├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── examples
└── simple
│ └── simple.ino
├── keywords.txt
├── library.properties
└── src
├── NEC_timings.h
├── NecDecoder.h
└── NecEncoder.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/tg-send.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Telegram Message
3 | on:
4 | release:
5 | types: [published]
6 | jobs:
7 | build:
8 | name: Send Message
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: send telegram message on push
12 | uses: appleboy/telegram-action@master
13 | with:
14 | to: ${{ secrets.TELEGRAM_TO }}
15 | token: ${{ secrets.TELEGRAM_TOKEN }}
16 | disable_web_page_preview: true
17 | message: |
18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
19 | ${{ github.event.release.body }}
20 | https://github.com/${{ github.repository }}
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Alex
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/GyverLibs/NecDecoder/releases/latest/download/NecDecoder.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/NecDecoder)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/NecDecoder?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](https://t.me/GyverLibs)
8 |
9 | > [!NOTE]
10 | > **Для передачи по ИК кастомных данных используйте библиотеку [GyverWire](https://github.com/GyverLibs/GyverWire)**
11 |
12 | # NecDecoder
13 | Лёгкая библиотека для декодирования ИК протокола NEC (99% китайских пультов)
14 | - Библиотека не забирает прерывания
15 | - Отсчет времени на micros()
16 | - Обработка команды повтора (удержание кнопки пульта)
17 |
18 | ### Совместимость
19 | Совместима со всеми Arduino платформами (используются Arduino-функции)
20 |
21 | ## Содержание
22 | - [Использование](#usage)
23 | - [Пример](#example)
24 | - [Версии](#versions)
25 | - [Установка](#install)
26 | - [Баги и обратная связь](#feedback)
27 |
28 |
29 |
30 | ## Использование
31 | ### NecDecoder
32 | Чтение данных с ИК приёмника:
33 |
34 | ```cpp
35 | // Вызывать в FALLING прерывании ИК приемника
36 | void tick();
37 |
38 | // Есть данные для чтения (новые или повтор)
39 | bool available();
40 |
41 | // Возвращает true, если принят флаг повтора команды
42 | bool isRepeated();
43 |
44 | // Прочитать данные (адрес + команда)
45 | uint16_t readData();
46 |
47 | // Прочитать адрес
48 | uint8_t readAddress();
49 |
50 | // Прочитать команду
51 | uint8_t readCommand();
52 |
53 | // Прочитать весь пакет NEC
54 | uint32_t readPacket();
55 | ```
56 |
57 | ### NecEncoder
58 | Отправка данных с ИК светодиода:
59 |
60 | ```cpp
61 | NecEncoder::send(uint8_t pin, uint8_t addr, uint8_t cmd);
62 | ```
63 |
64 |
65 |
66 | ## Пример
67 | Остальные примеры смотри в **examples**!
68 |
69 | ### Приём
70 | ```cpp
71 | #include
72 | NecDecoder ir;
73 |
74 | // в прерывании вызываем tick()
75 | void irIsr() {
76 | ir.tick();
77 | }
78 |
79 | void setup() {
80 | Serial.begin(115200);
81 | // подключил на D2, прерывание 0
82 | attachInterrupt(0, irIsr, FALLING);
83 | }
84 |
85 | void loop() {
86 | // если пакет успешно принят
87 | if (ir.available()) {
88 | Serial.print("0x");
89 |
90 | // адрес + команда (16 бит)
91 | Serial.println(ir.readData(), HEX);
92 |
93 | // команда (8 бит)
94 | // Serial.println(ir.readCommand(), HEX);
95 |
96 | // весь пакет (32 бита)
97 | // Serial.println(ir.readPacket(), HEX);
98 | }
99 | }
100 | ```
101 |
102 | ### Отправка
103 | ```cpp
104 | #include
105 | #define LED_PIN 3
106 |
107 | void setup() {
108 | }
109 |
110 | void loop() {
111 | NecEncoder::send(LED_PIN, 0x15, 0xaa);
112 | delay(1000);
113 | }
114 | ```
115 |
116 |
117 |
118 | ## Версии
119 | - v1.0
120 | - v1.1 - исправлены ошибки, добавлена возможность подключения обработчиков, добавлен контроль потока
121 | - v2.0 - завёз очень много оптимизации, стабильноси, надёжности, упрощения и удобства (by AlexGyver)
122 | - v2.1 - добавил отправку (NecEncoder)
123 | - v3.0 - библиотека переписана. Уменьшен вес, улучшена стабильность
124 |
125 |
126 | ## Установка
127 | - Библиотеку можно найти по названию **NecDecoder** и установить через менеджер библиотек в:
128 | - Arduino IDE
129 | - Arduino IDE v2
130 | - PlatformIO
131 | - [Скачать библиотеку](https://github.com/GyverLibs/NecDecoder/archive/refs/heads/main.zip) .zip архивом для ручной установки:
132 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
133 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
134 | - Распаковать и положить в *Документы/Arduino/libraries/*
135 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
136 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
137 | ### Обновление
138 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
139 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
140 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
141 |
142 |
143 | ## Баги и обратная связь
144 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
145 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
146 |
147 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
148 | - Версия библиотеки
149 | - Какой используется МК
150 | - Версия SDK (для ESP)
151 | - Версия Arduino IDE
152 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
153 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности
154 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # Necdecoder
4 | Light library for decoding IR NEC protocol (Chinese remote controls)
5 | - The library does not take any interruptions
6 | - Counting time on micros ()
7 | - processing the repetition command (holding the remote control button)
8 | - processing and reading is 500B flash
9 |
10 | ## compatibility
11 | Compatible with all arduino platforms (used arduino functions)
12 |
13 | ## Content
14 | - [installation] (# Install)
15 | - [initialization] (#init)
16 | - [use] (#usage)
17 | - [Example] (# Example)
18 | - [versions] (#varsions)
19 | - [bugs and feedback] (#fedback)
20 |
21 |
22 | ## Installation
23 | - The library can be found by the name ** Necdecoder ** and installed through the library manager in:
24 | - Arduino ide
25 | - Arduino ide v2
26 | - Platformio
27 | - [download library] (https://github.com/gyverlibs/necdecoder/archive/refs/heads/main.zip). Zip archive for manual installation:
28 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64)
29 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32)
30 | - unpack and put in *documents/arduino/libraries/ *
31 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive
32 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
33 | ### Update
34 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
35 | - through the IDE library manager: find the library how to install and click "update"
36 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors!
37 |
38 |
39 |
40 | ## initialization
41 | `` `CPP
42 | // Reading
43 | NECDECODER IR;
44 |
45 | // Sending
46 | Necencoder ENC (PIN);
47 | Necencoder ENC (PIN, DEL);
48 | // pin - any digital pin
49 | // del - the number of ISS to get 38 kHz.By the silence 10
50 | // (from the calculation of 10mx delay + 3 μs execution of DigitalWrite Arduino)
51 | `` `
52 |
53 |
54 | ## Usage
55 | `` `CPP
56 | // Necdecoder
57 | VOID Tick ();// Call with a negative (Falling) front on the pin of the IR receiver in interruption
58 | Bool Available ();// Returns True if the correct package is read or repeated (ISDECODED () + isrepeated ())
59 | uint32_t Readpacket ();// read the entire package (address + ~ address + command + ~ team)
60 | Uint8_T Readaddress ();// Read the address
61 | uint8_t Readcommand ();// Read the command
62 | Bool ISDECODED ();// returns True if the package is successfully decoded
63 | Bool ISREPEATED ();// Returns True if the flag of the repetition of the team is adopted
64 |
65 | // Necencoder
66 | VOID SEND (UINT8_T Address, Uint8_t Data);// Send the address and data
67 | `` `
68 |
69 |
70 | ## Example
71 | The rest of the examples look at ** Examples **!
72 | ** Reception **
73 | `` `CPP
74 | // Reception of commands from the remote control
75 | // receiver connect to interruption by falling
76 |
77 | #include
78 | NECDECODER IR;
79 |
80 | VOID setup () {
81 | Serial.Begin (9600);
82 | // Full constructionsilt on d2, interruption 0
83 | Attachinterrupt (0, Irisr, Falling);
84 | }
85 |
86 | // In interruption we call tick ()
87 | VOID Irisr () {
88 | Ir.tick ();
89 | }
90 |
91 | VOID loop () {
92 | // if the package is successfully accepted
93 | if (Ir.available ()) {
94 | // We display the entire package (32 bits)
95 | Serial.print ("0x");
96 | Serial.println (IR.Readpacket (), hex);
97 |
98 | // You can only display the command (8 bits)
99 | //Serial.println (IR.Readcommand (), Hex);
100 | }
101 | }
102 | `` `
103 |
104 | ** Sending **
105 | `` `CPP
106 | #include
107 | Necencoder ENC (3);
108 |
109 | VOID setup () {
110 | }
111 |
112 | VOID loop () {
113 | ENC.SEND (0x15, 0XAA);
114 | DELAY (1000);
115 | }
116 | `` `
117 |
118 |
119 | ## versions
120 | - V1.0
121 | - V1.1 - Fixed errors, added the ability to connect handlers, added stream control
122 | - V2.0 - made up a lot of optimization, stable, reliability, simplification and convenience (by Alexgyver)
123 | - V2.1 - added sending
124 |
125 |
126 | ## bugs and feedback
127 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru)
128 | The library is open for refinement and your ** pull Request ** 'ow!
129 |
130 |
131 | When reporting about bugs or incorrect work of the library, it is necessary to indicate:
132 | - The version of the library
133 | - What is MK used
134 | - SDK version (for ESP)
135 | - version of Arduino ide
136 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code
137 | - what code has been loaded, what work was expected from it and how it works in reality
138 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code
--------------------------------------------------------------------------------
/examples/simple/simple.ino:
--------------------------------------------------------------------------------
1 | // приём команд с пульта
2 | // приёмник подключать на прерывание по FALLING
3 |
4 | #include
5 | NecDecoder ir;
6 |
7 | // в прерывании вызываем tick()
8 | void irIsr() {
9 | ir.tick();
10 | }
11 |
12 | void setup() {
13 | Serial.begin(115200);
14 | // подключил на D2, прерывание 0
15 | attachInterrupt(0, irIsr, FALLING);
16 | }
17 |
18 | void loop() {
19 | // если пакет успешно принят
20 | if (ir.available()) {
21 | Serial.print("0x");
22 |
23 | // адрес + команда (16 бит)
24 | Serial.println(ir.readData(), HEX);
25 |
26 | // команда (8 бит)
27 | // Serial.println(ir.readCommand(), HEX);
28 |
29 | // весь пакет (32 бита)
30 | // Serial.println(ir.readPacket(), HEX);
31 | }
32 | }
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For NecDecoder
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 |
9 | NecDecoder KEYWORD1
10 | NecEncoder KEYWORD1
11 |
12 | #######################################
13 | # Methods and Functions (KEYWORD2)
14 | #######################################
15 |
16 | tick KEYWORD2
17 | available KEYWORD2
18 | readPacket KEYWORD2
19 | readAddress KEYWORD2
20 | readCommand KEYWORD2
21 | isDecoded KEYWORD2
22 | isRepeated KEYWORD2
23 | send KEYWORD2
24 |
25 | #######################################
26 | # Constants (LITERAL1)
27 | #######################################
28 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=NecDecoder
2 | version=3.0.0
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Light library for IR receiver with NEC protocol
6 | paragraph=Light library for IR receiver with NEC protocol
7 | category=Device Control
8 | url=https://github.com/GyverLibs/NecDecoder
9 | architectures=*
10 | depends=GyverIO
--------------------------------------------------------------------------------
/src/NEC_timings.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // NEC timings
4 | #define _NEC_START 9000ul
5 | #define _NEC_DATA 4500ul
6 | #define _NEC_REPEAT 2250ul
7 | #define _NEC_BIT 562ul
8 | #define _NEC_HIGH 2250ul
9 | #define _NEC_LOW 1120ul
10 | #define _NEC_FRAME 108000ul
--------------------------------------------------------------------------------
/src/NecDecoder.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #include "NEC_timings.h"
5 |
6 | #define _NEC_BIT_TOL 150ul // допуск бита
7 | #define _NEC_FRAME_TOL 1500ul // допуск фрейма
8 | #define _NEC_SKIP_REPEATS 3 // пропуск повторов
9 |
10 | #define _NEC_START_DATA (_NEC_START + _NEC_DATA)
11 | #define _NEC_START_REPEAT (_NEC_START + _NEC_REPEAT)
12 | #define _NEC_WAIT_REP1 (_NEC_FRAME - _NEC_START_DATA - (_NEC_HIGH + _NEC_LOW) * 16)
13 | #define _NEC_WAIT_REP2 (_NEC_FRAME - _NEC_START_REPEAT)
14 |
15 | // class
16 | class NecDecoder {
17 | enum State : uint8_t {
18 | NEC_start = 0,
19 | NEC_end = 32,
20 | NEC_repeat = 33 + _NEC_SKIP_REPEATS,
21 | NEC_idle,
22 | };
23 |
24 | public:
25 | // Вызывать в FALLING прерывании ИК приемника
26 | void tick() {
27 | uint32_t pulse = micros() - _tmr; // время импульса
28 | _tmr += pulse; // == (_tmr = micros() )
29 | bool bit = 0;
30 |
31 | switch (pulse) {
32 | // START
33 | case ((_NEC_START_REPEAT + _NEC_START_DATA) / 2 + 1)...(_NEC_START_DATA + _NEC_FRAME_TOL):
34 | _state = NEC_start;
35 | return;
36 |
37 | // WAIT REPEAT
38 | case (_NEC_WAIT_REP1 - _NEC_FRAME_TOL)...(_NEC_WAIT_REP1 + _NEC_FRAME_TOL):
39 | case (_NEC_WAIT_REP2 - _NEC_FRAME_TOL)...(_NEC_WAIT_REP2 + _NEC_FRAME_TOL):
40 | if (_state >= NEC_end) return;
41 | break;
42 |
43 | // REPEAT
44 | case (_NEC_START_REPEAT - _NEC_FRAME_TOL)...(_NEC_START_REPEAT + _NEC_START_DATA) / 2:
45 | switch (_state) {
46 | case NEC_end ... NEC_repeat - 1:
47 | ++_state;
48 | return;
49 | case NEC_repeat:
50 | _ready = true;
51 | return;
52 | }
53 | break;
54 |
55 | // DATA
56 | case (_NEC_HIGH - _NEC_BIT_TOL)...(_NEC_HIGH + _NEC_BIT_TOL):
57 | bit = 1;
58 | case (_NEC_LOW - _NEC_BIT_TOL)...(_NEC_LOW + _NEC_BIT_TOL):
59 | if (_state < NEC_end) {
60 | _buf = (_buf << 1) | bit;
61 | if (++_state == NEC_end) {
62 | if (!(((_buf >> 8) & _buf) & 0xFF00FF)) {
63 | _data = ((_buf >> 16) & 0xff00) | ((_buf >> 8) & 0xff);
64 | _ready = true;
65 | } else {
66 | _state = NEC_idle;
67 | }
68 | }
69 | return;
70 | }
71 | break;
72 | }
73 | _state = NEC_idle;
74 | }
75 |
76 | // Есть данные для чтения (новые или повтор)
77 | bool available() {
78 | return _ready ? _ready = false, true : false;
79 | }
80 |
81 | // Возвращает true, если принят флаг повтора команды
82 | bool isRepeated() {
83 | return _state == NEC_repeat;
84 | }
85 |
86 | // Прочитать данные (адрес + команда)
87 | uint16_t readData() {
88 | return _data;
89 | }
90 |
91 | // Прочитать адрес
92 | uint8_t readAddress() {
93 | return _data >> 8;
94 | }
95 |
96 | // Прочитать команду
97 | uint8_t readCommand() {
98 | return _data;
99 | }
100 |
101 | // Прочитать весь пакет NEC
102 | uint32_t readPacket() {
103 | return (uint32_t(_data & 0xff00) << 16) | (uint32_t(~_data & 0xff00) << 8) | ((_data & 0xff) << 8) | (~_data & 0xff);
104 | }
105 |
106 | private:
107 | uint32_t _tmr = 0;
108 | uint32_t _buf = 0;
109 | uint16_t _data = 0;
110 | uint8_t _state = NEC_idle;
111 | bool _ready = false;
112 | };
--------------------------------------------------------------------------------
/src/NecEncoder.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | #include "NEC_timings.h"
6 |
7 | // отправка
8 | class NecEncoder {
9 | public:
10 | static void send(uint8_t pin, uint8_t addr, uint8_t cmd) {
11 | gio::init(pin, OUTPUT);
12 | _pulse38(pin, _NEC_START);
13 | delayMicroseconds(_NEC_DATA);
14 | _sendByte(pin, addr);
15 | _sendByte(pin, ~addr);
16 | _sendByte(pin, cmd);
17 | _sendByte(pin, ~cmd);
18 | _pulse38(pin, _NEC_BIT);
19 | }
20 |
21 | // legacy
22 | NecEncoder(uint8_t pin, uint8_t del = 10) : _pin(pin) {}
23 |
24 | void send(uint8_t addr, uint8_t cmd) {
25 | send(_pin, addr, cmd);
26 | }
27 |
28 | private:
29 | static void _pulse38(uint8_t pin, int dur) {
30 | bool f = 0;
31 | while (dur > 0) {
32 | gio::write(pin, f ^= 1);
33 | delayMicroseconds(13);
34 | dur -= 13;
35 | }
36 | if (f) gio::write(pin, 0);
37 | }
38 |
39 | static void _sendByte(uint8_t pin, uint8_t data) {
40 | int i = 8;
41 | while (i--) {
42 | _pulse38(pin, _NEC_BIT);
43 | delayMicroseconds((data & (1 << 7)) ? (_NEC_HIGH - _NEC_BIT) : _NEC_BIT);
44 | data <<= 1;
45 | }
46 | }
47 |
48 | const uint8_t _pin;
49 | };
--------------------------------------------------------------------------------