I am using an Arduino Uno WIFI Rev2 board to read internal gyroscope data. I picked it up after 3 months of not using it, and now the IMU initialization process seems to be broken. There is a condition set up to check whether the IMU has been initialized and it doesn't go past that. If i remove that code, the gyroscope is only sending out data for the first fraction of a second, then stops.
This is the entire code, it has additional stuff but all of that works perfectly if i remove any code that has to do with the IMU.
// Built-in gyroscope library
#include <Arduino_LSM6DS3.h>
// Ultrasonic sensor library
#include "Ultrasonic.h"
Ultrasonic ultrasonicX(2);
Ultrasonic ultrasonicY(3);
Ultrasonic ultrasonicZ(4);
int prev_isClosed = 0;
void setup() {
// Start the serial communication
Serial.begin(9600);
while (!Serial);
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
Serial.print("Gyroscope sample rate = ");
Serial.print(IMU.gyroscopeSampleRate());
Serial.println(" Hz");
Serial.println();
Serial.println("Gyroscope in degrees/second");
Serial.println("X\tY\tZ");
pinMode(A0, INPUT);
}
void loop() {
// Read the gyro data
float gyro_x, gyro_y, gyro_z;
// Read the ultrasonic sensor data
float uson_x = ultrasonicX.MeasureInCentimeters();
float uson_y = ultrasonicY.MeasureInCentimeters();
float uson_z = ultrasonicZ.MeasureInCentimeters();
// proximity sensor indicating whether the box is open or not. 1 for closed, 0 for open
int isClosed = digitalRead(A1);
if(isClosed != prev_isClosed){
Serial.print("prox ");
Serial.println(isClosed);
prev_isClosed = isClosed;
}
Serial.print("xPos: ");
Serial.print(uson_x);
Serial.print(" yPos: ");
Serial.print(uson_y);
Serial.print(" zPos: ");
Serial.println(uson_z);
//gyroscope data
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(gyro_x, gyro_y, gyro_z);
Serial.print("gyro ");
Serial.print(gyro_x);
Serial.print(" ");
Serial.print(gyro_y);
Serial.print(" ");
Serial.println(gyro_z);
}
}
Check the I2C connections by running the I2C Address Scanner program, with the IMU module connected. If the program doesn't see the correct device address, most likely your wiring is faulty, or the required pullup resistors on SDA and SCL are missing.
It does not matter that the sensor is built in. Run the address scanner and post the addresses reported.
Make SURE that you are using the proper sensor library for your Arduino!
Edit: the schematic for the wifi rev 2 shows that the SPI bus is used instead (which is unusual), so the I2C scanner won't find it. Thus it is even more likely that you are not using the correct library.
int LSM6DS3Class::begin()
{
if (_spi != NULL) {
pinMode(_csPin, OUTPUT);
digitalWrite(_csPin, HIGH);
_spi->begin();
} else {
_wire->begin();
}
if (!(readRegister(LSM6DS3_WHO_AM_I_REG) == 0x6C || readRegister(LSM6DS3_WHO_AM_I_REG) == 0x69)) {
end();
return 0;
}
//set the gyroscope control register to work at 104 Hz, 2000 dps and in bypass mode
writeRegister(LSM6DS3_CTRL2_G, 0x4C);
// Set the Accelerometer control register to work at 104 Hz, 4 g,and in bypass mode and enable ODR/4
// low pass filter (check figure9 of LSM6DS3's datasheet)
writeRegister(LSM6DS3_CTRL1_XL, 0x4A);
// set gyroscope power mode to high performance and bandwidth to 16 MHz
writeRegister(LSM6DS3_CTRL7_G, 0x00);
// Set the ODR config register to ODR/4
writeRegister(LSM6DS3_CTRL8_XL, 0x09);
return 1;
}
and some definitions from the .h file
private:
TwoWire* _wire;
SPIClass* _spi;
uint8_t _slaveAddress;
int _csPin;
int _irqPin;
SPISettings _spiSettings;
};
The library is set up to use either the SPI or the I2C bus.
So, it is possible that some definition or setting outside of the library is forcing it to set up for I2C, which won't work. Be sure to select the correct board in the Arduino IDE.
Definitely have the correct one selected, but I was using the online editor. Tried on the IDE just now, same result. And it's definitely the correct board, and the same COM3 port I used back when everything worked
The sensor may have died an early death. There are plenty of external IMU modules that you can substitute. I would recommend to use the I2C bus to avoid conflicts with the built in sensor.