Electronic – arduino – Python serial between Arduino and Raspberry Pi: Data is modified upon reception

arduinopythonraspberry piserial

I'm using an Arduino for sensor readings and sending them to a Raspberry Pi via USB, using PySerial for data reception.

It works great, except for the fact received data is awkwardly modified (And set as constant). For example, I'm reading voltages and calculating currents. The results on the Arduino serial are as follows:

Volt   Current
4.93   0.38
4.92   0.37
4.92   0.37
4.92   0.36
...    ...

However, on the Raspberry Pi, it's constantly read as follows (Notice how the digits are changed to zero):

  Volt   Current
    4.99   0.30
    4.99   0.30
    4.99   0.30
    4.99   0.30
    ...    ...

I've tried several turnarounds, but with no luck. I'm not sure where the problem lies, as I am very confident my code is flawless. I even converted the readings to string before sending and yet the constant readings and zero'd digits keep appearing. I appended a counter integer which was sent correctly with no problems.

Has anyone ever tried this before? Any thoughts on how to solve this?

Raspberry Pi Code:

from time import gmtime, strftime
import time
import serial
import struct
ser = serial.Serial('/dev/ttyACM1', 19200)
f = open('results.txt','w')

while 1:
        temp=strftime("%Y-%m-%d %H:%M:%S", gmtime())+'\t'+ser.readline()
        print(temp)
        f.write(temp)
        f.close()
        f = open('results.txt','a')
        time.sleep(5)

Arduino Code:

...

  double volt = 5.0*(analogRead(A0))/1023.0;

  double current = 5.18 - temp;   //Resistance ~= 1 Ohm if you are wondering

  buffer += d2s(volt,2)+'\t'+d2s(current,2)+'\t'+ d2s(count,0) +'\t' + d2s(minCount,0);

  Serial.println(buffer);

...

//I got this from the web

String d2s(double input,int decimalPlaces){

  String string;

  if(decimalPlaces!=0){
    string = String((int)(input*pow(10,decimalPlaces)));

       if(abs(input)<1){
          if(input>0)
              string = "0"+string;
          else if(input<0)
              string = string.substring(0,1)+"0"+string.substring(1);
  }

  return string.substring(0,string.length()-
decimalPlaces)+"."+string.substring(string.length()-decimalPlaces);
}

   else {
     return String((int)input);

}
}

Best Answer

The arduino is not well suited to doing floating point math, nor is it partiularly well suited to doing string manipulation.

You would be better off by sending the value read from the analog input directly to the python code on the Pi and do the math and string manipulation in Python.

On the arduino side just do something like this:

int value;

value = analogRead(A0); // reads a 12bit integer value from the Analog input
Serial.println(value);  // converts the integer to a string and sends it over the serial port

Then on the Pi side:

str = ser.readline()  # read a string from the serial port

value = float(str)    # convert a string to a floating point number

volt = 5.0 * value / 1023.0  # compute the voltage