Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
7.2 KiB

  1. /*
  2. * RemoteSwitch library v2.0.0 made by Randy Simons http://randysimons.nl
  3. *
  4. * License: "Free BSD license". See license.txt
  5. */
  6. #ifndef RemoteSwitch_h
  7. #define RemoteSwitch_h
  8. //#include "WProgram.h"
  9. #include "Arduino.h"
  10. /**
  11. * RemoteSwitch provides a generic class for simulation of common RF remote controls, like the 'Klik aan Klik uit'-system
  12. * (http://www.klikaanklikuit.nl/), used to remotely switch lights etc.
  13. *
  14. * Many of these remotes seem to use a 433MHz SAW resonator and one of these chips: LP801B, HX2262, PT2262, M3E.
  15. * Datasheet for the HX2262/PT2262 ICs:
  16. * http://www.princeton.com.tw/downloadprocess/downloadfile.asp?mydownload=PT2262_1.pdf
  17. *
  18. * Hardware required for this library: a 433MHz SAW oscillator transmitter, e.g.
  19. * http://www.sparkfun.com/commerce/product_info.php?products_id=7815
  20. * http://www.conrad.nl/goto/?product=130428
  21. *
  22. * Notes:
  23. * - Since these chips use (and send!) tri-state inputs (low, high and floating) I use 'trits' instead of 'bits',
  24. * when appropriate.
  25. * - I measured the period lengths with a scope. Thus: they work for my remotes, but may fail for yours...
  26. * A better way would be to calculate the 'target'-timings using the datasheets and the resistor-values on the remotes.
  27. */
  28. class RemoteSwitch {
  29. public:
  30. /**
  31. * Constructor.
  32. *
  33. * To obtain the correct period length, an oscilloscope is convenient, but you can also read the
  34. * datasheet of the transmitter, measure the resistor for the oscillator and calculate the freqency.
  35. *
  36. * @param pin output pin on Arduino to which the transmitter is connected
  37. * @param periodsec [0..511] Duration of one period, in microseconds. A trit is 6 periods.
  38. * @param repeats [0..7] The 2log-Number of times the signal is repeated. The actual number of repeats will be 2^repeats. 3 would be a good start.
  39. */
  40. RemoteSwitch(unsigned short pin, unsigned int periodusec, unsigned short repeats);
  41. /**
  42. * Encodes the data base on the current object and the given trits. The data can be reused, e.g.
  43. * for use with the static version of sendTelegram, so you won't need to instantiate costly objects!
  44. *
  45. * @return The data suited for use with RemoteSwitch::sendTelegram.
  46. */
  47. unsigned long encodeTelegram(unsigned short trits[]);
  48. /**
  49. * Send a telegram, including synchronisation-part.
  50. *
  51. * @param trits Array of size 12. "trits" should be either 0, 1 or 2, where 2 indicaties "float"
  52. */
  53. void sendTelegram(unsigned short trits[]);
  54. /**
  55. * Send a telegram, including synchronisation-part. The data-param encodes the period duration, number of repeats and the actual data.
  56. * Note: static method, which allows for use in low-mem situations.
  57. *
  58. * Format data:
  59. * pppppppp|prrrdddd|dddddddd|dddddddd (32 bit)
  60. * p = perioud (9 bit unsigned int
  61. * r = repeats as 2log. Thus, if r = 3, then signal is sent 2^3=8 times
  62. * d = data
  63. *
  64. * @param data data, period and repeats.
  65. * @param pin Pin number of the transmitter.
  66. */
  67. static void sendTelegram(unsigned long data, unsigned short pin);
  68. /**
  69. * Compares the data received with RemoteReceive with the data obtained by one of the getTelegram-functions.
  70. * Period duration and repetitions are ignored by this function; only the data-payload is compared.
  71. *
  72. * @return true, if the codes are identical (the 20 least significant bits match)
  73. */
  74. static boolean isSameCode(unsigned long encodedTelegram, unsigned long receivedData);
  75. protected:
  76. unsigned short _pin; //Radio output pin
  77. unsigned int _periodusec; //oscillator period in microseconds
  78. unsigned short _repeats; //Number over repetitions of one telegram
  79. };
  80. /**
  81. * ActionSwitch simulatos a remote, as sold in the Dutch 'Action' stores. But there are many similar systems on the market.
  82. * If your remote has setting for 5 address bits, and can control 5 devices on or off, then you can try to use the ActionSwitch
  83. */
  84. class ActionSwitch: RemoteSwitch {
  85. public:
  86. /**
  87. * Constructor
  88. *
  89. * @param pin output pin on Arduino to which the transmitter is connected
  90. * @param periodsec Duration of one period, in microseconds. Default is 190usec
  91. * @see RemoteSwitch
  92. */
  93. ActionSwitch(unsigned short pin, unsigned int periodusec=190);
  94. /**
  95. * Send a on or off signal to a device.
  96. *
  97. * @param systemCode 5-bit addres (dip switches in remote). Range [0..31]
  98. * @param device Device to switch. Range: [A..E] (case sensitive!)
  99. * @param on True, to switch on. False to switch off,
  100. */
  101. void sendSignal(unsigned short systemCode, char device, boolean on);
  102. /**
  103. * Generates the telegram (data) which can be used for RemoteSwitch::sendTelegram.
  104. * See sendSignal for details on the parameters
  105. *
  106. * @return Encoded data, including repeats and period duration.
  107. */
  108. unsigned long getTelegram(unsigned short systemCode, char device, boolean on);
  109. };
  110. /**
  111. * BlokkerSwitch simulatos a remote, as sold in the Dutch 'Blokker' stores. But there are many similar systems on the market.
  112. * These remotes have 4 on, 4 off buttons and a switch to switch between device 1-4 and 5-8. No futher configuration
  113. * possible.
  114. */
  115. class BlokkerSwitch: RemoteSwitch {
  116. public:
  117. /**
  118. * Constructor
  119. *
  120. * @param pin output pin on Arduino to which the transmitter is connected
  121. * @param periodsec Duration of one period, in microseconds. Default is 307usec
  122. * @see RemoteSwitch
  123. */
  124. BlokkerSwitch(unsigned short pin, unsigned int periodusec=230);
  125. /**
  126. * Send a on or off signal to a device.
  127. *
  128. * @param device Device to switch. Range: [1..8]
  129. * @param on True, to switch on. False to switch off,
  130. */
  131. void sendSignal(unsigned short device, boolean on);
  132. /**
  133. * @see RemoteSwitch::getTelegram
  134. */
  135. unsigned long getTelegram(unsigned short device, boolean on);
  136. };
  137. /**
  138. * KaKuSwitch simulates a KlikAanKlikUit-remote, but there are many clones.
  139. * If your transmitter has a address dial with the characters A till P, you can try this class.
  140. */
  141. class KaKuSwitch: RemoteSwitch {
  142. public:
  143. /**
  144. * Constructor
  145. *
  146. * @param pin output pin on Arduino to which the transmitter is connected
  147. * @param periodsec Duration of one period, in microseconds. Default is 375usec
  148. * @see RemoteSwitch
  149. */
  150. KaKuSwitch(unsigned short pin, unsigned int periodusec=375);
  151. /**
  152. * Send a on or off signal to a device.
  153. *
  154. * @param address addres (dial switches in remote). Range [A..P] (case sensitive!)
  155. * @param group Group to switch. Range: [1..4]
  156. * @param device Device to switch. Range: [1..4]
  157. * @param on True, to switch on. False to switch off,
  158. */
  159. void sendSignal(char address, unsigned short group, unsigned short device, boolean on);
  160. /**
  161. * Send a on or off signal to a device.
  162. *
  163. * @param address addres (dip switches in remote). Range [A..P] (case sensitive!)
  164. * @param device device (dial switches in remote). Range [1..16]
  165. * @param on True, to switch on. False to switch off,
  166. */
  167. void sendSignal(char address, unsigned short device, boolean on);
  168. /**
  169. * @see RemoteSwitch::getTelegram
  170. */
  171. unsigned long getTelegram(char address, unsigned short group, unsigned short device, boolean on);
  172. /**
  173. * @see RemoteSwitch::getTelegram
  174. */
  175. unsigned long getTelegram(char address, unsigned short device, boolean on);
  176. };
  177. #endif