1

I need to send an array of floating-point numbers from python to Arduino Mega. For that, I read many sources [this this this this this] this] and many more links for the same I referred. But unable to solve the problem.

I tried to send the angles to Arduino through python and return these values to python to print.

Below is the Python code in which I try to send the array named angle and tries to print the values received from Arduino.

import cv2
import numpy as np
import serial
import struct
import time

ser = serial.Serial('COM3', 9600, timeout = 1)
time.sleep(2)
if(ser.isOpen() == False):
    ser.open()
print('com3 is open', ser.isOpen())   

angle = [120.2,154.2,14.25]
ser.write(struct.pack('>fff', 10.5,11.9,48.2)) # B for interger and f for float
#ser.write(struct.pack('>f', angle)) # B for interger and f for float


time.sleep(2)
ser.flush()


data = ser.readline()
data = str(data.decode("utf"))
print(data)

ser.close()

Below is the Arduino code:

float f1; float f2; float f3; 

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);

Serial.println("Arduino is in parseFloat!");
}

void loop() {

  if (Serial.available() > 0)
  {
    d1 = Serial.parseFloat(); d2 = Serial.parseFloat(); d3 = Serial.parseFloat(); 

    ad = d1 +2.5;
    Serial.println(ad)
  }
delay(2000);
}

The error I got is: I got no error or warnings but there is no output also for the print commands as shown in below Figure. enter image description here

I need help to send the values to Arduino using python.

2
  • 2
    You seem to be sending binary instead of text. May 6, 2022 at 11:30
  • 2
    You aren't giving your Arduino time to reboot after opening the serial port and before sending it any data...
    – Majenko
    May 6, 2022 at 11:32

1 Answer 1

2

There are two things going on here.

First of all, if you look up the readline() method in Python that is referenced in the PySerial manual, you'll see the following:

readline(size=- 1, /)

Read and return one line from the stream. If size is specified, at most size bytes will be read.
The line terminator is always b'\n' for binary files; for text files, the newline argument to open() can be used to select the line terminator(s) recognized. 

In your program, you are actually sending more than one line back to serial port from the Arduino. The first line is the ASCII-encoded "Arduino is in ParseFloat!". The second one is the test float calculation. If you don't account for the fact you are expecting multiple "lines" from the serial port, you wouldn't see the test calculation, because you are not actually reading it. For encoded data, it states that the line ends at the '\n' char/digit (10).

Try it out change the "println" to "print" in your Arduino program and add another message either in the setup or the loop. Run your Python program. What do you see? Now change the "print" back to println". Run your Python program again. What do you see now?

Secondly, Edgar Bonet points out the second issue. The write() method in the PySerial API requires data to be a bytes array, but it's the way you are encoding it. It seems that the Arduino Serial class expects a ASCII-encoded byte-array, rather than a float byte-array (the floats encoded as a single-precision floating point number), which is what you are sending.

If you change your code to something like this (for example):

angle = [120.2,154.2,14.25]
ser.write(str(angle).encode('utf-8'))

you should be able to see your test calculation come back, granted that you read what I wrote in the first part of this answer.

1
  • By removing println, I successfully send and receive values. May 8, 2022 at 6:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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