NavX Sensor with Arduino

Hello, I am working with a NavX Micro and and Arduino, and I’m trying to measure Z velocity. I have read over the example on Kauail Labs’ GitHub page and an older post on here from 2017 and I still cant seem to get my code to work. Here’s what I have so far:

#include <Wire.h>
#include "AHRSProtocol.h"
byte data[512];

void setup() {  
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}
 
void loop() {
  int i = 0;
  /* Transmit I2C data */
  Wire.beginTransmission(0x60); // transmit to device 
  Wire.write(NAVX_REG_VEL_Z_I_L); // Sends the starting register address
  Wire.write(4);   // Send number of bytes to read
  Wire.endTransmission();    // stop transmitting
  /* Receive the echoed value back */
  Wire.beginTransmission(0x60);
  Wire.requestFrom(0x60,4);
  while(Wire.available()) { // slave may send less than requested
     data[i++] = Wire.read();
  }
  Wire.endTransmission();
  
float vel_z = IMURegisters::decodeProtocol1616Float(Wire.read());
Serial.println(vel_z);
}

I am using the .h files from this link: navxmxp/arduino/navXTestJig at master · kauailabs/navxmxp · GitHub

Any help would be greatly appreciated.

May I ask why you’re using a NavX micro and an Arduino? (As opposed to plugging it into the Rio’s I2C…

1 Like

This is for a project that doesn’t use a Rio, and ideally just an arduino. I also just happened to have a NavX micro laying around and I figured id try and use it to detect Z velocity

1 Like

Per the Register protocol specification, the navX-Micro I2C address is 50 (0x32).

Per the I2C section of the navX-sensor Arduino example, the Arduino code should look like this:

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[i++] = Wire.read();
}
Wire.endTransmission();

So based on that, the code you have provided looks about right, except that the I2C address currently used is incorrect.

2 Likes

Thank you for the response! I switched over the values and I2C communication seems to be working, however, I am only getting one value when I run the program. Could this be related to the specific register I am using? I noticed that there are multiple velocity registers for each axis.
void loop() {

New code:

int i = 0;
/* Transmit I2C data /
Wire.beginTransmission(0x32); // transmit to device
Wire.write(NAVX_REG_VEL_Z_I_L); // 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[i++] = Wire.read();
}
Wire.endTransmission();

float vel_z = IMURegisters::decodeProtocol1616Float(Wire.read());
Serial.println(vel_z);
}

You’re only decoding and printing whatever was left on the interface after reading the velocities. You should be decoding what is in the data array.

1 Like

Thank you for your response @ Joe_Ross! Ok, so I switched it to read the data array, but it now only outputs zero. I tried playing around with where and how I initialize “i” to see if that would change it, and so far I haven’t had any luck. Anything else I might be missing?

I figured it out, in line 16 I was setting the number of bytes to read to 32, but I needed to be reading 32 bits or 4 bytes. Thanks for the help everyone!

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.