35 Commits

Author SHA1 Message Date
AlexGyver 6c91bf4e80 Update library.properties
2.1.1
2024-04-11 16:55:23 +03:00
AlexGyver 102beca9f5 edit badge 2024-04-11 16:38:21 +03:00
AlexGyver c4a9822af4 english readme 2023-12-22 23:51:58 +03:00
AlexGyver b7b2f840da english readme 2023-12-22 23:49:46 +03:00
AlexGyver f0a5bdad5b english readme 2023-12-22 23:39:32 +03:00
AlexGyver a73d2f6bbc Update README.md 2023-08-15 10:26:42 +03:00
AlexGyver 9e7e75ffe5 edit workflow 2023-04-12 14:36:06 +03:00
AlexGyver 1700798c90 edit workflow 2023-04-11 17:37:22 +03:00
AlexGyver 463158e667 edit badge 2022-09-03 14:08:14 +03:00
AlexGyver a2265e1aae edit badge 2022-07-20 13:58:34 +03:00
AlexGyver 17fa4047f9 edit workflow 2022-06-29 15:06:41 +03:00
AlexGyver 17d9e91111 edit readme 2022-06-27 23:48:54 +03:00
AlexGyver f97e26411f edit readme 2022-06-27 23:46:28 +03:00
AlexGyver fe49edcfa6 edit readme 2022-06-27 23:44:23 +03:00
AlexGyver 3587e96247 edit readme 2022-06-27 23:41:04 +03:00
AlexGyver fc967f7554 edit readme 2022-06-27 23:36:34 +03:00
AlexGyver 2d1566ace2 edit readme 2022-06-27 23:34:09 +03:00
AlexGyver a0dd1f6aee edit readme 2022-06-27 23:28:39 +03:00
AlexGyver 035596d252 create workflow 2022-06-27 23:20:36 +03:00
AlexGyver 5a467a1c93 edit readme 2022-06-27 19:36:36 +03:00
AlexGyver e987107e6e issues 2022-06-27 14:52:39 +03:00
AlexGyver f3a861ecd1 update 2022-05-24 12:03:59 +03:00
Alex 8f40368bdf english readme 2022-05-04 04:43:34 +03:00
Alex 83e3903f88 english readme 2022-05-04 04:33:47 +03:00
Alex 33477745b2 Update README.md 2022-05-03 03:26:00 +03:00
Alex 52277d98e8 Update README.md 2022-01-28 02:37:40 +03:00
Alex 9c10e644db Update README.md 2022-01-25 02:38:34 +03:00
Alex 03525ebe93 Merge branch 'main' of https://github.com/GyverLibs/Gyver433 2022-01-06 00:50:23 +03:00
Alex 9d18b80bb6 upd 2022-01-06 00:50:15 +03:00
Alex 415de7a97a Update README.md 2021-12-16 01:45:57 +03:00
Alex 970e454920 Update README.md 2021-12-15 15:40:41 +03:00
Alex b416ae981a Update README.md 2021-12-11 14:34:17 +03:00
Alex e66a74de62 upd 2021-12-11 14:33:29 +03:00
Alex 48c3ee21a4 upd 2021-09-09 17:57:11 +03:00
Alex e6f45643b9 upd 2021-09-09 17:54:30 +03:00
20 changed files with 578 additions and 326 deletions
+20
View File
@@ -0,0 +1,20 @@
name: Telegram Message
on:
release:
types: [published]
jobs:
build:
name: Send Message
runs-on: ubuntu-latest
steps:
- name: send telegram message on push
uses: appleboy/telegram-action@master
with:
to: ${{ secrets.TELEGRAM_TO }}
token: ${{ secrets.TELEGRAM_TOKEN }}
disable_web_page_preview: true
message: |
${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
${{ github.event.release.body }}
https://github.com/${{ github.repository }}
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2021 Alex Copyright (c) 2021 AlexGyver
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+103 -52
View File
@@ -1,19 +1,29 @@
![License: MIT](https://img.shields.io/badge/License-MIT-green.svg) [![latest](https://img.shields.io/github/v/release/GyverLibs/Gyver433.svg?color=brightgreen)](https://github.com/GyverLibs/Gyver433/releases/latest/download/Gyver433.zip)
![author](https://img.shields.io/badge/author-AlexGyver-informational.svg) [![PIO](https://badges.registry.platformio.org/packages/gyverlibs/library/Gyver433.svg)](https://registry.platformio.org/libraries/gyverlibs/Gyver433)
[![arduino-library](https://www.ardu-badge.com/badge/Gyver433.svg?)](https://www.ardu-badge.com/Gyver433)
[![Foo](https://img.shields.io/badge/Website-AlexGyver.ru-blue.svg?style=flat-square)](https://alexgyver.ru/)
[![Foo](https://img.shields.io/badge/%E2%82%BD$%E2%82%AC%20%D0%9D%D0%B0%20%D0%BF%D0%B8%D0%B2%D0%BE-%D1%81%20%D1%80%D1%8B%D0%B1%D0%BA%D0%BE%D0%B9-orange.svg?style=flat-square)](https://alexgyver.ru/support_alex/)
[![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)
[![Foo](https://img.shields.io/badge/ПОДПИСАТЬСЯ-НА%20ОБНОВЛЕНИЯ-brightgreen.svg?style=social&logo=telegram&color=blue)](https://t.me/GyverLibs)
# Gyver433 # Gyver433
Библиотека для радиомодулей 433 МГц и Arduino Библиотека для радиомодулей 433 МГц и Arduino
- Супер лёгкая либа, заведётся даже на тини13 (отправка) - **Передача данных с модуля на модуль по собственному интерфейсу связи**, т.е. не работает с китайскими пультами и шлагбаумами!
- Поддержка кривых китайских модулей - Поддержка кривых китайских модулей
- Интерфейс Manchester или Pulselength - Встроенный CRC контроль целостности
- Встроенный CRC контроль целостности (CRC8 или XOR)
- Ускоренный алгоритм IO для AVR Arduino - Ускоренный алгоритм IO для AVR Arduino
- Опционально работа в прерывании (приём данных) - Асинхронный приём в прерывании
- Супер лёгкая либа, заведётся даже на тини13
### Совместимость ### Совместимость
Совместима со всеми Arduino платформами (используются Arduino-функции) Совместима со всеми Arduino платформами (используются Arduino-функции)
- При подключении прерывания на esp8266 не забудь аттрибут `IRAM_ATTR`
## Содержание ## Содержание
- [Установка](#install) - [Установка](#install)
- [Интерфейс](#interface)
- [Подключение](#wiring)
- [Инициализация](#init) - [Инициализация](#init)
- [Использование](#usage) - [Использование](#usage)
- [Пример](#example) - [Пример](#example)
@@ -32,31 +42,52 @@
- Распаковать и положить в *Документы/Arduino/libraries/* - Распаковать и положить в *Документы/Arduino/libraries/*
- (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
- Читай более подробную инструкцию по установке библиотек [здесь](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) - Читай более подробную инструкцию по установке библиотек [здесь](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)
### Обновление
- Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
- Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
- Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
<a id="interface"></a>
## Интерфейс
- Перед отправкой данных идёт синхронизирующий импульс, *TRAIN* мс
- Далее старт импульс, *START* мс, LOW
- Данные кодируются длиной импульса
- Завершает отправку стоп импульс, *TRAIN* мс
![scheme](/doc/interface.png)
![scheme](/doc/timing.png)
<a id="wiring"></a>
## Подключение
![scheme](/doc/radio433.png)
Передатчики:
- SYN115, маленький чип: 1.8-3.6V, макс. скорость 8000
- FS1000A: 3-12V, макс. скорость 10000
- WL102-341: 2.0-3.6V, макс. скорость 6000
Приёмники:
- SYN480R, крупный чип: 3.3-5.5V
- MX-RM-5V (RF-5V): 5V
- RX470 (WL101-341): 3-5V
![scheme](/doc/scheme.jpg)
![scheme](/doc/radio.png)
<a id="init"></a> <a id="init"></a>
## Инициализация ## Инициализация
```cpp ```cpp
// === КЛАССЫ === // === ПЕРЕДАТЧИК ===
// Gyver433_RX - приёмник Gyver433_TX<пин> tx;
// Gyver433_TX - передатчик Gyver433_TX<пин, CRC> tx;
// === ПРИЁМНИК ===
Gyver433_RX<пин> rx;
Gyver433_RX<пин, буфер> rx;
Gyver433_RX<пин, буфер, CRC> rx;
// === ИНИЦИАЛИЗАЦИЯ ===
Gyver433_xx<пин> xx;
Gyver433_xx<пин, буфер> xx;
Gyver433_xx<пин, буфер, CRC> xx;
// пин: цифровой пин // пин: цифровой пин
// буфер: размер буфера в байтах. На "ручную" отправку буфер не нужен. По умолч. 64 // буфер: размер буфера в байтах, по умолч. 64
// CRC: проверка целостности данных: G433_CRC8 (надёжный), G433_XOR (лёгкий), G433_NOCRC (отключено). По умолч. G433_CRC8 // CRC: проверка целостности данных: G433_CRC8 (надёжный), G433_XOR (лёгкий), G433_NOCRC (отключено). По умолч. G433_CRC8
// === ДЕФАЙНЫ-НАСТРОЙКИ ===
// вызывать перед подключением библиотеки
#define G433_FAST // [TX] короткая синхронизация для зелёных модулей
#define G433_MEDIUM // [TX] средняя синхронизация при отправке на SYN480R ЧАЩЕ 400мс (активно по умолчанию)
#define G433_SLOW // [TX] длинная синхронизация при отправке на SYN480R РЕЖЕ 400мс
#define G433_MANCHESTER // [должно быть одинаково на RX и TX] интерфейс Manchester Coding для экспериментов =)
#define G433_SPEED 1000 // [должно быть одинаково на RX и TX] скорость 100-8000 бит/с, по умолч. 2000 бит/с
#define G433_RSSI_COUNT 10 // [RX] количество успешно принятых пакетов для расчёта RSSI (по умолч. 10)
``` ```
<a id="usage"></a> <a id="usage"></a>
@@ -65,32 +96,56 @@ Gyver433_xx<пин, буфер, CRC> xx;
// ========= Gyver433_TX ========= // ========= Gyver433_TX =========
void sendData(T &data); // отправить данные любого типа (CRC добавляется автоматически) void sendData(T &data); // отправить данные любого типа (CRC добавляется автоматически)
void write(uint8_t* buf, uint8_t size); // отправить массив байт указанного размера (CRC не добавляется) void write(uint8_t* buf, uint8_t size); // отправить массив байт указанного размера (CRC не добавляется)
uint8_t buffer[]; // доступ к буферу для отладки
// ========= Gyver433_RX ========= // ========= Gyver433_RX =========
uint16_t tick(); // неблокирующий приём, вернёт кол-во успешно принятых байт // приём в прерывании
uint16_t tickWait(); // блокирующий приём (более надёжный), вернёт кол-во успешно принятых байт void tickISR(); // тикер приёма для вызова в прерывании по CHANGE
uint16_t tickISR(); // тикер для прерывания по CHANGE (см. пример isr_rx) uint8_t tickISRraw(); // ручной приём в прерывании по CHANGE. Вернёт 1 (начало приёма), 2 (принят байт), 3 (конец пакета)
// приём в loop
uint16_t tick(); // неблокирующий приём. Вернёт количество успешно принятых байт
uint16_t tickWait(); // блокирующий приём. Вернёт количество успешно принятых байт
bool readData(T &data); // прочитает буфер в любой тип данных (в указанную переменную) bool readData(T &data); // прочитает буфер в любой тип данных (в указанную переменную)
uint16_t getSize(); // получить размер принятых данных uint16_t getSize(); // получить размер принятых данных
uint16_t gotData(); // вернёт количество успешно принятых в tickISR() байт (см. пример isr_rx) uint16_t gotData(); // вернёт количество успешно принятых в tickISR() байт (см. пример isr_rx)
uint8_t buffer[]; // доступ к буферу для отладки uint8_t getRSSI(); // получить качество приёма (процент успешных передач 0.. 100)
uint8_t getRSSI(); // получить качество приёма (процент успешных передач)
uint8_t buffer[]; // доступ к буферу приёма
uint8_t byteBuf; // доступ к буферу принятого байта
// ============= CRC ============= // ============= CRC =============
// можно использовать встроенные функции для генерации байта CRC для ручной упаковки пакетов // можно использовать встроенные функции для генерации байта CRC для ручной упаковки пакетов
uint8_t G433_crc8(uint8_t *buffer, uint8_t size); // ручной CRC8 uint8_t G433_crc8(uint8_t *buffer, uint8_t size); // ручной CRC8
uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size); // ручной CRC XOR uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size); // ручной CRC XOR
// ====== ДЕФАЙНЫ-НАСТРОЙКИ ======
// вызывать перед подключением библиотеки
#define G433_FAST // [TX] короткая синхронизация для зелёных модулей
#define G433_MEDIUM // [TX] средняя синхронизация при отправке на SYN480R ЧАЩЕ 400мс (активно по умолчанию)
#define G433_SLOW // [TX] длинная синхронизация при отправке на SYN480R РЕЖЕ 400мс
#define G433_SPEED 1000 // [RX/TX] скорость, должна быть одинакова на RX и TX, 100-10000 бит/с, по умолч. 2000 бит/с
#define G433_RSSI_COUNT 8 // [RX] количество успешно принятых пакетов для расчёта RSSI (по умолч. 8)
#define G433_CUT_RSSI // [RX] убрать расчёт RSSI из кода (сэкономит чуть памяти)
``` ```
### Работа приёмника без прерываний
Для приёма данных достаточно вызывать в основном цикле метод `tick()`, он сам опрашивает пин радио.
- Если в программе есть блокирующие места и loop() выполняется с задержками - будет потеря данных
- Для более надёжного приёма рекомендуется вызывать `tickWait()`, она блокирует выполнение кода на время приёма.
### Работа приёмника с прерываниями
Рекомендуется использовать приём в прерывании по CHANGE, для этого нужно вызывать в нём `tickISR()`.
Тогда приём будет асинхронный и будет работать даже в загруженной программе.
- Если стандартных пинов прерываний не хватает, можно задействовать PCINT. Вручную или с помощью библиотеки https://github.com/NicoHood/PinChangeInterrupt
<a id="example"></a> <a id="example"></a>
## Примеры ## Примеры
Остальные примеры смотри в **examples**! Остальные примеры смотри в **examples**!
![scheme](/doc/scheme.jpg)
### Отправка ### Отправка
```cpp ```cpp
#include <Gyver433.h> #include <Gyver433.h>
Gyver433_TX<2, 20> tx; // указали пин и размер буфера Gyver433_TX<2> tx; // указали пин
void setup() { void setup() {
} }
@@ -108,23 +163,6 @@ void loop() {
} }
``` ```
### Приём
```cpp
#include <Gyver433.h>
Gyver433_RX<2, 20> rx; // указали пин и размер буфера
void setup() {
Serial.begin(9600);
}
void loop() {
if (rx.tickWait()) { // если успешно принято больше 0
Serial.write(rx.buffer, rx.size); // выводим
Serial.println();
}
}
```
### Приём в прерывании ### Приём в прерывании
```cpp ```cpp
#include <Gyver433.h> #include <Gyver433.h>
@@ -135,8 +173,9 @@ void setup() {
attachInterrupt(0, isr, CHANGE); // прерывание пина радио по CHANGE attachInterrupt(0, isr, CHANGE); // прерывание пина радио по CHANGE
} }
// спец. тикер вызывается в прерывании
void isr() { void isr() {
rx.tickISR(); // спец. тикер вызывается в прерывании rx.tickISR();
} }
void loop() { void loop() {
@@ -144,7 +183,7 @@ void loop() {
Serial.write(rx.buffer, rx.size); // выводим Serial.write(rx.buffer, rx.size); // выводим
Serial.println(); Serial.println();
} }
delay(200); // имитация загруженного кода delay(50); // имитация загруженного кода
} }
``` ```
@@ -156,8 +195,20 @@ void loop() {
- v1.3 - добавлен вывод RSSI - v1.3 - добавлен вывод RSSI
- v1.4 - переделан FastIO - v1.4 - переделан FastIO
- v1.4.1 - убран FastIO, CRC вынесен отдельно - v1.4.1 - убран FastIO, CRC вынесен отдельно
- v2.0 - убран буфер на отправку, убран манчестер, полностью переделан и оптимизирован интерфейс связи
- v2.0.1 - fix compiler warnings
<a id="feedback"></a> <a id="feedback"></a>
## Баги и обратная связь ## Баги и обратная связь
При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru) При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
Библиотека открыта для доработки и ваших **Pull Request**'ов! Библиотека открыта для доработки и ваших **Pull Request**'ов!
При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
- Версия библиотеки
- Какой используется МК
- Версия SDK (для ESP)
- Версия Arduino IDE
- Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
- Какой код загружался, какая работа от него ожидалась и как он работает в реальности
- В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
+206
View File
@@ -0,0 +1,206 @@
This is an automatic translation, may be incorrect in some places. See sources and examples!
# Gyver433
Library for Radio Modules 433 MHz and Arduino
- ** Data transfer from the module to the module on your own communication interface **, i.e.Does not work with Chinese remote controls and barriers!
- Support for crooked Chinese modules
- Built -in CRC Control of integrity
- Accelerated IO algorithm for AVR Arduino
- asynchronous reception in interruption
- Super lightly Liba, will even start on Tini13
## compatibility
Compatible with all arduino platforms (used arduino functions)
- When connecting an interruption on the ESP8266, do not forget the Attricbut `IRAM_ATTR`
## Content
- [installation] (# Install)
- [interface] (#interface)
- [connection] (#wiring)
- [initialization] (#init)
- [use] (#usage)
- [Example] (# Example)
- [versions] (#varsions)
- [bugs and feedback] (#fedback)
<a id="install"> </a>
## Installation
- The library can be found by the name ** Gyver433 ** and installed through the library manager in:
- Arduino ide
- Arduino ide v2
- Platformio
- [download the library] (https://github.com/gyverlibs/gyver433/archive/refs/heads/main.zip) .Zip archive for manual installation:
- unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64)
- unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32)
- unpack and put in *documents/arduino/libraries/ *
- (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive
- 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)
### Update
- I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
- through the IDE library manager: find the library how to install and click "update"
- 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!
<a Id="INterFace"> </a>
## Interface
- Before sending the data, there is a synchronizing pulse, * train * ms
- Next, start impulse, * Start * ms, Low
- Data is encoded by pulse length
- completes the sending of the stop impulse, * train * ms
! [Scheme] (/doc/interface.png)
! [Scheme] (/doc/timing.png)
<a id="wiring"> </a>
## connection
! [Scheme] (/doc/radio433.png)
Transmitters:
- SYN115, small chip: 1.8-3.6V, max.speed 8000
- FS1000A: 3-12V, Max.speed of 10,000
-WL102-341: 2.0-3.6V, max.speed 6000
Receivers:
- SYN480R, large chip: 3.3-5.5V
-MX-RM-5V (RF-5V): 5V
-RX470 (WL101-341): 3-5V
! [Scheme] (/doc/scheme.jpg)
! [Scheme] (/doc/radio.png)
<a id="init"> </a>
## initialization
`` `CPP
// === transmitter ===
Gyver433_TX <PIN> TX;
Gyver433_TX <PIN, CRC> TX;
// === The receiver ====
Gyver433_rx <PIN> RX;
Gyver433_rx <pin, buffer> rx;
Gyver433_rx <pin, buffer, CRC> rx;
// PIN: Digital PIN
// buffer: the size of the buffer in bytes, by the silence.64
// CRC: Statement of data integrity: G433_CRC8 (reliable), G433_XOR (Light), G433_NOCRC (disconnected).By the silence.G433_CRC8
`` `
<a id="usage"> </a>
## Usage`` `CPP
// ========= gyver433_TX ============
VOID SendData (T & Data);// Send data any type (CRC is added automatically)
VOID Write (uint8_t* buf, uint8_t size);// Send an array of byte of the specified size (CRC is not added)
// ========= gyver433_rx ============
// Reception in interruption
VOID Tickisr ();// Take of reception for calling in interruption by Change
uint8_t TickisrRaw ();// manual reception in the interruption in Change.Return 1 (beginning of reception), 2 (Baite adopted), 3 (end of the package)
// Reception in Loop
uint16_t tick ();// Neboking technique.Will return the number of successfully accepted bytes
uint16_t tickwait ();// blocking reception.Will return the number of successfully accepted bytes
Bool Readdata (T & Data);// read the buffer in any type of data (in the specified variable)
uint16_t getsize ();// Get the amount of data accepted
uint16_t gotdata ();// will return the number of byte successfully accepted in Tickisr () (see ISR_RX example)
uint8_t getrssi ();// get the quality of the reception (percentage of successful gears 0 .. 100)
uint8_t buffer [];// Access to the reception buffer
uint8_t bytebuf;// Access to the Baita Boofer
// ============== CRC ==================
// you can use the built -in functions for generating the CRC byt for manual packages
uint8_t g433_crc8 (uint8_t *buffer, uint8_t size);// manual CRC8
uint8_t g433_crc_xor (uint8_t *buffer, uint8_t size);// manual CRC XOR
// ====== Defain-settings ==========
// Call before connecting the library
#define g433_fast // [tx] short synchronization for green modules
#define g433_Medium // [tx] average synchronization when sending to SYN480R more than 400MS (actively by default)
#define g433_slow // [tx] Long synchronization when sending to SYN480R less often 400ms
#define G433_Speed 1000 // [RX/TX] Speed, should be the same on RX and TX, 100-10,000 bits/s, silent.2000 bits/s
#define g433_rssi_count 8 // [RX] The number of successfully accepted packets for RSSI calculation (according to default. 8)
#define g433_cut_rssi // [rx] Remove the RSSI calculation from the code (save a little memory)
`` `
### Work of the receiver without interruption
To receive data, it is enough to cause a basic cycle of the `tick ()` method, he himself interviews a pin of the radio.
- If the program has blocking places and Loop () is performed with delays - there will be a loss of data
- For more reliable reception, it is recommended to call `tickwait ()`, it blocks the performance of the code during the reception.
### Work of the receiver with interruptions
It is recommended to use the technique in the interrupt on Change, for this you need to call `Tickisr ()` in it.
Then the reception will be asynchronous and will work even in a loaded program.
- 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
<a id="EXAMPLE"> </a>
## Examples
The rest of the examples look at ** Examples **!
### Sending
`` `CPP
#include <gyver433.h>
Gyver433_tx <2> tx;// indicated the pin
VOID setup () {
}
Char Data [] = "Hello from #xx";// line for sending
Byte count = 0;// counter for sending
VOID loop () {
// Add the counter to the line
Data [12] = (Count / 10) + '0';
Data [13] = (Count % 10) + '0';
if (++ count> = 100) count = 0;
TX.SendData (Data);
DELAY (100);
}
`` `
### Reception in interruption
`` `CPP
#include <gyver433.h>
Gyver433_rx <2, 20> rx;// indicated the pin and size of the buffer
VOID setup () {
Serial.Begin (9600);
Attachinterrupt (0, Isr, Change);// Interruption of Pina Radio on Change
}
// Special.The ticer is called in interruption
VOID isr () {
rx.tickisr ();
}
VOID loop () {
if (rx.gotdata ()) {// If more than 0 successfully accepted
Serial.write (rx.buffer, rx.size);// Display
Serial.println ();
}
DELAY (50);// imitation of a loaded code
}
`` `
<a id="versions"> </a>
## versions
- V1.0
- V1.1 - optimization, new interface, support for cheap blue modules, work in interruption
- V1.2 -improvement in communication quality, optimization of work in interruption
- v1.3 - added RSSI withdrawal
- V1.4 - Redeled Fastio
- v1.4.1 - removed Fastio, CRC is taken separately
- V2.0 - removed the buffer for sending, removed Manchester, completely redone and optimized the communication interface
- V2.0.1 - FIX Compiler Warnings
<a id="feedback"> </a>
## bugs and feedback
Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru)
The library is open for refinement and your ** pull Request ** 'ow!
When reporting about bugs or incorrect work of the library, it is necessary to indicate:
- The version of the library
- What is MK used
- SDK version (for ESP)
- version of Arduino ide
- whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code
- what code has been loaded, what work was expected from it and how it works in reality
- Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 333 KiB

After

Width:  |  Height:  |  Size: 172 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

+32 -18
View File
@@ -1,39 +1,53 @@
// демо-пример: инициализация и настройки // демо-пример приёма в прерывании
// крупный приёмник SYN480R [VCC: 3.3-5.5V, logic: VCC] // SYN480R, крупный чип: 3.3-5.5V
// или MX-RM-5V (RF-5V) [VCC: 5V, logic: 5V] // MX-RM-5V (RF-5V): 5V
// RX470 (WL101-341): 3-5V
// дефайны перед подключением библиотеки // дефайны перед подключением библиотеки
//#define G433_MANCHESTER // интерфейс Manchester Coding для экспериментов =) //#define G433_SPEED 2000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с
//#define G433_SPEED 1000 // скорость 100-8000 бит/с, по умолч. 2000 бит/с
#include <Gyver433.h> #include <Gyver433.h>
//Gyver433_RX<пин> rx; //Gyver433_RX<пин> rx;
//Gyver433_RX<пин, буфер> rx; //Gyver433_RX<пин, буфер> rx;
//Gyver433_RX<пин, буфер, CRC> rx;
// пин: цифровой пин // пин: цифровой пин
// буфер: размер буфера в байтах. По умолч. 64 // буфер: размер приёмного буфера в байтах. По умолч. 64
// CRC: проверка целостности данных: G433_CRC8 (надёжный), G433_XOR (лёгкий), G433_NOCRC (отключено). По умолч. G433_CRC8
#include <Gyver433.h>
Gyver433_RX<2, 20> rx; Gyver433_RX<2, 20> rx;
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
// взводим прерывания по CHANGE
attachInterrupt(0, isr, CHANGE);
} }
void loop() { // тикер вызывается в прерывании
// "тик" опрашивает радио и вернёт количество успешно принятых байт void isr() {
// tick принимает асинхронно, но может ловить ошибки при загруженном коде rx.tickISR();
// tickWait блокирует выполнение, но принимает данные чётко }
//if (rx.tick()) { void loop() {
if (rx.tickWait()) { // gotData() вернёт количество удачно принятых байт
// принятые данные доступны в .buffer if (rx.gotData()) { // если больше 0
// и имеют размер .size // ЧИТАЕМ. СПОСОБ 1
Serial.write(rx.buffer, rx.size); // я знаю, что передатчик отправляет char[15]
char data[15];
// читаем принятые данные в data
// если данные совпадают по размеру - ок
if (rx.readData(data)) Serial.print(data);
else Serial.print("Data error");
// выведем также качество связи // ЧИТАЕМ. СПОСОБ 2
// вывести сырые данные из буфера в порт
//Serial.write(rx.buffer, rx.size);
// выведем также качество соединения
Serial.print(", RSSI: "); Serial.print(", RSSI: ");
Serial.println(rx.getRSSI()); Serial.println(rx.getRSSI());
} }
// имитация загруженного кода. Не влияет на приём
delay(50);
} }
+8 -15
View File
@@ -1,24 +1,17 @@
// демо-пример: инициализация и настройки // демо-пример отправки
// мелкий передатчик SYN115 [VCC: 1.8-3.6V, logic: VCC] // SYN115, маленький чип: 1.8-3.6V
// или FS1000A [VCC: 3-12V, logic: 5V] // FS1000A: 3-12V
// WL102-341: 2.0-3.6V
// дефайны перед подключением библиотеки // дефайны перед подключением библиотеки
//#define G433_FAST // короткая синхронизация для зелёных модулей //#define G433_FAST // короткая синхронизация для зелёных модулей
//#define G433_MEDIUM // средняя синхронизация для SYN480R при отправке ЧАЩЕ 400мс (активно по умолчанию) //#define G433_MEDIUM // средняя синхронизация для SYN480R при отправке ЧАЩЕ 400мс (активно по умолчанию)
//#define G433_SLOW // длинная синхронизация для SYN480R при отправке РЕЖЕ 400мс //#define G433_SLOW // длинная синхронизация для SYN480R при отправке РЕЖЕ 400мс
//#define G433_MANCHESTER // интерфейс Manchester Coding для экспериментов =) //#define G433_SPEED 2000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с
//#define G433_SPEED 1000 // скорость 100-8000 бит/с, по умолч. 2000 бит/с
#include <Gyver433.h> #include <Gyver433.h>
//Gyver433_TX<пин> tx; //Gyver433_RX<пин> tx;
//Gyver433_TX<пин, буфер> tx; Gyver433_TX<2> tx;
//Gyver433_TX<пин, буфер, CRC> tx;
// пин: цифровой пин
// буфер: размер буфера в байтах. На "ручную" отправку буфер не нужен. По умолч. 64
// CRC: проверка целостности данных: G433_CRC8 (надёжный), G433_XOR (лёгкий), G433_NOCRC (отключено). По умолч. G433_CRC8
Gyver433_TX<2, 20> tx;
void setup() { void setup() {
} }
@@ -32,7 +25,7 @@ void loop() {
data[13] = (count % 10) + '0'; data[13] = (count % 10) + '0';
if (++count >= 100) count = 0; if (++count >= 100) count = 0;
// отправка данных любого типа. Блокирующая на период отправки // отправка данных любого типа
tx.sendData(data); tx.sendData(data);
// отправка 10 раз в сек // отправка 10 раз в сек
-26
View File
@@ -1,26 +0,0 @@
// приём в прерывании. Отправляет пример demo_tx
//#define G433_SPEED 1000 // скорость 100-8000 бит/с, по умолч. 2000 бит/с
#include <Gyver433.h>
Gyver433_RX<2, 20> rx; // указали пин и размер буфера
void setup() {
Serial.begin(9600);
// взводим прерывания по CHANGE
attachInterrupt(0, isr, CHANGE);
}
void isr() {
rx.tickISR(); // спец. тикер вызывается в прерывании по CHANGE
}
void loop() {
// .gotData() вернёт количество удачно принятых в прерывании байт
if (rx.gotData()) { // если больше 0
Serial.write(rx.buffer, rx.size);
Serial.println();
}
// имитация загруженного кода
delay(100);
}
+9 -3
View File
@@ -1,15 +1,21 @@
// обмен сырыми данными без CRC и буфера на отправку // обмен сырыми данными без CRC
// отправляет пример raw_tx // отправляет пример raw_tx
// принимаем без прерывания! для примера
//#define G433_SPEED 1000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с
#include <Gyver433.h> #include <Gyver433.h>
Gyver433_RX<2, 20, G433_NOCRC> rx; // буфер на приём нужен! Gyver433_RX<2, 20, G433_NOCRC> rx; // буфер 20 байт
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
} }
void loop() { void loop() {
if (rx.tickWait()) { // этот тикер нужно вызывать как можно чаще
// лучше принимать в прерывании, см. пример demo
if (rx.tick()) {
// выводим сырые байты в порт
Serial.write(rx.buffer, rx.size); Serial.write(rx.buffer, rx.size);
Serial.println(); Serial.println();
} }
+3 -3
View File
@@ -1,10 +1,10 @@
// обмен сырыми данными без CRC и буфера на отправку // обмен сырыми данными без CRC
// принимает пример raw_rx // принимает пример raw_rx
//#define G433_SPEED 1000 // скорость 100-8000 бит/с, по умолч. 2000 бит/с //#define G433_SPEED 1000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с
#include <Gyver433.h> #include <Gyver433.h>
Gyver433_TX<2, 0, G433_NOCRC> tx; // буфер на отправку 0! Экономим Gyver433_TX<2, G433_NOCRC> tx;
void setup() { void setup() {
} }
+2 -2
View File
@@ -1,5 +1,5 @@
// выводим данные на дисплей. Отправляет пример demo_tx // выводим данные на дисплей. Отправляет пример demo_tx
//#define G433_SPEED 1000 // скорость 100-8000 бит/с, по умолч. 2000 бит/с //#define G433_SPEED 1000 // скорость 100-10000 бит/с, по умолч. 1500 бит/с
#include <Gyver433.h> #include <Gyver433.h>
Gyver433_RX<2> rx; // указали пин Gyver433_RX<2> rx; // указали пин
@@ -18,4 +18,4 @@ void loop() {
lcd.home(); lcd.home();
for (byte i = 0; i < rx.size; i++) lcd.write(rx.buffer[i]); for (byte i = 0; i < rx.size; i++) lcd.write(rx.buffer[i]);
} }
} }
+14 -12
View File
@@ -1,12 +1,12 @@
// приём структуры данных // приём структуры данных
//#define G433_SPEED 1000 // скорость 100-8000 бит/с, по умолч. 2000 бит/с //#define G433_SPEED 1000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с
#include <Gyver433.h> #include <Gyver433.h>
Gyver433_RX<2, 10> rx; // указали пин и размер буфера Gyver433_RX<2, 12> rx; // указали пин и размер буфера
// формат пакета для приёма (такой же как отправляется) // формат пакета для приёма (такой же как отправляется)
struct dataPack { struct DataPack {
byte counter; byte counter;
byte randomNum; byte randomNum;
int analog; int analog;
@@ -19,14 +19,16 @@ void setup() {
void loop() { void loop() {
if (rx.tick()) { if (rx.tick()) {
dataPack data; // "буферная" структура DataPack data; // "буферная" структура
rx.readData(data); // переписываем данные в неё if (rx.readData(data)) { // переписываем данные в неё
// если данные подходят - выводим
Serial.println("Received:"); Serial.println(data.counter);
Serial.println(data.counter); Serial.println(data.randomNum);
Serial.println(data.randomNum); Serial.println(data.analog);
Serial.println(data.analog); Serial.println(data.time);
Serial.println(data.time); Serial.println();
Serial.println(); } else {
Serial.println("Wrong data");
}
} }
} }
+6 -7
View File
@@ -1,19 +1,19 @@
// передача структуры данных // передача структуры данных
//#define G433_SPEED 1000 // скорость 100-8000 бит/с, по умолч. 2000 бит/с //#define G433_SPEED 1000 // скорость 100-10000 бит/с, по умолч. 2000 бит/с
#define G433_SLOW // отправляю раз в секунду на SYN480R #define G433_SLOW // отправляю раз в секунду на SYN480R
#include <Gyver433.h> #include <Gyver433.h>
Gyver433_TX<2, 10> tx; // указали пин и размер буфера Gyver433_TX<2> tx; // указали пин
// формат пакета для отправки // формат пакета для отправки
struct dataPack { struct DataPack {
byte counter; byte counter = 0;
byte randomNum; byte randomNum;
int analog; int analog;
uint32_t time; uint32_t time;
}; };
dataPack data; DataPack data;
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@@ -24,9 +24,8 @@ void loop() {
data.randomNum = random(256); // случайное число data.randomNum = random(256); // случайное число
data.analog = analogRead(0); // тут ацп data.analog = analogRead(0); // тут ацп
data.time = millis(); // тут миллис data.time = millis(); // тут миллис
tx.sendData(data); tx.sendData(data);
Serial.println("Transmitted:"); Serial.println("Transmitted:");
Serial.println(data.counter); Serial.println(data.counter);
Serial.println(data.randomNum); Serial.println(data.randomNum);
+4 -4
View File
@@ -13,12 +13,11 @@ Gyver433_RX KEYWORD1
# Methods and Functions (KEYWORD2) # Methods and Functions (KEYWORD2)
####################################### #######################################
sendData KEYWORD2 sendData KEYWORD2
sendDataSlow KEYWORD2
write KEYWORD2 write KEYWORD2
writeSlow KEYWORD2
tick KEYWORD2 tick KEYWORD2
tickISR KEYWORD2
tickWait KEYWORD2 tickWait KEYWORD2
tickISR KEYWORD2
tickISRraw KEYWORD2
readData KEYWORD2 readData KEYWORD2
size KEYWORD2 size KEYWORD2
buffer KEYWORD2 buffer KEYWORD2
@@ -31,6 +30,7 @@ getRSSI KEYWORD2
####################################### #######################################
# Constants (LITERAL1) # Constants (LITERAL1)
####################################### #######################################
G433_CLI LITERAL1
G433_CRC8 LITERAL1 G433_CRC8 LITERAL1
G433_XOR LITERAL1 G433_XOR LITERAL1
G433_NOCRC LITERAL1 G433_NOCRC LITERAL1
@@ -38,4 +38,4 @@ G433_FAST LITERAL1
G433_MEDIUM LITERAL1 G433_MEDIUM LITERAL1
G433_SLOW LITERAL1 G433_SLOW LITERAL1
G433_SPEED LITERAL1 G433_SPEED LITERAL1
G433_MANCHESTER LITERAL1 G433_CUT_RSSI LITERAL1
+2 -2
View File
@@ -1,9 +1,9 @@
name=Gyver433 name=Gyver433
version=1.4.1 version=2.1.1
author=AlexGyver <alex@alexgyver.ru> author=AlexGyver <alex@alexgyver.ru>
maintainer=AlexGyver <alex@alexgyver.ru> maintainer=AlexGyver <alex@alexgyver.ru>
sentence=Simple library for 433 MHz radio sentence=Simple library for 433 MHz radio
paragraph=Simple library for 433 MHz radio paragraph=Simple library for 433 MHz radio
category=Device Control category=Device Control
url=https://github.com/GyverLibs/Gyver433 url=https://github.com/GyverLibs/Gyver433
architectures=* architectures=*
+168 -181
View File
@@ -3,12 +3,11 @@
Документация: Документация:
GitHub: https://github.com/GyverLibs/Gyver433 GitHub: https://github.com/GyverLibs/Gyver433
Возможности: Возможности:
- Супер лёгкая либа, заведётся даже на тини13 (отправка)
- Поддержка кривых китайских модулей - Поддержка кривых китайских модулей
- Интерфейс Manchester или Pulselength - Встроенный CRC контроль целостности
- Встроенный CRC контроль целостности (CRC8 или XOR)
- Ускоренный алгоритм IO для AVR Arduino - Ускоренный алгоритм IO для AVR Arduino
- Опционально работа в прерывании (приём данных) - Асинхронный приём в прерывании
- Супер лёгкая либа, заведётся даже на тини13
AlexGyver, alex@alexgyver.ru AlexGyver, alex@alexgyver.ru
https://alexgyver.ru/ https://alexgyver.ru/
@@ -21,14 +20,16 @@
v1.3 - добавлен вывод RSSI v1.3 - добавлен вывод RSSI
v1.4 - переделан FastIO v1.4 - переделан FastIO
v1.4.1 - убран FastIO, CRC вынесен отдельно v1.4.1 - убран FastIO, CRC вынесен отдельно
v2.0 - убран буфер на отправку, убран манчестер, полностью переделан и оптимизирован интерфейс связи
v2.0.1 - fix compiler warnings
*/ */
#ifndef Gyver433_h #ifndef _Gyver433_h
#define Gyver433_h #define _Gyver433_h
#include <Arduino.h> #include <Arduino.h>
#include "G433_crc.h" #include "G433_crc.h"
#define TRAINING_TIME_SLOW (500000ul) // время синхронизации для SLOW_MODE #define TRAINING_TIME_SLOW (500000) // время синхронизации для SLOW_MODE
// ========================================================================= // =========================================================================
#ifndef G433_SPEED #ifndef G433_SPEED
@@ -36,27 +37,27 @@
#endif #endif
#ifndef G433_RSSI_COUNT #ifndef G433_RSSI_COUNT
#define G433_RSSI_COUNT 10 #define G433_RSSI_COUNT 8
#endif #endif
// тайминги интерфейса // тайминги интерфейса
#define FRAME_TIME (1000000ul / G433_SPEED) // время фрейма (либо HIGH) #define G433_HIGH (1000000ul / G433_SPEED) // время HIGH
#define HALF_FRAME (FRAME_TIME / 2) // полфрейма (либо LOW) #define G433_LOW (G433_HIGH / 2) // время LOW
#define START_PULSE (FRAME_TIME * 2) // стартовый импульс #define G433_START (G433_HIGH * 2) // стартовый импульс
#define G433_TRAIN (G433_HIGH * 3 / 2) // синхроимпульс
// окно времени для обработки импульса #define G433_WINDOW (G433_HIGH / 4)
#define START_MIN (START_PULSE * 3 / 4) #define G433_EDGE_L (G433_LOW - G433_WINDOW)
#define START_MAX (START_PULSE * 5 / 4) #define G433_EDGE_LH (G433_HIGH - G433_WINDOW)
#define FRAME_MIN (FRAME_TIME * 3 / 4) #define G433_EDGE_HT (G433_HIGH + G433_WINDOW)
#define FRAME_MAX (FRAME_TIME * 5 / 4) #define G433_EDGE_TS (G433_TRAIN + G433_WINDOW)
#define HALF_FRAME_MIN (HALF_FRAME * 3 / 4) #define G433_EDGE_S (G433_START + G433_WINDOW)
#define HALF_FRAME_MAX (HALF_FRAME * 5 / 4)
// жоский delay для avr // жоский delay для avr
#ifdef AVR #ifdef _delay_us
#define G433_DELAY _delay_us #define G433_DELAY(x) _delay_us(x)
#else #else
#define G433_DELAY delayMicroseconds #define G433_DELAY(x) delayMicroseconds(x)
#endif #endif
// режимы CRC // режимы CRC
@@ -66,17 +67,17 @@
// количество синхроимпульсов // количество синхроимпульсов
#if defined(G433_FAST) #if defined(G433_FAST)
#define TRAINING_PULSES 10 #define TRAINING_TIME 10000
#elif defined(G433_MEDIUM) #elif defined(G433_MEDIUM)
#define TRAINING_PULSES 50 #define TRAINING_TIME 100000
#elif defined(G433_SLOW) #elif defined(G433_SLOW)
#define TRAINING_PULSES (TRAINING_TIME_SLOW / FRAME_TIME / 2) #define TRAINING_TIME (TRAINING_TIME_SLOW)
#else #else
#define TRAINING_PULSES 50 #define TRAINING_TIME 100000
#endif #endif
// ============ ПЕРЕДАТЧИК ============ // =================================== ПЕРЕДАТЧИК ===================================
template <uint8_t TX_PIN, uint16_t TX_BUF = 64, uint8_t CRC_MODE = G433_CRC8> template <uint8_t TX_PIN, uint8_t CRC_MODE = G433_CRC8>
class Gyver433_TX { class Gyver433_TX {
public: public:
Gyver433_TX() { Gyver433_TX() {
@@ -85,145 +86,174 @@ public:
// отправка, блокирующая. Кушает любой тип данных // отправка, блокирующая. Кушает любой тип данных
template <typename T> template <typename T>
bool sendData(T &data) { void sendData(T &data) {
if (sizeof(T) > TX_BUF) return 0; uint8_t *ptr = (uint8_t*) &data;
const uint8_t *ptr = (const uint8_t*) &data; write(ptr, sizeof(T));
for (uint16_t i = 0; i < sizeof(T); i++) buffer[i] = *ptr++;
if (CRC_MODE == G433_CRC8) {
buffer[sizeof(T)] = G433_crc8(buffer, sizeof(T));
write(buffer, sizeof(T) + 1);
} else if (CRC_MODE == G433_XOR) {
buffer[sizeof(T)] = G433_crc_xor(buffer, sizeof(T));
write(buffer, sizeof(T) + 1);
} else {
write(buffer, sizeof(T));
}
return 1;
} }
// отправка сырого набора байтов // отправка сырого набора байтов
void write(uint8_t* buf, uint16_t size) { void write(uint8_t* buf, uint16_t size) {
for (uint16_t i = 0; i < TRAINING_PULSES; i++) { uint8_t crc;
fastWrite(TX_PIN, 1); if (CRC_MODE == G433_CRC8) crc = G433_crc8(buf, size);
G433_DELAY(FRAME_TIME); else if (CRC_MODE == G433_XOR) crc = G433_crc_xor(buf, size);
fastWrite(TX_PIN, 0);
G433_DELAY(FRAME_TIME);
}
fastWrite(TX_PIN, 1); // старт
G433_DELAY(START_PULSE); // ждём
fastWrite(TX_PIN, 0); // старт бит
#ifdef G433_MANCHESTER // раскачка радио
G433_DELAY(HALF_FRAME); // ждём flag = 0;
for (uint16_t n = 0; n < size; n++) { for (uint16_t i = 0; i < (TRAINING_TIME / G433_TRAIN / 2) * 2 + 1; i++) {
uint8_t data = buf[n]; fastWrite(TX_PIN, flag = !flag);
for (uint8_t b = 0; b < 8; b++) { G433_DELAY(G433_TRAIN);
fastWrite(TX_PIN, !(data & 1));
G433_DELAY(HALF_FRAME);
fastWrite(TX_PIN, (data & 1));
G433_DELAY(HALF_FRAME);
data >>= 1;
}
} }
fastWrite(TX_PIN, 0); // конец передачи
#else // старт бит
bool flag = 0; fastWrite(TX_PIN, 0); // старт
for (uint16_t n = 0; n < size; n++) { G433_DELAY(G433_START); // ждём
uint8_t data = buf[n]; fastWrite(TX_PIN, 1); // старт бит
for (uint8_t b = 0; b < 8; b++) {
if (data & 1) G433_DELAY(FRAME_TIME); for (uint16_t i = 0; i < size; i++) write(buf[i]); // дата
else G433_DELAY(HALF_FRAME); if (CRC_MODE) write(crc); // CRC
fastWrite(TX_PIN, flag = !flag); G433_DELAY(G433_TRAIN);
data >>= 1; fastWrite(TX_PIN, flag = !flag); // стоп
} }
// отправить байт (без старт бита!)
void write(uint8_t data) {
for (uint8_t b = 0; b < 8; b++) {
if (data & 1) G433_DELAY(G433_HIGH);
else G433_DELAY(G433_LOW);
fastWrite(TX_PIN, flag = !flag);
data >>= 1;
} }
#endif
} }
// доступ к буферу
uint8_t buffer[TX_BUF + !!CRC_MODE];
private: private:
// быстрый IO
void fastWrite(const uint8_t pin, bool val) { void fastWrite(const uint8_t pin, bool val) {
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
if (pin < 8) bitWrite(PORTD, pin, val); if (pin < 8) bitWrite(PORTD, pin, val);
else if (pin < 14) bitWrite(PORTB, (pin - 8), val); else if (pin < 14) bitWrite(PORTB, (pin - 8), val);
else if (pin < 20) bitWrite(PORTC, (pin - 14), val); else if (pin < 20) bitWrite(PORTC, (pin - 14), val);
#elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__) #elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__)
bitWrite(PORTB, pin, val); bitWrite(PORTB, pin, val);
#else #else
digitalWrite(pin, val); digitalWrite(pin, val);
#endif #endif
} }
bool flag = 0;
}; };
// ============ ПРИЁМНИК ============ // =================================== ПРИЁМНИК ===================================
template <uint8_t RX_PIN, uint16_t RX_BUF = 64, uint8_t CRC_MODE = G433_CRC8> template <uint8_t RX_PIN, uint16_t RX_BUF = 64, uint8_t CRC_MODE = G433_CRC8>
class Gyver433_RX { class Gyver433_RX {
public: public:
Gyver433_RX() { Gyver433_RX() {
pinMode(RX_PIN, INPUT); pinMode(RX_PIN, INPUT);
} }
// неблокирующий приём, вернёт кол-во успешно принятых байт // неблокирующий приём. Вернёт количество успешно принятых байт
uint16_t tick() { uint16_t tick() {
if (pinChanged()) checkState(); if (pinChanged()) tickISR();
return gotData(); return gotData();
} }
// tick для вызова в прерывании по CHANGE // блокирующий приём. Вернёт количество успешно принятых байт
void tickISR() {
#ifdef G433_MANCHESTER
if (pinChanged()) checkState();
#else
checkState();
#endif
}
// блокирующий приём, вернёт кол-во успешно принятых байт
uint16_t tickWait() { uint16_t tickWait() {
do { do {
if (tick()) return size; if (pinChanged()) tickISR();
} while (parse == 2); } while (state == 1);
return gotData();
}
// ручной приём в прерывании по CHANGE. Вернёт 1 (начало приёма), 2 (принят байт), 3 (конец пакета)
// принятый байт можно прочитать в byteBuf
uint8_t tickISRraw() {
uint32_t pulse = micros() - tmr; // время импульса
tmr += pulse; // сброс таймера. Равносильно tmr = micros()
if (pulse <= G433_EDGE_L) return parse = 0; // импульс слишком короткий
trains <<= 1; // счётчик train импульсов (0b11111111 << 1)
if (pulse <= G433_EDGE_HT && parse) { // окно LOW/HIGH и идёт парсинг
byteBuf >>= 1; // двигаем байт-буфер
if (pulse > G433_EDGE_LH) byteBuf |= (1 << 7); // пишем бит, если это HIGH
if (!(++bits & 0x7)) return 2; // 2: ПРИНЯТ БАЙТ: собрали байт (каждые 8 бит, 0x7 == 0b111)
} else if (pulse <= G433_EDGE_TS) { // окно START
trains |= 1; // добавляем 1 справа к trains
if (parse) { // был парсинг, а это стоп бит
parse = 0; // стоп машина
return 3; // 3: ПРИНЯТ ПАКЕТ: принят стоп-бит
}
} else if (pulse <= G433_EDGE_S) { // окно STOP/TRAINING
if (trains == 0xFE) { // было 7 train импульсов (0xFE == 0b11111110)
bits = 0; // прерываем парсинг, если он был
parse = 1; // старт бит, начинаем парсинг
return 1; // 1: СТАРТ ПРИЁМА
}
} else return parse = 0; // слишком длинный импульс, выходим
return 0; return 0;
} }
// тикер приёма для вызова в прерывании по CHANGE
void tickISR() {
switch (tickISRraw()) {
case 1: // СТАРТ БИТ
if (!state) { // старта не было
state = 1; // старт
bytes = 0; // сброс
} // старт был - ошибка приёма
break;
case 2: // ПРИНЯТ БАЙТ
if (state == 1) { // парсинг идёт
buffer[bytes] = byteBuf; // пишем в буфер
bytes++; // счётчик принятых
if (bytes > sizeof(buffer)) { // буфер переполнен
state = 3; // флаг на чтение
}
}
break;
case 3: // КОНЕЦ ПАКЕТА
if (state == 1) state = 2; // флаг на чтение
break;
}
}
// если пакет прочитан успешно - вернёт количество байт в нём
uint16_t gotData() {
if (state >= 2) { // флаг на чтение
size = 0; // обнуляем размер
if (state != 3 && bytes != 0) { // если буфер не переполнен, проверяем CRC
if (CRC_MODE == G433_CRC8) { // CRC8
if (!G433_crc8(buffer, bytes)) size = bytes - 1;
} else if (CRC_MODE == G433_XOR) { // CRC XOR
if (!G433_crc_xor(buffer, bytes)) size = bytes - 1;
} else size = bytes; // без CRC
}
#ifndef G433_CUT_RSSI
if (!size) errCount++; // принято 0 байт - ошибка
if (++rcCount >= G433_RSSI_COUNT) {
RSSI = 100 - errCount * 100 / G433_RSSI_COUNT;
errCount = rcCount = 0;
}
#endif
state = 0;
return size;
}
return 0;
}
// прочитает буфер в любой тип данных // прочитает буфер в любой тип данных
template <typename T> template <typename T>
bool readData(T &data) { bool readData(T &data) {
if (sizeof(T) > RX_BUF) return false; if (sizeof(T) > RX_BUF) return false; // великовато для буфера
uint8_t *ptr = (uint8_t*) &data; if (sizeof(T) != size) return false; // данные не соответствуют
uint8_t *ptr = (uint8_t*) &data;
for (uint16_t i = 0; i < sizeof(T); i++) *ptr++ = buffer[i]; for (uint16_t i = 0; i < sizeof(T); i++) *ptr++ = buffer[i];
return true; return true;
} }
// вернёт true при получении корректных данных
uint16_t gotData() {
if (parse == 2 && millis() - tmr2 >= 10) { // фрейм не закрыт
parse = size = 0; // приём окончен
if (byteCount > (1 + !!CRC_MODE)) { // если что то приняли
if (!bitCount) { // байт закрыт
if (CRC_MODE == G433_CRC8) { // CRC8
if (!G433_crc8(buffer, byteCount)) size = byteCount - 2;
} else if (CRC_MODE == G433_XOR) { // CRC XOR
if (!G433_crc_xor(buffer, byteCount)) size = byteCount - 2;
} else size = byteCount - 1; // без CRC
}
// расчёт RSSI
if (!size) errCount++;
if (++rcCount >= G433_RSSI_COUNT) {
RSSI = 100 - errCount * 100 / G433_RSSI_COUNT;
errCount = rcCount = 0;
}
}
return size;
}
return 0;
}
// получить качество приёма (процент успешных передач) // получить качество приёма (процент успешных передач)
uint8_t getRSSI() { uint8_t getRSSI() {
#ifndef G433_CUT_RSSI
return RSSI; return RSSI;
#endif
} }
// получить размер принятых данных // получить размер принятых данных
@@ -236,80 +266,37 @@ public:
// доступ к буферу // доступ к буферу
uint8_t buffer[RX_BUF + !!CRC_MODE]; uint8_t buffer[RX_BUF + !!CRC_MODE];
uint8_t byteBuf;
private: private:
bool fastRead(const uint8_t pin) { bool fastRead(const uint8_t pin) {
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
if (pin < 8) return bitRead(PIND, pin); if (pin < 8) return bitRead(PIND, pin);
else if (pin < 14) return bitRead(PINB, pin - 8); else if (pin < 14) return bitRead(PINB, pin - 8);
else if (pin < 20) return bitRead(PINC, pin - 14); else if (pin < 20) return bitRead(PINC, pin - 14);
#elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__) #elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__)
return bitRead(PINB, pin); return bitRead(PINB, pin);
#else #else
return digitalRead(pin); return digitalRead(pin);
#endif #endif
return 0; return 0;
} }
bool pinChanged() { bool pinChanged() {
bit = fastRead(RX_PIN); if (prevBit != fastRead(RX_PIN)) {
if (bit != prevBit) { prevBit = !prevBit;
prevBit = bit;
return 1; return 1;
} return 0; } return 0;
} }
void checkState() { bool prevBit;
uint32_t thisPulse = micros() - tmr; // время импульса volatile uint8_t state = 0;
if (parse == 1) { // в прошлый раз поймали фронт volatile uint8_t parse = 0, trains = 0;
#ifdef G433_MANCHESTER volatile uint32_t tmr = 0;
tmr += thisPulse; // сброс таймера приёма uint8_t bits = 0, bytes = 0;
#endif #ifndef G433_CUT_RSSI
if (thisPulse > START_MIN && thisPulse < START_MAX) { // старт бит? uint8_t errCount = 0, rcCount = 0, RSSI = 100;
tmr2 = millis(); // сброс таймера активности #endif
parse = 2; // ключ на старт
byteCount = bitCount = size = 0; // сброс
} else parse = 0; // не старт бит
} else if (parse == 2) { // идёт парсинг
#ifdef G433_MANCHESTER
if (thisPulse > FRAME_MIN && thisPulse < FRAME_MAX) { // фронт внутри таймфрейма
tmr += thisPulse; // синхронизируем тайминги
tmr2 = millis(); // сброс таймера активности
buffer[byteCount] >>= 1; // двигаем байт
buffer[byteCount] |= (bit << 7); // пишем данные
bitCount++; // счётчик битов
}
#else
uint8_t state = 2;
if (thisPulse > HALF_FRAME_MIN && thisPulse < HALF_FRAME_MAX) state = 0; // low бит
else if (thisPulse > FRAME_MIN && thisPulse < FRAME_MAX) state = 1; // high бит
if (state != 2) {
buffer[byteCount] >>= 1; // двигаем байт
buffer[byteCount] |= (state << 7); // пишем данные
bitCount++; // счётчик битов
tmr2 = millis(); // сброс таймера активности
}
#endif
if (bitCount == 8) { // собрали байт
bitCount = 0; // сброс
if (++byteCount >= RX_BUF) parse = 0; // буфер переполнен
}
}
#ifdef G433_MANCHESTER
if (bit && parse == 0) { // ловим фронт
parse = 1; // флаг на старт
tmr += thisPulse; // сброс таймера
}
#else
if (parse == 0) parse = 1; // принудительно стартуем
tmr += thisPulse; // сброс таймера приёма
#endif
}
bool bit, prevBit;
uint8_t parse = 0;
uint32_t tmr = 0, tmr2 = 0;
uint8_t bitCount = 0, byteCount = 0;
uint8_t errCount = 0, rcCount = 0, RSSI = 0;
}; };
#endif #endif