ESP8266 SHT30 shield I2C code example

This example uses the same Wemos SHt30 shield or one of the variants on the internet but tis time we don’t use a library, no difificult to do this and very handy for learning just in case you ever encounter an I2C device with no library and you may have to write your own.

The key is the datasheet for the device, in there you will find the I2C address(es) and any commands or configuration that you may need, the SHT30 is quite an easy one. You can actually look at the code in the libraries you download (or on github) as well.

Code

#include <Wire.h>
 
// WEMOS SHT30 I2C address is 0x45
#define Addr 0x45
 
void setup()
{
  // Initialise I2C communication as MASTER
  Wire.begin();
  // Initialise serial communication, set baud rate = 9600
  Serial.begin(9600);
  delay(300);
}
 
void loop()
{
  unsigned int data[6];
 
  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Send measurement command
  Wire.write(0x2C);
  Wire.write(0x06);
  // Stop I2C transmission
  Wire.endTransmission();
  delay(500);
 
  // Request 6 bytes of data
  Wire.requestFrom(Addr, 6);
 
  // Read 6 bytes of data
  // cTemp msb, cTemp lsb, cTemp crc, humidity msb, humidity lsb, humidity crc
  if (Wire.available() == 6)
  {
    data[0] = Wire.read();
    data[1] = Wire.read();
    data[2] = Wire.read();
    data[3] = Wire.read();
    data[4] = Wire.read();
    data[5] = Wire.read();
  }
 
  // Convert the data
  float cTemp = ((((data[0] * 256.0) + data[1]) * 175) / 65535.0) - 45;
  float fTemp = (cTemp * 1.8) + 32;
  float humidity = ((((data[3] * 256.0) + data[4]) * 100) / 65535.0);
  // Output data to serial monitor
  Serial.print("Relative Humidity : ");
  Serial.print(humidity);
  Serial.println(" %RH");
  Serial.print("Temperature in Celsius : ");
  Serial.print(cTemp);
  Serial.println(" C");
  Serial.print("Temperature in Fahrenheit : ");
  Serial.print(fTemp);
  Serial.println(" F");
  delay(500);
}

 

Output

Open the serial monitor

Temperature in Celsius : 30.02 C
Temperature in Fahrenheit : 86.03 F
Relative Humidity : 56.31 %RH
Temperature in Celsius : 30.56 C
Temperature in Fahrenheit : 87.02 F
Relative Humidity : 60.39 %RH
Temperature in Celsius : 30.98 C
Temperature in Fahrenheit : 87.77 F
Relative Humidity : 60.43 %RH
Temperature in Celsius : 30.55 C
Temperature in Fahrenheit : 86.99 F
Relative Humidity : 54.71 %RH
Temperature in Celsius : 30.28 C
Temperature in Fahrenheit : 86.51 F
Relative Humidity : 49.55 %RH

ESP8266 and SHt30 shield example

This time we look at the SHT30 shield from Wemos. Now there are other versions of this board as well, this is the official one. You will notice they now use LOLIN (after all of the dubious clones of their products I’m assuming on the internet)

For reference the other boards look like this, I have tried these and they work as well

Here is some blurb about the SHT30

The new digital SHT3x humidity sensor series takes sensor technology to a new level. As the successor of the SHT2x series it is determined to set the next industry standard in humidity sensing. The SHT3x humidity sensor series consists of a low-cost version with the SHT30 humidity sensor, a standard version with the SHT31 humidity sensor, and a high-end version with the SHT35 humidity sensor. The SHT3x humidity sensor series combines multiple functions and various interfaces (I2C, analog voltage output) with a applications-friendly, very wide operating voltage range (2.15 to 5.5 V). The SHT3x humidity sensor is available in both large and small volumes.

More information at sensiron

The sensor is an I2C device so uses D1 and D2

 

Code

Wemos have their own library so we will use that – https://github.com/wemos/WEMOS_SHT3x_Arduino_Library

I changed the baud rate in Serial.begin, I couldn’t get the example to work. Not sure why but this did. there is also an example which use this and the OLED shield in the github repo, worth looking at

#include <WEMOS_SHT3X.h>
 
SHT3X sht30(0x45);
 
void setup() 
{
  Serial.begin(9600);
}
 
void loop() {
 
  if(sht30.get()==0){
    Serial.print("Temperature in Celsius : ");
    Serial.println(sht30.cTemp);
    Serial.print("Temperature in Fahrenheit : ");
    Serial.println(sht30.fTemp);
    Serial.print("Relative Humidity : ");
    Serial.println(sht30.humidity);
    Serial.println();
  }
  else
  {
    Serial.println("Error!");
  }
  delay(1000);
 
}

 

Output

Open the serial monitor and you should see something like this

Temperature in Celsius : 30.47
Temperature in Fahrenheit : 86.84
Relative Humidity : 40.68

Temperature in Celsius : 31.28
Temperature in Fahrenheit : 88.31
Relative Humidity : 53.50

Temperature in Celsius : 31.73
Temperature in Fahrenheit : 89.12
Relative Humidity : 61.84

 

Link

This is a clone

SHT30 Shield for WAVGAT D1 mini SHT30 I2C digital temperature and humidity sensor module

WS2812B RGB SHIELD for WeMos D1 mini examples

In this example we look at a new wemos shield (for us anyway), this is called the RGB shield and as you might expect contains RGB leds, in fact it has 7 of these LEDs

7 RGB LEDs (WS2812B-mini) each with 24-bit RGB color

Not a lot to say about this other than lets look at some examples

Code

You need to add the Adafruit Neopixel library for these examples, there are other libraries you can try of course –

Example 1

#include <Adafruit_NeoPixel.h>
 
#define PIN   D4
#define LED_NUM 7
 
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
Adafruit_NeoPixel leds = Adafruit_NeoPixel(LED_NUM, PIN, NEO_GRB + NEO_KHZ800);
 
 
void setup() 
{
  leds.begin(); // This initializes the NeoPixel library.
}
 
 
 
void led_set(uint8 R, uint8 G, uint8 B) 
{
  for (int i = 0; i < LED_NUM; i++) 
  {
    leds.setPixelColor(i, leds.Color(R, G, B));
    leds.show();
    delay(150);
  }
}
 
void loop() {
 
  led_set(10, 0, 0);//red
  led_set(0, 0, 0);
 
  led_set(0, 10, 0);//green
  led_set(0, 0, 0);
 
  led_set(0, 0, 10);//blue
  led_set(0, 0, 0);
 
}

 

Example 2

#include <Adafruit_NeoPixel.h>
 
#define PIN   D4
#define LED_NUM 7
 
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
Adafruit_NeoPixel leds = Adafruit_NeoPixel(LED_NUM, PIN, NEO_GRB + NEO_KHZ800);
 
 
void setup() 
{
  leds.begin(); // This initializes the NeoPixel library.
}
 
 
 
void loop() 
{
  for (int i = 0; i < LED_NUM; i++) 
  {
  leds.setPixelColor(i, leds.Color(10, 0, 0));
  leds.show();
  delay(250);
 
  leds.setPixelColor(i, leds.Color(0, 10, 0));
  leds.show();
  delay(250);
 
  leds.setPixelColor(i, leds.Color(0, 0, 10));
  leds.show();
  delay(250);
  }
}

 

Example 3

My favourite this one

#include <Adafruit_NeoPixel.h>
 
#define PIN   D4
#define LED_NUM 7
 
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
Adafruit_NeoPixel leds = Adafruit_NeoPixel(LED_NUM, PIN, NEO_GRB + NEO_KHZ800);
 
 
void setup() 
{
  leds.begin(); // This initializes the NeoPixel library.
  Serial.begin(9600);
  randomSeed(analogRead(A0));
}
 
 
void loop() 
{
  //you can make the colours 255 but that is bright
  int redRandom = random(10);
  int greenRandom = random(10);
  int blueRandom = random(10);
  int ledRandom = random(7);
  leds.setPixelColor(ledRandom, leds.Color(redRandom, greenRandom, blueRandom));
  leds.show();
  delay(250);
}

There are other examples in the Neopixel libarry which you can try and adapt as well

Buy it from Wemos at https://www.aliexpress.com/store/product/WS2812B-RGB-SHIELD-for-WeMos-D1-mini/1331105_32666803472.html

OPT3001 Digital Ambient Light Sensor and ESP8266 example

In this example we will connect an OPT3001 to a Wemos, this sensor measures light intensity – so you can easily create a lux meter

You can read about lux at https://en.wikipedia.org/wiki/Lux

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

 

Wemos MIni  CJMCU-3001
3v3 Vcc
Gnd Gnd
SDA SDA
SCL SCL

Code

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

#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: 7.09 lux
OPT3001: 13.30 lux
OPT3001: 21.46 lux
OPT3001: 77.02 lux
OPT3001: 186.72 lux
OPT3001: 322.96 lux
OPT3001: 371.68 lux
OPT3001: 129.60 lux
OPT3001: 9.83 lux
OPT3001: 12.87 lux
OPT3001: 6.92 lux
OPT3001: 4.42 lux

From wikipedia

Illuminance (lux) Surfaces illuminated by
0.0001 Moonless, overcast night sky (starlight)
0.002 Moonless clear night sky with airglow
0.05–0.3 Full moon on a clear night[4]
3.4 Dark limit of civil twilight under a clear sky
20–50 Public areas with dark surroundings
50 Family living room lights
80 Office building hallway/toilet lighting
100 Very dark overcast day
150 Train station platforms
320–500 Office lighting
400 Sunrise or sunset on a clear day.
1000 Overcast day; typical TV studio lighting
10,000–25,000 Full daylight (not direct sun)[3]
32,000–100,000 Direct sunlight

 

Link

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