2

I'm trying to establish basic communication between python and my arduino due. I have managed to get a message sent to the arduino and sent back, but the code that achieves this task does not give consistent results. I'm running python 3.5 with pyserial 3.3.

My Arduino Code:

String incoming;

void setup() {
        Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {

        // send data only when you receive data:
        if (Serial.available() > 0) {
                // read the incoming byte:
                incoming = Serial.readStringUntil('\n');

                // say what you got:
                Serial.print("I received: ");
                Serial.println(incoming);
        }
}

My Python Code

import serial

arduinoSerialData = serial.Serial("COM5",9600,timeout=1)

print("Initial in waiting:")
print(arduinoSerialData.in_waiting)
print("Initial out waiting:")
print(arduinoSerialData.out_waiting)

while (arduinoSerialData.in_waiting>0):
    garbage = arduinoSerialData.readline()
    print(garbage)

nummessages =0

while (nummessages<5):
    if (arduinoSerialData.in_waiting>0):
        myData = arduinoSerialData.readline()
        myData = myData.decode('utf-8')
        myData = myData.strip()
        print("The Arduino says:")
        print(myData)
        nummessages=nummessages+1
    elif(arduinoSerialData.out_waiting>0):
        pass
    else: 
        arduinoSerialData.write(b'Hello Arduino!\n')

while (arduinoSerialData.in_waiting>0):
    garbage = arduinoSerialData.readline()
    print(garbage)

print("In Waiting: ")
print(arduinoSerialData.in_waiting)
print("Out Waiting: ")
print(arduinoSerialData.out_waiting)
arduinoSerialData.close()

These print statements are largely my failed attempt to diagnose the problem. The "garbage" loops were my attempt to make sure conditions were as identical as possible when the python code starts up. If I start the arduino program running and then call this python program from my command line I get inconsistent results. Sometimes my first call to the python "works" and then others won't, sometime it works several times in a row, and that first line out output where it says "The Arduino Says: I" will have a varying amounts of the "I Received: Hello Arduino" message the arduino was supposed to send. Any Ideas what could be causing this lack of consistency? If I try starting the python code first, the arduino can't even start up.

enter image description here

  • Why are you trying to utf-8 decode the data? Life will probably be simplest if you throw away or substitute anything that isn't an ASCII character and then print what you have. – Chris Stratton Jul 19 '17 at 20:42
  • I mostly just tried that because similar examples used that as a translation tool. If I comment out the decode() and strip() lines then the program seems to always function, except that the first line is erratic. The number of characters varies, and it sometimes has \xff at the end. I'm assuming these cases are the ones that broke the decoder in the original question. I can look for a different way to go from b'text\r\n' to 'text' to try deal with this. I'll try to add a picture in the main question for clarity. – cpoole Jul 19 '17 at 21:24
  • Please don't use pictures. – Chris Stratton Jul 19 '17 at 21:26
  • Likely this should be a Stackoverflow question (or search for existing answers) on how to pull the printable characters out of a buffer containing (mostly but not entirely) legacy ASCII. – Chris Stratton Jul 19 '17 at 21:26
3

In case other people run into similar issues, I'll lay out what I've found today.

-The inconsistent output was due to the fact that when you open a serial connection with python, it resets the Arduino and so python can send signals without the arduino having finished its setup() function. If I put in a 1 second delay on the python side, inconsistency stops and I no longer run into byte errors at all. I'm looking into alternative means of preventing this reset since the time delay is a deal-breaker for me.

UPDATE: Replacing

arduinoSerialData("COM5",9600,timeout=1)

with

arduinoSerialData = serial.Serial()
arduinoSerialData.port = "COM5"
arduinoSerialData.baudrate = 9600
arduinoSerialData.timeout = 1
arduinoSerialData.setDTR(False)
#arduinoSerialData.setRTS(False)
arduinoSerialData.open()

seems to bypass the reset. I included both the setDTR and SetRTS functions here because although setDTR works for DUE, it seems some other Arduino boards need setRTS instead.

-The decode() function has a keyword argument called errors, which can be set to "ignore" if you want the code to just ignore things that can't be interpreted in your desired format. With just this keyword setup, I never got errors but output was inconsistent due to reset.

  • Sounds like the ignore errors option basically gives you the noise filter. Good call on the reset thing - was just thinking about that in context of another question. – Chris Stratton Jul 19 '17 at 23:42
  • This sis not fix the same issue I had with Duo. The delay did help though. – SaTa Oct 12 '19 at 19:21
0

Problem:

Arduino being a microcontroller ( not a microprocessor ), is not efficient enough. If noticed carefully, messages sent to the Serial monitor gets overlapped if the time interval between 2 messages is less than half a second !! Also, there is an equal possibility of overlapping of data from Arduino resulting in garbage data !!


Solution:

To overcome these, python modules named Arduino_Master and Arduino_Master_Delta are available.

These modules also help you to visualize data in the form of graphs as well as filter data and remove garbage values.

Arduino_Master is used for approximation and easier interface whereas Arduino_Master_Delta is used for accurate data representation!


Links:

Links to their documentation is given below :

Arduino_Master

Arduino_Master_Delta


Examples:

The code for all these can be found in Arduino_Master_Delta 's documentation.

Lights

Impulse_Detection

Impulse_Removal

  • I have never noticed an issue of attempting to send distinct messages too quickly causing issues with Python. I was not utilizing the Serial Monitor. The problem I was encountering was definitely caused by the Arduino resetting the program when a Serial connection was opened by Python, as detailed in my self-answer. – cpoole Jun 17 '19 at 19:33

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.