3

I am trying to read potential meter data from Arduino using python, with the program on Arduino as follows :

#include <cvzone.h>

SerialData serialData;
int sendVals[2];

void setup() {
  serialData.begin(9600);
}

void loop() {
  int potVal = analogRead(A0);
  sendVals[0]= potVal;
  serialData.Send(sendVals);
}

the program on the arduino side is running fine

and program in python as follows

from cvzone.SerialModule import SerialObject

arduino = SerialObject("COM7")

while True:
   data = arduino.getData()
   print(data[0])

but I get this error:

Traceback (most recent call last):
    data = arduino.getData()
  File "C:...\site-packages\cvzone\SerialModule.py", line 68, in getData
    data = data.decode("utf-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf7 in position 0: invalid start byte

How to solve it?

Greenonline
  • 2,844
  • 7
  • 31
  • 46
  • the new USB connection resets the Mega and it spends some time in bootloader waiting for upload. – Juraj Dec 06 '21 at 13:32
  • Maybe add some delay on the Arduino after initializing the serialData in `startup()` before it starts sending data in the `loop()`. – Dave X Dec 06 '21 at 14:45

2 Answers2

2

I would embed the call to .getData() into a try block and handle this specific exception with except UnicodeDecodeError. There can always be a transmission error, especially when the script is started.

However, I would do it differently:

void loop() {
  Serial.println(analogRead(A0));
}

...and on the python side use serial.readline() from pyserial instead. But I don't know cvzone and you might have a reason to use this instead of the commonly used pyserial.

Sim Son
  • 1,809
  • 9
  • 18
0

There seems that there may be an issue with the implementation of getData() in SerialModule.py.

From line 62

    def getData(self):
        """
        :param numOfVals: number of vals to retrieve
        :return: list of data received
        """
        data = self.ser.readline()
        data = data.decode("utf-8")
        data = data.split('#')
        dataList = []
        [dataList.append(d) for d in data]
        return dataList[:-1]

The block of code containing the readLine() should probably be with in a try...except block, like so:

    def getData(self):
        """
        :param numOfVals: number of vals to retrieve
        :return: list of data received
        """
        try:
            data = self.ser.readline()
            data = data.decode("utf-8")
            data = data.split('#')
            dataList = []
            [dataList.append(d) for d in data]
            return dataList[:-1]
        except Exception as e:
            print(e)
            self.ser.close

An issue has been raised on Github: SerialModule.py - readLine() should be within try block. #49

Greenonline
  • 2,844
  • 7
  • 31
  • 46