I am a hardware design engineer trying to play with high-level-languages recently. These are my first Python codes. I am very far from OOP and all high-level-language shenanigans. I loved Python very much but I am at the very beginning of learning it. Thanks for your help in advance.
I am trying to read serial data from Arduino. This code is running on Raspberry Pi 3+. It doesn't read in the first loop.
Here is the Arduino code that sends dummy data upon request:
String data = "";
void setup(){
Serial.begin(115200);
}
void loop(){
while (Serial.available() > 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");
}
}
}
Here is the Python code that sends request and read the response from Arduino and write it into 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() > 0:
line = str(ser.readline().decode('ascii').strip()).split(",")
response_dict = dict(zip(responseKey, line))
return response_dict
If I write this: if len(request(channel[0], request_type[0])) > 0:
if statement, it waits for sometime and return the right response. But it waits for a long time.
while 1:
if counter < 2:
if len(request(channel[0], request_type[0])) > 0:
Write2DB(request(channel[0], request_type[0]))
else:
pass
counter += 1
else:
break:
If I do if counter < 1:
instead of if counter < 2:
, it doesn't return anything. So I think it is all about "not getting the response string on time"
This loop needed to loop many times:
while True:
if counter <3:
request(channel[0],request_type[0])
else:
break
If I change the sleep(2)
to sleep(1)
or a lesser value, it never reads the response from Arduino.
What I need is, reading the response from Arduino faster, in the first loop if it is possible without waiting more than 2-3 seconds. I've read the serial library documentation, but couldn't figure out what solves my problem.
I assume some kind of handshake between Python and Arduino will solve the problem but am not sure.
What do you recommend? What should I do?
Thanks again.
Changed timeout=0
to timeout=1
and it solved the problem.
ser = serial.Serial("/dev/cu.usbserial-1420", baudrate=115200, timeout=0)