AHTxx.cpp 5.4 KB

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