1

For an Arduino project I am working on, I am trying to modify the SparkFun 6 Degrees of Freedom IMU Digital Combo Board - ITG3200/ADXL345 to support DSSCircuit's I2C Master Library (https://github.com/DSSCircuits/I2C-Master-Library). This is to combat the known issue of the Arduino Wire library to often get hung up while trying to run the EndTransmission function.

I'm new to this and do not understand how the terms 'slave address' and 'register address' and 'bytes you want to send' are different, if they are. I also do not understand how buffering works in the base IMU library. Any information on those would be appreciated, but is not the focus of my question.

I use the example code of the IMU unit...

#include <FreeSixIMU.h>
#include <FIMU_ADXL345.h>
#include <FIMU_ITG3200.h>
#include <Wire.h>
#include <I2C.h>

int raw[6]; // x y z yaw pitch roll

// Set the FreeSixIMU object
FreeSixIMU sixDOF = FreeSixIMU();

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

  delay(100);
  sixDOF.init(); //begin the IMU
  delay(100);
}

void loop() { 
  sixDOF.getRawValues(raw);
  Serial.print(raw[0]);
  Serial.print(" x | ");  
  Serial.print(raw[1]);
  Serial.print(" y | ");
  Serial.print(raw[2]);
  Serial.println(" z");
  delay(100); 
}

And I changed the selected IMU library functions as follows:

// Writes val to address register on device
void ADXL345::writeTo(byte address, byte val) {
  I2c.write(address, val);
  // send register address
}

// Reads num bytes starting from address register on device in to _buff array
void ADXL345::readFrom(byte address, int num, byte _buff[]) {
  I2c.read(address, (byte) num);
  // sends address to read from
}

void ITG3200::writemem(uint8_t _addr, uint8_t _val) {
  I2c.write(_addr, _val);   // start transmission to device
}

void ITG3200::readmem(uint8_t _addr, uint8_t _nbytes, uint8_t __buff[]) {
  I2c.read(_addr, _addr, _nbytes);   // start transmission to device
}

And added the #include <I2C.h> statements to the headers files where applicable.

When running the example code, the serial output will not change values based on how I move the accelerometer, which makes me think I used the wrong slave address to read data from, or some other issue.

Can someone help me modify the IMU library to include DSSCircuit's Master I2C Library?

Thank you Stack Exchange Community! John

EDIT:

Please see PersonAGem's edit below. Using the wire library is known to have arbitrary hangups, and in this example PersonAGem lists the edits I should make to the other libraries I am using as well as gives me the code I should use in my .ino.

I ask a new question about this topic here.

1

You are missing the rest of the code in reading operations. You are just requesting the data, no actually reading it from the device:

the original code of adlx345::read

void ADXL345::readFrom(byte address, int num, byte _buff[]) {
  Wire.beginTransmission(_dev_address); // start transmission to device
  Wire.write(address);             // sends address to read from
  Wire.endTransmission();         // end transmission

  Wire.beginTransmission(_dev_address); // start transmission to device
  Wire.requestFrom(_dev_address, 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++;
  }
  if(i != num){
    status = ADXL345_ERROR;
    error_code = ADXL345_READ_ERROR;
  }
  Wire.endTransmission();         // end transmission
}

would change to (if no mistakes made):

void ADXL345::readFrom(byte address, int num, byte _buff[]) {
  I2c.read(_dev_address, address, num) // request 6 bytes from device
  if(I2c.available() != num){  // device may send less than requested (abnormal)
    status = ADXL345_ERROR;
    error_code = ADXL345_READ_ERROR;
  }

  int i = 0;
  while(I2c.available())         
  {
    _buff[i] = I2c.receive();    // receive a byte
    i++;
  }
}

you may need to force cast parameters between functions.

If for some reason you don't want the actual code and want to use another library, I'll suggest I2Cdev site with a well documented classes for adlx345 and ITG3200.

Edit:

This caused me no problem. That is the only 2 functions I changed:

// Writes val to address register on device
void ADXL345::writeTo(byte address, byte val) {
  I2c.write((uint8_t) _dev_address, (uint8_t) address, (uint8_t) val);
}

// Reads num bytes starting from address register on device in to _buff array
void ADXL345::readFrom(byte address, int num, byte _buff[]) {
  I2c.read((uint8_t) _dev_address, (uint8_t) address, (uint8_t) num);  // request 6 bytes from device
  if(I2c.available() != num){  // device may send less than requested (abnormal)
    status = ADXL345_ERROR;
    error_code = ADXL345_READ_ERROR;
  }

  int i = 0;
  while(I2c.available())         
  {
    _buff[i] = I2c.receive();    // receive a byte
    i++;
  }
}

Arduino code used:

#include <I2C.h>
#include "FIMU_ADXL345.h"

ADXL345 acc = ADXL345();
int x=0,  y=0, z=0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  I2c.begin();
  delay(100);
  acc.init(ADXL345_ADDR_ALT_LOW);
  delay(100);
  Serial.print("Is ACC OK?: ");
  Serial.println(acc.status);
  Serial.print("Any Error code?: ");
  Serial.println(acc.error_code);
  Serial.println("********Print all register current values********");
  acc.printAllRegister();
  Serial.println("********END register print******");
  Serial.println(acc.getRate());
}

void loop() {
  // put your main code here, to run repeatedly:
  acc.readAccel(&x,&y,&z);
  Serial.print(x);
  Serial.print('\t');
  Serial.print(y);
  Serial.print('\t');
  Serial.println(z);
  delay(500);
}

Output given:

Is ACC OK?: 1
Any Error code?: 0
********Print all register current values********
0x00: B11100101
0x1D: B00000000
0x1E: B00000000
0x1F: B00000000
0x20: B00000000
0x21: B00000000
0x22: B00000000
0x23: B00000000
0x24: B00000000
0x25: B00000000
0x26: B00000000
0x27: B00000000
0x28: B00000000
0x29: B00000000
0x2A: B00000000
0x2B: B00000000
0x2C: B00001010
0x2D: B00001000
0x2E: B00000000
0x2F: B00000000
0x30: B10000011
0x31: B00000000
0x32: B11110101
0x33: B11111111
0x34: B00000011
0x35: B00000000
0x36: B11100101
0x37: B00000000
0x38: B00000000
0x39: B00000000
********END register print******
100.00
-12 4   230
-10 2   231
-11 3   231
-12 3   228
-10 3   230
-11 2   231
-12 2   229
-11 3   229
-10 3   231
-11 3   229
-10 2   230
-12 4   230
-12 3   229
-10 2   229
-13 4   230
-11 3   230
-10 3   230
-11 2   230
-11 4   229
-11 3   230
-11 3   230
-11 3   229
-12 3   229
-10 2   229
-11 3   230
-11 3   231
-11 3   230
-15 14  227
34  104 210
138 95  191
243 18  88
323 -15 74
280 -8  -2
263 -2  37
212 10  163
16  39  233
28  114 195
29  161 170
33  124 211
5   49  244
7   22  224
-10 3   229
-11 2   230
-12 2   230
-11 3   231
-12 4   228
  • Thank you I will try this in the morning. I can see I did not realize I was not reading the data when I requested it. – John Doe Nov 23 '15 at 3:16
  • Sorry, it did not work... I am now getting something in the range of 0-256, only positive values, and they vary widely. I've seen 92 as minimum and 230 as maximum. I modified your code || I2c.read(dev_address, address, num) // request 6 bytes from device || --> || I2c.read(address, (byte) num); // request 6 bytes from device || and it compiled. – John Doe Nov 23 '15 at 18:28
  • *This is while it is lying on the table. Left to run for about a minutes. The code in general prints to serial about 7Hz as tested a week ago. – John Doe Nov 23 '15 at 18:52
  • have you changed all the other functions? – brtiberio Nov 23 '15 at 19:54
  • @JohnDoe I managed to get an adlx345 for testing communication and all went fine apparently. Look at updated code for the read with the forced casts. However, I really advise you that this can result in many mistakes. I couldn't find any documentation for the I2C library you are suggesting. – brtiberio Nov 23 '15 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.