├── .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 | [![latest](https://img.shields.io/github/v/release/GyverLibs/NecDecoder.svg?color=brightgreen)](https://github.com/GyverLibs/NecDecoder/releases/latest/download/NecDecoder.zip) 2 | [![PIO](https://badges.registry.platformio.org/packages/gyverlibs/library/NecDecoder.svg)](https://registry.platformio.org/libraries/gyverlibs/NecDecoder) 3 | [![Foo](https://img.shields.io/badge/Website-AlexGyver.ru-blue.svg?style=flat-square)](https://alexgyver.ru/) 4 | [![Foo](https://img.shields.io/badge/%E2%82%BD%24%E2%82%AC%20%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D1%82%D1%8C-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B0-orange.svg?style=flat-square)](https://alexgyver.ru/support_alex/) 5 | [![Foo](https://img.shields.io/badge/README-ENGLISH-blueviolet.svg?style=flat-square)](https://github-com.translate.goog/GyverLibs/NecDecoder?_x_tr_sl=ru&_x_tr_tl=en) 6 | 7 | [![Foo](https://img.shields.io/badge/ПОДПИСАТЬСЯ-НА%20ОБНОВЛЕНИЯ-brightgreen.svg?style=social&logo=telegram&color=blue)](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 | }; --------------------------------------------------------------------------------