lettura registri sensore I2C (chiudo e apro altro topic)

Ciao
Sto lavorando con un sensore AS7263
https://ams.com/as7263#tab/features
ma sto incontrando alcuni problemi forniti con gli esempi delle librerie-
Intanto ho cercato di leggere i registri con questo sketch:

/*
  I2C comunication
  to read from registers

  CS pin 3v3
  SDA pin SDA +10k to 3v3
  SDO pin GND
  SCL pin SCL +10k to 3v3
  3v3 VCC
  GND GND
*/
#define AS72XX_Device_Type       (0x00)    // HW_Version Device Type
#define AS72XX_HW_Version        (0x01)    // HW_Version HW_Version
#define AS72XX_FW_Version_m      (0x02)    // FW_Version minor
#define AS72XX_FW_Version_M      (0x03)    // FW_Version major
#define AS72XX_Control_Setup     (0x04)    // Control_Setup
#define AS72XX_INT_T             (0x05)    // INT_T
#define AS72XX_Device_Temp       (0x06)    // Device_Temp
#define AS72XX_LED_Control       (0x07)    // LED Control

#define AS72XX_R_High            (0x08)    // R_High
#define AS72XX_R_Low             (0x09)    // R_Low

#define AS72XX_S_High            (0x0A)    // S_High
#define AS72XX_S_Low             (0x0B)    // S_Low

#define AS72XX_T_High            (0x0C)    // T_High
#define AS72XX_T_Low             (0x0D)    // T_Low

#define AS72XX_U_High            (0x0E)    // U_High
#define AS72XX_U_Low             (0x0F)    // U_Low

#define AS72XX_V_High            (0x10)    // V_High
#define AS72XX_V_Low             (0x11)    // V_Low

#define AS72XX_W_High            (0x12)    // W_High
#define AS72XX_W_Low             (0x13)    // W_Low

#define AS72XX_R_Cal_1           (0x14)    // R_Cal
#define AS72XX_R_Cal_2           (0x15)    // R_Cal
#define AS72XX_R_Cal_3           (0x16)    // R_Cal
#define AS72XX_R_Cal_4           (0x17)    // R_Cal

#define AS72XX_S_Cal_1           (0x18)    // S_Cal
#define AS72XX_S_Cal_1           (0x19)    // S_Cal
#define AS72XX_S_Cal_1           (0x1A)    // S_Cal
#define AS72XX_S_Cal_1           (0x1B)   // S_Cal

#define AS72XX_T_Cal_1           (0x1C)    // T_Cal
#define AS72XX_T_Cal_2           (0x1D)    // T_Cal
#define AS72XX_T_Cal_3           (0x1E)    // T_Cal
#define AS72XX_T_Cal_4           (0x1F)    // T_Cal

#define AS72XX_U_Cal_1           (0x20)    // U_Cal
#define AS72XX_U_Cal_2           (0x21)    // U_Cal
#define AS72XX_U_Cal_3           (0x22)    // U_Cal
#define AS72XX_U_Cal_4           (0x23)    // U_Cal

#define AS72XX_V_Cal_1           (0x24)    // V_Cal
#define AS72XX_V_Cal_2           (0x25)    // V_Cal
#define AS72XX_V_Cal_3           (0x26)    // V_Cal
#define AS72XX_V_Cal_4           (0x27)    // V_Cal

#define AS72XX_W_Cal_1           (0x28)    // W_Cal
#define AS72XX_W_Cal_2           (0x29)    // W_Cal
#define AS72XX_W_Cal_3           (0x2A)    // W_Cal
#define AS72XX_W_Cal_4           (0x2B)    // W_Cal

//44 registrers
/*=========================================================================*/
#include <Wire.h>

#define DEVICE (0x49)//ADXL345 device address
#define TO_READ (44)//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
int AS72XX_REG_ = AS72XX_Device_Type;//indirizzo di partenza
//int AS72XX_REG_ = 29;//indirizzo di partenza
//byte reg_[TO_READ];

char* reg[] = {
  "AS72XX_Device_Type",
  "AS72XX_HW_Version",
  "AS72XX_FW_Version_m",
  "AS72XX_FW_Version_M",
  "AS72XX_Control_Setup",
  "AS72XX_INT_T",
  "AS72XX_Device_Temp",
  "AS72XX_LED Control",

  "AS72XX_R_High",
  "AS72XX_R_Low",

  "AS72XX_S_High",
  "AS72XX_S_Low",

  "AS72XX_T_High",
  "AS72XX_T_Low",

  "AS72XX_U_High",
  "AS72XX_U_Low",

  "AS72XX_V_High",
  "AS72XX_V_Low",

  "AS72XX_W_High",
  "AS72XX_W_Low",

  "AS72XX_R_Cal_1",
  "AS72XX_R_Cal_2",
  "AS72XX_R_Cal_3",
  "AS72XX_R_Cal_4",

  "AS72XX_S_Cal_1",
  "AS72XX_S_Cal_1",
  "AS72XX_S_Cal_1",
  "AS72XX_S_Cal_1",

  "AS72XX_T_Cal_1",
  "AS72XX_T_Cal_2",
  "AS72XX_T_Cal_3",
  "AS72XX_T_Cal_4",

  "AS72XX_U_Cal_1",
  "AS72XX_U_Cal_2",
  "AS72XX_U_Cal_3",
  "AS72XX_U_Cal_4",

  "AS72XX_V_Cal_1",
  "AS72XX_V_Cal_2",
  "AS72XX_V_Cal_3",
  "AS72XX_V_Cal_4",

  "AS72XX_W_Cal_1",
  "AS72XX_W_Cal_2",
  "AS72XX_W_Cal_3",
  "AS72XX_W_Cal_4"
};


byte reg_[] = {
  AS72XX_Device_Type,
  AS72XX_HW_Version,
  AS72XX_FW_Version_m,
  AS72XX_FW_Version_M,
  AS72XX_Control_Setup,
  AS72XX_INT_T,
  AS72XX_Device_Temp,
  AS72XX_LED_Control,

  AS72XX_R_High,
  AS72XX_R_Low,

  AS72XX_S_High,
  AS72XX_S_Low,

  AS72XX_T_High,
  AS72XX_T_Low,

  AS72XX_U_High,
  AS72XX_U_Low,

  AS72XX_V_High,
  AS72XX_V_Low,

  AS72XX_W_High,
  AS72XX_W_Low,

  AS72XX_R_Cal_1,
  AS72XX_R_Cal_2,
  AS72XX_R_Cal_3,
  AS72XX_R_Cal_4,

  AS72XX_S_Cal_1,
  AS72XX_S_Cal_1,
  AS72XX_S_Cal_1,
  AS72XX_S_Cal_1,

  AS72XX_T_Cal_1,
  AS72XX_T_Cal_2,
  AS72XX_T_Cal_3,
  AS72XX_T_Cal_4,

  AS72XX_U_Cal_1,
  AS72XX_U_Cal_2,
  AS72XX_U_Cal_3,
  AS72XX_U_Cal_4,

  AS72XX_V_Cal_1,
  AS72XX_V_Cal_2,
  AS72XX_V_Cal_3,
  AS72XX_V_Cal_4,

  AS72XX_W_Cal_1,
  AS72XX_W_Cal_2,
  AS72XX_W_Cal_3,
  AS72XX_W_Cal_4
};

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  //Turning on the sensor

  //  writeTo(DEVICE, 0x2D, 0x00); //enter in standby mode to configure
  //  writeTo(DEVICE, 0x31, 0b00000000); //0b00000011 self mode off with 10 bit resolution 2g
  //  writeTo(DEVICE, 0x31, 0b00000011); //0b00000011 self mode off with 10 bit resolution 16g
  //writeTo(DEVICE, 0x31, 0b00001011); //0b00001011 self mode off with 13 bit resolution 16g

  //  writeTo(DEVICE, 0x2C, 0x0F); //set 100 Hz data rate
  // writeTo(DEVICE, 0x38, 0x80); //FIFO stream mode
  //  writeTo(DEVICE, 0x2D, 0x08); //enter in measurement mode
}

void loop()
{
  Serial.println("START");
  for (int k = 0; k < TO_READ; k++)
  {
    //    readFrom(DEVICE, AS72XX_REG_, TO_READ, buff); //read the acceleration data from the ADXL345
    readFrom(DEVICE, reg_, TO_READ, buff); //read the acceleration data from the ADXL345

    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(100);//It appears that delay is needed in order not to clog the port
  }
  delay(100);//It appears that delay is needed in order not to clog the port
}//fine loop

///////////////////////////////////////////////////////////////////////////////////
void readFrom(int device, byte address, int num, byte buff[])
{
  Wire.beginTransmission(device); //start transmission to device
  Wire.write(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 address, byte val)
{
  Wire.beginTransmission(device); //start transmission to device
  Wire.write(address);        // send register address
  Wire.write(val);        // send value to write
  Wire.endTransmission(); //end transmission
}

con questo output:

START
0 0x0 10000000
1 0x1 0
2 0x2 0
3 0x3 0
4 0x4 0
5 0x5 0
6 0x6 0
7 0x7 0
8 0x8 0
9 0x9 0
10 0xA 0
11 0xB 0
12 0xC 0
13 0xD 0
14 0xE 0
15 0xF 0
16 0x10 1110010
17 0x11 1000000
18 0x12 0
19 0x13 0
20 0x14 0
21 0x15 0
22 0x16 0
23 0x17 0
24 0x1B 0
25 0x1B 0
26 0x1B 0
27 0x1B 0
28 0x1C 0
29 0x1D 0
30 0x1E 0
31 0x1F 0
32 0x20 0
33 0x21 0
34 0x22 0
35 0x23 0
36 0x24 0
37 0x25 0
38 0x26 0
39 0x27 0
40 0x28 0
41 0x29 0
42 0x2A 0
43 0x2B 0

skecth e output sono sensati? (

Ma come hai collegato quel integrato all' Arduino?
Ciao Uwe

Ciao
lato sensore SCL → SCL lato arduino
lato sensore SDA → SDA lato arduino
lato sensore GND → GND lato arduino
lato sensore 3V3 → 3V3 lato arduino

le resistenze da 10k le vedo già integrate

Qwiic_Spectral_Sensor-AS726x_v10.pdf (90.5 KB)

Ciao
Da prove fatte con altro sensore e datasheet questo sketch mi soddisfa:

/*
  I2C comunication
  to read from registers
  magnetic sensor HMC5883L

  CS pin 3v3
  SDA pin SDA +10k to 3v3
  SDO pin GND
  SCL pin SCL +10k to 3v3
  3v3 VCC
  GND GND
*/
#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

/*=========================================================================*/
#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
//int HMC5883L_ = HMC5883L_Configuration_Register_A_;//indirizzo di partenza

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_
};

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  //Turning on the sensor

//  writeTo(DEVICE, reg_[0], 0x10); //enter register value
//    writeTo(DEVICE, reg_[1], 0x20); //enter register value
     writeTo(DEVICE, reg_[2], 0x00); //enter register value
}

void loop()
{
  Serial.println("START++++++++++++++++++++++++++++++++++++++++++++++");
  for (int k = 0; k < TO_READ; k++)
  {
    readFrom(DEVICE, reg_, TO_READ, buff); //read the acceleration data from the ADXL345

    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(100);//It appears that delay is needed in order not to clog the port
  }
  delay(100);//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
}

Riesco scrivere e leggo quanto impostato.

Ora ho una altra domanda:
è possibile lavorare con questo sensore GY271 senza richiamare librerie particolari, ho provato a comprenderle ma sono abbastanza complicate per il mio livello

Nel post successivo le librerie

Adafruit_HMC5883_U.ccp

/***************************************************************************
  This is a library for the HMC5883 magnentometer/compass

  Designed specifically to work with the Adafruit HMC5883 Breakout
  http://www.adafruit.com/products/1746

  These displays use I2C to communicate, 2 pins are required to interface.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Kevin Townsend for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/
#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

#ifdef __AVR_ATtiny85__
  #include "TinyWireM.h"
  #define Wire TinyWireM
#else
  #include <Wire.h>
#endif

#include <limits.h>

#include "Adafruit_HMC5883_U.h"

static float _hmc5883_Gauss_LSB_XY = 1100.0F;  // Varies with gain
static float _hmc5883_Gauss_LSB_Z  = 980.0F;   // Varies with gain

/***************************************************************************
 MAGNETOMETER
 ***************************************************************************/
/***************************************************************************
 PRIVATE FUNCTIONS
 ***************************************************************************/

/**************************************************************************/
/*!
    @brief  Abstract away platform differences in Arduino wire library
*/
/**************************************************************************/
void Adafruit_HMC5883_Unified::write8(byte address, byte reg, byte value)
{
  Wire.beginTransmission(address);
  #if ARDUINO >= 100
    Wire.write((uint8_t)reg);
    Wire.write((uint8_t)value);
  #else
    Wire.send(reg);
    Wire.send(value);
  #endif
  Wire.endTransmission();
}

/**************************************************************************/
/*!
    @brief  Abstract away platform differences in Arduino wire library
*/
/**************************************************************************/
byte Adafruit_HMC5883_Unified::read8(byte address, byte reg)
{
  byte value;

  Wire.beginTransmission(address);
  #if ARDUINO >= 100
    Wire.write((uint8_t)reg);
  #else
    Wire.send(reg);
  #endif
  Wire.endTransmission();
  Wire.requestFrom(address, (byte)1);
  #if ARDUINO >= 100
    value = Wire.read();
  #else
    value = Wire.receive();
  #endif  
  Wire.endTransmission();

  return value;
}

/**************************************************************************/
/*!
    @brief  Reads the raw data from the sensor
*/
/**************************************************************************/
void Adafruit_HMC5883_Unified::read()
{
  // Read the magnetometer
  Wire.beginTransmission((byte)HMC5883_ADDRESS_MAG);
  #if ARDUINO >= 100
    Wire.write(HMC5883_REGISTER_MAG_OUT_X_H_M);
  #else
    Wire.send(HMC5883_REGISTER_MAG_OUT_X_H_M);
  #endif
  Wire.endTransmission();
  Wire.requestFrom((byte)HMC5883_ADDRESS_MAG, (byte)6);
  
  // Wait around until enough data is available
  while (Wire.available() < 6);

  // Note high before low (different than accel)  
  #if ARDUINO >= 100
    uint8_t xhi = Wire.read();
    uint8_t xlo = Wire.read();
    uint8_t zhi = Wire.read();
    uint8_t zlo = Wire.read();
    uint8_t yhi = Wire.read();
    uint8_t ylo = Wire.read();
  #else
    uint8_t xhi = Wire.receive();
    uint8_t xlo = Wire.receive();
    uint8_t zhi = Wire.receive();
    uint8_t zlo = Wire.receive();
    uint8_t yhi = Wire.receive();
    uint8_t ylo = Wire.receive();
  #endif
  
  // Shift values to create properly formed integer (low byte first)
  _magData.x = (int16_t)(xlo | ((int16_t)xhi << 8));
  _magData.y = (int16_t)(ylo | ((int16_t)yhi << 8));
  _magData.z = (int16_t)(zlo | ((int16_t)zhi << 8));
  
  // ToDo: Calculate orientation
  _magData.orientation = 0.0;
}

/***************************************************************************
 CONSTRUCTOR
 ***************************************************************************/
 
/**************************************************************************/
/*!
    @brief  Instantiates a new Adafruit_HMC5883 class
*/
/**************************************************************************/
Adafruit_HMC5883_Unified::Adafruit_HMC5883_Unified(int32_t sensorID) {
  _sensorID = sensorID;
}

/***************************************************************************
 PUBLIC FUNCTIONS
 ***************************************************************************/
 
/**************************************************************************/
/*!
    @brief  Setups the HW
*/
/**************************************************************************/
bool Adafruit_HMC5883_Unified::begin()
{
  // Enable I2C
  Wire.begin();

  // Enable the magnetometer
  write8(HMC5883_ADDRESS_MAG, HMC5883_REGISTER_MAG_MR_REG_M, 0x00);
  
  // Set the gain to a known level
  setMagGain(HMC5883_MAGGAIN_1_3);

  return true;
}

/**************************************************************************/
/*!
    @brief  Sets the magnetometer's gain
*/
/**************************************************************************/
void Adafruit_HMC5883_Unified::setMagGain(hmc5883MagGain gain)
{
  write8(HMC5883_ADDRESS_MAG, HMC5883_REGISTER_MAG_CRB_REG_M, (byte)gain);
  
  _magGain = gain;
 
  switch(gain)
  {
    case HMC5883_MAGGAIN_1_3:
      _hmc5883_Gauss_LSB_XY = 1100;
      _hmc5883_Gauss_LSB_Z  = 980;
      break;
    case HMC5883_MAGGAIN_1_9:
      _hmc5883_Gauss_LSB_XY = 855;
      _hmc5883_Gauss_LSB_Z  = 760;
      break;
    case HMC5883_MAGGAIN_2_5:
      _hmc5883_Gauss_LSB_XY = 670;
      _hmc5883_Gauss_LSB_Z  = 600;
      break;
    case HMC5883_MAGGAIN_4_0:
      _hmc5883_Gauss_LSB_XY = 450;
      _hmc5883_Gauss_LSB_Z  = 400;
      break;
    case HMC5883_MAGGAIN_4_7:
      _hmc5883_Gauss_LSB_XY = 400;
      _hmc5883_Gauss_LSB_Z  = 255;
      break;
    case HMC5883_MAGGAIN_5_6:
      _hmc5883_Gauss_LSB_XY = 330;
      _hmc5883_Gauss_LSB_Z  = 295;
      break;
    case HMC5883_MAGGAIN_8_1:
      _hmc5883_Gauss_LSB_XY = 230;
      _hmc5883_Gauss_LSB_Z  = 205;
      break;
  } 
}

/**************************************************************************/
/*! 
    @brief  Gets the most recent sensor event
*/
/**************************************************************************/
bool Adafruit_HMC5883_Unified::getEvent(sensors_event_t *event) {
  /* Clear the event */
  memset(event, 0, sizeof(sensors_event_t));

  /* Read new data */
  read();
  
  event->version   = sizeof(sensors_event_t);
  event->sensor_id = _sensorID;
  event->type      = SENSOR_TYPE_MAGNETIC_FIELD;
  event->timestamp = 0;
  event->magnetic.x = _magData.x / _hmc5883_Gauss_LSB_XY * SENSORS_GAUSS_TO_MICROTESLA;
  event->magnetic.y = _magData.y / _hmc5883_Gauss_LSB_XY * SENSORS_GAUSS_TO_MICROTESLA;
  event->magnetic.z = _magData.z / _hmc5883_Gauss_LSB_Z * SENSORS_GAUSS_TO_MICROTESLA;
  
  return true;
}

/**************************************************************************/
/*! 
    @brief  Gets the sensor_t data
*/
/**************************************************************************/
void Adafruit_HMC5883_Unified::getSensor(sensor_t *sensor) {
  /* Clear the sensor_t object */
  memset(sensor, 0, sizeof(sensor_t));

  /* Insert the sensor name in the fixed length char array */
  strncpy (sensor->name, "HMC5883", sizeof(sensor->name) - 1);
  sensor->name[sizeof(sensor->name)- 1] = 0;
  sensor->version     = 1;
  sensor->sensor_id   = _sensorID;
  sensor->type        = SENSOR_TYPE_MAGNETIC_FIELD;
  sensor->min_delay   = 0;
  sensor->max_value   = 800; // 8 gauss == 800 microTesla
  sensor->min_value   = -800; // -8 gauss == -800 microTesla
  sensor->resolution  = 0.2; // 2 milligauss == 0.2 microTesla
}

Adafruit_HMC5883_U.h

/***************************************************************************
  This is a library for the HMC5883 magnentometer/compass

  Designed specifically to work with the Adafruit HMC5883 Breakout
  http://www.adafruit.com/products/1746

  These displays use I2C to communicate, 2 pins are required to interface.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Kevin Townsend for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/
#ifndef __HMC5883_H__
#define __HMC5883_H__

#if (ARDUINO >= 100)
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

#include <Adafruit_Sensor.h>

#ifdef __AVR_ATtiny85__
  #include "TinyWireM.h"
  #define Wire TinyWireM
#else
  #include <Wire.h>
#endif


/*=========================================================================
    I2C ADDRESS/BITS
    -----------------------------------------------------------------------*/
    #define HMC5883_ADDRESS_MAG            (0x3C >> 1)         // 0011110x
/*=========================================================================*/

/*=========================================================================
    REGISTERS
    -----------------------------------------------------------------------*/
    typedef enum
    {
      HMC5883_REGISTER_MAG_CRA_REG_M             = 0x00,
      HMC5883_REGISTER_MAG_CRB_REG_M             = 0x01,
      HMC5883_REGISTER_MAG_MR_REG_M              = 0x02,
      HMC5883_REGISTER_MAG_OUT_X_H_M             = 0x03,
      HMC5883_REGISTER_MAG_OUT_X_L_M             = 0x04,
      HMC5883_REGISTER_MAG_OUT_Z_H_M             = 0x05,
      HMC5883_REGISTER_MAG_OUT_Z_L_M             = 0x06,
      HMC5883_REGISTER_MAG_OUT_Y_H_M             = 0x07,
      HMC5883_REGISTER_MAG_OUT_Y_L_M             = 0x08,
      HMC5883_REGISTER_MAG_SR_REG_Mg             = 0x09,
      HMC5883_REGISTER_MAG_IRA_REG_M             = 0x0A,
      HMC5883_REGISTER_MAG_IRB_REG_M             = 0x0B,
      HMC5883_REGISTER_MAG_IRC_REG_M             = 0x0C,
      HMC5883_REGISTER_MAG_TEMP_OUT_H_M          = 0x31,
      HMC5883_REGISTER_MAG_TEMP_OUT_L_M          = 0x32
    } hmc5883MagRegisters_t;
/*=========================================================================*/

/*=========================================================================
    MAGNETOMETER GAIN SETTINGS
    -----------------------------------------------------------------------*/
    typedef enum
    {
      HMC5883_MAGGAIN_1_3                        = 0x20,  // +/- 1.3
      HMC5883_MAGGAIN_1_9                        = 0x40,  // +/- 1.9
      HMC5883_MAGGAIN_2_5                        = 0x60,  // +/- 2.5
      HMC5883_MAGGAIN_4_0                        = 0x80,  // +/- 4.0
      HMC5883_MAGGAIN_4_7                        = 0xA0,  // +/- 4.7
      HMC5883_MAGGAIN_5_6                        = 0xC0,  // +/- 5.6
      HMC5883_MAGGAIN_8_1                        = 0xE0   // +/- 8.1
    } hmc5883MagGain; 
/*=========================================================================*/

/*=========================================================================
    INTERNAL MAGNETOMETER DATA TYPE
    -----------------------------------------------------------------------*/
    typedef struct hmc5883MagData_s
    {
        float x;
        float y;
        float z;
      float orientation;
    } hmc5883MagData;
/*=========================================================================*/

/*=========================================================================
    CHIP ID
    -----------------------------------------------------------------------*/
    #define HMC5883_ID                     (0b11010100)
/*=========================================================================*/


/* Unified sensor driver for the magnetometer */
class Adafruit_HMC5883_Unified : public Adafruit_Sensor
{
  public:
    Adafruit_HMC5883_Unified(int32_t sensorID = -1);
  
    bool begin(void);
    void setMagGain(hmc5883MagGain gain);
    bool getEvent(sensors_event_t*);
    void getSensor(sensor_t*);

  private:
    hmc5883MagGain   _magGain;
    hmc5883MagData   _magData;     // Last read magnetometer data will be available here
    int32_t         _sensorID;
    
    void write8(byte address, byte reg, byte value);
    byte read8(byte address, byte reg);
    void read(void);
};

#endif

questa esperessione:

_magData.x = (int16_t)(xlo | ((int16_t)xhi << 8));

seguendo il REFERENCE
se ho capito, prende xlo (16bits) lo sovrappone ad xhi (16bits) shiftato di 8bits verso sx
è corretto?

unisce i due byte HIGH e LOW in uno solo chiamato x facendo un or con xhi e xlo per cui i primi 8 sono lo xhi shiftato di 8 (<< 8 ) e i secondi 8 lo xlo

grazie perfetto ho capito
come conferma posso scriverlo anche così:

_magData.x = (((int16_t)xhi << 8) | (int16_t)(xlo));

Sul datasheet leggo:

Register Access
This section describes the process of reading from and writing to this device. The devices uses an address pointer to indicate which register location is to be read from or written to. These pointer locations are sent from the master to this slave device and succeed the 7-bit address (0x1E) plus 1 bit read/write identifier, i.e. 0x3D for read and 0x3C for write.
...
1. Write CRA (00) – send 0x3C 0x00 0x70 (8-average, 15 Hz default, normal measurement)
2. Write CRB (01) – send 0x3C 0x01 0xA0 (Gain=5, or any other desired gain)
3. Write Mode (02) – send 0x3C 0x02 0x00 (Continuous-measurement mode)
4. Wait 6 ms or monitor status register or DRDY hardware interrupt pin
5. Loop
Send 0x3D 0x06 (Read all 6 bytes. If gain is changed then this data set is using previous gain)
Convert three 16-bit 2’s compliment hex values to decimal values and assign to X, Z, Y, respectively.
Send 0x3C 0x03 (point to first data register 03)
Wait about 67 ms (if 15 Hz rate) or monitor status register or DRDY hardware interrupt pin
End_loop

ma io leggo e scrivo senza utilizzare quei valori

HMC5883L_3-Axis_Digital_Compass_IC.pdf (772 KB)