Humidity Sensor Investigation (Electronic work) [What is the first place? ]

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

Comments

Copied title and URL