luat_lib_sensor.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. @module sensor
  3. @summary 传感器操作库
  4. @version 1.0
  5. @data 2020.03.30
  6. */
  7. #include "luat_base.h"
  8. #include "luat_log.h"
  9. #include "luat_timer.h"
  10. #include "luat_malloc.h"
  11. #include "rtthread.h"
  12. #include "rthw.h"
  13. #include <rtdevice.h>
  14. #include "luat_gpio.h"
  15. #define CONNECT_SUCCESS 0
  16. #define CONNECT_FAILED 1
  17. #define W1_INPUT_MODE PIN_MODE_INPUT_PULLUP
  18. RT_WEAK void luat_timer_us_delay(size_t us) {
  19. rt_hw_us_delay(us);
  20. }
  21. static void w1_reset(int pin)
  22. {
  23. luat_gpio_mode(pin, Luat_GPIO_OUTPUT);
  24. luat_gpio_set(pin, Luat_GPIO_LOW);
  25. luat_timer_us_delay(550); /* 480us - 960us */
  26. luat_gpio_set(pin, Luat_GPIO_HIGH);
  27. luat_timer_us_delay(40); /* 15us - 60us*/
  28. }
  29. static uint8_t w1_connect(int pin)
  30. {
  31. uint8_t retry = 0;
  32. luat_gpio_mode(pin, W1_INPUT_MODE);
  33. while (luat_gpio_get(pin) && retry < 200)
  34. {
  35. retry++;
  36. luat_timer_us_delay(1);
  37. };
  38. if(retry >= 200)
  39. return CONNECT_FAILED;
  40. else
  41. retry = 0;
  42. while (!luat_gpio_get(pin) && retry < 240)
  43. {
  44. retry++;
  45. luat_timer_us_delay(1);
  46. };
  47. if(retry >= 240)
  48. return CONNECT_FAILED;
  49. return CONNECT_SUCCESS;
  50. }
  51. static uint8_t w1_read_bit(int pin)
  52. {
  53. uint8_t data;
  54. luat_gpio_mode(pin, Luat_GPIO_OUTPUT);
  55. luat_gpio_set(pin, Luat_GPIO_LOW);
  56. luat_timer_us_delay(2);
  57. luat_gpio_set(pin, Luat_GPIO_HIGH);
  58. luat_gpio_mode(pin, W1_INPUT_MODE);
  59. luat_timer_us_delay(5);
  60. if(luat_gpio_get(pin))
  61. data = 1;
  62. else
  63. data = 0;
  64. luat_timer_us_delay(50);
  65. return data;
  66. }
  67. static uint8_t w1_read_byte(int pin)
  68. {
  69. uint8_t i, j, dat;
  70. dat = 0;
  71. //rt_base_t level;
  72. //level = rt_hw_interrupt_disable();
  73. for (i = 1; i <= 8; i++)
  74. {
  75. j = w1_read_bit(pin);
  76. dat = (j << 7) | (dat >> 1);
  77. }
  78. //rt_hw_interrupt_enable(level);
  79. return dat;
  80. }
  81. static void w1_write_byte(int pin, uint8_t dat)
  82. {
  83. uint8_t j;
  84. uint8_t testb;
  85. luat_gpio_mode(pin, Luat_GPIO_OUTPUT);
  86. for (j = 1; j <= 8; j++)
  87. {
  88. testb = dat & 0x01;
  89. dat = dat >> 1;
  90. if(testb)
  91. {
  92. luat_gpio_set(pin, Luat_GPIO_LOW);
  93. luat_timer_us_delay(2);
  94. luat_gpio_set(pin, Luat_GPIO_HIGH);
  95. luat_timer_us_delay(60);
  96. }
  97. else
  98. {
  99. luat_gpio_set(pin, Luat_GPIO_LOW);
  100. luat_timer_us_delay(60);
  101. luat_gpio_set(pin, Luat_GPIO_HIGH);
  102. luat_timer_us_delay(2);
  103. }
  104. }
  105. }
  106. static int32_t ds18b20_get_temperature(int pin)
  107. {
  108. uint8_t TL, TH;
  109. int32_t tem;
  110. //ds18b20_start(pin);
  111. w1_reset(pin);
  112. w1_connect(pin);
  113. w1_write_byte(pin, 0xcc); /* skip rom */
  114. w1_write_byte(pin, 0x44); /* convert */
  115. //ds18b20_init(pin);
  116. w1_reset(pin);
  117. w1_connect(pin);
  118. w1_write_byte(pin, 0xcc);
  119. w1_write_byte(pin, 0xbe);
  120. TL = w1_read_byte(pin); /* LSB first */
  121. TH = w1_read_byte(pin);
  122. if (TH > 7)
  123. {
  124. TH =~ TH;
  125. TL =~ TL;
  126. tem = TH;
  127. tem <<= 8;
  128. tem += TL;
  129. tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
  130. return -tem;
  131. }
  132. else
  133. {
  134. tem = TH;
  135. tem <<= 8;
  136. tem += TL;
  137. tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
  138. return tem;
  139. }
  140. }
  141. /*
  142. 获取DS18B20的温度数据
  143. @function sensor.ds18b20(pin)
  144. @int gpio端口号
  145. @return int 温度数据
  146. -- 如果读取失败,会返回nil
  147. while 1 do sys.wait(5000) log.info("ds18b20", sensor.ds18b20(14)) end
  148. */
  149. static int l_sensor_ds18b20(lua_State *L) {
  150. int32_t temp = ds18b20_get_temperature(luaL_checkinteger(L, 1));
  151. // -55°C ~ 125°C
  152. if (temp > 1250 || temp < -550) {
  153. return 0;
  154. }
  155. //rt_kprintf("temp:%3d.%dC\n", temp/10, temp%10);
  156. lua_pushinteger(L, temp);
  157. return 1;
  158. }
  159. #include "rotable.h"
  160. static const rotable_Reg reg_sensor[] =
  161. {
  162. { "ds18b20" , l_sensor_ds18b20 , 0},
  163. { NULL, NULL , 0}
  164. };
  165. LUAMOD_API int luaopen_sensor( lua_State *L ) {
  166. rotable_newlib(L, reg_sensor);
  167. return 1;
  168. }