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