Hello everyone,
I have 6 IMUs that I'm reading data from, so I use a multiplexer to switch between them. Today i calibrated the sensors and saved the values in the EEPROM of the Arduino Mega that I'm using. The code i used for saving the values comes from this post. Then, I created the calibrations functions that read from the EEPROM. After uploading the code, the arduino mega cannot identify the sensors. I tried connecting my other arduino mega, with the original code (without the calibration functions), and it worked as expected. Then I uploaded the new sketch (with the calibrations functions) and it stopped working again. I tried re-uploading the first sketch but the problem remained.
After @er_name_not_found's suggestion I'm posting the code in code tags. Thanks for the tip and the welcome!
The TCA communication code without the calibration functions
#include <Adafruit_FXOS8700.h>
#include <Adafruit_FXAS21002C.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#define TCAADDR 0x70
#define FRAMESIZE (45) //(1 + 4 + 4*3 + 4*3 + 4 + 4*3)
// accmag timestamp uint long + 3 floats acc + 3 floats mag + gyro timestamp uint long
#define NUMSENSORS 6
/* Assign a unique ID to this sensor at the same time */
Adafruit_FXOS8700 accelmag0 = Adafruit_FXOS8700(0x8700A, 0x8700B);
Adafruit_FXAS21002C gyro0 = Adafruit_FXAS21002C(0x0021002C);
byte dataframe[FRAMESIZE] ={0x00};
unsigned long timestamp;
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
// Wire.write(1 << i);
Wire.endTransmission();
}
void displaySensorDetails(void) {
sensor_t accel, mag, gy;
accelmag0.getSensor(&accel, &mag);
gyro0.getSensor(&gy);
Serial.println("------------------------------------");
Serial.println("ACCELEROMETER");
Serial.println("------------------------------------");
Serial.print("Sensor: ");
Serial.println(accel.name);
Serial.print("Driver Ver: ");
Serial.println(accel.version);
Serial.print("Unique ID: 0x");
Serial.println(accel.sensor_id, HEX);
Serial.print("Min Delay: ");
Serial.print(accel.min_delay);
Serial.println(" s");
Serial.print("Max Value: ");
Serial.print(accel.max_value, 4);
Serial.println(" m/s^2");
Serial.print("Min Value: ");
Serial.print(accel.min_value, 4);
Serial.println(" m/s^2");
Serial.print("Resolution: ");
Serial.print(accel.resolution, 8);
Serial.println(" m/s^2");
Serial.println("------------------------------------");
Serial.println("");
Serial.println("------------------------------------");
Serial.println("MAGNETOMETER");
Serial.println("------------------------------------");
Serial.print("Sensor: ");
Serial.println(mag.name);
Serial.print("Driver Ver: ");
Serial.println(mag.version);
Serial.print("Unique ID: 0x");
Serial.println(mag.sensor_id, HEX);
Serial.print("Min Delay: ");
Serial.print(accel.min_delay);
Serial.println(" s");
Serial.print("Max Value: ");
Serial.print(mag.max_value);
Serial.println(" uT");
Serial.print("Min Value: ");
Serial.print(mag.min_value);
Serial.println(" uT");
Serial.print("Resolution: ");
Serial.print(mag.resolution);
Serial.println(" uT");
Serial.println("------------------------------------");
Serial.println("");
Serial.println("------------------------------------");
Serial.println("GYROSCOPE");
Serial.println("------------------------------------");
Serial.print("Sensor: ");
Serial.println(gy.name);
Serial.print("Driver Ver: ");
Serial.println(gy.version);
Serial.print("Unique ID: 0x");
Serial.println(gy.sensor_id, HEX);
Serial.print("Max Value: ");
Serial.print(gy.max_value);
Serial.println(" rad/s");
Serial.print("Min Value: ");
Serial.print(gy.min_value);
Serial.println(" rad/s");
Serial.print("Resolution: ");
Serial.print(gy.resolution);
Serial.println(" rad/s");
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}
void setup(void) {
Serial.begin(115200);
/* Wait for the Serial Monitor */
while (!Serial) {
delay(1000);
}
Wire.begin();
for (uint8_t i=0; i<NUMSENSORS; i++) {
delay(100);
Serial.println("NXPsensor Test Accel+Gyro Test");
Serial.println("");
tcaselect(i);
/* Initialise the sensor */
if (!gyro0.begin()) {
/* There was a problem detecting the FXAS21002C ... check your connections
*/
Serial.println("Ooops, no FXAS21002C detected ... Check your wiring!");
while (1)
;
}
/* Initialise the sensor */
if (!accelmag0.begin(ACCEL_RANGE_4G)) {
/* There was a problem detecting the FXOS8700 ... check your connections */
Serial.println("Ooops, no FXOS8700 detected ... Check your wiring!");
while (1)
;
}
/* Display some basic information on this sensor */
displaySensorDetails();
}
timestamp = micros();
}
// https://arduino.stackexchange.com/questions/60863/print-byte-array-in-serial-monitor-screen-of-arduino-ide
//void printHex(uint8_t num) {
// char hexCar[2];
//
// sprintf(hexCar, "%02X", num);
// Serial.print(hexCar);
//}
void loop(void) {
// // Set sr to 100 Hz.
if ( micros() - timestamp <10000 - 10) {
// test micros()-timestamp>10000 ? delay( (micros()- timestamp-1000)/1000 : ; // delay for something less than time remaining only if there is a lot of time left
return;
}
timestamp = micros();
for (uint8_t i=0; i<NUMSENSORS; i++) {
tcaselect(i); //Change sensor
sensors_event_t aevent, mevent, gevent; //Nikos
/* Get a new sensor event */
accelmag0.getEvent(&aevent, &mevent);
gyro0.getEvent(&gevent);
/* dataframe:
* |UINT8_T| ULONG | FLOAT | FLOAT | FLOAT | FLOAT | FLOAT | FLOAT | ULONG | FLOAT | FLOAT | FLOAT |
* | - |- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|
* |sensor | accts | acc.x | acc.y | acc.z | mag.x | mag.y | mag.z | gyrts | gyr.x | gyr.y | gyr.z |
* | # | μs | m/s^2 | m/s^2 | m/s^2 | uT | uT | uT | μs | rad/s | rad/s | rad/s |
*
*/
dataframe[0] = i;
memcpy(&dataframe[1], &aevent.timestamp, 4);
memcpy(&dataframe[5], &aevent.acceleration, 12);
memcpy(&dataframe[17], &mevent.magnetic, 12);
memcpy(&dataframe[29], &gevent.timestamp, 4);
memcpy(&dataframe[33], &gevent.gyro, 12);
Serial.println("");
Serial.write(dataframe, FRAMESIZE);
}
// delay(10);
}
The calibration functions
template <class T> int EEPROM_readAnything(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
return i;
}
void getCalibration(int noIMU, double calibration[]){
unsigned int baseAddrTest = noIMU*12*4;
for (int i=0; i <= 11; i++){
double val;
int addr = (i*4)+baseAddrTest;
EEPROM_readAnything( addr, val);
calibration[i];
}
return;
}
bool calibrate_mag(sensors_event_t &mag_event, int noIMU){
double calibration[12];
getCalibration(noIMU, calibration);
float mx = mag_event.magnetic.x - calibration[0];
float my = mag_event.magnetic.y - calibration[1];
float mz = mag_event.magnetic.z - calibration[2];
mag_event.magnetic.x = mx * calibration[3] + my * calibration[6] + mz * calibration[7];
mag_event.magnetic.y = mx * calibration[6] + my * calibration[4] + mz * calibration[8];
mag_event.magnetic.z = mx * calibration[7] + my * calibration[8] + + mz * calibration[5];
}
bool calibrate_gyro(sensors_event_t &gyro_event, int noIMU){
double calibration[12];
getCalibration(noIMU, calibration);
gyro_event.gyro.x -= calibration[9];
gyro_event.gyro.y -= calibration[10];
gyro_event.gyro.z -= calibration[11];
return true;
}
The EEPROM read/write sketch
#include <EEPROM.h>
template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
const byte* p = (const byte*)(const void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++);
return i;
}
template <class T> int EEPROM_readAnything(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
return i;
}
unsigned int noIMU = 5;
double calibration[12] = {13.73, -33.57, -44.06, 0.0975, 0.964, 1.067, 0.033, -0.026, 0.024, -0.0082, -0.0164, -0.0003};
byte noElem = 12;
unsigned int baseAddr = noIMU*12*4;
unsigned int baseAddrTest;
unsigned int n = 0;
void setup() {
Serial.begin(9600);
//// // write data to eeprom
// for (int i=0; i <= noElem-1; i++){
// n = EEPROM_writeAnything( (i*4)+baseAddr, calibration[i]);
// }
// read data back
for (int NI=0; NI<=5; NI++){
Serial.print("Number of IMU:");
Serial.println(NI);
baseAddrTest = NI*12*4;
for (int i=0; i <= noElem-1; i++){
double val;
int addr = (i*4)+baseAddrTest;
n = EEPROM_readAnything( addr, val);
Serial.println(val,4);
}
}
}
void loop() {
}
Any ideas?