This commit is contained in:
Alex
2021-06-14 21:53:39 +03:00
parent 1e37f86364
commit ecfcdf1bf9
4 changed files with 119 additions and 96 deletions
+31 -5
View File
@@ -54,16 +54,17 @@ Gyver433_xx<пин, буфер, CRC> xx;
## Использование ## Использование
```cpp ```cpp
// ========= 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[]; // доступ к буферу для отладки uint8_t buffer[]; // доступ к буферу для отладки
// ========= Gyver433_RX ========= // ========= Gyver433_RX =========
uint8_t tick(); // неблокирующий приём, вернёт кол-во успешно принятых байт uint16_t tick(); // неблокирующий приём, вернёт кол-во успешно принятых байт
uint8_t tickWait(); // блокирующий приём, вернёт кол-во успешно принятых байт uint16_t tickWait(); // блокирующий приём (более надёжный), вернёт кол-во успешно принятых байт
uint16_t tickISR(); // тикер для прерывания по CHANGE (см. пример isr_rx)
bool readData(T &data); // прочитает буфер в любой тип данных (в указанную переменную) bool readData(T &data); // прочитает буфер в любой тип данных (в указанную переменную)
int getSize(); // получить размер принятых данных uint16_t getSize(); // получить размер принятых данных
bool gotData(); // вернёт true при получении корректных данных (если tick опрашивается в другом месте) uint16_t gotData(); // вернёт количество успешно принятых в tickISR() байт (см. пример isr_rx)
uint8_t buffer[]; // доступ к буферу для отладки uint8_t buffer[]; // доступ к буферу для отладки
// ============= CRC ============= // ============= CRC =============
@@ -115,6 +116,31 @@ void loop() {
} }
``` ```
### Приём в прерывании
```cpp
#define G433_SLOW_MODE
#include <Gyver433.h>
Gyver433_RX<2, 20> rx; // указали пин и размер буфера
void setup() {
Serial.begin(9600);
attachInterrupt(0, isr, CHANGE); // прерывание пина радио по CHANGE
}
void isr() {
rx.tickISR(); // спец тикер вызывается в прерывании
}
void loop() {
// вернёт количество удачно принятых в прерывании байт
if (rx.gotData()) {
Serial.write(rx.buffer, rx.size);
Serial.println();
}
delay(200); // имитация загруженного кода
}
```
<a id="versions"></a> <a id="versions"></a>
## Версии ## Версии
- v1.0 - v1.0
+2 -4
View File
@@ -11,13 +11,11 @@ void setup() {
} }
void isr() { void isr() {
rx.tick(); // тикер вызывается в прерывании rx.tickISR(); // спец тикер вызывается в прерывании по CHANGE
} }
void loop() { void loop() {
// .gotData() вернёт true при получении корректных данных // .gotData() вернёт количество удачно принятых в прерывании байт
// и сам сбросится до следующего приёма
// внутри gotData() встроен тик!
if (rx.gotData()) { if (rx.gotData()) {
Serial.write(rx.buffer, rx.size); Serial.write(rx.buffer, rx.size);
Serial.println(); Serial.println();
+1
View File
@@ -15,6 +15,7 @@ Gyver433_RX KEYWORD1
sendData KEYWORD2 sendData KEYWORD2
write KEYWORD2 write KEYWORD2
tick KEYWORD2 tick KEYWORD2
tickISR KEYWORD2
tickWait KEYWORD2 tickWait KEYWORD2
readData KEYWORD2 readData KEYWORD2
size KEYWORD2 size KEYWORD2
+52 -54
View File
@@ -143,36 +143,60 @@ public:
} }
// неблокирующий приём, вернёт кол-во успешно принятых байт // неблокирующий приём, вернёт кол-во успешно принятых байт
uint8_t tick() { uint16_t tick() {
uint32_t thisPulse = micros() - tmr; // время импульса checkState();
if (parse == 2 && thisPulse >= FRAME_TIME * 2) { // фрейм не закрыт return checkEnd();
parse = size = 0; // приём окончен
if (byteCount > 1) { // если что то приняли
if (CRC_MODE == G433_CRC8) { // CRC8
if (!G433_crc8(buffer, byteCount)) {
size = byteCount - 2;
dataReady = 1;
} }
} else if (CRC_MODE == G433_XOR) { // CRC XOR
if (!G433_crc_xor(buffer, byteCount)) { // tick для вызова в прерывании
size = byteCount - 2; void tickISR() {
dataReady = 1; checkState();
} }
} else { // без CRC
size = byteCount - 1; // блокирующий приём, вернёт кол-во успешно принятых байт
dataReady = 1; uint16_t tickWait() {
do {
if (tick()) return size;
} while (parse == 2);
return 0;
} }
// прочитает буфер в любой тип данных
template <typename T>
bool readData(T &data) {
if (sizeof(T) > RX_BUF) return false;
uint8_t *ptr = (uint8_t*) &data;
for (uint16_t i = 0; i < sizeof(T); i++) *ptr++ = buffer[i];
return true;
} }
// вернёт true при получении корректных данных
bool gotData() {
return checkEnd();
}
// получить размер принятых данных
uint16_t getSize() {
return size; return size;
} }
// размер принятых данных
uint16_t size = 0;
// доступ к буферу
uint8_t buffer[RX_BUF];
private:
void checkState() {
bool bit = fastRead(RX_PIN); // читаем пин bool bit = fastRead(RX_PIN); // читаем пин
if (bit != prevBit) { // ловим изменение сигнала if (bit != prevBit) { // ловим изменение сигнала
uint32_t thisPulse = micros() - tmr; // время импульса
if (parse == 1) { // в прошлый раз поймали фронт if (parse == 1) { // в прошлый раз поймали фронт
tmr += thisPulse; // сброс таймера tmr += thisPulse; // сброс таймера
if (thisPulse > START_MIN && thisPulse < START_MAX) { // старт бит? if (thisPulse > START_MIN && thisPulse < START_MAX) { // старт бит?
parse = 2; // ключ на старт parse = 2; // ключ на старт
byteCount = bitCount = size = 0; // сброс byteCount = bitCount = size = 0; // сброс
dataReady = 0; //dataReady = 0;
for (uint8_t i = 0; i < RX_BUF; i++) buffer[i] = 0; // чистим буфер for (uint8_t i = 0; i < RX_BUF; i++) buffer[i] = 0; // чистим буфер
} else parse = 0; // не старт бит } else parse = 0; // не старт бит
} else if (parse == 2) { // идёт парсинг } else if (parse == 2) { // идёт парсинг
@@ -194,47 +218,21 @@ public:
} }
prevBit = bit; prevBit = bit;
} }
return 0;
} }
uint16_t checkEnd() {
// блокирующий приём, вернёт кол-во успешно принятых байт if (parse == 2 && micros() - tmr >= FRAME_TIME * 2) { // фрейм не закрыт
uint8_t tickWait() { parse = size = 0; // приём окончен
do { if (byteCount > 1) { // если что то приняли
if (tick()) return size; if (CRC_MODE == G433_CRC8) { // CRC8
} while (parse == 2); if (!G433_crc8(buffer, byteCount)) size = byteCount - 2;
return 0; } else if (CRC_MODE == G433_XOR) { // CRC XOR
if (!G433_crc_xor(buffer, byteCount)) size = byteCount - 2;
} else size = byteCount - 1; // без CRC
} }
// прочитает буфер в любой тип данных
template <typename T>
bool readData(T &data) {
if (sizeof(T) > RX_BUF) return false;
uint8_t *ptr = (uint8_t*) &data;
for (uint16_t i = 0; i < sizeof(T); i++) *ptr++ = buffer[i];
return true;
}
// вернёт true при получении корректных данных
bool gotData() {
tick();
if (dataReady) {
dataReady = 0;
return 1;
} return 0;
}
// получить размер принятых данных
int getSize() {
return size; return size;
} }
return 0;
// размер принятых данных }
int size = 0;
// доступ к буферу
uint8_t buffer[RX_BUF];
private:
bool prevBit, dataReady = 0; bool prevBit, dataReady = 0;
uint8_t parse = 0; uint8_t parse = 0;
uint32_t tmr = 0; uint32_t tmr = 0;