luat_lib_sensor.c 18 KB

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