Goal
Arduino device to compare data for as much t/RH sensors as possible without manual sensor switch
Preparation
Use of same sensor on i2c usually limited by 1 or 2 (using ALT i2c address) of same type. And SHT20, SHT21, SHT25, HTU21 is actually same type, so to be able to compare measurement there is need to use i2c multiplexer. In case of 8 line multiplexer there is possibility to have 8-16 sensor of same time to be connected with Arduino.
Sensor i2c addresses
Sensor | address | alt address | spec | V | ||
---|---|---|---|---|---|---|
Senserion SHT2x | 0x40 | 64 | 0x41 | 65 | 20,21,25 | 3.3v |
Senserion SHT3x | 0x44 | 68 | 0x45 | 69 | SHT3x | 3.3v |
Senserion SHT8x | 0x44 | 68 | 69 | SHT85 | 3.3v | |
Meas(1) HTU21D | 0x40 | 64 | HTU21D | 3.3v | ||
Silicon Labs Si7021 | 0x40 | 64 | 3.3v | |||
Bosch(2) BMEx80 | 0x76 | 118 | 0x77 | 119 | 280,680 | 3.3v |
Ti(3) HDC1080 | 0x40 | 64 | 3.3v | |||
AOSONG DHT12 | 0x5C | 92 | 3.3v | |||
1 TE Connectivity Measurement Specialties
2 Texas Instruments
3 Bosch Sensortec
Multiplexer Lines
Line | 0x40 | 0x44 | 0x5c | 0x77 | 0x41 | 0x45 | 0x76 | 0x70 |
---|---|---|---|---|---|---|---|---|
A | SHT21 | SHT30 | DHT12 | BME680 | ||||
B | SHT21 | SHT30 | DHT12 | BME680 | ||||
C | HTU21D | SHT31 | DHT12 | BME280 | ||||
D | HTU21D | SHT31 | - | BME280 | ||||
E | HTU21D | SHT35 | - | BME280 | ||||
F | SHT20 | SHT35 | - | BME680 | ||||
G | SHT21 | SHT31 | - | BME680 | ||||
H | SHT25 | SHT85 | - | - |
i2c Scan
Port:0 i2c addr 64 i2c addr 68 i2c addr 119 Port:1 i2c addr 64 i2c addr 68 i2c addr 119 Port:2 i2c addr 64 i2c addr 68 i2c addr 118 Port:3 i2c addr 64 i2c addr 68 i2c addr 118 Port:4 i2c addr 64 i2c addr 68 i2c addr 118 Port:5 i2c addr 64 i2c addr 68 i2c addr 92 i2c addr 118 Port:6 i2c addr 64 i2c addr 68 i2c addr 92 i2c addr 118 Port:7 i2c addr 64 i2c addr 68 i2c addr 92
Hardware in use
- Mega2560 keyestudio
- LCD 3.5 inch Arduino Mega2560
- DFRobot i2c multiplexer (or compatible ShangSi MoudleCX TCA9548A i2c multiplexer)
- Sensors (DHT11, SHT21, SHT20, SHT25, HTU21D, SHT30, SHT31, SHT35, SHT85, BME280, BME680)
Draft sketch
Libraries
- UTFT
- Sodaq_SHT2x
DFRobot_I2CMultiplexer
#include <SPI.h> #include <SD.h> #include <UTFT.h> #include <DFRobot_I2CMultiplexer.h> #include <Wire.h> #include <Sodaq_SHT2x.h> // Declare which fonts we will be using extern uint8_t SmallFont[]; extern uint8_t SevenSegNumFont[]; extern uint8_t BigFont[]; /*Create an I2CMultiplexer object, the address of I2CMultiplexer is 0x70*/ DFRobot_I2CMultiplexer I2CMultiplexer(0x70); // SCREEN Type and PINs UTFT LCD(ILI9486,38,39,40,41); // SD Card PIN const int SDCARD = 53; // Variables int x; int y; int i2cPort; char i; void setupSD () { LCD.clrScr(); LCD.setColor(255, 255, 255); LCD.setBackColor(0, 0, 0); LCD.setFont(BigFont); // Setup SD LCD.print("Initializing SD card...", LEFT, 1); pinMode(SDCARD, OUTPUT); if (!SD.begin(SDCARD)) { LCD.print("Card failed, or not present", LEFT, 18); return; } LCD.print("card initialized.", LEFT, 18); } void drawTable () { LCD.setFont(SmallFont); LCD.clrScr(); // RED header LCD.setColor(80, 80, 80); LCD.fillRect(0, 0, 479, 13); // Gray Footer LCD.setColor(60, 70, 80); LCD.fillRect(0, 306, 479, 319); // Header Text (White) LCD.setColor(255, 255, 255); LCD.setBackColor(80, 80, 80); LCD.print("RH/t sensor comparision sketch", CENTER, 1); // Footer Text (Yellow) LCD.setBackColor(64, 64, 64); LCD.setColor(255,255,0); LCD.print("https://wiki.liutyi.info/", CENTER, 307); // Table title LCD.setBackColor(0, 0, 0); LCD.setColor(150,150,0); LCD.setFont(BigFont); LCD.print(" SHT2 SHT3 BMEx DHTx OTHr", CENTER, 18); for (uint8_t port=1; port<9; port++) { x=20; y=18+(28*port); LCD.printNumI(port, x, y); } // Gray Frame LCD.setColor(60, 60, 60); LCD.drawRect(0, 14, 479, 305); //Draw Grid and header text for (int y=14; y<270; y+=28) LCD.drawLine(1, y, 479, y); for (int x=79; x<479; x+=80) LCD.drawLine(x, 14, x, 266); } void initSensors () { LCD.setBackColor(0, 0, 0); LCD.setColor(100,100,0); LCD.setFont(BigFont); for (uint8_t port=0; port<8; port++) { uint8_t* dev = I2CMultiplexer.scan(port); while(*dev){ i2cPort=*dev; // SHT2x if ( i2cPort == 64 ) { i=1; } // SHT3x if ( i2cPort == 68 ) { i=2; } // BMEx80 if ( (i2cPort == 118) || (i2cPort == 119) ) { i=3; } // DHTxx if ( i2cPort == 92 ) { i=4; } x=20+(i*80); y=46+(28*port); LCD.printNumI (i2cPort, x, y); dev++; } } } void readSensors () { float hum; float temp; LCD.setFont(SmallFont); LCD.setBackColor(0, 0, 0); for (uint8_t port=0; port<8; port++) { uint8_t* dev = I2CMultiplexer.scan(port); while(*dev){ i2cPort=*dev; hum=0; temp=0; // SHT2x if ( i2cPort == 64 ) { i=1; hum=SHT2x.GetHumidity(); temp=SHT2x.GetTemperature(); } // SHT3x if ( i2cPort == 68 ) { i=2; } // BMEx80 if ( (i2cPort == 118) || (i2cPort == 119) ) { i=3; } // DHTxx if ( i2cPort == 92 ) { i=4; } x=(i*80); y=44+(28*port); LCD.setColor(0,0,255); LCD.printNumF (hum, 2, x, y, '.', 5); x=38+(i*80); y=12+46+(28*port); LCD.setColor(255,255,0); LCD.printNumF (temp, 2, x, y, '.', 5); dev++; } } delay (2000); } void setup() { int x; int y; char i; // Setup the LCD LCD.InitLCD(); // LCD.lcdOff(); // LCD.lcdOn(); // LCD.setContrast(64); // LCD.setBrightness(16); // LCD.fillScr(90,90,90); setupSD (); // Clear the screen and draw the frame drawTable (); initSensors (); delay(1000); drawTable (); } void loop() { //drawTable (); readSensors (); delay(1000); }