luat_lib_ir.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. @module ir
  3. @summary 红外遥控
  4. @version 1.0
  5. @date 2021.10.26
  6. @demo ir
  7. @tag LUAT_USE_IR
  8. */
  9. #include "luat_base.h"
  10. #include "luat_gpio.h"
  11. #define LUAT_LOG_TAG "ir"
  12. #include "luat_log.h"
  13. //发送指定数量脉冲,当pwm来用
  14. static void send_pulse(int pin, size_t waith, size_t waitl, size_t count)
  15. {
  16. while(count--)
  17. {
  18. luat_gpio_set(pin, Luat_GPIO_HIGH);
  19. luat_timer_us_delay(waith);
  20. luat_gpio_set(pin, Luat_GPIO_LOW);
  21. luat_timer_us_delay(waitl);
  22. }
  23. }
  24. #define IR_NEC_PWM_SEND_START(pin) send_pulse(pin, 7, 18, 375); luat_timer_us_delay(4500)
  25. #define IR_NEC_PWM_SEND_REPEAT(pin) send_pulse(pin, 7, 18, 375); luat_timer_us_delay(2250); send_pulse(pin, 7, 17, 23)
  26. #define IR_NEC_PWM_SEND_STOP(pin) send_pulse(pin, 7, 17, 23)
  27. #define IR_NEC_PWM_SEND_0(pin) send_pulse(pin, 7, 17, 23); luat_timer_us_delay(560)
  28. #define IR_NEC_PWM_SEND_1(pin) send_pulse(pin, 7, 17, 23); luat_timer_us_delay(1680)
  29. static void ir_nec_pwm_send(int pin, uint8_t code)
  30. {
  31. uint8_t c = 8;
  32. while(c--)
  33. {
  34. if(code & 0x01)
  35. {
  36. IR_NEC_PWM_SEND_1(pin);
  37. }
  38. else
  39. {
  40. IR_NEC_PWM_SEND_0(pin);
  41. }
  42. code = code >> 1;
  43. }
  44. }
  45. #define IR_NEC_SEND_START(pin) luat_gpio_set(pin, Luat_GPIO_HIGH); \
  46. luat_timer_us_delay(9000); \
  47. luat_gpio_set(pin, Luat_GPIO_LOW); \
  48. luat_timer_us_delay(4500)
  49. #define IR_NEC_SEND_REPEAT(pin) luat_gpio_set(pin, Luat_GPIO_HIGH); \
  50. luat_timer_us_delay(9000); \
  51. luat_gpio_set(pin, Luat_GPIO_LOW); \
  52. luat_timer_us_delay(2250); \
  53. luat_gpio_set(pin, Luat_GPIO_HIGH); \
  54. luat_timer_us_delay(560); \
  55. luat_gpio_set(pin, Luat_GPIO_LOW)
  56. #define IR_NEC_SEND_STOP(pin) luat_gpio_set(pin, Luat_GPIO_HIGH); \
  57. luat_timer_us_delay(560); \
  58. luat_gpio_set(pin, Luat_GPIO_LOW)
  59. #define IR_NEC_SEND_0(pin) luat_gpio_set(pin, Luat_GPIO_HIGH); \
  60. luat_timer_us_delay(560); \
  61. luat_gpio_set(pin, Luat_GPIO_LOW); \
  62. luat_timer_us_delay(560)
  63. #define IR_NEC_SEND_1(pin) luat_gpio_set(pin, Luat_GPIO_HIGH); \
  64. luat_timer_us_delay(560); \
  65. luat_gpio_set(pin, Luat_GPIO_LOW); \
  66. luat_timer_us_delay(1690)
  67. static void ir_nec_send(int pin, uint8_t code)
  68. {
  69. uint8_t c = 8;
  70. while(c--)
  71. {
  72. if(code & 0x01)
  73. {
  74. IR_NEC_SEND_1(pin);
  75. }
  76. else
  77. {
  78. IR_NEC_SEND_0(pin);
  79. }
  80. code = code >> 1;
  81. }
  82. }
  83. /**
  84. 发送NEC数据
  85. @api ir.sendNEC(pin, addr, cmd, repeat, disablePWM)
  86. @int 使用的GPIO引脚编号
  87. @int 用户码(大于0xff则采用Extended NEC模式)
  88. @int 数据码
  89. @int 可选,引导码发送次数(110ms一次),默认0次
  90. @bool 可选,是否禁止直接发送pwm波,默认false
  91. @usage
  92. --直接发
  93. ir.sendNEC(0, 0x11, 0x22)
  94. --外接了38K的PWM载波,只控制电平
  95. ir.sendNEC(0, 0x11, 0x22,0,true)
  96. */
  97. static int l_ir_send_nec(lua_State *L) {
  98. uint8_t code1,code2,data1,data2;
  99. int pin = luaL_checkinteger(L, 1);
  100. int code = luaL_checkinteger(L, 2);
  101. if(code > 0xFF)
  102. {
  103. code1 = code % 256;
  104. code2 = code / 256;
  105. }
  106. else
  107. {
  108. code1 = code;
  109. code2 = ~code;
  110. }
  111. data1 = luaL_checkinteger(L, 3);
  112. data2 = ~data1;
  113. int count = luaL_optinteger(L, 4, 0);
  114. int pwm = !lua_toboolean(L, 5);
  115. luat_gpio_mode(pin, Luat_GPIO_OUTPUT, Luat_GPIO_DEFAULT, Luat_GPIO_LOW);
  116. //38k载波,每周期26.31us
  117. //推荐载波占空比为1/3至1/4
  118. //此处高电平7us,低电平19us
  119. //http://www.taichi-maker.com/homepage/reference-index/arduino-library-index/irremote-library/nec-ir/
  120. luat_os_entry_cri();
  121. if(pwm)
  122. {
  123. IR_NEC_PWM_SEND_START(pin);
  124. ir_nec_pwm_send(pin, code1);
  125. ir_nec_pwm_send(pin, code2);
  126. ir_nec_pwm_send(pin, data1);
  127. ir_nec_pwm_send(pin, data2);
  128. while (count--)
  129. {
  130. IR_NEC_PWM_SEND_REPEAT(pin);
  131. luat_timer_us_delay(110000);
  132. }
  133. IR_NEC_PWM_SEND_STOP(pin);
  134. }
  135. else
  136. {
  137. IR_NEC_SEND_START(pin);
  138. ir_nec_send(pin, code1);
  139. ir_nec_send(pin, code2);
  140. ir_nec_send(pin, data1);
  141. ir_nec_send(pin, data2);
  142. while (count--)
  143. {
  144. IR_NEC_SEND_REPEAT(pin);
  145. luat_timer_us_delay(110000);
  146. }
  147. IR_NEC_SEND_STOP(pin);
  148. }
  149. luat_os_exit_cri();
  150. return 0;
  151. }
  152. #include "rotable2.h"
  153. static const rotable_Reg_t reg_ir[] =
  154. {
  155. { "sendNEC" , ROREG_FUNC(l_ir_send_nec)},
  156. { NULL, ROREG_INT(0) }
  157. };
  158. LUAMOD_API int luaopen_ir( lua_State *L ) {
  159. luat_newlib2(L, reg_ir);
  160. return 1;
  161. }