AHTxx.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #include "AHTxx.h"
  2. /* Defines */
  3. #define AHT_I2C_ADDR (uint8_t)0x38
  4. #define CMD_GET_STATUS (uint8_t)0x71
  5. #define CMD_INIT (uint8_t)0xbe
  6. #define CMD_MEASURE (uint8_t)0xac
  7. #define CMD_MEASURE_CTL (uint8_t)0x33
  8. #define CMD_MEASURE_NOP (uint8_t)0x00
  9. #define CMD_SRESET (uint8_t)0xba
  10. #define CMD_CALIBR1 (uint8_t)0x1b
  11. #define CMD_CALIBR2 (uint8_t)0x1c
  12. #define CMD_CALIBR3 (uint8_t)0x1e
  13. #define STATUS_BUSY (uint8_t)0x80
  14. #define STATUS_CMD (uint8_t)0x40
  15. #define STATUS_CYC (uint8_t)0x20
  16. #define STATUS_CAL (uint8_t)0x08
  17. #define STATUS_CALB (uint8_t)0x18
  18. /* Functions prototypes */
  19. /*
  20. uint8_t Calc_CRC8(uint8_t *message, uint8_t Num);
  21. ahtxx_st_t JH_Reset_REG(uint8_t addr);
  22. */
  23. static bool ReadyToRequest;
  24. static ahtxx_t Data;
  25. /**
  26. * Initialization
  27. */
  28. AHTxx::AHTxx(void)
  29. {
  30. // Just powered on, it takes time for the product chip to be ready internally,
  31. // the delay is 100~500ms, and 500ms is recommended
  32. auto timer = new AutoDeleteTimer;
  33. timer->initializeMs<500>(Init);
  34. timer->startOnce();
  35. ReadyToRequest = false;
  36. }
  37. void AHTxx::Init(void) {
  38. ahtxx_st_t res;
  39. uint8_t data;
  40. // When power on, send 0x71 to read the status word for the first time,
  41. // and judge whether the status word is 0x18.
  42. Wire.beginTransmission(AHT_I2C_ADDR);
  43. Wire.write(CMD_GET_STATUS);
  44. res = (ahtxx_st_t)Wire.endTransmission();
  45. if (res != St_OK) {
  46. Data.Error = res;
  47. return;
  48. }
  49. Wire.requestFrom(AHT_I2C_ADDR, 1);
  50. data = Wire.read();
  51. if ((data & STATUS_CALB) != STATUS_CALB) {
  52. //reinitialize registers
  53. res = JH_Reset_REG(0x1b);
  54. if (res != St_OK) {
  55. Data.Error = res;
  56. return;
  57. }
  58. res = JH_Reset_REG(0x1c);
  59. if (res != St_OK) {
  60. Data.Error = res;
  61. return;
  62. }
  63. res = JH_Reset_REG(0x1e);
  64. if (res != St_OK) {
  65. Data.Error = res;
  66. return;
  67. }
  68. delay(1);
  69. }
  70. Data.Error = St_OK;
  71. ReadyToRequest = true;
  72. }
  73. void AHTxx::SoftReset(void) {
  74. ahtxx_st_t res;
  75. Data.Error = St_OK;
  76. res = I2CWriteTo(CMD_SRESET);
  77. if (res != St_OK) {
  78. Data.Error = res;
  79. return;
  80. }
  81. }
  82. void AHTxx::StartMeasure(void) {
  83. if (ReadyToRequest == false) {
  84. return;
  85. }
  86. ahtxx_st_t res;
  87. Data.Error = St_OK;
  88. Wire.beginTransmission(AHT_I2C_ADDR);
  89. Wire.write(CMD_MEASURE);
  90. Wire.write(CMD_MEASURE_CTL);
  91. Wire.write(CMD_MEASURE_NOP);
  92. res = (ahtxx_st_t)Wire.endTransmission();
  93. if (res != St_OK) {
  94. Data.Error = res;
  95. return;
  96. }
  97. }
  98. void AHTxx::GetData(ahtxx_t * data) {
  99. if (ReadyToRequest == false) {
  100. return;
  101. }
  102. ahtxx_st_t res;
  103. uint8_t buf[8] = {0}, i = 0;
  104. Data.Error = St_OK;
  105. /* Now read 7 bytes of data */
  106. Wire.requestFrom(AHT_I2C_ADDR, 7);
  107. while (Wire.available()) {
  108. buf[i] = Wire.read();
  109. i ++;
  110. }
  111. if (i < 7) {
  112. Data.Error = St_NACK_Data;
  113. data->Error = Data.Error;
  114. return;
  115. }
  116. if ((buf[0] & STATUS_BUSY) != 0) {
  117. Data.Error = St_Timeout;
  118. data->Error = Data.Error;
  119. return;
  120. }
  121. /* Calculate values */
  122. uint32_t result;
  123. /* Humidity = Srh * 100% / 2^20 */
  124. result = buf[1];
  125. result <<= 8;
  126. result |= buf[2];
  127. result <<= 8;
  128. result |= buf[3];
  129. result >>= 4;
  130. result *= 1000;
  131. result += 524288;
  132. result /= 256;
  133. result /= 256;
  134. result /= 16;
  135. Data.Humidity = (uint16_t)result; // in xx.x %
  136. /* Temperature = St * 200 / 2^20 - 50 */
  137. result = buf[3] & 0xf;
  138. result <<= 8;
  139. result |= buf[4];
  140. result <<= 8;
  141. result |= buf[5];
  142. result *= 2000;
  143. result += 524288;
  144. result /= 256;
  145. result /= 256;
  146. result /= 16;
  147. Data.Temperature = (int16_t)(result - 500); // in xx.x *C
  148. data->Error = Data.Error;
  149. data->Humidity = Data.Humidity;
  150. data->Temperature = Data.Temperature;
  151. }
  152. /**
  153. * CRC check type: CRC8/MAXIM
  154. * Polynomial: X8+X5+X4+1
  155. * Poly: 0011 0001 0x31
  156. * When the high bit is placed in the back, it becomes 1000 1100 0x8c
  157. */
  158. uint8_t AHTxx::Calc_CRC8(uint8_t *message, uint8_t Num)
  159. {
  160. uint8_t i;
  161. uint8_t byte;
  162. uint8_t crc = 0xFF;
  163. for (byte=0; byte<Num; byte++) {
  164. crc ^= (message[byte]);
  165. for (i=8; i>0; --i) {
  166. if (crc & 0x80) {
  167. crc = (crc << 1) ^ 0x31;
  168. } else {
  169. crc = (crc << 1);
  170. }
  171. }
  172. }
  173. return crc;
  174. }
  175. /* Reset register */
  176. ahtxx_st_t AHTxx::JH_Reset_REG(uint8_t addr) {
  177. ahtxx_st_t res;
  178. uint8_t Byte_first, Byte_second, Byte_third;
  179. Wire.beginTransmission(AHT_I2C_ADDR);
  180. Wire.write((uint8_t)0x70);
  181. Wire.write(addr);
  182. Wire.write((uint8_t)0x00);
  183. Wire.write((uint8_t)0x00);
  184. res = (ahtxx_st_t)Wire.endTransmission();
  185. if (res != St_OK) {
  186. return res;
  187. }
  188. delay(5); //Delay about 5ms
  189. Wire.beginTransmission(AHT_I2C_ADDR);
  190. Wire.write((uint8_t)0x71);
  191. res = (ahtxx_st_t)Wire.endTransmission();
  192. if (res != St_OK) {
  193. return res;
  194. }
  195. Wire.requestFrom(AHT_I2C_ADDR, 3);
  196. Byte_first = Wire.read();
  197. Byte_second = Wire.read();
  198. Byte_third = Wire.read();
  199. delay(10); //Delay about 10ms
  200. Wire.beginTransmission(AHT_I2C_ADDR);
  201. Wire.write((uint8_t)0x70);
  202. Wire.write((uint8_t)(0xB0|addr)); //register command
  203. Wire.write(Byte_second);
  204. Wire.write(Byte_third);
  205. res = (ahtxx_st_t)Wire.endTransmission();
  206. if (res != St_OK) {
  207. return res;
  208. }
  209. return St_OK;
  210. }
  211. ahtxx_st_t AHTxx::I2CWriteTo(uint8_t DataToSend) {
  212. Wire.beginTransmission(AHT_I2C_ADDR);
  213. Wire.write(DataToSend);
  214. return (ahtxx_st_t)Wire.endTransmission();
  215. }
  216. bool AHTxx::IsReadyToRequest(void) {
  217. return ReadyToRequest;
  218. }