I have been trying to send data to my Arduino Nano via a serial connection. The data is sent properly once I start sending data immediately after initialising. However, if there is a pause in sending data, it stops sending properly.
This is my Python code. I created it for debugging:
import serial
import time
port = 'COM6'
baudrate = 9600
# Open the serial connection
ser = serial.Serial(port, baudrate)
time.sleep(3)
data_to_send = "hello, world~"
# Encode data as bytes (optional for some data types)
data_bytes = data_to_send.encode('utf-8') # Encodes string to bytes
while True:
# Send data to Arduino
ser.write(data_bytes)
data = ser.readline()
print("data", data)
print(f"Data sent: {data_to_send}")
This is the Arduino code:
#include <Servo.h>
bool newData = false;
char receivedChars[64];
void setup() {
// Motor control pins as outputs
Serial.begin(9600);
delay(1000); // Give the serial connection time to initialize
Serial.println("READY");
}
void loop() {
static byte ndx = 0;
char endMarker = '~';
char rc;
while (Serial.available() && newData == false) {
rc = Serial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
} else {
// receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
Serial.println(receivedChars);
Now if I remove time.sleep(3)
from the Python code, it keeps sending data immediately after the port has been initialised. The output looks something like this:
Data sent: hello, world~
data b'hello, world\r\n'
Data sent: hello, world~
data b'hello, world\r\n'
Data sent: hello, world~
data b'hello, world\r\n'
Data sent: hello, world~
data b'hello, world\r\n'
Data sent: hello, world~
data b'hello, world\r\n'
However, when time.sleep(3)
is present in the code, this is the output:
Data sent: hello, world~
data b'\r\n'
Data sent: hello, world~
data b'\r\n'
Data sent: hello, world~
data b'\r\n'
Data sent: hello, world~
data b'\r\n'
I have tried setting the timeout parameter to a large value or to None
but that doesn't help either.
From what it looks like, the while loop (that starts with while (Serial.available() > 0…
) is exiting early while the python sending program is sleeping, as @timroberts pointed out.
But since you’ve put the serial print call after the while loop, the loop ends and the Arduino ends up spamming the computer’s serial receive buffer with \r\n
over and over until it’s full.
So I can see two solutions:
Serial.println
if ndx
is zero.ser.reset_input_buffer()
immediately before the while loop to wipe the buffer and get fresh data when the loop starts.