Infineon has released the third-generation of their 3D magnetic sensors! Two of them are packed on the "MS2Go" Kit with an onboard XMC1100 Arduino-compatible microcontroller. On the front side, you’ll find the TLE493D-P3I8, and on the back side, the TLE493D-P3B6 A0. The board comes with an onboard MCU and debugger, so you can direct plug it into your PC using a micro-USB cable and start programming.
Key features of both sensors:
- Supply voltages: 3.3 V or 5 V.
- Operating temperature: -40°C to 150°C.
- Selectable Magnetic Field Range.
- Integrated chip temperature measurement.
- 3D magnetic field sensing up to ±160 mT.
Communication Interface:
- TLE493D-P3I8: SPI up to 2 MHz.
- TLE493D-P3B6: I2C up to 1 MHz.
Before we can start we need to have the Arduino IDE installed. Have a look here for instructions. After that, we can download the Arduino software library for the 3D magnetic sensors. For this, navigate to Sketch -> Include Library -> Manage libraries... within your Arduino IDE. The name of the library you're looking for is “XENSIV 3D Magnetic Sensor TLx493D”:
Make sure to select the latest version and click Install. After a few seconds a message should show up in the terminal, stating that the library has been installed successfully:
That's it. The library installation is completed. :)
3. XMC for ArduinoThe TLE493D-P3xx-MS2GO comes with a XMC1100 microcontroller. Fortunately, this model is Arduino-compatible (thanks to XMC for Arduino). If you do not have XMC for Arduino installed yet have a look here before you continue this guide.
4. Setup and Code with ArduinoIn this section, we will go through the main functions provided by the TLx493D library and provide some sample code to demonstrate how to use the sensor within Arduino.
Main Functions
begin()
: Initializes all necessary peripherals of the chosen sensor board.getTemperature()
: Reads the temperature value from the sensor.getMagneticField()
: Reads the magnetic field values in X, Y, and Z directions.getMagneticFieldAndTemperature()
: Read the magnetic field values in X, Y, and Z directions and the temperature value.setI2CAddress()
: Sets the I2C address of the sensor.getRawTemperature()
: Reads the raw temperature value.printRegisters()
: Prints the sensor registers for debugging.reset()
: Resets the sensor (doing a power cycle).setSensitivity()
: Sets the sensitivity of the sensor to Full Range, Short Range, or Extra Short Range.setPowerPin()
: Configures the power pin settings for the sensor.setPowerMode
(): Sets the power mode of the sensor to Normal or Low Power.
Coding TimeNow we can start coding :)
The code begins with including the necessary header file and namespace:
#include "TLx493D_inc.hpp"
using namespace ifx::tlx493d;
For both communication protocols (SPI and I2C) the header file "TLx493D_inc.hpp" needs to be included.After that a namespace is used that we can access its classes and functions without repeatedly using the namespace.
4.1 Front Sensor with I2CAfter including the header file, we create an object of the sensor class and set the location of the power pin, which will be used to power cycle the sensor.
const uint8_t POWER_PIN = 8; // XMC1100 : LED2
TLx493D_P3B6 dut(Wire, TLx493D_IIC_ADDR_A0_e);
Here, the POWER_PIN is set to 8 and controls an onboard PMOS transistor, powering the sensor.
Setup Function
The setup function initializes serial communication and the sensor:
void setup() {
Serial.begin(115200);
delay(5000);
// Setting the power pin to low controls the PMOS transistor
dut.setPowerPin(POWER_PIN, OUTPUT, INPUT, LOW, HIGH, 0, 250000);
// Initialize the sensor
dut.begin();
Serial.print("setup done.\n");
}
Serial.begin(115200);
starts the serial monitor at a baud rate of 115200.
The power pin is configured using dut.setPowerPin(...),
setting pin 8 to low to control the PMOS transistor.
dut.begin();
initializes the sensor. Note that the address cannot be changed as in the second generation sensors.
Loop Function
The loop function continuously reads sensor data and prints it to the Serial Monitor:
void loop() {
double t, x, y, z;
dut.setSensitivity(TLx493D_FULL_RANGE_e);
Serial.print(true == dut.getMagneticFieldAndTemperature(&x, &y, &z, &t)
? "getMagneticFieldAndTemperature ok\n" : "getMagneticFieldAndTemperature error\n");
dut.printRegisters();
Serial.print("\nTemperature is: ");
Serial.print(t);
Serial.println("°C");
Serial.print("Value X is: ");
Serial.print(x);
Serial.println(" mT");
Serial.print("Value Y is: ");
Serial.print(y);
Serial.println(" mT");
Serial.print("Value Z is: ");
Serial.print(z);
Serial.println(" mT");
dut.setSensitivity(TLx493D_SHORT_RANGE_e);
Serial.print(true == dut.getMagneticFieldAndTemperature(&x, &y, &z, &t) ?
"getMagneticFieldAndTemperature ok\n" : "getMagneticFieldAndTemperature error\n");
dut.printRegisters();
Serial.print("\nTemperature is: ");
Serial.print(t);
Serial.println("°C");
Serial.print("Value X is: ");
Serial.print(x);
Serial.println(" mT");
Serial.print("Value Y is: ");
Serial.print(y);
Serial.println(" mT");
Serial.print("Value Z is: ");
Serial.print(z);
Serial.println(" mT");
Serial.print("\n\n\n\n");
delay(1000);
Serial.print("count : ");
Serial.println(count);
if( ++count == 4 ) {
Serial.println("\nBefore reset -------------------------------------------");
/** Reset does not work for W2BW : either drive strength too low or delay to
stabilize critical. */
dut.reset(true, dut.getSensorType() != TLx493D_A1B6_e);
Serial.println("\nAfter reset -------------------------------------------");
count = 0;
}
}
The variables t, x, y, and z store the temperature and magnetic field readings in the X, Y, and Z directions, respectively. The sensor's sensitivity is initially set to full range using the command dut.setSensitivity(TLx493D_FULL_RANGE_e);
. There are three sensitivity options available: Full Range, Short Range, and Extra Short Range, and you can switch between these modes at any time:
- Full Range: ±160 mT, normal sensitivity.
- Short Range: ±100 mT, higher sensitivity.
- Extra Short Range: ±50 mT, highest sensitivity.
For more information about the different modes of the sensor have a look into the datasheet.
To retrieve the magnetic field values and temperature, the command dut.getMagneticFieldAndTemperature(&x, &y, &z, &t);
is used. For debugging purposes, the sensor's register values can be printed using dut.printRegisters();
. All sensor data is displayed on Arduino's Serial Monitor.
After the first readout, the sensitivity is switched to short range, and the data is read and printed again. A counter keeps track of the loop iterations. After every four iterations, the sensor is reset by executing dut.reset(true);
, which performs a power cycle of the chip. This is only to showcase the reset functionality and can be commented out if you don't need it :)
And there you go! Now you can read out the temperature and magnetic field from the TLE493D P3B6:
To find more information about the SPI variant, TLE493D-P3B6, have a look here.
4.2 Back Sensor with SPIAfter including the header file and namespace (see 4), we need to define the right pins for the SPI sensor:
/** Definition of the power and chip select pin. */
/** P3XX evaluation board */
const uint8_t POWER_PIN = 4; // XMC1100_XMC2GO
const uint8_t CHIP_SELECT_PIN = 3;
/** Declaration of the sensor object. */
TLx493D_P3I8 dut(SPI);
The CSN (Inverted Chip Select) input of the SPI sensor is attached to pin 3 of the XMC and the gate of the PMOS powering the sensor is connected to pin 4.
Setup Function
As in the I2C example, the setup function initializes serial communication and the sensor:
void setup() {
Serial.begin(115200);
delay(3000);
/** Setting the chip select pin for the SPI board using the functions of the Board Support Class.
* Power supply has to be switched on through transistor, therefore inverse logic.
*/
dut.setPowerPin(POWER_PIN, OUTPUT, INPUT, LOW, HIGH, 1000, 250000);
dut.setSelectPin(CHIP_SELECT_PIN, OUTPUT, INPUT, LOW, HIGH, 0, 0);
dut.begin(true, true);
Serial.print("setup done.\n");
}
Serial.begin(115200)
; starts the serial monitor at a baud rate of 115200.
The power pin and chip select pin are set using dut.setPowerPin(...)
and dut.setSelectPin(...)
, respectively.
dut.begin(true, true);
initializes the sensor with power pin enabled and chip select enabled.
Loop Function
void loop() {
double temp = 0.0;
double valX = 0, valY = 0, valZ = 0;
int16_t tempRaw = 0;
dut.printRegisters();
Serial.print("\n");
/** Note that you don't have to toggle any chip select signal, this is done in the background within the transfer function. */
Serial.print(true == dut.getTemperature(&temp) ? "getTemperature ok\n" : "getTemperature error\n");
Serial.print("Temperature is: ");
Serial.print(temp);
Serial.println(" °C");
dut.getRawTemperature(&tempRaw);
Serial.print("Raw temperature is: ");
Serial.print(tempRaw);
Serial.println(" LSB");
Serial.print(true == dut.getMagneticFieldAndTemperature(&valX, &valY, &valZ, &temp) ? "getMagneticFieldAndTemperature ok\n" : "getMagneticFieldAndTemperature error\n");
Serial.print("Value X is: ");
Serial.print(valX);
Serial.println(" mT");
Serial.print("Value Y is: ");
Serial.print(valY);
Serial.println(" mT");
Serial.print("Value Z is: ");
Serial.print(valZ);
Serial.println(" mT");
dut.printRegisters();
Serial.print("\n");
delay(1000);
Serial.print("count : ");
Serial.println(count);
if( ++count == 10 ) {
Serial.println("Before reset -------------------------------------------");
/* Use reset to do a full power down reset or softwareReset to reset using register settings. **/
dut.reset();
// dut.softwareReset();
Serial.println("After reset -------------------------------------------");
count = 0;
}
}
The variables temp, valX, valY, valZ, and tempRaw are used to store the temperature, magnetic field readings in the X, Y, and Z directions, and raw temperature values, respectively.
The function dut.getTemperature(&temp);
retrieves the temperature value. This function handles the chip select signal in the background, so manual toggling is not required. The retrieved temperature value is then printed to Arduino's Serial Monitor.
Similarly, the function dut.getRawTemperature(&tempRaw);
retrieves the raw temperature value, which is also printed.
The function dut.getMagneticField(&valX, &valY, &valZ);
retrieves the magnetic field readings for the X, Y, and Z directions and prints them.
For debugging purposes, the sensor's register values are printed using dut.printRegisters();
.
A counter, keeps track of loop iterations. After ten iterations, the sensor is reset usingdut.reset();
to perform a power cycle. This is possible because the chip's VDD is connected to the power supply through a PMOS transistor. Additionally, a software reset can be performed using dut.softwareReset();
.And there you go! Now you can read out the temperature and magnetic field from the TLE493D P3I8:
To find more information about the SPI variant, TLE493D-P3I8, have a look here.
5. Farewell & Application ExamplesLet us know in the comments what you are building with the new 3rd generation TLE493D-P3xx 3D magnetic sensor kit 2Go!
Make sure to check out the code examples in the Attachments section of this article, and find some inspiration here: Robotic Haptics by 3D Magnetic Sensor.
Stay tuned for our next Maker Monday for more 3D magnetic sensing! 🧲🔨
Happy exploring and tinkering! 🚀
Comments
Please log in or sign up to comment.