X-Git-Url: https://vault307.fbx.one/gitweb/micorpython_ir.git/blobdiff_plain/c1af37a9947002e9a95813966750b72871a2f4f0..1c76b13fbbd3284fdc007f8aca140724469e1367:/README.md diff --git a/README.md b/README.md index d90a74f..58cbc9e 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,23 @@ This repo provides a driver to receive from IR (infra red) remote controls and a driver for IR "blaster" apps. The device drivers are nonblocking. They do not require `uasyncio` but are compatible with it. +NOTE: The receiver is intended to be cross-platform. In testing it has proved +problematic on ESP8266. The cause is +[this firmware issue](https://github.com/micropython/micropython/issues/5714) +which should be fixed in due course. + # 1. IR communication IR communication uses a carrier frequency to pulse the IR source. Modulation takes the form of OOK (on-off keying). There are multiple protocols and at -least two options for carrier frequency, namely 36KHz and 38KHz. +least three options for carrier frequency, namely 36KHz, 38KHz and 40KHz. -The drivers support the NEC protocol and two Philips protocols, namely RC-5 and -RC-6 mode 0. In the case of the transmitter the carrier frequency is a runtime -parameter: any value may be specified. The receiver uses a hardware demodulator -which must be specified for the correct frequency. The receiver device driver -sees the demodulated signal and is hence carrier frequency agnostic. +The drivers support NEC and Sony protocols and two Philips protocols, namely +RC-5 and RC-6 mode 0. In the case of the transmitter the carrier frequency is a +runtime parameter: any value may be specified. The receiver uses a hardware +demodulator which should be specified for the correct frequency. The receiver +device driver sees the demodulated signal and is hence carrier frequency +agnostic. Examining waveforms from various remote controls it is evident that numerous protocols exist. Some are doubtless proprietary and undocumented. The supported @@ -26,10 +32,11 @@ Pyboard. A remote using the NEC protocol is [this one](https://www.adafruit.com/products/389). -Remotes normally transmit an address and a data byte. The address denotes the -physical device being controlled. The data is associated with the button on the -remote. Provision exists for differentiating between a button repeatedly -pressed and one which is held down; the mechanism is protocol dependent. +Remotes transmit an address and a data byte, plus in some cases an extra value. +The address denotes the physical device being controlled. The data defines the +button on the remote. Provision usually exists for differentiating between a +button repeatedly pressed and one which is held down; the mechanism is protocol +dependent. # 2. Hardware Requirements @@ -39,11 +46,14 @@ For 38KHz devices a receiver chip such as the Vishay TSOP4838 or the [adafruit one](https://www.adafruit.com/products/157) is required. This demodulates the 38KHz IR pulses and passes the demodulated pulse train to the microcontroller. The tested chip returns a 0 level on carrier detect, but the -driver design should ensure operation regardless of sense. +driver design ensures operation regardless of sense. + +In my testing a 38KHz demodulator worked with 36KHz and 40KHz remotes, but this +is obviously neither guaranteed nor optimal. -The pin used to connect the decoder chip to the target is arbitrary but the -test programs assume pin X3 on the Pyboard, pin 13 on the ESP8266 and pin 23 on -ESP32. +The pin used to connect the decoder chip to the target is arbitrary. The test +program assumes pin X3 on the Pyboard, pin 23 on ESP32 and pin 13 on ESP8266. +On the WeMos D1 Mini the equivalent pin is D7. The transmitter requires a Pyboard 1.x (not Lite) or a Pyboard D. Output is via an IR LED which will normally need a transistor to provide sufficient current. @@ -67,10 +77,8 @@ Copy the following files to the target filesystem: There are no dependencies. The demo can be used to characterise IR remotes. It displays the codes returned -by each button. This can aid in the design of receiver applications. When the -demo runs, the REPL prompt reappears: this is because it sets up an ISR context -and returns. Press `ctrl-d` to cancel it. A real application would run code -after initialising reception so this behaviour would not occur. +by each button. This can aid in the design of receiver applications. The demo +prints "running" every 5 seconds and reports any data received from the remote. ## 3.2 Transmitter @@ -84,22 +92,34 @@ from the official library and `aswitch.py` from # 4. Receiver -This implements a class for each supported protocol, namely `NEC_IR`, `RC5_IR` -and `RC6_M0`. Applications should instantiate the appropriate class with a -callback. The callback will run whenever an IR pulsetrain is received. +This implements a class for each supported protocol, namely `NEC_IR`, +`SONY_IR`, `RC5_IR` and `RC6_M0`. Applications should instantiate the +appropriate class with a callback. The callback will run whenever an IR pulse +train is received. Constructor: `NEC_IR` args: `pin`, `callback`, `extended=True`, `*args` +`SONY_IR` args: `pin`, `callback`, `bits=20`, `*args` `RC5_IR` and `RC6_M0`: args `pin`, `callback`, `*args` -Args: + +Args (all protocols): 1. `pin` is a `machine.Pin` instance configured as an input, connected to the IR decoder chip. 2. `callback` is the user supplied callback (see below). - 3. `extended` is an NEC specific boolean. Remotes using the NEC protocol can + 4. `*args` Any further args will be passed to the callback. + +Protocol specific args: + 1. `extended` is an NEC specific boolean. Remotes using the NEC protocol can send 8 or 16 bit addresses. If `True` 16 bit addresses are assumed - an 8 bit address will be correctly received. Set `False` to enable extra error checking for remotes that return an 8 bit address. - 4. `*args` Any further args will be passed to the callback. + 2. `bits=20` Sony specific. The SIRC protocol comes in 3 variants: 12, 15 and + 20 bits. The default will handle bitstreams from all three types of remote. A + value matching your remote improves the timing and reduces the likelihood of + errors when handling repeats: in 20-bit mode SIRC timing when a button is held + down is tight. A worst-case 20-bit block takes 39ms nominal, yet the repeat + time is 45ms nominal. On ESP32 20-bit mode did not work well. + The Sony remote tested issues both 12 bit and 15 bit streams. The callback takes the following args: 1. `data` Integer value fom the remote. A negative value indicates an error @@ -107,7 +127,9 @@ The callback takes the following args: 2. `addr` Address from the remote 3. `ctrl` 0 in the case of NEC. Philips protocols toggle this bit on repeat button presses. If the button is held down the bit is not toggled. The - transmitter demo implements this behaviour. + transmitter demo implements this behaviour. + In the case of Sony the value will be 0 unless receiving a 20-bit stream, in + which case it will hold the extended value. 4. Any args passed to the constructor. Class variable: @@ -128,7 +150,7 @@ running the chip at 160MHz. In general applications should provide user feedback of correct reception. Users tend to press the key again if the expected action is absent. -Data values passed to the callback are normally positive. Negative values +Data values passed to the callback are zero or positive. Negative values indicate a repeat code or an error. `REPEAT` A repeat code was received. @@ -151,8 +173,14 @@ against the check byte. This code is returned on failure. # 4.2 Receiver platforms The NEC protocol has been tested against Pyboard, ESP8266 and ESP32 targets. -The Philips protocols - especially RC-6 - have tighter timing constraints. I -have not yet tested these, but I anticipate problems. +The Philips protocols - especially RC-6 - have tighter timing constraints. +Currently the ESP8266 suffers from [this issue](https://github.com/micropython/micropython/issues/5714) +which prevented testing. + +All modes work on the Pyboard. On ESP32 NEC mode works. Sony works for lengths +of 12 and 15 bits, but 20 bit mode was not reliable owing to the rate at which +repeats are transmitted. Philips RC-5 worked, with some "bad block" messages. +Work is ongoing to characterise ESP32 and ESP8266. # 4.3 Principle of operation @@ -167,15 +195,15 @@ The size of the array and the duration of the timer are protocol dependent and are set by the subclasses. The `.decode` method is provided in the subclass. CPU times used by `.decode` (not including the user callback) were measured on -a Pyboard D SF2W at stock frequency. They were NEC 1ms for normal data, 100μs +a Pyboard D SF2W at stock frequency. They were: NEC 1ms for normal data, 100μs for a repeat code. Philips codes: RC-5 900μs, RC-6 mode 0 5.5ms. # 5 Transmitter This is specific to Pyboard D and Pyboard 1.x (not Lite). -It implements a class for each supported protocol, namely `NEC`, `RC5` and -`RC6_M0`. The application instantiates the appropriate class and calls the +It implements a class for each supported protocol, namely `NEC`, `SONY`, `RC5` +and `RC6_M0`. The application instantiates the appropriate class and calls the `transmit` method to send data. Constructor @@ -184,18 +212,24 @@ All constructors take the following args: is employed by the test script. Must be connected to the IR diode as described below. 2. `freq=default` The carrier frequency in Hz. The default for NEC is 38000, - and for Philips is 36000. + Sony is 40000 and Philips is 36000. 3. `verbose=False` If `True` emits debug output. +The `SONY` constructor is of form `pin, bits=12, freq=40000, verbose=False`. +The `bits` value may be 12, 15 or 20 to set SIRC variant in use. Other args are +as above. + Method: 1. `transmit(addr, data, toggle=0)` Integer args. `addr` and `data` are - normally 8-bit values and `toggle` is 0 or 1. + normally 8-bit values and `toggle` is normally 0 or 1. In the case of NEC, if an address < 256 is passed, normal mode is assumed and the complementary value is appended. 16-bit values are transmitted as extended addresses. In the case of NEC the `toggle` value is ignored. For Philips protocols it should be toggled each time a button is pressed, and retained if the button is - held down. The test program illustrates a way to do this. + held down. The test program illustrates a way to do this. + `SONY` ignores `toggle` unless in 20-bit mode, in which case it is transmitted + as the `extended` value and can be any integer in range 0 to 255. The `transmit` method is synchronous with rapid return. Actual transmission occurs as a background process, controlled by timers 2 and 5. Execution times @@ -214,7 +248,7 @@ increase power. The transistor type is not critical. -These circuits assume circuits as shown. Here the carrier "off" state is 0V, +The driver assumes circuits as shown. Here the carrier "off" state is 0V, which is the driver default. If using a circuit where "off" is required to be 3.3V, the constant `_SPACE` in `ir_tx.py` should be changed to 100. @@ -222,7 +256,7 @@ which is the driver default. If using a circuit where "off" is required to be The classes inherit from the abstract base class `IR`. This has an array `.arr` to contain the duration (in μs) of each carrier on or off period. The -`transmit` method calls a `tx` method in the subclass which populates this +`transmit` method calls a `tx` method of the subclass which populates this array. On completion `transmit` appends a special `STOP` value and initiates physical transmission which occurs in an interrupt context. @@ -231,7 +265,7 @@ channel 1 is used to configure the output pin as a PWM channel. Its frequency is set in the constructor. The OOK is performed by dynamically changing the duty ratio using the timer channel's `pulse_width_percent` method: this varies the pulse width from 0 to a duty ratio passed to the constructor. The NEC -protocol defaults to 50%, the Philips ones to 30%. +protocol defaults to 50%, the Sony and Philips ones to 30%. The duty ratio is changed by the Timer 5 callback `._cb`. This retrieves the next duration from the array. If it is not `STOP` it toggles the duty cycle @@ -244,15 +278,17 @@ Philips protocols. # 6. References -The NEC protocol is described in these references: +[General information about IR](https://www.sbprojects.net/knowledge/ir/) + +The NEC protocol: [altium](http://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol) [circuitvalley](http://www.circuitvalley.com/2013/09/nec-protocol-ir-infrared-remote-control.html) -The Philips protocols may be found in these refs: +Philips protocols: [RC5](https://en.wikipedia.org/wiki/RC-5) [RC6](https://www.sbprojects.net/knowledge/ir/rc6.php) -Sony protocol (future use): +Sony protocol: [SIRC](https://www.sbprojects.net/knowledge/ir/sirc.php) # Appendix 1 NEC Protocol description