luat_lib_sensor.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. /*
  2. @module sensor
  3. @summary 传感器操作库
  4. @version 1.0
  5. @date 2020.03.30
  6. @tag LUAT_USE_SENSOR
  7. */
  8. #include "luat_base.h"
  9. #include "luat_timer.h"
  10. #include "luat_malloc.h"
  11. #include "luat_gpio.h"
  12. #include "luat_zbuff.h"
  13. #define LUAT_LOG_TAG "sensor"
  14. #include "luat_log.h"
  15. #define CONNECT_SUCCESS 0
  16. #define CONNECT_FAILED 1
  17. unsigned int temp;
  18. static void w1_reset(int pin)
  19. {
  20. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
  21. luat_gpio_set(pin, Luat_GPIO_LOW);
  22. luat_timer_us_delay(550); /* 480us - 960us */
  23. luat_gpio_set(pin, Luat_GPIO_HIGH);
  24. luat_timer_us_delay(40); /* 15us - 60us*/
  25. }
  26. static uint8_t w1_connect(int pin)
  27. {
  28. uint8_t retry = 0;
  29. luat_gpio_mode(pin, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 0);
  30. while (luat_gpio_get(pin) && retry < 200)
  31. {
  32. retry++;
  33. luat_timer_us_delay(1);
  34. };
  35. if (retry >= 200)
  36. return CONNECT_FAILED;
  37. else
  38. retry = 0;
  39. while (!luat_gpio_get(pin) && retry < 240)
  40. {
  41. retry++;
  42. luat_timer_us_delay(1);
  43. };
  44. if (retry >= 240)
  45. return CONNECT_FAILED;
  46. return CONNECT_SUCCESS;
  47. }
  48. static uint8_t w1_read_bit(int pin)
  49. {
  50. uint8_t data;
  51. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 0);
  52. luat_gpio_set(pin, Luat_GPIO_LOW);
  53. luat_timer_us_delay(2);
  54. luat_gpio_set(pin, Luat_GPIO_HIGH);
  55. luat_gpio_mode(pin, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 0);
  56. luat_timer_us_delay(5);
  57. if (luat_gpio_get(pin))
  58. data = 1;
  59. else
  60. data = 0;
  61. luat_timer_us_delay(50);
  62. return data;
  63. }
  64. static uint8_t w1_read_byte(int pin)
  65. {
  66. uint8_t i, j, dat;
  67. dat = 0;
  68. //rt_base_t level;
  69. //level = rt_hw_interrupt_disable();
  70. for (i = 1; i <= 8; i++)
  71. {
  72. j = w1_read_bit(pin);
  73. dat = (j << 7) | (dat >> 1);
  74. }
  75. //rt_hw_interrupt_enable(level);
  76. return dat;
  77. }
  78. static void w1_write_byte(int pin, uint8_t dat)
  79. {
  80. uint8_t j;
  81. uint8_t testb;
  82. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
  83. for (j = 1; j <= 8; j++)
  84. {
  85. testb = dat & 0x01;
  86. dat = dat >> 1;
  87. if (testb)
  88. {
  89. luat_gpio_set(pin, Luat_GPIO_LOW);
  90. luat_timer_us_delay(2);
  91. luat_gpio_set(pin, Luat_GPIO_HIGH);
  92. luat_timer_us_delay(60);
  93. }
  94. else
  95. {
  96. luat_gpio_set(pin, Luat_GPIO_LOW);
  97. luat_timer_us_delay(60);
  98. luat_gpio_set(pin, Luat_GPIO_HIGH);
  99. luat_timer_us_delay(2);
  100. }
  101. }
  102. }
  103. static uint8_t crc8_maxim[256] = {
  104. 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
  105. 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
  106. 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
  107. 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
  108. 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
  109. 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
  110. 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
  111. 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
  112. 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
  113. 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
  114. 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
  115. 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
  116. 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
  117. 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
  118. 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
  119. 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
  120. static int32_t ds18b20_get_temperature(int pin, int32_t *val, int check_crc)
  121. {
  122. uint8_t TL, TH;
  123. int32_t tem;
  124. uint8_t data[9] = {0};
  125. //ds18b20_start(pin);
  126. w1_reset(pin);
  127. if (w1_connect(pin))
  128. {
  129. //LLOGD("ds18b20 connect fail");
  130. return -1;
  131. }
  132. w1_write_byte(pin, 0xcc); /* skip rom */
  133. w1_write_byte(pin, 0x44); /* convert */
  134. //ds18b20_init(pin);
  135. w1_reset(pin);
  136. if (w1_connect(pin))
  137. {
  138. //LLOGD("ds18b20 connect fail");
  139. return -2;
  140. }
  141. w1_write_byte(pin, 0xcc);
  142. w1_write_byte(pin, 0xbe);
  143. data[0] = w1_read_byte(pin); /* LSB first */
  144. data[1] = w1_read_byte(pin);
  145. // if (data[0] == 0xFF || data[1] == 0xFF)
  146. // {
  147. // //LLOGD("ds18b20 bad data, skip");
  148. // return -3;
  149. // }
  150. // 9个字节都读出来,校验CRC
  151. if (check_crc)
  152. {
  153. for (size_t i = 2; i < 9; i++)
  154. {
  155. data[i] = w1_read_byte(pin);
  156. }
  157. uint8_t crc = 0;
  158. for (size_t i = 0; i < 8; i++)
  159. {
  160. crc = crc8_maxim[crc ^ data[i]];
  161. }
  162. // LLOGD("ds18b20 %02X%02X%02X%02X%02X%02X%02X%02X [%02X %02X]",
  163. // data[0], data[1], data[2], data[3],
  164. // data[4], data[5], data[6], data[7],
  165. // data[8], crc);
  166. if (data[8] != crc)
  167. {
  168. //LLOGD("ds18b20 bad crc");
  169. return -4;
  170. }
  171. }
  172. TL = data[0];
  173. TH = data[1];
  174. if (TH > 7)
  175. {
  176. TH = ~TH;
  177. TL = ~TL;
  178. tem = TH;
  179. tem <<= 8;
  180. tem += TL;
  181. tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
  182. *val = -tem;
  183. return 0;
  184. }
  185. else
  186. {
  187. tem = TH;
  188. tem <<= 8;
  189. tem += TL;
  190. tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
  191. *val = tem;
  192. return 0;
  193. }
  194. }
  195. /*
  196. 获取DS18B20的温度数据
  197. @api sensor.ds18b20(pin)
  198. @int gpio端口号
  199. @boolean 是否校验crc值,默认为true. 不校验crc值能提高读取成功的概率,但可能会读取到错误的值
  200. @return int 温度数据,单位0.1摄氏度,读取失败时返回错误码
  201. @return boolean 成功返回true,否则返回false
  202. @usage
  203. while 1 do
  204. sys.wait(5000)
  205. local val,result = sensor.ds18b20(17, true) -- GPIO17且校验CRC值
  206. -- val 301 == 30.1摄氏度
  207. -- result true 读取成功
  208. log.info("ds18b20", val, result)
  209. end
  210. */
  211. static int l_sensor_ds18b20(lua_State *L)
  212. {
  213. int32_t val = 0;
  214. int check_crc = lua_gettop(L) > 1 ? lua_toboolean(L, 2) : 1;
  215. int pin = luaL_checkinteger(L, 1);
  216. luat_os_entry_cri();
  217. int32_t ret = ds18b20_get_temperature(pin, &val, check_crc);
  218. luat_os_exit_cri();
  219. // -55°C ~ 125°C
  220. if (ret || !(val <= 1250 && val >= -550))
  221. {
  222. LLOGI("ds18b20 read fail");
  223. lua_pushinteger(L, ret);
  224. lua_pushboolean(L, 0);
  225. return 2;
  226. }
  227. //rt_kprintf("temp:%3d.%dC\n", temp/10, temp%10);
  228. lua_pushinteger(L, val);
  229. lua_pushboolean(L, 1);
  230. return 2;
  231. }
  232. //-------------------------------------
  233. // W1 单总线协议, 暴露w1_xxx方法
  234. //-------------------------------------
  235. /*
  236. 单总线协议,复位设备
  237. @api sensor.w1_reset(pin)
  238. @int gpio端口号
  239. @return nil 无返回
  240. */
  241. static int l_w1_reset(lua_State *L)
  242. {
  243. w1_reset((int)luaL_checkinteger(L, 1));
  244. return 0;
  245. }
  246. /*
  247. 单总线协议,连接设备
  248. @api sensor.w1_connect(pin)
  249. @int gpio端口号
  250. @return boolean 成功返回true,失败返回false
  251. */
  252. static int l_w1_connect(lua_State *L)
  253. {
  254. if (w1_connect((int)luaL_checkinteger(L, 1)) == CONNECT_SUCCESS)
  255. {
  256. lua_pushboolean(L, 1);
  257. }
  258. else
  259. {
  260. lua_pushboolean(L, 0);
  261. }
  262. return 1;
  263. }
  264. /*
  265. 单总线协议,往总线写入数据
  266. @api sensor.w1_write(pin, data1,data2)
  267. @int gpio端口号
  268. @int 第一个数据
  269. @int 第二个数据, 可以写N个数据
  270. @return nil 无返回值
  271. */
  272. static int l_w1_write_byte(lua_State *L)
  273. {
  274. int pin = luaL_checkinteger(L, 1);
  275. int top = lua_gettop(L);
  276. if (top > 1)
  277. {
  278. for (size_t i = 2; i <= top; i++)
  279. {
  280. uint8_t data = luaL_checkinteger(L, i);
  281. w1_write_byte(pin, data);
  282. }
  283. }
  284. return 0;
  285. }
  286. /*
  287. 单总线协议,从总线读取数据
  288. @api sensor.w1_read(pin, len)
  289. @int gpio端口号
  290. @int 读取的长度
  291. @return int 按读取的长度返回N个整数
  292. */
  293. static int l_w1_read_byte(lua_State *L)
  294. {
  295. int pin = luaL_checkinteger(L, 1);
  296. int len = luaL_checkinteger(L, 2);
  297. for (size_t i = 0; i < len; i++)
  298. {
  299. lua_pushinteger(L, w1_read_byte(pin));
  300. }
  301. return len;
  302. }
  303. unsigned long ReadCount(int date,int clk) //增益128
  304. {
  305. unsigned long count;
  306. unsigned char i;
  307. luat_gpio_mode(date, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 0);
  308. luat_gpio_set(date, Luat_GPIO_HIGH);
  309. luat_timer_us_delay(1);
  310. luat_gpio_mode(clk, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 0);
  311. luat_gpio_set(clk, Luat_GPIO_LOW);
  312. luat_gpio_mode(date, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 0);
  313. luat_timer_us_delay(1);
  314. count = 0;
  315. while (luat_gpio_get(date))
  316. ; // TODO 用tick或者us_delay统计timeout
  317. for (i = 0; i < 24; i++)
  318. {
  319. luat_gpio_set(clk, Luat_GPIO_HIGH);
  320. count = count << 1;
  321. luat_gpio_set(clk, Luat_GPIO_LOW);
  322. if (luat_gpio_get(date))
  323. count++;
  324. }
  325. luat_gpio_set(clk, Luat_GPIO_HIGH);
  326. luat_timer_us_delay(1);
  327. luat_gpio_set(clk, Luat_GPIO_LOW);
  328. return count;
  329. }
  330. /*
  331. 获取Hx711的温度数据
  332. @api sensor.hx711(pin_date,pin_clk)
  333. @int 数据的gpio端口号
  334. @int 时钟的gpio端口号
  335. @return int hx711读到的数据
  336. @usage
  337. -- 如果设备不存在会卡在读取接口
  338. sys.taskInit(
  339. function()
  340. sys.wait(1000)
  341. local maopi = sensor.hx711(0,7)
  342. while true do
  343. sys.wait(2000)
  344. a = sensor.hx711(0,7) - maopi
  345. if a > 0 then
  346. log.info("tag", a / 4.6)
  347. end
  348. end
  349. end
  350. )
  351. */
  352. static int l_sensor_hx711(lua_State *L)
  353. {
  354. // unsigned int j;
  355. unsigned long hx711_dat;
  356. int date = luaL_checkinteger(L, 1);
  357. int clk = luaL_checkinteger(L, 2);
  358. //for (j = 0; j < 5; j++)
  359. // luat_timer_us_delay(5000);
  360. hx711_dat = ReadCount(date,clk); //HX711AD转换数据处理
  361. temp = (unsigned int)(hx711_dat / 100); //缩放long数据为int型,方便处理
  362. //LLOGI("hx711:%d",temp);
  363. lua_pushinteger(L, temp);
  364. return 1;
  365. }
  366. /*
  367. 设置ws2812b输出(gpio驱动方式)
  368. @api sensor.ws2812b(pin,data,T0H,T0L,T1H,T1L)
  369. @int ws2812b的gpio端口号
  370. @string/zbuff 待发送的数据(如果为zbuff数据,则会无视指针位置始终从0偏移开始)
  371. @int T0H时间,表示延时多少个nop,每个型号不一样,自己调
  372. @int T0L时间,表示延时多少个nop
  373. @int T1H时间,表示延时多少个nop
  374. @int T1L时间,表示延时多少个nop
  375. @usage
  376. local buff = zbuff.create({8,8,24})
  377. buff:drawLine(1,2,5,6,0x00ffff)
  378. sensor.ws2812b(7,buff,300,700,700,700)
  379. */
  380. const unsigned char xor_bit_table[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  381. #define WS2812B_BIT_0() \
  382. t0h_temp = t0h; t0l_temp = t0l; \
  383. luat_gpio_pulse(pin,&pulse_level,2,t0h); \
  384. while(t0l_temp--)
  385. #define WS2812B_BIT_1() \
  386. t1h_temp = t1h; t1l_temp = t1l; \
  387. luat_gpio_pulse(pin,&pulse_level,2,t1h); \
  388. while(t1l_temp--)
  389. static int l_sensor_ws2812b(lua_State *L)
  390. {
  391. int j;
  392. size_t len,i;
  393. uint8_t pulse_level = 0x80;
  394. const char *send_buff = NULL;
  395. int pin = luaL_checkinteger(L, 1);
  396. if (lua_isuserdata(L, 2))
  397. {
  398. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  399. send_buff = (const char*)buff->addr;
  400. len = buff->len;
  401. }
  402. else
  403. {
  404. send_buff = lua_tolstring(L, 2, &len);
  405. }
  406. volatile uint32_t t0h_temp,t0h = luaL_checkinteger(L, 3);
  407. volatile uint32_t t0l_temp,t0l = luaL_checkinteger(L, 4);
  408. volatile uint32_t t1h_temp,t1h = luaL_checkinteger(L, 5);
  409. volatile uint32_t t1l_temp,t1l = luaL_checkinteger(L, 6);
  410. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
  411. pulse_level = 0 ;
  412. luat_gpio_pulse(pin,&pulse_level,2,t0h);
  413. pulse_level = 0x80;
  414. luat_os_entry_cri();
  415. for(i=0;i<len;i++)
  416. {
  417. for(j=7;j>=0;j--)
  418. {
  419. if(send_buff[i]&xor_bit_table[j])
  420. {
  421. WS2812B_BIT_1();
  422. }
  423. else
  424. {
  425. WS2812B_BIT_0();
  426. }
  427. }
  428. }
  429. luat_os_exit_cri();
  430. return 0;
  431. }
  432. #ifdef LUAT_USE_PWM
  433. #include "luat_pwm.h"
  434. static luat_pwm_conf_t ws2812b_pwm_conf = {
  435. .pnum = 1,
  436. .period = 800*1000,
  437. .precision = 100
  438. };
  439. /*
  440. 设置ws2812b输出(pwm驱动方式)
  441. @api sensor.ws2812b_pwm(pin,data)
  442. @int pwm端口号
  443. @string/zbuff 待发送的数据(如果为zbuff数据,则会无视指针位置始终从0偏移开始)
  444. @usage
  445. local buff = zbuff.create({8,8,24})
  446. buff:setFrameBuffer(8,8,24,0x0000ff)
  447. sensor.ws2812b_pwm(7,buff)
  448. */
  449. static int l_sensor_ws2812b_pwm(lua_State *L)
  450. {
  451. int ret = 0;
  452. int j = 0;
  453. size_t len,i;
  454. const char *send_buff = NULL;
  455. ws2812b_pwm_conf.channel = luaL_checkinteger(L, 1);
  456. if (lua_isuserdata(L, 2)){
  457. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  458. send_buff = (const char*)buff->addr;
  459. len = buff->len;
  460. }else if(lua_isstring(L, 2)){
  461. send_buff = lua_tolstring(L, 2, &len);
  462. }else return 0;
  463. //ws2812b_pwm_conf.pulse = 0;
  464. //luat_pwm_setup(&ws2812b_pwm_conf);
  465. for(i=0;i<len;i++){
  466. for(j=7;j>=0;j--){
  467. if(send_buff[i]>>j&0x01){
  468. ws2812b_pwm_conf.pulse = 200/3;
  469. ret = luat_pwm_setup(&ws2812b_pwm_conf);
  470. }else{
  471. ws2812b_pwm_conf.pulse = 100/3;
  472. ret = luat_pwm_setup(&ws2812b_pwm_conf);
  473. }
  474. if (ret) {
  475. LLOGW("luat_pwm_setup ret %d, end of PWM output", ret);
  476. return 0;
  477. }
  478. }
  479. }
  480. return 0;
  481. }
  482. #endif
  483. #ifdef LUAT_USE_SPI
  484. #include "luat_spi.h"
  485. static luat_spi_t ws2812b_spi_conf = {
  486. .cs = 255,
  487. .CPHA = 0,
  488. .CPOL = 0,
  489. .dataw = 8,
  490. .bandrate = 5*1000*1000,
  491. .bit_dict = 1,
  492. .master = 1,
  493. .mode = 1,
  494. };
  495. /*
  496. 设置ws2812b输出(spi驱动方式)
  497. @api sensor.ws2812b_spi(pin,data)
  498. @int spi端口号
  499. @string/zbuff 待发送的数据(如果为zbuff数据,则会无视指针位置始终从0偏移开始)
  500. @usage
  501. local buff = zbuff.create({8,8,24})
  502. buff:setFrameBuffer(8,8,24,0x0000ff)
  503. sensor.ws2812b_spi(2,buff)
  504. */
  505. static int l_sensor_ws2812b_spi(lua_State *L)
  506. {
  507. int j,m;
  508. size_t len,i;
  509. const char *send_buff = NULL;
  510. ws2812b_spi_conf.id = luaL_checkinteger(L, 1);
  511. if (lua_isuserdata(L, 2)){
  512. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  513. send_buff = (const char*)buff->addr;
  514. len = buff->len;
  515. }else if(lua_isstring(L, 2)){
  516. send_buff = lua_tolstring(L, 2, &len);
  517. }else return 0;
  518. const char res_buff = 0x00;
  519. const char low_buff = 0xc0;
  520. const char high_buff = 0xf8;
  521. luat_spi_setup(&ws2812b_spi_conf);
  522. luat_spi_send(ws2812b_spi_conf.id, &res_buff, 1);
  523. char *gbr_buff = luat_heap_malloc(len*8);
  524. m=0;
  525. for(i=0;i<len;i++){
  526. for(j=7;j>=0;j--){
  527. if(send_buff[i]>>j&0x01){
  528. gbr_buff[m]=high_buff;
  529. }else{
  530. gbr_buff[m]=low_buff;
  531. }
  532. m++;
  533. }
  534. }
  535. luat_spi_send(ws2812b_spi_conf.id, gbr_buff, len*8);
  536. luat_spi_close(ws2812b_spi_conf.id);
  537. luat_heap_free(gbr_buff);
  538. return 0;
  539. }
  540. #endif
  541. //总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒
  542. static void dht_reset(int pin)
  543. {
  544. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  545. luat_gpio_set(pin, Luat_GPIO_HIGH);
  546. luat_timer_mdelay(100);
  547. luat_gpio_set(pin, Luat_GPIO_LOW);
  548. luat_timer_mdelay(20);
  549. }
  550. //主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号
  551. static uint8_t dht_connect(int pin)
  552. {
  553. luat_gpio_mode(pin, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 0);
  554. luat_timer_us_delay(10);
  555. uint8_t retry = 0;
  556. while (luat_gpio_get(pin) && retry < 100)
  557. {
  558. retry++;
  559. luat_timer_us_delay(1);
  560. };
  561. if (retry >= 100)
  562. return CONNECT_FAILED;
  563. retry = 0;
  564. while (!luat_gpio_get(pin) && retry < 100)
  565. {
  566. retry++;
  567. luat_timer_us_delay(1);
  568. };
  569. if (retry >= 100)
  570. return CONNECT_FAILED;
  571. //相应完后等变低
  572. while (luat_gpio_get(pin) && retry < 200)
  573. {
  574. retry++;
  575. luat_timer_us_delay(1);
  576. };
  577. return CONNECT_SUCCESS;
  578. }
  579. //总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短决定了数据位是0还是1
  580. static uint8_t dht_read_bit(int pin)
  581. {
  582. uint8_t retry=0,d=0;
  583. while (!luat_gpio_get(pin) && retry < 200)
  584. {
  585. retry++;
  586. luat_timer_us_delay(1);
  587. };
  588. luat_timer_us_delay(30);
  589. d = luat_gpio_get(pin);
  590. retry=0;
  591. while (luat_gpio_get(pin) && retry < 200)
  592. {
  593. retry++;
  594. luat_timer_us_delay(1);
  595. };
  596. return d;
  597. }
  598. static uint8_t dht_read_byte(int pin)
  599. {
  600. uint8_t i, dat;
  601. dat = 0;
  602. for (i = 0; i < 8; i++)//MSB
  603. {
  604. dat<<=1;
  605. dat+=dht_read_bit(pin);
  606. }
  607. return dat;
  608. }
  609. /*
  610. 获取DHT11/DHT12的温湿度数据
  611. @api sensor.dht1x(pin)
  612. @int gpio端口号
  613. @boolean 是否校验crc值,默认为true. 不校验crc值能提高读取成功的概率,但可能会读取到错误的值
  614. @return int 湿度数据,单位0.01%,读取失败时返回错误值
  615. @return int 温度数据,单位0.01摄氏度,读取失败时返回错误值
  616. @return boolean 成功返回true,否则返回false
  617. @usage
  618. while 1 do
  619. sys.wait(1000)
  620. local h,t,r = sensor.dht1x(17, true) -- GPIO17且校验CRC值
  621. log.info("dht11", h/100,t/100,r)--90.1 23.22
  622. end
  623. */
  624. static int dht1x_read(lua_State *L)
  625. {
  626. int pin = luaL_checkinteger(L,1);
  627. int check = lua_toboolean(L,2);
  628. dht_reset(pin);
  629. luat_os_entry_cri();
  630. if(dht_connect(pin) != CONNECT_SUCCESS)//没连上
  631. {
  632. luat_os_exit_cri();
  633. lua_pushinteger(L,0);
  634. lua_pushinteger(L,0);
  635. lua_pushboolean(L,0);
  636. return 3;
  637. }
  638. uint8_t buff[5];
  639. buff[0] = dht_read_byte(pin);
  640. buff[1] = dht_read_byte(pin);//小数部分
  641. buff[2] = dht_read_byte(pin);
  642. buff[3] = dht_read_byte(pin);//小数部分
  643. buff[4] = dht_read_byte(pin);//这是crc
  644. luat_os_exit_cri();
  645. lua_pushinteger(L,buff[0]*100+buff[1]);
  646. lua_pushinteger(L,buff[2]*100+buff[3]);
  647. if(check)
  648. {
  649. uint8_t check_r = 0;
  650. check_r = buff[0]+buff[1]+buff[2]+buff[3];
  651. lua_pushboolean(L,check_r == buff[4]);
  652. }
  653. else
  654. {
  655. lua_pushboolean(L,1);
  656. }
  657. return 3;
  658. }
  659. #include "rotable2.h"
  660. static const rotable_Reg_t reg_sensor[] =
  661. {
  662. {"w1_reset", ROREG_FUNC(l_w1_reset)},
  663. {"w1_connect", ROREG_FUNC(l_w1_connect)},
  664. {"w1_write", ROREG_FUNC(l_w1_write_byte)},
  665. {"w1_read", ROREG_FUNC(l_w1_read_byte)},
  666. {"ds18b20", ROREG_FUNC(l_sensor_ds18b20)},
  667. {"hx711", ROREG_FUNC(l_sensor_hx711)},
  668. {"ws2812b", ROREG_FUNC(l_sensor_ws2812b)},
  669. {"dht1x", ROREG_FUNC(dht1x_read)},
  670. #ifdef LUAT_USE_PWM
  671. {"ws2812b_pwm", ROREG_FUNC(l_sensor_ws2812b_pwm)},
  672. #endif
  673. #ifdef LUAT_USE_SPI
  674. {"ws2812b_spi", ROREG_FUNC(l_sensor_ws2812b_spi)},
  675. #endif
  676. {NULL, ROREG_INT(0) }
  677. };
  678. LUAMOD_API int luaopen_sensor(lua_State *L)
  679. {
  680. luat_newlib2(L, reg_sensor);
  681. return 1;
  682. }