luat_lib_ir.c 4.9 KB

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