Связь между 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 даже не сможет запуститься.

, 👍2

Обсуждение

Почему вы пытаетесь декодировать данные utf-8? Жизнь, вероятно, будет проще, если вы выбросите или замените все, что не является символом ASCII, а затем напечатаете то, что у вас есть., @Chris Stratton

В основном я просто пробовал это, потому что в аналогичных примерах это использовалось в качестве инструмента перевода. Если я закомментирую строки decode() и strip(), программа будет работать всегда, за исключением того, что первая строка ошибочна. Количество символов варьируется, иногда в конце стоит \xff. Я предполагаю, что именно эти случаи сломали декодер в исходном вопросе. Я могу найти другой способ перейти от b'text\r\n' к 'тексту', чтобы попытаться справиться с этим. Постараюсь добавить картинку в основной вопрос для ясности., @cpoole

Пожалуйста, не используйте картинки., @Chris Stratton

Вероятно, это должен быть вопрос Stackoverflow (или поиск существующих ответов) о том, как вытащить печатные символы из буфера, содержащего (в основном, но не полностью) устаревший ASCII., @Chris Stratton


2 ответа


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

3

На случай, если другие люди столкнутся с похожими проблемами, я изложу то, что нашел сегодня.

-Несогласованный вывод был связан с тем, что когда вы открываете последовательное соединение с 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


0

Проблема:

Arduino, будучи микроконтроллером (а не микропроцессором), недостаточно эффективен. При внимательном рассмотрении сообщения, отправляемые на последовательный монитор, перекрываются, если временной интервал между двумя сообщениями составляет менее половины секунды !! Также существует равная вероятность наложения данных от Arduino, что приводит к мусорным данным !!


Решение:

Для решения этих проблем доступны модули Python с именами Arduino_Master и Arduino_Master_Delta.

Эти модули также помогают визуализировать данные в виде графиков, а также фильтровать данные и удалять ненужные значения.

Arduino_Master используется для аппроксимации и упрощения интерфейса тогда как Arduino_Master_Delta используется для точного представления данных!


Ссылки:

Ссылки на их документацию приведены ниже:

Arduino_Master

Arduino_Master_Delta


Примеры:

Код для всего этого можно найти в документации Arduino_Master_Delta.

Lights

Impulse_Detection

Impulse_Removal

,

Я никогда не замечал проблемы с попыткой отправить отдельные сообщения слишком быстро, вызывая проблемы с Python. Я не использовал серийный монитор. Проблема, с которой я столкнулся, определенно была вызвана сбросом программы Arduino, когда Python открыл последовательное соединение, как подробно описано в моем ответе., @cpoole