I connected my arduino uno to my system and then using serial tried writing and reading data but there is a problem which I found when I tried giving arduino crafted messages. My arduino code is pretty simple.
void setup() {
Serial.begin(115200);
}
void loop() {
if (Serial.available() > 0) {
String data = Serial.readStringUntil('\n');
Serial.print(" You sent me: ");
Serial.println(data);
}
}
and my python code on my system
#!/usr/bin/env python3
import serial
import time
if __name__ == '__main__':
ser = serial.Serial('/dev/ttyACM0', 115200, timeout=1)
ser.flush()
while True:
string=input("Enter the string: ")
ser.write(str.encode(string))
line = ser.readline().decode('utf-8').rstrip()
print(line)
time.sleep(0.01)
Now this gives me ability to write instructions to my arduino but following sequences of communication occur
└──╼ $python3 serial_communication.py
Enter the string: a
Enter the string: v
Enter the string: v
You sent me: v
Enter the string: s
You sent me: v
Enter the string: d
Enter the string: r
You sent me: sd
Enter the string: d
You sent me: r
Enter the string: s
Enter the string: e
You sent me: ds
Enter the string: r
You sent me: e
Enter the string:
Looking at them I understand that this might be a problem with my code or I am using the wrong protocol.
1 Answer 1
There's a number of things going on here that combined give you the results you're seeing.
First off there's the delay at the start:
Enter the string: a
Enter the string: v
Enter the string: v
You sent me: v
Enter the string: s
You sent me: v
This is because when you first open the serial port the Arduino resets and enters the bootloader. Thus the first few things that get sent are discarded, and nothing is sent back from the Arduino - your sketch just isn't running at that point.
Next is the format of what you're sending compared to how you're receiving it.
You input a string and then send that string verbatim. But on the Arduino you are reading all data up until a terminating newline character, which you are not sending.
But the reading function also has a timeout in it so it will return whatever it has managed to read in that time even if the terminator hasn't arrived. That timeout is 1 second by default.
So everything that gets sent within a 1 second window gets grouped together, which is what you see here:
Enter the string: d
You sent me: r
Enter the string: s
Enter the string: e
You sent me: ds
The "out of sync" appearance is because of that 1 second timeout - you are seeing what was sent a second ago.
The fix is simple enough: make sure that you send the terminating newline character from Python:
ser.write(str.encode(string + "\n"))
And wait a few seconds after starting your program and opening the serial port before asking for anything to be sent. Maybe add a time.sleep(2)
after opening the port to enforce that delay.
-
Thank you for the answer. This really helps as my target was something else to get to work but as this is the starting point I did not want my concepts to get messed up.Ritesh Sharma– Ritesh Sharma2021年03月30日 13:30:55 +00:00Commented Mar 30, 2021 at 13:30
input()
function does not preserve the terminating\n
.