Using serial with arduino and python, cannot read propper data from adruino

Hey everyone,

I am starting a project with arduino and python. My current task is to just to communicate over serial from my python program to my arduino and back.

I believe i am writing the data correctly but am unsure since the data i get back from the arduino is the print out, b ' ', where i am only sending "1" and should be returning that a string that states "serial available, X\n", where X is a string of the data sent from the python program.

I have tried using serial.read and serial.readline and both have the same outcome.

Looking at examples on the website i do not see what i am doing wrong. Though my serial interface is in a class on the python side of things.

Arduino code

#define BAUD_RATE 115200
#define MSG_BUFF 256
#define S_IN_BUFF 10 // serial input buffer size

uint8_t serial_in[S_IN_BUFF] = {'\0'};
char serial_msg[MSG_BUFF] = {'\0'};

void setup()
{
    Serial.begin(BAUD_RATE);
    while (!Serial) {} // wait for serial interace to connect
    Serial.setTimeout(1);
}

void loop()
{
    int i = 0;
    int num_recv = 0;
    if (Serial.available()) {
        num_recv = Serial.readBytes(serial_in, S_IN_BUFF-1); // room for '\0'
        serial_in[num_recv] = '\0';
        sprintf(serial_msg, "serial available, %s\n", serial_in);
        Serial.print(serial_msg);
    }
}

Python code

import serial
import time

class arduino_com:

    def __init__(self, port, baudrate, rtimeout, encoding):
        self.port = port
        self.baudrate = baudrate
        self.rtimeout = rtimeout
        self.arduino = 0 # will be serial object
        self.encoding = encoding

    def begin(self):
        self.arduino = serial.Serial(port=self.port, baudrate=self.baudrate,
                                     timeout=self.rtimeout);
    def write(self, msg, delay=0.05):
        self.arduino.write(bytes(msg, self.encoding)) 
        time.sleep(delay)

    def read(self):
        return self.arduino.read()

    def read_line(self):
        return self.arduino.readline()

Python main

from arduino_serial import arduino_com

BAUD_RATE = 115200
SERIAL_PORT = "/dev/ttyACM0"
RTIMEOUT = 0.1 # read serial timeout
ENCODING = "utf-8"

if __name__ == "__main__":
    arduino_serial = arduino_com(SERIAL_PORT, BAUD_RATE, RTIMEOUT, ENCODING)
    arduino_serial.begin()
    arduino_serial.write("1")
    print(arduino_serial.read_line())

Any suggestions would be appreciated.

Also it happens with anything i send, "1" or "x" etc. the printout is b ' '

The issue is with your Python code. When I run your Arduino sketch with this simple python keyboard send a message to Arduino and read the reply I can see the Arduino code you wrote echo the received message.

import serial  
import time  

ArduinoSerial = serial.Serial('COM6',115200, timeout = 2) #timeout for response on readline()
time.sleep(2) #allow time for serial port to open

while True:
 print ("enter message for Arduino")
 var = input()# get input from user
 print ("you entered", var )# print the input for confirmation
 ArduinoSerial.write(var.encode())#send to Arduino
 #read echo back from arduino to verify receipt of message
 data = ArduinoSerial.readline() #the last bit gets rid of the new-line char
 if data:
    print("received message back from Arduino")
    print (data.decode())
 time.sleep(1)

You can simplify things by using proven libraries to communicate between Arduino and Python: pySerialTransfer and SerialTransfer.h.

SerialTransfer.h can be installed via the Arduino IDE's Libraries Manager and pySerialTransfer is pip-installable. Both libraries come with a plethora of examples.

Thanks for the reply, ill look into my python code more closely then. Appreciate the effort on the simple python program.

I still could not get the code i wrote to work but found out what was going on, kind of.

It does not work the first time. I have to put the python code in a while loop like the example from cattledog. Once i run it twice in one program run, it works just fine.

Anyone have any idea how to stop this? it happens with the sample code as well. The first loop, nothing, second loop and on is good.

Sometimes it does not work the second time through as well. But have not seen it fail 3 times in a row. After it starts working it seems to be fine.

A number of Arduinos reset when you open the serial port. The reset results in the bootloader being invoked which runs for a few seconds; whatever you send in those few seconds will be lost.

You can add a delay in your python code after opening the serial port. Or better, let the Arduino send something and check in pythos if you received the correct message before sending data to teh Arduino.

1 Like

Or (as I have done in the past on FINISHED projects)... you can add a CAP to the Arduino to bypass the 'reset'..

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.