ESP8266 and a BH1745NUC Luminance and Colour Sensor

In this article we look at a BH1745NUC Luminance and Colour Sensor and connect it to a Wemos Mini

First of all lets take a look at the sensor – most of the info is on the manufacturers website

The BH1745NUC is digital color sensor IC with I²C bus interface. This IC senses Red, Green and Blue light (RGB) and converts them to digital values. The high sensitivity, wide dynamic range and excellent Ircut characteristics makes this IC the most suitable to obtain the illuminance and color temperature of ambient light for adjusting LCD backlight of TV, mobile phone and tablet PC. It is possible to detect very wide range light intensity. (0.005 – 40k lx)

Specifications:

VCC Voltage Range: 2.3V to 3.6V
Maximum Sensitivity: 0.005Lx/step
Current Consumption: 130μA (Typ)
Standby Mode Current: 0.8μA (Typ)
Operating Temperature Range: -40°C to +85°C

Features

The High Sensitivity and Wide Dynamic Range (0.005 – 40k lx)
Supports Low Transmittance (Dark) Window
Correspond to I²C Bus Interface
Low Current by Power Down Function
Rejecting 50Hz/60Hz Light Noise
Correspond to 1.8V Logic Interface
Programmable Interrupt Function
It is possible to select 2 type of I²C bus slave address (ADDR =’L’: “0111000”, ADDR =’H’: “0111001”)

Here is a typical module that I used

 

 

Parts Required

I connected a sensor shield to an Arduino and then the sensor via connecting wire

Name Link
Wemos Mini
BH1745NUC BH1745NUC Digital Color Sensor RGB Detecting Sensor Light Module
Connecting wire Free shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire

 

Schematic/Connection

Be careful as I used a CJMCU-1745 – the sensor is rated at 2.3V to 3.6V. So use the 3.3v output

 

Code Example

This is a controleverything example – they have code examples for various platforms. It does not use a library and I always think these are good for learning especially when you pair this up with the datasheet and how they build the code. An example is the following line

// Select mode control register1
Wire.write(0x41);

#include <Wire.h>

// I2C address of the BH1745NUC
#define Addr 0x38

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 mode control register1
    Wire.write(0x41);
    // Set RGBC measurement time 160 msec
    Wire.write(0x00);
    // Stop I2C Transmission
    Wire.endTransmission();
    
    // Start I2C Transmission
    Wire.beginTransmission(Addr);
    // Select mode control register2
    Wire.write(0x42);
    // Set measurement mode is active, gain = 1x
    Wire.write(0x90);
    // Stop I2C Transmission
    Wire.endTransmission();
    
    // Start I2C Transmission
    Wire.beginTransmission(Addr);
    // Select mode control register3
    Wire.write(0x44);
    // Set default value
    Wire.write(0x02);
    // Stop I2C Transmission
    Wire.endTransmission();
    delay(300);
}

void loop()
{
    unsigned int data[8];
    for(int i = 0; i < 8; i++)
    {
        // Start I2C Transmission
        Wire.beginTransmission(Addr);
        // Select data register
        Wire.write((80+i));
        // Stop I2C Transmission
        Wire.endTransmission();
        
        // Request 1 byte of data from the device
        Wire.requestFrom(Addr, 1);
        
        // Read 8 bytes of data
        // Red lsb, Red msb, Green lsb, Green msb, Blue lsb, Blue msb
        // cData lsb, cData msb
        if(Wire.available() == 1)
        {
            data[i] = Wire.read();
        }
        delay(300);
    }

    // Convert the data
    int red = ((data[1] & 0xFF) * 256) + (data[0] & 0xFF);
    int green = ((data[3] & 0xFF) * 256) + (data[2] & 0xFF);
    int blue = ((data[5] & 0xFF) * 256) + (data[4] & 0xFF);
    int cData = ((data[7] & 0xFF) * 256) + (data[6] & 0xFF);
    
    // Output data to serial monitor
    Serial.print("Red Color luminance  : ");
    Serial.println(red);
    Serial.print("Green Color luminance : ");
    Serial.println(green);
    Serial.print("Blue Color luminance : ");
    Serial.println(blue);
    Serial.print("Clear Data Color luminance : ");
    Serial.println(cData);
}

[/codesyntax]

 

Output

Open the serial monitor, this is what I saw

Clear Data Color luminance : 2
Red Color luminance : 50
Green Color luminance : 52
Blue Color luminance : 14
Clear Data Color luminance : 16
Red Color luminance : 51
Green Color luminance : 46
Blue Color luminance : 15
Clear Data Color luminance : 17
Red Color luminance : 13
Green Color luminance : 0
Blue Color luminance : 0
Clear Data Color luminance : 0
Red Color luminance : 0
Green Color luminance : 0
Blue Color luminance : 9
Clear Data Color luminance : 24

Place different colored objects beside the sensor and check the values

Links

https://www.rohm.com/datasheet/BH1749NUC/bh1749nuc-e

ESP8266 and BMP388 barometric pressure sensor

In this article we look at another sensor – it is a BMP388 by Bosch Sensortec, so lets crack on and try this out with our Wemos board

As usual we will look at some of the manufacturers information from the website on the sensor

BMP388 Information

The BMP388 is a very small, low-power and low-noise 24 bit absolute barometric pressure sensor. It enables accurate altitude tracking and is specifically suited for drone applications. The best-in-class TCO of the BMP388 between 0-65°C for accurate altitude measurement over a wide temperature range greatly enhances the drone flying experience by making accurate steering easier.

It is compatible for use with other Bosch sensors, including BMI088 for better performance, robustness and stability.

The BMP388 sensor offers outstanding design flexibility, providing a single package solution that is easy to integrate into other existing and upcoming devices such as smart homes, industrial products and wearables.

It is more accurate than its predecessors, covering a wide measurement range from 300 hPa to 1250 hPa. BMP388 exhibits an attractive price-performance ratio coupled with low power consumption. It is available in a compact 10-pin 2.0 x 2.0 x 0.75 mm³ LGA package with metal lid.

  • Operating voltage: 3.3V/5V
  • Communication interface: I2C/SPI
  • Barometric pressure operation range: 300~1250hPa
  • Barometric pressure absolute accuracy: ±0.40hPa (@900~1100hPa, 25~40℃)
  • Barometric pressure relative accuracy: ±0.08hPa (@900~1100hPa, 25~40℃)
  • Temperature coefficient offset: ±0.75Pa/K (@700~1100hPa, -20~65℃))
  • Temperature absolute accuracy: ±0.5℃ (0~65℃)
  • Possible resolution: 0.016Pa (high precision mode)
  • Possible sampling rate: 200Hz
  • Operating voltage: -40~85℃

If you purchase a module they will have a 3.3v regulator on board, you will also have the option of I2C or SPI, here is the module that I located. You can see that it has Vin and 3v written on the board

Parts Required

 

Name Link
ESP8266 – wemos D1 mini by WeMos
BMP388 24-bit low noise BMP388 digital temperature atmospheric pressure sensor
Connecting wire Free shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire

Schematic/Connection

I use the sensor in I2C mode – as you can see in the layout below

wemos and bmp388
wemos and bmp388

Code Example

I used the library from adafruit, you can download this from – https://github.com/adafruit/Adafruit_BMP3XX. 

This library can be installed via the library manager. This is the default code example and I have removed some of the SPI code and code comments since I was using the sensor in I2C mode

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"
 
 
#define SEALEVELPRESSURE_HPA (1013.25)
 
Adafruit_BMP3XX bmp; // I2C
 
 
void setup() {
  Serial.begin(115200);
  while (!Serial);
  Serial.println("BMP388 test");
 
  if (!bmp.begin()) {
    Serial.println("Could not find a valid BMP3 sensor, check wiring!");
    while (1);
  }
 
  // Set up oversampling and filter initialization
  bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
  bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
  bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
  //bmp.setOutputDataRate(BMP3_ODR_50_HZ);
}
 
void loop() {
  if (! bmp.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }
  Serial.print("Temperature = ");
  Serial.print(bmp.temperature);
  Serial.println(" *C");
 
  Serial.print("Pressure = ");
  Serial.print(bmp.pressure / 100.0);
  Serial.println(" hPa");
 
  Serial.print("Approx. Altitude = ");
  Serial.print(bmp.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");
 
  Serial.println();
  delay(2000);
}

 

Output

Open the serial monitor and you should see something like this, the value swill be slightly different depending on your location and current weather conditions

BMP388 test
Temperature = 23.64 *C
Pressure = 844.40 hPa
Approx. Altitude = 470.89 m

 

 

Read and write to the eeprom on the ESP8266

Description

The ESP8266 has 512 bytes of internal EEPROM, this could be useful if you need to store some settings, such as an IP address or some Wifi details

Code

The write example first

#include <EEPROM.h>
 
int addr = 0;
 
void setup()
{
  EEPROM.begin(512);  //Initialize EEPROM
 
  // write to EEPROM.
  EEPROM.write(addr, 'a');    
  addr++;                      //Increment address
  EEPROM.write(addr, 'b');   
  addr++;                      //Increment address
  EEPROM.write(addr, 'C');    
 
  //Write string to eeprom
  String sample = "testing eeprom";
  for(int i=0;i<sample.length();i++)
  {
    EEPROM.write(0x0F+i, sample[i]); //Write one by one with starting address of 0x0F
  }
  EEPROM.commit();    //Store data to EEPROM
}
 
void loop()
{   
}

 

And now the read example

#include <EEPROM.h>
 
int addr = 0;
 
void setup()
{
  EEPROM.begin(512);  //Initialize EEPROM
  Serial.begin(9600); 
  Serial.println("");
  Serial.print(char(EEPROM.read(addr)));
  addr++;                      //Increment address
  Serial.print(char(EEPROM.read(addr)));
  addr++;                      //Increment address
  Serial.println(char(EEPROM.read(addr)));
 
  //Read string from eeprom (testing eeprom)
  String strText;   
  for(int i=0;i<14;i++) 
  {
    strText = strText + char(EEPROM.read(0x0F+i)); //Read one by one with starting address of 0x0F    
  }  
 
  Serial.print(strText);  //Print the text
}
 
void loop()
{ 
}

Output

Open the serial monitor
abC
testing eeprom

A look at various ESP specific APIs

 

Description

Some ESP-specific APIs related to deep sleep, RTC and flash memories are available in the ESP object. These may be useful, we have already looked at the restart one

Code

 

/*
ESP.restart() restarts the CPU.
ESP.getResetReason() returns a String containing the last reset reason in human readable format.
ESP.getFreeHeap() returns the free heap size.
ESP.getHeapFragmentation() returns the fragmentation metric (0% is clean, more than ~50% is not harmless)
ESP.getMaxFreeBlockSize() returns the maximum allocatable ram block regarding heap fragmentation
ESP.getChipId() returns the ESP8266 chip ID as a 32-bit integer.
ESP.getCoreVersion() returns a String containing the core version.
ESP.getSdkVersion() returns the SDK version as a char.
ESP.getCpuFreqMHz() returns the CPU frequency in MHz as an unsigned 8-bit integer.
ESP.getSketchSize() returns the size of the current sketch as an unsigned 32-bit integer.
ESP.getFreeSketchSpace() returns the free sketch space as an unsigned 32-bit integer.
ESP.getSketchMD5() returns a lowercase String containing the MD5 of the current sketch.
ESP.getFlashChipId() returns the flash chip ID as a 32-bit integer.
ESP.getFlashChipSize() returns the flash chip size, in bytes, as seen by the SDK (may be less than actual size).
ESP.getFlashChipRealSize() returns the real chip size, in bytes, based on the flash chip ID.
ESP.getFlashChipSpeed(void) returns the flash chip frequency, in Hz.
ESP.getCycleCount() returns the cpu instruction cycle count since start as an unsigned 32-bit. This is useful for accurate timing of very short actions like bit banging.
ESP.getVcc() may be used to measure supply voltage. ESP needs to reconfigure the ADC at startup in order for this feature to be available. Add the following line to the top of your sketch to use
*/
 
void setup() {
 
Serial.begin(115200);
 
Serial.print("SDK version:");
Serial.println(ESP.getSdkVersion());
 
Serial.print("Core version:");
Serial.println(ESP.getCoreVersion());
 
Serial.print("CPU ferquency:");
Serial.println(ESP.getCpuFreqMHz());
 
Serial.print("Chip ID:");
Serial.println(ESP.getChipId());
 
Serial.print("Reset Reason:");
Serial.println(ESP.getResetReason());
 
Serial.print("Free heap:");
Serial.println(ESP.getFreeHeap());
 
}
 
void loop() {}

 

Output

Open the serial monitor

SDK version:2.2.1(cfd48f3)
Core version:2_4_2
CPU ferquency:80
Chip ID:1947093
Reset Reason:External System
Free heap:51880