Skip to content

This is a RF signal encode and decode library that can be adapted to different protocols by specifying the timing conditions is a table. Can be used with 433 MHz and IR receivers and senders.

License

Notifications You must be signed in to change notification settings

mathertel/rfcodes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RFCodes library

This is a library that can encode and decode signals patterns that are used in the 433 MHz and IR technology.

These signals use a carrier frequency (433MHz or 44kHz) that is switched on and off using a defined pattern.

Each protocol often defined by a device manufacturer or a chip producing company consists of a series of pulses and pauses (codes) with a defined length that have a special semantic.

There is a textual representation for sending and receiving a sequence by specifying the short name of the protocol and the characters specifying the code. For some protocols there is an algorithm defined that compiles the characters into a real value. So any code sequence corresponds to a textual representation like it2 s_##___#____#_#__###_____#__#____x

Use the library

Using the library requires the following steps:

  • A set of protocol definitions that you expect that they are used.
  • A pin where the inbound signal comes in (receiver)
  • A pin where the outbound signal can be send (sender)
  • A function that gets called when a code was decoded.

For the receiver role the library uses a interrupt routine that gets called when ever a signal change on the pin has been detected. Some microprocessors support only specific pins with interrupts so please look up the documentation for Arduino attachInterrupt() function for the processor.

Sending a protocol uses no interrupts but also should not be interrupted by another ISR routine.

The Wiring

A interrupt capable pin can be used to attach a receiver. e.g. D5 on a ESP8266 board.

Another pin can be used to attach a transmitter e.g. D6 on a ESP8266 board.

Both, receiver and transmitter must be connected to VCC and GND. Best option is to use variants that can be used with 3.3V when using a ESP8266.

     3.3V ---------------- 3.3V --------------- 3.3V
      |                     |                    |  
+-----+-----+         +-----+-----+         +----+------+
| RF433     |         | ESP8266   |         | RF433     |
| receiver  +----> D5-+ board     +-D6 ---->+ sender    |  
| module    |         |           |         | module    |
+-----+-----+         +-----+-----+         +----+------+
      |                     |                    |  
     GND ----------------- GND ---------------- GND

The receiver modules that can be used must detect the RF signal and produce a signal when the carrier frequency has been detected. The polarity of the signal is not relevant. The modules I used and found reliable are the type RXB8 and RXB12, both with a ceramic resonator. The RF-5V and XY-MK-5V modules were not reliable in my environment and setup.

The sender modules must produce a carrier frequency on HIGH output. When not transmitting a code the output is LOW so other devices can use the carrier frequency on their own. I used several modules all with ceramic resonators (no adjustable air coils). They seem to be less critical.

Examples

The following examples sketches are available:

  • The Intertechno example shows how to register and use the 2 protocols used by devices from intertechno.

  • The TempSensor example shows how to receive temperature+humidity from a cresta protocol based sensor.

  • The necIR example shows how to receive and send the Infrared NEC protocol.

  • The Scanner example can be used to collect code timings for further analysis.

Protocol definitions

Here are some hints on how to configure a protocol:

In the protocol structure the (short) name of the protocol and some settings must be defined:

  • name - a short name of the protocol.
  • minCodeLen - the minimum length of a code sequence including all start, data and end codes.
  • maxCodeLen - the maximum length of a code sequence including all start, data and end codes.
  • tolerance - codes are not sent and not captured using very precise timings. The tolerance defines the percentage the timing may derive.
  • sendRepeat - When sending the code the sequence should be repeated as specified by the sendRepeat parameter.
  • baseTime - Many protocols use a base clock time. This should be specified in the baseTime parameter and the factors in the code.
  • codes - The list of codes in this protocol.

In the code definitions the typical timing patterns are defined.

  • type - The code type defines the role of this code in the sequence.

    • A start code is defined to recognize that a protocol is send out as it is sent at the beginning only. This can be used to simply wait until such a unique timing can be found. This may be a code with a exceptional duration or a series of durations marking the start of a sequence. As the following codes often have shorter timings so a short pulse and a long pause is part of many protocols to detect other senders transmitting into the pause. A simple way of collision detection.

    • Multiple data codes are defined to represent data bits. For binary protocols one sequence stays for a set bit and another for a cleared bit but you can find also protocols with 3 data codes. Multiple of these codes in a row can then be used to build the protocol data.

    • A end code marks the end of a sequence. This is useful for protocols that have a variable length of data. A code defined with the END flag will always stop the current sequence detection. When the minimum length is not yet given the sequence is not taken as a valid code.

    • Codes with a fixed length are defined using the minimum and maximum length with the length of the sequence. Do use the END flag only when there is a special code defined marking the end. Some protocols just end after a number of codes.

  • name - The single character representing a code in the sequence. It must be unique within the protocol.

  • durations - The list of durations that represent the code.

Protocol Example

The code used by the SC5272 chip is named "sc5", has 3 data codes ('0', '1' and 'f') and a stop code ('S') defined. So the textual representation may be "[sc5 0000f0000fffS]"

The chip can be used with different clock speeds so the baseTime can be adjusted to fit the speed of your device.

/** Definition of the protocol from SC5272 and similar chips with 32 - 46 data bits data */
SignalParser::Protocol sc5 = {
    "sc5",
    .minCodeLen = 1 + 12,
    .maxCodeLen = 1 + 12,

    .tolerance = 25,
    .sendRepeat = 3,
    .baseTime = 100,
    .codes = {
        {SignalParser::CodeType::ANYDATA, '0', {4, 12, 4, 12}},
        {SignalParser::CodeType::ANYDATA, '1', {12, 4, 12, 4}},
        {SignalParser::CodeType::ANYDATA, 'f', {4, 12, 12, 4}},
        {SignalParser::CodeType::END, 'S', {4, 124}}}};

This 3-state protocol is also found using the END code as a start code. When submitting multiple sequences in a row as it is usually done by senders and expected by receivers this protocol is partially equivalent to the it1 protocol.

Implementation

There are 2 classes combined here:

SignalParser

The SignalParser is a general usable class that knows all about the timing of codes in the protocol and knows how to decode and encode them.

This class can take pulse/gap durations give to the parse() method and uses the registered protocol definitions to detect a full protocol sequence using valid codes. This allows a flexible usage of the SignalParser to be combined with different signal sources and frequencies or use the class to test for codes in a given series of durations. (see Example testcodes.ino)

Since the solutions of the manufacturers vary quiet a lot this library can be adapted to different protocols by registering the signal patterns of the protocols using the load method by passing a Protocol+Codes definition.

Whenever a full sequence is detected from the given durations the callback function is used to pass the sequence over for further processing.

SignalParser sig;

// load some protocols into the SignalParser
sig.load(&RFCodes::it1);
sig.load(&RFCodes::it2);

// register the callback function.
sig.attachCallback(receiveCode);

SignalCollector

The SignalCollector class handles interrupt routines and the IO pins. Every time when receiving a signal change the duration since the previous change is collected into a buffer.

The loop() function must be called from the main loop function to transfer the durations from the buffer into the parser.

Sending a sequence is done by calling the send() function with the protocol name and the codes as a string.

SignalCollector col;

// initialize the SignalCollector library
col.init(&sig, D5, D6); // input at pin D5, output at pin D6

// send a sequence
col.send("it2 s_##___#____#_#__###_____#____#__x");

See also

About

This is a RF signal encode and decode library that can be adapted to different protocols by specifying the timing conditions is a table. Can be used with 433 MHz and IR receivers and senders.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published