AHTxx.cpp 5.4 KB

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