ciao a tutti,
sto un pochino litigando con la lettura del sensore BNO055 tramite I2C senza utilizzare librerie.
nel mio progetto in realtà utilizzo una libreria per leggere i dati che è la MKRIMU.
unico problema? libreria un po' abbandonata a se stessa, mancano molte funzionalità semplici da implementare (a mio avviso).
questo sensore ha un algoritmo automatico di calibrazione che mi fornisce anche i valori con la quale è stato calibrato.
essendo che ogni volta non voglio stare a rifare la calibrazione (dovrei ruotare nello spazio il sensore) so che c'è la possibilità di caricare i valori della matrice di calibrazione al suo interno.
in più vorrei leggere anche lo stato di calibrazione del sistema(scritto nei vari registri).
ho provato a fare una semplice lettura di un registro, in particolare quello dedicato al valore di temperatura per esempio ma non sto ottenendo grandi risultati.
ho aperto la libreria che uso è ho cercato di capire come funziona per provare ad emularla ma non ci sto venendo a capo.
vi lascio il codice e il datasheet.
#include <Wire.h>
int16_t data [8];
#define BNNO055_ADDRESS 0x28
#define BNNO055_CHIP_ID_REG 0x00
#define BNNO055_ACC_DATA_X_LSB_REG 0x08
#define BNNO055_MAG_DATA_X_LSB_REG 0x0e
#define BNNO055_GYR_DATA_X_LSB_REG 0x14
#define BNNO055_EUL_DATA_X_LSB_REG 0x1a
#define BNNO055_PAGE_ID_REG 0x07
#define BNNO055_TEMP_REG 0x34
#define BNNO055_SYS_STATUS_REG 0x39
#define BNNO055_UNIT_SEL_REG 0x3b
#define BNNO055_OPR_MODE_REG 0x3d
#define BNNO055_SYS_TRIGGER_REG 0x3f
#define BNNO055_AXIS_MAP_CONFIG_REG 0x41
#define BNNO055_AXIS_MAP_SIGN_REG 0x42
//0x28
void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(9600);
// enter config mode
Wire.beginTransmission(BNNO055_ADDRESS);
Wire.write(0x3d);
Wire.write(0x00);
delay(100);
// select page id 0
Wire.beginTransmission(BNNO055_ADDRESS);
Wire.write(BNNO055_PAGE_ID_REG);
Wire.write(0x00);
delay(100);
// enable external clock
Wire.beginTransmission(BNNO055_ADDRESS);
Wire.write(BNNO055_SYS_TRIGGER_REG);
Wire.write(0x80);
delay(100);
// set acceleration unit to mG's, and fusion data output mode to Android
Wire.beginTransmission(BNNO055_ADDRESS);
Wire.write(BNNO055_UNIT_SEL_REG);
Wire.write(0x81);
delay(100);
// set X = X, Y = Y, Z = Z
Wire.beginTransmission(BNNO055_ADDRESS);
Wire.write(BNNO055_AXIS_MAP_CONFIG_REG);
Wire.write(0x24);
delay(100);
// invert X and Y axis signs
Wire.beginTransmission(BNNO055_ADDRESS);
Wire.write(BNNO055_AXIS_MAP_SIGN_REG);
Wire.write(0x06);
delay(100);
// enter NDOF mode
Wire.beginTransmission(BNNO055_ADDRESS);
Wire.write(BNNO055_OPR_MODE_REG);
Wire.write(0x0c);
delay(100);
}
void loop() {
readIMU();
delay(100);
}
void readIMU(){
Wire.beginTransmission(BNNO055_ADDRESS);
Wire.write(BNNO055_TEMP_REG);
Wire.endTransmission(false);
Wire.requestFrom(BNNO055_ADDRESS,7);
if (Wire.available()) {
for (int i = 0; i < 8; i++) {
data[i] = Wire.read();
Serial.print(data[i]);
}
}else return;
Serial.println("");
delay(1);
}
il datasheet
probabilmente sarà una cosa banale, ma ho provato a studiare il più possibile la libreria wire e capire come funzionava la libreria
edit:
vi lascio anche uno spezzone della libreria che dovrebbe andare a leggere la temperatura:
float IMUClass::readTemperature()
{
int temp = readRegister(BNNO055_TEMP_REG);
if (temp == -1) {
return NAN;
}
return (int8_t)temp;
}
int IMUClass::readRegister(uint8_t address)
{
_wire->beginTransmission(BNNO055_ADDRESS);
_wire->write(address);
if (_wire->endTransmission(false) != 0) {
return -1;
}
if (_wire->requestFrom(BNNO055_ADDRESS, 1) != 1) {
return -1;
}
return _wire->read();
}
int IMUClass::readRegisters(uint8_t address, uint8_t* data, size_t length)
{
_wire->beginTransmission(BNNO055_ADDRESS);
_wire->write(address);
if (_wire->endTransmission(false) != 0) {
return -1;
}
if (_wire->requestFrom(BNNO055_ADDRESS, length) != length) {
return 0;
}
for (size_t i = 0; i < length; i++) {
*data++ = _wire->read();
}
return 1;
}