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