STM32 Nucleo and TSL2561 Luminosity Sensor example

This TSL2561 is an I2C light-to-digital converter TSL2561 that transforms light intensity to a digital signal. The TSL2561 features a selectable light spectrum range due to its dual light sensitive diodes: infrared and full spectrum. You can switch among three detection modes to take your readings. They are infrared mode, full spectrum and human visible mode.

When running under the human visible mode, this sensor will give you readings just close to your eye feelings.

Features

Selectable detection modes
High resolution 16-Bit digital output at 400 kHz I2C Fast-Mode
Wide dynamic range: 0.1 – 40,000 LUX
Wide operating temperature range: -40°C to 85°C
Programmable interrupt function with User-Defined Upper and lower threshold settings

Here is a typical module that makes it easier to work with the sensor

tsl2561

Layout and Connection

 

Code

We use this as a basis – https://os.mbed.com/users/anhnt2407/code/TSL2561_Light_sensor/

Update the tsl2561.h for STM32 nucleo

#define TSL2561_I2C_PINNAME_SDA PB_9
#define TSL2561_I2C_PINNAME_SCL PB_8

 

#include "mbed.h"
#include "TSL2561.h"
Serial PC(USBTX, USBRX);
#define PC_PRINTX(z,x) if(z==1) PC.printf(x);
#define PC_PRINTLNX(z,x) if(z==1) {PC.printf(x); PC.printf("\r\n");}
#define PC_PRINTXY(z,x, y) if(z==1) PC.printf(x, y);
#define PC_PRINTLNXY(z,x, y) if(z==1) {PC.printf(x, y); PC.printf("\r\n");}
DigitalOut myled(LED1);
TSL2561 tsl2561(TSL2561_ADDR_FLOAT);
Timer setuptimer;
Timer executetimer;
void setup(void){
if (tsl2561.begin()) {
PC_PRINTLNX(1,"TSL2561 Sensor Found");
} else {
PC_PRINTLNX(1,"TSL2561 Sensor not Found");
}
// You can change the gain on the fly, to adapt to brighter/dimmer tsl2561 situations
tsl2561.setGain(TSL2561_GAIN_0X); // set no gain (for bright situtations)
tsl2561.setTiming(TSL2561_INTEGRATIONTIME_402MS); // longest integration time (dim tsl2561)
// Now we're ready to get readings!
}
int main() {
PC_PRINTLNX(1,"----------START-------------");
setuptimer.start();
setup();
setuptimer.stop();
PC_PRINTLNXY(1,"Setup time: %f",setuptimer.read());
setuptimer.reset();
uint16_t x,y,z;
while(1) {
executetimer.start();
x = tsl2561.getLuminosity(TSL2561_VISIBLE);
y = tsl2561.getLuminosity(TSL2561_FULLSPECTRUM);
z = tsl2561.getLuminosity(TSL2561_INFRARED);
executetimer.stop();
PC_PRINTLNXY(1,"Visible: %d",x);
PC_PRINTLNXY(1,"Full Spectrum: %d",y);
PC_PRINTLNXY(1,"Infrared: %d",z);
PC_PRINTLNXY(1,"Execution Time: %f",executetimer.read());
executetimer.reset();
// wait(1);
PC_PRINTLNX(1,"----------COMPLETE-------------");
}
}

Testing

Using a terminal program like teraterm you should see something like this

tsl2561 output

tsl2561 output

 

Links

Free Shipping 1pcs GY-2561 TSL2561 Luminosity Sensor Breakout infrared Light Sensor module integrating sensor AL

Share

STM32 Nucleo and LM75 temperature sensor example

In this example we connect an LM75 to a STM32 Nucleo and we will use the MBEd compiler

The LM75 temperature sensor includes a delta-sigma analog-to-digital converter, and a digital overtemperature detector. The host can query the LM75 through its I²C interface to read temperature at any time. The open-drain overtemperature output (OS) sinks current when the programmable temperature limit is exceeded.

The OS output operates in either of two modes, comparator or interrupt. The host controls the temperature at which the alarm is asserted (TOS) and the hysteresis temperature below which the alarm condition is not valid (THYST). Also, the LM75’s TOS and THYST registers can be read by the host.

The address of the LM75 is set with three pins to allow multiple devices to work on the same bus. Power-up is in comparator mode, with defaults of TOS = +80°C and THYST = +75°C. The 3.0V to 5.5V supply voltage range, low supply current, and I²C interface make the LM75 ideal for many applications in thermal management and protection.

Key Features

SO (SOP) and µMAX® (µSOP) Packages
I²C Bus Interface
Separate Open-Drain OS Output Operates as Interrupt or Comparator/Thermostat Input
Register Readback Capability
Power-Up Defaults Permit Stand-Alone Operation as a Thermostat
3.0V to 5.5V Supply Voltage
Low Operating Supply Current 250µA (typ), 1mA (max)
4µA (typ) Shutdown Mode Minimizes Power Consumption
Up to Eight LM75s Can Be Connected to a Single Bus

 

Layout

I2C device you can power it from 3.3 or 5v

 

stm32nucleo and lm75

stm32nucleo and lm75

 

Code

I used this library – https://os.mbed.com/users/chris/code/LM75B/

 

#include "mbed.h"
#include "LM75B.h"
LM75B tmp(I2C_SDA, I2C_SCL);
Serial pc(SERIAL_TX, SERIAL_RX);
int main ()
{
while (1) {
pc.printf("%.2f celsius\r\n",tmp.read());
wait(1.0);
}
}

 

Output

Using a serial terminal program you should see something like this

lm75 output

lm75 output

 

Links

LM75 temperature sensor high speed I2C interface high precision development board module

Share

STM32 Nucleo and MS5611 barometric pressure sensor example

In this example we connect an MS5611 to an STM32 Nucleo – in this case it was a Nucleo-F446RE

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.

 

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

ST32 Nucleo Module connection
3v3 Vcc
Gnd Gnd
SCL SCL
SDA SDA

Here is a layout

stm32nucleo and ms5611

stm32nucleo and ms5611

Code

Import this into the MBEd compiler – https://os.mbed.com/teams/Aerodyne/code/MS5611Example/

I slightly modified to loop the output, thats about it

/* MS5611 Pressure sensor example
Aerodyne Labs
2014
*/
#include "mbed.h"
//Only uncomment the one needed.
//#include "MS5611SPI.h"
#include "MS5611I2C.h"
int main() {
//Only uncomment the I2C or SPI version.
//MS5611SPI ms5611(p11, p12, p13, p10);
//MS5611I2C ms5611(p9, p10, false);
//PB_9 and PB_8 for Nucleo boards
MS5611I2C ms5611(PB_9, PB_8, false);
//Print the Coefficients from the
ms5611.printCoefficients();
while(1) {
printf("Pressure = %.0f Pa \r\n", ms5611.getPressure());
printf("Temperature = %.2f degC \r\n", ms5611.getTemperature());
printf("Altitude = %.2f m \r\n", ms5611.getAltitude());
printf("-------------------\r\n");
wait(2.0f);
}
}

 

Output

Use a program like teraterm and you should see something like this

 

ms5611 output

ms5611 output

 

Link

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

Share

Arduino Due and TM1637 7 segment display example

A common display module that you can buy on the internet contain the Tm1638 driver chip, I was interested in this one which is the TM1637 which appears to be a more basic version which can only control a display, the TM1638 can also control LED’s, buttons and two displays at the same time.

This is a common anode 4-digit tube display module which uses the TM1637 driver chip; Only 2 connections are required to control the 4-digit 8-segment displays

Here is the module

Features of the module

Display common anode for the four red LED
Powered supply by 3.3V/5V
Four common anode tube display module is driven by IC TM1637
Can be used for Arduino devices, two signal lines can make the MCU control 4 8 digital tube. Digital tube 8 segment is adjustable

Here is how to hook the module up, the good news is this worked with my Arduino Due and 3.3v

Schematic

arduino due and TM1637

arduino due and TM1637

 

Code

There is a library for this IC, you can get it from https://github.com/avishorp/TM1637 , as usual there is a built in example but here is a simple sketch

#include <TM1637Display.h>
 
const int CLK = 3; //Set the CLK pin connection to the display
const int DIO = 2; //Set the DIO pin connection to the display
 
int numCounter = 0;
 
TM1637Display display(CLK, DIO); //set up the 4-Digit Display.
 
void setup()
{
display.setBrightness(0x0a); //set the diplay to maximum brightness
}
 
void loop()
{
for(numCounter = 0; numCounter < 1000; numCounter++) //Iterate numCounter
{
display.showNumberDec(numCounter); //Display the numCounter value;
delay(1000);
}
}

 

Links

1pcs SAMIORE ROBOT 4 Bits TM1637 Red Digital Tube LED Display Module & Clock LED

Share

OPT3001 Digital Ambient Light Sensor and Arduino example

In this example we will connect an OPT3001 to an Arduino Due

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.

 

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

 

Arduino Due CJMCU-3001
3.3v Vcc
Gnd Gnd
SDA SDA
SCL 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

Open the serial monitor and you should see something like this

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

Link

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

Share