Scusate non volevo sollevare un vespaio.
Ho continuato a fare prove e ho capito dove era l'errore.
I risultati ottenuti attraverso la funzione ora sono uguali a quelli che ottengo mettendo le istruzioni dentro al LOOP.
Lo sketch arriva da esempi allegati alle librerie della scheda, adesso non so se i risultati che ottengo sono sensati.
Ho seguito una procedura di calibrazione fornita in questo link
A me interessava ottenere il valore risultante del campo magnetico, che dovrebbe essere costante a parità di posizione per qualsiasi orientamento.
Al momento non ottengo questo ma forse ho il sensore di scarsa qualità, perchè quando faccio le letture dei registri uno di essi non restituisce sempre lo stesso valore.
Grazie per la pazienza.
Allego per condivisione, un file XLS, che concatenando i testi mi ha permesso di velocizzare la scrittura dei vettori
/*
I2C comunication
to read from registers
magnetic sensor HMC5883L alias gy271
CS pin 3v3
SDA pin SDA +10k to 3v3
SDO pin GND
SCL pin SCL +10k to 3v3
3v3 VCC
GND GND
*/
#include <Wire.h>
#define DEVICE (0x1E)//HMC5883L_ device addressE
#define TO_READ (13)//num of bytes-1 we are going to read each time
byte buff[TO_READ]; //n bytes buffer for saving data read from the device
#define HMC5883L_Configuration_Register_A_ (0x00) // Read/Write
#define HMC5883L_Configuration_Register_B_ (0x01) // Read/Write
#define HMC5883L_Mode_Register (0x02) // Read/Write
#define HMC5883L_Data_Output_X_MSBRegister (0x03) // Read
#define HMC5883L_Data_Output_X_LSBRegister (0x04) // Read
#define HMC5883L_Data_Output_Z_MSBRegister (0x05) // Read
#define HMC5883L_Data_Output_Z_LSBRegister (0x06) // Read
#define HMC5883L_Data_Output_Y_MSBRegister (0x07) // Read
#define HMC5883L_Data_Output_Y_LSBRegister (0x08) // Read
#define HMC5883L_Status_Register_ (0x09) // Read
#define HMC5883L_Identification_Register_A_ (0x0A) // Read
#define HMC5883L_Identification_Register_B_ (0x0B) // Read
#define HMC5883L_Identification_Register_C_ (0x0C) // Read
char* reg[] =
{
"HMC5883L_Configuration_Register_A_",
"HMC5883L_Configuration_Register_B_",
"HMC5883L_Mode_Register",
"HMC5883L_Data_Output_X_MSBRegister",
"HMC5883L_Data_Output_X_LSBRegister",
"HMC5883L_Data_Output_Z_MSBRegister",
"HMC5883L_Data_Output_Z_LSBRegister",
"HMC5883L_Data_Output_Y_MSBRegister",
"HMC5883L_Data_Output_Y_LSBRegister",
"HMC5883L_Status_Register_",
"HMC5883L_Identification_Register_A_",
"HMC5883L_Identification_Register_B_",
"HMC5883L_Identification_Register_C_"
};
byte reg_[] =
{
HMC5883L_Configuration_Register_A_,
HMC5883L_Configuration_Register_B_,
HMC5883L_Mode_Register,
HMC5883L_Data_Output_X_MSBRegister,
HMC5883L_Data_Output_X_LSBRegister,
HMC5883L_Data_Output_Z_MSBRegister,
HMC5883L_Data_Output_Z_LSBRegister,
HMC5883L_Data_Output_Y_MSBRegister,
HMC5883L_Data_Output_Y_LSBRegister,
HMC5883L_Status_Register_,
HMC5883L_Identification_Register_A_,
HMC5883L_Identification_Register_B_,
HMC5883L_Identification_Register_C_
};
int _hmc5883_Gauss_LSB_XY;
int _hmc5883_Gauss_LSB_Z;
float _magData_x, magnetic_x;
float _magData_z, magnetic_z;
float _magData_y, magnetic_y;
float _mag_vector;
float magnetic[3];
float calibrated_values[3];
byte k_ = 1;
byte SENSORS_GAUSS_TO_MICROTESLA;
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
//Turning on the sensor
_hmc5883_Gauss_LSB_XY = 1100.0;
_hmc5883_Gauss_LSB_Z = 980.0;
SENSORS_GAUSS_TO_MICROTESLA = 100;
writeTo(DEVICE, reg_[0], 0b00010000); //enter register value
delay(100);
writeTo(DEVICE, reg_[1], 0b00000000); //enter register value
delay(100);
writeTo(DEVICE, reg_[2], 0b00000000); //enter register value
delay(100);
for (int k = 0; k < 3; k++)
{
readFrom(DEVICE, reg_, TO_READ, buff); //read the acceleration data from the sensor
Serial.println(reg[k]);
Serial.print(k);
Serial.print('\t');
Serial.print("0x");
Serial.print(reg_[k], HEX);
Serial.print('\t');
Serial.print(buff[k], BIN);
Serial.println();
delay(200);//It appears that delay is needed in order not to clog the port
}
}
void loop()
{
// Serial.println("START++++++++++++++++++++++++++++++++++++++++++++++");
for (byte k = 0; k < TO_READ; k++)
{
readFrom(DEVICE, reg_, TO_READ, buff); //read the acceleration data from the sensor
// delay(200);//It appears that delay is needed in order not to clog the port
}
_magData_x = buff[4] | (buff[3] << 8);
//Serial.println(buff[4]);
_magData_y = buff[8] | (buff[7] << 8);
//Serial.println(_magData_y);
_magData_z = buff[6] | (buff[5] << 8);
//Serial.println(_magData_z);
magnetic[0] = _magData_x / _hmc5883_Gauss_LSB_XY * SENSORS_GAUSS_TO_MICROTESLA;
magnetic[1] = _magData_y / _hmc5883_Gauss_LSB_XY * SENSORS_GAUSS_TO_MICROTESLA;
magnetic[2] = _magData_z / _hmc5883_Gauss_LSB_Z * SENSORS_GAUSS_TO_MICROTESLA;
// for (byte k = 0; k < 3; k++)
// {
// transformation(magnetic, k);
// }
transformation(magnetic, k_);
k_++;
Serial.print(calibrated_values[0]);
Serial.print('\t');
Serial.print(calibrated_values[1]);
Serial.print('\t');
Serial.println(calibrated_values[2]);
Serial.println();
_mag_vector = pow((pow(calibrated_values[0], 2) + pow(calibrated_values[1], 2) + pow(calibrated_values[1], 2)) , 0.5);
Serial.println(_mag_vector);
delay(200);//It appears that delay is needed in order not to clog the port
}//fine loop
///////////////////////////////////////////////////////////////////////////////////
void readFrom(int device, byte reg_address, int num, byte buff[])
{
Wire.beginTransmission(device); //start transmission to device
Wire.write(reg_address); //sends address to read from
Wire.endTransmission(); //end transmission
Wire.beginTransmission(device); //start transmission to device (initiate again)
Wire.requestFrom(device, num); // request TO_READ bytes from device
int i = 0;
while (Wire.available()) //device may send less than requested (abnormal)
{
buff[i] = Wire.read(); // receive a byte
i++;
}
Wire.endTransmission(); //end transmission
}
///////////////////////////////////////////////////////////////////////////////////
void writeTo(int device, byte reg_address, byte val)
{
Wire.beginTransmission(device); //start transmission to device
Wire.write(reg_address); // send register address
Wire.write(val); // send value to write
Wire.endTransmission(); //end transmission
}
////////////////////////////////////////////////////////////////////////////////////
void transformation(float uncalibrated_values[], byte _k)
{
// float calibrated_values[3];
//calibration_matrix[3][3] is the transformation matrix
//replace M11, M12,..,M33 with your transformation matrix data
double calibration_matrix[3][3] =
{
{1.287,0.022,0.08},
{0.024,1.278,0.024},
{0.033,-0.01,1.129}
};
//bias[3] is the bias
//replace Bx, By, Bz with your bias data
double bias[3] =
{1.287,0.024,0.033};
//calculation
for (byte i = 0; i < 3; ++i)
{
uncalibrated_values[i] = uncalibrated_values[i] - bias[i];
}
float result[3] = {0, 0, 0};
for (byte i = 0; i < 3; ++i)
for (byte j = 0; j < 3; ++j)
{
result[i] += calibration_matrix[i][j] * uncalibrated_values[j];
}
for (byte i = 0; i < 3; ++i)
{
calibrated_values[i] = result[i];
// result[i] = 0;
}
}
i2c_registri.zip (19.1 KB)