Microbit and MS5611 barometric pressure sensor example

This barometric pressure sensor is optimized for altimeters and variometers with an altitude resolution of 10 cm. The sensor module includes a high linearity pressure sensor and an ultra-low power 24 bit ΔΣ ADC with internal factory calibrated coefficients. It provides a precise digital 24 Bit pressure and temperature value and different operation modes that allow the user to optimize for conversion speed and current consumption. A high resolution temperature output allows the implementation of an altimeter/thermometer function without any additional sensor. The MS5611-01BA can be interfaced to virtually any microcontroller. The communication protocol is simple, without the need of programming internal registers in the device.

Small dimensions of only 5.0 mm x 3.0 mm and a height of only 1.0 mm allow for integration in mobile devices. This new sensor module generation is based on leading MEMS technology and latest benefits from MEAS Switzerland proven experience and know-how in high volume manufacturing of altimeter modules, which have been widely used for over a decade. The sensing principle employed leads to very low hysteresis and high stability of both pressure and temperature signal.

features

 

  • High resolution module, 10 cm
  • Fast conversion down to 1 ms
  • Low power, 1 µA (standby < 0.15 µA)
  • QFN package 5.0 x 3.0 x 1.0 mm3
  • Supply voltage 1.8 to 3.6 V
  • Integrated digital pressure sensor (24 bit ΔΣ ADC)
  • Operating range: 10 to 1200 mbar, -40 to +85 °C
  • I2C and SPI interface up to 20 MHz
  • No external components (Internal oscillator)
  • Excellent long term stability

 

 

Connection

Microbit Module connection
3.3v Vcc
Gnd Gnd
SCL – 19 SCL
SDA – 20 SDA

 

Code

This example comes from the https://github.com/jarzebski/Arduino-MS5611 library

#include <Wire.h>
#include <MS5611.h>
 
MS5611 ms5611;
 
double referencePressure;
 
void setup() 
{
  Serial.begin(9600);
 
  // Initialize MS5611 sensor
  Serial.println("Initialize MS5611 Sensor");
 
  while(!ms5611.begin())
  {
    Serial.println("Could not find a valid MS5611 sensor, check wiring!");
    delay(500);
  }
 
  // Get reference pressure for relative altitude
  referencePressure = ms5611.readPressure();
 
  // Check settings
  checkSettings();
}
 
void checkSettings()
{
  Serial.print("Oversampling: ");
  Serial.println(ms5611.getOversampling());
}
 
void loop()
{
  // Read raw values
  uint32_t rawTemp = ms5611.readRawTemperature();
  uint32_t rawPressure = ms5611.readRawPressure();
 
  // Read true temperature & Pressure
  double realTemperature = ms5611.readTemperature();
  long realPressure = ms5611.readPressure();
 
  // Calculate altitude
  float absoluteAltitude = ms5611.getAltitude(realPressure);
  float relativeAltitude = ms5611.getAltitude(realPressure, referencePressure);
 
  Serial.println("--");
 
  Serial.print(" rawTemp = ");
  Serial.print(rawTemp);
  Serial.print(", realTemp = ");
  Serial.print(realTemperature);
  Serial.println(" *C");
 
  Serial.print(" rawPressure = ");
  Serial.print(rawPressure);
  Serial.print(", realPressure = ");
  Serial.print(realPressure);
  Serial.println(" Pa");
 
  Serial.print(" absoluteAltitude = ");
  Serial.print(absoluteAltitude);
  Serial.print(" m, relativeAltitude = ");
  Serial.print(relativeAltitude);    
  Serial.println(" m");
 
  delay(1000);
}

 

Output

Open the serial monitor and you will see something like this

rawTemp = 8432348, realTemp = 24.08 *C
rawPressure = 8669780, realPressure = 101367 Pa
absoluteAltitude = -3.50 m, relativeAltitude = -0.17 m

rawTemp = 8476892, realTemp = 25.56 *C
rawPressure = 8654596, realPressure = 101383 Pa
absoluteAltitude = -4.83 m, relativeAltitude = -1.50 m

rawTemp = 8553596, realTemp = 28.06 *C
rawPressure = 8628308, realPressure = 101383 Pa
absoluteAltitude = -4.83 m, relativeAltitude = -1.50 m

rawTemp = 8595300, realTemp = 29.42 *C
rawPressure = 8613628, realPressure = 101374 Pa
absoluteAltitude = -4.08 m, relativeAltitude = -0.75 m

 

Link

GY-63 MS5611-01BA03 Precision MS5611 Atmospheric Pressure Sensor Module Height Sensor Module

OPT3001 Digital Ambient Light Sensor and Microbit example

The OPT3001 is a sensor that measures the intensity of visible light. The spectral response of the sensor tightly matches the photopic response of the human eye and includes significant infrared rejection.

The OPT3001 is a single-chip lux meter, measuring the intensity of light as visible by the human eye. The precision spectral response and strong IR rejection of the device enables the OPT3001 to accurately meter the intensity of light as seen by the human eye regardless of light source. The strong IR rejection also aids in maintaining high accuracy when industrial design calls for mounting the sensor under dark glass for aesthetics. The OPT3001 is designed for systems that create light-based experiences for humans, and an ideal preferred replacement for photodiodes, photoresistors, or other ambient light sensors with less human eye matching and IR rejection.

Measurements can be made from 0.01 lux up to 83k lux without manually selecting full-scale ranges by using the built-in, full-scale setting feature. This capability allows light measurement over a 23-bit effective dynamic range.

The digital operation is flexible for system integration. Measurements can be either continuous or single-shot. The control and interrupt system features autonomous operation, allowing the processor to sleep while the sensor searches for appropriate wake-up events to report via the interrupt pin. The digital output is reported over an I2C- and SMBus-compatible, two-wire serial interface.

The low power consumption and low power-supply voltage capability of the OPT3001 enhance the battery life of battery-powered systems.

Features

  • Precision Optical Filtering to Match Human Eye:
    • Rejects > 99% (typ) of IR
  • Automatic Full-Scale Setting Feature Simplifies Software and Ensures Proper Configuration
  • Measurements: 0.01 lux to 83 k lux
  • 23-Bit Effective Dynamic Range With
    Automatic Gain Ranging
  • 12 Binary-Weighted Full-Scale Range Settings:
    < 0.2% (typ) Matching Between Ranges
  • Low Operating Current: 1.8 µA (typ)
  • Operating Temperature Range: –40°C to +85°C
  • Wide Power-Supply Range: 1.6 V to 3.6 V
  • 5.5-V Tolerant I/O

Connection

Microbit CJMCU-3001
3.3v Vcc
Gnd Gnd
SDA – 20 SDA
SCL – 19 SCL

Code

This example uses the following library https://github.com/closedcube/ClosedCube_OPT3001_Arduino

/*
 
This is example for ClosedCube OPT3001 Digital Ambient Light Sensor breakout board 
 
Initial Date: 02-Dec-2015
 
Hardware connections for Arduino Uno:
VDD to 3.3V DC
SDA to A4
SCL to A5
GND to common ground
 
Written by AA for ClosedCube
 
MIT License
 
*/
 
#include <Wire.h>
#include <ClosedCube_OPT3001.h>
 
ClosedCube_OPT3001 opt3001;
 
#define OPT3001_ADDRESS 0x44
 
void setup()
{
	Serial.begin(9600);
	Serial.println("ClosedCube OPT3001 Arduino Test");
 
	opt3001.begin(OPT3001_ADDRESS);
	Serial.print("OPT3001 Manufacturer ID");
	Serial.println(opt3001.readManufacturerID());
	Serial.print("OPT3001 Device ID");
	Serial.println(opt3001.readDeviceID());
 
	configureSensor();
	printResult("High-Limit", opt3001.readHighLimit());
	printResult("Low-Limit", opt3001.readLowLimit());
	Serial.println("----");
}
 
void loop()
{
	OPT3001 result = opt3001.readResult();
	printResult("OPT3001", result);
	delay(500);
}
 
void configureSensor() {
	OPT3001_Config newConfig;
 
	newConfig.RangeNumber = B1100;	
	newConfig.ConvertionTime = B0;
	newConfig.Latch = B1;
	newConfig.ModeOfConversionOperation = B11;
 
	OPT3001_ErrorCode errorConfig = opt3001.writeConfig(newConfig);
	if (errorConfig != NO_ERROR)
		printError("OPT3001 configuration", errorConfig);
	else {
		OPT3001_Config sensorConfig = opt3001.readConfig();
		Serial.println("OPT3001 Current Config:");
		Serial.println("------------------------------");
 
		Serial.print("Conversion ready (R):");
		Serial.println(sensorConfig.ConversionReady,HEX);
 
		Serial.print("Conversion time (R/W):");
		Serial.println(sensorConfig.ConvertionTime, HEX);
 
		Serial.print("Fault count field (R/W):");
		Serial.println(sensorConfig.FaultCount, HEX);
 
		Serial.print("Flag high field (R-only):");
		Serial.println(sensorConfig.FlagHigh, HEX);
 
		Serial.print("Flag low field (R-only):");
		Serial.println(sensorConfig.FlagLow, HEX);
 
		Serial.print("Latch field (R/W):");
		Serial.println(sensorConfig.Latch, HEX);
 
		Serial.print("Mask exponent field (R/W):");
		Serial.println(sensorConfig.MaskExponent, HEX);
 
		Serial.print("Mode of conversion operation (R/W):");
		Serial.println(sensorConfig.ModeOfConversionOperation, HEX);
 
		Serial.print("Polarity field (R/W):");
		Serial.println(sensorConfig.Polarity, HEX);
 
		Serial.print("Overflow flag (R-only):");
		Serial.println(sensorConfig.OverflowFlag, HEX);
 
		Serial.print("Range number (R/W):");
		Serial.println(sensorConfig.RangeNumber, HEX);
 
		Serial.println("------------------------------");
	}
 
}
 
void printResult(String text, OPT3001 result) {
	if (result.error == NO_ERROR) {
		Serial.print(text);
		Serial.print(": ");
		Serial.print(result.lux);
		Serial.println(" lux");
	}
	else {
		printError(text,result.error);
	}
}
 
void printError(String text, OPT3001_ErrorCode error) {
	Serial.print(text);
	Serial.print(": [ERROR] Code #");
	Serial.println(error);
}

Output

Here is a sample of the output from the Serial Monitor

OPT3001: 7910.40 lux
OPT3001: 8017.92 lux
OPT3001: 7969.28 lux
OPT3001: 454.40 lux
OPT3001: 125.28 lux
OPT3001: 192.88 lux
OPT3001: 247.76 lux
OPT3001: 252.56 lux
OPT3001: 256.48 lux
OPT3001: 256.80 lux
OPT3001: 5.44 lux
OPT3001: 6.09 lux
OPT3001: 6.81 lux
OPT3001: 38.48 lux
OPT3001: 229.84 lux
OPT3001: 233.68 lux

 

Link

OPT3001 CJMCU-3001 ambient light sensor eye like measurement light intensity single chip illumination meter

Microbit and MAG3110 magnetic sensor example

The MAG3110 is a small, low-power digital 3D magnetic sensor with a wide dynamic range to allow operation in PCBs with high extraneous magnetic fields. The MAG3110:

  • Measures the components of the local magnetic field, the sum of the geomagnetic field and the magnetic field created by components on the circuit board
  • Can be used in conjunction with a 3-axis accelerometer so that orientation-independent accurate compass heading information may be achieved
  • Features a standard I²C serial interface and is capable of measuring local magnetic fields up to 10 Gauss with output data rates up to 80 Hz

 

Features

Layout

 

microbit and MAG3110

microbit and MAG3110

 

Code

 

#include <Wire.h>
#define MAG_ADDR 0x0E //7-bit address for the MAG3110, doesn't change
 
void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(9600); // start serial for output
  config(); // turn the MAG3110 on
}
 
void loop()
{
  print_values();
  delay(500);
}
 
void config(void)
{
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x11); // cntrl register2
  Wire.write(0x80); // send 0x80, enable auto resets
  Wire.endTransmission(); // stop transmitting
  delay(15);
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x10); // cntrl register1
  Wire.write(1); // send 0x01, active mode
  Wire.endTransmission(); // stop transmitting
}
 
void print_values(void)
{
  Serial.print("x=");
  Serial.print(readx());
  Serial.print(",");
  Serial.print("y=");
  Serial.print(ready());
  Serial.print(",");
  Serial.print("z=");
  Serial.println(readz());
}
 
int readx(void)
{
  int xl, xh; //define the MSB and LSB
 
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x01); // x MSB reg
  Wire.endTransmission(); // stop transmitting
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
    xh = Wire.read(); // receive the byte
  }
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x02); // x LSB reg
  Wire.endTransmission(); // stop transmitting
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
    xl = Wire.read(); // receive the byte
  }
  int xout = (xl|(xh << 8)); //concatenate the MSB and LSB
  return xout;
}
 
int ready(void)
{
  int yl, yh; //define the MSB and LSB
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x03); // y MSB reg
  Wire.endTransmission(); // stop transmitting
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
    yh = Wire.read(); // receive the byte
  }
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x04); // y LSB reg
  Wire.endTransmission(); // stop transmitting
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
    yl = Wire.read(); // receive the byte
  }
  int yout = (yl|(yh << 8)); //concatenate the MSB and LSB
  return yout;
}
 
int readz(void)
{
  int zl, zh; //define the MSB and LSB
 
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x05); // z MSB reg
  Wire.endTransmission(); // stop transmitting
 
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
 
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
    zh = Wire.read(); // receive the byte
  }
 
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
 
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x06); // z LSB reg
  Wire.endTransmission(); // stop transmitting
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
   zl = Wire.read(); // receive the byte
  }
  int zout = (zl|(zh << 8)); //concatenate the MSB and LSB
  return zout;
}

 

Output

Open the serial monitor window

x=126,y=1552,z=72
x=256,y=1552,z=19
x=259,y=15,z=67
x=124,y=1544,z=67
x=128,y=1545,z=64
x=124,y=1544,z=68
x=0,y=1953,z=513
x=50,y=2082,z=88
x=81,y=1698,z=612
x=186,y=1961,z=65056
x=0,y=1188,z=13
x=258,y=1286,z=65041
x=112,y=1536,z=65113

 

Links

MAG3110 Triple 3 Axis Magnetometer Breakout Electronic Compass Sensor Module For Arduino

Microbit and MMA7660 accelerometer example

The MMA7660FC is a digital output I²C, very low-power, low-profile capacitive micro-machined accelerometer featuring a low pass filter, compensation for zero-g offset and gain errors and conversion to six-bit digital values at a user configurable output data rate. The device can be used for sensor data changes, product orientation and gesture detection through an interrupt pin (INT).

Communication is handled through a 2 pin I2C interface, available on a wide range of microcontrollers. The I2C address by default is 0x4c.

Features

  • Digital output I²C
  • 3 mm x 3 mm x 0.9 mm DFN package
  • Low-power current consumption
    • Off mode: 0.4 µA
    • Standby mode: 2 µA
    • Active mode: Configurable down to 47 µA
  • Low-voltage operation: 2.4 – 3.6-volts
  • 3-axis ±1.5 g MEMS sensor and CMOS interface controller built into one package
  • Configurable output data rate from one to 120 samples a second
  • Auto wake/sleep feature for low-power consumption
  • Tilt orientation detection for portrait/landscape capability
  • Gesture detection including shake and pulse detection
  • Robust design, high shock survivability (10,000g)

 

Connection

Module connection to Microbit

  • GND = GND
  • VCC = 3v3
  • SDA = 20
  • SCL = 21

 

Code

I used this library – https://github.com/mcauser/Grove-3Axis-Digital-Accelerometer-1.5g-MMA7660FC

This is the default example

 

#include <Wire.h>
#include "MMA7660.h"
MMA7660 acc;
void setup()
{
acc.init();
Serial.begin(115200);
}
void loop()
{
static long cnt = 0;
static long cntout = 0;
float ax,ay,az;
int8_t x, y, z;
acc.getXYZ(&x,&y,&z);
if(acc.getAcceleration(&ax,&ay,&az))
{
Serial.print("got data ok: ");
}
else
{
Serial.print("timed out: ");
}
Serial.println("acceleration of X/Y/Z: ");
Serial.print(ax);
Serial.println(" g");
Serial.print(ay);
Serial.println(" g");
Serial.print(az);
Serial.println(" g");
Serial.println();
delay(500);
}

 

Output

Open the serial monitor

got data ok: acceleration of X/Y/Z:
2.76 g
0.19 g
2.33 g

got data ok: acceleration of X/Y/Z:
1.48 g
1.48 g
1.52 g

got data ok: acceleration of X/Y/Z:
2.62 g
0.00 g
0.48 g

got data ok: acceleration of X/Y/Z:
2.90 g
0.81 g
2.43 g

 

Link

https://www.nxp.com/docs/en/data-sheet/MMA7660FC.pdf

1PCS NEW MMA7660 Replace MMA7260 3 Axis Triaxial accelerometer sensor module