Связь между Python и Arduino ненадежна
Я пытаюсь установить базовую связь между Python и моей Arduino. Мне удалось отправить сообщение на Arduino и отправить обратно, но код, выполняющий эту задачу, не дает последовательных результатов. Я использую Python 3.5 с pyserial 3.3.
Мой код Arduino:
String incoming;
void setup() {
Serial.begin(9600); // открывает последовательный порт, устанавливает скорость передачи данных 9600 бит/с
}
void loop() {
// отправлять данные только при получении данных:
if (Serial.available() > 0) {
// прочитать входящий байт:
incoming = Serial.readStringUntil('\n');
// скажите, что у вас есть:
Serial.print("I received: ");
Serial.println(incoming);
}
}
Мой код Python
import serial
arduinoSerialData = serial.Serial("COM5",9600,timeout=1)
print("Initial in waiting:")
print(arduinoSerialData.in_waiting)
print("Initial out waiting:")
print(arduinoSerialData.out_waiting)
while (arduinoSerialData.in_waiting>0):
garbage = arduinoSerialData.readline()
print(garbage)
nummessages =0
while (nummessages<5):
if (arduinoSerialData.in_waiting>0):
myData = arduinoSerialData.readline()
myData = myData.decode('utf-8')
myData = myData.strip()
print("The Arduino says:")
print(myData)
nummessages=nummessages+1
elif(arduinoSerialData.out_waiting>0):
pass
else:
arduinoSerialData.write(b'Hello Arduino!\n')
while (arduinoSerialData.in_waiting>0):
garbage = arduinoSerialData.readline()
print(garbage)
print("In Waiting: ")
print(arduinoSerialData.in_waiting)
print("Out Waiting: ")
print(arduinoSerialData.out_waiting)
arduinoSerialData.close()
Эти операторы печати во многом являются моей неудачной попыткой диагностировать проблему. Циклы «мусора» были моей попыткой убедиться, что условия максимально идентичны при запуске кода Python. Если я запускаю программу arduino, а затем вызываю эту программу python из командной строки, я получаю противоречивые результаты. Иногда мой первый вызов python «работает», а затем другие — нет, иногда он работает несколько раз подряд, и вывод первой строки, где написано «Arduino Says: I», будет иметь различное количество « Я получил: Привет, Arduino» сообщение, которое должна была отправить Arduino. Любые идеи, что может быть причиной такого отсутствия согласованности? Если я попытаюсь сначала запустить код Python, Arduino даже не сможет запуститься.
@cpoole, 👍2
Обсуждение2 ответа
Лучший ответ:
На случай, если другие люди столкнутся с похожими проблемами, я изложу то, что нашел сегодня.
-Несогласованный вывод был связан с тем, что когда вы открываете последовательное соединение с python, он сбрасывает Arduino, и поэтому python может отправлять сигналы без завершения arduino своей функции setup(). Если я добавлю 1-секундную задержку на стороне Python, несогласованность прекратится, и я больше не столкнусь с байтовыми ошибками. Я ищу альтернативные способы предотвращения этого сброса, так как временная задержка является для меня решающим фактором.
ОБНОВЛЕНИЕ: Замена
arduinoSerialData("COM5",9600,timeout=1)
с
arduinoSerialData = serial.Serial()
arduinoSerialData.port = "COM5"
arduinoSerialData.baudrate = 9600
arduinoSerialData.timeout = 1
arduinoSerialData.setDTR(False)
#arduinoSerialData.setRTS(False)
arduinoSerialData.open()
Кажется, обходит сброс. Я включил здесь обе функции setDTR и SetRTS, потому что, хотя setDTR работает для DUE, кажется, что некоторые другие платы Arduino вместо этого нуждаются в setRTS.
-Функция decode() имеет аргумент с ключевым словом, называемым ошибками, для которого можно установить значение «игнорировать», если вы хотите, чтобы код просто игнорировал то, что не может быть интерпретировано в желаемом формате. Только с этой настройкой ключевого слова я никогда не получал ошибок, но вывод был несогласованным из-за сброса.
Похоже, опция игнорирования ошибок по сути дает вам фильтр шума. Хороший звонок по поводу перезагрузки - просто думал об этом в контексте другого вопроса., @Chris Stratton
Эта сестра не решает ту же проблему, что и у меня с Duo. Однако задержка помогла., @SaTa
Проблема:
Arduino, будучи микроконтроллером (а не микропроцессором), недостаточно эффективен. При внимательном рассмотрении сообщения, отправляемые на последовательный монитор, перекрываются, если временной интервал между двумя сообщениями составляет менее половины секунды !! Также существует равная вероятность наложения данных от Arduino, что приводит к мусорным данным !!
Решение:
Для решения этих проблем доступны модули Python с именами Arduino_Master и Arduino_Master_Delta.
Эти модули также помогают визуализировать данные в виде графиков, а также фильтровать данные и удалять ненужные значения.
Arduino_Master используется для аппроксимации и упрощения интерфейса тогда как Arduino_Master_Delta используется для точного представления данных!
Ссылки:
Ссылки на их документацию приведены ниже:
Arduino_Master
Arduino_Master_Delta
Примеры:
Код для всего этого можно найти в документации Arduino_Master_Delta.
Я никогда не замечал проблемы с попыткой отправить отдельные сообщения слишком быстро, вызывая проблемы с Python. Я не использовал серийный монитор. Проблема, с которой я столкнулся, определенно была вызвана сбросом программы Arduino, когда Python открыл последовательное соединение, как подробно описано в моем ответе., @cpoole
- Построение графика на Python с использованием Tkinter Canvas
- Протокол связи Arduino с python — помимо примера pyserial и Arduino
- Не удается связаться с ардуино с помощью python (Windows)
- Последовательная связь Arduino с Python: отправка массива
- Как отправить целое число через pyserial с Python на Arduino и получить тот же результат?
- Сброс последовательного порта Arduino в последовательном мониторе и Python
- Отправка числа с плавающей запятой из python в arduino
- Что является более быстрой альтернативой parseInt()?
Почему вы пытаетесь декодировать данные utf-8? Жизнь, вероятно, будет проще, если вы выбросите или замените все, что не является символом ASCII, а затем напечатаете то, что у вас есть., @Chris Stratton
В основном я просто пробовал это, потому что в аналогичных примерах это использовалось в качестве инструмента перевода. Если я закомментирую строки decode() и strip(), программа будет работать всегда, за исключением того, что первая строка ошибочна. Количество символов варьируется, иногда в конце стоит \xff. Я предполагаю, что именно эти случаи сломали декодер в исходном вопросе. Я могу найти другой способ перейти от b'text\r\n' к 'тексту', чтобы попытаться справиться с этим. Постараюсь добавить картинку в основной вопрос для ясности., @cpoole
Пожалуйста, не используйте картинки., @Chris Stratton
Вероятно, это должен быть вопрос Stackoverflow (или поиск существующих ответов) о том, как вытащить печатные символы из буфера, содержащего (в основном, но не полностью) устаревший ASCII., @Chris Stratton