I have an Arduino pumping out the characters 0 - 9 through a serial port
void setup() {
Serial.begin(9600);
}
void loop() {
for(int i = 0; i < 10; i++){
Serial.print(i);
delay(200);
}
}
I'm using the following Python code to recieve the data on a PC,
import serial
usbport = 'COM3'
ser = serial.Serial(usbport, 9600, timeout=1)
count = 0
while ser.in_waiting < 1 and count < 5:
p = ser.read(10)
p = p.decode()
print(p, type(p))
count += 1
ser.close()
The Arduino will reset whenever a serial communication is initiated (which is fine in this case) but I've notced that the Python code always picks up an empty byte prior to reading the serial data.
Example output,
<class 'str'>
0123456789 <class 'str'>
0123456789 <class 'str'>
0123456789 <class 'str'>
0123456789 <class 'str'>
It always does this, anybody know why?
Also for a bonus point, can anyone tell me why I have to put while ser.in_waiting < 1
to get this to work & not just while ser.in_waiting
?
The empty byte is because of the connecting with the serial port. Also generally, it would be much better if you add some code to your arduino, such that it starts the process when a command is sent:
void setup() {
Serial.begin(9600);
}
void loop() {
// Wait for a command from the serial port
while (!Serial.available()) {
// Do nothing until a command is received
}
// Read the command from the serial port
String command = Serial.readStringUntil('\n');
// Check if the received command is "start"
if (command == "start") {
// Start sending numbers 0-9
for (int i = 0; i < 10; i++) {
Serial.print(i);
delay(200);
}
}
}
In this case, when you write "start\n".encode()
to the arduino port, it will start the process of looping, once.
Furthermore, I usually flushInput and flushOutput before using the port, specifically to avoid such things:
usbport = 'COM3'
ser = serial.Serial(usbport, 9600, timeout=1)
time.sleep(1) # sleep to give enough time for the arduino to initialize
ser.flushInput() # flush input
ser.flushOutput() # flush output
And now, you can use your code, with the addition of writing the command:
count = 0 # init count
ser.write("start\n".encode()) # write the command to start
while ser.in_waiting < 1 and count < 5:
p = ser.read(10)
p = p.decode()
print(p, type(p))
count += 1
ser.close()
Also, regarding your last question, using ser.in_waiting < 1
, you are cchecking if there is less than one byte in the input buffer, which is equivalent to checking if the buffer is empty. I.e. it would be much more explicite if you just check !ser.in_waiting
.