[SOLVED] Any experiences with Due and Sparkfun 9DOF sensor stick?

Hey guys,

i´m pretty new to electrical engineering and micro controllers. But I want to learn how to get these things running! So I bought a Arduino Due and a 9DOF sensor stick from Sparkfun. I want to read the sensor values and experiment with some filters afterwards. But I have troubles with the reading the most significant 8 bits for each possible axis. The values always jump from about 0-3 to 253-255 with no steps in between.

I posted this issue already in the Sensors board:

I wanted to start another topic because I want to know if any Due users have experience with this stick. I am very excited about experimenting with it but this is a bummer right now. I only have this board so I can´t check if this is an issue of the board. Probably the stick is broken, who knows? I hope some one can help me out (:

Cheers,

Michael

I have several MCUs but all of them are SPI. Anyway, to determine what is going on with your Due-9DOF Stick, I’d recommend you to start trying to communicate with one of the sensors, let’s say the accelerometer, and then with the other two. I assume that you know how accelerometers work. Just in case remember, under steady-state, all the values (x,y,z) should be zero. When the stick is in motion, the values change.

Here a sketch that I have built just for the accelerometer after the chionophilous’ tutorial that you have followed. It should work (theoretically). I assume, also, that you have connected 3.3V, GND, SDA and SCL between the stick and due.

#include <Wire.h>
#define ADXL345_ADDRESS (0xA6 >> 1)
#define ADXL345_REGISTER_XLSB (0x32)
#define ADXL_REGISTER_PWRCTL (0x2D)
#define ADXL_PWRCTL_MEASURE (1 << 3)
int accelerometer_data[3];

void setup() {
  Wire.begin();
  Serial.begin(9600);

  for(int i = 0; i < 3; ++i) {
    accelerometer_data[i] = 0;
  }
  init_adxl345();
}

void loop() {
   read_adxl345();
   Serial.print("ACCEL: ");
   Serial.print(accelerometer_data[0]);
   Serial.print("\t");
   Serial.print(accelerometer_data[1]);
   Serial.print("\t");
   Serial.print(accelerometer_data[2]);
   Serial.print("\n");
   delay(100);
}
 
void init_adxl345() {
  byte data = 0;
  i2c_write(ADXL345_ADDRESS, ADXL_REGISTER_PWRCTL, ADXL_PWRCTL_MEASURE);
  i2c_read(ADXL345_ADDRESS, ADXL_REGISTER_PWRCTL, 1, &data);
  Serial.println((unsigned int)data);
}


void read_adxl345() {
  byte bytes[6];
  memset(bytes,0,6);
  i2c_read(ADXL345_ADDRESS, ADXL345_REGISTER_XLSB, 6, bytes);
  for (int i=0;i<3;++i) {
  accelerometer_data[i] = (int)bytes[2*i] + (((int)bytes[2*i + 1]) << 8);
  }
}

void i2c_write(int address, byte reg, byte data) {
  Wire.beginTransmission(address);
  Wire.write(reg);
  Wire.write(data);
  Wire.endTransmission();
}

void i2c_read(int address, byte reg, int count, byte* data) {
 int i = 0;
 Wire.beginTransmission(address);
 Wire.write(reg);
 Wire.endTransmission();
 Wire.beginTransmission(address);
 Wire.requestFrom(address,count);
 while(Wire.available()) {
   char c = Wire.read();
   data[i] = c;
   i++;
 }
 Wire.endTransmission();
}

Let me know how it goes.

p

EDIT: Try to make shorter the wires between Due and the stick.

Thanks for your reply Palliser!

The Sketch is working but the problem is the same. I also stripped down the sketch from chinophilous and I was focusing on one axis at a time.

Here are some results from your sketch:

ACCEL: 65510 44 244
ACCEL: 65468 10 214
ACCEL: 65406 0 214
ACCEL: 65382 0 184
ACCEL: 65314 65514 138
ACCEL: 65310 65530 172
ACCEL: 65344 42 186
ACCEL: 65434 150 154
ACCEL: 65432 224 150
ACCEL: 65522 216 48
ACCEL: 65512 258 50
ACCEL: 6 240 26
ACCEL: 65510 236 14

It looks like this, even if i don´t move it. Every time the value goes up to 65k the most significant 8 bit part jumps form 0 or 1 to some values around 255.

But I will try to shorten the wires now! I was thinking that 30cm would be ok. But they are probably to long. I will report my results ASAP!

Thanks!

Michael

Nope - I tried it with some cables of 10 cm length. Didn´t work :/… It was worth a try though

Edit: But maybe my cables are to thin?

I got these: https://www.tinkersoup.de/jumper-wires-premium-30-cm-m-f-pack-of-10/a-796/

and maybe I soldered it not the right way? This evening I will meet a friend. He has probably some tools to do some troubeshooting. But the soldering points look fine.

Let’s put aside for a moment the wiring subject. I want you to try another code (it seems to be the same I gave you). I think we miss nothing if you make a try running it. Here the sketch:

#include <Wire.h>
#define DEVICE (0x53)    //ADXL345 device address
#define TO_READ (6)        //num of bytes we are going to read each time (two bytes for each axis)

byte buff[TO_READ] ;    //6 bytes buffer for saving data read from the device
char str[512];                      //string buffer to transform data before sending it to the serial port

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  
  //Turning on the ADXL345
  writeTo(DEVICE, 0x2D, 0);      
  writeTo(DEVICE, 0x2D, 16);
  writeTo(DEVICE, 0x2D, 8);
}

void loop()
{
  int regAddress = 0x32;    //first axis-acceleration-data register on the ADXL345
  int x, y, z;
  
  readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345
  
   //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
   //thus we are converting both bytes in to one int
  x = (((int)buff[1]) << 8) | buff[0];   
  y = (((int)buff[3])<< 8) | buff[2];
  z = (((int)buff[5]) << 8) | buff[4];
  
  //we send the x y z values as a string to the serial port
  sprintf(str, "%d %d %d", x, y, z);  
  Serial.print(str);
  Serial.write(10);
  
  //It appears that delay is needed in order not to clog the port
  delay(15);
}

void writeTo(int device, byte address, byte val) {
   Wire.beginTransmission(device); //start transmission to device 
   Wire.write(address);        // send register address
   Wire.write(val);        // send value to write
   Wire.endTransmission(); //end transmission
}

void readFrom(int device, byte address, int num, byte buff[]) {
  Wire.beginTransmission(device); //start transmission to device 
  Wire.write(address);        //sends address to read from
  Wire.endTransmission(); //end transmission
  
  Wire.beginTransmission(device); //start transmission to device (initiate again)
  Wire.requestFrom(device, num);    // request 6 bytes from device
  
  int i = 0;
  while(Wire.available())    //device may send less than requested (abnormal)
  { 
    buff[i] = Wire.read(); // receive a byte
    i++;
  }
  Wire.endTransmission(); //end transmission
}

p

Thanks for the sketch Palliser. Results seem to be the same.

63 115 238
65453 98 188
65494 130 262
65439 91 195
65384 103 197
65358 99 204
65374 100 201
65425 73 204
65519 50 204
65515 88 231
65523 89 255
27 117 276
23 114 281

Its always the left most register part (0x33,0x35, 0x39) going either 0 or 255. It´s very strange.

Update: works on an arduino uno without code changes. So the stick is fine. But what could be the problem with the due? The wire library? Can my I2C port be broken? Do I need to clock my cpu down somehow? no idea...

I have read a couple of posts and it looks like given the MCU library was built for AVR 8-bit and that Due is an ARM 32-bit, the difference between architectures could oblige the programmer (us) to consider to implement a solution (changes in the library) to make Due to correctly interpret the MCU data. I mean, a common 16 bit-based system instead of misreadings of standard 32-bit integers that will result in the 16 bit signed data coming out all positive and over 65000 for negatives. Thus, here could be the mystery. Let's grasp a bit about it.

p

Hello Jambi,
Try the first code (reply#1) replacing the line 6

int accelerometer_data[3];

with the following line:

int16_t accelerometer_data[3];

With that, you are defining the Accelerometer outputs as signed 16 bit values. It should work.

p

It works! We are UP AND RUNNING! ;)... Thank you very much!

ACCEL: 128 5632 15360
ACCEL: 896 5952 15040
ACCEL: 1280 6208 15552
ACCEL: 832 6080 15488
ACCEL: 192 5888 15360
ACCEL: 640 6080 15424

Now these values look just pretty!

Thanks,

Michael

What was the address that ended up working for the ADXL345? I have the DUE and the 10724 sparkfun sensor stick and I can’t get any communication up. I just get all 0’s. When I print the integer from the Wire.endTransmission I get a 2, which I believe is a NACK from the address transmit (line 200 of Wire.cpp).
I’ve tried both:

#define ADXL345_ADDRESS (0xA6 >> 1)

and

#define ADXL345_ADDRESS (0x53)

Thanks