2

I use a RPi 3b to request and receive float values over serial from an Arduino Nano (fake). For that I use python and pyserial.

Arduino Loop:

if (Serial.available() > 0) {
    String req = Serial.readStringUntil('\n');
    if (req == "co2") {
        double adjustedCO2 = myMHZ19.getCO2Raw();
        Serial.println(adjustedCO2, 2);}
    else if (req == "hum") {   
        Serial.println(bme.humidity);}
}

RPi Request:

def read_data(command): 
    req = command + "\n"
    ser.write(req.encode())
    line = ser.readline(100).decode('utf-8').rstrip()
    return float(line)
    
#main   
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
ser.flush()
time.sleep(2) #time to open up the serial connection
co2 = read_data("co2")
humidity = read_data("hum")

It works well for some time, but after a while (days/hours) my read_data() function returns only None. A reboot helps but I want to avoid that.

What am I missing? Do I need some timeouts? Is there a way to reset my serial port without rebooting?

2
  • It would be interesting to hear from people who voted to close, how did they deduce the problem was not Pi-specific. Jun 6 at 19:32
  • 1
    To me it seemed like the pi was the problem. Because rebooting the pi helped temporarily while resetting the Arduino didn't.
    – Razorneck
    Jun 6 at 21:19
2

Yes, there is a way to reset the serial port, by closing it and opening it again. This will also reset the Arduino.

However, I would rather try to understand what's wrong with the communication. You already have a timeout which should apply to all read/write operations.

Print raw strings (make sure you can distinguish strings with and without \n) which you send and receive from the UART inside read_data(). Then wait for the issue to happen and check how the communication looks on RPi side.

One thing I would try to avoid is using dynamic objects on Arduino. The String req object gets repeatedly created and destroyed, which could potentially result in memory fragmentation and lead to a situation where no new objects could be created until you reset. I'm not sure it's the root cause (req is tiny, even for Arduino) but it may be not the only dynamic object in your code.

2
  • 1
    I adjusted my Arduino Code accordingly. But the error was still there. Then I replaced the Arduino with a new one and now everything works again (for 2 days so far). I used the old one for half a year and requested data every minute. Could the dyn object or frequent request wear off my Arduinos serial port?
    – Razorneck
    Jun 6 at 16:16
  • 1
    @Razorneck No, you can't "wear off" a serial port. You can have a buggy Arduino though, and it's possible that the bugs become more pronounced with age due to worse voltage stabilization for instance. Jun 6 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.