OPT3001 Digital Ambient Light Sensor and Arduino example

In this example we will connect an OPT3001 to an Arduino

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.



  • 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



Arduino  CJMCU-3001
5v Vcc
Gnd Gnd


This example uses the following library

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.println("ClosedCube OPT3001 Arduino Test");
	Serial.print("OPT3001 Manufacturer ID");
	Serial.print("OPT3001 Device ID");
	printResult("High-Limit", opt3001.readHighLimit());
	printResult("Low-Limit", opt3001.readLowLimit());
void loop()
	OPT3001 result = opt3001.readResult();
	printResult("OPT3001", result);
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.print("Conversion ready (R):");
		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);
void printResult(String text, OPT3001 result) {
	if (result.error == NO_ERROR) {
		Serial.print(": ");
		Serial.println(" lux");
	else {
void printError(String text, OPT3001_ErrorCode error) {
	Serial.print(": [ERROR] Code #");


Open the serial monitor and you should see something like this

High-Limit: 83865.54 lux
Low-Limit: 0.00 lux
OPT3001: 248.16 lux
OPT3001: 19.08 lux
OPT3001: 12.85 lux
OPT3001: 18.91 lux
OPT3001: 230.24 lux
OPT3001: 218.64 lux
OPT3001: 15.07 lux
OPT3001: 53.40 lux
OPT3001: 173.28 lux
OPT3001: 145.44 lux


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


Arduino and US – 100 ultrasonic ranging module serial data mode example

US – 100 ultrasonic ranging module can be realized 2cm ~ 450cm of non-contact distance measurement function, with 2.4V to 4.5V wide voltage input range, the static function GPIO, serial variety of communication methods, within the band watchdog, stable and reliable.

This module is improved, the module itself has temperature compensation, the accuracy of the highest module now clean out treasure, absolute stable, economical, practical 20 * 45 mm module circuit 15 mm thick
US-100 ultrasonic ranging module can realize 2 cm ~ 4.5 m non-contact ranging function, with a 2.4 ~ 5.5 V of wide voltage input range, static power consumption less than 2 mA, bring their own temperature sensor calibration on the ranging results, and has GPIO, serial ports and so on many kinds of communication mode, inside take watchdog, stable and reliable.


Voltage: DC 2.4V – 5V
Quiescent current: < 2mA
Output mode: level or UART
Induction angle: < 15°
Detection distance: 2cm – 450cm
Precision: 0.3cm ± 1%
Working temperature: -20°C to +70°C
Size: 45 x 20 x 1.6mm


1. VCC: 5V DC
2. Trig: trigger input
3. Echo: pulse output
4. GND: ground
5. GND: ground



Module Connection Arduino Connection
VCC 5v
Trig TX (Pin 1)
Echo RX (Pin 0)



// RX (Pin 0 of Arduino digital IO) to Echo
// TX (Pin 1 of Arduino digital IO) to Trig 
unsigned int HighLen = 0;
unsigned int LowLen  = 0;
unsigned int Len_mm  = 0;
void setup() 
void loop() 
    Serial.write(0X55);                           // trig US-100 begin to measure the distance
    if(Serial.available() >= 2)                   // receive 2 bytes 
        HighLen =;                   // High byte of distance
        LowLen  =;                   // Low byte of distance
        Len_mm  = HighLen*256 + LowLen;            // Calculate the distance
        if((Len_mm > 1) && (Len_mm < 10000))       // normal distance should between 1mm and 10000mm (1mm, 10m)
            Serial.print("Present Length is: ");   
            Serial.print(Len_mm, DEC);             



UUUPresent Length is: 58mm
UPresent Length is: 57mm
UPresent Length is: 58mm
UPresent Length is: 58mm
UUUUPresent Length is: 53mm
UPresent Length is: 57mm
UUUUPresent Length is: 78mm



1 pc US-100 Ultrasonic Sensor Module With Temperature Compensation Range Distance 450cm For Arduino


Arduino and MMA8653 example

The NXP® MMA8653FC 10-bit accelerometer has industry leading performance in a small DFN package. Packed with embedded functions that include:

Flexible user-programmable options and two configurable interrupt pins
Overall power savings through inertial wake-up interrupt signals that monitor events and remain in a low-power mode during periods of inactivity

Low-profile 2 x 2 x 1.0 mm DFN package
High sensitivity: 1 mg per LSB
Low noise: 150 micro g per root Hertz (independent of resolution)
Low-power mode: 7 micro amps
Interrupt and IIC interface supply: 1.62 to 3.6 V
Supply voltage : 1.95 to 3.6 V
Output data rate: 1.5 to 800 Hz



#include <Wire.h>
// I2C BUS: already defined in "wire" librairy
// SDA: PIN 2 with pull up 4.7K to 3.3V on arduino Micro
// SCL: PIN 3 with pull up 4.7K to 3.3V on arduino Micro
// Accelerometer connected to +3.3V of arduino DO NOT CONNECT TO 5V (this will destroy the accelerometer!)
// all GND Pin of accelerometer connected to gnd of arduino
/********************ACCELEROMETER DATAS************/
// adresss of accelerometer
int adress_acc=0X1D; // MMA8653FC and MMA8652FC
// adress of registers for MMA8653FC
int ctrl_reg1 = 0x2A;
int ctrl_reg2 = 0x2B;
int ctrl_reg3 = 0x2C;
int ctrl_reg4 = 0x2D;
int ctrl_reg5 = 0x2E;
int int_source = 0x0C;
int status_ = 0x00;
int f_setup = 0x09;
int out_x_msb = 0x01;
int out_y_msb = 0x03;
int out_z_msb = 0x05;
int sysmod = 0x0B;
int xyz_data_cfg = 0x0E;
/******PROGRAM DATAS**********/
int result [3];
int axeXnow ;
int axeYnow ;
int axeZnow ;
void setup(){
Wire.begin(); // start of the i2c protocol
Serial.begin(9600); // start serial for output
ACC_INIT(); // initialize the accelerometer by the i2c bus. enter the sub to adjust the range (2g, 4g, 8g), and the data rate (800hz to 1,5Hz)
void loop()
void ACC_INIT()
I2C_SEND(ctrl_reg1 ,0X00); // standby to be able to configure
I2C_SEND(xyz_data_cfg ,B00000000); // 2G full range mode
// I2C_SEND(xyz_data_cfg ,B00000001); // 4G full range mode
// delay(1);
// I2C_SEND(xyz_data_cfg ,B00000010); // 8G full range mode
// delay(1);
I2C_SEND(ctrl_reg1 ,B00000001); // Output data rate at 800Hz, no auto wake, no auto scale adjust, no fast read mode
// I2C_SEND(ctrl_reg1 ,B00100001); // Output data rate at 200Hz, no auto wake, no auto scale adjust, no fast read mode
// delay(1);
// I2C_SEND(ctrl_reg1 ,B01000001); // Output data rate at 50Hz, no auto wake, no auto scale adjust, no fast read mode
// delay(1);
// I2C_SEND(ctrl_reg1 ,B01110001); // Output data rate at 1.5Hz, no auto wake, no auto scale adjust, no fast read mode
// delay(1); 
void I2C_SEND(unsigned char REG_ADDRESS, unsigned char DATA) //SEND data to MMA7660
void I2C_READ_ACC(int ctrlreg_address) //READ number data from i2c slave ctrl-reg register and return the result in a vector
byte REG_ADDRESS[7];
int accel[4];
int i=0; 
Wire.beginTransmission(adress_acc); //=ST + (Device Adress+W(0)) + wait for ACK
Wire.write(ctrlreg_address); // store the register to read in the buffer of the wire library
Wire.endTransmission(); // actually send the data on the bus -note: returns 0 if transmission OK-
Wire.requestFrom(adress_acc,7); // read a number of byte and store them in (note: by nature, this is called an "auto-increment register adress")
for(i=0; i<7; i++) // 7 because on datasheet p.19 if FREAD=0, on auto-increment, the adress is shifted
REG_ADDRESS[i]; //each time you read the it gives you the next byte stored. The couter is reset on requestForm
for (i=1;i<7;i=i+2)
accel[0] = (REG_ADDRESS[i+1]|((int)REG_ADDRESS[i]<<8))>>6; // X
if (accel[0]>0x01FF) {accel[1]=(((~accel[0])+1)-0xFC00);} // note: with signed int, this code is optional
else {accel[1]=accel[0];} // note: with signed int, this code is optional
case 1: axeXnow=accel[1];
case 3: axeYnow=accel[1];
case 5: axeZnow=accel[1];
void I2C_READ_REG(int ctrlreg_address) //READ number data from i2c slave ctrl-reg register and return the result in a vector
unsigned char REG_ADDRESS;
int i=0; 
Wire.beginTransmission(adress_acc); //=ST + (Device Adress+W(0)) + wait for ACK
Wire.write(ctrlreg_address); // register to read
Wire.requestFrom(adress_acc,1); // read a number of byte and store them in write received








Arduino 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.



  • 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




Arduino Module connection
5v Vcc
Gnd Gnd



This example comes from the library

#include <Wire.h>
#include <MS5611.h>
MS5611 ms5611;
double referencePressure;
void setup() 
  // Initialize MS5611 sensor
  Serial.println("Initialize MS5611 Sensor");
    Serial.println("Could not find a valid MS5611 sensor, check wiring!");
  // Get reference pressure for relative altitude
  referencePressure = ms5611.readPressure();
  // Check settings
void checkSettings()
  Serial.print("Oversampling: ");
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.print(" rawTemp = ");
  Serial.print(", realTemp = ");
  Serial.println(" *C");
  Serial.print(" rawPressure = ");
  Serial.print(", realPressure = ");
  Serial.println(" Pa");
  Serial.print(" absoluteAltitude = ");
  Serial.print(" m, relativeAltitude = ");
  Serial.println(" m");



Open the serial monitor and you will see something like this

rawTemp = 8422100, realTemp = 23.74 *C
rawPressure = 8600108, realPressure = 99667 Pa
absoluteAltitude = 138.96 m, relativeAltitude = -0.17 m

rawTemp = 8422252, realTemp = 23.75 *C
rawPressure = 8600084, realPressure = 99667 Pa
absoluteAltitude = 138.96 m, relativeAltitude = -0.17 m

rawTemp = 8471308, realTemp = 25.38 *C
rawPressure = 8583196, realPressure = 99682 Pa
absoluteAltitude = 137.69 m, relativeAltitude = -1.44 m

rawTemp = 8545740, realTemp = 27.80 *C
rawPressure = 8558564, realPressure = 99688 Pa
absoluteAltitude = 137.19 m, relativeAltitude = -1.95 m

rawTemp = 8580420, realTemp = 28.93 *C
rawPressure = 8546820, realPressure = 99691 Pa
absoluteAltitude = 136.94 m, relativeAltitude = -2.20 m



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