Navx Arduino programming

Hello all,

I am having trouble using the Navx arduino library. The example code they provide only gets Bytes, and I cannot find which Bytes relate to which type of information (gyro, magnometer …etc). If someone can tell me what functions to use it would be super helpful !!!
Here is a link to the official navx MXP arduino library

Hi Hamza,

What are you attempting to do w/the Arduino? We can get something added to the samples, just let us know your use case.

In general, you can use the IMURegisters.h file, which documents the register locations and provides decode functions as well.

If you simply want the yaw value, you’d read the two-byte yaw value (starting at register address NAVX_REG_YAW_L), and then invoke the decodeProtocolSignedHundredthsFloat() function to decode it to a floating point value (from -180 to 180).

  • scott

Thank you so much!
I have written a function based on what you told me. I initially had trouble determining what function to use and what register address to start with.
This is the function I wrote, I have not tried it yet but I thought I would share it here:

void publishData(){
  Wire.beginTransmission(NAVX_REG_YAW_L);
  Wire.requestFrom(NAVX_REG_YAW_L,2);
  float angle = IMURegisters::decodeProtocolSignedHundredthsFloat((char*) Wire.read());
  Wire.endTransmission();
  dtostrf(angle, 5, 5, (char*)str_msg.data);
  chatter.publish( &str_msg );
  nh.spinOnce();
  delay(10);
}

Hi Scott,
I still need to use the Navx with Arduino, but I am still having issues. I would really appreciate it if you could help me as I am really riddled.
Here is my code:


Wire.beginTransmission(NAVX_REG_YAW_L);
  Wire.requestFrom(NAVX_REG_YAW_L,2);
  
  float angle = IMURegisters::decodeProtocolSignedHundredthsFloat(Wire.read());
  Wire.endTransmission();
  Serial.print("test");
  Serial.print(angle);

I only get one value that does not change at all : 137.0125

Looking forward to your reply! :slight_smile:

Here’s a snippet of a working arduino code sequence that reads 32 bytes of register data from a NavX-family device over I2C:

/* Transmit I2C data /
Wire.beginTransmission(0x32); // transmit to device #0x32 (50)
Wire.write(next); // Sends the starting register address
Wire.write(32); // Send number of bytes to read
Wire.endTransmission(); // stop transmitting
/
Receive the echoed value back /
Wire.beginTransmission(0x32);
Wire.requestFrom(0x32,32);
while(Wire.available()) { // slave may send less than requested
data
= Wire.read();
}
Wire.endTransmission();
Serial.print(“I2C: “);
for ( int x = 0; x < i; x++ ) {
Serial.print(data[x],HEX);
data[x] = 0;
Serial.print(” “);
}
Serial.println(””);

Two key points are that Wire.beginTransmission takes as parameter the NavX I2C device NavX number (decimal: 50; hexadecimal: 0x32). Also, it’s required to tell NavX (by writing to it) what register address you want to start reading from and how many bytes.

In this example, the “next” variable is the starting address to read from; 32 bytes of data are read and printed out.

I return home from FIRST championships next Monday and can help more then. The code above should work. I’d recommend comparing the above to your code, there are a few key differences.*

I also have another question. You said that 0x32 is to start reading from I2C, but looking at the IMURegisters file, 0x32 is NAVX_REG_MPU_TEMP_C_L

Please carefully review the example sent previously. The code you’ve posted does tell the navX sensor to get ready to send data; however, the code you’ve posted does not include code to actually read the data back.

The code to read the data back (from the example sent previously) that needs to be added is:


/* Receive the echoed value back */
Wire.beginTransmission(0x32);
Wire.requestFrom(0x32,32);
while(Wire.available()) { // slave may send less than requested
data* = Wire.read();
}
Wire.endTransmission();

This code needs to be added after the 4th line in the example code you posted previously. This code needs to be added before the data is decoded.*

  • 0x32 (hexadecimal) is the navX I2C address

  • 0x32 (hexadecimal) is also the register address of NAVX_REG_MPU_TEMP_C_L

  • 32 (decimal) is the number of bytes being read from the sensor in the Arduino example.

Each represents something different.

The fact all these different constants have a similar numeric value is a coincidence.

Please review https://www.arduino.cc/en/Reference/WireRead

Review what data type it returns.

And note that IMURegisters::decodeProtocolSignedHundredthsFloat() requires an array of characters as input.

So the return result from Wire.read() cannot be directly passed to IMURegisters::decodeProtocolSignedHundredthsFloat().

Hi, I got it working. Thanks for your help. I had the correct I2C code but forgot to paste it in. My issue was using hexadecimal addresses instead of using decimal addresses. Once I converted the Yaw lower byte address to its corresponding decimal value it worked.
Thanks for your patience!