Arduino быстро отправляет команды

Мне нужен станок с ЧПУ, чтобы работать как можно более плавно.

Он получает такие команды, как "M_XY 10.233 20.123".

Если я посылаю команду за командой, то есть небольшая задержка между командами и ее заметностью. Я установил последовательный тайм-аут на 5 мс.

Я попытался отправить n команд и сохранить их на arduino, но arduino не может много хранить в оперативной памяти. Существует огромная задержка при отправке n команд.

Я думал о преобразовании букв (машина пишет буквы) в безье и отправке дуги за дугой или буквы за буквами по дугам. Может ли atmega328p достаточно быстро интерполировать безье?

Будет ли это быстрее, если я буду посылать числа в байтах, а не в строках? Это будет 4 байта на float и слияние с объединением на arduino.

Есть ли какой-нибудь лучший способ сделать это, о котором я не знаю?

Редактировать: Именно так обрабатываются строковые команды.

void addCommByte(const byte b){
  if(commID == MAX_COMM+1){
    commID = 0;
    Serial.println("TOO LONG COMMAND");
    Serial.flush();
    return;
  }
  
  if(b == '\n'){
    comm[commID] = '\n';
    commID = 0;
    
    processCommand();
  }
  else if(b == '\r')
  {
    commID = 0;
  }
  else
  {
    comm[commID++] = b;
  }
}

void loop() {
  Serial.flush();
  while(Serial.available() > 0) {
    addCommByte(Serial.read());
  }
}

Правка. Гораздо лучше.

Сторона C#. Проверьте наличие порядковых номеров в c#. Arduino-это маленький эндиан.

        public void MOV_X(float mm)
            {
                SendCharAsByte("q"[0]);
                SendFloatAsBytes(mm);
            }
        public void SendFloatAsBytes(float f)
        {
            byte[] vOut = BitConverter.GetBytes(f);
            serialPort.Write(vOut, 0, 4);
        }

        public void SendShortAsBytes(short f)
        {
            byte[] vOut = BitConverter.GetBytes(f);
            serialPort.Write(vOut, 0, 2);
        }

        public void SendCharAsByte(char c)
        {
            byte[] aaa = new byte[1];
            aaa[0] = (byte)c;
            serialPort.Write(aaa, 0, 1);
        }

Arduino сторона.

void loop() {
  while(Serial.available() > 0) {
    processV2(Serial.read());
  }
}
// from processV2
if(byt == 'q'){   // mov x
    float mm = readFloat();
    if(X_DIR == 1) mm *= -1.0;
    
    stepperXY.moveXForMMSync(mm);
    Serial.println("p");
    return;
  }
// merge bytes
union u_tag {
   byte b[4];
   float fval;
} u;

float readFloat(){
  Serial.readBytes(u.b, 4);
  return u.fval;
}

Нет никакой необходимости смывать Serial.

, 👍1

Обсуждение

Если вы получаете последовательные данные правильно, то нет никакой необходимости в последовательном таймауте. Вы не должны полагаться на Serial.parseFloat() и такие функции., @Majenko

Я использую строку c = Serial.ReadString(); в цикле., @some rand

И в этом твоя проблема. Вы полагаетесь на тайм-аут. Вместо этого вы должны искать символ конца строки и читать данные до тех пор, пока не увидите это. А также не используйте "строку", так как это приведет к случайному сбою вашей системы., @Majenko

https://majenko.co.uk/blog/reading-serial-arduino, @Majenko

Пожалуйста, включите в свой вопрос компилируемый минимальный пример кода. Вы можете вырезать все детали с ЧПУ и просто оставить код последовательной связи. Пожалуйста, убедитесь, что код все еще компилируется, @chrisl

Я переключился на char за char и его быстрее. Задержка все еще заметна., @some rand

Почему вы спускаете серийный в петле? Как я помню, прошивка, подобная GRBL, также использует связь на основе ASCII для прямой отправки gcode на ЧПУ. Так что это может сработать. Что вы делаете для обработки команды? Вы измеряете задержку между отправкой команды и движением двигателя? Сколько сейчас времени?, @chrisl

Я сделал идею Боггимена. Есть еще небольшая задержка, но она приемлема. Я использую поток для цикла отправки и получения команд. Эта задержка может исходить из цикла c# thread.sleep. Где-то я прочитал, что поток не может спать меньше 12 или около того мс. Что-то связанное с ОС Windows., @some rand


1 ответ


Лучший ответ:

1

Если у вас есть существующий ЧПУ, вам, возможно, придется соблюдать его протокол связи. В противном случае, если Arduino является частью ЧПУ, который вы строите, и он должен принимать команды от главного компьютера, первое, что нужно сделать, это убедиться, что ваша скорость передачи данных установлена выше, чем по умолчанию. Я нашел 115200, чтобы быть хорошим выбором для стабильности. Затем следует избегать отправки текстовых строк типа TTY и вместо этого отправлять двоичные значения. Вы бы отправили начальный байт или слово, чтобы указать тип команды, а затем данные. В моем скетче DaqPort с открытым исходным кодом для высокоскоростного сбора данных https://www.daqarta.com/dw_rraa.htm Я использую высокий nybble команды, чтобы указать общий тип, и низкий nybble, чтобы указать больше деталей, таких как номер канала. Скетч использует большой цикл с if(Serial.available() > 0), чтобы прочитать первый байт, и переключатель/случай, чтобы определить, что делать. Конкретная команда считывает нужное количество байтов и делает все, что угодно. Это намного быстрее, чем разбор текста и преобразование в двоичный код.

,