Как предотвратить сборку данных при инициализации последовательного порта?
Я использую Arduino Uno. Я получаю мусор в последовательном мониторе или гипертерминале сразу после подключения к порту. Вот пример кода:
void setup() {
// initialize serial:
Serial.begin(57600);
}
void loop() {
Serial.println("Test");
}
Пример скриншота вывода. При повторном подключении порта первые полученные данные не проверяются:
Поэтому моя проблема в том, что при инициализации порта первые полученные данные являются мусором. Есть ли способ предотвратить это? Это как - то связано со скоростью передачи данных загрузчика? Я попробовал другие скорости передачи данных и получил ту же проблему, и я действительно хочу использовать скорость передачи данных 57600 или 115200.
@ty_1917, 👍0
Обсуждение2 ответа
Вероятно, существует ряд причин, которые могут способствовать возникновению проблемы, которую вы наблюдаете:
Вы пытаетесь отправить строку "Текст" в основном цикле без каких-либо задержек между вызовами println. Таким образом, микропроцессор работает на полной скорости и пытается отправить строку "Текст" намного быстрее, чем может вместить скорость передачи данных. Последовательный интерфейс имеет конечный буфер ввода-вывода, который, вероятно, заполняется очень быстро и перезаписывает старые значения в середине последовательной передачи. Следовательно, потенциально мусорные символы.
Даже когда HyperTerminal не работает, ПК и Arduino обмениваются последовательными сообщениями. Поэтому, когда вы запускаете HyperTerminal в какое-то произвольное время, данные в последовательном буфере могут не полностью соответствовать началу или концу передачи.
В качестве альтернативы вы можете захотеть дождаться последовательной команды от компьютера, прежде чем начать отправлять последовательные данные. Например, при использовании последовательного монитора вы можете отправить нажатие клавиши на Arduino, которое затем начнет отправлять данные, чтобы данные не терялись, пока на стороне ПК нет прослушивающих устройств или пока не запущена программа терминала.
Наконец, очистка последовательных буферов по обе стороны последовательного соединения может помочь вам очистить частичные последовательные сообщения.
Причина 1 недопустима: "Serial.println ()" не перезаписывает байты, которые еще не были отправлены. Вместо этого он переключается в режим блокировки, где ожидает, пока интерфейс освободит достаточно места в буфере для нового сообщения., @Edgar Bonet
Последовательный объект блокируется, когда буфер UART заполнен, поэтому никакие данные не перезаписываются в буфере UART., @JRobert
Использование вами терминологии в отредактированном сообщении и комментариях проблематично, потому что вы недостаточно ясно выразились. Например:
"Я имею в виду во время Serial.begin(57600); Я получаю мусорные значения. Как это пропустить? " и "Если я закомментирую, я ничего не получу".
"По "При повторном подключении порта" означает нажатие "позвонить" в HyperTerminal или откройте последовательный монитор Arduino. Первые данные всегда мусор". Есть и другие."
"Пример скриншота вывода. При повторном подключении порта первые полученные данные не являются тестовыми:" - Но первые полученные данные, которые вы показываете, это, по сути, слово Test.
Есть и другие.
Я постараюсь помочь, ответив на ваш главный вопрос, который, похоже, звучит так: "Как предотвратить мусорные данные" и обратите внимание, что я не включил "когда последовательный порт инициализируется".
Во-первых, когда я использую Uno и V 1.8.13 среды IDE, а также компилирую и запускаю ваш образец программы, я получаю обычный вывод, показывающий ход компиляции и загрузки на плату, и этот текст заканчивается " ;avrdude готово. Спасибо. В этот момент программа работает, и println делает свое дело.
Когда я открываю последовательный монитор (нажав на поле в правом верхнем углу полного экрана IDE - скорость передачи = 57600, без окончания строки), я сначала получаю искаженные символы. Так всегда происходит, и я верю, что вы видите именно это.
Это происходит потому, что когда вы открываете последовательный монитор, UNO сбрасывается, но это не полный сброс, который выполняется, когда вы загружаете код и начинаете выполнение. Чтобы быть немного упрощенным, когда вы открываете последовательный монитор, ваша программа работает, и сброс при открытии последовательного монитора не является чистым запуском, который выполняется, когда вы компилируете, загружаете и начинаете выполнять программу.
Используйте любую из этих программ, чтобы проверить, к чему я клоню.
void setup() {
// инициализируем сериал:
Serial.begin(57600);
}
void loop() {
delay(10000);
while(1){
Serial.println("Test");
}
}
или
void setup() {
// инициализируем сериал:
Serial.begin(57600);
delay(10000);
}
void loop() {
Serial.println("Test");
}
Выполните шаги с любой из этих модифицированных версий и откройте последовательный монитор в течение 10-секундной задержки (отключите автопрокрутку, чтобы его было легче увидеть), и вы не получите никаких повреждений.
Если, однако, вы скомпилируете/загрузите/выполните программу, а затем начнете открывать и закрывать последовательный монитор, вы начнете видеть повреждение при последующих открытиях последовательного монитора - опять же, потому что сброс при открытии последовательного монитора не чистый сброс, который выполняется при компиляции/загрузке/выполнении.
Почему никто не жалуется как сумасшедший на проблему, с которой вы столкнулись? Я думаю, потому что люди учатся работать с UNO. Ваш код просто отправляет последовательные данные, так что это явная иллюстрация проблемы, но это не непреодолимая проблема.
Вы можете углубиться в код последовательного монитора, узнать все о том, что происходит, и придумать элегантное и, вероятно, утомительное решение - я не уверен, но не сомневаюсь, что некоторые сделали это, и это может даже включать некоторые аппаратные манипуляции с последовательными линиями управления.
В качестве альтернативы вы можете написать программу, которая даст время завершить открытие последовательного монитора, прежде чем вы начнете отправлять данные. Вы даже можете очистить любые остаточные данные (если вы знаете, что делаете), если вы ожидаете многократных открытий и закрытий.
Надеюсь, это поможет.
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Использовать все контакты как цифровые входы/выходы
- Float печатается только 2 десятичных знака после запятой
- Arduino как USB HID
- Serial1' was not declared in this scope
- Очень простая операция Arduino Uno Serial.readString()
- AT-команда не отвечает на последовательный монитор
Я имею в виду во время Serial.begin(57600); Я получаю значения мусора. Как я могу пропустить это?, @ty_1917
@jsotola Я заново сформулировал проблему. Пожалуйста, ознакомьтесь с правкой., @ty_1917
Если я прокомментирую, то ничего не получу. Под "Когда порт повторно подключен" подразумевается нажатие кнопки "вызов" в гипертерминале или открытие последовательного монитора Arduino. Первые данные всегда являются мусором., @ty_1917
В HyperTerminal есть кнопки отключения и вызова, которые закрывают и инициируют порт. Аналогично последовательному монитору Arduino. Я не мог найти решение., @ty_1917
это может быть проблемой XY ... почему случайные символы являются проблемой?, @jsotola
используйте завершающий или инициализирующий символ для запуска мониторинга на стороне ПК; таким образом, любые непреднамеренные сигналы игнорируются., @dandavis