]> vault307.fbx.one Git - micorpython_ir.git/blob - README.md
TX and RX support NEC, RC5 and RC6 mode 0.
[micorpython_ir.git] / README.md
1 # Device drivers for IR (infra red) remote controls
2
3 This repo provides a driver to receive from IR (infra red) remote controls and
4 a driver for IR "blaster" apps. The device drivers are nonblocking. They do not
5 require `uasyncio` but are compatible with it.
6
7 # 1. IR communication
8
9 IR communication uses a carrier frequency to pulse the IR source. Modulation
10 takes the form of OOK (on-off keying). There are multiple protocols and at
11 least two options for carrier frequency, namely 36KHz and 38KHz.
12
13 The drivers support the NEC protocol and two Philips protocols, namely RC-5 and
14 RC-6 mode 0. In the case of the transmitter the carrier frequency is a runtime
15 parameter: any value may be specified. The receiver uses a hardware demodulator
16 which must be specified for the correct frequency. The receiver device driver
17 sees the demodulated signal and is hence carrier frequency agnostic.
18
19 Examining waveforms from various remote controls it is evident that numerous
20 protocols exist. Some are doubtless proprietary and undocumented. The supported
21 protocols are those for which I managed to locate documentation. My preference
22 is for the NEC version. It has conservative timing and ample scope for error
23 detection. RC-5 has limited error detection, and RC-6 mode 0 has rather fast
24 timing: I doubt that detection can be accomplished on targets slower than a
25 Pyboard.
26
27 A remote using the NEC protocol is [this one](https://www.adafruit.com/products/389).
28
29 Remotes normally transmit an address and a data byte. The address denotes the
30 physical device being controlled. The data is associated with the button on the
31 remote. Provision exists for differentiating between a button repeatedly
32 pressed and one which is held down; the mechanism is protocol dependent.
33
34 # 2. Hardware Requirements
35
36 The receiver is cross-platform. It requires an IR receiver chip to demodulate
37 the carrier. The chip must be selected for the frequency in use by the remote.
38 For 38KHz devices a receiver chip such as the Vishay TSOP4838 or the
39 [adafruit one](https://www.adafruit.com/products/157) is required. This
40 demodulates the 38KHz IR pulses and passes the demodulated pulse train to the
41 microcontroller. The tested chip returns a 0 level on carrier detect, but the
42 driver design should ensure operation regardless of sense.
43
44 The pin used to connect the decoder chip to the target is arbitrary but the
45 test programs assume pin X3 on the Pyboard, pin 13 on the ESP8266 and pin 23 on
46 ESP32.
47
48 The transmitter requires a Pyboard 1.x (not Lite) or a Pyboard D. Output is via
49 an IR LED which will normally need a transistor to provide sufficient current.
50 Typically these need 50-100mA of drive to achieve reasonable range and data
51 integrity. A suitable LED is [this one](https://www.adafruit.com/product/387).
52
53 The transmitter test script assumes pin X1 for IR output. It can be changed,
54 but it must support Timer 2 channel 1. Pins for pushbutton inputs are
55 arbitrary: X3 and X4 are used.
56
57 # 3. Installation
58
59 On import, demos print an explanation of how to run them.
60
61 ## 3.1 Receiver
62
63 Copy the following files to the target filesystem:
64 1. `ir_rx.py` The receiver device driver.
65 2. `ir_rx_test.py` Demo of a receiver.
66
67 There are no dependencies.
68
69 The demo can be used to characterise IR remotes. It displays the codes returned
70 by each button. This can aid in the design of receiver applications. When the
71 demo runs, the REPL prompt reappears: this is because it sets up an ISR context
72 and returns. Press `ctrl-d` to cancel it. A real application would run code
73 after initialising reception so this behaviour would not occur.
74
75 ## 3.2 Transmitter
76
77 Copy the following files to the Pyboard filesystem:
78 1. `ir_tx.py` The transmitter device driver.
79 2. `ir_tx_test.py` Demo of a 2-button remote controller.
80
81 The device driver has no dependencies. The test program requires `uasyncio`
82 from the official library and `aswitch.py` from
83 [this repo](https://github.com/peterhinch/micropython-async).
84
85 # 4. Receiver
86
87 This implements a class for each supported protocol, namely `NEC_IR`, `RC5_IR`
88 and `RC6_M0`. Applications should instantiate the appropriate class with a
89 callback. The callback will run whenever an IR pulsetrain is received.
90
91 Constructor:
92 `NEC_IR` args: `pin`, `callback`, `extended=True`, `*args`
93 `RC5_IR` and `RC6_M0`: args `pin`, `callback`, `*args`
94 Args:
95 1. `pin` is a `machine.Pin` instance configured as an input, connected to the
96 IR decoder chip.
97 2. `callback` is the user supplied callback (see below).
98 3. `extended` is an NEC specific boolean. Remotes using the NEC protocol can
99 send 8 or 16 bit addresses. If `True` 16 bit addresses are assumed - an 8 bit
100 address will be correctly received. Set `False` to enable extra error checking
101 for remotes that return an 8 bit address.
102 4. `*args` Any further args will be passed to the callback.
103
104 The callback takes the following args:
105 1. `data` Integer value fom the remote. A negative value indicates an error
106 except for the value of -1 which signifies an NEC repeat code (see below).
107 2. `addr` Address from the remote
108 3. `ctrl` 0 in the case of NEC. Philips protocols toggle this bit on repeat
109 button presses. If the button is held down the bit is not toggled. The
110 transmitter demo implements this behaviour.
111 4. Any args passed to the constructor.
112
113 Class variable:
114 1. `verbose=False` If `True` emits debug output.
115
116 # 4.1 Errors
117
118 IR reception is inevitably subject to errors, notably if the remote is operated
119 near the limit of its range, if it is not pointed at the receiver or if its
120 batteries are low. So applications must check for, and usually ignore, errors.
121 These are flagged by data values < `REPEAT` (-1).
122
123 On the ESP8266 there is a further source of errors. This results from the large
124 and variable interrupt latency of the device which can exceed the pulse
125 duration. This causes pulses to be missed. This tendency is slightly reduced by
126 running the chip at 160MHz.
127
128 In general applications should provide user feedback of correct reception.
129 Users tend to press the key again if the expected action is absent.
130
131 Data values passed to the callback are normally positive. Negative values
132 indicate a repeat code or an error.
133
134 `REPEAT` A repeat code was received.
135
136 Any data value < `REPEAT` denotes an error. In general applications do not
137 need to decode these, but they may be of use in debugging. For completeness
138 they are listed below.
139
140 `BADSTART` A short (<= 4ms) start pulse was received. May occur due to IR
141 interference, e.g. from fluorescent lights. The TSOP4838 is prone to producing
142 200µs pulses on occasion, especially when using the ESP8266.
143 `BADBLOCK` A normal data block: too few edges received. Occurs on the ESP8266
144 owing to high interrupt latency.
145 `BADREP` A repeat block: an incorrect number of edges were received.
146 `OVERRUN` A normal data block: too many edges received.
147 `BADDATA` Data did not match check byte.
148 `BADADDR` Where `extended` is `False` the 8-bit address is checked
149 against the check byte. This code is returned on failure.
150
151 # 4.2 Receiver platforms
152
153 The NEC protocol has been tested against Pyboard, ESP8266 and ESP32 targets.
154 The Philips protocols - especially RC-6 - have tighter timing constraints. I
155 have not yet tested these, but I anticipate problems.
156
157 # 4.3 Principle of operation
158
159 Protocol classes inherit from the abstract base class `IR_RX`. This uses a pin
160 interrupt to store in an array the start and end times of pulses (in μs).
161 Arrival of the first pulse triggers a software timer which runs for the
162 expected duration of an IR block (`tblock`). When it times out its callback
163 (`.decode`) decodes the data and calls the user callback. The use of a software
164 timer ensures that `.decode` and the user callback can allocate.
165
166 The size of the array and the duration of the timer are protocol dependent and
167 are set by the subclasses. The `.decode` method is provided in the subclass.
168
169 CPU times used by `.decode` (not including the user callback) were measured on
170 a Pyboard D SF2W at stock frequency. They were NEC 1ms for normal data, 100μs
171 for a repeat code. Philips codes: RC-5 900μs, RC-6 mode 0 5.5ms.
172
173 # 5 Transmitter
174
175 This is specific to Pyboard D and Pyboard 1.x (not Lite).
176
177 It implements a class for each supported protocol, namely `NEC`, `RC5` and
178 `RC6_M0`. The application instantiates the appropriate class and calls the
179 `transmit` method to send data.
180
181 Constructor
182 All constructors take the following args:
183 1. `pin` An initialised `pyb.Pin` instance supporting Timer 2 channel 1: `X1`
184 is employed by the test script. Must be connected to the IR diode as described
185 below.
186 2. `freq=default` The carrier frequency in Hz. The default for NEC is 38000,
187 and for Philips is 36000.
188 3. `verbose=False` If `True` emits debug output.
189
190 Method:
191 1. `transmit(addr, data, toggle=0)` Integer args. `addr` and `data` are
192 normally 8-bit values and `toggle` is 0 or 1.
193 In the case of NEC, if an address < 256 is passed, normal mode is assumed and
194 the complementary value is appended. 16-bit values are transmitted as extended
195 addresses.
196 In the case of NEC the `toggle` value is ignored. For Philips protocols it
197 should be toggled each time a button is pressed, and retained if the button is
198 held down. The test program illustrates a way to do this.
199
200 The `transmit` method is synchronous with rapid return. Actual transmission
201 occurs as a background process, controlled by timers 2 and 5. Execution times
202 on a Pyboard 1.1 were 3.3ms for NEC, 1.5ms for RC5 and 2ms for RC6.
203
204 # 5.1 Wiring
205
206 I use the following circuit which delivers just under 40mA to the diode. R2 may
207 be reduced for higher current.
208 ![Image](images/circuit.png)
209
210 This alternative delivers a constant current of about 53mA if a higher voltage
211 than 5V is available. R4 determines the current value and may be reduced to
212 increase power.
213 ![Image](images/circuit2.png)
214
215 The transistor type is not critical.
216
217 These circuits assume circuits as shown. Here the carrier "off" state is 0V,
218 which is the driver default. If using a circuit where "off" is required to be
219 3.3V, the constant `_SPACE` in `ir_tx.py` should be changed to 100.
220
221 # 5.2 Principle of operation
222
223 The classes inherit from the abstract base class `IR`. This has an array `.arr`
224 to contain the duration (in μs) of each carrier on or off period. The
225 `transmit` method calls a `tx` method in the subclass which populates this
226 array. On completion `transmit` appends a special `STOP` value and initiates
227 physical transmission which occurs in an interrupt context.
228
229 This is performed by two hardware timers initiated in the constructor. Timer 2,
230 channel 1 is used to configure the output pin as a PWM channel. Its frequency
231 is set in the constructor. The OOK is performed by dynamically changing the
232 duty ratio using the timer channel's `pulse_width_percent` method: this varies
233 the pulse width from 0 to a duty ratio passed to the constructor. The NEC
234 protocol defaults to 50%, the Philips ones to 30%.
235
236 The duty ratio is changed by the Timer 5 callback `._cb`. This retrieves the
237 next duration from the array. If it is not `STOP` it toggles the duty cycle
238 and re-initialises T5 for the new duration.
239
240 The `IR.append` enables times to be added to the array, keeping track of the
241 notional carrier on/off state for biphase generation. The `IR.add` method
242 facilitates lengthening a pulse as required in the biphase sequences used in
243 Philips protocols.
244
245 # 6. References
246
247 The NEC protocol is described in these references:
248 [altium](http://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol)
249 [circuitvalley](http://www.circuitvalley.com/2013/09/nec-protocol-ir-infrared-remote-control.html)
250
251 The Philips protocols may be found in these refs:
252 [RC5](https://en.wikipedia.org/wiki/RC-5)
253 [RC6](https://www.sbprojects.net/knowledge/ir/rc6.php)
254
255 # Appendix 1 NEC Protocol description
256
257 A normal burst comprises exactly 68 edges, the exception being a repeat code
258 which has 4. An incorrect number of edges is treated as an error. All bursts
259 begin with a 9ms pulse. In a normal code this is followed by a 4.5ms space; a
260 repeat code is identified by a 2.25ms space. A data burst lasts for 67.5ms.
261
262 Data bits comprise a 562.5µs mark followed by a space whose length determines
263 the bit value. 562.5µs denotes 0 and 1.6875ms denotes 1.
264
265 In 8 bit address mode the complement of the address and data values is sent to
266 provide error checking. This also ensures that the number of 1's and 0's in a
267 burst is constant, giving a constant burst length of 67.5ms. In extended
268 address mode this constancy is lost. The burst length can (by my calculations)
269 run to 76.5ms.
270
271 A pin interrupt records the time of every state change (in µs). The first
272 interrupt in a burst sets an event, passing the time of the state change. A
273 coroutine waits on the event, yields for the duration of a data burst, then
274 decodes the stored data before calling the user-specified callback.
275
276 Passing the time to the `Event` instance enables the coro to compensate for
277 any asyncio latency when setting its delay period.
278
279 The algorithm promotes interrupt handler speed over RAM use: the 276 bytes used
280 for the data array could be reduced to 69 bytes by computing and saving deltas
281 in the interrupt service routine.