This protocol is widely used. An example remote is this one. To interface the device a receiver chip such as the Vishay TSOP4838 or the adafruit one is required. This demodulates the 38KHz IR pulses and passes the demodulated pulse train to the microcontroller.
The driver and test programs run on the Pyboard and ESP8266.
aremote.py
The device driver.art.py
A test program to characterise a remote.art1.py
Control an onboard LED using a remote. The data and addresss values need changing to match your characterised remote.
The driver requires the uasyncio
library and the file asyn.py
from this
repository.
The pin used to connect the decoder chip to the target is arbitrary but the test programs assume pin X3 on the Pyboard and pin 13 on the ESP8266.
The driver is event driven. Pressing a button on the remote causes a user defined callback to be run. The NEC protocol returns a data value and an address. These are passed to the callback as the first two arguments (further user defined arguments may be supplied). The address is normally constant for a given remote, with the data corresponding to the button. Applications should check the address to ensure that they only respond to the correct remote.
Data values are 8 bit. Addresses may be 8 or 16 bit depending on whether the remote uses extended addressing.
If a button is held down a repeat code is sent. In this event the driver
returns a data value of REPEAT
and the address associated with the last
valid data block.
To characterise a remote run art.py
and note the data value for each button
which is to be used. If the address is less than 256, extended addressing is
not in use.
IR reception is inevitably subject to errors, notably if the remote is operated
near the limit of its range, if it is not pointed at the receiver or if its
batteries are low. So applications must check for, and usually ignore, errors.
These are flagged by data values < REPEAT
.
On the ESP8266 there is a further source of errors. This results from the large and variable interrupt latency of the device which can exceed the pulse duration. This causes pulses to be missed. This tendency is slightly reduced by running the chip at 160MHz.
In general applications should provide user feedback of correct reception. Users tend to press the key again if no acknowledgement is received.
The constructor takes the following positional arguments.
pin
APin
instance for the decoder chip.cb
The user callback function.extended
SetFalse
to enable extra error checking if the remote returns an 8 bit address.- Further arguments, if provided, are passed to the callback.
The callback receives the following positional arguments:
- The data value returned from the remote.
- The address value returned from the remote.
- Any further arguments provided to the
NEC_IR
constructor.
Negative data values are used to signal repeat codes and transmission errors.
The test program art1.py
provides an example of a minimal application.
The NEC protocol is described in these references.
altium
circuitvalley
A normal burst comprises exactly 68 edges, the exception being a repeat code which has 4. An incorrect number of edges is treated as an error. All bursts begin with a 9ms pulse. In a normal code this is followed by a 4.5ms space; a repeat code is identified by a 2.25ms space. A data burst lasts for 67.5ms.
Data bits comprise a 562.5µs mark followed by a space whose length determines the bit value. 562.5µs denotes 0 and 1.6875ms denotes 1.
In 8 bit address mode the complement of the address and data values is sent to provide error checking. This also ensures that the number of 1's and 0's in a burst is constant, giving a constant burst length of 67.5ms. In extended address mode this constancy is lost. The burst length can (by my calculations) run to 76.5ms.
A pin interrupt records the time of every state change (in µs). The first interrupt in a burst sets an event, passing the time of the state change. A coroutine waits on the event, yields for the duration of a data burst, then decodes the stored data before calling the user-specified callback.
Passing the time to the Event
instance enables the coro to compensate for
any asyncio latency when setting its delay period.
The algorithm promotes interrupt handler speed over RAM use: the 276 bytes used for the data array could be reduced to 69 bytes by computing and saving deltas in the interrupt service routine.
Data values passed to the callback are normally positive. Negative values indicate a repeat code or an error.
REPEAT
A repeat code was received.
Any data value < REPEAT
denotes an error. In general applications do not
need to decode these, but they may be of use in debugging. For completeness
they are listed below.
BADSTART
A short (<= 4ms) start pulse was received. May occur due to IR
interference, e.g. from fluorescent lights. The TSOP4838 is prone to producing
200µs pulses on occasion, especially when using the ESP8266.
BADBLOCK
A normal data block: too few edges received. Occurs on the ESP8266
owing to high interrupt latency.
BADREP
A repeat block: an incorrect number of edges were received.
OVERRUN
A normal data block: too many edges received.
BADDATA
Data did not match check byte.
BADADDR
Where extended
is False
the 8-bit address is checked
against the check byte. This code is returned on failure.