AHT1x / AHT2x Sensor Module#


Aosong Digital Temperature & Humidity Sensors#

บริษัท Aosong Electronics ในประเทศจีน เป็นผู้ผลิตชิปและโมดูลประเภทเซนเซอร์ราคาถูกสำหรับวัดค่าอุณหภูมิและความชื้นสัมพัทธ์แบบดิจิทัล (Digital Temperature & Humidity Sensor) ยกตัวอย่างเช่น โมดูล DHT11 และ DHT22 (AM2302) เป็นต้น และใช้สายสัญญาณดิจิทัลเพียงเส้นเดียวสำหรับการสื่อสารข้อมูล

แต่ถ้าเป็นเซนเซอร์ที่ใช้วิธีการสื่อสารด้วยบัส I2C (สามารถใช้ความเร็วได้ถึง 400kHz) และเป็นชิปที่มีขนาดเล็ก ใช้พลังงานต่ำ ก็มีตัวเลือกดังนี้

AHT10 AHT20 AHT21
Humidity 0 ~ 100 %RH 0 ~ 100 %RH 0 ~ 100 %RH
Humidity Accuracy (@25℃) ±2 %RH ±2 %RH ±2 %RH
Temperature -40 ~ +85 °C -40 ~ +85 ℃ -40 ~ +120 ℃
Temperature Accuracy ±0.3 °C ±0.3 °C ±0.3 °C
Supply Voltage (VDD) 1.8 ~ 3.6 V 2.2 ~ 5.5 V 2.2 ~ 5.5 V
Power Consumption (Measure) 0.07 mW 3.2 mW 3.2 mW

Datasheet (PDF, local copy): AHT10 | AHT20 | AHT21

จากตารางเปรียบเทียบ จะเห็นได้ว่า AHT10 มีช่วงแรงดันไฟเลี้ยงที่ต่ำกว่า และใช้กำลังไฟฟ้าน้อยกว่า AHT2x และ AHT22 สามารถทำงานและวัดค่าอุณหภูมิได้สูงกว่า +85 ℃ (ได้ถึง +120 ℃) แต่ถ้าพิจารณาทั้งสามตัวเลือก เรื่องความแม่นของการวัดค่า (Measurement Accuracy) ก็ถือว่า ไม่แตกต่างกัน

ไอซี AHT10 / ATH20 / AHT21 มีขา ADDR เพียงหนึ่งขา ดังนั้นจึงสามารถเลือกแอดเดรส (7-bit I2C device address) สำหรับการสื่อสารด้วยบัส I2C ได้เป็น 0x38 และ 0x39 เท่านั้น

สำหรับการเลือกใช้งาน ก็มีโมดูลประเภท Breakout ให้เลือกใช้งาน โมดูล AHT2x มักจะมีไอซี LDO Voltage Regulator อยู่ด้วย เช่น ไอซีเบอร์ 662K / XC6206P332MR แปลงแรงดัน VCC / VDD จาก +5V ให้เป็น +3.3V และมีไอซีทรานซิสเตอร์ N-channel MOSFET (เช่น เบอร์ K27 / 2N7002) ในวงจรแปลงระดับแรงดัน (Logic Voltage Level Shifter) สำหรับสัญญาณ SDA และ SCL ซึ่งมีตัวต้านทานแบบ Pull-Up (เช่น 4.7kΩ หรือ 10kΩ) อยู่ด้วย โมดูลที่มีวงจรในลักษณะนี้สามารถใช้งานร่วมกับบอร์ดไมโครคอนโทรลเลอร์ 5V ได้ เช่น Arduino Uno หรือ Nano เป็นต้น

รูป: ตัวอย่างการเชื่อมต่อด้วยบัส I2C กับอุปกรณ์ที่ทำหน้าที่เป็น I2C Master เช่น ไมโครคอนโทรลเลอร์

รูป: ตัวอย่างโมดูล AHT10 (มีตัวต้านทานแบบ SMD บัดกรีไว้เพื่อเลือกแอดเดรส)

รูป: ตัวอย่างโมดูล AHT2x มีไอซี AHT21 และใช้แอดเดรส 0x38 แต่ไม่สามารถเลือกแอดเดรสได้

รูป: ตัวอย่างโมดูล AHT20 (ซ้าย) และ AHT21 (ขวา)

รูป: ตัวอย่างโมดูล AHT20

รูป: ตัวอย่างโมดูล AHT20

 

ข้อสังเกต: โมดูล AHT10 / AHT2x ที่ได้เลือกมาเป็นตัวอย่างมีการใช้ไอซี 662K สำหรับ 3.3V LDO Voltage Regulator มีไอซี K27 (Dual N-Channel MOSFETs) และตัวตานทานแบบ R-Pack (เช่น 4.7k หรือ 10k) สำหรับการสร้างวงจรที่ใช้ทรานซิสเตอร์แปลงระดับแรงดันลอจิกที่ขาสัญญาณ I2C (SCL/SDA)

ในกรณีที่ต้องการใช้งานโมดูลเซนเซอร์ร่วมกับบอร์ด Arduino Uno / Nano (5V) แต่ตัวไอซี AHT10 จะทำงานที่แรงดันไฟเลี้ยง 3.3V (ไม่เกิน 3.6V) ดังนั้นจึงต้องมีการแปลงระดับแรงดันไฟฟ้าของสัญญาณ ระหว่าง 5V กับ 3.3V (Logic Voltage Levels) แต่ถ้าเป็น AHT2x จะรับช่วงแรงดันไฟเลี้ยงได้ถึง +5V

รูป: ตัวอย่างผังวงจรของโมดูล AHT10

รูป: ตัวอย่างโมดูล AHT21B (ไม่มี 3.3V Voltage Regulator) และสามารถใช้แรงดันไฟเลี้ยง +5V สำหรับบอร์ด Arduino Uno/Nano หรือใช้ +3.3V สำหรับบอร์ดไมโครคอนโทรลเลอร์ เช่น ESP32 และ RP2040

 

ในปัจจุบันก็มีหลายบริษัทได้ผลิตและจำหน่ายโมดูล AHT2x และได้พัฒนาไลบรารีสำหรับการเขียนโปรแกรมด้วย Arduino ให้เลือกใช้งาน ได้แก่

โค้ดของไลบรารีสำหรับ MicroPython / CircuitPython ใน Github ก็มีเช่นกัน

รูป: การส่งคำสั่งเพื่ออ่านค่าจากเซนเซอร์ผ่านทางบัส I2C สำหรับ AHT2x (อ้างอิงจาก AHT21 Datasheet)

จากรูปจะเห็นได้ว่า ถ้าต้องการอ่านค่าจากเซนเซอร์ ก็ให้ส่งคำสั่ง Trigger Measurement Command ที่ประกอบด้วย 4 ไบต์ ตามลำดับไปยังเซนเซอร์ โดยที่ไบต์แแรกเป็น 7-bit address + Write bit แล้วจึงตามด้วย 0xAC (CMD), 0x33 (DATA1), 0x00 (DATA2) ตามลำดับ

หลังจากนั้นจะต้องรออย่างน้อย 80 msec จึงอ่านข้อมูลจำนวน 6 ไบต์ (สำหรับ AHT10) โดยที่ข้อมูลไบต์แรก เป็น State Bits แล้วตามด้วยข้อมูลอีก 5 ไบต์ (หรือ 40 บิต) แบ่งเป็นค่าความชื้นสัมพัทธ์ () และค่าอุณหภูมิ () อย่างละ 20 บิต ซึ่งสามารถนำไปแปลงค่าตามสูตรต่อไปนี้

แต่ถ้าเป็น AHT2x จะมีอีกหนึ่งไบต์ (CRC8 Checksum Byte) ซึ่งจะใช้สำหรับตรวจสอบความถูกต้องด้วยวิธีการคำนวณค่า CRC8 Checksum ตามรูปแบบของ Dallas/Maxim

 


ตัวอย่างโค้ดสำหรับ Arduino#

โค้ดตัวอย่างแรกสาธิตการตรวจสอบดูว่า มีอุปกรณ์ I2C Slave Devices ที่เชื่อมต่อกับ บัส I2C อยู่หรือไม่ โดยจะแสดงเลขแอดเดรส (ฐานสิบหก) ของอุปกรณ์

// Author: RSP @ KMUTNB
// Date: 2022-08-21
// Target: Arduino ESP32 or Uno/Nano
#include <Wire.h>

// Select I2C Pins for ESP32 
#define I2C_SDA_PIN   (33) 
#define I2C_SCL_PIN   (32)

void setup() {
  Serial.begin( 115200 );
  while (!Serial) { delay(10); }
  Serial.println( "\n\n\n" );
  // __DATE__ and __TIME__ expand to current date and time (at compile time). 
  Serial.println( "Compiled on " __DATE__ ", at " __TIME__ );
  // set I2C pins for ESP32
#if defined(ESP32)
  Serial.println( "Set I2C pins for ESP32" );
  Wire.begin( I2C_SDA_PIN, I2C_SCL_PIN );
#else
  Wire.begin();
#endif  
  Wire.setClock( 100000 ); // 100kHz
}

#define LINE_SEP  "--------------------"

void i2c_scan() {
  char sbuf[32];
  int n_devices = 0;
  Serial.println( F("Scanning I2C bus...") );
  Serial.print( "   " );
  for ( uint8_t col=0; col < 16; col++ ) {
    sprintf( sbuf, "%3x", col );
    Serial.print( sbuf );
  }
  Serial.println( "" );
  uint8_t addr=0;
  for( uint8_t row=0; row < 8; row++ ) {
    sprintf( sbuf, "%02x:", row << 4 );
    Serial.print( sbuf );
    for ( uint8_t col=0; col < 16; col++ ) {
      if ( row==0 && addr<=1 ) {
        Serial.print("   ");
      } else {
        Wire.beginTransmission( addr );
        if ( Wire.endTransmission() > 0 ) {
          Serial.print( " --" );
        } else {
          sprintf( sbuf, " %2x", addr );
          Serial.print( sbuf );
          n_devices++;
        }
      }
      addr++;
    }
    Serial.println( "" );
  }
  Serial.println( LINE_SEP LINE_SEP LINE_SEP );
  Serial.flush();
}

void loop() {
  i2c_scan();
  delay(5000);
}

รูป: ตัวอย่างข้อความเอาต์พุต ซึ่งแสดงให้เห็นว่า มีการตรวจพบอุปกรณ์หมายเลข0x38 ที่กำลังเชื่อมต่ออยู่

ถัดไปเป็นตัวอย่างการเขียนโค้ด Arduino สำหรับ ESP32 หรือ Arduino Uno/Nano เพื่ออ่านค่าจากโมดูลเซนเซอร์ AHT2x

ถ้าเป็น ESP32 ได้เลือกใช้ขาตามความเหมาะสม เช่น GPIO-32 และ GPIO-33 ในตัวอย่างนี้ แต่ถ้าเป็น Arduino จะเป็นขา A4 และ A5 สำหรับสัญญาณ SCL และ SDA ตามลำดับ

ในโค้ดตัวอย่างนี้ ได้มีการสร้างฟังก์ชันเพื่อใช้งานกับ AHT2x ดังนี้

  • aht2x_init() เริ่มต้นใช้งานอุปกรณ์ (Device Initialization) โดยส่งคำสั่งไปยังอุปกรณ์และเปิดการตั้งค่าชดเชย (Calibration Enabled)
  • aht2x_crc8() ตรวจสอบความถูกต้องของข้อมูลไบต์ในอาร์เรย์ที่ได้รับมา โดยเปรียบเทียบกับข้อมูลไบต์สำหรับ CRC8 Checksum
  • aht2x_read_sensor() สั่งให้อุปกรณ์ทำการวัดแล้วอ่านค่าความชื้นสัมพัทธ์และอุณหภูมิ
#include <Wire.h>

// Select I2C Pins for ESP32
#define I2C_SDA_PIN  (33)
#define I2C_SCL_PIN  (32)
// Note: use A4/A5 for SDA/SCL pins for Arduino Uno/Nano boards.

#define AHT2X_ADDR   (0x38)  // 0x38 or 0x39
const uint8_t AHT2X_CALIB_CMD[3]   = {0xBE, 0x08, 0x00};
const uint8_t AHT2X_MEASURE_CMD[3] = {0xAC, 0x33, 0x00};

void aht2x_init() {
  Wire.beginTransmission( AHT2X_ADDR );
  Wire.write( AHT2X_CALIB_CMD, 3 );
  Wire.endTransmission();
}

uint8_t aht2x_crc8( uint8_t *data, int len ) {
  // Calculate CRC8 checksum (Dallas/Maxim).
  // The initial value of CRC is 0xFF.
  // The CRC polynomial: X^8 + X^5 + X^4 + 1 => 0b00110001 (0x31)
  uint8_t crc = 0xff;
  for ( uint8_t j=0; j < len; j++ ) {
     crc ^= data[j];
     for ( uint8_t i=0; i < 8; i++ ) {
       if (crc & 0x80) {
          crc = (crc << 1) ^ 0x31;
       } else {
          crc = (crc << 1);
       }
     }
  }
  return crc;
}

bool aht2x_read_sensor( float *humidity, float *temperature ) {
  Wire.beginTransmission( AHT2X_ADDR );
  Wire.write( AHT2X_MEASURE_CMD, 3 );
  Wire.endTransmission();
  // After the host sends a trigger-measurement command (0xAC),
  // a delay of 80+ msec is necessary before reading the data.
  delay(100);
  Wire.requestFrom( AHT2X_ADDR, 7 );
  if ( Wire.available() >= 7 ) { // expect 7 bytes from the sensor
     uint8_t buf[7] = {0};
     for( int i=0; i < 7; i++ ) {
        buf[i] = Wire.read();
     } 
     uint8_t crc8 = buf[6];
     if ( buf[0] & 0x80 ) {
        Serial.println( "AHT2x is busy!" );
        return false; // failed
     }
     if ( aht2x_crc8( buf, 6 ) != crc8 ) {
        Serial.println( "CRC8 check failed!" );
        *humidity = 0.0;
        *temperature = 0.0;
        return false; // failed
     } else {
        uint32_t value;
        // 20-bit raw value for humidity
        value = buf[1];
        value = (value << 8) | buf[2];
        value = (value << 8) | buf[3];
        value >>= 4;
        *humidity = (100.0*value)/(1UL<<20);
        // 20-bit raw value for temperature
        value = (buf[3] & 0x0F);
        value = (value << 8) | buf[4];
        value = (value << 8) | buf[5];
        *temperature = ((200.0*value)/(1UL<<20)) - 50;
        return true; // ok
     }
  }
  return false;
}

void setup() {
  Serial.begin(115200);
  // show the compile date and time of the sketch.
  Serial.println( "\n\nCompiled on " __DATE__ ", at " __TIME__ );
#if defined(ESP32)
  Serial.println( "Set I2C pins for ESP32" );
  Wire.begin( I2C_SDA_PIN, I2C_SCL_PIN );
#else
  Wire.begin();
#endif
  Wire.setClock( 400000 ); // Set I2C speed to 400kHz.
  aht2x_init(); // Initialize the AHT2x.
  delay(500);
}

void loop() {
  float t, rh;
  if ( aht2x_read_sensor( &rh, &t ) ) {
#if defined(__AVR__)
     Serial.print( "H: " );
     Serial.print( rh, 1 ); // only 1 digit after the decimal point
     Serial.print( " %RH, T: " );
     Serial.print(  t, 1 ); // only 1 digit after the decimal point
     Serial.println( " deg.C" );
#endif
#if defined(ESP32)
     Serial.printf( "H: %.1f %%RH, T: %.1f deg.C\n", rh, t );
#endif
  } 
  delay(5000); 
}

รูป: การต่อวงจรทดลองร่วมกับบอร์ด Arduino Nano (ใช้แรงดันไฟเลี้ยง +5V สำหรับโมดูล AHT21)

รูป: การต่อวงจรทดลองร่วมกับบอร์ด ESP32 (ใช้แรงดันไฟเลี้ยง +3.3V สำหรับโมดูล AHT21)

รูป: ตัวอย่างข้อความเอาต์พุตที่แสดงผลใน Arduino Serial Monitor

 


ตัวอย่างโค้ดสำหรับ Arduino ESP32#

ตัวอย่างถัดไปสาธิตการสร้างคลาสชื่อ AHT2x ในภาษา C++ และเก็บไว้ในไฟล์ aht2x.h เพื่อให้ง่ายต่อการนำมาใช้งานโมดูล AHT2x

// File: aht2x.h
#pragma once
#include <Arduino.h>
#include <Wire.h>

class AHT2x {

private:
   uint8_t addr;
   static const uint8_t AHT2X_CALIB_CMD[3];
   static const uint8_t AHT2X_MEASURE_CMD[3];

public:
   static const uint8_t AHT2X_DEF_ADDR = 0x38; // 0x38 or 0x39

  AHT2x(uint8_t _addr = AHT2x::AHT2X_DEF_ADDR) 
   : addr(_addr) {
     // empty
  }

  void init() {
    Wire.beginTransmission( addr );
    Wire.write( AHT2x::AHT2X_CALIB_CMD, 3 );
    Wire.endTransmission();
  }

  static uint8_t crc8( uint8_t *data, int len ) {
    // calculate CRC8 (Dallas/Maxim)
    // The initial value of CRC is 0xFF.
    // The CRC polynomial: X^8 + X^5 + X^4 + 1 => 0b00110001 (0x31)
    uint8_t crc = 0xff;
    for ( uint8_t j=0; j < len; j++ ) {
       crc ^= data[j];
       for ( uint8_t i=0; i < 8; i++ ) {
         if (crc & 0x80) {
           crc = (crc << 1) ^ 0x31;
         } else {
           crc = crc << 1;
        }
      }
    }
    return crc;
  }

  bool read( float *humidity, float *temperature ) {
    Wire.beginTransmission( addr );
    Wire.write( AHT2x::AHT2X_MEASURE_CMD, 3 );
    Wire.endTransmission();
    // After the host sends a trigger-measurement command (0xAC),
    // a delay of 80+ msec is necessary before reading the data.
    delay(100);
    Wire.requestFrom( (int)addr, 7 );
    if ( Wire.available() >= 7 ) { // expect 7 bytes from the sensor
       uint8_t buf[7] = {0};
       for( int i=0; i < 7; i++ ) {
         buf[i] = Wire.read();
       } 
       uint8_t crc8 = buf[6];
       if ( buf[0] & 0x80 ) { // AHT2x busy
          return false; // failed
       }
       if ( AHT2x::crc8( buf, 6 ) != crc8 ) { // CRC8 failed
          *humidity = 0.0;
          *temperature = 0.0;
          return false; // failed
       } else {
          uint32_t value;
          // 20-bit raw value for humidity
          value = buf[1];
          value = (value << 8) | buf[2];
          value = (value << 8) | buf[3];
          value >>= 4;
          *humidity = (100.0*value)/(1UL<<20);
          // 20-bit raw value for temperature
          value = (buf[3] & 0x0F);
          value = (value << 8) | buf[4];
          value = (value << 8) | buf[5];
          *temperature = ((200.0*value)/(1UL<<20)) - 50;
          return true; // ok
       }
    }
    return false;
  }

};

const uint8_t AHT2x::AHT2X_CALIB_CMD[3]   = {0xBE, 0x08, 0x00};
const uint8_t AHT2x::AHT2X_MEASURE_CMD[3] = {0xAC, 0x33, 0x00};

 

ถัดไปเป็นตัวอย่างการเขียนโค้ด Arduino Sketch สำหรับ ESP32 และมีการสร้างอ็อบเจกต์จากคลาส AHT2x เพื่อใช้ในการอ่านข้อมูลจากโมดูลเซนเซอร์ AHT20 และนำไปใช้กับบอร์ดไมโครคอนโทรลเลอร์ ESP32 (WeMos Lolin32 Lite Board)

// File: esp32_aht2x_demo.ino
// Date: 2023-11-13
#include "aht2x.h"

// Select I2C Pins for ESP32.
#define I2C_SDA_PIN   (16)
#define I2C_SCL_PIN   (17)

// Set time interval (in msec) for sensor readings
#define INTERVAL_MSEC (4000)

AHT2x aht2x; // Create an object from the AHT2x class.

void setup() {
  // Initialize the serial port.
  Serial.begin(115200);
  // Show the compile date and time of the sketch.
  Serial.println( "\n\nCompiled on " __DATE__ ", at " __TIME__ );
  Serial.println( "Set I2C pins for ESP32..." );
  // Set the I2C speed and initialize the I2C bus.
  Wire.begin( I2C_SDA_PIN, I2C_SCL_PIN, 400000 );
  Serial.printf( "I2C clock frequency: %lu\n", Wire.getClock() );
  Serial.printf( "I2C timeout: %u msec\n", Wire.getTimeOut() );

  // Initialize the AHT2x sensor.
  aht2x.init();
  delay(500);
}

void loop() {
  static uint32_t ts;
  uint32_t now = millis();
  if ( now - ts >= INTERVAL_MSEC ) {    
    float t, rh;
    ts = now;
    // Read sensor values from the AHT2x.
    if ( aht2x.read( &rh, &t ) ) { // ok
      Serial.printf( "T: %.1f deg.C, H: %.1f %%RH\n", t, rh );
    } else { // error
      Serial.printf( "AHT2x reading error!\n" );
    }
  }
}

 


ตัวอย่างโค้ดสำหรับ Arduino ESP32 + SH1106 OLED#

ตัวอย่างถัดไปสาธิตการใช้งานโมดูลเซนเซอร์ AHT2x และโมดูล SH1106 OLED (Organic LED) ขนาด 1.3" (128x64 pixels) โดยเลือกใช้งานไลบรารีที่มีชื่อว่า esp8266-oled-ssd1306 ทั้งสองอุปกรณ์ใช้วิธีเชื่อมต่อแบบ I2C และมีแอดเดรสสำหรับ I2C Slave Devices ที่แตกต่างกัน

// File: esp32_aht2x_sh1106_oled_demo.ino
// Date: 2023-11-13
#include <Wire.h>
#include "aht2x.h"

#include "SH1106Wire.h" // The library must be already installed.
// see: https://github.com/ThingPulse/esp8266-oled-ssd1306/

// Select I2C Pins for ESP32.
#define I2C_SDA_PIN  (16)
#define I2C_SCL_PIN  (17)

// Set the update interval (in msec) for AHT2x sensor.
#define INTERVAL_MSEC (4000) 

#define AHT2x_I2C_ADDR  (0x38)
#define OLED_I2C_ADDR   (0x3C)

// Create an object from the AHT2x class.
AHT2x aht2x( AHT2x_I2C_ADDR );

// Create an object from the SH1106Wire class.
SH1106Wire display( OLED_I2C_ADDR, -1 /*sda*/, -1 /*scl*/, 
                    GEOMETRY_128_64, I2C_ONE /*Wire*/, -1 );

void initOLED() {
  display.init();
  display.flipScreenVertically();
  display.clear();
  display.setFont( ArialMT_Plain_16 );
  display.setTextAlignment( TEXT_ALIGN_CENTER );
  display.drawString( 64,  8, String("ESP32 Demo")  );
  display.drawString( 64, 32, String("SH1106 OLED") );
  display.display();
}

void setup() {
  // Initialize the serial port.
  Serial.begin(115200);
  // Show the compile date and time of the sketch.
  Serial.println( "\n\nCompiled on " __DATE__ ", at " __TIME__ );
  Serial.println( "Set I2C pins for ESP32..." );
  // Set the I2C speed and initialize the I2C bus.
  Wire.begin( I2C_SDA_PIN, I2C_SCL_PIN );

  // Initialize the OLED display.
  initOLED();
  // Initialize the AHT2x sensor.
  aht2x.init();
  delay(500);
}

void loop() {
  static uint32_t ts;
  uint32_t now = millis();
  if ( now - ts >= INTERVAL_MSEC ) {    
    float t, rh;
    ts = now;
    String line1 = "T: ", line2 = "H: ";
    // Read sensor values from the AHT2x.
    if ( aht2x.read( &rh, &t ) ) { // ok
      Serial.printf( "T: %.1f deg.C, H: %.1f %%RH\n", t, rh );
      line1 += t;
      line1 += " deg.C";
      line2 += rh;
      line2 += " %RH";
    } else { // error
      Serial.printf( "AHT2x reading error!\n" );
      line1 += "--.- deg.C";
      line2 += "--.- %RH";
    }
    display.clear();
    display.drawString( 64,  8, line1 );
    display.drawString( 64, 32, line2 );
    display.display();
  }
}

รูป: โมดูล OLED + SH1106 Driver ขนาด 1.3 นิ้ว (128 x 64 พิกเซล) สามารถใช้แรงดันไฟเลี้ยง 3.3V หรือ 5V ได้ (มีไอซี XC6206 3.3V LDO และมีตัวต้านทาน 4.7k แบบ Pull-up ที่ขา SCL และ SDA ไปยังไฟเลี้ยง 3.3V)

รูป: ตัวอย่างการต่อวงจรทดลองสำหรับโมดูล AHT21

รูป: ตัวอย่างการต่อวงจรทดลองสำหรับโมดูล AHT20

แต่ถ้าจะลองใช้ไลบรารี Adafruit_SH110X ของบริษัท Adafruit ก็มีตัวอย่างโค้ดดังนี้

#include <Wire.h>

#define SH110X_NO_SPLASH
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
// see: https://github.com/adafruit/Adafruit_SH110x

#include "aht2x.h"

// Select I2C Pins for ESP32
#define I2C_SDA_PIN  (16)
#define I2C_SCL_PIN  (17)

#define INTERVAL_MSEC (4000) 

#define AHT2x_I2C_ADDR (0x38)
#define OLED_I2C_ADDR  (0x3C)

#define SCREEN_WIDTH  (128)
#define SCREEN_HEIGHT  (64)

// Create an object from the Adafruit_SH1106G class.
Adafruit_SH1106G display( SCREEN_WIDTH, SCREEN_HEIGHT, 
                          &Wire, -1, 100000, 100000 );

// Create an object from the AHT2x class.
AHT2x aht2x( AHT2x_I2C_ADDR );

void showCenteredText( int ypos, const String &text ) {
  int16_t x, y;
  uint16_t text_h, text_w;
  display.getTextBounds(text, 0, 0, &x, &y, &text_w, &text_h);
  int xpos = (SCREEN_WIDTH  - text_w) / 2;
  display.setCursor(xpos, ypos);
  display.println(text);
}

void initOLED() {
 if( !display.begin(OLED_I2C_ADDR, false) ) {
    Serial.println( "OLED init failed!" );
    for(;;) delay(10);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor( SH110X_WHITE );
  showCenteredText( 16, String("ESP32 Demo") );
  showCenteredText( 32, String("SH1106 OLED") );
  display.display();
  delay(2000);
}

void setup() {
  // Initialize the serial port.
  Serial.begin(115200);
  // Show the compile date and time of the sketch.
  Serial.println( "\n\nCompiled on " __DATE__ ", at " __TIME__ );
  Serial.println( "Set I2C pins for ESP32..." );
  // Set the I2C speed and initialize the I2C bus.
  Wire.begin( I2C_SDA_PIN, I2C_SCL_PIN );
  //Wire.setClock( 400000 );

  // Initialize the OLED display.
  initOLED();
  // Initialize the AHT2x sensor.
  aht2x.init();
  delay(500);
}

void loop() {
  static uint32_t ts;
  uint32_t now = millis();
  if ( now - ts >= INTERVAL_MSEC ) {    
    float t, rh;
    ts = now;
    String line1 = "T: ", line2 = "H: ";
    // Read sensor values from the AHT2x.
    if ( aht2x.read( &rh, &t ) ) { // ok 
      Serial.printf( "T: %.1f deg.C, H: %.1f %%RH\n", t, rh );
      line1 += t;
      line1 += " deg.C";
      line2 += rh;
      line2 += " %RH";
    } else { // error
      Serial.printf( "AHT2x reading error!\n" );
      line1 += "--.- deg.C";
      line2 += "--.- %RH";
    }
    display.clearDisplay();
    showCenteredText( 16, line1 );
    showCenteredText( 32, line2 );
    display.display();
  }
}

รูป: ตัวอย่างการต่อวงจรทดลองโดยเลือกใช้ไลบรารี Adafruit_SH110X

 


กล่าวสรุป#

บทความนี้ได้นำเสนอการใช้งานโมดูลที่มีไอซี AHT2x ซึ่งเป็นเซนเซอร์สำหรับการวัดค่าความชื้นสัมพัทธ์ และอุณหภูมิ โดยนำมาทดลองใช้งานร่วมกับบอร์ดไมโครคอนโทรลเลอร์ ESP32 และ Arduino Nano และเขียนโปรแกรมด้วย Arduino IDE

 


This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Created: 2022-08-21 | Last Updated: 2023-11-13