hello,
who knows about CMPS11 IMU how to calculate it's raw accelerometer values to SI units (m/s² or gravity g fraction ?)
It's registers provide int16_t values for each x,y,z dimension (high + low byte), but which physical unit does it represent ?
https://www.robotshop.com/media/files/pdf/datasheet-i2c-mode-cmps10.pdf (CMPS10/11 similar)
Register
16,17
Accelerometer X axis raw output, 16 bit signed integer with register 16 being the upper 8 bits
18,19
Accelerometer Y axis raw output, 16 bit signed integer with register 18 being the upper 8 bits
20,21
Accelerometer Z axis raw output, 16 bit signed integer with register 20 being the upper 8 bits
You could hold the accelerometer still, with any axis pointing up or down. The reading is equal to +/- g or +/- 9.8 m/s^2.
For all accelerometers, an offset and scale factor is required to properly calibrate each axis, as described in this blog article.
thanks, yes, the CMPS11 already has been calibrated, it's procedure is much simpler than for MPU6050/9050.
I just was curious about the units of the raw int values by design. apart from experimental readings.
e.g. even if I incidentally get vaues of approx. 10000 at rest for 1 axis, which might mean 1g, that does not always have to be true for 2g accelerations, too.
that does not always have to be true for 2g accelerations
Then do a systematic calibration, as described in this tutorial. That requires you to use calibrated accelerations.
no, the calibration is currently absolutely fine, the issue is just about the units of the raw readings and conversion to SI units.
who knows about CMPS11 IMU how to calculate it's raw accelerometer values to SI units (m/s² or gravity g fraction ?)
Explained in reply #1, first line. That reading is the scale factor required to convert to g or m/s^2.
no, the calibration is currently absolutely fine
You have provided no evidence that this is true. It almost certainly is not.
jremington, Delta_G:
where do you take your assumptions from?
the readings are sth like (fixed to table, almost horizontal, table edge close to North):
roll: 0 pitch: 0 angle full: 180.70
accx=15882
accy=-37
accz=28
roll: 0 pitch: 0 angle full: 180.90
accx=15900
accy=-4
accz=67
roll: 0 pitch: 0 angle full: 181.10
accx=15798
accy=-15
accz=66
/*****************************************
* CMPS11 I2C example for Arduino *
* By James Henderson, 2014 *
*****************************************/
// target MCU: Adafruit M0
#include <Wire.h>
#define CMPS11_ADDRESS 0x60 // Address of CMPS11 shifted right one bit for arduino wire library
#define ANGLE_8 1 // Register to read 8bit angle from
unsigned char high_byte, low_byte, angle8;
char pitch, roll;
unsigned int angle16;
double anglef;
int accx, accy, accz;
void setup()
{
Serial.begin(115200); // Start serial port
Wire.begin();
delay(1000);
Serial.println("starting...");
}
int read_cmps11() {
byte b, bbuf, b10,b11,b12,b13,b14,b15,b16,b17,b18,b19,b20,b21;
Wire.beginTransmission(CMPS11_ADDRESS); //starts communication with CMPS11
Wire.write(ANGLE_8); //Sends the register we wish to start reading from
Wire.endTransmission();
// Request 21 bytes from the CMPS11
// this will give us the 8 bit bearing,
// both bytes of the 16 bit bearing, pitch and roll
Wire.requestFrom(CMPS11_ADDRESS, 21);
while(Wire.available() < 21); // Wait for all bytes to come back
angle8 = Wire.read(); // 1; Read back the first 5 bytes
high_byte = Wire.read();
low_byte = Wire.read();
pitch = Wire.read();
roll = Wire.read(); // 5
bbuf=Wire.read();
bbuf=Wire.read();
bbuf=Wire.read();
bbuf=Wire.read();
b10= Wire.read(); // 10
b11= Wire.read();
b12= Wire.read();
b13= Wire.read();
b14= Wire.read();
b15= Wire.read();
b16= Wire.read(); // 16
b17= Wire.read();
b18= Wire.read();
b19= Wire.read();
b20= Wire.read();
b21= Wire.read(); // 21
accx= (int16_t)((b16<<8) + b17);
accy= (int16_t)((b18<<8) + b19);
accz= (int16_t)((b20<<8) + b21);
angle16 = (high_byte<<8) + low_byte; // Calculate 16 bit angle
anglef=angle16/10.0;
}
void loop()
{
char sbuf[100];
read_cmps11();
Serial.print("roll: "); // Display roll data
Serial.print(roll, DEC);
Serial.print(" pitch: "); // Display pitch data
Serial.print(pitch, DEC);
sprintf(sbuf, "%6.2f ", anglef);
Serial.println((String)" angle full: "+sbuf); // Display 16 bit angle with decimal place
Serial.print(" accx="); Serial.println(accx);
Serial.print(" accy="); Serial.println(accy);
Serial.print(" accz="); Serial.println(accz);
Serial.println();
delay(100); // Short delay before next loop
}
I probably misunderstood what you meant by "arbitrary values". Anyway, IIUC, they don't seem to be decimal fractions or 10x multiples of g or 1 m/s².
Surprisingly, other than accx, the accy or accz values never exceed 1000, even after multiple recalibrations. - perhaps the sensor is defective.
perhaps the sensor is defective
The output posted in reply #7 suggests that it is working exactly as expected.
15860 (give or take measurement noise, scale and offset errors) = 1g or 9.8 m/s^2 for the X axis.
jremington:
The output posted in reply #7 suggests that it is working exactly as expected.
15860 (give or take measurement noise, scale and offset errors) = 1g or 9.8 m/s^2 for the X axis.
yes, but as stated, if turning the IMU (roll, pitch), the accy and/or accz don't show 15860 but instead about 1000 max, whilst accx decreases to about zero.
If it was ok, accy and/or accz are expected to increase to 15860 actually then.
Additionally, roll and/or pitch don't show +-90° when turned to +-90°, just about +-50° or +-60°.
Forget the roll and pitch, the unit is not properly calibrated.
Read out and pay attention only to the steady state RAW values from the accelerometer.
Those values ARE NOT in the register locations you specified in the original post. Consult the documentation for the CMPS11 to see where those values are actually located.
Post those RAW values, for X axis, straight up and straight down, Y axis straight up and straight down, Z axis up and down.
If you need pictures, follow this tutorial.
Delta_G:
Not arbitrary values. Arbitrary units. Big difference.
...
So with your accelerometer, measure a known value (gravity) and get a conversion factor from this whatever unit that you are getting and the real units you want.
ah, ok, now I understand.
But as stated, unfortunately the raw accx values differ very much from accy and from accz, if orientated accordingly. So there obviously is no reliable arbitrary unit which fits to all, and they all are rather noisy.
That's why I needed the reliable value(s), which had to be expected for 1g earth gravity acceration in raw values, most possibly by design, or perhaps by multiple experimental readings of other people who own that IMU, too.
But as stated, unfortunately the raw accx values differ very much from accy and from accz, if orientated accordingly. So there obviously is no reliable arbitrary unit which fits to all, and they all are rather noisy.
You are reading the wrong registers.