Arduino will not read three successive packets in the serial connection

I am trying to send serial commands from Python to the Arduino Micro. This is my code for both:

Python

import serial

ser = serial.Serial('COM5', 9600)

ser.write(b'0')
ser.write(b'1')
# ~ ser.write(b'2')

print('done')

Arduino

void setup()
{
  Serial.begin(9600);
  delay(10000);
}

void loop()
{

  while (!Serial.available()){}
  Serial.println(Serial.read()-48); 
 
}

I can't send data from Python and view the serial monitor in Arduino at the same time, so I added a 10 second delay to the Arduino start up. This gives me enough time to execute the Python script, close the serial connection, and start up the Arduino serial monitor.

If I keep the ser.write(b'2') line in the Python code commented out, the code executes nearly instantly, and I am able to see both transmissions in the serial monitor. If I uncomment it, the Python code takes about 5-7 seconds to execute, and none of the data comes through the serial monitor.

I've tried different baud rates but that hasn't helped. I've also tried sending an integer rather than b'#', and the same thing happens, no data is transmitted if I have all 3 serial commands active.

What is happening in my code? Is the serial buffer overloaded by the 3 successive writes and the buffer ends up flushing?

Thanks

secretempire1:
If I uncomment it, the code takes about 5-7 seconds to execute, and none of the data comes through the serial monitor.

Which code? Python?

Because I don't see how the Arduino code can take significant longer.

Sorry yes, the Python code takes longer to run (updated original post to clarify).

Have a look at this simple Python - Arduino demo

Send your three values as a single message like <valA, valB, valC> and then they won't get mixed up.

Also look at the parse example in Serial Input Basics

...R

You are sending stuff to the Arduino but the Arduino has its fingers in its ears during the delay().

There is a small Serial buffer on the Arduino which is able to accept a few characters during that time but it is not intended to store a lot of data.

Also check that the Arduino is not being reset by the Serial Monitor. Make it turn on the LED during the delay. Check it does not come on when Serial Monitor opens.

Robin2:
Have a look at this simple Python - Arduino demo

Send your three values as a single message like <valA, valB, valC> and then they won't get mixed up.

Also look at the parse example in Serial Input Basics

...R

Thanks Robin, I'll check it out!

MorganS:
You are sending stuff to the Arduino but the Arduino has its fingers in its ears during the delay().

There is a small Serial buffer on the Arduino which is able to accept a few characters during that time but it is not intended to store a lot of data.

Also check that the Arduino is not being reset by the Serial Monitor. Make it turn on the LED during the delay. Check it does not come on when Serial Monitor opens.

But wouldn't any problems imposed by the delay() and by opening the serial monitor be present for both 2 ser.write commands as well as 3? I don't know why this problem would only occur with 3 ser.write commands.

I can't send data from Python and view the serial monitor in Arduino at the same time, so I added a 10 second delay to the Arduino start up. This gives me enough time to execute the Python script, close the serial connection, and start up the Arduino serial monitor.

You are aware that opening the Serial Monitor application resets the Arduino, right?

PaulS:
You are aware that opening the Serial Monitor application resets the Arduino, right?

I am now :slight_smile:

But why would I only receive this problem when I'm writing 3 times, and not 2?

secretempire1:
I am now :slight_smile:

But why would I only receive this problem when I'm writing 3 times, and not 2?

When you open the serial port, using the Serial Monitor app or using the Python script, the Arduino resets. There is, immediately upon reset, a period of time where the bootloader is listening for a new script to be uploaded. It is remotely possible that the data that you are sending it is recognized by the bootloader, for the first two bytes, but the third causes the bootloader to decide that it is not a new sketch being uploaded.

PaulS:
When you open the serial port, using the Serial Monitor app or using the Python script, the Arduino resets. There is, immediately upon reset, a period of time where the bootloader is listening for a new script to be uploaded. It is remotely possible that the data that you are sending it is recognized by the bootloader, for the first two bytes, but the third causes the bootloader to decide that it is not a new sketch being uploaded.

Hi Paul, so how can I verify that the Arduino is receiving all of the data? Should I send the characters to the Arduino, have it capture them, and then send them back to Python, which can read them out?

The Micro has a second serial port. With an FTDI or any other USB-to-serial converter, you can have the Micro tell you directly what it is doing.

If you didn't have that extra port, SoftwareSerial can be used, or just flash lights to indicate what was received.

Note that you don't want a USB-to-RS232 converter. Unless you have a Serial to RS232 converter too.

secretempire1:
Hi Paul, so how can I verify that the Arduino is receiving all of the data? Should I send the characters to the Arduino, have it capture them, and then send them back to Python, which can read them out?

Have you tried the examples in the link I gave you. I would be very surprised if there is any doubt about the data being received.

If you want to add belt-and-braces (belt-and-suspenders in the USA) you can include a check byte in your data and if the Arduino does not calculate the same value as the check byte it will know there is a problem. However the problem you expressed in your Original Post does not need check bytes - it just needs robust code.

...R

MorganS:
The Micro has a second serial port. With an FTDI or any other USB-to-serial converter, you can have the Micro tell you directly what it is doing.

If you didn't have that extra port, SoftwareSerial can be used, or just flash lights to indicate what was received.

Note that you don't want a USB-to-RS232 converter. Unless you have a Serial to RS232 converter too.

I saw the TX/RX port on the board but never thought to use it XD. I'll have to look more into that FTDI, since I've never worked with one before. But flashing the lights is also a really simple way, I'll probably just do that. Thanks.

Robin2:
Have you tried the examples in the link I gave you. I would be very surprised if there is any doubt about the data being received.

If you want to add belt-and-braces (belt-and-suspenders in the USA) you can include a check byte in your data and if the Arduino does not calculate the same value as the check byte it will know there is a problem. However the problem you expressed in your Original Post does not need check bytes - it just needs robust code.

...R

Hi Robin, I do plan on perusing that when I get home. Right now I'm just making the occasional post in between meetings at work.