A few years ago I wrote this to do the thing with a MLX90393.
void fMLX90393_1( void * pvParameters )
{
int rx[10] = { 0 };
int _gain = MLX90393_GAIN_1X;
int xyResoultion = 0;
int zResoultion = 1;
int xRes;
int yRes;
int zRes;
float xAverage = 0.0f;
esp_err_t intError;
vTaskDelay( 500 ); // delay to let the other sensor come online 1st
intError = fWriteSPIdata8bits2( _hMLX90393_1, MLX90393_REG_RT ); // reset
vTaskDelay( 300 ); // allow reset time to complete
// set gain
intError = fWriteSPIdata32bits( _hMLX90393_1, MLX90393_REG_WR, 0x00, (((_gain & 0x7) << MLX90393_GAIN_SHIFT) | MLX90393_HALL_CONF), (MLX90393_CONF1 & 0x3F) << 2 );
vTaskDelay( 10 );
// MLX90393_CONF2 for comm mode TRIG_INT_SEL 0x1 + 0x10 use spi + relative measurement 0x1 + temp compensation 0x1 = 0xD0
intError = fWriteSPIdata32bits( _hMLX90393_1, MLX90393_REG_WR, 0x00, 0xD0, (MLX90393_CONF2 & 0x3f) << 2 ); // using 0x00 for the lower 8 bits of the register
vTaskDelay( 10 );
//
fMLX90393_ChangeResoultion( _hMLX90393_1, 0 );
vTaskDelay( 10 );
// read MLX90393_CONF3 for resolution
intError = fReadSPIdataXbits( _hMLX90393_1, (MLX90393_CONF3 & 0x3F) << 2, rx, 3 );
// combine response into 16bit
// Serial.print ( rx[2], BIN );
// Serial.print ( " : ");
// Serial.print( rx[1], BIN );
// Serial.print ( " " );
int temp = ( rx[2] << 8) | rx[1];
// Serial.print ( temp, BIN );
// Serial.print ( " " );
// find resoultion being used
temp = temp >> 5;
// Serial.print ( temp, BIN );
// Serial.print ( " " );
// extract 1st 2 bits, x resolution
xRes = temp & 3;
temp = temp >> 2;
yRes = temp & 3;
temp = temp >> 2;
zRes = temp & 3;
// Serial.print ( zRes, BIN );
// Serial.print ( " " );
// Serial.print ( yRes, BIN );
// Serial.print ( " " );
// Serial.print ( xRes, BIN );
// Serial.println ( );
attachInterrupt( MLX90393int_1, fMLX90393_triggerReadSensor_1, RISING );
while (1)
{
xEventGroupWaitBits ( eg, evtTriggerMLX90393_1, pdTRUE, pdTRUE, portMAX_DELAY);
// Serial.println( " wakie wakie 1 ");
// request a single data read
intError = fWriteSPIdata8bits2( _hMLX90393_1, MLX90393_REG_SM | MLX90393_AXIS_ALL ); // single measurement all axis and temprature
//triggered from void IRAM_ATTR triggerMLX90393read(), when the unit has data available
xEventGroupWaitBits ( eg, evtfMLX90393_ReadSensor_1, pdTRUE, pdTRUE, portMAX_DELAY );
intError = fReadSPIdataXbits( _hMLX90393_1, MLX90393_REG_RM | MLX90393_AXIS_ALL, rx, 9 );
/* rx[0] = status bit
rx[1] & rx[2] = temprature
rx[3] & rx[4] x
rx[5] & rx[6] y
rx[7] & rx[8] z
*/
// Convert data to 16 bit
int16_t xi, yi, zi;
xi = (rx[3] << 8) | rx[4]; // shift MSB over to the left by 8 & with LSB
yi = (rx[5] << 8) | rx[6];
zi = (rx[7] << 8) | rx[8];
// determine gain being used
float xT = 0.0f, yT = 0.0f, zT = 0.0f;
xT = (float)xi * mlx90393_lsb_lookup[_gain][xRes][xyResoultion];
yT = (float)yi * mlx90393_lsb_lookup[_gain][yRes][xyResoultion];
zT = (float)zi * mlx90393_lsb_lookup[_gain][zRes][zResoultion];
xMag.x -= xT;
xMag.y -= yT;
xMag.z -= zT;
// multiply by 10 for milliGauss
// Serial.print ( " MLX90393_1 ");
// Serial.print( " X uT: " );
// Serial.print( xT , 6 );
// Serial.print( ", Y uT: " );
// Serial.print( yT, 6 );
// Serial.print( ", Z uT: " );
// Serial.print( zT, 6 );
// Serial.println();
// Serial.print ( "Summed readings: " );
// Serial.print( " X uT: ");
Serial.print( "DATA," );
Serial.print( String(xMag.x) );
Serial.print( ", " );
// Serial.print( " Y uT: ");
Serial.print( String(xMag.y) );
Serial.print( ", " );
// Serial.print( " Z uT: ");
Serial.print( String(xMag.z) );
Serial.print( ", " );
Serial.print( "AUTOSCROLL_20" );
Serial.println();
}
vTaskDelete(NULL);
}