Go Down

Topic: Arduino Nano v3 + GY-521 (acc+gyro) --> Processing --> CSV, can't get it to work (Read 2273 times) previous topic - next topic


Dear all,

For a school project I have to get the acceleration and the filtered angle data from the acc+gyro (GY-521) sensor into Excel to analyze them. I use an Arduino nano v3 and a macbook with lion - OSX 10.7.5.  Today (for a quick test) I was hoping to let Processing create a simple CSV with the y-accelerations in there, one on each row, but I can't get it to work... The Processing sketch does make the CSV file, but it's sometimes it's empty and sometimes it's showing the right values but like so:



It splits the 201,00 somewhere in the middle and sometimes it adds a empty line.

Now my question is: How is it possible that sometimes it writes a empty file and sometimes a filled file. And why does the filled then jump at random places to the next line? It looks like it's not in sync??! The serial monitor of the Arduino environment gives my the perfect rows of values..

Can somebody help me? Thanks very much!

This is the Processing sketch I used:

Code: [Select]
import processing.serial.*;
Serial mySerial;
PrintWriter output;
//float accel_y;

void setup() {
  mySerial = new Serial( this, Serial.list()[1], 19200 );
  output = createWriter( "documents/datalaumann5.txt" );

void draw() {
   if (mySerial.available() > 0 ) {
        String accel_y = mySerial.readString();
        if ( accel_y != null ) {

void keyPressed() {
 output.flush();  // Writes the remaining data to the file
 output.close();  // Finishes the file
 exit();  // Stops the program

And this is my Arduino code (part of the complete code):

Code: [Select]

  float accel_y;

void setup()
  int error;
  uint8_t c;

  Serial.println(F("InvenSense MPU-6050"));
  Serial.println(F("June 2012"));
  // Initialize the 'Wire' class for the I2C-bus.

  // default at power-up:
  //    Gyro at 250 degrees second
  //    Acceleration at 2g
  //    Clock source at internal 8MHz
  //    The device is in sleep mode.

  error = MPU6050_read (MPU6050_WHO_AM_I, &c, 1);
  Serial.print(F("WHO_AM_I : "));
  Serial.print(F(", error = "));

  // According to the datasheet, the 'sleep' bit
  // should read a '1'. But I read a '0'.
  // That bit has to be cleared, since the sensor
  // is in sleep mode at power-up. Even if the
  // bit reads '0'.
  error = MPU6050_read (MPU6050_PWR_MGMT_2, &c, 1);
  Serial.print(F("PWR_MGMT_2 : "));
  Serial.print(F(", error = "));

  // Clear the 'sleep' bit to start the sensor.
  MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0);
  //Initialize the angles
  set_last_read_angle_data(millis(), 0, 0, 0, 0, 0, 0);

void loop()
  int error;
  double dT;
  accel_t_gyro_union accel_t_gyro;

  // Read the raw values.
  error = read_gyro_accel_vals((uint8_t*) &accel_t_gyro);
  // Get the time of reading for rotation computations
  unsigned long t_now = millis();

  // Convert gyro values to degrees/sec
  float FS_SEL = 131;
  float gyro_x = (accel_t_gyro.value.x_gyro - base_x_gyro)/FS_SEL;
  float gyro_y = (accel_t_gyro.value.y_gyro - base_y_gyro)/FS_SEL;
  float gyro_z = (accel_t_gyro.value.z_gyro - base_z_gyro)/FS_SEL;
  float gyro_x = (accel_t_gyro.value.x_gyro - base_x_gyro)/FS_SEL;
  float gyro_y = (accel_t_gyro.value.y_gyro - base_y_gyro)/FS_SEL;
  float gyro_z = (accel_t_gyro.value.z_gyro - base_z_gyro)/FS_SEL;
  // Get raw acceleration values
  //float G_CONVERT = 16384;
  float accel_x = accel_t_gyro.value.x_accel;
  float accel_y = accel_t_gyro.value.y_accel;
  float accel_z = accel_t_gyro.value.z_accel;
  // Get angle values from accelerometer
  float RADIANS_TO_DEGREES = 180/3.14159;
//  float accel_vector_length = sqrt(pow(accel_x,2) + pow(accel_y,2) + pow(accel_z,2));
  float accel_angle_y = atan(-1*accel_x/sqrt(pow(accel_y,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES;
  float accel_angle_x = atan(accel_y/sqrt(pow(accel_x,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES;

  float accel_angle_z = 0;
  // Compute the (filtered) gyro angles
  float dt =(t_now - get_last_time())/1000.0;
  float gyro_angle_x = gyro_x*dt + get_last_x_angle();
  float gyro_angle_y = gyro_y*dt + get_last_y_angle();
  float gyro_angle_z = gyro_z*dt + get_last_z_angle();
  // Compute the drifting gyro angles
  float unfiltered_gyro_angle_x = gyro_x*dt + get_last_gyro_x_angle();
  float unfiltered_gyro_angle_y = gyro_y*dt + get_last_gyro_y_angle();
  float unfiltered_gyro_angle_z = gyro_z*dt + get_last_gyro_z_angle();
  // Apply the complementary filter to figure out the change in angle - choice of alpha is
  // estimated now.  Alpha depends on the sampling rate...
  float alpha = 0.96;
  float angle_x = alpha*gyro_angle_x + (1.0 - alpha)*accel_angle_x;
  float angle_y = alpha*gyro_angle_y + (1.0 - alpha)*accel_angle_y;
  float angle_z = gyro_angle_z;  //Accelerometer doesn't give z-angle
  // Update the saved data with the latest values
  set_last_read_angle_data(t_now, angle_x, angle_y, angle_z, unfiltered_gyro_angle_x, unfiltered_gyro_angle_y, unfiltered_gyro_angle_z);
  // Send the data to the serial port
  Serial.print(F("DEL:"));              //Delta T
  Serial.print(dt, DEC);
  Serial.print(F("#ACC:"));              //Accelerometer angle
  Serial.print(accel_angle_x, 2);
  Serial.print(accel_angle_y, 2);
  Serial.print(accel_angle_z, 2);
  Serial.print(unfiltered_gyro_angle_x, 2);        //Gyroscope angle
  Serial.print(unfiltered_gyro_angle_y, 2);
  Serial.print(unfiltered_gyro_angle_z, 2);
  Serial.print(F("#FIL:"));             //Filtered angle
  Serial.print(angle_x, 2);
  Serial.print(angle_y, 2);
  Serial.print(angle_z, 2);

  // Delay so we don't swamp the serial port


Code: [Select]
         String accel_y = mySerial.readString();
What, exactly, defines a string? What makes readString() stop reading?

You really should have a serialEvent() function, instead of doing serial reading in draw().
You really should have a mySerial.bufferUntil() statement in setup(), to define when to trigger the serialEvent() method, and you should use readBytesUntil() in serialEvent().
The art of getting good answers lies in asking good questions.

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131