Python serial.read() не считывает данные с Arduino в первом цикле

#python #arduino #raspberry-pi #raspberry-pi3 #pyserial

#питон #arduino #малина-пи #малина-pi3 #писериал

Вопрос:

Я инженер-проектировщик аппаратного обеспечения, в последнее время пытаюсь играть с языками высокого уровня. Это мои первые коды на Python. Я очень далек от ООП и всех языковых махинаций высокого уровня. Я очень любил Python, но я нахожусь в самом начале его изучения. Заранее спасибо за вашу помощь.

Я пытаюсь считывать последовательные данные с Arduino. Этот код работает на Raspberry Pi 3 . Он не читается в первом цикле.

Вот код Arduino, который отправляет фиктивные данные по запросу:

 String data = ""; void setup(){    Serial.begin(115200); }   void loop(){    while (Serial.available() gt; 0) {  data = Serial.readStringUntil('n');  if(data=="$ACONSP?"){  Serial.println("$ACONSP,3600,100,100,200,300,400,500,600,700");  }  else if (data == "$ASTAT"){  Serial.println("$ASTAT,0,1,0,0,1,0,1,0");  }  else if (data == "$AENV"){  Serial.println("$AENV,234.2,49.3,27.7,41.6,24.9,39.9,0,0");  }  } }  

Вот код Python, который отправляет запрос, считывает ответ с Arduino и записывает его в SQLite.

 from time import sleep import serial  PowerResponseKeys = ['head','timePassed','Ch0Consp','Ch1Consp','Ch2Consp','Ch3Consp','Ch4Consp','Ch5Consp','Ch6Consp','Ch7Consp'] StatusResponseKeys = ['head','Ch0Stat','Ch1Stat','Ch2Stat','Ch3Stat','Ch4Stat','Ch5Stat','Ch6Stat','Ch7Stat'] EnvironmentResponseKeys = ['head','Voltage','Frequency','InTemp','InHumidity','ExtTemp','ExtHumidity','DoorSwitch','DoorRelay'] channel = ["A","B","C"] request_type = ["CONSP?", "STAT", "ENV"] ser = serial.Serial("/dev/cu.usbserial-1420", baudrate=115200, timeout=0) counter = 0  #The function that sends the "requestline= "$" channel request_type" string to Arduino and read the response def request(channel,request_type):  line = ''  responseKey = []  requestline= "$" channel request_type  if request_type == 'CONSP?':  responseKey = PowerResponseKeys  elif request_type == 'STAT':  responseKey = StatusResponseKeys  elif request_type == 'ENV':  responseKey = EnvironmentResponseKeys  else:  pass  ser.write(requestline.encode())  sleep(2)  if ser.inWaiting() gt; 0:  line = str(ser.readline().decode('ascii').strip()).split(",")  response_dict = dict(zip(responseKey, line))  return response_dict   

Если я напишу это: if len(request(channel[0], request_type[0])) gt; 0: оператор if, он подождет некоторое время и вернет правильный ответ. Но это ждет еще долго.

 while 1:  if counter lt; 2:  if len(request(channel[0], request_type[0])) gt; 0:  Write2DB(request(channel[0], request_type[0]))  else:  pass  counter  = 1  else:  break:    

Если я сделаю if counter lt; 1: это вместо if counter lt; 2: этого , это ничего не вернет. Поэтому я думаю, что все дело в том, чтобы «не получить строку ответа вовремя».

Этот цикл нужно было повторять много раз:

 while True:  if counter lt;3:  request(channel[0],request_type[0])  else:  break  

Если я изменю значение sleep(2) на sleep(1) или на меньшее, он никогда не прочитает ответ от Arduino.

Что мне нужно, так это прочитать ответ от Arduino быстрее, в первом цикле, если это возможно, не дожидаясь более 2-3 секунд. Я прочитал документацию по серийной библиотеке, но не смог понять, что решает мою проблему.

Я предполагаю, что какое-то рукопожатие между Python и Arduino решит проблему, но не уверен.

Что вы рекомендуете? Что мне следует делать?

Еще раз спасибо.

Комментарии:

1. новое USB-соединение сбрасывает некоторые Arduino, и Arduino затем ждет несколько секунд в загрузчике для загрузки

2. Как я могу проверить, так ли это на самом деле? Я использую Arduino Nano, Arduino 328P (старый загрузчик) Хм, там написано старый загрузчик. Позвольте мне попробовать с другим и вернуться.

3. Nano сбрасывается при новом USB-подключении. не имеет значения, какой загрузчик или какой-либо другой. схема автоматического сброса находится на USB-чипе. новый загрузчик (Optiboot) ожидает более короткого времени для загрузки (потому что установлен для автоматического сброса, а не для ручного сброса пользователем)

4. @Juraj спасибо, я этого не знал. Я попробую с обычной настройкой.

5. @Juraj не сработал. Кроме того, поскольку я устанавливаю его на пользовательскую плату без USB-чипа, у меня все еще возникают проблемы. Данные, которые я читаю, не очень хороши в первые пару секунд. Я открою новый вопрос с подробностями и поделюсь ссылкой здесь.

Ответ №1:

Изменился timeout=0 на timeout=1 , и это решило проблему.

 ser = serial.Serial("/dev/cu.usbserial-1420", baudrate=115200, timeout=0)