123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- #include "AHTxx.h"
- /* Defines */
- #define AHT_I2C_ADDR (uint8_t)0x38
- #define CMD_GET_STATUS (uint8_t)0x71
- #define CMD_INIT (uint8_t)0xbe
- #define CMD_MEASURE (uint8_t)0xac
- #define CMD_MEASURE_CTL (uint8_t)0x33
- #define CMD_MEASURE_NOP (uint8_t)0x00
- #define CMD_SRESET (uint8_t)0xba
- #define CMD_CALIBR1 (uint8_t)0x1b
- #define CMD_CALIBR2 (uint8_t)0x1c
- #define CMD_CALIBR3 (uint8_t)0x1e
- #define STATUS_BUSY (uint8_t)0x80
- #define STATUS_CMD (uint8_t)0x40
- #define STATUS_CYC (uint8_t)0x20
- #define STATUS_CAL (uint8_t)0x08
- #define STATUS_CALB (uint8_t)0x18
- /* Private variables */
- static ahtxx_t Data;
- static Timer startTimer, getTimer;
- /* Private functions prototypes */
- static ahtxx_st_t I2CWriteTo(uint8_t DataToSend);
- //static uint8_t Calc_CRC8(uint8_t *message, uint8_t Num);
- static ahtxx_st_t JH_Reset_REG(uint8_t addr);
- void _Init(void);
- void _GetData(void);
- void _StartMeasure(void);
- /**
- * Initialization
- */
- void AHTxx_Init(void) {
- // Just powered on, it takes time for the product chip to be ready internally,
- // the delay is 100~500ms, and 500ms is recommended
- auto timer = new AutoDeleteTimer;
- timer->initializeMs<500>(_Init);
- timer->startOnce();
- }
- void _Init(void) {
- ahtxx_st_t res;
- uint8_t data;
- // When power on, send 0x71 to read the status word for the first time,
- // and judge whether the status word is 0x18.
- Wire.beginTransmission(AHT_I2C_ADDR);
- Wire.write(CMD_GET_STATUS);
- res = (ahtxx_st_t)Wire.endTransmission();
- if (res != St_OK) {
- Data.Error = St_NoSensor;
- return;
- }
- Wire.requestFrom(AHT_I2C_ADDR, 1);
- data = Wire.read();
- if ((data & STATUS_CALB) != STATUS_CALB) {
- //reinitialize registers
- res = JH_Reset_REG(0x1b);
- if (res != St_OK) {
- Data.Error = res;
- return;
- }
- res = JH_Reset_REG(0x1c);
- if (res != St_OK) {
- Data.Error = res;
- return;
- }
- res = JH_Reset_REG(0x1e);
- if (res != St_OK) {
- Data.Error = res;
- return;
- }
- delay(1);
- }
- Data.Error = St_OK;
- // start polling sensors - once per two seconds
- startTimer.initializeMs(2000, _StartMeasure).start();
- }
- void AHTxx_SoftReset(void) {
- ahtxx_st_t res;
- Data.Error = St_OK;
- res = I2CWriteTo(CMD_SRESET);
- if (res != St_OK) {
- Data.Error = res;
- return;
- }
- startTimer.restart();
- }
- /**
- * @brief Start Sensor measure.
- */
- void _StartMeasure(void) {
- ahtxx_st_t res;
- Data.Error = St_OK;
- Wire.beginTransmission(AHT_I2C_ADDR);
- Wire.write(CMD_MEASURE);
- Wire.write(CMD_MEASURE_CTL);
- Wire.write(CMD_MEASURE_NOP);
- res = (ahtxx_st_t)Wire.endTransmission();
- if (res != St_OK) {
- Data.Error = res;
- return;
- }
- getTimer.initializeMs(600, _GetData).startOnce();
- }
- void AHTxx_GetData(ahtxx_t * data) {
- data->Error = Data.Error;
- data->Humidity = Data.Humidity;
- data->Temperature = Data.Temperature;
- }
- void _GetData(void) {
- ahtxx_st_t res;
- uint8_t buf[8] = {0}, i = 0;
- Data.Error = St_OK;
- /* Now read 7 bytes of data */
- Wire.requestFrom(AHT_I2C_ADDR, 7);
- while (Wire.available()) {
- buf[i] = Wire.read();
- i ++;
- }
- if (i < 7) {
- Data.Error = St_NACK_Data;
- return;
- }
- if ((buf[0] & STATUS_BUSY) != 0) {
- Data.Error = St_Timeout;
- return;
- }
- /* Calculate values */
- uint32_t result;
- /* Humidity = Srh * 100% / 2^20 */
- result = buf[1];
- result <<= 8;
- result |= buf[2];
- result <<= 8;
- result |= buf[3];
- result >>= 4;
- result *= 1000;
- result += 524288;
- result /= 256;
- result /= 256;
- result /= 16;
- Data.Humidity = (uint16_t)result; // in xx.x %
- /* Temperature = St * 200 / 2^20 - 50 */
- result = buf[3] & 0xf;
- result <<= 8;
- result |= buf[4];
- result <<= 8;
- result |= buf[5];
- result *= 2000;
- result += 524288;
- result /= 256;
- result /= 256;
- result /= 16;
- Data.Temperature = (int16_t)(result - 500); // in xx.x *C
- }
- /* Reset register */
- static ahtxx_st_t JH_Reset_REG(uint8_t addr) {
- ahtxx_st_t res;
- uint8_t Byte_first, Byte_second, Byte_third;
- Wire.beginTransmission(AHT_I2C_ADDR);
- Wire.write((uint8_t)0x70);
- Wire.write(addr);
- Wire.write((uint8_t)0x00);
- Wire.write((uint8_t)0x00);
- res = (ahtxx_st_t)Wire.endTransmission();
- if (res != St_OK) {
- return res;
- }
- delay(5); //Delay about 5ms
- Wire.beginTransmission(AHT_I2C_ADDR);
- Wire.write((uint8_t)0x71);
- res = (ahtxx_st_t)Wire.endTransmission();
- if (res != St_OK) {
- return res;
- }
- Wire.requestFrom(AHT_I2C_ADDR, 3);
- Byte_first = Wire.read();
- Byte_second = Wire.read();
- Byte_third = Wire.read();
- delay(10); //Delay about 10ms
- Wire.beginTransmission(AHT_I2C_ADDR);
- Wire.write((uint8_t)0x70);
- Wire.write((uint8_t)(0xB0|addr)); //register command
- Wire.write(Byte_second);
- Wire.write(Byte_third);
- res = (ahtxx_st_t)Wire.endTransmission();
- if (res != St_OK) {
- return res;
- }
- return St_OK;
- }
- static ahtxx_st_t I2CWriteTo(uint8_t DataToSend) {
- Wire.beginTransmission(AHT_I2C_ADDR);
- Wire.write(DataToSend);
- return (ahtxx_st_t)Wire.endTransmission();
- }
- /**
- * CRC check type: CRC8/MAXIM
- * Polynomial: X8+X5+X4+1
- * Poly: 0011 0001 0x31
- * When the high bit is placed in the back, it becomes 1000 1100 0x8c
- */
- /*
- static uint8_t Calc_CRC8(uint8_t *message, uint8_t Num)
- {
- uint8_t i;
- uint8_t byte;
- uint8_t crc = 0xFF;
- for (byte=0; byte<Num; byte++) {
- crc ^= (message[byte]);
- for (i=8; i>0; --i) {
- if (crc & 0x80) {
- crc = (crc << 1) ^ 0x31;
- } else {
- crc = (crc << 1);
- }
- }
- }
- return crc;
- }
- */
|