{"id":13894035,"url":"https://github.com/mathertel/rfcodes","last_synced_at":"2025-03-19T11:30:33.167Z","repository":{"id":49765440,"uuid":"127648661","full_name":"mathertel/rfcodes","owner":"mathertel","description":"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.","archived":false,"fork":false,"pushed_at":"2023-04-26T19:12:11.000Z","size":147,"stargazers_count":35,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-17T06:35:30.877Z","etag":null,"topics":["arduino","arduino-library","protocols","rf-signal","rf433"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mathertel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-01T16:22:29.000Z","updated_at":"2025-02-27T02:55:39.000Z","dependencies_parsed_at":"2024-10-27T20:31:42.028Z","dependency_job_id":"4b726b00-76b7-4806-8bf0-e68d2342554f","html_url":"https://github.com/mathertel/rfcodes","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathertel%2Frfcodes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathertel%2Frfcodes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathertel%2Frfcodes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathertel%2Frfcodes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mathertel","download_url":"https://codeload.github.com/mathertel/rfcodes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244416818,"owners_count":20449345,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","arduino-library","protocols","rf-signal","rf433"],"created_at":"2024-08-06T18:01:22.192Z","updated_at":"2025-03-19T11:30:33.160Z","avatar_url":"https://github.com/mathertel.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# RFCodes library\r\n\r\nThis is a library that can encode and decode signals patterns that are used in the 433 MHz and IR technology.\r\n\r\nThese signals use a carrier frequency (433MHz or 44kHz) that is switched on and off using a defined pattern.\r\n\r\nEach 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.\r\n\r\nThere 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.\r\nSo any code sequence corresponds to a textual representation like `it2 s_##___#____#_#__###_____#__#____x`\r\n\r\n## Use the library\r\n\r\nUsing the library requires the following steps:\r\n\r\n* A set of protocol definitions that you expect that they are used.\r\n* A pin where the inbound signal comes in (receiver)\r\n* A pin where the outbound signal can be send (sender)\r\n* A function that gets called when a code was decoded.\r\n\r\nFor the receiver role the library uses a interrupt routine that gets called when ever a signal change on the pin has been detected.\r\nSome microprocessors support only specific pins with interrupts\r\nso please look up the documentation for **Arduino attachInterrupt()** function for the processor.\r\n\r\nSending a protocol uses no interrupts but also should not be interrupted by another ISR routine.\r\n\r\n## The Wiring\r\n\r\nA interrupt capable pin can be used to attach a receiver. e.g. D5 on a ESP8266 board.\r\n\r\nAnother pin can be used to attach a transmitter e.g. D6 on a ESP8266 board.\r\n\r\nBoth, receiver and transmitter must be connected to VCC and GND.\r\nBest option is to use variants that can be used with 3.3V when using a ESP8266.\r\n\r\n```TXT\r\n     3.3V ---------------- 3.3V --------------- 3.3V\r\n      |                     |                    |  \r\n+-----+-----+         +-----+-----+         +----+------+\r\n| RF433     |         | ESP8266   |         | RF433     |\r\n| receiver  +----\u003e D5-+ board     +-D6 ----\u003e+ sender    |  \r\n| module    |         |           |         | module    |\r\n+-----+-----+         +-----+-----+         +----+------+\r\n      |                     |                    |  \r\n     GND ----------------- GND ---------------- GND\r\n```\r\n\r\nThe 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.\r\nThe 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.\r\n\r\nThe 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.\r\n\r\n## Examples\r\n\r\nThe following examples sketches are available:\r\n\r\n* The [Intertechno](./examples/intertechno/README.md) example shows how to register and use\r\n    the 2 protocols used by devices from intertechno.\r\n\r\n* The [TempSensor](./examples/TempSensor/README.md) example shows how to receive temperature+humidity\r\n  from a cresta protocol based sensor.\r\n\r\n* The [necIR](./examples/necIR/README.md) example shows how to receive and send the Infrared NEC protocol.\r\n\r\n* The [Scanner](./examples/scanner/README.md) example can be used to collect code timings for further analysis.\r\n\r\n## Protocol definitions\r\n\r\nHere are some hints on how to configure a protocol:\r\n\r\nIn the protocol structure the (short) name of the protocol and some\r\nsettings must be defined:\r\n\r\n* **name** - a short name of the protocol.\r\n* **minCodeLen** - the minimum length of a code sequence including all start, data and end codes.\r\n* **maxCodeLen** - the maximum length of a code sequence including all start, data and end codes.\r\n* **tolerance** - codes are not sent and not captured using very precise timings. The tolerance defines the percentage the timing may derive.\r\n* **sendRepeat** - When sending the code the sequence should be repeated as specified by the sendRepeat parameter.\r\n* **baseTime** - Many protocols use a base clock time. This should be specified in the baseTime parameter and the factors in the code.\r\n* **codes** -  The list of codes in this protocol.\r\n\r\nIn the code definitions the typical timing patterns are defined.\r\n\r\n* **type** - The code type defines the role of this code in the sequence.\r\n\r\n  * A **start code** is defined to recognize that a protocol is send out as it is sent at the beginning only.\r\n    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.\r\n    As the following codes often have shorter timings so a\r\n    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.\r\n\r\n  * Multiple **data codes** are defined to represent data bits.\r\n    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.\r\n\r\n  * A **end code** marks the end of a sequence.\r\n    This is useful for protocols that have a variable length of data.\r\n    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.\r\n\r\n  * 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.\r\n    Some protocols just end after a number of codes.\r\n\r\n* **name** - The single character representing a code in the sequence.\r\nIt must be unique within the protocol.\r\n\r\n* **durations** - The list of durations that represent the code.\r\n\r\n### Protocol Example\r\n\r\nThe code used by the SC5272 chip is named \"sc5\", has 3 data codes ('0', '1' and 'f') and a stop code ('S') defined.\r\nSo the textual representation may be \"[sc5 0000f0000fffS]\"\r\n\r\nThe chip can be used with different clock speeds so the baseTime can be adjusted to fit the speed of your device.\r\n\r\n```CPP\r\n/** Definition of the protocol from SC5272 and similar chips with 32 - 46 data bits data */\r\nSignalParser::Protocol sc5 = {\r\n    \"sc5\",\r\n    .minCodeLen = 1 + 12,\r\n    .maxCodeLen = 1 + 12,\r\n\r\n    .tolerance = 25,\r\n    .sendRepeat = 3,\r\n    .baseTime = 100,\r\n    .codes = {\r\n        {SignalParser::CodeType::ANYDATA, '0', {4, 12, 4, 12}},\r\n        {SignalParser::CodeType::ANYDATA, '1', {12, 4, 12, 4}},\r\n        {SignalParser::CodeType::ANYDATA, 'f', {4, 12, 12, 4}},\r\n        {SignalParser::CodeType::END, 'S', {4, 124}}}};\r\n```\r\n\r\nThis 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.\r\n\r\n## Implementation\r\n\r\nThere are 2 classes combined here:\r\n\r\n**SignalParser**\r\n\r\nThe `SignalParser` is a general usable class that knows all about the timing of codes in the protocol\r\nand knows how to decode and encode them.\r\n\r\nThis class can take pulse/gap durations give to the `parse()` method and uses the registered protocol definitions\r\nto detect a full protocol sequence using valid codes.\r\nThis allows a flexible usage of the SignalParser to be combined with different signal sources and frequencies\r\nor use the class to test for codes in a given series of durations. (see Example testcodes.ino)\r\n\r\nSince 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.\r\n\r\nWhenever a full sequence is detected from the given durations the callback function is used to pass the sequence over for further processing.\r\n\r\n```CPP\r\nSignalParser sig;\r\n\r\n// load some protocols into the SignalParser\r\nsig.load(\u0026RFCodes::it1);\r\nsig.load(\u0026RFCodes::it2);\r\n\r\n// register the callback function.\r\nsig.attachCallback(receiveCode);\r\n```\r\n\r\n**SignalCollector**\r\n\r\nThe `SignalCollector` class handles interrupt routines and the IO pins.\r\nEvery time when receiving a signal change the duration since the previous change is collected into a buffer.\r\n\r\nThe loop() function must be called from the main loop function to transfer the durations from the buffer into the parser.\r\n\r\nSending a sequence is done by calling the send() function with the protocol name and the codes as a string.\r\n\r\n```CPP\r\nSignalCollector col;\r\n\r\n// initialize the SignalCollector library\r\ncol.init(\u0026sig, D5, D6); // input at pin D5, output at pin D6\r\n\r\n// send a sequence\r\ncol.send(\"it2 s_##___#____#_#__###_____#____#__x\");\r\n```\r\n\r\n## See also\r\n\r\n* [About RF Protocols](/docs/rf433.md)\r\n* [Standard protocols](/docs/SC5272_protocol.md)\r\n* [EV1527 protocol](/docs/ev1527_protocol.md)\r\n* [intertechno protocols](/docs/intertechno_protocol.md)\r\n* [Cresta protocol for sensors](/docs/cresta_protocol.md)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathertel%2Frfcodes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmathertel%2Frfcodes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathertel%2Frfcodes/lists"}