Почему arduino так медленно реагирует на последовательный ввод

У меня есть очень простой скетч, где я мигаю светодиодной лампочкой. Если я отправлю другое значение на последовательный монитор, то сначала всегда будет короткая секунда, когда индикатор больше не мигает. Почему это так, и как я могу от этого избавиться?

int the_delay = 300;

void setup() {
  Serial.begin(115200);
  pinMode(12, OUTPUT);
}

void loop() {
  digitalWrite(12, HIGH);   
  delay(the_delay);            
  digitalWrite(12, LOW);    
  delay(the_delay);            
}


void serialEvent() {

  if (Serial.available()) {   
    the_delay = Serial.parseInt();
    Serial.println(the_delay);
  }
}

В случае, если это поможет, в конечном итоге я хотел бы отправлять значения со скоростью 60 кадров в секунду.

, 👍3


4 ответа


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

3

Это потому, что вы используете Serial.parseInt(). Он использует тайм-аут, чтобы найти конец данных на последовательном порту, и пока он ждет этого тайм-аута, он больше ничего не может сделать.

Вам было бы лучше вручную считывать последовательные данные по одному символу за раз, чтобы создать входную строку (C-строку, а не строку Arduino) с соответствующим терминатором строки (строка, \n), а затем преобразовать ее в целое число с помощью atoi().

,

2

Попробуйте ввести нецифровый символ после значения задержки; даже ввод должен работать, если ваш терминал настроен на отправку любого вида сообщений в конце строки. Serial.parseInt() ожидает полного тайм-аута (по умолчанию: 1000 мс) после каждой цифры для следующей. Безразрядное значение немедленно завершит ввод значения.

,

1

Смотрите, как обрабатывать входящие последовательные данные без блокировки. Промежуточное решение состоит в том, чтобы заставить последовательный монитор автоматически отправлять новую строку при нажатии кнопки Отправить.

Вот пример кода, который обрабатывает ввод без блокировки:

// Example of processing incoming serial data without blocking.

// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 50;

void setup ()
  {
  Serial.begin (115200);
  } // end of setup

// here to process incoming serial data after a terminator received
void process_data (const char * data)
  {
  // for now just display it
  // (but you could compare it to some value, convert to an integer, etc.)
  Serial.println (data);
  }  // end of process_data

void processIncomingByte (const byte inByte)
  {
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;

  switch (inByte)
    {

    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte

      // terminator reached! process input_line here ...
      process_data (input_line);

      // reset buffer for next time
      input_pos = 0;  
      break;

    case '\r':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;

    }  // end of switch

  } // end of processIncomingByte  

void loop()
  {
  // if serial data available, process it
  while (Serial.available () > 0)
    processIncomingByte (Serial.read ());

  // do other stuff here like testing digital input (button presses) ...

  }  // end of loop
,

1

Отредактируйте следующим образом: Серийный номер.начало(115200); Serial.setTimeout(10); //Максимальное время в мс, в течение которого он должен ждать данных

Задержка по умолчанию составляет 1000 мс. Приведенный выше код устанавливает его на 10 мс. Поиграйте со значением тайм-аута и проверьте наличие ошибок. https://www.arduino.cc/reference/en/language/functions/communication/serial/settimeout/

,

Это хорошо, насколько это возможно. Но, похоже, в основном это повторение существующего ответа., @timemage