Почему 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 кадров в секунду.
@clankill3r, 👍3
4 ответа
Лучший ответ:
Это потому, что вы используете Serial.parseInt()
. Он использует тайм-аут, чтобы найти конец данных на последовательном порту, и пока он ждет этого тайм-аута, он больше ничего не может сделать.
Вам было бы лучше вручную считывать последовательные данные по одному символу за раз, чтобы создать входную строку (C-строку, а не строку Arduino) с соответствующим терминатором строки (строка, \n
), а затем преобразовать ее в целое число с помощью atoi()
.
Попробуйте ввести нецифровый символ после значения задержки; даже ввод
должен работать, если ваш терминал настроен на отправку любого вида сообщений в конце строки. Serial.parseInt()
ожидает полного тайм-аута (по умолчанию: 1000 мс) после каждой цифры для следующей. Безразрядное значение немедленно завершит ввод значения.
Смотрите, как обрабатывать входящие последовательные данные без блокировки. Промежуточное решение состоит в том, чтобы заставить последовательный монитор автоматически отправлять новую строку при нажатии кнопки Отправить.
Вот пример кода, который обрабатывает ввод без блокировки:
// 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
Отредактируйте следующим образом: Серийный номер.начало(115200); Serial.setTimeout(10); //Максимальное время в мс, в течение которого он должен ждать данных
Задержка по умолчанию составляет 1000 мс. Приведенный выше код устанавливает его на 10 мс. Поиграйте со значением тайм-аута и проверьте наличие ошибок. https://www.arduino.cc/reference/en/language/functions/communication/serial/settimeout/
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Использовать все контакты как цифровые входы/выходы
- Float печатается только 2 десятичных знака после запятой
- Arduino как USB HID
- Serial1' was not declared in this scope
- Очень простая операция Arduino Uno Serial.readString()
- AT-команда не отвечает на последовательный монитор
Это хорошо, насколько это возможно. Но, похоже, в основном это повторение существующего ответа., @timemage