ЕСТЬ РЕШЕНИЕ Парсер протокола GRBL

knack

МЕСТНЫЙ
ПРОВЕРЕННЫЙ
Регистрация
30.05.2023
Сообщения
3
Реакции
4
Баллы
13
Причина: Отредактирован скетч + добавлен архив
Последнее редактирование модератором:
Доброго времени суток товарищи! )
т.к. могу постить только в этот раздел, уж извините.
Может кому сгодится или кому станет интересно и будут идеи и тема получит развитие...
Недавно купил сей станочек и затянуло, не понравилось, что нет доступных портов для подключения чего либо. решил обойти это ограничение с помощью своего костыля.
Подключил станок через локальную сеть, с помощью esp32(должно работать и на wemos если чуток код подправить), настроил второй UART и на esp написал простенький парсер протокола, который обрабатывает мои комманды. Тем самым я уже не привязан к плате станка и через интерфейс Candle или Gcode могу рулить еспэхой(шаговики, моторыб сожи и т.д. и т.п.).
C++:
#include <HardwareSerial.h>

HardwareSerial PortCNC(2);

//#include <ESP8266WiFi.h>
#include "WiFi.h"

//how many clients should be able to telnet to this ESP8266
#define MAX_SRV_CLIENTS 1
const char* ssid = "SWEET_HOME";
const char* password = "123123123123";

IPAddress ip(192, 168, 10, 99);
IPAddress gateway(192, 168, 10, 1);
IPAddress subnet(255, 255, 255, 0);

WiFiServer server(23);
WiFiClient serverClients[MAX_SRV_CLIENTS];


//String messCandl = "";
boolean protokol = true;

float X = 0;
float Y = 0;
float Z = 0;

unsigned long getCoordinateTime = 0;

void setup() {
  Serial.begin(115200);
  PortCNC.begin(115200, SERIAL_8N1, 16, 17);


  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet);
  Serial.print("\nConnecting to "); Serial.println(ssid);
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) {
    delay(500);
  }
  if (i == 21) {
    Serial.print("Could not connect to"); Serial.println(ssid);
    while (1) {
      delay(500);
    }
  }
  //start UART and the server
  server.begin();
  server.setNoDelay(true);

  Serial.print("Ready! Use 'telnet ");
  Serial.print(WiFi.localIP());
               Serial.println(" 23' to connect");
}

void loop() {
  uint8_t i;
  //check if there are any new clients
  if (server.hasClient() ) {
  for (i = 0; i < MAX_SRV_CLIENTS; i++) {
      //find free/disconnected spot
      if (!serverClients[i] || !serverClients[i].connected() ) {
      if (serverClients[i]) {
          serverClients[i].stop();
        }
        serverClients[i] = server.available();
        Serial.print("New client: "); Serial.print(i);
        break;
      }
    }
    //no free/disconnected spot so reject
    if (i == MAX_SRV_CLIENTS) {
      WiFiClient serverClient = server.available();
      serverClient.stop();
      Serial.println("Connection rejected ");
    }
  }
  //check clients for data
  if (serverClients[0] && serverClients[0].connected() ) {
  if (serverClients[0].available()) {

    //get data from the telnet client and push it to the UART
    if (serverClients[0].available()) {
      size_t len = serverClients[0].available();
        uint8_t sbuf[len];
        serverClients[0].readBytes(sbuf, len);
        if (protokol) {//отключение пакетов от Candle
          PortCNC.write(sbuf, len);
        }
        parsCANDY(sbuf, len);//парсинг буфера TCP порта
      }
    }
  }

  //check UART for data
  if (PortCNC.available()) {

  size_t len = PortCNC.available();
    uint8_t sbuf[len];
    PortCNC.readBytes(sbuf, len);

    //push UART data to all connected telnet clients
    for (i = 0; i < MAX_SRV_CLIENTS; i++) {
      if (serverClients[i] && serverClients[i].connected()) {
      serverClients[i].write(sbuf, len);
        parsCNC(sbuf, len);//парсинг UART от 3018
      }
    }
  }

  //обновляем координаты когда Candle отрезан (40ms)
  if (!protokol) {
  if (millis() - getCoordinateTime > 40) {
      PortCNC.println("?");
      getCoordinateTime = millis();
    }
  }
}

//парсинг UART от 3018
String messUART = "";
boolean otladkaCNC = false;
void parsCNC(uint8_t inpt[], int len) {

  for (int i = 0; i < len; i++) {
    if (inpt[i] != 10 && inpt[i] != 13)messUART += char(inpt[i]);//отрезаем спецсимволы

    if (inpt[i] == 13) {//находим конец пакета
      if (otladkaCNC) {//включение\отключение отладки
        Serial.print("FromCNC:");
        Serial.println(messUART);
      }

      //парсим XYZ
      if (messUART.startsWith("<Idle|MPos:")) {
      int startX = messUART.indexOf(':');
        int sepX = messUART.indexOf(',');
        X = messUART.substring(startX + 1, sepX).toFloat();
        int sepY = messUART.indexOf(',', sepX + 1);
        Y = messUART.substring(sepX + 1, sepY).toFloat();
        int sepZ = messUART.indexOf('|', sepY + 1);
        Z = messUART.substring(sepY + 1, sepZ).toFloat();
      }
      messUART = "";
    }
  }
}

boolean otladkaCandle = false;

void parsCANDY(uint8_t inpt[], int len) {
  String messCandl = "";
  for (int i = 0; i < len; i++) {
    if (inpt[i] != 10 && inpt[i] != 13)messCandl += char(inpt[i]);//отрезаем спецсимволы

    if (inpt[i] == 13) {//находим конец пакета
      if (otladkaCandle) {//включение\отключение отладки
        Serial.print("FromCandle:");
        Serial.println(messCandl);
      }

      //Парсим комманды с консоли Candle, при отрезанном Candle комманды парсятся, машинные координаты так же работают, переменные float XYZ
      if (messCandl == "M100")protokol = false;//отрезаем Candle
      if (messCandl == "M101")protokol = true;//подключаем, нужно $X
      if (messCandl == "CNC")otladkaCNC = !otladkaCNC;//содержание пакетов в отладочный порт
      if (messCandl == "CNDL")otladkaCandle = !otladkaCandle;//содержание пакетов в отладочный порт

      //пример
      if (messCandl == "T6") {
        if (X == 10)PortCNC.println("X0");
        if (X == 0)PortCNC.println("X10");
      }
      messCandl = "";
    }
  }
}
 

Вложения

  • esp.jpg
    esp.jpg
    145.6 KB · Просмотры: 60
  • sketch.zip
    1.9 KB · Просмотры: 4
А управляющие программы тоже по воздуху в него закидываете? или через карту памяти?
 
Serial.print("Ready! Use 'telnet ");
Serial.print(WiFi.localIP:));
Serial.println(" 23' to connect");
видимо, какая-то прослойка ещё есть, или Кэндл умеет прямиком в сеть слать?

я попробовал Netgear чего-то-там, тут мелькало на форуме, но он дико непредсказуемый (как минимум, в моих условиях). я уж как только код не переписывал, но всё равно какие-то задержки между посылками, визуализатор лагает, станок из Run постоянно сваливается в Idle (ну как станок, я просто плату без станка гоняю с визуализатором)

буквально сегодня попробовал Serial to Ethernet connector от Electronic Team (их прям на сайте нетгира советуют, типа, наш софт только с нашими железками норм работает, за других не ручаемся, вот сюда идите), сразу как-то всё оживилось, время работы почти секунда в секунду совпадает с проводным вариантом, но софтина стоит негуманно (на мой взгляд), да и платить сейчас нашими картами сложновато.

собственно, вопрос: как данные в сеть улетают, что посередине между кэндлом и вайфай-роутером? (эксперты в семиуровневой системе, не доколупывайтесь :))
 
Есть отличный пост komatoz(a) как это устроено, не стал расписывать, думал всем известно. Прослойка, да. Микроконтроллер с wifi или bluetooth который прикидывается com портом, а с компьютера софтина которая то же прикидывается com портом, а софтина и мк общаются по воздуху, выше от каматоза всё просто написано, думаю любой настроит.
 
видимо, какая-то прослойка ещё есть, или Кэндл умеет прямиком в сеть слать?
нет не умеет, он шлёт в виртуальный com порт, а программа которая создала этот виртуальный com порт уже по TCP шлёт в микроконтроллер по воздуху, в котором залит определённый скетч который позволяет общаться с данной программой. Для Candle как буд то станок подключён по кабелю.
 
Не знаю, как так вышло, я вроде писал как человек, который чёт попробовал и даже в чём-то разбирается :)

Короче, эта программа, которая делает виртуальный ком-порт и прокидывает данные из него в сеть (How to Create a Virtual Serial Port (COM Port)) - полная ерунда. Возможно она умеет хорошо работать с железками от вендора, может там требования свои, но, как минимум для моих условий, она совершенно непригодна: время обработки может достигать удвоенного значения относительно времени обработки по проводу, статус GRBL меняется с Run на Idle постоянно, подозреваю, что если бы я пробовал на реальной обработке, то это бы вылилось в лучшем случае в потерю времени, в худшем - скорее бы всего ломалась фреза. Об том, что софт подойдет не всем, впрочем, производитель и упоминает. Но при этом дает ссылку на другой продукт, Share Serial port Over Ethernet with Serial to Ethernet Connector

Вот с этой прогой всё стало значительно лучше, исчезли лаги в передаче данных, время обработки стало практически равным времени обработки на проводе. Но стоит эта прога 260 долларов, что не выглядит рациональным приобретением. Если не найду чего-то готового, придётся самому писать.

Поэтому я и хотел узнать, все и дальше продолжают пользоваться Netburner и всем норм, или есть какие-то иные решения по созданию виртуальных ком-портов с возможностью транслировать данные в сеть. Пост komatoz(a) это хороший старт, но это не ультимативное решение, к сожалению.
 
  • Последнее редактирование:
Последнее редактирование:
Короче, эта программа, которая делает виртуальный ком-порт и прокидывает данные из него в сеть (How to Create a Virtual Serial Port (COM Port)) - полная ерунда.
NetBurner вполне пригоден к использованию. Конкретно у меня есть баг, если ноут засыпает то служба умирает и приходится перезагружаться. Или вам нужен именно rs232? Ну я думаю и с ним должно работать, хотя тема немножко о другом, про ESP.

Всё зависит от поставленных задач. А чем вам nerBurner не устраивает? Какой вам необходим функционал?
 
Как я уже и сказал, скорость передачи пакетов у Netburner неудовлетворительная, отключения алгоритма Нейгла нет, из-за этого станок не получает равномерный поток данных
 
Таких проблем не наблюдал, 115200 перемалывает. Может проблема в самой сети? Особо затыков не наблюдал. Если нужно отойти от usb, и наличие провода не смущает можно сделать мост на rs485... Всё же тема не про это.
 
JDY-40 как вариант, опять же всё зависит от поставленной задачи.
 
вот эта хорошая, почти такая же, как за деньги, только бесплатная :)

спасибо!
Ваши сообщения автоматически объединены:

Может проблема в самой сети?
может быть. но когда одна прога работает значительно лучше, чем другая в рамках одной и той же сети, выводы напрашиваются сами собой :)
 
В общем, история развернулась вообще в другую сторону :)
Я все упражнялся на дятле, потому что Инектра на балконе и лень было отцеплять плату для опытов.
Но после того, как станок окончательно осел в ящике, были проведены все провода, ждать стало нельзя :) (вообще, пришлось-таки Инектру отцепить, чтобы поменять тип входа с USB на UART)
Так вот, прицепил свою ESP32 (в формате M5StickC, лежала без дела, да и ноги паять не нужно), запустил и чудо! - визуализатор летает, лагов нет, время беспровода не отличается от проводного подключения.
Возможно даже NetBurner сработал бы хорошо, надо попробовать :)
 

Вложения

  • IMG_1146.jpeg
    IMG_1146.jpeg
    91.7 KB · Просмотры: 32
  • Причина: ЗЫ
  • Последнее редактирование:
Причина: ЗЫ
Последнее редактирование:
Автору.
Плиз, обрамляйте код тэгом "код" <>, иначе нарушаются скобки (движок форума их меняет на смайлы) и всё становится неработоспособным.
Или прикладывайте в архиве исходник.

ЗЫ. Отредактировал код в первом сообщении + добавил архив.
 
Сверху Снизу
Обнаружен блокировщик рекламы AdBlock

МЫ ДОГАДЫВАЕМСЯ, ЧТО РЕКЛАМА ВАС РАЗДРАЖАЕТ!

Конечно, Ваше программное обеспечение для блокировки рекламы отлично справляется с блокировкой рекламы на нашем сайте, но оно также блокирует полезные функции. Мы стараемся для Вас и не обязываем Вас донатить и скидывать денег на наши кошельки, чтобы пользоваться форумом, но реклама это единственное, что позволяет поддерживать проект и развивать его.

Спасибо за Ваше понимание!

Я отключил свой AdBlock    Нет, я не буду ничего отключать