├── .gitattributes ├── .github └── workflows │ └── tg-send.yml ├── LICENSE ├── README.md ├── README_EN.md ├── doc ├── interface.png ├── radio.png ├── radio433.png ├── scheme.jpg └── timing.png ├── examples ├── demo_rx │ └── demo_rx.ino ├── demo_tx │ └── demo_tx.ino ├── raw_rx │ └── raw_rx.ino ├── raw_tx │ └── raw_tx.ino ├── rx433_lcd │ └── rx433_lcd.ino ├── rx433_struct │ └── rx433_struct.ino └── tx433_struct │ └── tx433_struct.ino ├── keywords.txt ├── library.properties └── src ├── G433_crc.cpp ├── G433_crc.h └── Gyver433.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 AlexGyver 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/Gyver433.svg?color=brightgreen)](https://github.com/GyverLibs/Gyver433/releases/latest/download/Gyver433.zip) 2 | [![PIO](https://badges.registry.platformio.org/packages/gyverlibs/library/Gyver433.svg)](https://registry.platformio.org/libraries/gyverlibs/Gyver433) 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/Gyver433?_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 | # Gyver433 13 | Библиотека для радиомодулей 433 МГц и Arduino 14 | - **Передача данных с модуля на модуль по собственному интерфейсу связи**, т.е. не работает с китайскими пультами и шлагбаумами! 15 | - Поддержка кривых китайских модулей 16 | - Встроенный CRC контроль целостности 17 | - Ускоренный алгоритм IO для AVR Arduino 18 | - Асинхронный приём в прерывании 19 | - Супер лёгкая либа, заведётся даже на тини13 20 | 21 | ### Совместимость 22 | Совместима со всеми Arduino платформами (используются Arduino-функции) 23 | - При подключении прерывания на esp8266 не забудь аттрибут `IRAM_ATTR` 24 | 25 | ## Содержание 26 | - [Установка](#install) 27 | - [Интерфейс](#interface) 28 | - [Подключение](#wiring) 29 | - [Инициализация](#init) 30 | - [Использование](#usage) 31 | - [Пример](#example) 32 | - [Версии](#versions) 33 | - [Баги и обратная связь](#feedback) 34 | 35 | 36 | ## Установка 37 | - Библиотеку можно найти по названию **Gyver433** и установить через менеджер библиотек в: 38 | - Arduino IDE 39 | - Arduino IDE v2 40 | - PlatformIO 41 | - [Скачать библиотеку](https://github.com/GyverLibs/Gyver433/archive/refs/heads/main.zip) .zip архивом для ручной установки: 42 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64) 43 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32) 44 | - Распаковать и положить в *Документы/Arduino/libraries/* 45 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив 46 | - Читай более подробную инструкцию по установке библиотек [здесь](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) 47 | ### Обновление 48 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи 49 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить" 50 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам! 51 | 52 | 53 | 54 | ## Интерфейс 55 | - Перед отправкой данных идёт синхронизирующий импульс, *TRAIN* мс 56 | - Далее старт импульс, *START* мс, LOW 57 | - Данные кодируются длиной импульса 58 | - Завершает отправку стоп импульс, *TRAIN* мс 59 | ![scheme](/doc/interface.png) 60 | ![scheme](/doc/timing.png) 61 | 62 | 63 | ## Подключение 64 | ![scheme](/doc/radio433.png) 65 | Передатчики: 66 | - SYN115, маленький чип: 1.8-3.6V, макс. скорость 8000 67 | - FS1000A: 3-12V, макс. скорость 10000 68 | - WL102-341: 2.0-3.6V, макс. скорость 6000 69 | 70 | Приёмники: 71 | - SYN480R, крупный чип: 3.3-5.5V 72 | - MX-RM-5V (RF-5V): 5V 73 | - RX470 (WL101-341): 3-5V 74 | 75 | ![scheme](/doc/scheme.jpg) 76 | ![scheme](/doc/radio.png) 77 | 78 | 79 | ## Инициализация 80 | ```cpp 81 | // === ПЕРЕДАТЧИК === 82 | Gyver433_TX<пин> tx; 83 | Gyver433_TX<пин, CRC> tx; 84 | 85 | // === ПРИЁМНИК === 86 | Gyver433_RX<пин> rx; 87 | Gyver433_RX<пин, буфер> rx; 88 | Gyver433_RX<пин, буфер, CRC> rx; 89 | 90 | // пин: цифровой пин 91 | // буфер: размер буфера в байтах, по умолч. 64 92 | // CRC: проверка целостности данных: G433_CRC8 (надёжный), G433_XOR (лёгкий), G433_NOCRC (отключено). По умолч. G433_CRC8 93 | ``` 94 | 95 | 96 | ## Использование 97 | ```cpp 98 | // ========= Gyver433_TX ========= 99 | void sendData(T &data); // отправить данные любого типа (CRC добавляется автоматически) 100 | void write(uint8_t* buf, uint8_t size); // отправить массив байт указанного размера (CRC не добавляется) 101 | 102 | // ========= Gyver433_RX ========= 103 | // приём в прерывании 104 | void tickISR(); // тикер приёма для вызова в прерывании по CHANGE 105 | uint8_t tickISRraw(); // ручной приём в прерывании по CHANGE. Вернёт 1 (начало приёма), 2 (принят байт), 3 (конец пакета) 106 | 107 | // приём в loop 108 | uint16_t tick(); // неблокирующий приём. Вернёт количество успешно принятых байт 109 | uint16_t tickWait(); // блокирующий приём. Вернёт количество успешно принятых байт 110 | 111 | bool readData(T &data); // прочитает буфер в любой тип данных (в указанную переменную) 112 | uint16_t getSize(); // получить размер принятых данных 113 | uint16_t gotData(); // вернёт количество успешно принятых в tickISR() байт (см. пример isr_rx) 114 | uint8_t getRSSI(); // получить качество приёма (процент успешных передач 0.. 100) 115 | 116 | uint8_t buffer[]; // доступ к буферу приёма 117 | uint8_t byteBuf; // доступ к буферу принятого байта 118 | 119 | // ============= CRC ============= 120 | // можно использовать встроенные функции для генерации байта CRC для ручной упаковки пакетов 121 | uint8_t G433_crc8(uint8_t *buffer, uint8_t size); // ручной CRC8 122 | uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size); // ручной CRC XOR 123 | 124 | // ====== ДЕФАЙНЫ-НАСТРОЙКИ ====== 125 | // вызывать перед подключением библиотеки 126 | #define G433_FAST // [TX] короткая синхронизация для зелёных модулей 127 | #define G433_MEDIUM // [TX] средняя синхронизация при отправке на SYN480R ЧАЩЕ 400мс (активно по умолчанию) 128 | #define G433_SLOW // [TX] длинная синхронизация при отправке на SYN480R РЕЖЕ 400мс 129 | #define G433_SPEED 1000 // [RX/TX] скорость, должна быть одинакова на RX и TX, 100-10000 бит/с, по умолч. 2000 бит/с 130 | #define G433_RSSI_COUNT 8 // [RX] количество успешно принятых пакетов для расчёта RSSI (по умолч. 8) 131 | #define G433_CUT_RSSI // [RX] убрать расчёт RSSI из кода (сэкономит чуть памяти) 132 | ``` 133 | 134 | ### Работа приёмника без прерываний 135 | Для приёма данных достаточно вызывать в основном цикле метод `tick()`, он сам опрашивает пин радио. 136 | - Если в программе есть блокирующие места и loop() выполняется с задержками - будет потеря данных 137 | - Для более надёжного приёма рекомендуется вызывать `tickWait()`, она блокирует выполнение кода на время приёма. 138 | 139 | ### Работа приёмника с прерываниями 140 | Рекомендуется использовать приём в прерывании по CHANGE, для этого нужно вызывать в нём `tickISR()`. 141 | Тогда приём будет асинхронный и будет работать даже в загруженной программе. 142 | - Если стандартных пинов прерываний не хватает, можно задействовать PCINT. Вручную или с помощью библиотеки https://github.com/NicoHood/PinChangeInterrupt 143 | 144 | 145 | ## Примеры 146 | Остальные примеры смотри в **examples**! 147 | ### Отправка 148 | ```cpp 149 | #include 150 | Gyver433_TX<2> tx; // указали пин 151 | 152 | void setup() { 153 | } 154 | 155 | char data[] = "Hello from #xx"; // строка для отправки 156 | byte count = 0; // счётчик для отправки 157 | 158 | void loop() { 159 | // добавляем счётчик в строку 160 | data[12] = (count / 10) + '0'; 161 | data[13] = (count % 10) + '0'; 162 | if (++count >= 100) count = 0; 163 | tx.sendData(data); 164 | delay(100); 165 | } 166 | ``` 167 | 168 | ### Приём в прерывании 169 | ```cpp 170 | #include 171 | Gyver433_RX<2, 20> rx; // указали пин и размер буфера 172 | 173 | void setup() { 174 | Serial.begin(9600); 175 | attachInterrupt(0, isr, CHANGE); // прерывание пина радио по CHANGE 176 | } 177 | 178 | // спец. тикер вызывается в прерывании 179 | void isr() { 180 | rx.tickISR(); 181 | } 182 | 183 | void loop() { 184 | if (rx.gotData()) { // если успешно принято больше 0 185 | Serial.write(rx.buffer, rx.size); // выводим 186 | Serial.println(); 187 | } 188 | delay(50); // имитация загруженного кода 189 | } 190 | ``` 191 | 192 | 193 | ## Версии 194 | - v1.0 195 | - v1.1 - оптимизация, новый интерфейс, поддержка дешёвых синих модулей, работа в прерывании 196 | - v1.2 - улучшение качества связи, оптимизация работы в прерывании 197 | - v1.3 - добавлен вывод RSSI 198 | - v1.4 - переделан FastIO 199 | - v1.4.1 - убран FastIO, CRC вынесен отдельно 200 | - v2.0 - убран буфер на отправку, убран манчестер, полностью переделан и оптимизирован интерфейс связи 201 | - v2.0.1 - fix compiler warnings 202 | 203 | 204 | ## Баги и обратная связь 205 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru) 206 | Библиотека открыта для доработки и ваших **Pull Request**'ов! 207 | 208 | 209 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать: 210 | - Версия библиотеки 211 | - Какой используется МК 212 | - Версия SDK (для ESP) 213 | - Версия Arduino IDE 214 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде 215 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности 216 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код 217 | -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 | This is an automatic translation, may be incorrect in some places. See sources and examples! 2 | 3 | # Gyver433 4 | Library for Radio Modules 433 MHz and Arduino 5 | - ** Data transfer from the module to the module on your own communication interface **, i.e.Does not work with Chinese remote controls and barriers! 6 | - Support for crooked Chinese modules 7 | - Built -in CRC Control of integrity 8 | - Accelerated IO algorithm for AVR Arduino 9 | - asynchronous reception in interruption 10 | - Super lightly Liba, will even start on Tini13 11 | 12 | ## compatibility 13 | Compatible with all arduino platforms (used arduino functions) 14 | - When connecting an interruption on the ESP8266, do not forget the Attricbut `IRAM_ATTR` 15 | 16 | ## Content 17 | - [installation] (# Install) 18 | - [interface] (#interface) 19 | - [connection] (#wiring) 20 | - [initialization] (#init) 21 | - [use] (#usage) 22 | - [Example] (# Example) 23 | - [versions] (#varsions) 24 | - [bugs and feedback] (#fedback) 25 | 26 | 27 | ## Installation 28 | - The library can be found by the name ** Gyver433 ** and installed through the library manager in: 29 | - Arduino ide 30 | - Arduino ide v2 31 | - Platformio 32 | - [download the library] (https://github.com/gyverlibs/gyver433/archive/refs/heads/main.zip) .Zip archive for manual installation: 33 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64) 34 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32) 35 | - unpack and put in *documents/arduino/libraries/ * 36 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive 37 | - 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) 38 | ### Update 39 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added 40 | - through the IDE library manager: find the library how to install and click "update" 41 | - 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! 42 | 43 | 44 | 45 | ## Interface 46 | - Before sending the data, there is a synchronizing pulse, * train * ms 47 | - Next, start impulse, * Start * ms, Low 48 | - Data is encoded by pulse length 49 | - completes the sending of the stop impulse, * train * ms 50 | ! [Scheme] (/doc/interface.png) 51 | ! [Scheme] (/doc/timing.png) 52 | 53 | 54 | ## connection 55 | ! [Scheme] (/doc/radio433.png) 56 | Transmitters: 57 | - SYN115, small chip: 1.8-3.6V, max.speed 8000 58 | - FS1000A: 3-12V, Max.speed of 10,000 59 | -WL102-341: 2.0-3.6V, max.speed 6000 60 | 61 | Receivers: 62 | - SYN480R, large chip: 3.3-5.5V 63 | -MX-RM-5V (RF-5V): 5V 64 | -RX470 (WL101-341): 3-5V 65 | 66 | ! [Scheme] (/doc/scheme.jpg) 67 | ! [Scheme] (/doc/radio.png) 68 | 69 | 70 | ## initialization 71 | `` `CPP 72 | // === transmitter === 73 | Gyver433_TX TX; 74 | Gyver433_TX TX; 75 | 76 | // === The receiver ==== 77 | Gyver433_rx RX; 78 | Gyver433_rx rx; 79 | Gyver433_rx rx; 80 | 81 | // PIN: Digital PIN 82 | // buffer: the size of the buffer in bytes, by the silence.64 83 | // CRC: Statement of data integrity: G433_CRC8 (reliable), G433_XOR (Light), G433_NOCRC (disconnected).By the silence.G433_CRC8 84 | `` ` 85 | 86 | 87 | ## Usage`` `CPP 88 | // ========= gyver433_TX ============ 89 | VOID SendData (T & Data);// Send data any type (CRC is added automatically) 90 | VOID Write (uint8_t* buf, uint8_t size);// Send an array of byte of the specified size (CRC is not added) 91 | 92 | // ========= gyver433_rx ============ 93 | // Reception in interruption 94 | VOID Tickisr ();// Take of reception for calling in interruption by Change 95 | uint8_t TickisrRaw ();// manual reception in the interruption in Change.Return 1 (beginning of reception), 2 (Baite adopted), 3 (end of the package) 96 | 97 | // Reception in Loop 98 | uint16_t tick ();// Neboking technique.Will return the number of successfully accepted bytes 99 | uint16_t tickwait ();// blocking reception.Will return the number of successfully accepted bytes 100 | 101 | Bool Readdata (T & Data);// read the buffer in any type of data (in the specified variable) 102 | uint16_t getsize ();// Get the amount of data accepted 103 | uint16_t gotdata ();// will return the number of byte successfully accepted in Tickisr () (see ISR_RX example) 104 | uint8_t getrssi ();// get the quality of the reception (percentage of successful gears 0 .. 100) 105 | 106 | uint8_t buffer [];// Access to the reception buffer 107 | uint8_t bytebuf;// Access to the Baita Boofer 108 | 109 | // ============== CRC ================== 110 | // you can use the built -in functions for generating the CRC byt for manual packages 111 | uint8_t g433_crc8 (uint8_t *buffer, uint8_t size);// manual CRC8 112 | uint8_t g433_crc_xor (uint8_t *buffer, uint8_t size);// manual CRC XOR 113 | 114 | // ====== Defain-settings ========== 115 | // Call before connecting the library 116 | #define g433_fast // [tx] short synchronization for green modules 117 | #define g433_Medium // [tx] average synchronization when sending to SYN480R more than 400MS (actively by default) 118 | #define g433_slow // [tx] Long synchronization when sending to SYN480R less often 400ms 119 | #define G433_Speed 1000 // [RX/TX] Speed, should be the same on RX and TX, 100-10,000 bits/s, silent.2000 bits/s 120 | #define g433_rssi_count 8 // [RX] The number of successfully accepted packets for RSSI calculation (according to default. 8) 121 | #define g433_cut_rssi // [rx] Remove the RSSI calculation from the code (save a little memory) 122 | `` ` 123 | 124 | ### Work of the receiver without interruption 125 | To receive data, it is enough to cause a basic cycle of the `tick ()` method, he himself interviews a pin of the radio. 126 | - If the program has blocking places and Loop () is performed with delays - there will be a loss of data 127 | - For more reliable reception, it is recommended to call `tickwait ()`, it blocks the performance of the code during the reception. 128 | 129 | ### Work of the receiver with interruptions 130 | It is recommended to use the technique in the interrupt on Change, for this you need to call `Tickisr ()` in it. 131 | Then the reception will be asynchronous and will work even in a loaded program. 132 | - If the standard pins of interruptions are not enough, you can use PCINT.Manually or with the help of the library https://github.com/nicohood/pinchangeinterrapt 133 | 134 | 135 | ## Examples 136 | The rest of the examples look at ** Examples **! 137 | ### Sending 138 | `` `CPP 139 | #include 140 | Gyver433_tx <2> tx;// indicated the pin 141 | 142 | VOID setup () { 143 | } 144 | 145 | Char Data [] = "Hello from #xx";// line for sending 146 | Byte count = 0;// counter for sending 147 | 148 | VOID loop () { 149 | // Add the counter to the line 150 | Data [12] = (Count / 10) + '0'; 151 | Data [13] = (Count % 10) + '0'; 152 | if (++ count> = 100) count = 0; 153 | TX.SendData (Data); 154 | DELAY (100); 155 | } 156 | `` ` 157 | 158 | ### Reception in interruption 159 | `` `CPP 160 | #include 161 | Gyver433_rx <2, 20> rx;// indicated the pin and size of the buffer 162 | 163 | VOID setup () { 164 | Serial.Begin (9600); 165 | Attachinterrupt (0, Isr, Change);// Interruption of Pina Radio on Change 166 | } 167 | 168 | // Special.The ticer is called in interruption 169 | VOID isr () { 170 | rx.tickisr (); 171 | } 172 | 173 | VOID loop () { 174 | if (rx.gotdata ()) {// If more than 0 successfully accepted 175 | Serial.write (rx.buffer, rx.size);// Display 176 | Serial.println (); 177 | } 178 | DELAY (50);// imitation of a loaded code 179 | } 180 | `` ` 181 | 182 | 183 | ## versions 184 | - V1.0 185 | - V1.1 - optimization, new interface, support for cheap blue modules, work in interruption 186 | - V1.2 -improvement in communication quality, optimization of work in interruption 187 | - v1.3 - added RSSI withdrawal 188 | - V1.4 - Redeled Fastio 189 | - v1.4.1 - removed Fastio, CRC is taken separately 190 | - V2.0 - removed the buffer for sending, removed Manchester, completely redone and optimized the communication interface 191 | - V2.0.1 - FIX Compiler Warnings 192 | 193 | 194 | ## bugs and feedback 195 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru) 196 | The library is open for refinement and your ** pull Request ** 'ow! 197 | 198 | 199 | When reporting about bugs or incorrect work of the library, it is necessary to indicate: 200 | - The version of the library 201 | - What is MK used 202 | - SDK version (for ESP) 203 | - version of Arduino ide 204 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code 205 | - what code has been loaded, what work was expected from it and how it works in reality 206 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code -------------------------------------------------------------------------------- /doc/interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/Gyver433/5502e83387cefa5af616159663dcbac70eb0a17b/doc/interface.png -------------------------------------------------------------------------------- /doc/radio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/Gyver433/5502e83387cefa5af616159663dcbac70eb0a17b/doc/radio.png -------------------------------------------------------------------------------- /doc/radio433.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/Gyver433/5502e83387cefa5af616159663dcbac70eb0a17b/doc/radio433.png -------------------------------------------------------------------------------- /doc/scheme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/Gyver433/5502e83387cefa5af616159663dcbac70eb0a17b/doc/scheme.jpg -------------------------------------------------------------------------------- /doc/timing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/Gyver433/5502e83387cefa5af616159663dcbac70eb0a17b/doc/timing.png -------------------------------------------------------------------------------- /examples/demo_rx/demo_rx.ino: -------------------------------------------------------------------------------- 1 | // демо-пример приёма в прерывании 2 | // SYN480R, крупный чип: 3.3-5.5V 3 | // MX-RM-5V (RF-5V): 5V 4 | // RX470 (WL101-341): 3-5V 5 | 6 | // дефайны перед подключением библиотеки 7 | //#define G433_SPEED 2000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с 8 | 9 | #include 10 | //Gyver433_RX<пин> rx; 11 | //Gyver433_RX<пин, буфер> rx; 12 | 13 | // пин: цифровой пин 14 | // буфер: размер приёмного буфера в байтах. По умолч. 64 15 | 16 | #include 17 | Gyver433_RX<2, 20> rx; 18 | 19 | void setup() { 20 | Serial.begin(9600); 21 | // взводим прерывания по CHANGE 22 | attachInterrupt(0, isr, CHANGE); 23 | } 24 | 25 | // тикер вызывается в прерывании 26 | void isr() { 27 | rx.tickISR(); 28 | } 29 | 30 | void loop() { 31 | // gotData() вернёт количество удачно принятых байт 32 | if (rx.gotData()) { // если больше 0 33 | // ЧИТАЕМ. СПОСОБ 1 34 | // я знаю, что передатчик отправляет char[15] 35 | char data[15]; 36 | 37 | // читаем принятые данные в data 38 | // если данные совпадают по размеру - ок 39 | if (rx.readData(data)) Serial.print(data); 40 | else Serial.print("Data error"); 41 | 42 | // ЧИТАЕМ. СПОСОБ 2 43 | // вывести сырые данные из буфера в порт 44 | //Serial.write(rx.buffer, rx.size); 45 | 46 | // выведем также качество соединения 47 | Serial.print(", RSSI: "); 48 | Serial.println(rx.getRSSI()); 49 | } 50 | 51 | // имитация загруженного кода. Не влияет на приём 52 | delay(50); 53 | } 54 | -------------------------------------------------------------------------------- /examples/demo_tx/demo_tx.ino: -------------------------------------------------------------------------------- 1 | // демо-пример отправки 2 | // SYN115, маленький чип: 1.8-3.6V 3 | // FS1000A: 3-12V 4 | // WL102-341: 2.0-3.6V 5 | 6 | // дефайны перед подключением библиотеки 7 | //#define G433_FAST // короткая синхронизация для зелёных модулей 8 | //#define G433_MEDIUM // средняя синхронизация для SYN480R при отправке ЧАЩЕ 400мс (активно по умолчанию) 9 | //#define G433_SLOW // длинная синхронизация для SYN480R при отправке РЕЖЕ 400мс 10 | //#define G433_SPEED 2000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с 11 | 12 | #include 13 | //Gyver433_RX<пин> tx; 14 | Gyver433_TX<2> tx; 15 | 16 | void setup() { 17 | } 18 | 19 | char data[] = "Hello from #xx"; // строка для отправки 20 | byte count = 0; // счётчик для отправки 21 | 22 | void loop() { 23 | // добавляем счётчик в строку 24 | data[12] = (count / 10) + '0'; 25 | data[13] = (count % 10) + '0'; 26 | if (++count >= 100) count = 0; 27 | 28 | // отправка данных любого типа 29 | tx.sendData(data); 30 | 31 | // отправка 10 раз в сек 32 | delay(100); 33 | } 34 | -------------------------------------------------------------------------------- /examples/raw_rx/raw_rx.ino: -------------------------------------------------------------------------------- 1 | // обмен сырыми данными без CRC 2 | // отправляет пример raw_tx 3 | // принимаем без прерывания! для примера 4 | 5 | //#define G433_SPEED 1000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с 6 | 7 | #include 8 | Gyver433_RX<2, 20, G433_NOCRC> rx; // буфер 20 байт 9 | 10 | void setup() { 11 | Serial.begin(9600); 12 | } 13 | 14 | void loop() { 15 | // этот тикер нужно вызывать как можно чаще 16 | // лучше принимать в прерывании, см. пример demo 17 | if (rx.tick()) { 18 | // выводим сырые байты в порт 19 | Serial.write(rx.buffer, rx.size); 20 | Serial.println(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/raw_tx/raw_tx.ino: -------------------------------------------------------------------------------- 1 | // обмен сырыми данными без CRC 2 | // принимает пример raw_rx 3 | 4 | //#define G433_SPEED 1000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с 5 | 6 | #include 7 | Gyver433_TX<2, G433_NOCRC> tx; 8 | 9 | void setup() { 10 | } 11 | 12 | char data[] = "Hello from #xx"; // строка для отправки 13 | byte count = 0; // счётчик для отправки 14 | 15 | void loop() { 16 | // добавляем счётчик в строку 17 | data[12] = (count / 10) + '0'; 18 | data[13] = (count % 10) + '0'; 19 | if (++count >= 100) count = 0; 20 | 21 | // отправка данных типа byte* 22 | tx.write((byte*)data, sizeof(data)); 23 | 24 | // отправка 10 раз в сек 25 | delay(100); 26 | } 27 | -------------------------------------------------------------------------------- /examples/rx433_lcd/rx433_lcd.ino: -------------------------------------------------------------------------------- 1 | // выводим данные на дисплей. Отправляет пример demo_tx 2 | //#define G433_SPEED 1000 // скорость 100-10000 бит/с, по умолч. 1500 бит/с 3 | 4 | #include 5 | Gyver433_RX<2> rx; // указали пин 6 | 7 | #include 8 | LiquidCrystal_I2C lcd(0x3f, 16, 2); // или 0x27 9 | 10 | void setup() { 11 | lcd.init(); 12 | lcd.backlight(); 13 | } 14 | 15 | void loop() { 16 | if (rx.tick()) { 17 | lcd.clear(); 18 | lcd.home(); 19 | for (byte i = 0; i < rx.size; i++) lcd.write(rx.buffer[i]); 20 | } 21 | } -------------------------------------------------------------------------------- /examples/rx433_struct/rx433_struct.ino: -------------------------------------------------------------------------------- 1 | // приём структуры данных 2 | 3 | //#define G433_SPEED 1000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с 4 | 5 | #include 6 | Gyver433_RX<2, 12> rx; // указали пин и размер буфера 7 | 8 | // формат пакета для приёма (такой же как отправляется) 9 | struct DataPack { 10 | byte counter; 11 | byte randomNum; 12 | int analog; 13 | uint32_t time; 14 | }; 15 | 16 | void setup() { 17 | Serial.begin(9600); 18 | } 19 | 20 | void loop() { 21 | if (rx.tick()) { 22 | DataPack data; // "буферная" структура 23 | if (rx.readData(data)) { // переписываем данные в неё 24 | // если данные подходят - выводим 25 | Serial.println(data.counter); 26 | Serial.println(data.randomNum); 27 | Serial.println(data.analog); 28 | Serial.println(data.time); 29 | Serial.println(); 30 | } else { 31 | Serial.println("Wrong data"); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/tx433_struct/tx433_struct.ino: -------------------------------------------------------------------------------- 1 | // передача структуры данных 2 | 3 | //#define G433_SPEED 1000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с 4 | #define G433_SLOW // отправляю раз в секунду на SYN480R 5 | 6 | #include 7 | Gyver433_TX<2> tx; // указали пин 8 | 9 | // формат пакета для отправки 10 | struct DataPack { 11 | byte counter = 0; 12 | byte randomNum; 13 | int analog; 14 | uint32_t time; 15 | }; 16 | DataPack data; 17 | 18 | void setup() { 19 | Serial.begin(9600); 20 | } 21 | 22 | void loop() { 23 | data.counter++; // тут счётчик 24 | data.randomNum = random(256); // случайное число 25 | data.analog = analogRead(0); // тут ацп 26 | data.time = millis(); // тут миллис 27 | tx.sendData(data); 28 | 29 | Serial.println("Transmitted:"); 30 | Serial.println(data.counter); 31 | Serial.println(data.randomNum); 32 | Serial.println(data.analog); 33 | Serial.println(data.time); 34 | Serial.println(); 35 | 36 | delay(1000); 37 | } 38 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Gyver433 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | Gyver433 KEYWORD1 9 | Gyver433_TX KEYWORD1 10 | Gyver433_RX KEYWORD1 11 | 12 | ####################################### 13 | # Methods and Functions (KEYWORD2) 14 | ####################################### 15 | sendData KEYWORD2 16 | write KEYWORD2 17 | tick KEYWORD2 18 | tickWait KEYWORD2 19 | tickISR KEYWORD2 20 | tickISRraw KEYWORD2 21 | readData KEYWORD2 22 | size KEYWORD2 23 | buffer KEYWORD2 24 | getSize KEYWORD2 25 | gotData KEYWORD2 26 | G433_crc8 KEYWORD2 27 | G433_crc_xor KEYWORD2 28 | getRSSI KEYWORD2 29 | 30 | ####################################### 31 | # Constants (LITERAL1) 32 | ####################################### 33 | G433_CLI LITERAL1 34 | G433_CRC8 LITERAL1 35 | G433_XOR LITERAL1 36 | G433_NOCRC LITERAL1 37 | G433_FAST LITERAL1 38 | G433_MEDIUM LITERAL1 39 | G433_SLOW LITERAL1 40 | G433_SPEED LITERAL1 41 | G433_CUT_RSSI LITERAL1 -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Gyver433 2 | version=2.1.1 3 | author=AlexGyver 4 | maintainer=AlexGyver 5 | sentence=Simple library for 433 MHz radio 6 | paragraph=Simple library for 433 MHz radio 7 | category=Device Control 8 | url=https://github.com/GyverLibs/Gyver433 9 | architectures=* 10 | -------------------------------------------------------------------------------- /src/G433_crc.cpp: -------------------------------------------------------------------------------- 1 | #include "G433_crc.h" 2 | 3 | void G433_crc8_byte(uint8_t &crc, uint8_t data) { 4 | #if defined (__AVR__) 5 | // резкий алгоритм для AVR 6 | uint8_t counter; 7 | uint8_t buffer; 8 | asm volatile ( 9 | "EOR %[crc_out], %[data_in] \n\t" 10 | "LDI %[counter], 8 \n\t" 11 | "LDI %[buffer], 0x8C \n\t" 12 | "_loop_start_%=: \n\t" 13 | "LSR %[crc_out] \n\t" 14 | "BRCC _loop_end_%= \n\t" 15 | "EOR %[crc_out], %[buffer] \n\t" 16 | "_loop_end_%=: \n\t" 17 | "DEC %[counter] \n\t" 18 | "BRNE _loop_start_%=" 19 | : [crc_out]"=r" (crc), [counter]"=d" (counter), [buffer]"=d" (buffer) 20 | : [crc_in]"0" (crc), [data_in]"r" (data) 21 | ); 22 | #else 23 | // обычный для всех остальных 24 | uint8_t i = 8; 25 | while (i--) { 26 | crc = ((crc ^ data) & 1) ? (crc >> 1) ^ 0x8C : (crc >> 1); 27 | data >>= 1; 28 | } 29 | #endif 30 | } 31 | 32 | uint8_t G433_crc8(uint8_t *buffer, uint8_t size) { 33 | uint8_t crc = 0; 34 | for (uint8_t i = 0; i < size; i++) G433_crc8_byte(crc, buffer[i]); 35 | return crc; 36 | } 37 | uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size) { 38 | uint8_t crc = 0; 39 | for (uint8_t i = 0; i < size; i++) crc ^= buffer[i]; 40 | return crc; 41 | } -------------------------------------------------------------------------------- /src/G433_crc.h: -------------------------------------------------------------------------------- 1 | #ifndef G433_crc_h 2 | #define G433_crc_h 3 | #include 4 | uint8_t G433_crc8(uint8_t *buffer, uint8_t size); // ручной CRC8 5 | uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size); // ручной CRC XOR 6 | void G433_crc8_byte(uint8_t &crc, uint8_t data); // crc8 один байт 7 | #endif -------------------------------------------------------------------------------- /src/Gyver433.h: -------------------------------------------------------------------------------- 1 | /* 2 | Библиотека для радиомодулей 433 МГц и Arduino 3 | Документация: 4 | GitHub: https://github.com/GyverLibs/Gyver433 5 | Возможности: 6 | - Поддержка кривых китайских модулей 7 | - Встроенный CRC контроль целостности 8 | - Ускоренный алгоритм IO для AVR Arduino 9 | - Асинхронный приём в прерывании 10 | - Супер лёгкая либа, заведётся даже на тини13 11 | 12 | AlexGyver, alex@alexgyver.ru 13 | https://alexgyver.ru/ 14 | MIT License 15 | 16 | Версии: 17 | v1.0 - релиз 18 | v1.1 - оптимизация, новый интерфейс, поддержка дешёвых синих модулей, работа в прерывании 19 | v1.2 - улучшение качества связи, оптимизация работы в прерывании 20 | v1.3 - добавлен вывод RSSI 21 | v1.4 - переделан FastIO 22 | v1.4.1 - убран FastIO, CRC вынесен отдельно 23 | v2.0 - убран буфер на отправку, убран манчестер, полностью переделан и оптимизирован интерфейс связи 24 | v2.0.1 - fix compiler warnings 25 | */ 26 | 27 | #ifndef _Gyver433_h 28 | #define _Gyver433_h 29 | #include 30 | #include "G433_crc.h" 31 | 32 | #define TRAINING_TIME_SLOW (500000) // время синхронизации для SLOW_MODE 33 | 34 | // ========================================================================= 35 | #ifndef G433_SPEED 36 | #define G433_SPEED 2000 37 | #endif 38 | 39 | #ifndef G433_RSSI_COUNT 40 | #define G433_RSSI_COUNT 8 41 | #endif 42 | 43 | // тайминги интерфейса 44 | #define G433_HIGH (1000000ul / G433_SPEED) // время HIGH 45 | #define G433_LOW (G433_HIGH / 2) // время LOW 46 | #define G433_START (G433_HIGH * 2) // стартовый импульс 47 | #define G433_TRAIN (G433_HIGH * 3 / 2) // синхроимпульс 48 | 49 | #define G433_WINDOW (G433_HIGH / 4) 50 | #define G433_EDGE_L (G433_LOW - G433_WINDOW) 51 | #define G433_EDGE_LH (G433_HIGH - G433_WINDOW) 52 | #define G433_EDGE_HT (G433_HIGH + G433_WINDOW) 53 | #define G433_EDGE_TS (G433_TRAIN + G433_WINDOW) 54 | #define G433_EDGE_S (G433_START + G433_WINDOW) 55 | 56 | // жоский delay для avr 57 | #ifdef _delay_us 58 | #define G433_DELAY(x) _delay_us(x) 59 | #else 60 | #define G433_DELAY(x) delayMicroseconds(x) 61 | #endif 62 | 63 | // режимы CRC 64 | #define G433_NOCRC 0 65 | #define G433_CRC8 1 66 | #define G433_XOR 2 67 | 68 | // количество синхроимпульсов 69 | #if defined(G433_FAST) 70 | #define TRAINING_TIME 10000 71 | #elif defined(G433_MEDIUM) 72 | #define TRAINING_TIME 100000 73 | #elif defined(G433_SLOW) 74 | #define TRAINING_TIME (TRAINING_TIME_SLOW) 75 | #else 76 | #define TRAINING_TIME 100000 77 | #endif 78 | 79 | // =================================== ПЕРЕДАТЧИК =================================== 80 | template 81 | class Gyver433_TX { 82 | public: 83 | Gyver433_TX() { 84 | pinMode(TX_PIN, OUTPUT); 85 | } 86 | 87 | // отправка, блокирующая. Кушает любой тип данных 88 | template 89 | void sendData(T &data) { 90 | uint8_t *ptr = (uint8_t*) &data; 91 | write(ptr, sizeof(T)); 92 | } 93 | 94 | // отправка сырого набора байтов 95 | void write(uint8_t* buf, uint16_t size) { 96 | uint8_t crc; 97 | if (CRC_MODE == G433_CRC8) crc = G433_crc8(buf, size); 98 | else if (CRC_MODE == G433_XOR) crc = G433_crc_xor(buf, size); 99 | 100 | // раскачка радио 101 | flag = 0; 102 | for (uint16_t i = 0; i < (TRAINING_TIME / G433_TRAIN / 2) * 2 + 1; i++) { 103 | fastWrite(TX_PIN, flag = !flag); 104 | G433_DELAY(G433_TRAIN); 105 | } 106 | 107 | // старт бит 108 | fastWrite(TX_PIN, 0); // старт 109 | G433_DELAY(G433_START); // ждём 110 | fastWrite(TX_PIN, 1); // старт бит 111 | 112 | for (uint16_t i = 0; i < size; i++) write(buf[i]); // дата 113 | if (CRC_MODE) write(crc); // CRC 114 | G433_DELAY(G433_TRAIN); 115 | fastWrite(TX_PIN, flag = !flag); // стоп 116 | } 117 | 118 | // отправить байт (без старт бита!) 119 | void write(uint8_t data) { 120 | for (uint8_t b = 0; b < 8; b++) { 121 | if (data & 1) G433_DELAY(G433_HIGH); 122 | else G433_DELAY(G433_LOW); 123 | fastWrite(TX_PIN, flag = !flag); 124 | data >>= 1; 125 | } 126 | } 127 | 128 | private: 129 | // быстрый IO 130 | void fastWrite(const uint8_t pin, bool val) { 131 | #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) 132 | if (pin < 8) bitWrite(PORTD, pin, val); 133 | else if (pin < 14) bitWrite(PORTB, (pin - 8), val); 134 | else if (pin < 20) bitWrite(PORTC, (pin - 14), val); 135 | #elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__) 136 | bitWrite(PORTB, pin, val); 137 | #else 138 | digitalWrite(pin, val); 139 | #endif 140 | } 141 | 142 | bool flag = 0; 143 | }; 144 | 145 | // =================================== ПРИЁМНИК =================================== 146 | template 147 | class Gyver433_RX { 148 | public: 149 | Gyver433_RX() { 150 | pinMode(RX_PIN, INPUT); 151 | } 152 | 153 | // неблокирующий приём. Вернёт количество успешно принятых байт 154 | uint16_t tick() { 155 | if (pinChanged()) tickISR(); 156 | return gotData(); 157 | } 158 | 159 | // блокирующий приём. Вернёт количество успешно принятых байт 160 | uint16_t tickWait() { 161 | do { 162 | if (pinChanged()) tickISR(); 163 | } while (state == 1); 164 | return gotData(); 165 | } 166 | 167 | // ручной приём в прерывании по CHANGE. Вернёт 1 (начало приёма), 2 (принят байт), 3 (конец пакета) 168 | // принятый байт можно прочитать в byteBuf 169 | uint8_t tickISRraw() { 170 | uint32_t pulse = micros() - tmr; // время импульса 171 | tmr += pulse; // сброс таймера. Равносильно tmr = micros() 172 | if (pulse <= G433_EDGE_L) return parse = 0; // импульс слишком короткий 173 | trains <<= 1; // счётчик train импульсов (0b11111111 << 1) 174 | if (pulse <= G433_EDGE_HT && parse) { // окно LOW/HIGH и идёт парсинг 175 | byteBuf >>= 1; // двигаем байт-буфер 176 | if (pulse > G433_EDGE_LH) byteBuf |= (1 << 7); // пишем бит, если это HIGH 177 | if (!(++bits & 0x7)) return 2; // 2: ПРИНЯТ БАЙТ: собрали байт (каждые 8 бит, 0x7 == 0b111) 178 | } else if (pulse <= G433_EDGE_TS) { // окно START 179 | trains |= 1; // добавляем 1 справа к trains 180 | if (parse) { // был парсинг, а это стоп бит 181 | parse = 0; // стоп машина 182 | return 3; // 3: ПРИНЯТ ПАКЕТ: принят стоп-бит 183 | } 184 | } else if (pulse <= G433_EDGE_S) { // окно STOP/TRAINING 185 | if (trains == 0xFE) { // было 7 train импульсов (0xFE == 0b11111110) 186 | bits = 0; // прерываем парсинг, если он был 187 | parse = 1; // старт бит, начинаем парсинг 188 | return 1; // 1: СТАРТ ПРИЁМА 189 | } 190 | } else return parse = 0; // слишком длинный импульс, выходим 191 | return 0; 192 | } 193 | 194 | // тикер приёма для вызова в прерывании по CHANGE 195 | void tickISR() { 196 | switch (tickISRraw()) { 197 | case 1: // СТАРТ БИТ 198 | if (!state) { // старта не было 199 | state = 1; // старт 200 | bytes = 0; // сброс 201 | } // старт был - ошибка приёма 202 | break; 203 | case 2: // ПРИНЯТ БАЙТ 204 | if (state == 1) { // парсинг идёт 205 | buffer[bytes] = byteBuf; // пишем в буфер 206 | bytes++; // счётчик принятых 207 | if (bytes > sizeof(buffer)) { // буфер переполнен 208 | state = 3; // флаг на чтение 209 | } 210 | } 211 | break; 212 | case 3: // КОНЕЦ ПАКЕТА 213 | if (state == 1) state = 2; // флаг на чтение 214 | break; 215 | } 216 | } 217 | 218 | // если пакет прочитан успешно - вернёт количество байт в нём 219 | uint16_t gotData() { 220 | if (state >= 2) { // флаг на чтение 221 | size = 0; // обнуляем размер 222 | if (state != 3 && bytes != 0) { // если буфер не переполнен, проверяем CRC 223 | if (CRC_MODE == G433_CRC8) { // CRC8 224 | if (!G433_crc8(buffer, bytes)) size = bytes - 1; 225 | } else if (CRC_MODE == G433_XOR) { // CRC XOR 226 | if (!G433_crc_xor(buffer, bytes)) size = bytes - 1; 227 | } else size = bytes; // без CRC 228 | } 229 | #ifndef G433_CUT_RSSI 230 | if (!size) errCount++; // принято 0 байт - ошибка 231 | if (++rcCount >= G433_RSSI_COUNT) { 232 | RSSI = 100 - errCount * 100 / G433_RSSI_COUNT; 233 | errCount = rcCount = 0; 234 | } 235 | #endif 236 | state = 0; 237 | return size; 238 | } 239 | return 0; 240 | } 241 | 242 | // прочитает буфер в любой тип данных 243 | template 244 | bool readData(T &data) { 245 | if (sizeof(T) > RX_BUF) return false; // великовато для буфера 246 | if (sizeof(T) != size) return false; // данные не соответствуют 247 | uint8_t *ptr = (uint8_t*) &data; 248 | for (uint16_t i = 0; i < sizeof(T); i++) *ptr++ = buffer[i]; 249 | return true; 250 | } 251 | 252 | // получить качество приёма (процент успешных передач) 253 | uint8_t getRSSI() { 254 | #ifndef G433_CUT_RSSI 255 | return RSSI; 256 | #endif 257 | } 258 | 259 | // получить размер принятых данных 260 | uint16_t getSize() { 261 | return size; 262 | } 263 | 264 | // размер принятых данных 265 | uint16_t size = 0; 266 | 267 | // доступ к буферу 268 | uint8_t buffer[RX_BUF + !!CRC_MODE]; 269 | uint8_t byteBuf; 270 | 271 | private: 272 | bool fastRead(const uint8_t pin) { 273 | #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) 274 | if (pin < 8) return bitRead(PIND, pin); 275 | else if (pin < 14) return bitRead(PINB, pin - 8); 276 | else if (pin < 20) return bitRead(PINC, pin - 14); 277 | #elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__) 278 | return bitRead(PINB, pin); 279 | #else 280 | return digitalRead(pin); 281 | #endif 282 | return 0; 283 | } 284 | 285 | bool pinChanged() { 286 | if (prevBit != fastRead(RX_PIN)) { 287 | prevBit = !prevBit; 288 | return 1; 289 | } return 0; 290 | } 291 | 292 | bool prevBit; 293 | volatile uint8_t state = 0; 294 | volatile uint8_t parse = 0, trains = 0; 295 | volatile uint32_t tmr = 0; 296 | uint8_t bits = 0, bytes = 0; 297 | #ifndef G433_CUT_RSSI 298 | uint8_t errCount = 0, rcCount = 0, RSSI = 100; 299 | #endif 300 | }; 301 | 302 | #endif --------------------------------------------------------------------------------