luat_lib_sensor.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  1. /*
  2. @module sensor
  3. @summary 传感器操作库
  4. @version 1.0
  5. @date 2020.03.30
  6. @tag LUAT_USE_SENSOR
  7. @demo dht11
  8. @usage
  9. -- 请查阅demo/dht11 demo/ds18b20
  10. */
  11. #include "luat_base.h"
  12. #include "luat_timer.h"
  13. #include "luat_mem.h"
  14. #include "luat_gpio.h"
  15. #include "luat_zbuff.h"
  16. #ifdef LUAT_USE_SENSOR
  17. #define LUAT_LOG_TAG "sensor"
  18. #include "luat_log.h"
  19. #define CONNECT_SUCCESS 0
  20. #define CONNECT_FAILED 1
  21. static void w1_reset(int pin)
  22. {
  23. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
  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, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 0);
  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. uint8_t data;
  53. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 0);
  54. luat_gpio_set(pin, Luat_GPIO_LOW);
  55. luat_timer_us_delay(2);
  56. // luat_gpio_set(pin, Luat_GPIO_HIGH);
  57. luat_gpio_mode(pin, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 0);
  58. data = (uint8_t)luat_gpio_get(pin);
  59. luat_timer_us_delay(60);
  60. return data;
  61. }
  62. static uint8_t w1_read_byte(int pin)
  63. {
  64. uint8_t i, j, dat;
  65. dat = 0;
  66. luat_timer_us_delay(90);
  67. //rt_base_t level;
  68. //level = rt_hw_interrupt_disable();
  69. for (i = 1; i <= 8; i++)
  70. {
  71. j = w1_read_bit(pin);
  72. dat = (j << 7) | (dat >> 1);
  73. }
  74. //rt_hw_interrupt_enable(level);
  75. return dat;
  76. }
  77. static void w1_write_byte(int pin, uint8_t dat)
  78. {
  79. uint8_t j;
  80. uint8_t testb;
  81. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
  82. for (j = 1; j <= 8; j++)
  83. {
  84. testb = dat & 0x01;
  85. dat = dat >> 1;
  86. if (testb)
  87. {
  88. luat_gpio_set(pin, Luat_GPIO_LOW);
  89. luat_timer_us_delay(2);
  90. luat_gpio_set(pin, Luat_GPIO_HIGH);
  91. luat_timer_us_delay(60);
  92. }
  93. else
  94. {
  95. luat_gpio_set(pin, Luat_GPIO_LOW);
  96. luat_timer_us_delay(60);
  97. luat_gpio_set(pin, Luat_GPIO_HIGH);
  98. luat_timer_us_delay(2);
  99. }
  100. }
  101. }
  102. static const uint8_t crc8_maxim[256] = {
  103. 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
  104. 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
  105. 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
  106. 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
  107. 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
  108. 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
  109. 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
  110. 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
  111. 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
  112. 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
  113. 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
  114. 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
  115. 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
  116. 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
  117. 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
  118. 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
  119. static int32_t ds18b20_get_temperature(int pin, int32_t *val, int check_crc)
  120. {
  121. uint8_t TL, TH;
  122. int32_t tem;
  123. uint8_t data[9] = {0};
  124. //ds18b20_start(pin);
  125. w1_reset(pin);
  126. if (w1_connect(pin)){
  127. // LLOGD("ds18b20 connect fail");
  128. return -1;
  129. }
  130. w1_write_byte(pin, 0xcc); /* skip rom */
  131. w1_write_byte(pin, 0x44); /* convert */
  132. //ds18b20_init(pin);
  133. w1_reset(pin);
  134. if (w1_connect(pin)){
  135. // LLOGD("ds18b20 connect fail");
  136. return -2;
  137. }
  138. w1_write_byte(pin, 0xcc);
  139. w1_write_byte(pin, 0xbe);
  140. data[0] = w1_read_byte(pin); /* LSB first */
  141. data[1] = w1_read_byte(pin);
  142. // if (data[0] == 0xFF || data[1] == 0xFF)
  143. // {
  144. // //LLOGD("ds18b20 bad data, skip");
  145. // return -3;
  146. // }
  147. // 9个字节都读出来,校验CRC
  148. if (check_crc)
  149. {
  150. for (size_t i = 2; i < 9; i++){
  151. data[i] = w1_read_byte(pin);
  152. }
  153. uint8_t crc = 0;
  154. for (size_t i = 0; i < 8; i++){
  155. crc = crc8_maxim[crc ^ data[i]];
  156. }
  157. // LLOGD("ds18b20 %02X%02X%02X%02X%02X%02X%02X%02X [%02X %02X]",
  158. // data[0], data[1], data[2], data[3],
  159. // data[4], data[5], data[6], data[7],
  160. // data[8], crc);
  161. if (data[8] != crc){
  162. // LLOGD("ds18b20 bad crc");
  163. return -4;
  164. }
  165. }
  166. TL = data[0];
  167. TH = data[1];
  168. if (TH > 7){
  169. TH = ~TH;
  170. TL = ~TL;
  171. tem = TH;
  172. tem <<= 8;
  173. tem += TL;
  174. tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
  175. *val = -tem;
  176. return 0;
  177. }else{
  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. }
  186. /*
  187. 获取DS18B20的温度数据
  188. @api sensor.ds18b20(pin, check_crc)
  189. @int gpio端口号
  190. @boolean 是否校验crc值,默认为true. 不校验crc值能提高读取成功的概率,但可能会读取到错误的值
  191. @return int 温度数据,单位0.1摄氏度,读取失败时返回错误码
  192. @return boolean 成功返回true,否则返回false
  193. @usage
  194. while 1 do
  195. sys.wait(5000)
  196. local val,result = sensor.ds18b20(17, true) -- GPIO17且校验CRC值
  197. -- val 301 == 30.1摄氏度
  198. -- result true 读取成功
  199. log.info("ds18b20", val, result)
  200. end
  201. */
  202. static int l_sensor_ds18b20(lua_State *L)
  203. {
  204. int32_t val = 0;
  205. int check_crc = lua_gettop(L) > 1 ? lua_toboolean(L, 2) : 1;
  206. int pin = luaL_checkinteger(L, 1);
  207. #ifdef LUAT_USE_MOBILE
  208. #else
  209. luat_os_entry_cri();
  210. #endif
  211. int32_t ret = ds18b20_get_temperature(pin, &val, check_crc);
  212. #ifdef LUAT_USE_MOBILE
  213. #else
  214. luat_os_exit_cri();
  215. #endif
  216. // -55°C ~ 125°C
  217. if (ret || !(val <= 1250 && val >= -550))
  218. {
  219. LLOGI("ds18b20 read fail");
  220. lua_pushinteger(L, ret);
  221. lua_pushboolean(L, 0);
  222. return 2;
  223. }
  224. //rt_kprintf("temp:%3d.%dC\n", temp/10, temp%10);
  225. lua_pushinteger(L, val);
  226. lua_pushboolean(L, 1);
  227. return 2;
  228. }
  229. //-------------------------------------
  230. // W1 单总线协议, 暴露w1_xxx方法
  231. //-------------------------------------
  232. /*
  233. 单总线协议,复位设备
  234. @api sensor.w1_reset(pin)
  235. @int gpio端口号
  236. @return nil 无返回
  237. */
  238. static int l_w1_reset(lua_State *L)
  239. {
  240. w1_reset((int)luaL_checkinteger(L, 1));
  241. return 0;
  242. }
  243. /*
  244. 单总线协议,连接设备
  245. @api sensor.w1_connect(pin)
  246. @int gpio端口号
  247. @return boolean 成功返回true,失败返回false
  248. */
  249. static int l_w1_connect(lua_State *L)
  250. {
  251. if (w1_connect((int)luaL_checkinteger(L, 1)) == CONNECT_SUCCESS)
  252. {
  253. lua_pushboolean(L, 1);
  254. }
  255. else
  256. {
  257. lua_pushboolean(L, 0);
  258. }
  259. return 1;
  260. }
  261. /*
  262. 单总线协议,往总线写入数据
  263. @api sensor.w1_write(pin, data1,data2)
  264. @int gpio端口号
  265. @int 第一个数据
  266. @int 第二个数据, 可以写N个数据
  267. @return nil 无返回值
  268. */
  269. static int l_w1_write_byte(lua_State *L)
  270. {
  271. int pin = luaL_checkinteger(L, 1);
  272. int top = lua_gettop(L);
  273. if (top > 1)
  274. {
  275. for (int i = 2; i <= top; i++)
  276. {
  277. uint8_t data = luaL_checkinteger(L, i);
  278. w1_write_byte(pin, data);
  279. }
  280. }
  281. return 0;
  282. }
  283. /*
  284. 单总线协议,从总线读取数据
  285. @api sensor.w1_read(pin, len)
  286. @int gpio端口号
  287. @int 读取的长度
  288. @return int 按读取的长度返回N个整数
  289. */
  290. static int l_w1_read_byte(lua_State *L)
  291. {
  292. int pin = luaL_checkinteger(L, 1);
  293. int len = luaL_checkinteger(L, 2);
  294. for (int i = 0; i < len; i++)
  295. {
  296. lua_pushinteger(L, w1_read_byte(pin));
  297. }
  298. return len;
  299. }
  300. unsigned long ReadCount(int date,int clk) //增益128
  301. {
  302. unsigned long count = 0;
  303. unsigned char i = 0;
  304. luat_gpio_mode(date, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 0);
  305. luat_gpio_set(date, Luat_GPIO_HIGH);
  306. luat_timer_us_delay(1);
  307. luat_gpio_mode(clk, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 0);
  308. luat_gpio_set(clk, Luat_GPIO_LOW);
  309. luat_gpio_mode(date, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 0);
  310. luat_timer_us_delay(1);
  311. count = 0;
  312. int retry = 50; // 最多等待5ms == 50 * 100us
  313. while (retry > 0 && luat_gpio_get(date)) {
  314. luat_timer_us_delay(100);
  315. retry --;
  316. }
  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 = 0;
  356. unsigned int temp = 0;
  357. int date = luaL_checkinteger(L, 1);
  358. int clk = luaL_checkinteger(L, 2);
  359. //for (j = 0; j < 5; j++)
  360. // luat_timer_us_delay(5000);
  361. hx711_dat = ReadCount(date,clk); //HX711AD转换数据处理
  362. temp = (unsigned int)(hx711_dat / 100); //缩放long数据为int型,方便处理
  363. //LLOGI("hx711:%d",temp);
  364. lua_pushinteger(L, temp);
  365. return 1;
  366. }
  367. /*
  368. 获取cs1237传感数据
  369. @api sensor.cs1237(pin_date,pin_clk)
  370. @int 数据的gpio端口号
  371. @int 时钟的gpio端口号
  372. @return int cs1237读到的数据
  373. @usage
  374. -- 如果设备不存在会卡在读取接口
  375. sys.taskInit(
  376. function()
  377. sys.wait(1000)
  378. local cs1237_data = sensor.cs1237(0,7)
  379. while true do
  380. sys.wait(2000)
  381. cs1237_data = sensor.cs1237(0,7) - maopi
  382. log.info("cs1237_data:", cs1237_data)--得到原始数据
  383. end
  384. end
  385. )
  386. */
  387. static int l_sensor_cs1237(lua_State *L)
  388. {
  389. // unsigned int j;
  390. unsigned long cs1237_dat = 0;
  391. unsigned int temp = 0;
  392. int date = luaL_checkinteger(L, 1);
  393. int clk = luaL_checkinteger(L, 2);
  394. //for (j = 0; j < 5; j++)
  395. // luat_timer_us_delay(5000);
  396. cs1237_dat = ReadCount(date,clk);
  397. temp = (unsigned int)cs1237_dat;
  398. //LLOGI("cs1237:%d",temp);
  399. lua_pushinteger(L, temp);
  400. return 1;
  401. }
  402. /*
  403. 设置ws2812b输出(gpio驱动方式)
  404. @api sensor.ws2812b(pin,data,T0H,T0L,T1H,T1L)
  405. @int ws2812b的gpio端口号
  406. @string/zbuff 待发送的数据(如果为zbuff数据,则会无视指针位置始终从0偏移开始)
  407. @int T0H时间,表示延时多少个nop,每个型号不一样,自己调
  408. @int T0L时间,表示延时多少个nop
  409. @int T1H时间,表示延时多少个nop
  410. @int T1L时间,表示延时多少个nop
  411. @usage
  412. local buff = zbuff.create({8,8,24})
  413. buff:drawLine(1,2,5,6,0x00ffff)
  414. sensor.ws2812b(7,buff,300,700,700,700)
  415. */
  416. const unsigned char xor_bit_table[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  417. #define WS2812B_BIT_0() \
  418. t0h_temp = t0h; t0l_temp = t0l; \
  419. luat_gpio_pulse(pin,&pulse_level,2,t0h); \
  420. while(t0l_temp--)
  421. #define WS2812B_BIT_1() \
  422. t1h_temp = t1h; t1l_temp = t1l; \
  423. luat_gpio_pulse(pin,&pulse_level,2,t1h); \
  424. while(t1l_temp--)
  425. static int l_sensor_ws2812b(lua_State *L)
  426. {
  427. int j;
  428. size_t len,i;
  429. uint8_t pulse_level = 0x80;
  430. const char *send_buff = NULL;
  431. int pin = luaL_checkinteger(L, 1);
  432. if (lua_isuserdata(L, 2))
  433. {
  434. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  435. send_buff = (const char*)buff->addr;
  436. len = buff->len;
  437. }
  438. else
  439. {
  440. send_buff = lua_tolstring(L, 2, &len);
  441. }
  442. #ifdef LUAT_WS2812B_MAX_CNT
  443. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_DEFAULT, Luat_GPIO_LOW);
  444. uint8_t bit0h = luaL_optinteger(L, 3, 10);
  445. uint8_t bit0l = luaL_optinteger(L, 4, 0);
  446. uint8_t bit1h = luaL_optinteger(L, 5, 10);
  447. uint8_t bit1l = luaL_optinteger(L, 6, 0);
  448. uint32_t frame_cnt = luaL_optinteger(L, 7, 0);
  449. luat_gpio_driver_ws2812b(pin, send_buff, len, frame_cnt, bit0h, bit0l, bit1h, bit1l);
  450. #else
  451. volatile uint32_t t0h_temp,t0h = luaL_checkinteger(L, 3);
  452. volatile uint32_t t0l_temp,t0l = luaL_checkinteger(L, 4);
  453. volatile uint32_t t1h_temp,t1h = luaL_checkinteger(L, 5);
  454. volatile uint32_t t1l_temp,t1l = luaL_checkinteger(L, 6);
  455. (void)t1h_temp;(void)t0h_temp;
  456. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_LOW);
  457. pulse_level = 0 ;
  458. luat_gpio_pulse(pin,&pulse_level,2,t0h);
  459. pulse_level = 0x80;
  460. luat_os_entry_cri();
  461. for(i=0;i<len;i++)
  462. {
  463. for(j=7;j>=0;j--)
  464. {
  465. if(send_buff[i]&xor_bit_table[j])
  466. {
  467. WS2812B_BIT_1();
  468. }
  469. else
  470. {
  471. WS2812B_BIT_0();
  472. }
  473. }
  474. }
  475. luat_os_exit_cri();
  476. #endif
  477. return 0;
  478. }
  479. #ifdef LUAT_USE_PWM
  480. #include "luat_pwm.h"
  481. static luat_pwm_conf_t ws2812b_pwm_conf = {
  482. .pnum = 1,
  483. .period = 800*1000,
  484. .precision = 100
  485. };
  486. /*
  487. 设置ws2812b输出(pwm驱动方式,需要pwm能输出800k频率,否则无法使用此方法)
  488. @api sensor.ws2812b_pwm(pin,data)
  489. @int pwm端口号
  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_pwm(7,buff)
  495. */
  496. static int l_sensor_ws2812b_pwm(lua_State *L)
  497. {
  498. int ret = 0;
  499. int j = 0;
  500. size_t len,i;
  501. const char *send_buff = NULL;
  502. ws2812b_pwm_conf.channel = luaL_checkinteger(L, 1);
  503. if (lua_isuserdata(L, 2)){
  504. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  505. send_buff = (const char*)buff->addr;
  506. len = buff->len;
  507. }else if(lua_isstring(L, 2)){
  508. send_buff = lua_tolstring(L, 2, &len);
  509. }else return 0;
  510. //ws2812b_pwm_conf.pulse = 0;
  511. //luat_pwm_setup(&ws2812b_pwm_conf);
  512. for(i=0;i<len;i++){
  513. for(j=7;j>=0;j--){
  514. if(send_buff[i]>>j&0x01){
  515. ws2812b_pwm_conf.pulse = 200/3;
  516. ret = luat_pwm_setup(&ws2812b_pwm_conf);
  517. }else{
  518. ws2812b_pwm_conf.pulse = 100/3;
  519. ret = luat_pwm_setup(&ws2812b_pwm_conf);
  520. }
  521. if (ret) {
  522. LLOGW("luat_pwm_setup ret %d, end of PWM output", ret);
  523. return 0;
  524. }
  525. }
  526. }
  527. return 0;
  528. }
  529. #endif
  530. #ifdef LUAT_USE_SPI
  531. #include "luat_spi.h"
  532. static luat_spi_t ws2812b_spi_conf = {
  533. .cs = 255,
  534. .CPHA = 0,
  535. .CPOL = 0,
  536. .dataw = 8,
  537. .bandrate = 5*1000*1000,
  538. .bit_dict = 1,
  539. .master = 1,
  540. .mode = 1,
  541. };
  542. /*
  543. 设置ws2812b输出(spi驱动方式,需要spi能输出5M频率,否则无法使用此方法)
  544. @api sensor.ws2812b_spi(pin,data)
  545. @int spi端口号
  546. @string/zbuff 待发送的数据(如果为zbuff数据,则会无视指针位置始终从0偏移开始)
  547. @usage
  548. local buff = zbuff.create({8,8,24})
  549. buff:setFrameBuffer(8,8,24,0x0000ff)
  550. sensor.ws2812b_spi(2,buff)
  551. */
  552. static int l_sensor_ws2812b_spi(lua_State *L)
  553. {
  554. int j,m;
  555. size_t len,i;
  556. const char *send_buff = NULL;
  557. ws2812b_spi_conf.id = luaL_checkinteger(L, 1);
  558. if (lua_isuserdata(L, 2)){
  559. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  560. send_buff = (const char*)buff->addr;
  561. len = buff->len;
  562. }else if(lua_isstring(L, 2)){
  563. send_buff = lua_tolstring(L, 2, &len);
  564. }else return 0;
  565. const char res_buff = 0x00;
  566. const char low_buff = 0xc0;
  567. const char high_buff = 0xf8;
  568. luat_spi_setup(&ws2812b_spi_conf);
  569. luat_spi_send(ws2812b_spi_conf.id, &res_buff, 1);
  570. char *gbr_buff = luat_heap_malloc(len*8);
  571. m=0;
  572. for(i=0;i<len;i++){
  573. for(j=7;j>=0;j--){
  574. if(send_buff[i]>>j&0x01){
  575. gbr_buff[m]=high_buff;
  576. }else{
  577. gbr_buff[m]=low_buff;
  578. }
  579. m++;
  580. }
  581. }
  582. luat_spi_send(ws2812b_spi_conf.id, gbr_buff, len*8);
  583. luat_spi_close(ws2812b_spi_conf.id);
  584. luat_heap_free(gbr_buff);
  585. return 0;
  586. }
  587. #endif
  588. //总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒
  589. static void dht_reset(int pin)
  590. {
  591. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  592. luat_gpio_set(pin, Luat_GPIO_HIGH);
  593. luat_timer_mdelay(100);
  594. luat_gpio_set(pin, Luat_GPIO_LOW);
  595. luat_timer_mdelay(20);
  596. luat_gpio_set(pin, Luat_GPIO_HIGH);
  597. }
  598. //主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号
  599. static uint8_t dht_connect(int pin)
  600. {
  601. luat_gpio_mode(pin, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  602. luat_timer_us_delay(10);
  603. uint8_t retry = 0;
  604. while (luat_gpio_get(pin) && retry < 100)
  605. {
  606. retry++;
  607. luat_timer_us_delay(1);
  608. };
  609. if (retry >= 100)
  610. return CONNECT_FAILED;
  611. retry = 0;
  612. while (!luat_gpio_get(pin) && retry < 100)
  613. {
  614. retry++;
  615. luat_timer_us_delay(1);
  616. };
  617. if (retry >= 100)
  618. return CONNECT_FAILED;
  619. //相应完后等变低
  620. while (luat_gpio_get(pin) && retry < 200)
  621. {
  622. retry++;
  623. luat_timer_us_delay(1);
  624. };
  625. return CONNECT_SUCCESS;
  626. }
  627. //总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短决定了数据位是0还是1
  628. static uint8_t dht_read_bit(int pin)
  629. {
  630. uint8_t retry=0,d=0;
  631. while (!luat_gpio_get(pin) && retry < 200)
  632. {
  633. retry++;
  634. luat_timer_us_delay(1);
  635. };
  636. luat_timer_us_delay(30);
  637. d = luat_gpio_get(pin);
  638. retry=0;
  639. while (luat_gpio_get(pin) && retry < 200)
  640. {
  641. retry++;
  642. luat_timer_us_delay(1);
  643. };
  644. return d;
  645. }
  646. static uint8_t dht_read_byte(int pin)
  647. {
  648. uint8_t i, dat;
  649. dat = 0;
  650. for (i = 0; i < 8; i++)//MSB
  651. {
  652. dat<<=1;
  653. dat+=dht_read_bit(pin);
  654. }
  655. return dat;
  656. }
  657. /*
  658. 获取DHT11/DHT12的温湿度数据
  659. @api sensor.dht1x(pin)
  660. @int gpio端口号
  661. @boolean 是否校验crc值,默认为true. 不校验crc值能提高读取成功的概率,但可能会读取到错误的值
  662. @return int 湿度数据,单位0.01%,读取失败时返回错误值
  663. @return int 温度数据,单位0.01摄氏度,读取失败时返回错误值
  664. @return boolean 成功返回true,否则返回false
  665. @usage
  666. while 1 do
  667. sys.wait(1000)
  668. local h,t,r = sensor.dht1x(17, true) -- GPIO17且校验CRC值
  669. log.info("dht11", h/100,t/100,r)--90.1 23.22
  670. end
  671. */
  672. static int dht1x_read(lua_State *L)
  673. {
  674. int pin = luaL_checkinteger(L,1);
  675. int check = lua_toboolean(L,2);
  676. dht_reset(pin);
  677. luat_os_entry_cri();
  678. if(dht_connect(pin) != CONNECT_SUCCESS)//没连上
  679. {
  680. luat_os_exit_cri();
  681. lua_pushinteger(L,0);
  682. lua_pushinteger(L,0);
  683. lua_pushboolean(L,0);
  684. return 3;
  685. }
  686. uint8_t buff[5];
  687. buff[0] = dht_read_byte(pin);
  688. buff[1] = dht_read_byte(pin);//小数部分
  689. buff[2] = dht_read_byte(pin);
  690. buff[3] = dht_read_byte(pin);//小数部分
  691. buff[4] = dht_read_byte(pin);//这是crc
  692. luat_os_exit_cri();
  693. int temp = (buff[0] & 0x7F) *100 + buff[1];
  694. int humi = (buff[2] & 0x7F) *100 + buff[3];
  695. if (buff[0] & 0x80)
  696. {
  697. temp = -temp;
  698. }
  699. lua_pushinteger(L, temp);
  700. lua_pushinteger(L, humi);
  701. if(check)
  702. {
  703. uint8_t check_r = 0;
  704. check_r = buff[0]+buff[1]+buff[2]+buff[3];
  705. lua_pushboolean(L,check_r == buff[4]);
  706. }
  707. else
  708. {
  709. lua_pushboolean(L,1);
  710. }
  711. return 3;
  712. }
  713. static unsigned char sc12a_wait_ack(int sda, int scl)
  714. {
  715. luat_gpio_set(sda, Luat_GPIO_HIGH);
  716. luat_gpio_mode(sda, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 1);
  717. luat_timer_us_delay(5);
  718. luat_gpio_set(scl, Luat_GPIO_HIGH);
  719. luat_timer_us_delay(5 * 3);
  720. int max_wait_time = 3000;
  721. while (max_wait_time--)
  722. {
  723. if (luat_gpio_get(sda) == Luat_GPIO_LOW)
  724. {
  725. luat_gpio_set(scl, Luat_GPIO_LOW);
  726. return 1;
  727. }
  728. luat_timer_us_delay(1);
  729. }
  730. // 停止信号
  731. luat_gpio_mode(sda, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 1);
  732. luat_gpio_set(scl, Luat_GPIO_LOW);
  733. luat_timer_us_delay(5);
  734. luat_gpio_set(sda, Luat_GPIO_LOW);
  735. luat_timer_us_delay(5);
  736. luat_gpio_set(scl, Luat_GPIO_HIGH);
  737. luat_timer_us_delay(5);
  738. luat_gpio_set(sda, Luat_GPIO_HIGH);
  739. luat_timer_us_delay(5);
  740. return 0;
  741. }
  742. static unsigned int read_sc12akey(int sda, int scl)
  743. {
  744. unsigned int data=0 ;
  745. unsigned char sc12a_addr = 0x81;
  746. // 发送开始信号
  747. luat_gpio_mode(scl, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 1);
  748. luat_gpio_mode(sda, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 1);
  749. luat_timer_us_delay(5);
  750. luat_gpio_set(scl, Luat_GPIO_HIGH);
  751. luat_timer_us_delay(5);
  752. luat_gpio_set(sda, Luat_GPIO_LOW);
  753. luat_timer_us_delay(5);
  754. luat_gpio_set(scl, Luat_GPIO_LOW);
  755. luat_timer_us_delay(5);
  756. // 发送地址
  757. unsigned char i = 8;
  758. luat_gpio_mode(sda, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 0);
  759. while (i--)
  760. {
  761. luat_gpio_set(scl, Luat_GPIO_LOW);
  762. luat_timer_us_delay(5 * 2);
  763. if (sc12a_addr & 0x80)
  764. {
  765. luat_gpio_set(sda, Luat_GPIO_HIGH);
  766. }
  767. else
  768. {
  769. luat_gpio_set(sda, Luat_GPIO_LOW);
  770. }
  771. luat_timer_us_delay(5);
  772. sc12a_addr <<= 1;
  773. luat_gpio_set(scl, Luat_GPIO_HIGH);
  774. luat_timer_us_delay(5);
  775. luat_gpio_set(scl, Luat_GPIO_LOW);
  776. luat_timer_us_delay(5);
  777. }
  778. // 等待回应ack
  779. if (!sc12a_wait_ack(sda, scl))
  780. {
  781. luat_gpio_mode(sda, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 1);
  782. luat_gpio_set(scl, Luat_GPIO_LOW);
  783. luat_timer_us_delay(5);
  784. luat_gpio_set(sda, Luat_GPIO_LOW);
  785. luat_timer_us_delay(5);
  786. luat_gpio_set(scl, Luat_GPIO_HIGH);
  787. luat_timer_us_delay(5);
  788. luat_gpio_set(sda, Luat_GPIO_HIGH);
  789. luat_timer_us_delay(5);
  790. return -1;
  791. }
  792. i = 16;
  793. luat_gpio_set(sda, Luat_GPIO_HIGH);
  794. luat_gpio_mode(sda, Luat_GPIO_INPUT, Luat_GPIO_PULLUP, 1);
  795. while (i--)
  796. {
  797. data <<= 1;
  798. luat_gpio_set(scl, Luat_GPIO_LOW);
  799. luat_timer_us_delay(5);
  800. luat_gpio_set(scl, Luat_GPIO_HIGH);
  801. luat_timer_us_delay(5);
  802. if (luat_gpio_get(sda))
  803. data |= 0x01;
  804. }
  805. //发送NOACK
  806. luat_gpio_set(scl, Luat_GPIO_LOW);
  807. luat_gpio_mode(sda, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 1);
  808. luat_timer_us_delay(5);
  809. luat_gpio_set(scl, Luat_GPIO_HIGH);
  810. luat_timer_us_delay(5);
  811. luat_gpio_set(scl, Luat_GPIO_LOW);
  812. //发送STOP
  813. luat_gpio_mode(sda, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 1);
  814. luat_gpio_set(scl, Luat_GPIO_LOW);
  815. luat_timer_us_delay(5);
  816. luat_gpio_set(sda, Luat_GPIO_LOW);
  817. luat_timer_us_delay(5);
  818. luat_gpio_set(scl, Luat_GPIO_HIGH);
  819. luat_timer_us_delay(5);
  820. luat_gpio_set(sda, Luat_GPIO_HIGH);
  821. luat_timer_us_delay(5);
  822. return (data);
  823. }
  824. /*
  825. 获取sc12a被触摸的通道数据
  826. @api sensor.sc12a(sda,scl)
  827. @int 数据的gpio端口号
  828. @int 时钟的gpio端口号
  829. @return int 读取成功返回整形数据,读取失败时返回错误值
  830. @usage
  831. while true do
  832. local temp1=sensor.sc12a(4,7)
  833. if bit.rshift(bit.band( temp1, 0x8000), 15 )==0x01 then
  834. log.info("被按下的有通道0")
  835. end
  836. if bit.rshift(bit.band( temp1, 0x4000), 14 )==0x01 then
  837. log.info("被按下的有通道1")
  838. end
  839. if bit.rshift(bit.band( temp1, 0x2000), 13 )==0x01 then
  840. log.info("被按下的有通道2")
  841. end
  842. if bit.rshift(bit.band( temp1, 0x1000), 12 )==0x01 then
  843. log.info("被按下的有通道3")
  844. end
  845. if bit.rshift(bit.band( temp1, 0x800), 11 )==0x01 then
  846. log.info("被按下的有通道4")
  847. end
  848. if bit.rshift(bit.band( temp1, 0x400), 10 )==0x01 then
  849. log.info("被按下的有通道5")
  850. end
  851. if bit.rshift(bit.band( temp1, 0x200), 9 )==0x01 then
  852. log.info("被按下的有通道6")
  853. end
  854. if bit.rshift(bit.band( temp1, 0x100), 8 )==0x01 then
  855. log.info("被按下的有通道7")
  856. end
  857. if bit.rshift(bit.band( temp1, 0x80), 7 )==0x01 then
  858. log.info("被按下的有通道8")
  859. end
  860. if bit.rshift(bit.band( temp1, 0x40), 6 )==0x01 then
  861. log.info("被按下的有通道9")
  862. end
  863. if bit.rshift(bit.band( temp1, 0x20), 5 )==0x01 then
  864. log.info("被按下的有通道10")
  865. end
  866. if bit.rshift(bit.band( temp1, 0x10), 4 )==0x01 then
  867. log.info("被按下的有通道11")
  868. end
  869. sys.wait(200)
  870. end
  871. */
  872. static int l_sensor_sc12a(lua_State *L)
  873. {
  874. unsigned int sc12a_data = 0xffff;
  875. int sda = luaL_checkinteger(L, 1);
  876. int scl = luaL_checkinteger(L, 2);
  877. sc12a_data = read_sc12akey(sda,scl);
  878. sc12a_data =sc12a_data^0xffff;
  879. lua_pushinteger(L, sc12a_data);
  880. return 1;
  881. }
  882. /*
  883. 单总线命令读写YHM27XX
  884. @api sensor.yhm27xxx(pin, chip_id, reg, data)
  885. @int gpio端口号
  886. @int 芯片ID
  887. @int 寄存器地址
  888. @int 要写入的数据,如果没填,则表示从寄存器读取数据
  889. @return boolean 成功返回true,失败返回false
  890. @return int 读取成功返回寄存器值,写入成功无返回
  891. @usage
  892. while 1 do
  893. sys.wait(1000)
  894. local result, data = sensor.yhm27xxx(15, 0x04, 0x05)
  895. log.info("yhm27xxx", result, data)
  896. end
  897. */
  898. #ifdef LUAT_USE_YHM27XX
  899. static int l_sensor_yhm27xx(lua_State *L)
  900. {
  901. uint8_t pin = luaL_checkinteger(L, 1);
  902. uint8_t chip_id = luaL_checkinteger(L, 2);
  903. uint8_t reg = luaL_checkinteger(L, 3);
  904. uint8_t data = 0;
  905. uint8_t is_read = 1;
  906. if (!lua_isnone(L, 4))
  907. {
  908. is_read = 0;
  909. data = luaL_checkinteger(L, 4);
  910. }
  911. if(luat_gpio_driver_yhm27xx(pin, chip_id, reg, is_read, &data))
  912. {
  913. lua_pushboolean(L, 0);
  914. return 1;
  915. }
  916. lua_pushboolean(L, 1);
  917. if (is_read)
  918. {
  919. lua_pushinteger(L, data);
  920. return 2;
  921. }
  922. return 1;
  923. }
  924. #endif
  925. #include "rotable2.h"
  926. static const rotable_Reg_t reg_sensor[] =
  927. {
  928. {"w1_reset", ROREG_FUNC(l_w1_reset)},
  929. {"w1_connect", ROREG_FUNC(l_w1_connect)},
  930. {"w1_write", ROREG_FUNC(l_w1_write_byte)},
  931. {"w1_read", ROREG_FUNC(l_w1_read_byte)},
  932. {"ds18b20", ROREG_FUNC(l_sensor_ds18b20)},
  933. {"hx711", ROREG_FUNC(l_sensor_hx711)},
  934. {"cs1237", ROREG_FUNC(l_sensor_cs1237)},
  935. {"ws2812b", ROREG_FUNC(l_sensor_ws2812b)},
  936. {"dht1x", ROREG_FUNC(dht1x_read)},
  937. {"sc12a", ROREG_FUNC(l_sensor_sc12a)},
  938. #ifdef LUAT_USE_PWM
  939. {"ws2812b_pwm", ROREG_FUNC(l_sensor_ws2812b_pwm)},
  940. #endif
  941. #ifdef LUAT_USE_SPI
  942. {"ws2812b_spi", ROREG_FUNC(l_sensor_ws2812b_spi)},
  943. #endif
  944. #ifdef LUAT_USE_YHM27XX
  945. {"yhm27xx", ROREG_FUNC(l_sensor_yhm27xx)},
  946. #endif
  947. {NULL, ROREG_INT(0) }
  948. };
  949. LUAMOD_API int luaopen_sensor(lua_State *L)
  950. {
  951. luat_newlib2(L, reg_sensor);
  952. return 1;
  953. }
  954. #endif