Overview
When using ESP32, I investigated which humidity sensor is good.
It is a continuation investigation from the temperature sensor. I understand the basic specifications and programming of I2C.
We investigated four temperature sensors priced from 350 yen to 480 yen and considered what would be the best overall temperature/humidity sensor.
Video
Japanese【日本語】
English
Sensor List
Circuit
Program
//*************************************************************************
// Temprature1 Ver2023.2.23
// Arduino board : ESP32(Arduino core for the ESP32) by Espressif Systems ver 2.0.7
// Written by IT-Taro
//***********************************************************************
#include <Wire.h>
#include <Adafruit_AHTX0.h>
#define ADC1_PIN 34
#define ADC2_PIN 15
#define S5851_ADDRESS 0x48 // S-5851A Address
Adafruit_AHTX0 aht;
unsigned long loopCount = 0;
void setup() {
// Serial monitor
Serial.begin(115200);
// ADC Setting
//analogSetAttenuation(ADC_0db); // ATT 0dB[Default 11db]
//analogSetAttenuation(ADC_6db); // ATT -6dB[Default 11db],
//analogSetWidth(10); // Resolution Default:12bit(0-4095)[9-12]
pinMode(ADC1_PIN, ANALOG);
pinMode(ADC2_PIN, ANALOG);
// I2C Setting
Wire.begin();
// AHT Setting
if (! aht.begin()) {
Serial.println("Could not find AHT? Check wiring");
while (1) delay(1000);
}
// Display Serial monitor
Serial.println("Setup completed!");
}
void loop() {
// Sleep[30 sec]
delay(30000);
loopCount++;
// ADC1[MCP9700]
uint16_t analog1_adc = analogRead(ADC1_PIN);
uint32_t analog1_mv = analogReadMilliVolts(ADC1_PIN);
double temprature1 = double(analog1_mv - 500) / 10.0;
Serial.printf("[%ld] MCP9700 ADC=%d, mV=%d[mV], temprature=%2.2f[°]\n", loopCount, analog1_adc, analog1_mv, temprature1);
// ADC2[MCP9700A]
uint16_t analog2_adc = analogRead(ADC2_PIN);
uint32_t analog2_mv = analogReadMilliVolts(ADC2_PIN);
double temprature2 = double(analog2_mv - 500) / 10.0;
Serial.printf("[%ld] MCP9700A, ADC=%d, mV=%d[mV], temprature=%2.2f[°]\n", loopCount, analog2_adc, analog2_mv, temprature2);
// I2C[S5851]
double temprature3 = updateS5851() * 0.0625 ;
Serial.printf("[%ld] S-5851A[I2C], temprature=%f[°]\n", loopCount, temprature3);
// I2C[AHT21]
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
Serial.printf("[%ld] AHT21[I2C], temprature=%f[°], humidity=%f[%]\n", loopCount, temp.temperature, humidity.relative_humidity);
}
int updateS5851 () {
Wire.beginTransmission(S5851_ADDRESS);
Wire.write(0x00); // Read Tempreture Sensor
Wire.endTransmission();
Wire.requestFrom(S5851_ADDRESS, 2);
//wait for response
while(Wire.available() == 0);
int T = Wire.read();
T = ( T << 8 | Wire.read() ) >> 4 ;
return ( -(T & 0b100000000000) | (T & 0b011111111111) );
}
//*************************************************************************
// Temprature2 Ver2023.2.23
// Arduino board : ESP32(Arduino core for the ESP32) by Espressif Systems ver 2.0.7
// Written by IT-Taro
//***********************************************************************
#include <Wire.h>
#include <CRC8.h>
#define ADC1_PIN 34
#define ADC2_PIN 15
#define AHT25_ADDRESS 0x38 // AHT25 ADDRESS
unsigned long loopCount = 0;
CRC8 crc;
void setup() {
// Serial monitor
Serial.begin(115200);
// ADC Setting
//analogSetAttenuation(ADC_0db); // ATT 0dB[Default 11db]
//analogSetAttenuation(ADC_6db); // ATT -6dB[Default 11db],
//analogSetWidth(10); // Resolution Default:12bit(0-4095)[9-12]
pinMode(ADC1_PIN, ANALOG);
pinMode(ADC2_PIN, ANALOG);
// I2C Setting
Wire.begin();
// Init AHT25
initAht25();
// Display Serial monitor
Serial.println("Setup completed!");
}
void loop() {
// Sleep[30 sec]
delay(30000);
loopCount++;
// ADC1[TMP36]
uint16_t analog1_adc = analogRead(ADC1_PIN);
uint32_t analog1_mv = analogReadMilliVolts(ADC1_PIN);
double temprature1 = double(analog1_mv - 500) / 10.0;
Serial.printf("[%ld] TMP36 ADC=%d, mV=%d[mV], temprature=%2.2f[°]\n", loopCount, analog1_adc, analog1_mv, temprature1);
// ADC2[LM335Z]
uint16_t analog2_adc = analogRead(ADC2_PIN);
uint32_t analog2_mv = analogReadMilliVolts(ADC2_PIN);
double temprature2 = double(analog2_mv / 10) - 273.15;;
Serial.printf("[%ld] LM335Z, ADC=%d, mV=%d[mV], temprature=%2.2f[°]\n", loopCount, analog2_adc, analog2_mv, temprature2);
// I2C[AHT25]
updateAht25();
}
void initAht25() {
delay(100);
Wire.beginTransmission(AHT25_ADDRESS);
Wire.write(0x71);
Wire.endTransmission();
delay(10);
crc.setPolynome(0x31);
crc.setStartXOR(0xFF);
}
void updateAht25() {
byte buf[7];
uint32_t humidity_raw;
uint32_t temperature_raw;
byte state;
Wire.beginTransmission(AHT25_ADDRESS);
Wire.write(0xAC);
Wire.write(0x33);
Wire.write(0x00);
Wire.endTransmission();
do {
delay(80);
Wire.requestFrom(AHT25_ADDRESS, 7);
if (Wire.available() >= 7) {
for(int i=0; i<7; i++) {
buf[i] = Wire.read();
}
}
} while((buf[0] & 0x80) != 0);
crc.restart();
crc.add(buf, 6);
if (buf[6] == crc.getCRC()) {
state = buf[0];
humidity_raw = ((uint32_t)buf[1] << 12)|((uint32_t)buf[2] << 4)|(((uint32_t)buf[3] >> 4) & 0x0F);
temperature_raw = (((uint32_t)buf[3] & 0x0F) << 16)|((uint32_t)buf[4] << 8)|((uint32_t)buf[5]);
double humidity = humidity_raw / 1048576.0 * 100;
double temperature = temperature_raw / 1048576.0 * 200 - 50;
Serial.printf("[%ld] AHT25[I2C], temprature=%f[°], humidity=%f[%]\n", loopCount, temperature, humidity);
} else {
// error
Serial.printf("[%ld] AHT25[I2C] Read Error!\n");
}
}
//*************************************************************************
// Temprature3 Ver2023.2.23
// Arduino board : ESP32(Arduino core for the ESP32) by Espressif Systems ver 2.0.7
// Written by IT-Taro
//***********************************************************************
#include <Wire.h>
#include <DHT.h>
#define ADC1_PIN 34
//#define ADC2_PIN 15
#define DHT11_PIN 32
#define DHT20_ADDRESS 0x38 // DHT20 Address
DHT dht11(DHT11_PIN, DHT11);
unsigned long loopCount = 0;
void setup() {
// Serial monitor
Serial.begin(115200);
// ADC Setting
//analogSetAttenuation(ADC_0db); // ATT 0dB[Default 11db]
//analogSetAttenuation(ADC_6db); // ATT -6dB[Default 11db],
//analogSetWidth(10); // Resolution Default:12bit(0-4095)[9-12]
pinMode(ADC1_PIN, ANALOG);
// pinMode(ADC2_PIN, ANALOG);
// I2C Setting
Wire.begin();
// DHT11 Setting
dht11.begin();
// Display Serial monitor
Serial.println("Setup completed!");
}
void loop() {
// Sleep[30 sec]
delay(30000);
loopCount++;
// ADC1[LM61]
uint16_t analog1_adc = analogRead(ADC1_PIN);
uint32_t analog1_mv = analogReadMilliVolts(ADC1_PIN);
double temprature1 = double(analog1_mv - 600) / 10.0;
Serial.printf("[%ld] LM61 ADC=%d, mV=%d[mV], temprature=%2.2f[°]\n", loopCount, analog1_adc, analog1_mv, temprature1);
/*/ ADC2[LM60]
uint16_t analog2_adc = analogRead(ADC2_PIN);
uint32_t analog2_mv = analogReadMilliVolts(ADC2_PIN);
double temprature2 = double(analog2_mv - 424) / 6.25;
Serial.printf("[%ld] LM60, ADC=%d, mV=%d[mV], temprature=%2.2f[°]\n", loopCount, analog2_adc, analog2_mv, temprature2);*/
// I2C[DHT20]
updateDht20();
// IO26[DHT11]
float humidity4 = dht11.readHumidity();
float temperature4 = dht11.readTemperature();
Serial.printf("[%ld] DHT11[IO26], temprature=%f[°], humidity=%f[%]\n", loopCount, temperature4, humidity4);
}
void updateDht20 () {
float hu, tp;
uint8_t buf[8];
long a;
int flg;
delay(500);
flg = 1;
while (flg) {
Wire.beginTransmission(DHT20_ADDRESS);
Wire.write(0xac);
Wire.write(0x33);
Wire.write(0x00);
Wire.endTransmission();
delay(100);
Wire.requestFrom(DHT20_ADDRESS, 6);
for (uint8_t i = 0; i < 6; i++) buf[i] = Wire.read();
if (buf[0] & 0x80) Serial.println("Measurement not Comp");
else flg = 0;
}
a = buf[1];
a <<= 8;
a |= buf[2];
a <<= 4;
a |= ((buf[3] >> 4) & 0x0f);
hu = a / 10485.76;
a = (buf[3] & 0xf);
a <<= 8;
a |= buf[4];
a <<= 8;
a |= buf[5];
tp = a / 5242.88 - 50;
Serial.printf("[%ld] DHT20[I2C], temprature=%f[°], humidity=%f[%]\n", loopCount, tp, hu);
}
Measurement result
・High-precision measurements require advanced measuring instruments, but in normal use, any sensor can measure humidity changes.
・This time, the error is the least 1st place: DHT20 2nd place: AHT25 3rd place: DHT11
Summary (Consideration: temperature and humidity sensor)
・Calculate the error rate for all measurements of temperature and humidity (10% if there is an error of 2℃ at 20℃) and total
・Least error rate 1st place: AHT25 2nd place: DHT11 3rd place: DHT20
If you use it for electronic work, I felt that “DHT20” is the best in terms of accuracy, ease of work, price, etc.
However, I2C programming is somewhat complicated, so if you want to make programming easier, “DHT11”
Document
Japanese【日本語】
English
Comments