TMAG5237 incorrect measurement

Hello,

I am using TMAG5273 sensor to measure magnetic field. I use it with ESP32-C6 and ESP-IDF in VScode. My problem is, that results is a one random value which doesn’t change or 0. I think it is an issue with sensor configuration, however I don’t see what lacks.

I attach my code:

#include “tmag5273.h”

#include <stdlib.h>

#include “math.h”

#include “freertos/FreeRTOS.h”

#include “freertos/task.h”

#include “driver/i2c_master.h”

#define TMAG_RANGE

#define I2C_SDA 22

#define I2C_SCL 23

#define PORT_NUM I2C_NUM_0

#define I2C_FREQ 100000

const float scale = 40.0f / 32768.0f;

i2c_master_bus_handle_t bus_handle;

i2c_master_dev_handle_t dev_handle;

void tmag5273_init(void)

{

i2c_master_bus_config_t i2c_mst_config = {

    .clk_source = I2C_CLK_SRC_DEFAULT,

    .i2c_port = PORT_NUM,

    .scl_io_num = I2C_SCL,

    .sda_io_num = I2C_SDA,

    .glitch_ignore_cnt = 7,

    .flags.enable_internal_pullup = true,

};

ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));



i2c_device_config_t dev_cfg = {

.dev_addr_length = I2C_ADDR_BIT_LEN_7,

.device_address = 0x22,

.scl_speed_hz = I2C_FREQ,

};

ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));

}

void tmag5273_measure_magneticField(tmag5273_measurement_t *result)

{

uint8_t reg = {0x12};  

uint8_t data\[6\];

ESP_ERROR_CHECK(i2c_master_transmit_receive(dev_handle, &reg, 1, data, 6, -1));

//ESP_ERROR_CHECK(i2c_master_receive(dev_handle, data, 6, -1));

int16_t x = (int16_t)((data\[0\] << 8) | data\[1\]);

int16_t y = (int16_t)((data\[2\] << 8) | data\[3\]);

int16_t z = (int16_t)((data\[4\] << 8) | data\[5\]);

printf("%02X %02X %02X %02X %02X %02X\\n",

   data\[0\], data\[1\], data\[2\],

   data\[3\], data\[4\], data\[5\]);

float Bx = x \* scale;

float By = y \* scale;

float Bz = z \* scale;

result->Bx = Bx;

result->By = By;

result->Bz = Bz;

result->magneticField = (float)sqrt(Bx \* Bx + By \* By + Bz \* Bz);

}

I will be grateful for any advice.

Hi @Mikee ,

The TMAG5273 has one of four possible I2C addresses, depending on which version it is:

Have you checked your device_address = 0x22 is correct for your device?

Perhaps you need to set the MAG into continuous measure mode? The device defaults to Stand-by mode (the two DEVICE_CONFIG_2 OPERATING_MODE bits default to 0 = Stand-by mode). You may need to replicate this start-up code from the SparkFun library?

I hope this helps,
Paul

What about the connection?

Your read operation from 0x12 is correct, but the sensor powers up with all magnetic channels disabled and in standby mode. Configure it before reading:

uint8_t axes[] = {0x02, 0x70}; // Enable X, Y and Z
ESP_ERROR_CHECK(i2c_master_transmit(dev_handle, axes, 2, -1));

uint8_t mode[] = {0x01, 0x02}; // Continuous measurement mode
ESP_ERROR_CHECK(i2c_master_transmit(dev_handle, mode, 2, -1));

vTaskDelay(pdMS_TO_TICKS(2));

Also run an I2C scan to verify that 0x22 matches your particular TMAG5273 variant. Check the manufacturer/device ID registers before trusting the data, and use proper external SDA/SCL pull-ups; the ESP32’s internal pull-ups are often too weak.

Finally, 40 / 32768 is valid only for a TMAG5273x1 configured for the ±40 mT range. The x2 version and other range settings require a different scale factor.

This I2C project also illustrates the use of external SDA/SCL pull-ups. However, the principal issue here remains the TMAG5273’s reset configuration: its magnetic channels are disabled and it remains in standby until the appropriate registers are written.

Hello, thank you for answer.
I actually did something like that:

// Config

#define REG_DEVICE_CONFIG_1 0x00

#define VAL_DEVICE_CONFIG_1 0x02

#define REG_DEVICE_CONFIG_2 0x01

#define VAL_DEVICE_CONFIG_2 0x02 // Continuous measure mode (for Standby 0x01)

#define REG_SENSOR_CONFIG_1 0x02

#define VAL_SENSOR_CONFIG_1 0x70 // Enable X, Y and Z channels (MAG_CH_EN)

…

esp_err_t tmag5273_write_reg(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint8_t data) {

uint8_t write_buf\[2\] = {reg_addr, data};

return i2c_master_transmit(dev_handle, write_buf, sizeof(write_buf), -1);

}

…

ESP_ERROR_CHECK(tmag5273_write_reg(dev_handle, REG_DEVICE_CONFIG_1, VAL_DEVICE_CONFIG_1));

ESP_ERROR_CHECK(tmag5273_write_reg(dev_handle, REG_DEVICE_CONFIG_2, VAL_DEVICE_CONFIG_2));

ESP_ERROR_CHECK(tmag5273_write_reg(dev_handle, REG_SENSOR_CONFIG_1, VAL_SENSOR_CONFIG_1));

Right know I receive values, but they seem quite random.

EDIT:
I tried your modifications and unfortunatelly I still got some random values, however they are far more possible than previous. What was probably wrong is this line #define VAL_DEVICE_CONFIG_1 , it should be 0x00 here

These are my sample values:
New measurement:
FF 70 FF E0 00 00
Magnetic field: 0.18 mT X: -0.18 mT Y: -0.04 mT Z: 0.00 mT
FF 60 FF C0 00 40
Current: 11.22 A
New measurement:
FE E0 FF 40 00 40
Magnetic field: 0.43 mT X: -0.35 mT Y: -0.23 mT Z: 0.08 mT
FF E0 00 90 00 30
Current: 9.47 A
New measurement:
FF 30 FF 80 00 00
Magnetic field: 0.30 mT X: -0.25 mT Y: -0.16 mT Z: 0.00 mT
FF E0 00 20 00 30
Current: 4.03 A
New measurement:
FF B0 FF A0 00 30
Magnetic field: 0.16 mT X: -0.10 mT Y: -0.12 mT Z: 0.06 mT
FF 30 00 50 00 40
Current: 14.15 A
New measurement:
FF A0 00 C0 00 60
Magnetic field: 0.29 mT X: -0.12 mT Y: 0.23 mT Z: 0.12 mT
FF F0 00 00 00 90
Current: 8.84 A
New measurement:
FF 00 00 30 00 20
Magnetic field: 0.32 mT X: -0.31 mT Y: 0.06 mT Z: 0.04 mT
FF 20 00 30 00 20
Current: 14.12 A
New measurement:
00 20 FF C0 00 30
Magnetic field: 0.11 mT X: 0.04 mT Y: -0.08 mT Z: 0.06 mT
FF D0 00 10 00 80
Current: 8.40 A
New measurement:
FE E0 00 60 00 90
Magnetic field: 0.41 mT X: -0.35 mT Y: 0.12 mT Z: 0.18 mT
FF C0 FF D0 00 70
Current: 8.40 A
New measurement:
FF A0 FF E0 00 00
Magnetic field: 0.12 mT X: -0.12 mT Y: -0.04 mT Z: 0.00 mT
FF 30 00 10 00 40
Current: 13.32 A
New measurement:
FF D0 00 20 00 70
Magnetic field: 0.15 mT X: -0.06 mT Y: 0.04 mT Z: 0.14 mT
FF 90 00 70 00 60
Current: 11.30 A

I also added pullup resistors, but it doesn’t effect results it terms of their randomness.

I would say it is proper.