diff --git a/README.md b/README.md index 19f62c6..69812a4 100644 --- a/README.md +++ b/README.md @@ -54,16 +54,17 @@ Gyver433_xx<пин, буфер, CRC> xx; ## Использование ```cpp // ========= Gyver433_TX ========= -void sendData(T &data); // отправить данные любого типа (CRC добавится автоматически) +void sendData(T &data); // отправить данные любого типа (CRC добавляется автоматически) void write(uint8_t* buf, uint8_t size); // отправить массив байт указанного размера (CRC не добавляется) uint8_t buffer[]; // доступ к буферу для отладки // ========= Gyver433_RX ========= -uint8_t tick(); // неблокирующий приём, вернёт кол-во успешно принятых байт -uint8_t tickWait(); // блокирующий приём, вернёт кол-во успешно принятых байт +uint16_t tick(); // неблокирующий приём, вернёт кол-во успешно принятых байт +uint16_t tickWait(); // блокирующий приём (более надёжный), вернёт кол-во успешно принятых байт +uint16_t tickISR(); // тикер для прерывания по CHANGE (см. пример isr_rx) bool readData(T &data); // прочитает буфер в любой тип данных (в указанную переменную) -int getSize(); // получить размер принятых данных -bool gotData(); // вернёт true при получении корректных данных (если tick опрашивается в другом месте) +uint16_t getSize(); // получить размер принятых данных +uint16_t gotData(); // вернёт количество успешно принятых в tickISR() байт (см. пример isr_rx) uint8_t buffer[]; // доступ к буферу для отладки // ============= CRC ============= @@ -115,6 +116,31 @@ void loop() { } ``` +### Приём в прерывании +```cpp +#define G433_SLOW_MODE +#include +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); // имитация загруженного кода +} +``` + ## Версии - v1.0 diff --git a/examples/isr_rx/isr_rx.ino b/examples/isr_rx/isr_rx.ino index b59039b..919cf02 100644 --- a/examples/isr_rx/isr_rx.ino +++ b/examples/isr_rx/isr_rx.ino @@ -11,13 +11,11 @@ void setup() { } void isr() { - rx.tick(); // тикер вызывается в прерывании + rx.tickISR(); // спец тикер вызывается в прерывании по CHANGE } void loop() { - // .gotData() вернёт true при получении корректных данных - // и сам сбросится до следующего приёма - // внутри gotData() встроен тик! + // .gotData() вернёт количество удачно принятых в прерывании байт if (rx.gotData()) { Serial.write(rx.buffer, rx.size); Serial.println(); diff --git a/keywords.txt b/keywords.txt index 0e7eb9a..47648b4 100644 --- a/keywords.txt +++ b/keywords.txt @@ -15,6 +15,7 @@ Gyver433_RX KEYWORD1 sendData KEYWORD2 write KEYWORD2 tick KEYWORD2 +tickISR KEYWORD2 tickWait KEYWORD2 readData KEYWORD2 size KEYWORD2 diff --git a/src/Gyver433.h b/src/Gyver433.h index 69d63e0..41ffe38 100644 --- a/src/Gyver433.h +++ b/src/Gyver433.h @@ -97,32 +97,32 @@ public: void write(uint8_t* buf, uint16_t size) { #ifdef G433_SLOW_MODE for (uint16_t i = 0; i < ((millis() - tmr > 400) ? TRAINING_AMOUNT_SLOW : TRAINING_AMOUNT); i++) { - #else - for (uint16_t i = 0; i < TRAINING_AMOUNT; i++) { - #endif - fastWrite(TX_PIN, 1); - G433_DELAY(FRAME_TIME); - fastWrite(TX_PIN, 0); - G433_DELAY(FRAME_TIME); - } - fastWrite(TX_PIN, 1); // старт - G433_DELAY(START_PULSE); // ждём - fastWrite(TX_PIN, 0); // старт бит - G433_DELAY(HALF_FRAME); // ждём - for (uint16_t n = 0; n < size; n++) { - uint8_t data = buf[n]; - for (uint8_t b = 0; b < 8; b++) { - fastWrite(TX_PIN, !(data & 1)); - G433_DELAY(HALF_FRAME); - fastWrite(TX_PIN, (data & 1)); - G433_DELAY(HALF_FRAME); - data >>= 1; + #else + for (uint16_t i = 0; i < TRAINING_AMOUNT; i++) { + #endif + fastWrite(TX_PIN, 1); + G433_DELAY(FRAME_TIME); + fastWrite(TX_PIN, 0); + G433_DELAY(FRAME_TIME); } - } - fastWrite(TX_PIN, 0); // конец передачи - #ifdef G433_SLOW_MODE - tmr = millis(); - #endif + fastWrite(TX_PIN, 1); // старт + G433_DELAY(START_PULSE); // ждём + fastWrite(TX_PIN, 0); // старт бит + G433_DELAY(HALF_FRAME); // ждём + for (uint16_t n = 0; n < size; n++) { + uint8_t data = buf[n]; + for (uint8_t b = 0; b < 8; b++) { + fastWrite(TX_PIN, !(data & 1)); + G433_DELAY(HALF_FRAME); + fastWrite(TX_PIN, (data & 1)); + G433_DELAY(HALF_FRAME); + data >>= 1; + } + } + fastWrite(TX_PIN, 0); // конец передачи + #ifdef G433_SLOW_MODE + tmr = millis(); + #endif } // доступ к буферу @@ -143,36 +143,60 @@ public: } // неблокирующий приём, вернёт кол-во успешно принятых байт - uint8_t tick() { - uint32_t thisPulse = micros() - tmr; // время импульса - if (parse == 2 && thisPulse >= FRAME_TIME * 2) { // фрейм не закрыт - 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)) { - size = byteCount - 2; - dataReady = 1; - } - } else { // без CRC - size = byteCount - 1; - dataReady = 1; - } - } - return size; - } + uint16_t tick() { + checkState(); + return checkEnd(); + } + + // tick для вызова в прерывании + void tickISR() { + checkState(); + } + + // блокирующий приём, вернёт кол-во успешно принятых байт + uint16_t tickWait() { + do { + if (tick()) return size; + } while (parse == 2); + return 0; + } + + // прочитает буфер в любой тип данных + template + 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; + } + + // размер принятых данных + uint16_t size = 0; + + // доступ к буферу + uint8_t buffer[RX_BUF]; + + private: + void checkState() { bool bit = fastRead(RX_PIN); // читаем пин if (bit != prevBit) { // ловим изменение сигнала + uint32_t thisPulse = micros() - tmr; // время импульса if (parse == 1) { // в прошлый раз поймали фронт tmr += thisPulse; // сброс таймера if (thisPulse > START_MIN && thisPulse < START_MAX) { // старт бит? parse = 2; // ключ на старт byteCount = bitCount = size = 0; // сброс - dataReady = 0; + //dataReady = 0; for (uint8_t i = 0; i < RX_BUF; i++) buffer[i] = 0; // чистим буфер } else parse = 0; // не старт бит } else if (parse == 2) { // идёт парсинг @@ -194,47 +218,21 @@ public: } prevBit = bit; } + } + uint16_t checkEnd() { + if (parse == 2 && micros() - tmr >= FRAME_TIME * 2) { // фрейм не закрыт + parse = size = 0; // приём окончен + if (byteCount > 1) { // если что то приняли + 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 + } + return size; + } return 0; } - - // блокирующий приём, вернёт кол-во успешно принятых байт - uint8_t tickWait() { - do { - if (tick()) return size; - } while (parse == 2); - return 0; - } - - // прочитает буфер в любой тип данных - template - 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; - } - - // размер принятых данных - int size = 0; - - // доступ к буферу - uint8_t buffer[RX_BUF]; - - private: bool prevBit, dataReady = 0; uint8_t parse = 0; uint32_t tmr = 0;