В чем разница, когда ардуино был отключен от сети, и когда последовательный порт был закрыт?

Используя код python для подключения последовательного порта к arduino, он отправляет значение в arduino, который затем начинает печатать значения в serial. Код python будет печатать значение при первом или втором запуске (если запустить достаточно скоро), но после этого он не будет снова читать то, что из Serial.println. Чтобы заставить его снова читать (независимо от того, жду ли я какое-то время или нет, например, завершения цикла while), arduino должен быть отключен и снова подключен, почему это отличается от того, что соединение последовательного порта закрывается python? Вот используемый код arduino,

int measured;
int counter = 0;
int maxnum = 10;

void setup()
{
Serial.begin(9600);
}

void loop()
{
  if(Serial.available() > 0)
  {
    while(counter < maxnum)
    {

        Serial.println("V");
        counter++;
        delay(100);

    }
  }
}

Я знаю, что значение, отправленное из python, может быть прочитано, потому что я добавил в код, который читает из serial после проверки, доступен ли он, и изменил выходное значение PIN, которое работает, даже если последовательный println не читается.

Edit: Поскольку ответ заключается в том, что не должно быть существенной разницы, и сценарий arduino должен быть сброшен, если последовательный порт был закрыт, проблема должна быть с кодом python.

, 👍2


1 ответ


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

2

Мы не можем знать, есть ли проблема и в вашем коде python. Но ваш код Arduino отправит серию букв "V" только один раз.

Вы используете этот цикл while:

while(counter < maxnum)

там вы увеличиваете счетчик переменных . Но после того, как вы вышли из цикла while, вы никогда не сбрасываете счетчик на ноль. Так что в следующий раз счетчик все равно будет равен maxnum. Таким образом, цикл while больше не будет выполняться. Чтобы решить эту проблему, вставьте

counter = 0;

непосредственно после вашего цикла while. Хотя для таких циклов обычно проще просто использовать цикл for.


Кроме того, у вас может возникнуть вторая проблема. В настоящее время код ожидает получения последовательных данных. Когда что-то будет получено, код войдет в систему.

if(Serial.available() > 0)

заявление. Но это останется верным, если вы на самом деле не читаете данные. В настоящее время код внутри оператора if будет выполняться на каждом взаимодействии loop() навсегда. Поэтому, если вы применяете вышеуказанное исправление к первой проблеме, код отправит "V" навсегда после того, как вы отправите первый байт в Arduino. Чтобы на самом деле реагировать только на полученные данные, вам нужно прочитать данные из буфера - даже если вы выбрасываете данные:

Serial.read();

В чем разница, когда arduino был отключен от сети, а когда последовательный порт был закрыт?

Для самого Arduino? Почти нет. Повторное открытие последовательного соединения приведет к сбросу Arduino. Затем код снова запускается с самого начала. Это также то, что происходит, когда вы включаете цикл питания (подпитка) Arduino. Я думаю, что есть некоторые небольшие детали, где оба отличаются, но это, конечно, не проблема здесь.

Для компьютера заполнение означает, что USB-устройство (USB-последовательный чип на Arduino, чтобы быть точным) отключается и снова подключается. Это может привести к тому, что ОС выделит для него другой com-порт/файл устройства, чем раньше. Хотя это непосредственно не делает что-то с кодом Arduino (кроме упомянутого цикла питания со сбросом).

Для сброса (сохранено из комментария ОП):

Я обнаружил, что, установив DTR на 0, затем 1, затем снова 0, прямо перед закрытием порта, arduino сбрасывается.

,

Хорошо, да, я достал какой-то код, чтобы сделать простейший пример, но в любом случае он должен хотя бы один раз прочитать " V " при запуске. Когда я использую pyserial, он будет перечитан после перезапуска сценария, но с pyqt5 он не будет перечитан снова. Так что, возможно, проблема в том, что определенный код python неправильно закрывает последовательный порт, если отключение и закрытие последовательного порта должны дать те же результаты. [Here](https://stackoverflow.com/questions/66789407/why-would-qtserialport-not-read-after-running-more-than-once-or-twice) - это версия pyqt5 python, которая больше не будет считываться., @user14094230

Хотя да, когда я ставлю если " (серийно.доступно() > 0) { int counter = 0;` вместо инициализации счетчика в начале, он каждый раз считывается. Итак, опять же, похоже, что код python не сбрасывал код arduino с новым подключением последовательного порта., @user14094230

Я не эксперт в серии pyqt5, но разве этот код не вышел бы просто, когда он получил одну (или несколько) строк? И программа просто завершает работу, не открывая последовательный порт. Итак, когда именно вы подумали, что порт должен быть открыт снова?, @chrisl

Он будет снова открыт, когда я снова запущу сценарий. Да, он читает только одну строку, но если код python читает 10 строк, как печатает arduino, он все равно, похоже, не сбрасывает код arduino при перезапуске сценария. Я просто пытался создать здесь самый простой сценарий., @user14094230

Mhh, как было написано выше, мы не являемся экспертами в серии pyqt5. Arduino выполнит сброс сигналов на линиях DTR или RTS (ссылка question). Возможно, реализация pyqt5 не делает этого по умолчанию. Вы можете ознакомиться с вариантами серийного номера pyqt5. Для нас это выходит за рамки. Если вам нужна помощь в этом, вы можете попробовать спросить в stackoverflow. Это может дать вам лучшие результаты, чем здесь., @chrisl

Да, я изменил вопрос о переполнении стека, чтобы спросить о том, как открывается и закрывается pyqt5. Возможно, в этом проблема, в pyqt5 есть опции для установки DTR и RTS. Спасибо., @user14094230

Знаете ли вы, связано ли это с тем, почему код python иногда получает и выводит байтовый объект b' V ' вместо строкового объекта V? Это может быть связано с другим вопросом и снова может быть проблемой с кодом python., @user14094230

Это полностью на стороне python. Последовательный интерфейс не знает разницы между строкой V и байтовым объектом b'V'. Я бы счел это нормальным, если бы код python предоставил мне байтовый объект в качестве последовательных данных (поскольку последовательные данные не обязательно являются строковыми данными; также могут быть реальными двоичными)., @chrisl

Я обнаружил, что, установив DTR на 0, затем 1, затем снова 0, прямо перед закрытием порта, arduino сбрасывается., @user14094230

@пользователь14094230 Отлично! Я сохранил это в конце своего ответа, так как комментарии являются временными, и это может помочь другим с той же проблемой., @chrisl