Go Down

Topic: Wire partially working to talk to Adafruit BNO055 IMU (Read 277 times) previous topic - next topic

cal40john

The problem is reading the 2nd and 3rd axes numbers.  It looks like the numbers start out correct then become random or zero.

I started by using the ADAfruit Sensor and ADAfruit BNO055 libraries.  To check the libraries I got out my UNO and they worked on the UNO.

I wondered if the ADAfruit libraries were doing something UNO register specific, so I wrote a test program using the Wire library.  The test program works on the UNO but not the WIFI R2 with the same type of failure.



 
Code: [Select]

#include <Wire.h>
int head =0;
int pitch =0;
int roll = 0;
int reading = 0;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  //setup BNo055(IMU), ext clock, reset int, reset system, self test
  Wire.beginTransmission(0x28);
  Wire.write(byte (0x3F));
  Wire.write(byte (0xE1));
  Wire.endTransmission();
  delay(1000);

  //read chip id register to see if IMU is working
  Wire.beginTransmission(0x28);
  Wire.write(byte (0x00));
  Wire.endTransmission();
  Wire.requestFrom(0x28, 1);
  if (1 <= Wire.available()) {
    reading = Wire.read();
  }
  delay(250);

  //should be 160 (0xA0) if IMU is responding
  Serial.println(reading);
  //set IMU to IMU fusion mode
  Wire.beginTransmission(0x28);
  Wire.write(byte (0x3D));
  Wire.write(byte (0x08));
  Wire.endTransmission();

  //read mode register to see if IMU is in fusion mode (8)
  Wire.beginTransmission(0x28);
  Wire.write(byte (0x3D));
  Wire.endTransmission();
  Wire.requestFrom(0x28, 1);
  if (1 <= Wire.available()) {
    reading = Wire.read();
  }
   delay(250);
  Serial.println(reading);
}

void loop() {
  //read temperature register
  Wire.beginTransmission(0x28);
  Wire.write(byte (0x34));
  Wire.endTransmission();
  Wire.requestFrom(0x28, 1);
  if (1 <= Wire.available()) {
    int readLSB = Wire.read();
    Serial.print(readLSB);
    Serial.print("  ");
  }

  //read yaw (or heading), roll, and pitch Euler registers
  Wire.beginTransmission(0x28);
  Wire.write(byte (0x1A));
  Wire.endTransmission();
  Wire.requestFrom(0x28, 6);
  if (6 <= Wire.available()) {
    int pairs[6];
    int orient[3];
    for(int i =0; i <6; i++){
      pairs[i] = Wire.read();
    }
    //each axis is 2 bytes,
    //shift MSB and combine bytes to get axis number
    for (int i=0; i<3; i++){
       orient[i] =  pairs[ 0 + 2*i]|(pairs[1+2*i] << 8);
       Serial.print(orient[i]/16);
        Serial.print("  ");
    }
  }
   delay(1000);
   Serial.println();
}

cal40john

The example in the Arduino reference has bothered me with the statement if data is available, collect it.  What if there's a glitch and the reads get out of sync? I have tried a few things (one was only reading 2 bytes at a time).  What seems to have fixed the problem is adding this piece of code at the end of the loop. 

What's interesting to me is that it never prints "error".  Perhaps just touching Wire.available fixes something?

Code: [Select]

while (Wire.available() >= 1) {
    Serial.print("error"); 
  }


Still why is this an issue with the Wifi R2 and not the UNO?

cal40john

Further update.  The code that seemed to work was unstable.  Since the tests I had done on the UNO seemed to be very reliable and noise free I've been moving everything over to the UNO.  I've given up on the wifi r2.

The complete project is building an Arduino based drone.  I've spent a fair amount of time getting the wifi r2 to get data from the receiver.  The timing on the interrupts has been an issue and I wound up checking for and throwing away impossible numbers.  Sending data back to the console results in 6% of the data corrupted.  Commenting out the Serial.print() statements gets it down to 0.3%. (collect data for 30 seconds then jump to a state that prints out the data.)    On the UNO I haven't run the program to check bad data, but even with sending data to the console, there's barely a tremor on the motors.  The wifi r2 had the motors pulsing to mid speeds and back to zero.

The wifi r2 has the capability to assign interrupts to every pin.  Whereas the UNO you can only do pin change interrupts on a port (byte), so maybe there is an issue there in some way.  Maybe if I'm bored at some point I'll try the pin change code on the wifi r2.


Go Up