Categories

Arduino and MLX90393 magnetic field sensor example

The MLX90393 magnetic field sensor can be reprogrammed to different modes and with different settings at run-time. The sensor offers a 16-bit output proportional to the magnetic flux density sensed along the XYZ axes using the Melexis proprietary Triaxis® technology and also offers a temperature output signal. These digital values are available via I2C and SPI, where the MLX90393 is a slave on the bus.

By selecting which axes are to be measured, the raw data can be used as input for further post-processing, such as for joystick applications, rotary knobs, and more complex 3D position sensing applications. Unparallelled performance is achieved with this sensor, which is primarily targeting industrial and consumer applications.

mlx90393 module

mlx90393 module

Connection

Module Arduino
VDD 3v3
Gnd Gnd
SDA A4
SCL A5

Code

 

 

 

// Distributed with a free-will license.
// Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
// MLX90393
// This code is designed to work with the MLX90393_I2CS I2C Mini Module available from ControlEverything.com.
// https://www.controleverything.com/products
#include<Wire.h>
 
// MLX90393 I2C Address is 0x0C(12)
#define Addr 0x0C
 
void setup()
{
// Initialise I2C communication as MASTER
Wire.begin();
// Initialise serial communication, set baud rate = 9600
Serial.begin(9600);
 
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select Write register command
Wire.write(0x60);
// Set AH = 0x00, BIST disabled
Wire.write(0x00);
// Set AL = 0x5C, Hall plate spinning rate = DEFAULT, GAIN_SEL = 5
Wire.write(0x5C);
// Select address register, (0x00 << 2)
Wire.write(0x00);
// Stop I2C Transmission
Wire.endTransmission();
 
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
 
// Read status byte
if(Wire.available() == 1)
{
unsigned int c = Wire.read();
}
 
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select Write register command
Wire.write(0x60);
// Set AH = 0x02
Wire.write(0x02);
// Set AL = 0xB4, RES for magnetic measurement = 0
Wire.write(0xB4);
// Select address register, (0x02 << 2)
Wire.write(0x08);
// Stop I2C Transmission
Wire.endTransmission();
 
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
 
// Read status byte
if(Wire.available() == 1)
{
unsigned int c = Wire.read();
}
delay(300);
}
 
void loop()
{
unsigned int data[7];
 
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Start single meaurement mode, ZYX enabled
Wire.write(0x3E);
// Stop I2C Transmission
Wire.endTransmission();
 
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
 
// Read status byte
if(Wire.available() == 1)
{
unsigned int c = Wire.read();
}
delay(100);
 
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Send read measurement command, ZYX enabled
Wire.write(0x4E);
// Stop I2C Transmission
Wire.endTransmission();
 
// Request 7 bytes of data
Wire.requestFrom(Addr, 7);
 
// Read 7 bytes of data
// status, xMag msb, xMag lsb, yMag msb, yMag lsb, zMag msb, zMag lsb
if(Wire.available() == 7);
{
data[0] = Wire.read();
data[1] = Wire.read();
data[2] = Wire.read();
data[3] = Wire.read();
data[4] = Wire.read();
data[5] = Wire.read();
data[6] = Wire.read();
}
 
// Convert the data
int xMag = data[1] * 256 + data[2];
int yMag = data[3] * 256 + data[4];
int zMag = data[5] * 256 + data[6];
 
// Output data to serial monitor
Serial.print("Magnetic Field in X-Axis : ");
Serial.println(xMag);
Serial.print("Magnetic Field in Y-Axis : ");
Serial.println(yMag);
Serial.print("Magnetic Field in Z-Axis : ");
Serial.println(zMag);
delay(500);
}

 

 

 

Output

Open the serial monitor and you should see something like this

Magnetic Field in X-Axis : 66
Magnetic Field in Y-Axis : 65458
Magnetic Field in Z-Axis : 8
Magnetic Field in X-Axis : 83
Magnetic Field in Y-Axis : 65477
Magnetic Field in Z-Axis : 65525
Magnetic Field in X-Axis : 76
Magnetic Field in Y-Axis : 65452
Magnetic Field in Z-Axis : 65506
Magnetic Field in X-Axis : 25
Magnetic Field in Y-Axis : 65374
Magnetic Field in Z-Axis : 65512
Magnetic Field in X-Axis : 80

 

Links

https://www.melexis.com/-/media/files/documents/datasheets/mlx90393-datasheet-melexis.pdf

CJMCU-90393, MLX90393 digital 3D Holzer sensor, displacement, angle, rotation, 3D position

Share

Arduino and HMC5983 magnetometer example

The Honeywell HMC5983 is a temperature compensated three-axis integrated circuit magnetometer. This surface-mount, multi-chip module is designed for low-field magnetic sensing for applications such as automotive and personal navigation, vehicle detection, and pointing.

The HMC5983 includes our state-of-the-art, high-resolution HMC118X series magnetoresistive sensors plus an ASIC containing amplification, automatic degaussing strap drivers, offset cancellation, and a 12-bit ADC that enables 1° to 2° compass heading accuracy. The I²C or SPI serial bus allows for easy interface. The HMC5983 is a 3.0×3.0x0.9mm surface mount 16-pin leadless chip carrier (LCC).

The HMC5983 utilizes Honeywell’s Anisotropic Magnetoresistive (AMR) technology that provides advantages over other magnetic sensor technologies. Honeywell’s anisotropic, directional sensors excel in linearity, low hysteresis, null output and scale factor stability over temperature, and with very low cross-axis sensitivity. These sensors’ solid-state construction is designed to measure both the direction and the magnitude of magnetic fields, from milli-gauss to 8 gauss. Honeywell’s Magnetic Sensors are among the most sensitive and reliable low-field sensors in the industry.

 

Schematic

 

 

Code

#include <Wire.h> //I2C Arduino Library
#define addr 0x1E //I2C Address for The HMC5883
 
void setup()
{
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(addr);
Wire.write(0x02);
Wire.write(0x00); //Continuously Measure
Wire.endTransmission();
}
 
void loop()
{
int x,y,z; //triple axis data
Wire.beginTransmission(addr);
Wire.write(0x03);
Wire.endTransmission();
//Read the data
Wire.requestFrom(addr, 6);
if(6<=Wire.available())
{
  x = Wire.read()<<8; //MSB  x 
  x |= Wire.read(); //LSB  x
  z = Wire.read()<<8; //MSB  z
  z |= Wire.read(); //LSB z
  y = Wire.read()<<8; //MSB y
  y |= Wire.read(); //LSB y
}
// Show Values
Serial.print("X Value: ");
Serial.println(x);
Serial.print("Y Value: ");
Serial.println(y);
Serial.print("Z Value: ");
Serial.println(z);
Serial.println();
delay(500);
}

 

 

Output

Open the serial monitor

X Value: -379
Y Value: 301
Z Value: 126

X Value: 116
Y Value: 548
Z Value: -255

X Value: -458
Y Value: 119
Z Value: -273

X Value: -314
Y Value: -39
Z Value: 383

X Value: -91
Y Value: 471
Z Value: 129

X Value: 473
Y Value: 236
Z Value: -387

 

Link

GY-282 HMC5983 Replace HMC5883L High-precision High-sensitivity Temperature Compensation Triaxial Compass IIC SPI Module

Share

Arduino and MAX30100 oximetry and heart-rate monitor sensor example

The MAX30100 is an integrated pulse oximetry and heart-rate monitor sensor solution. It combines two LEDs, a photodetector, optimized optics, and low-noise analog signal processing to detect pulse oximetry and heart-rate signals.

The MAX30100 operates from 1.8V and 3.3V power supplies and can be powered down through software with negligible standby current, permitting the power supply to remain connected at all times.

MAX30100-Sensor-Module

MAX30100-Sensor-Module

Key Features

  • Complete Pulse Oximeter and Heart-Rate Sensor Solution Simplifies Design
    • Integrated LEDs, Photo Sensor, and High-Performance Analog Front-End
    • Tiny 5.6mm x 2.8mm x 1.2mm 14-Pin Optically Enhanced System-in-Package
  • Ultra-Low-Power Operation Increases Battery Life for Wearable Devices
    • Programmable Sample Rate and LED Current for Power Savings
    • Ultra-Low Shutdown Current (0.7µA, typ)
  • Advanced Functionality Improves Measurement Performance
    • High SNR Provides Robust Motion Artifact Resilience
    • Integrated Ambient Light Cancellation
    • High Sample Rate Capability
    • Fast Data Output Capability

 

Connection

Arduino Module Pin
5v Vin
Gnd Gnd
SDA SDA
SCL SCL

 

Code

You will need the library from https://github.com/oxullo/Arduino-MAX30100 and import it into the Arduino IDE

This is the minimal example which worked with my module

#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
 
#define REPORTING_PERIOD_MS     1000
 
// PulseOximeter is the higher level interface to the sensor
// it offers:
//  * beat detection reporting
//  * heart rate calculation
//  * SpO2 (oxidation level) calculation
PulseOximeter pox;
 
uint32_t tsLastReport = 0;
 
// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
    Serial.println("Beat!");
}
 
void setup()
{
    Serial.begin(115200);
 
    Serial.print("Initializing pulse oximeter..");
 
    // Initialize the PulseOximeter instance
    // Failures are generally due to an improper I2C wiring, missing power supply
    // or wrong target chip
    if (!pox.begin()) {
        Serial.println("FAILED");
        for(;;);
    } else {
        Serial.println("SUCCESS");
    }
 
    // The default current for the IR LED is 50mA and it could be changed
    //   by uncommenting the following line. Check MAX30100_Registers.h for all the
    //   available options.
    // pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
 
    // Register a callback for the beat detection
    pox.setOnBeatDetectedCallback(onBeatDetected);
}
 
void loop()
{
    // Make sure to call update as fast as possible
    pox.update();
 
    // Asynchronously dump heart rate and oxidation levels to the serial
    // For both, a value of 0 means "invalid"
    if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
        Serial.print("Heart rate:");
        Serial.print(pox.getHeartRate());
        Serial.print("bpm / SpO2:");
        Serial.print(pox.getSpO2());
        Serial.println("%");
 
        tsLastReport = millis();
    }
}

 

Output

Open the serial monitor

Heart rate:95.04bpm / SpO2:93%
Beat!
Beat!
Heart rate:79.23bpm / SpO2:94%
Beat!
Heart rate:78.94bpm / SpO2:94%
Beat!
Heart rate:76.35bpm / SpO2:94%
Beat!
Beat!
Heart rate:76.26bpm / SpO2:94%
Beat!

 

Links

 

Share

Arduino and BMI160 sensor example

The BMI160 is a small, low power, low noise 16-bit inertial measurement unit designed for use in mobile applications like augmented reality or indoor navigation which require highly accurate, real-time sensor data.

In full operation mode, with both the accelerometer and gyroscope enabled, the current consumption is typically 950 μA, enabling always-on applications in battery driven devices. It is available in a compact 14-pin 2.5 x 3.0 x 0.8 mm³ LGA package.

bmi160 module

bmi160 module

Features

Parameter Technical data
Digital resolution Accelerometer (A): 16 bit
Gyroscope (G): 16bit
Measurement ranges
(programmable)
(A): ± 2 g, ± 4 g, ± 8 g, ± 16 g
(G): ± 125°/s, ± 250°/s, ± 500°/s, ± 1000°/s, ± 2000°/s
Sensitivity (calibrated) (A): ±2g: 16384LSB/g
±4g: 8192LSB/g
±8g: 4096LSB/g
±16g: 2048LSB/g
(G): ±125°/s: 262.4 LSB/°/s
±250°/s: 131.2 LSB/°/s
±500°/s: 65.6 LSB/°/s
±1000°/s: 32.8 LSB/°/s
±2000°/s: 16.4 LSB/°/s
Zero-g offset (typ., over life-time) (A): ±40mg (G): ± 10°/s
Noise density (typ.) (A): 180 μg/√Hz
(G): 0.008 °/s/√Hz
Bandwidths (programmable) 1600 Hz … 25/32 Hz
Digital inputs/outputs SPI, I²C, 4x digital
interrupts
Supply voltage (VDD) 1.71 … 3.6 V
I/0 supply voltage (VDDIO) 1.2 … 3.6 V
Temperature range -40 … +85°C
Current consumption
– full operation
– low-power mode
950 μA
3 μA
FIFO data buffer 1024 byte
LGA package 2.5 × 3.0 × 0.8 mm³
Shock resistance 10,000 g x 200 μs

 

Connection

 

Arduino pin Module Pin
5v Vin
Gnd Gnd
A4 SDA
A5 SCL

 

Code

This example used the following library – https://github.com/hanyazou/BMI160-Arduino

#include <BMI160Gen.h>
 
const int select_pin = 10;
const int i2c_addr = 0x69;
 
void setup() {
  Serial.begin(9600); // initialize Serial communication
  while (!Serial);    // wait for the serial port to open
 
  // initialize device
  //BMI160.begin(BMI160GenClass::SPI_MODE, select_pin);
  BMI160.begin(BMI160GenClass::I2C_MODE, i2c_addr);
}
 
void loop() {
  int gx, gy, gz;         // raw gyro values
 
  // read raw gyro measurements from device
  BMI160.readGyro(gx, gy, gz);
 
  // display tab-separated gyro x/y/z values
  Serial.print("g:\t");
  Serial.print(gx);
  Serial.print("\t");
  Serial.print(gy);
  Serial.print("\t");
  Serial.print(gz);
  Serial.println();
 
  delay(500);
}

 

 

Output

Open the serial monitor

g: 90 86 9
g: 69 69 40
g: 35 97 -9
g: -7370 3961 -1786
g: -31829 -2652 32767
g: -3221 25109 32767
g: 26020 31878 -26125
g: -20332 -21698 -15712
g: -7297 3463 -1723
g: -1137 1521 420
g: -203 305 96
g: 144 -102 54
g: 77 116 35

 

Links

https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMI160-DS000-07.pdf
CJMCU-160I BMI160 latest inertial measurement sensor attitude module 6DOF

Share