[Solved]Serial.write sending wrong values. [Python] [Serial.write()]

Hi,
So I’m using i2c with the ADXL345 Accelerometer. Everything seems to be working fine until I send the values over Serial.write(), If you look at the result below i end up with 5*10^74 g’s which seems like a bit much. Anyways, if anyone have any advice I would love to hear it.

Python Code:

        timeout = time.time() + 5
        while time.time() < timeout:
            x_vec.append(self.port.read(4))
            y_vec.append(self.port.read(4))
            z_vec.append(self.port.read(4))               
        
        self.port.write('a') #tell Arduino to Stop Sending         
        for i in range(len(x_vec)):
            x.append(struct.unpack( '<f' , x_vec[i]))
        for i in range(len(y_vec)):
            y.append(struct.unpack( '<f' , y_vec[i]))
        for i in range(len(z_vec)):
            z.append(struct.unpack( '<f' , z_vec[i]))
        
        
        for i in range(len(z_vec)):
            total.append( np.multiply(x[i],x[i]) + np.multiply(y[i], y[i]) + np.multiply(z[i],z[i]) )
        
        print("reading")  
           
        self.port.flush()
        
        print("finish Reading")
         
        fig = pl.figure(figsize= (4.25,4))
        pl.title('G / Samples')
        pl.plot(total)
        
        fig.savefig('plot.png')
        self.image_icon.set_from_file("plot.png")

Arduino

void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; 
  accel.getEvent(&event);
  if(record == true){
    x.floatingPoint = event.acceleration.x;
    y.floatingPoint = event.acceleration.y;
    z.floatingPoint = event.acceleration.z;
    x.floatingPoint = x.floatingPoint/9.81;
    y.floatingPoint = y.floatingPoint/9.81;
    z.floatingPoint = z.floatingPoint/9.81;
    //Serial.print(t);Serial.print("\n");
    Serial.write(x.binary, 4);
    Serial.write(y.binary, 4);
    Serial.write(z.binary, 4);
  }
}

Result:

Please post your code.

Hey, I'm new to the form are you unable to see my Python Code and Arduino Code Boxes?

I can see a coup!e of snippets, if that's what you mean.

Okay, here is all the arduino code and that is the only python function that deals with reading. I’m using the PySerial library. Let me know if a can post anything else.

Python:

    def on_buttonClick_runTest(self, button):
        self.console_buffer.insert(self.console_buffer.get_end_iter(), 
                                       "\n Beginning Test..")    
        
        x = []
        y = []
        z = []
        
        x_vec = []
        y_vec = []
        z_vec = []
        
        total  = []
    
        t = []
        tv = []
        self.port.write('b')
        self.console_buffer.insert(self.console_buffer.get_end_iter(), 
                                       "\n Starting Test") 
        self.port.flush()
        print("Starting")
        timeout = time.time() + 5
        
        while time.time() < timeout:
            x_vec.append(self.port.read(4))
            y_vec.append(self.port.read(4))
            z_vec.append(self.port.read(4))
           
        self.port.write('a')
        for i in range(len(x_vec)):
            x.append(struct.unpack( '<f' , x_vec[i]))
        for i in range(len(y_vec)):
            y.append(struct.unpack( '<f' , y_vec[i]))
        for i in range(len(z_vec)):
            z.append(struct.unpack( '<f' , z_vec[i]))
        
        
        for i in range(len(z_vec)):
            total.append( np.multiply(x[i],x[i]) + np.multiply(y[i], y[i]) + np.multiply(z[i],z[i]) )
        
        print("reading")  
           
        self.port.flush()
        
        print("finish Reading")
         
        fig = pl.figure(figsize= (4.25,4))
        pl.title('G / Samples')
        
        pl.plot(total)
        
        fig.savefig('plot.png')
        self.image_icon.set_from_file("plot.png")

Arduino:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

typedef union {
 float floatingPoint;
 byte binary[4];
} binaryFloat;
binaryFloat x,y,z;
float xcal, ycal, zcal;
bool record;

void displaySensorDetails(void)
{
  sensor_t sensor;
  accel.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" m/s^2");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" m/s^2");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" m/s^2");  
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

void displayDataRate(void)
{
  Serial.print  ("Data Rate:    "); 
  
  switch(accel.getDataRate())
  {
    case ADXL345_DATARATE_3200_HZ:
      Serial.print  ("3200 "); 
      break;
    case ADXL345_DATARATE_1600_HZ:
      Serial.print  ("1600 "); 
      break;
    case ADXL345_DATARATE_800_HZ:
      Serial.print  ("800 "); 
      break;
    case ADXL345_DATARATE_400_HZ:
      Serial.print  ("400 "); 
      break;
    case ADXL345_DATARATE_200_HZ:
      Serial.print  ("200 "); 
      break;
    case ADXL345_DATARATE_100_HZ:
      Serial.print  ("100 "); 
      break;
    case ADXL345_DATARATE_50_HZ:
      Serial.print  ("50 "); 
      break;
    case ADXL345_DATARATE_25_HZ:
      Serial.print  ("25 "); 
      break;
    case ADXL345_DATARATE_12_5_HZ:
      Serial.print  ("12.5 "); 
      break;
    case ADXL345_DATARATE_6_25HZ:
      Serial.print  ("6.25 "); 
      break;
    case ADXL345_DATARATE_3_13_HZ:
      Serial.print  ("3.13 "); 
      break;
    case ADXL345_DATARATE_1_56_HZ:
      Serial.print  ("1.56 "); 
      break;
    case ADXL345_DATARATE_0_78_HZ:
      Serial.print  ("0.78 "); 
      break;
    case ADXL345_DATARATE_0_39_HZ:
      Serial.print  ("0.39 "); 
      break;
    case ADXL345_DATARATE_0_20_HZ:
      Serial.print  ("0.20 "); 
      break;
    case ADXL345_DATARATE_0_10_HZ:
      Serial.print  ("0.10 "); 
      break;
    default:
      Serial.print  ("???? "); 
      break;
  }  
  Serial.println(" Hz");  
}

void displayRange(void)
{
  Serial.print  ("Range:         +/- "); 
  
  switch(accel.getRange())
  {
    case ADXL345_RANGE_16_G:
      Serial.print  ("16 "); 
      break;
    case ADXL345_RANGE_8_G:
      Serial.print  ("8 "); 
      break;
    case ADXL345_RANGE_4_G:
      Serial.print  ("4 "); 
      break;
    case ADXL345_RANGE_2_G:
      Serial.print  ("2 "); 
      break;
    default:
      Serial.print  ("?? "); 
      break;
  }  
  Serial.println(" g");  
}

void setup(void) 
{
  Serial.begin(9600);
  //Serial.println("Accelerometer Test"); Serial.println("");
  record = false;
  /* Initialise the sensor */
  if(!accel.begin())
  {
    /* There was a problem detecting the ADXL345 ... check your connections */
    //Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    //Serial.println("Error Code: 102");
    //while(1);
  }
  
  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);
  
  /* Display some basic information on this sensor */
  //displaySensorDetails();
  
  /* Display additional settings (outside the scope of sensor_t) */
  //displayDataRate();
  //displayRange();
  //Serial.print("Calibrating ADXL:");
   
  sensors_event_t event; 
  accel.getEvent(&event);
  xcal = event.acceleration.x;
  ycal = event.acceleration.y;
  zcal = event.acceleration.z;\
  Serial.print("");
}

void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; 
  accel.getEvent(&event);
  if(record == true){
    x.floatingPoint = event.acceleration.x;
    y.floatingPoint = event.acceleration.y;
    z.floatingPoint = event.acceleration.z;
    x.floatingPoint = x.floatingPoint/9.81;
    y.floatingPoint = y.floatingPoint/9.81;
    z.floatingPoint = z.floatingPoint/9.81;
    //float t = sqrt(x.floatingPoint*x.floatingPoint + y.floatingPoint*y.floatingPoint + z.floatingPoint*z.floatingPoint);
    //Serial.print(t);Serial.print("\n");
    Serial.write((byte)x.floatingPoint);
    Serial.write((byte)y.floatingPoint);
    Serial.write((byte)z.floatingPoint);

  }
}
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    if(inChar == 'b'){
      record = true;
    }
    else if (inChar == 'a') {
      record = false;
     }
    else if(inChar == 't'){
      Serial.print(104);
    }
   }
  }

What is Python's endianess?

Should be little-endian '>'

Have a look at this Python - Arduino demo.

That example is designed for human-readable characters. There is an example for sending any byte value at the start of that Thread.

Or you may be interested in this Python Binary Data demo.

...R

Thanks For the Documentation. Finally got it working by sending the values as strings then converting to floats.

ltdouthit: Finally got it working by sending the values as strings then converting to floats.

I suspect it would not be easy to match the binary float format used on a PC with that used on an Arduino so using text as an intermediate would certainly be my choice.

...R

Robin2: I suspect it would not be easy to match the binary float format used on a PC with that used on an Arduino so using text as an intermediate would certainly be my choice.

...R

I'd hope they're both IEEE-754

Groove: I'd hope they're both IEEE-754

Indeed. But what would one have to do to turn "hope" into "know" ?

...R