Skip to content

Instantly share code, notes, and snippets.

@Markismus
Created March 25, 2022 07:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Markismus/846bb3cfdf1d414cb9ccd00cc9ae414e to your computer and use it in GitHub Desktop.
Save Markismus/846bb3cfdf1d414cb9ccd00cc9ae414e to your computer and use it in GitHub Desktop.
#include <SensirionI2CSht4x.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <math.h>
#include "SparkFun_SHTC3.h" // Click here to get the library: http://librarymanager/All#SparkFun_SHTC3
#include <Adafruit_BME280.h>
#define sp Serial.print
#define spln Serial.println
#define ArrayLength(x) sizeof(x)/sizeof(x[0])
#define DELAYTIME 5000 // Time in milliseconds
#define DELAYSHTC3 190
#define DELAYSHT4X 1000
#define DELAYDHT22 2000
#define DELAYBME280 1000
#define NUMBEROFLOOPS 50
#define DEBUG1
#define USESHTC3
#define USEDHT22
#define USEBME280
#define USESHT4X
#ifdef USEDHT22
#define DHTPIN1 18 // Digital pin connected to the DHT sensor
#define DHTPIN2 19 // Digital pin connected to the DHT sensor
#define DHTPIN3 23 // Digital pin connected to the DHT sensor
#define DHTPIN4 25 // Digital pin connected to the DHT sensor
// Uncomment the type of sensor in use:
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE1 DHT22 // DHT 22 (AM2302)
#define DHTTYPE2 DHT22 // DHT 22 (AM2302)
#define DHTTYPE3 DHT22 // DHT 22 (AM2302)
#define DHTTYPE4 DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
#endif
// i2c lines connections
#define SDA1 21
#define CLK1 22
#define SDA2 32
#define CLK2 33
#define I2CADDRESS_BME280 0x76
#define I2CADDRESS_SHT3C 0x70
#define I2CADDRESS_SHT4X 0x44
#define I2CLINE_SHT4X 0 // Refers to the index of SDApin and CLKpin.
#define I2CLINE_BME280 0 // Refers to the index of SDApin and CLKpin.
int SDApin[2] = { SDA1, SDA2 };
int CLKpin[2] = { CLK1, CLK2 };
#ifdef USEDHT22
int DHTpin[4] = { DHTPIN1, DHTPIN2, DHTPIN3, DHTPIN4 };
int DHTType[4] = { DHTTYPE1, DHTTYPE2, DHTTYPE3, DHTTYPE4};
// See guide for details on sensor wiring and usage:
// https://learn.adafruit.com/dht/overview
DHT dht_sensor1(DHTPIN1, DHTTYPE1);
DHT dht_sensor2(DHTPIN2, DHTTYPE2);
DHT dht_sensor3(DHTPIN3, DHTTYPE3);
DHT dht_sensor4(DHTPIN4, DHTTYPE4);
DHT dht_sensor[4] = { dht_sensor1, dht_sensor2, dht_sensor3, dht_sensor4 };
#endif
#ifdef USESHTC3
SHTC3 mySHTC3[2]; // Declare an instance of the SHTC3 class
#endif
#ifdef USESHT4X
SensirionI2CSht4x sht4x;
#endif
#ifdef USEBME280
Adafruit_BME280 bme280; // I2C
#endif
int32_t delayMax;
void setup() {
Serial.begin(115200);
Serial.print("\n\nESP32 DHT22, SHT3C, SHT4X and BME280\n\n");
// Define delay between counts
delayMax = (int) DELAYTIME;
// Initialize sensor modules.
#ifdef USESHTC3
InitSHTC3();
delayMax = max( DELAYSHTC3, delayMax);
#endif
#ifdef USESHT4X
InitSHT4X();
delayMax = max( DELAYSHT4X, delayMax);
#endif
#ifdef USEBME280
InitBME280();
delayMax = max( DELAYBME280, delayMax);
#endif
#ifdef USEDHT22
Serial.println(F("DHT22 Sensor"));
for ( int index = 0; index < ArrayLength(dht_sensor); index++) {
dht_sensor[index].begin();
}
delayMax = max( DELAYDHT22, delayMax);
#endif
}
void loop() {
static int loopcounter = 1;
sp("Running loop, count "); sp(loopcounter); sp(". ( Delay between counts is "); sp(delayMax); sp(" ms.)\n");
#ifdef USESHT4X
// Read SHT4X sensor
Wire.begin(SDApin[I2CLINE_SHT4X], CLKpin[I2CLINE_SHT4X]);
uint16_t error;
char errorMessage[256];
float sht4x_temperature;
float sht4x_humidity;
error = sht4x.measureHighPrecision(sht4x_temperature, sht4x_humidity);
if (error) {
Serial.print("Error trying to execute measureHighPrecision(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
}
Wire.end();
#endif
// Get temperature event and print its value.
#ifdef USEBME280
printTemperatureBME280();
#endif
#ifdef USESHT4X
sp("Temperature SHT4X "); Serial.print(I2CLINE_SHT4X); Serial.print(": ");
sp( sht4x_temperature ); Serial.print("°C\n");
#endif
#ifdef USESHTC3
for ( int index = 0; index < ArrayLength(SDApin); index++) {
Wire.begin(SDApin[index], CLKpin[index]);
SHTC3_Status_TypeDef result = mySHTC3[index].update(); // Call "update()" to command a measurement, wait for measurement to complete, and update the RH and T members of the object
// printInfo(index); // This function is used to print a nice little line of info to the serial port
Wire.end();
}
printTemperature(0);
printTemperature(1);
#endif
#ifdef USEDHT22
for (int index = 0; index < ArrayLength(dht_sensor); index++) {
Serial.print("Temperature DHT"); Serial.print(DHTType[index]); Serial.print(" "); Serial.print(index); Serial.print(": ");
Serial.print( dht_sensor[index].readTemperature() ); Serial.print("°C (pin="); sp(DHTpin[index]); sp(")\n");
}
#endif
// Get humidity event and print its value.
#ifdef USEBME280
printHumidityBME280();
#endif
#ifdef USESHT4X
sp("Humidity SHT4X "); Serial.print(I2CLINE_SHT4X); Serial.print(": ");
sp( sht4x_humidity); Serial.print("%\n");
#endif
#ifdef USESHTC3
printHumidity(0);
printHumidity(1);
#endif
#ifdef USEDHT22
for (int index = 0; index < ArrayLength(dht_sensor); index++) {
Serial.print("Humidity DHT"); Serial.print(DHTType[index]); Serial.print(" "); Serial.print(index); Serial.print(": ");
Serial.print( dht_sensor[index].readHumidity() ); sp("% (pin="); sp(DHTpin[index]); sp(")\n");
}
#endif
if ( ++loopcounter > NUMBEROFLOOPS ) {
while (1) {
}
}
// Delay between measurements.
delay( delayMax );
}
///////////////////////
// Utility Functions //
///////////////////////
#ifdef USESHTC3
void InitSHTC3( void ) {
Serial.println("SHTC3 Basic Readings for two i2c lines"); // Title
for ( int index = 0; index < ArrayLength(SDApin); index++) {
Wire.begin(SDApin[index], CLKpin[index]);
Serial.print("Beginning sensor for line "); Serial.print(index); Serial.print(". Result = "); // Most SHTC3 functions return a variable of the type "SHTC3_Status_TypeDef" to indicate the status of their execution
errorDecoder(mySHTC3[index].begin()); // To start the sensor you must call "begin()", the default settings use Wire (default Arduino I2C port)
Serial.println();
Wire.end();
}
}
void printTemperature( int index )
{
if (mySHTC3[index].lastStatus == SHTC3_Status_Nominal) // You can also assess the status of the last command by checking the ".lastStatus" member of the object
{
Serial.print( F("Temperature SHT3C ") ); Serial.print(index); Serial.print(": ");
Serial.print(mySHTC3[index].toDegC()); // "toDegF" and "toDegC" return the temperature as a flaoting point number in deg F and deg C respectively
Serial.println(F("°C"));
}
else
{
Serial.print("Update failed for line "); Serial.print(index); Serial.print(", error: ");
errorDecoder(mySHTC3[index].lastStatus);
Serial.println();
}
}
void printHumidity( int index )
{
if (mySHTC3[index].lastStatus == SHTC3_Status_Nominal) // You can also assess the status of the last command by checking the ".lastStatus" member of the object
{
Serial.print(F("Humidity SHT3C ")); Serial.print(index); Serial.print(": ");
Serial.print(mySHTC3[index].toPercent()); // "toPercent" returns the percent humidity as a floating point number
Serial.println(F("%"));
}
else
{
Serial.print("Update failed for line "); Serial.print(index); Serial.print(", error: ");
errorDecoder(mySHTC3[index].lastStatus);
Serial.println();
}
}
void errorDecoder(SHTC3_Status_TypeDef message) // The errorDecoder function prints "SHTC3_Status_TypeDef" resultsin a human-friendly way
{
switch (message)
{
case SHTC3_Status_Nominal : Serial.print("Nominal"); break;
case SHTC3_Status_Error : Serial.print("Error"); break;
case SHTC3_Status_CRC_Fail : Serial.print("CRC Fail"); break;
default : Serial.print("Unknown return code"); break;
}
}
#endif
#ifdef USESHT4X
void InitSHT4X( void ) {
sp("SHT4X Readings on I2C-line "); sp( I2CLINE_SHT4X ); sp(".\n");
Wire.begin(SDApin[I2CLINE_SHT4X], CLKpin[I2CLINE_SHT4X]);
uint16_t error;
char errorMessage[256];
sht4x.begin(Wire);
uint32_t serialNumber;
error = sht4x.serialNumber(serialNumber);
if (error) {
Serial.print("Error trying to execute serialNumber(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else {
Serial.print("Serial Number: ");
Serial.println(serialNumber);
}
Wire.end();
}
#endif
#ifdef USEBME280
void InitBME280( void ) {
sp("BME280 Readings on I2C-line "); sp( I2CLINE_BME280 ); sp(".\n");
Wire.setPins(SDApin[I2CLINE_BME280], CLKpin[I2CLINE_BME280]); // Use setPins() instead of begin() to prevent warning Wire.cpp about bus already set to master.
unsigned status = bme280.begin(0x76, &Wire);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
Serial.print("SensorID was: 0x"); Serial.println(bme280.sensorID(), 16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
while (1) delay(10);
}
else {
Serial.print("SensorID is: 0x"); Serial.print(bme280.sensorID(), 16);
if ( bme280.sensorID() == 96 ) {
sp(": BME280!\n");
}
else {
sp(": NOT A BME280 ID!\n");
}
}
Wire.end();
return;
}
void printTemperatureBME280( void ) {
Wire.setPins(SDApin[I2CLINE_BME280], CLKpin[I2CLINE_BME280]); // Use setPins() instead of begin() to prevent warning Wire.cpp about bus already set to master.
unsigned status = bme280.begin(0x76, &Wire);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
Serial.print("SensorID was: 0x"); Serial.println(bme280.sensorID(), 16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
while (1) delay(10);
}
else {
sp("Temperature BME280 "); Serial.print(I2CLINE_BME280); Serial.print(":");
sp( bme280.readTemperature()); Serial.print("°C\n");
}
Wire.end();
return;
}
void printHumidityBME280( void ) {
Wire.setPins(SDApin[I2CLINE_BME280], CLKpin[I2CLINE_BME280]); // Use setPins() instead of begin() to prevent warning Wire.cpp about bus already set to master.
unsigned status = bme280.begin(0x76, &Wire);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
Serial.print("SensorID was: 0x"); Serial.println(bme280.sensorID(), 16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
while (1) delay(10);
}
else {
sp("Humidity BME280 "); Serial.print(I2CLINE_BME280); Serial.print(":");
sp( bme280.readHumidity()); Serial.print("%\n");
}
Wire.end();
return;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment