rfswitch.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * https://github.com/ffedoroff/nodemcu-firmware contributed by Roman Fedorov
  3. *
  4. * Module for operate 433/315Mhz devices like power outlet sockets, relays, etc.
  5. * This will most likely work with all popular low cost power outlet sockets
  6. * with a SC5262 / SC5272, HX2262 / HX2272, PT2262 / PT2272, EV1527,
  7. * RT1527, FP1527 or HS1527 chipset.
  8. *
  9. * This module using some code from original rc-switch arduino lib
  10. * https://github.com/sui77/rc-switch/ but unfortunatelly NodeMCU and Arduino
  11. * are not fully compatable, and it cause for full rewrite rc-switch lib into new rfswitch lib.
  12. */
  13. #include "module.h"
  14. #include "lauxlib.h"
  15. #include "platform.h"
  16. #include "user_interface.h"
  17. typedef struct HighLow {
  18. uint8_t high;
  19. uint8_t low;
  20. } HighLow;
  21. typedef struct Protocol {
  22. int pulseLength;
  23. HighLow syncFactor;
  24. HighLow zero;
  25. HighLow one;
  26. /** @brief if true inverts the high and low logic levels in the HighLow structs */
  27. bool invertedSignal;
  28. } Protocol;
  29. /* Format for protocol definitions:
  30. * {pulselength, Sync bit, "0" bit, "1" bit}
  31. *
  32. * pulselength: pulse length in microseconds, e.g. 350
  33. * Sync bit: {1, 31} means 1 high pulse and 31 low pulses
  34. * (perceived as a 31*pulselength long pulse, total length of sync bit is
  35. * 32*pulselength microseconds), i.e:
  36. * _
  37. * | |_______________________________ (don't count the vertical bars)
  38. * "0" bit: waveform for a data bit of value "0", {1, 3} means 1 high pulse
  39. * and 3 low pulses, total length (1+3)*pulselength, i.e:
  40. * _
  41. * | |___
  42. * "1" bit: waveform for a data bit of value "1", e.g. {3,1}:
  43. * ___
  44. * | |_
  45. *
  46. * These are combined to form Tri-State bits when sending or receiving codes.
  47. */
  48. static const Protocol proto[] = {
  49. { 350, { 1, 31 }, { 1, 3 }, { 3, 1 }, false }, // protocol 1
  50. { 650, { 1, 10 }, { 1, 2 }, { 2, 1 }, false }, // protocol 2
  51. { 100, { 30, 71 }, { 4, 11 }, { 9, 6 }, false }, // protocol 3
  52. { 380, { 1, 6 }, { 1, 3 }, { 3, 1 }, false }, // protocol 4
  53. { 500, { 6, 14 }, { 1, 2 }, { 2, 1 }, false }, // protocol 5
  54. { 450, { 23, 1 }, { 1, 2 }, { 2, 1 }, true } // protocol 6 (HT6P20B)
  55. };
  56. /**
  57. * Transmit a single high-low pulse.
  58. */
  59. void transmit(HighLow pulses, bool invertedSignal, int pulseLength, int pin) {
  60. platform_gpio_write(pin, !invertedSignal);
  61. os_delay_us(pulseLength * pulses.high);
  62. platform_gpio_write(pin, invertedSignal);
  63. os_delay_us(pulseLength * pulses.low);
  64. }
  65. /**
  66. * Transmit the first 'length' bits of the integer 'code'. The
  67. * bits are sent from MSB to LSB, i.e., first the bit at position length-1,
  68. * then the bit at position length-2, and so on, till finally the bit at position 0.
  69. */
  70. void send(unsigned long protocol_id, unsigned long pulse_length, unsigned long repeat, unsigned long pin, unsigned long value, unsigned int length) {
  71. platform_gpio_mode(pin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT);
  72. Protocol p = proto[protocol_id-1];
  73. for (int nRepeat = 0; nRepeat < repeat; nRepeat++) {
  74. for (int i = length-1; i >= 0; i--) {
  75. if (value & (1L << i))
  76. transmit(p.one, p.invertedSignal, pulse_length, pin);
  77. else
  78. transmit(p.zero, p.invertedSignal, pulse_length, pin);
  79. }
  80. transmit(p.syncFactor, p.invertedSignal, pulse_length, pin);
  81. }
  82. }
  83. static int rfswitch_send( lua_State *L )
  84. {
  85. unsigned int protocol_id = luaL_checkinteger( L, 1 );
  86. unsigned int pulse_length = luaL_checkinteger( L, 2 );
  87. unsigned int repeat = luaL_checkinteger( L, 3 );
  88. unsigned int pin = luaL_checkinteger( L, 4 );
  89. unsigned long value = luaL_checkinteger( L, 5 );
  90. unsigned long length = luaL_checkinteger( L, 6 );
  91. send(protocol_id, pulse_length, repeat, pin, value, length);
  92. return 0;
  93. }
  94. // Module function map
  95. LROT_BEGIN(rfswitch, NULL, 0)
  96. LROT_FUNCENTRY( send, rfswitch_send )
  97. LROT_END(rfswitch, NULL, 0)
  98. NODEMCU_MODULE(RFSWITCH, "rfswitch", rfswitch, NULL);