From 56c207b058b908b942f798600356d6a5d050447f Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 24 Jan 2024 12:23:18 +0300 Subject: [PATCH 01/51] isr optimizations --- IR_Decoder.cpp | 177 ++++++++++++++++++++++++++++++++++++++++++++++--- IR_Decoder.h | 26 +++++++- 2 files changed, 192 insertions(+), 11 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index fb33897..9293ef9 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -23,7 +23,7 @@ void IR_Decoder::writeToBuffer(bool bit) { }/* else { rawBuffer[(bufBitPos >> 3)] |= bit << (bufBitPos & ~(~0 << 3)); } */ - + Serial.print(bit); #ifdef IRDEBUG bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); #endif @@ -31,7 +31,7 @@ void IR_Decoder::writeToBuffer(bool bit) { if (isBufferOverflow) { //TODO: Буффер переполнен! } - +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //const auto testval = bufferBitSizeMax; if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) { switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { @@ -80,7 +80,7 @@ void IR_Decoder::writeToBuffer(bool bit) { break; } } - +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; } bufBitPos++; } @@ -168,19 +168,27 @@ uint16_t IR_Decoder::ceil_div(uint16_t val, uint16_t divider) { return ret; } -void IR_Decoder::listen(){ - if(isRecive && micros()-prevRise > IR_timeout*2) {isRecive = false;} +void IR_Decoder::listen() { + if (isRecive && micros() - prevRise > IR_timeout * 2) { + isRecive = false; + } } //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////// isr /////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// +void IR_Decoder::tick() { + if (firstUnHandledFront == nullptr) return; //Если данных нет - ничего не делаем -void IR_Decoder::isr() { // в прерывании вызываем isr() - if (isPairSending) return; + FrontStorage currentFront; + //найти следующий необработанный фронт/спад + noInterrupts(); + currentFront = *((FrontStorage*)firstUnHandledFront); + interrupts(); + //////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (micros() - prevRise > IR_timeout) { // первый + if (currentFront.time - prevRise > IR_timeout && currentFront.dir) { // первый ↑ isRecive = true; isPreamb = true; frontCounter = preambFronts - 1U; @@ -188,6 +196,156 @@ void IR_Decoder::isr() { // в прерывании вызываем isr() riseSyncTime = bitTime /* 1100 */; start_RX(); + // Serial.println(); + // Serial.print("currentFront.time: "); Serial.println(currentFront.time); + // Serial.print("currentFront.dir: "); Serial.println(currentFront.dir ? "UP" : "Down"); + // Serial.print("prevRise: "); Serial.println(prevRise); + // Serial.print("frontCounter: "); Serial.println(frontCounter); + + // prevRise = currentFront.time; + } + + if (frontCounter > 0) { // в преамбуле + uint32_t risePeriod = currentFront.time - prevRise; + if (currentFront.dir && risePeriod < IR_timeout) { // __/``` ↑ и мы в внутри пакета + + if (risePeriod < riseTimeMin << 1) { // fix рваной единицы + frontCounter += 2; + errorCounter++; + } else { + if (freeFrec) { riseSyncTime = (riseSyncTime + risePeriod / 2) / 2; } // tuner + } + } else { /* riseSyncTime = bitTime; */ } // сброс тюнера + frontCounter--; + // Serial.print("frontCounter: "); Serial.println(frontCounter); + } else { + if (isPreamb) {// первый фронт после + gotTune._set(riseSyncTime); + } + isPreamb = false; + } + + // определить направление фронта + if (currentFront.dir) { // Если __/``` ↑ + + uint16_t risePeriod = currentFront.time - prevRise; + uint16_t highTime = currentFront.time - prevFall; + uint16_t lowTime = prevFall - prevRise; + + int8_t highCount = 0; + int8_t lowCount = 0; + int8_t allCount = 0; + + if (risePeriod < IR_timeout && !isBufferOverflow && risePeriod > riseTimeMin) { + // Мы в пределах таймаута и буффер не переполнен и fix дроблёных единиц + + if (aroundRise(risePeriod)) { // тактирование есть, сигнал хороший - без ошибок(?) + + if (highTime > riseTimeMin >> 1) { // 1 + writeToBuffer(HIGH); + } else { // 0 + writeToBuffer(LOW); + } + + } else { // пропущены такты! сигнал средний // ошибка пропуска + highCount = ceil_div(highTime, riseTime); // предполагаемое колличество HIGH битов + lowCount = ceil_div(lowTime, riseTime); // предполагаемое колличество LOW битов + allCount = ceil_div(risePeriod, riseTime); // предполагаемое колличество всего битов + + if (highCount == 0 && highTime > riseTime / 3) { // fix короткой единицы (?)после пропуска нулей(?) + highCount++; + errorCounter++; + } + + if (lowCount + highCount > allCount) { // fix ошибочных сдвигов + if (lowCount > highCount) { // Лишние нули + lowCount = allCount - highCount; + } else if (lowCount < highCount) { // Лишние единицы + highCount = allCount - lowCount; + } else if (lowCount == highCount) {} // неизвестный случай + errorCounter += allCount; + } + + errorCounter += allCount; + + for (int8_t i = 0; i < lowCount && 8 - i; i++) { // отправка LOW битов, если есть + writeToBuffer(LOW); + } + + for (int8_t i = 0; i < highCount && 8 - i; i++) { // отправка HIGH битов, если есть + writeToBuffer(HIGH); + } + } + } + + if (risePeriod > riseTimeMax / 2 || highCount || lowCount) { // комплексный фикс рваной единицы + prevPrevRise = prevRise; + prevRise = currentFront.time; + } else { + errorCounter++; + + } + + } else { // Если ```\__ ↓ + + if (currentFront.time - prevFall > riseTimeMin) { + prevPrevFall = prevFall; + prevFall = currentFront.time; + } else { + + } + } + + if (isPreamb && frontCounter <= 0) { + prevRise = currentFront.time + riseTime; + } + + + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + firstUnHandledFront = firstUnHandledFront->next; //переместить флаг на следующий элемент (next or nullptr) +} + +void IR_Decoder::isr() { // в прерывании вызываем isr() + if (isPairSending) return; + + frontBuffer[currentFrontBufferWriteIndex].next = nullptr; + frontBuffer[currentFrontBufferWriteIndex].dir = (PIND >> isrPin) & 1; + frontBuffer[currentFrontBufferWriteIndex].time = micros(); + + if (firstUnHandledFront == nullptr) { + firstUnHandledFront = &frontBuffer[currentFrontBufferWriteIndex]; // Если нет необработанных данных - добавляем их + } else { + if (firstUnHandledFront == &frontBuffer[currentFrontBufferWriteIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его + firstUnHandledFront = firstUnHandledFront->next; + Serial.println(); + Serial.println("ERROR"); + Serial.println(); + } + } + + if (lastFront == nullptr) { + lastFront = &frontBuffer[currentFrontBufferWriteIndex]; + } else { + lastFront->next = &frontBuffer[currentFrontBufferWriteIndex]; + lastFront = &frontBuffer[currentFrontBufferWriteIndex]; + } + + + currentFrontBufferWriteIndex == (subBuffer - 1) ? currentFrontBufferWriteIndex = 0 : currentFrontBufferWriteIndex++; +} + + +void IR_Decoder::noFunc() { + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + if (micros() - prevRise > IR_timeout && (PIND >> isrPin) & 1) { // первый + isRecive = true; + isPreamb = true; + frontCounter = preambFronts - 1U; + errorCounter = 0; + riseSyncTime = bitTime /* 1100 */; + start_RX(); + Serial.println("First!"); + } if (frontCounter > 0) { // в преамбуле uint32_t risePeriod = micros() - prevRise; @@ -206,7 +364,7 @@ void IR_Decoder::isr() { // в прерывании вызываем isr() if (isPreamb) {// первый фронт после gotTune._set(riseSyncTime); } - isPreamb = false; + isPreamb = false; } // определить направление фронта @@ -325,6 +483,7 @@ void IR_Decoder::isr() { // в прерывании вызываем isr() #ifdef IRDEBUG digitalWrite(writeOp, isPreamb); #endif + //////////////////////////////////////////////////////////////////////////////////////////////////////////// } diff --git a/IR_Decoder.h b/IR_Decoder.h index 8397273..6eec030 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -21,6 +21,8 @@ #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) #define IR_timeout ((riseTimeMax * 8) + syncBits +1) // us // таймаут в 8 data + 3 sync + 1 +#define subBuffer 5 //Буфер для складирования фронтов, пока их не обработают + class IR_Encoder; class IR_Decoder : private IR_FOX { friend IR_Encoder; @@ -33,6 +35,8 @@ public: // @brief Для прерывания void isr(); + void tick(); + // @return Буффер переполнился bool isOverflow() { return isBufferOverflow; }; @@ -111,7 +115,6 @@ public: }; // class RawData : public Data { - // }; class Accept : public InputData { @@ -175,7 +178,6 @@ private: bool isWaitingAccept = false; uint16_t addrWaitingFrom = 0; - uint16_t addrFrom = 0; uint16_t riseSyncTime = bitTime; @@ -196,6 +198,26 @@ private: (bufferBitSizeMax / 8) + 1 : (bufferBitSizeMax / 8)); const uint8_t bufferDataSize = dataByteSizeMax; // + crc + //////////////////////////////////////////////////////////////////////// + void noFunc(); + volatile uint8_t currentFrontBufferWriteIndex; + struct FrontStorage { + volatile uint32_t time; + volatile bool dir; + volatile FrontStorage* next; + + FrontStorage& operator= (FrontStorage& val) { + this->next = val.next; + this->time = val.time; + this->dir = val.dir; + + return *this; + } + }; + volatile FrontStorage* lastFront = nullptr; + volatile FrontStorage* firstUnHandledFront = nullptr; + volatile FrontStorage frontBuffer[subBuffer]; + //////////////////////////////////////////////////////////////////////// uint8_t* rawBuffer = nullptr; uint8_t* dataBuffer = nullptr; From d629b24864cfd9a4bf490c50691f80f0698f8550 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 24 Jan 2024 16:13:03 +0300 Subject: [PATCH 02/51] fix extra zero, docs and debag --- IR_Decoder.cpp | 203 +++++++++++++++++++++++++++++++------------------ IR_Decoder.h | 31 +++++--- IR_config.h | 2 +- 3 files changed, 149 insertions(+), 87 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 9293ef9..a3f19af 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -8,6 +8,7 @@ IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), addrSelf(addr), encoder(encPair) { rawBuffer = new uint8_t[bufferRawSize] { 0 }; + dataBuffer = rawBuffer; prevRise = prevFall = prevPrevFall = prevPrevRise = 0; start_RX(); } @@ -17,73 +18,117 @@ IR_Decoder::~IR_Decoder() { } void IR_Decoder::writeToBuffer(bool bit) { - if (!isBufferOverflow && !isPreamb) { - if (HIGH_FIRST) { - rawBuffer[(bufBitPos >> 3)] |= bit << (7 - (bufBitPos & ~(~0 << 3))); - }/* else { - rawBuffer[(bufBitPos >> 3)] |= bit << (bufBitPos & ~(~0 << 3)); - } */ - Serial.print(bit); - #ifdef IRDEBUG - bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); - #endif + if (isBufferOverflow || isPreamb) return; - if (isBufferOverflow) { //TODO: Буффер переполнен! - - } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //const auto testval = bufferBitSizeMax; - if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) { - switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { - case IR_MSG_ACCEPT: - if (bufBitPos >= ((msgBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { - const uint8_t dataSize = msgBytes + addrBytes; - isRawAvaliable = true; - isMsgAvaliable = crcCheck(dataSize); - if (isMsgAvaliable && checkAddr(1, 2)) { - gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); - gotAccept._isAvaliable = true; - } - } - break; - - case IR_MSG_REQUEST: - if (bufBitPos >= ((msgBytes + addrBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { - const uint8_t dataSize = msgBytes + addrBytes + addrBytes; - isRawAvaliable = true; - isMsgAvaliable = (crcCheck(dataSize)); - if (isMsgAvaliable && checkAddr(3, 4)) { - gotRequest._isAvaliable = true; - gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); - } - } - break; - - - case IR_MSG_DATA_ACCEPT: - case IR_MSG_DATA_NOACCEPT: - if (bufBitPos >= ((bitPerByte + syncBits) * ((rawBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)) - syncBits) { - const uint8_t dataSize = (rawBuffer[0] & IR_MASK_MSG_INFO); - isRawAvaliable = true; - isMsgAvaliable = crcCheck(dataSize); - if (isMsgAvaliable && checkAddr(3, 4)) { - gotData._isAvaliable = true; - gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); - } else { - gotRawData._isAvaliable = true; - gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); - } - } - break; - - default: - break; - } - } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; } - bufBitPos++; + // Переключение флага, data или syncBit + if (bufBitPos == nextControlBit) { + nextControlBit += (isData ? syncBits : bitPerByte); + isData = !isData; + Serial.print(" "); } + Serial.print(bit); + + if (isData) { // Запись битов в dataBuffer + dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer%8); + i_dataBuffer++; + bufBitPos++; + i_syncBit = 0; + } else { // Проверка контрольных sync битов + if (i_syncBit == 0) { // Первый бит синхронизации + if (bit != dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))) { + bufBitPos++; + } else { + errorCounter++; + Serial.print("E"); + // Serial.print("bit: ");Serial.println(bit); + // Serial.print("dataBuffer: ");Serial.println(dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))); + } + } else { // Последующие биты синхронизации + bufBitPos++; + } + + i_syncBit++; + } + + // if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; } + + + + + + + + + + + + + + + + + + + + /* +#ifdef IRDEBUG + bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); +#endif + + if (isBufferOverflow) { //TODO: Буффер переполнен! + + } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //const auto testval = bufferBitSizeMax; + if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) { + switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { + case IR_MSG_ACCEPT: + if (bufBitPos >= ((msgBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { + const uint8_t dataSize = msgBytes + addrBytes; + isRawAvaliable = true; + isMsgAvaliable = crcCheck(dataSize); + if (isMsgAvaliable && checkAddr(1, 2)) { + gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + gotAccept._isAvaliable = true; + } + } + break; + + case IR_MSG_REQUEST: + if (bufBitPos >= ((msgBytes + addrBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { + const uint8_t dataSize = msgBytes + addrBytes + addrBytes; + isRawAvaliable = true; + isMsgAvaliable = (crcCheck(dataSize)); + if (isMsgAvaliable && checkAddr(3, 4)) { + gotRequest._isAvaliable = true; + gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + } + } + break; + + + case IR_MSG_DATA_ACCEPT: + case IR_MSG_DATA_NOACCEPT: + if (bufBitPos >= ((bitPerByte + syncBits) * ((rawBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)) - syncBits) { + const uint8_t dataSize = (rawBuffer[0] & IR_MASK_MSG_INFO); + isRawAvaliable = true; + isMsgAvaliable = crcCheck(dataSize); + if (isMsgAvaliable && checkAddr(3, 4)) { + gotData._isAvaliable = true; + gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); + } else { + gotRawData._isAvaliable = true; + gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); + } + } + break; + + default: + break; + } + }/**/ + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + } uint8_t* IR_Decoder::getDataBuffer(bool reset = false) { @@ -149,10 +194,20 @@ bool IR_Decoder::crcCheck(uint8_t len) { } void IR_Decoder::start_RX() { + // Serial.println(); + // Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN)); + // Serial.println(); + + resetAvaliable(); isBufferOverflow = false; memset(rawBuffer, 0x00, bufferRawSize); + bufBitPos = 0; + isData = true; + i_dataBuffer = 0; + nextControlBit = bitPerByte; + i_syncBit = 0; } void IR_Decoder::resetAvaliable() { @@ -308,14 +363,14 @@ void IR_Decoder::tick() { void IR_Decoder::isr() { // в прерывании вызываем isr() if (isPairSending) return; - frontBuffer[currentFrontBufferWriteIndex].next = nullptr; - frontBuffer[currentFrontBufferWriteIndex].dir = (PIND >> isrPin) & 1; - frontBuffer[currentFrontBufferWriteIndex].time = micros(); + subBuffer[currentSubBufferIndex].next = nullptr; + subBuffer[currentSubBufferIndex].dir = (PIND >> isrPin) & 1; + subBuffer[currentSubBufferIndex].time = micros(); if (firstUnHandledFront == nullptr) { - firstUnHandledFront = &frontBuffer[currentFrontBufferWriteIndex]; // Если нет необработанных данных - добавляем их + firstUnHandledFront = &subBuffer[currentSubBufferIndex]; // Если нет необработанных данных - добавляем их } else { - if (firstUnHandledFront == &frontBuffer[currentFrontBufferWriteIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его + if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его firstUnHandledFront = firstUnHandledFront->next; Serial.println(); Serial.println("ERROR"); @@ -324,14 +379,14 @@ void IR_Decoder::isr() { // в прерывании вызываем isr() } if (lastFront == nullptr) { - lastFront = &frontBuffer[currentFrontBufferWriteIndex]; + lastFront = &subBuffer[currentSubBufferIndex]; } else { - lastFront->next = &frontBuffer[currentFrontBufferWriteIndex]; - lastFront = &frontBuffer[currentFrontBufferWriteIndex]; + lastFront->next = &subBuffer[currentSubBufferIndex]; + lastFront = &subBuffer[currentSubBufferIndex]; } - currentFrontBufferWriteIndex == (subBuffer - 1) ? currentFrontBufferWriteIndex = 0 : currentFrontBufferWriteIndex++; + currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++; } diff --git a/IR_Decoder.h b/IR_Decoder.h index 6eec030..eac7a12 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -21,7 +21,7 @@ #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) #define IR_timeout ((riseTimeMax * 8) + syncBits +1) // us // таймаут в 8 data + 3 sync + 1 -#define subBuffer 5 //Буфер для складирования фронтов, пока их не обработают +#define subBufferSize 15 //Буфер для складирования фронтов, пока их не обработают class IR_Encoder; class IR_Decoder : private IR_FOX { @@ -200,13 +200,15 @@ private: const uint8_t bufferDataSize = dataByteSizeMax; // + crc //////////////////////////////////////////////////////////////////////// void noFunc(); - volatile uint8_t currentFrontBufferWriteIndex; + volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов + // Структура для хранения времени и направления фронта/спада struct FrontStorage { - volatile uint32_t time; - volatile bool dir; - volatile FrontStorage* next; + volatile uint32_t time; // Время + volatile bool dir; // Направление (true = ↑; false = ↓) + volatile FrontStorage* next; // Указатель на следующий связанный фронт/спад, или nullptr если конец - FrontStorage& operator= (FrontStorage& val) { + // Операторо присвоения + FrontStorage& operator= (FrontStorage& val) { this->next = val.next; this->time = val.time; this->dir = val.dir; @@ -214,9 +216,9 @@ private: return *this; } }; - volatile FrontStorage* lastFront = nullptr; - volatile FrontStorage* firstUnHandledFront = nullptr; - volatile FrontStorage frontBuffer[subBuffer]; + volatile FrontStorage* lastFront = nullptr; // Указатель последнего фронта/спада + volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада + volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов //////////////////////////////////////////////////////////////////////// uint8_t* rawBuffer = nullptr; uint8_t* dataBuffer = nullptr; @@ -229,9 +231,14 @@ private: private: uint8_t* getDataBuffer(bool reset = false); bool crcCheck(uint8_t len); - - inline void writeToBuffer(bool); - inline void start_RX(); + //////////////////////////////////////////////////////////////////////// + bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации + uint16_t i_dataBuffer; // Счётчик буфера данных + uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData + uint8_t i_syncBit; // Счётчик битов синхронизации + void writeToBuffer(bool); + //////////////////////////////////////////////////////////////////////// + void start_RX(); void resetAvaliable(); uint16_t ceil_div(uint16_t, uint16_t); diff --git a/IR_config.h b/IR_config.h index abb8b5b..b7f898b 100644 --- a/IR_config.h +++ b/IR_config.h @@ -146,7 +146,7 @@ public: case 2: for (size_t i = 0; i < s * 8; i++) { if (i == control) { - str += " "; + str += " "; control += bitPerByte; } From fdcb22b1a17f60ae7f0dace3c7e1b614e1b4e951 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 24 Jan 2024 18:24:46 +0300 Subject: [PATCH 03/51] fix extra zero --- IR_Decoder.cpp | 27 +++++++++++++++++---------- IR_Decoder.h | 2 +- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index a3f19af..21a3b28 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -24,31 +24,38 @@ void IR_Decoder::writeToBuffer(bool bit) { if (bufBitPos == nextControlBit) { nextControlBit += (isData ? syncBits : bitPerByte); isData = !isData; + i_syncBit = 0; Serial.print(" "); } - Serial.print(bit); + if (isData) { // Запись битов в dataBuffer - dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer%8); + if (i_dataBuffer % 8 == 7) { + Serial.print("+"); + } + dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer % 8); i_dataBuffer++; bufBitPos++; - i_syncBit = 0; } else { // Проверка контрольных sync битов if (i_syncBit == 0) { // Первый бит синхронизации - if (bit != dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))) { + Serial.print("~"); + if (bit != (dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - (i_dataBuffer - 1) % 8) & 1)) { bufBitPos++; + i_syncBit++; } else { + i_syncBit = 0; errorCounter++; Serial.print("E"); - // Serial.print("bit: ");Serial.println(bit); - // Serial.print("dataBuffer: ");Serial.println(dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))); + // Serial.print("bit: "); Serial.println(bit); + // Serial.print("dataBuffer: "); Serial.println(dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))); } } else { // Последующие биты синхронизации + Serial.print("`"); bufBitPos++; + i_syncBit++; } - - i_syncBit++; } + Serial.print(bit); // if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; } @@ -197,12 +204,12 @@ void IR_Decoder::start_RX() { // Serial.println(); // Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN)); // Serial.println(); - + resetAvaliable(); isBufferOverflow = false; memset(rawBuffer, 0x00, bufferRawSize); - + bufBitPos = 0; isData = true; i_dataBuffer = 0; diff --git a/IR_Decoder.h b/IR_Decoder.h index eac7a12..d93b8dc 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -21,7 +21,7 @@ #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) #define IR_timeout ((riseTimeMax * 8) + syncBits +1) // us // таймаут в 8 data + 3 sync + 1 -#define subBufferSize 15 //Буфер для складирования фронтов, пока их не обработают +#define subBufferSize 5 //Буфер для складирования фронтов, пока их не обработают class IR_Encoder; class IR_Decoder : private IR_FOX { From b05b9dc9d5dde7202ebea8d72ea71a11ea5f6079 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Thu, 25 Jan 2024 09:28:43 +0300 Subject: [PATCH 04/51] debug --- IR_Decoder.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 21a3b28..02f45d6 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -304,8 +304,14 @@ void IR_Decoder::tick() { if (aroundRise(risePeriod)) { // тактирование есть, сигнал хороший - без ошибок(?) if (highTime > riseTimeMin >> 1) { // 1 + #ifdef IRDEBUG + digitalWrite(wrHigh, 1); + #endif writeToBuffer(HIGH); } else { // 0 + #ifdef IRDEBUG + digitalWrite(wrLow, 1); + #endif writeToBuffer(LOW); } @@ -317,27 +323,49 @@ void IR_Decoder::tick() { if (highCount == 0 && highTime > riseTime / 3) { // fix короткой единицы (?)после пропуска нулей(?) highCount++; errorCounter++; + #ifdef IRDEBUG + errPulse(errOut, 2); + #endif } if (lowCount + highCount > allCount) { // fix ошибочных сдвигов if (lowCount > highCount) { // Лишние нули lowCount = allCount - highCount; + #ifdef IRDEBUG + errPulse(errOut, 3); + #endif } else if (lowCount < highCount) { // Лишние единицы highCount = allCount - lowCount; + #ifdef IRDEBUG + errPulse(errOut, 4); + #endif } else if (lowCount == highCount) {} // неизвестный случай errorCounter += allCount; } errorCounter += allCount; + #ifdef IRDEBUG + errPulse(errOut, 1); + #endif for (int8_t i = 0; i < lowCount && 8 - i; i++) { // отправка LOW битов, если есть writeToBuffer(LOW); + #ifdef IRDEBUG + digitalWrite(wrLow, 1); + #endif } for (int8_t i = 0; i < highCount && 8 - i; i++) { // отправка HIGH битов, если есть writeToBuffer(HIGH); + #ifdef IRDEBUG + digitalWrite(wrHigh, 1); + #endif } } + #ifdef IRDEBUG + digitalWrite(wrHigh, 0); + digitalWrite(wrLow, 0); + #endif } if (risePeriod > riseTimeMax / 2 || highCount || lowCount) { // комплексный фикс рваной единицы @@ -345,7 +373,9 @@ void IR_Decoder::tick() { prevRise = currentFront.time; } else { errorCounter++; - + #ifdef IRDEBUG + errPulse(errOut, 5); + #endif } } else { // Если ```\__ ↓ @@ -354,7 +384,9 @@ void IR_Decoder::tick() { prevPrevFall = prevFall; prevFall = currentFront.time; } else { - + #ifdef IRDEBUG + //errPulse(errOut, 5); + #endif } } @@ -362,9 +394,11 @@ void IR_Decoder::tick() { prevRise = currentFront.time + riseTime; } - +#ifdef IRDEBUG + digitalWrite(writeOp, isPreamb); +#endif //////////////////////////////////////////////////////////////////////////////////////////////////////////// - firstUnHandledFront = firstUnHandledFront->next; //переместить флаг на следующий элемент (next or nullptr) + firstUnHandledFront = firstUnHandledFront->next; //переместить флаг на следующий элемент для обработки (next or nullptr) } void IR_Decoder::isr() { // в прерывании вызываем isr() From 6691915aa0cb759d4124b9f3b652a78768247480 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Thu, 25 Jan 2024 14:33:59 +0300 Subject: [PATCH 05/51] check sync bits, fix rare invert error --- IR_Decoder.cpp | 303 ++++++++++++++++++++++++++++--------------------- IR_Decoder.h | 14 ++- 2 files changed, 179 insertions(+), 138 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 02f45d6..bfc6cbf 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -7,174 +7,183 @@ ) IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), addrSelf(addr), encoder(encPair) { - rawBuffer = new uint8_t[bufferRawSize] { 0 }; - dataBuffer = rawBuffer; + // rawBuffer = new uint8_t[bufferRawSize] { 0 }; + dataBuffer = new uint8_t[bufferDataSize] { 0 }; prevRise = prevFall = prevPrevFall = prevPrevRise = 0; start_RX(); } IR_Decoder::~IR_Decoder() { - delete rawBuffer; + delete dataBuffer; } void IR_Decoder::writeToBuffer(bool bit) { - if (isBufferOverflow || isPreamb) return; + if (i_dataBuffer >= bufferDataSize * 8 - 1) {// проверка переполнения + //TODO: Буффер переполнен! + isBufferOverflow = true; + } + if (isBufferOverflow || isPreamb || isWrongPack) return; // Переключение флага, data или syncBit if (bufBitPos == nextControlBit) { - nextControlBit += (isData ? syncBits : bitPerByte); + nextControlBit += (isData ? syncBits : bitPerByte); // маркер следующего переключения isData = !isData; - i_syncBit = 0; + i_syncBit = 0; // сброс счетчика битов синхронизации + err_syncBit = 0; // сброс счетчика ошибок синхронизации Serial.print(" "); } if (isData) { // Запись битов в dataBuffer + Serial.print(bit); + if (i_dataBuffer % 8 == 7) { - Serial.print("+"); + // Serial.print("+"); } dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer % 8); i_dataBuffer++; bufBitPos++; - } else { // Проверка контрольных sync битов + } else { + //********************************* Проверка контрольных sync битов*******************************// + ////////////////////// Исправление лишнего нуля /////////////////////// if (i_syncBit == 0) { // Первый бит синхронизации - Serial.print("~"); - if (bit != (dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - (i_dataBuffer - 1) % 8) & 1)) { + // Serial.print("~"); + if (bit != (dataBuffer[((i_dataBuffer - 1) / 8)] >> (7 - (i_dataBuffer - 1) % 8) & 1)) { bufBitPos++; i_syncBit++; } else { i_syncBit = 0; errorCounter++; - Serial.print("E"); + // Serial.print("E"); + err_syncBit++; // Serial.print("bit: "); Serial.println(bit); // Serial.print("dataBuffer: "); Serial.println(dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))); } } else { // Последующие биты синхронизации - Serial.print("`"); + // Serial.print("`"); bufBitPos++; i_syncBit++; } - } - Serial.print(bit); + ////////////////////// Проверка наличия битов синхранизации ////////////////////// + isWrongPack = err_syncBit >= syncBits; + if (isWrongPack) Serial.print("****************"); + }//**************************************************************************************************// - // if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; } - - - - - - - - - - - - - - - - - - - - /* + // Serial.print(bit); #ifdef IRDEBUG bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); #endif - if (isBufferOverflow) { //TODO: Буффер переполнен! - } - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //const auto testval = bufferBitSizeMax; - if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) { - switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { - case IR_MSG_ACCEPT: - if (bufBitPos >= ((msgBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { - const uint8_t dataSize = msgBytes + addrBytes; - isRawAvaliable = true; - isMsgAvaliable = crcCheck(dataSize); - if (isMsgAvaliable && checkAddr(1, 2)) { - gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); - gotAccept._isAvaliable = true; - } + + + + + + + + + + + + + + + + + + + /* +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //const auto testval = bufferBitSizeMax; + if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) { + switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { + case IR_MSG_ACCEPT: + if (bufBitPos >= ((msgBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { + const uint8_t dataSize = msgBytes + addrBytes; + isRawAvaliable = true; + isMsgAvaliable = crcCheck(dataSize); + if (isMsgAvaliable && checkAddr(1, 2)) { + gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + gotAccept._isAvaliable = true; } - break; + } + break; - case IR_MSG_REQUEST: - if (bufBitPos >= ((msgBytes + addrBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { - const uint8_t dataSize = msgBytes + addrBytes + addrBytes; - isRawAvaliable = true; - isMsgAvaliable = (crcCheck(dataSize)); - if (isMsgAvaliable && checkAddr(3, 4)) { - gotRequest._isAvaliable = true; - gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); - } + case IR_MSG_REQUEST: + if (bufBitPos >= ((msgBytes + addrBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { + const uint8_t dataSize = msgBytes + addrBytes + addrBytes; + isRawAvaliable = true; + isMsgAvaliable = (crcCheck(dataSize)); + if (isMsgAvaliable && checkAddr(3, 4)) { + gotRequest._isAvaliable = true; + gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); } - break; + } + break; - case IR_MSG_DATA_ACCEPT: - case IR_MSG_DATA_NOACCEPT: - if (bufBitPos >= ((bitPerByte + syncBits) * ((rawBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)) - syncBits) { - const uint8_t dataSize = (rawBuffer[0] & IR_MASK_MSG_INFO); - isRawAvaliable = true; - isMsgAvaliable = crcCheck(dataSize); - if (isMsgAvaliable && checkAddr(3, 4)) { - gotData._isAvaliable = true; - gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); - } else { - gotRawData._isAvaliable = true; - gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); - } + case IR_MSG_DATA_ACCEPT: + case IR_MSG_DATA_NOACCEPT: + if (bufBitPos >= ((bitPerByte + syncBits) * ((rawBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)) - syncBits) { + const uint8_t dataSize = (rawBuffer[0] & IR_MASK_MSG_INFO); + isRawAvaliable = true; + isMsgAvaliable = crcCheck(dataSize); + if (isMsgAvaliable && checkAddr(3, 4)) { + gotData._isAvaliable = true; + gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); + } else { + gotRawData._isAvaliable = true; + gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); } - break; + } + break; - default: - break; - } - }/**/ - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -} - -uint8_t* IR_Decoder::getDataBuffer(bool reset = false) { - if (!isRawAvaliable) { return nullptr; } - if (dataBuffer != nullptr) { delete dataBuffer; dataBuffer = nullptr; } // устранение утечки памяти - dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; // Буффер по максимуму - - bool isData = true; - bool controlCheckFirst = true; - bool controlCheck; - - uint8_t nextControlBit = bitPerByte; - uint16_t i_dataBuffer = 0; - for (uint16_t i = 0; i < dataBitSize; i++) { - if (i == nextControlBit) { - controlCheckFirst = true; - nextControlBit += (isData ? syncBits : bitPerByte); - isData = !isData; - } - - if (isData) { - dataBuffer[i_dataBuffer / 8] |= (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1) << 7 - (i_dataBuffer % 8); - i_dataBuffer++; - } else { // Проверка контрольных sync битов - if (controlCheckFirst) { - controlCheck = (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1); - controlCheckFirst = false; - } else { - controlCheck |= (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1); + default: + break; } + }/**/ + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - } - } - - isFilterBufferAvaliable = controlCheck; - if (reset) { resetAvaliable(); } - return dataBuffer; } +// uint8_t* IR_Decoder::getDataBuffer(bool reset = false) { +// if (!isRawAvaliable) { return nullptr; } +// if (dataBuffer != nullptr) { delete dataBuffer; dataBuffer = nullptr; } // устранение утечки памяти +// dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; // Буффер по максимуму + +// bool isData = true; +// bool controlCheckFirst = true; +// bool controlCheck; + +// uint8_t nextControlBit = bitPerByte; +// uint16_t i_dataBuffer = 0; +// for (uint16_t i = 0; i < dataBitSize; i++) { +// if (i == nextControlBit) { +// controlCheckFirst = true; +// nextControlBit += (isData ? syncBits : bitPerByte); +// isData = !isData; +// } + +// if (isData) { +// dataBuffer[i_dataBuffer / 8] |= (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1) << 7 - (i_dataBuffer % 8); +// i_dataBuffer++; +// } else { // Проверка контрольных sync битов +// if (controlCheckFirst) { +// controlCheck = (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1); +// controlCheckFirst = false; +// } else { +// controlCheck |= (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1); +// } + +// } +// } + +// isFilterBufferAvaliable = controlCheck; +// if (reset) { resetAvaliable(); } +// return dataBuffer; +// } + bool IR_Decoder::crcCheck(uint8_t len) { bool crcOK = false; // получить буффер, если нет @@ -208,13 +217,14 @@ void IR_Decoder::start_RX() { resetAvaliable(); isBufferOverflow = false; - memset(rawBuffer, 0x00, bufferRawSize); + memset(dataBuffer, 0x00, bufferDataSize); bufBitPos = 0; isData = true; i_dataBuffer = 0; nextControlBit = bitPerByte; i_syncBit = 0; + isWrongPack = false; } void IR_Decoder::resetAvaliable() { @@ -250,13 +260,19 @@ void IR_Decoder::tick() { interrupts(); //////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (currentFront.time - prevRise > IR_timeout && currentFront.dir) { // первый ↑ + if (currentFront.time - prevRise > IR_timeout) { // первый + // if (!currentFront.dir) { // ↓ + + errorCounter = 0; isRecive = true; isPreamb = true; - frontCounter = preambFronts - 1U; - errorCounter = 0; + // frontCounter = preambFronts - 1U; + // } else { // ↑ riseSyncTime = bitTime /* 1100 */; start_RX(); + frontCounter = preambFronts - 1U; + + // } // Serial.println(); // Serial.print("currentFront.time: "); Serial.println(currentFront.time); @@ -286,7 +302,6 @@ void IR_Decoder::tick() { } isPreamb = false; } - // определить направление фронта if (currentFront.dir) { // Если __/``` ↑ @@ -297,8 +312,10 @@ void IR_Decoder::tick() { int8_t highCount = 0; int8_t lowCount = 0; int8_t allCount = 0; + bool invertErr = false; - if (risePeriod < IR_timeout && !isBufferOverflow && risePeriod > riseTimeMin) { + + if (risePeriod < IR_timeout && !isBufferOverflow && risePeriod > riseTimeMin && !isWrongPack) { // Мы в пределах таймаута и буффер не переполнен и fix дроблёных единиц if (aroundRise(risePeriod)) { // тактирование есть, сигнал хороший - без ошибок(?) @@ -339,7 +356,13 @@ void IR_Decoder::tick() { #ifdef IRDEBUG errPulse(errOut, 4); #endif - } else if (lowCount == highCount) {} // неизвестный случай + // неизвестный случай Инверсит след бит или соседние + // Очень редко + // TODO: Отловить проверить + } else if (lowCount == highCount) { + invertErr = true; + Serial.print("..."); + } errorCounter += allCount; } @@ -349,17 +372,33 @@ void IR_Decoder::tick() { #endif for (int8_t i = 0; i < lowCount && 8 - i; i++) { // отправка LOW битов, если есть - writeToBuffer(LOW); - #ifdef IRDEBUG - digitalWrite(wrLow, 1); - #endif + if (i == lowCount - 1 && invertErr) { + invertErr = false; + writeToBuffer(!LOW); + #ifdef IRDEBUG + digitalWrite(wrLow, 1); + #endif + } else { + writeToBuffer(LOW); + #ifdef IRDEBUG + digitalWrite(wrLow, 1); + #endif + } } for (int8_t i = 0; i < highCount && 8 - i; i++) { // отправка HIGH битов, если есть - writeToBuffer(HIGH); - #ifdef IRDEBUG - digitalWrite(wrHigh, 1); - #endif + if (i == highCount - 1 && invertErr) { + invertErr = false; + writeToBuffer(!HIGH); + #ifdef IRDEBUG + digitalWrite(wrLow, 1); + #endif + } else { + writeToBuffer(HIGH); + #ifdef IRDEBUG + digitalWrite(wrHigh, 1); + #endif + } } } #ifdef IRDEBUG @@ -427,7 +466,7 @@ void IR_Decoder::isr() { // в прерывании вызываем isr() } - currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++; + currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++; // Закольцовка буффера } diff --git a/IR_Decoder.h b/IR_Decoder.h index d93b8dc..95b05f8 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -19,7 +19,7 @@ #define riseTimeMax (riseTime + riseTolerance) #define riseTimeMin (riseTime - riseTolerance) #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) -#define IR_timeout ((riseTimeMax * 8) + syncBits +1) // us // таймаут в 8 data + 3 sync + 1 +#define IR_timeout (riseTimeMax * (8 + syncBits +1)) // us // таймаут в 8 data + 3 sync + 1 #define subBufferSize 5 //Буфер для складирования фронтов, пока их не обработают @@ -188,15 +188,16 @@ private: volatile bool isFilterBufferAvaliable = false; volatile bool isBufferOverflow = false; + bool isWrongPack = false; volatile bool isPreamb = false; // флаг начальной последовости bool HIGH_FIRST = true; // порядок приходящих битов //Буффер - const uint8_t bufferRawSize = - ((bufferBitSizeMax % 8 > 0) ? - (bufferBitSizeMax / 8) + 1 : - (bufferBitSizeMax / 8)); + // const uint8_t bufferRawSize = + // ((bufferBitSizeMax % 8 > 0) ? + // (bufferBitSizeMax / 8) + 1 : + // (bufferBitSizeMax / 8)); const uint8_t bufferDataSize = dataByteSizeMax; // + crc //////////////////////////////////////////////////////////////////////// void noFunc(); @@ -220,7 +221,7 @@ private: volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов //////////////////////////////////////////////////////////////////////// - uint8_t* rawBuffer = nullptr; + // uint8_t* rawBuffer = nullptr; uint8_t* dataBuffer = nullptr; volatile uint32_t prevRise, prevFall, prevPrevFall, prevPrevRise; @@ -236,6 +237,7 @@ private: uint16_t i_dataBuffer; // Счётчик буфера данных uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData uint8_t i_syncBit; // Счётчик битов синхронизации + uint8_t err_syncBit; // Счётчик ошибок синхронизации void writeToBuffer(bool); //////////////////////////////////////////////////////////////////////// void start_RX(); From 5bf3a2694875c52e9af429033ebc682dbc544c68 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Thu, 25 Jan 2024 15:46:11 +0300 Subject: [PATCH 06/51] dataPack changes done --- IR_Decoder.cpp | 113 +++++++++++++++++++------------------------------ 1 file changed, 44 insertions(+), 69 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index bfc6cbf..293312b 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -75,76 +75,57 @@ void IR_Decoder::writeToBuffer(bool bit) { #endif - - - - - - - - - - - - - - - - - - - /* -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //const auto testval = bufferBitSizeMax; - if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) { - switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { - case IR_MSG_ACCEPT: - if (bufBitPos >= ((msgBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { - const uint8_t dataSize = msgBytes + addrBytes; - isRawAvaliable = true; - isMsgAvaliable = crcCheck(dataSize); - if (isMsgAvaliable && checkAddr(1, 2)) { - gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); - gotAccept._isAvaliable = true; - } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //const auto testval = bufferBitSizeMax; + if ((i_dataBuffer >= (8 * msgBytes)) && !isMsgAvaliable) { + switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { + case IR_MSG_ACCEPT: + if (i_dataBuffer >= ((msgBytes + addrBytes + crcBytes) * bitPerByte)) { + const uint8_t dataSize = msgBytes + addrBytes; + isRawAvaliable = true; + isMsgAvaliable = crcCheck(dataSize); + if (isMsgAvaliable && checkAddr(1, 2)) { + gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + gotAccept._isAvaliable = true; } - break; + } + break; - case IR_MSG_REQUEST: - if (bufBitPos >= ((msgBytes + addrBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { - const uint8_t dataSize = msgBytes + addrBytes + addrBytes; - isRawAvaliable = true; - isMsgAvaliable = (crcCheck(dataSize)); - if (isMsgAvaliable && checkAddr(3, 4)) { - gotRequest._isAvaliable = true; - gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); - } + case IR_MSG_REQUEST: + if (i_dataBuffer >= ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte)) { + const uint8_t dataSize = msgBytes + addrBytes + addrBytes; + isRawAvaliable = true; + isMsgAvaliable = (crcCheck(dataSize)); + if (isMsgAvaliable && checkAddr(3, 4)) { + gotRequest._isAvaliable = true; + gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); } - break; + } + break; - case IR_MSG_DATA_ACCEPT: - case IR_MSG_DATA_NOACCEPT: - if (bufBitPos >= ((bitPerByte + syncBits) * ((rawBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)) - syncBits) { - const uint8_t dataSize = (rawBuffer[0] & IR_MASK_MSG_INFO); - isRawAvaliable = true; - isMsgAvaliable = crcCheck(dataSize); - if (isMsgAvaliable && checkAddr(3, 4)) { - gotData._isAvaliable = true; - gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); - } else { - gotRawData._isAvaliable = true; - gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); - } + case IR_MSG_DATA_ACCEPT: + case IR_MSG_DATA_NOACCEPT: + if (i_dataBuffer >= ((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte) { + // Serial.println("OK"); + const uint8_t dataSize = (dataBuffer[0] & IR_MASK_MSG_INFO); + isRawAvaliable = true; + isMsgAvaliable = crcCheck(dataSize); + if (isMsgAvaliable && checkAddr(3, 4)) { + gotData._isAvaliable = true; + gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); + } else { + gotRawData._isAvaliable = true; + gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); } - break; - - default: - break; - } - }/**/ - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + } + break; + default: + break; + } + }/**/ + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } // uint8_t* IR_Decoder::getDataBuffer(bool reset = false) { @@ -186,12 +167,6 @@ void IR_Decoder::writeToBuffer(bool bit) { bool IR_Decoder::crcCheck(uint8_t len) { bool crcOK = false; - // получить буффер, если нет - if (!isFilterBufferAvaliable) getDataBuffer(); - if (dataBuffer == nullptr) { - - return false; - } crcValue = 0; crcValue = (crc8(dataBuffer, 0, len, poly1) << 8) & ~((crc_t)0xFF); From d0e0af53c4894c8d64aa9e93edbacb4ff9032313 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Thu, 25 Jan 2024 16:24:14 +0300 Subject: [PATCH 07/51] clean and docs --- IR_Decoder.cpp | 1 - IR_Decoder.h | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 293312b..07c0fc7 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -205,7 +205,6 @@ void IR_Decoder::start_RX() { void IR_Decoder::resetAvaliable() { isRawAvaliable = false; isMsgAvaliable = false; - isFilterBufferAvaliable = false; } uint16_t IR_Decoder::ceil_div(uint16_t val, uint16_t divider) { diff --git a/IR_Decoder.h b/IR_Decoder.h index 95b05f8..becdaba 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -185,7 +185,6 @@ private: volatile bool isRawAvaliable = false; volatile bool isMsgAvaliable = false; - volatile bool isFilterBufferAvaliable = false; volatile bool isBufferOverflow = false; bool isWrongPack = false; @@ -240,10 +239,17 @@ private: uint8_t err_syncBit; // Счётчик ошибок синхронизации void writeToBuffer(bool); //////////////////////////////////////////////////////////////////////// + + /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных void start_RX(); + /// @brief Сброс флагов доступности данных void resetAvaliable(); - uint16_t ceil_div(uint16_t, uint16_t); + /// @brief Целочисленное деление с округлением вверх + /// @param val Значение + /// @param divider Делитель + /// @return Результат + uint16_t ceil_div(uint16_t val, uint16_t divider); //uint16_t sma = 0; void SMA(uint16_t); From 469d9875c80de5005a82989206197ea9c542c560 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Fri, 26 Jan 2024 10:42:37 +0300 Subject: [PATCH 08/51] docs and cleanup --- IR_Decoder.cpp | 566 ++++++++++++++++--------------------------------- IR_Decoder.h | 89 ++++---- IR_config.h | 2 +- 3 files changed, 235 insertions(+), 422 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 07c0fc7..0a31fa4 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -17,214 +17,41 @@ IR_Decoder::~IR_Decoder() { delete dataBuffer; } -void IR_Decoder::writeToBuffer(bool bit) { - if (i_dataBuffer >= bufferDataSize * 8 - 1) {// проверка переполнения - //TODO: Буффер переполнен! - isBufferOverflow = true; - } - if (isBufferOverflow || isPreamb || isWrongPack) return; - - // Переключение флага, data или syncBit - if (bufBitPos == nextControlBit) { - nextControlBit += (isData ? syncBits : bitPerByte); // маркер следующего переключения - isData = !isData; - i_syncBit = 0; // сброс счетчика битов синхронизации - err_syncBit = 0; // сброс счетчика ошибок синхронизации - Serial.print(" "); - } - - - if (isData) { // Запись битов в dataBuffer - Serial.print(bit); - - if (i_dataBuffer % 8 == 7) { - // Serial.print("+"); - } - dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer % 8); - i_dataBuffer++; - bufBitPos++; - } else { - //********************************* Проверка контрольных sync битов*******************************// - ////////////////////// Исправление лишнего нуля /////////////////////// - if (i_syncBit == 0) { // Первый бит синхронизации - // Serial.print("~"); - if (bit != (dataBuffer[((i_dataBuffer - 1) / 8)] >> (7 - (i_dataBuffer - 1) % 8) & 1)) { - bufBitPos++; - i_syncBit++; - } else { - i_syncBit = 0; - errorCounter++; - // Serial.print("E"); - err_syncBit++; - // Serial.print("bit: "); Serial.println(bit); - // Serial.print("dataBuffer: "); Serial.println(dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))); - } - } else { // Последующие биты синхронизации - // Serial.print("`"); - bufBitPos++; - i_syncBit++; - } - ////////////////////// Проверка наличия битов синхранизации ////////////////////// - isWrongPack = err_syncBit >= syncBits; - if (isWrongPack) Serial.print("****************"); - }//**************************************************************************************************// - - // Serial.print(bit); -#ifdef IRDEBUG - bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); -#endif - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //const auto testval = bufferBitSizeMax; - if ((i_dataBuffer >= (8 * msgBytes)) && !isMsgAvaliable) { - switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { - case IR_MSG_ACCEPT: - if (i_dataBuffer >= ((msgBytes + addrBytes + crcBytes) * bitPerByte)) { - const uint8_t dataSize = msgBytes + addrBytes; - isRawAvaliable = true; - isMsgAvaliable = crcCheck(dataSize); - if (isMsgAvaliable && checkAddr(1, 2)) { - gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); - gotAccept._isAvaliable = true; - } - } - break; - - case IR_MSG_REQUEST: - if (i_dataBuffer >= ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte)) { - const uint8_t dataSize = msgBytes + addrBytes + addrBytes; - isRawAvaliable = true; - isMsgAvaliable = (crcCheck(dataSize)); - if (isMsgAvaliable && checkAddr(3, 4)) { - gotRequest._isAvaliable = true; - gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); - } - } - break; - - - case IR_MSG_DATA_ACCEPT: - case IR_MSG_DATA_NOACCEPT: - if (i_dataBuffer >= ((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte) { - // Serial.println("OK"); - const uint8_t dataSize = (dataBuffer[0] & IR_MASK_MSG_INFO); - isRawAvaliable = true; - isMsgAvaliable = crcCheck(dataSize); - if (isMsgAvaliable && checkAddr(3, 4)) { - gotData._isAvaliable = true; - gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); - } else { - gotRawData._isAvaliable = true; - gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); - } - } - break; - - default: - break; - } - }/**/ - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -} - -// uint8_t* IR_Decoder::getDataBuffer(bool reset = false) { -// if (!isRawAvaliable) { return nullptr; } -// if (dataBuffer != nullptr) { delete dataBuffer; dataBuffer = nullptr; } // устранение утечки памяти -// dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; // Буффер по максимуму - -// bool isData = true; -// bool controlCheckFirst = true; -// bool controlCheck; - -// uint8_t nextControlBit = bitPerByte; -// uint16_t i_dataBuffer = 0; -// for (uint16_t i = 0; i < dataBitSize; i++) { -// if (i == nextControlBit) { -// controlCheckFirst = true; -// nextControlBit += (isData ? syncBits : bitPerByte); -// isData = !isData; -// } - -// if (isData) { -// dataBuffer[i_dataBuffer / 8] |= (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1) << 7 - (i_dataBuffer % 8); -// i_dataBuffer++; -// } else { // Проверка контрольных sync битов -// if (controlCheckFirst) { -// controlCheck = (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1); -// controlCheckFirst = false; -// } else { -// controlCheck |= (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1); -// } - -// } -// } - -// isFilterBufferAvaliable = controlCheck; -// if (reset) { resetAvaliable(); } -// return dataBuffer; -// } - -bool IR_Decoder::crcCheck(uint8_t len) { - bool crcOK = false; - - crcValue = 0; - crcValue = (crc8(dataBuffer, 0, len, poly1) << 8) & ~((crc_t)0xFF); - crcValue |= crc8(dataBuffer, 0, len + 1, poly2) & (crc_t)0xFF; - - if ( - crcValue && - dataBuffer[len] == (crcValue >> 8) & 0xFF && - dataBuffer[len + 1] == (crcValue & 0xFF) - ) { - crcOK = true; - } else { crcOK = false; } - - - return crcOK; -} - -void IR_Decoder::start_RX() { - // Serial.println(); - // Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN)); - // Serial.println(); - - - resetAvaliable(); - isBufferOverflow = false; - memset(dataBuffer, 0x00, bufferDataSize); - - bufBitPos = 0; - isData = true; - i_dataBuffer = 0; - nextControlBit = bitPerByte; - i_syncBit = 0; - isWrongPack = false; -} - -void IR_Decoder::resetAvaliable() { - isRawAvaliable = false; - isMsgAvaliable = false; -} - -uint16_t IR_Decoder::ceil_div(uint16_t val, uint16_t divider) { - int ret = val / divider; - if ((val << 4) / divider - (ret << 4) >= 8) - ret++; - return ret; -} - -void IR_Decoder::listen() { - if (isRecive && micros() - prevRise > IR_timeout * 2) { - isRecive = false; - } -} - -//////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////// isr /////////////////////////////////////////// + +void IR_Decoder::isr() { + if (isPairSending) return; + + subBuffer[currentSubBufferIndex].next = nullptr; + subBuffer[currentSubBufferIndex].dir = (PIND >> isrPin) & 1; + subBuffer[currentSubBufferIndex].time = micros(); + + if (firstUnHandledFront == nullptr) { + firstUnHandledFront = &subBuffer[currentSubBufferIndex]; // Если нет необработанных данных - добавляем их + } else { + if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его + firstUnHandledFront = firstUnHandledFront->next; + Serial.println(); + Serial.println("ERROR"); + Serial.println(); + } + } + + if (lastFront == nullptr) { + lastFront = &subBuffer[currentSubBufferIndex]; + } else { + lastFront->next = &subBuffer[currentSubBufferIndex]; + lastFront = &subBuffer[currentSubBufferIndex]; + } + + + currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++; // Закольцовка буффера +} + //////////////////////////////////////////////////////////////////////////////////// void IR_Decoder::tick() { + listen(); if (firstUnHandledFront == nullptr) return; //Если данных нет - ничего не делаем FrontStorage currentFront; @@ -240,11 +67,11 @@ void IR_Decoder::tick() { errorCounter = 0; isRecive = true; isPreamb = true; - // frontCounter = preambFronts - 1U; + // preambFrontCounter = preambFronts - 1U; // } else { // ↑ riseSyncTime = bitTime /* 1100 */; start_RX(); - frontCounter = preambFronts - 1U; + preambFrontCounter = preambFronts - 1U; // } @@ -252,24 +79,24 @@ void IR_Decoder::tick() { // Serial.print("currentFront.time: "); Serial.println(currentFront.time); // Serial.print("currentFront.dir: "); Serial.println(currentFront.dir ? "UP" : "Down"); // Serial.print("prevRise: "); Serial.println(prevRise); - // Serial.print("frontCounter: "); Serial.println(frontCounter); + // Serial.print("preambFrontCounter: "); Serial.println(preambFrontCounter); // prevRise = currentFront.time; } - if (frontCounter > 0) { // в преамбуле + if (preambFrontCounter > 0) { // в преамбуле uint32_t risePeriod = currentFront.time - prevRise; if (currentFront.dir && risePeriod < IR_timeout) { // __/``` ↑ и мы в внутри пакета if (risePeriod < riseTimeMin << 1) { // fix рваной единицы - frontCounter += 2; + preambFrontCounter += 2; errorCounter++; } else { if (freeFrec) { riseSyncTime = (riseSyncTime + risePeriod / 2) / 2; } // tuner } } else { /* riseSyncTime = bitTime; */ } // сброс тюнера - frontCounter--; - // Serial.print("frontCounter: "); Serial.println(frontCounter); + preambFrontCounter--; + // Serial.print("preambFrontCounter: "); Serial.println(preambFrontCounter); } else { if (isPreamb) {// первый фронт после gotTune._set(riseSyncTime); @@ -403,7 +230,7 @@ void IR_Decoder::tick() { } } - if (isPreamb && frontCounter <= 0) { + if (isPreamb && preambFrontCounter <= 0) { prevRise = currentFront.time + riseTime; } @@ -414,187 +241,170 @@ void IR_Decoder::tick() { firstUnHandledFront = firstUnHandledFront->next; //переместить флаг на следующий элемент для обработки (next or nullptr) } -void IR_Decoder::isr() { // в прерывании вызываем isr() - if (isPairSending) return; - - subBuffer[currentSubBufferIndex].next = nullptr; - subBuffer[currentSubBufferIndex].dir = (PIND >> isrPin) & 1; - subBuffer[currentSubBufferIndex].time = micros(); - - if (firstUnHandledFront == nullptr) { - firstUnHandledFront = &subBuffer[currentSubBufferIndex]; // Если нет необработанных данных - добавляем их - } else { - if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его - firstUnHandledFront = firstUnHandledFront->next; - Serial.println(); - Serial.println("ERROR"); - Serial.println(); - } +void IR_Decoder::listen() { + if (isRecive && micros() - prevRise > IR_timeout * 2) { + isRecive = false; } - - if (lastFront == nullptr) { - lastFront = &subBuffer[currentSubBufferIndex]; - } else { - lastFront->next = &subBuffer[currentSubBufferIndex]; - lastFront = &subBuffer[currentSubBufferIndex]; - } - - - currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++; // Закольцовка буффера } +void IR_Decoder::start_RX() { + // Serial.println(); + // Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN)); + // Serial.println(); -void IR_Decoder::noFunc() { - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (micros() - prevRise > IR_timeout && (PIND >> isrPin) & 1) { // первый - isRecive = true; - isPreamb = true; - frontCounter = preambFronts - 1U; - errorCounter = 0; - riseSyncTime = bitTime /* 1100 */; - start_RX(); - Serial.println("First!"); + resetAvaliable(); + isBufferOverflow = false; + memset(dataBuffer, 0x00, bufferDataSize); + + bufBitPos = 0; + isData = true; + i_dataBuffer = 0; + nextControlBit = bitPerByte; + i_syncBit = 0; + isWrongPack = false; +} + +void IR_Decoder::writeToBuffer(bool bit) { + if (i_dataBuffer >= bufferDataSize * 8 - 1) {// проверка переполнения + //TODO: Буффер переполнен! + isBufferOverflow = true; } - if (frontCounter > 0) { // в преамбуле - uint32_t risePeriod = micros() - prevRise; - if ((PIND >> isrPin) & 1 && risePeriod < IR_timeout) { // __/``` ↑ и мы в внутри пакета + if (isBufferOverflow || isPreamb || isWrongPack) return; - if (risePeriod < riseTimeMin << 1) { // fix рваной единицы - frontCounter += 2; - errorCounter++; + // Переключение флага, data или syncBit + if (bufBitPos == nextControlBit) { + nextControlBit += (isData ? syncBits : bitPerByte); // маркер следующего переключения + isData = !isData; + i_syncBit = 0; // сброс счетчика битов синхронизации + err_syncBit = 0; // сброс счетчика ошибок синхронизации + Serial.print(" "); + } + + + if (isData) { // Запись битов в dataBuffer + Serial.print(bit); + + if (i_dataBuffer % 8 == 7) { + // Serial.print("+"); + } + dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer % 8); // Запись в буффер + i_dataBuffer++; + bufBitPos++; + } else { + //********************************* Проверка контрольных sync битов*******************************// + ////////////////////// Исправление лишнего нуля /////////////////////// + if (i_syncBit == 0) { // Первый бит синхронизации + // Serial.print("~"); + if (bit != (dataBuffer[((i_dataBuffer - 1) / 8)] >> (7 - (i_dataBuffer - 1) % 8) & 1)) { + bufBitPos++; + i_syncBit++; } else { - if (freeFrec) { riseSyncTime = (riseSyncTime + risePeriod / 2) / 2; } // tuner + i_syncBit = 0; + errorCounter++; + // Serial.print("E"); + err_syncBit++; + // Serial.print("bit: "); Serial.println(bit); + // Serial.print("dataBuffer: "); Serial.println(dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))); } - } else { /* riseSyncTime = bitTime; */ } // сброс тюнера - frontCounter--; - //Serial.println(frontCounter); - } else { - if (isPreamb) {// первый фронт после - gotTune._set(riseSyncTime); + } else { // Последующие биты синхронизации + // Serial.print("`"); + bufBitPos++; + i_syncBit++; } - isPreamb = false; - } - - // определить направление фронта - if ((PIND >> isrPin) & 1) { // Если __/``` ↑ - - uint16_t risePeriod = micros() - prevRise; - uint16_t highTime = micros() - prevFall; - uint16_t lowTime = prevFall - prevRise; - - int8_t highCount = 0; - int8_t lowCount = 0; - int8_t allCount = 0; - - if (risePeriod < IR_timeout && !isBufferOverflow && risePeriod > riseTimeMin) { - // Мы в пределах таймаута и буффер не переполнен и fix дроблёных единиц - - - if (aroundRise(risePeriod)) { // тактирование есть, сигнал хороший - без ошибок(?) - - if (highTime > riseTimeMin >> 1) { // 1 - #ifdef IRDEBUG - digitalWrite(wrHigh, 1); - #endif - writeToBuffer(HIGH); - } else { // 0 - #ifdef IRDEBUG - digitalWrite(wrLow, 1); - #endif - writeToBuffer(LOW); - } - - } else { // пропущены такты! сигнал средний // ошибка пропуска - - - highCount = ceil_div(highTime, riseTime); // предполагаемое колличество HIGH битов - lowCount = ceil_div(lowTime, riseTime); // предполагаемое колличество LOW битов - allCount = ceil_div(risePeriod, riseTime); // предполагаемое колличество всего битов - - if (highCount == 0 && highTime > riseTime / 3) { // fix короткой единицы (?)после пропуска нулей(?) - highCount++; - errorCounter++; - #ifdef IRDEBUG - errPulse(errOut, 2); - #endif - } - - if (lowCount + highCount > allCount) { // fix ошибочных сдвигов - if (lowCount > highCount) { // Лишние нули - lowCount = allCount - highCount; - #ifdef IRDEBUG - errPulse(errOut, 3); - #endif - } else if (lowCount < highCount) { // Лишние единицы - highCount = allCount - lowCount; - #ifdef IRDEBUG - errPulse(errOut, 4); - #endif - } else if (lowCount == highCount) {} // неизвестный случай - errorCounter += allCount; - } - - errorCounter += allCount; - #ifdef IRDEBUG - errPulse(errOut, 1); - #endif - - - for (int8_t i = 0; i < lowCount && 8 - i; i++) { // отправка LOW битов, если есть - #ifdef IRDEBUG - digitalWrite(wrLow, 1); - #endif - writeToBuffer(LOW); - } - - for (int8_t i = 0; i < highCount && 8 - i; i++) { // отправка HIGH битов, если есть - #ifdef IRDEBUG - digitalWrite(wrHigh, 1); - #endif - writeToBuffer(HIGH); - } - - } - - #ifdef IRDEBUG - digitalWrite(wrHigh, 0); - digitalWrite(wrLow, 0); - #endif - } - - if (risePeriod > riseTimeMax >> 1 || highCount || lowCount) { // комплексный фикс рваной единицы - prevPrevRise = prevRise; - prevRise = micros(); - } else { - errorCounter++; - #ifdef IRDEBUG - errPulse(errOut, 5); - #endif - } - - } else { // Если ```\__ ↓ - - if (micros() - prevFall > riseTimeMin) { - prevPrevFall = prevFall; - prevFall = micros(); - } else { - #ifdef IRDEBUG - //errPulse(errOut, 5); - #endif - } - } - - if (isPreamb && frontCounter <= 0) { - prevRise = micros() + riseTime; - } + ////////////////////// Проверка наличия битов синхранизации ////////////////////// + isWrongPack = err_syncBit >= syncBits; + if (isWrongPack) Serial.print("****************"); + }//**************************************************************************************************// + // Serial.print(bit); #ifdef IRDEBUG - digitalWrite(writeOp, isPreamb); + bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); #endif - //////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //const auto testval = bufferBitSizeMax; + if ((i_dataBuffer >= (8 * msgBytes)) && !isCrcCorrect) { + uint16_t crcValue; + switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { + case IR_MSG_ACCEPT: + if (i_dataBuffer >= ((msgBytes + addrBytes + crcBytes) * bitPerByte)) { + const uint8_t dataSize = msgBytes + addrBytes; + isCrcCorrect = crcCheck(dataSize, crcValue); + if (isCrcCorrect && checkAddr(1, 2)) { + gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + gotAccept._isAvaliable = true; + } + } + break; + + case IR_MSG_REQUEST: + if (i_dataBuffer >= ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte)) { + const uint8_t dataSize = msgBytes + addrBytes + addrBytes; + isCrcCorrect = (crcCheck(dataSize, crcValue)); + if (isCrcCorrect && checkAddr(3, 4)) { + gotRequest._isAvaliable = true; + gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + } + } + break; + + + case IR_MSG_DATA_ACCEPT: + case IR_MSG_DATA_NOACCEPT: + if (i_dataBuffer >= ((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte) { + // Serial.println("OK"); + const uint8_t dataSize = (dataBuffer[0] & IR_MASK_MSG_INFO); + isCrcCorrect = crcCheck(dataSize, crcValue); + if (isCrcCorrect && checkAddr(3, 4)) { + gotData._isAvaliable = true; + gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); + } else { + gotRawData._isAvaliable = true; + gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); + } + } + break; + + default: + break; + } + }/**/ + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } +bool IR_Decoder::crcCheck(uint8_t len, uint16_t &crc) { + bool crcOK = false; + + crc = 0; + crc = (crc8(dataBuffer, 0, len, poly1) << 8) & ~((crc_t)0xFF); + crc |= crc8(dataBuffer, 0, len + 1, poly2) & (crc_t)0xFF; + + if ( + crc && + dataBuffer[len] == (crc >> 8) & 0xFF && + dataBuffer[len + 1] == (crc & 0xFF) + ) { + crcOK = true; + } else { crcOK = false; } + + + return crcOK; +} + +void IR_Decoder::resetAvaliable() { + isCrcCorrect = false; +} + +uint16_t IR_Decoder::ceil_div(uint16_t val, uint16_t divider) { + int ret = val / divider; + if ((val << 4) / divider - (ret << 4) >= 8) + ret++; + return ret; +} + + // IRDEBUG FUNC #ifdef IRDEBUG diff --git a/IR_Decoder.h b/IR_Decoder.h index becdaba..da05118 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -21,25 +21,31 @@ #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) #define IR_timeout (riseTimeMax * (8 + syncBits +1)) // us // таймаут в 8 data + 3 sync + 1 -#define subBufferSize 5 //Буфер для складирования фронтов, пока их не обработают +#define subBufferSize 7 //Буфер для складирования фронтов, пока их не обработают class IR_Encoder; class IR_Decoder : private IR_FOX { friend IR_Encoder; public: uint16_t addrSelf; - + /// @brief Конструктор + /// @param isrPin Номер вывода прерывания/данных от приёмника (2 или 3 для atmega 328p) + /// @param addr Адрес приёмника + /// @param encPair Указатель на передатчик, работающий в паре IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr); ~IR_Decoder(); - // @brief Для прерывания + // @brief Функция прерывания void isr(); + /// @brief Обработка приёмника, необходима для работы void tick(); // @return Буффер переполнился bool isOverflow() { return isBufferOverflow; }; + /// @brief Флаг приёма + /// @return Возвращает true, если происходит приём пакета bool isReciving() { return isRecive; }; // @brief Слушатель для работы isReciving() void listen(); @@ -157,58 +163,51 @@ public: } }; + /// @brief Контейнер с данными Data gotData; Data gotRawData; - // RawData gotRawData; + /// @brief Контейнер с подтверждением Accept gotAccept; + /// @brief Контейнер с запросом Request gotRequest; + /// @brief Контейнер с информацией подстройки RawTune gotTune; private: - const uint8_t isrPin; + const uint8_t isrPin; // Пин прерывания - IR_Encoder* encoder; - bool isPairSending = false; - bool IsPairSendLOW = false; + IR_Encoder* encoder; // Указатель на парный передатчик + bool isPairSending = false; // Флаг передачи парного передатчика + bool IsPairSendLOW = false; // - volatile bool isRecive = false; + volatile bool isRecive = false; // Флаг приёма - bool isWaitingAccept = false; - uint16_t addrWaitingFrom = 0; + bool isWaitingAccept = false; // Флаг ожидания подтверждения + uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение - uint16_t addrFrom = 0; + uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс - uint16_t riseSyncTime = bitTime; + bool isCrcCorrect = false; // Флаг корректности crc + bool isBufferOverflow = false; // Флаг переполнения буффера данных + bool isWrongPack = false; // Флаг битого пакета - volatile bool isRawAvaliable = false; + volatile bool isPreamb = false; // флаг начальной последовости + bool HIGH_FIRST = true; //TODO: порядок приходящих битов - volatile bool isMsgAvaliable = false; - - volatile bool isBufferOverflow = false; - bool isWrongPack = false; - - volatile bool isPreamb = false; // флаг начальной последовости - bool HIGH_FIRST = true; // порядок приходящих битов - - //Буффер - // const uint8_t bufferRawSize = - // ((bufferBitSizeMax % 8 > 0) ? - // (bufferBitSizeMax / 8) + 1 : - // (bufferBitSizeMax / 8)); const uint8_t bufferDataSize = dataByteSizeMax; // + crc //////////////////////////////////////////////////////////////////////// void noFunc(); - volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов - // Структура для хранения времени и направления фронта/спада - struct FrontStorage { - volatile uint32_t time; // Время - volatile bool dir; // Направление (true = ↑; false = ↓) - volatile FrontStorage* next; // Указатель на следующий связанный фронт/спад, или nullptr если конец + volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов + + struct FrontStorage { // Структура для хранения времени и направления фронта/спада + volatile uint32_t time; // Время + volatile bool dir; // Направление (true = ↑; false = ↓) + volatile FrontStorage* next; // Указатель на следующий связанный фронт/спад, или nullptr если конец // Операторо присвоения - FrontStorage& operator= (FrontStorage& val) { + FrontStorage& operator= (FrontStorage& val) { this->next = val.next; this->time = val.time; this->dir = val.dir; @@ -220,23 +219,27 @@ private: volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов //////////////////////////////////////////////////////////////////////// - // uint8_t* rawBuffer = nullptr; - uint8_t* dataBuffer = nullptr; + uint8_t* dataBuffer = nullptr; // Указатель на буффер данных + uint32_t prevRise,prevPrevRise, prevFall, prevPrevFall; // Время предыдущих фронтов/спадов + uint16_t errorCounter = 0; // Счётчик ошибок + int8_t preambFrontCounter = 0; // Счётчик __/``` ↑ преамбулы + int16_t bufBitPos = 0; // Позиция для записи бита в буффер - volatile uint32_t prevRise, prevFall, prevPrevFall, prevPrevRise; - volatile uint16_t errorCounter = 0; - volatile int8_t frontCounter = 0; - volatile int16_t bufBitPos = 0; - crc_t crcValue = 0; private: - uint8_t* getDataBuffer(bool reset = false); - bool crcCheck(uint8_t len); + /// @brief Проверка CRC. Проверяет len байт со значением crc, пришедшим в пакете + /// @param len Длина в байтах проверяемых данных + /// @param crc Результат рассчёта crc (Выходной параметр) + /// @return true если crc верно + bool crcCheck(uint8_t len, uint16_t &crc); //////////////////////////////////////////////////////////////////////// bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации uint16_t i_dataBuffer; // Счётчик буфера данных uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData uint8_t i_syncBit; // Счётчик битов синхронизации uint8_t err_syncBit; // Счётчик ошибок синхронизации + + /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация + /// @param Бит данных void writeToBuffer(bool); //////////////////////////////////////////////////////////////////////// diff --git a/IR_config.h b/IR_config.h index b7f898b..4614402 100644 --- a/IR_config.h +++ b/IR_config.h @@ -132,7 +132,7 @@ protected: } return crc; } -public: +// public: /// @brief Вывод массива байт в строковом формате /// @param d Указатель на массив /// @param s Размер массива From 02410cc78c105b5ea69b4b04d9a01a2e7a83bad2 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Fri, 26 Jan 2024 11:23:48 +0300 Subject: [PATCH 09/51] cleanup --- IR_Decoder.cpp | 2 +- IR_Decoder.h | 9 +++++---- IR_config.h | 20 ++++++++++---------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 0a31fa4..cb9cdfd 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -374,7 +374,7 @@ void IR_Decoder::writeToBuffer(bool bit) { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } -bool IR_Decoder::crcCheck(uint8_t len, uint16_t &crc) { +bool IR_Decoder::crcCheck(uint8_t len, crc_t &crc) { bool crcOK = false; crc = 0; diff --git a/IR_Decoder.h b/IR_Decoder.h index da05118..36e6cb8 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -23,6 +23,7 @@ #define subBufferSize 7 //Буфер для складирования фронтов, пока их не обработают + class IR_Encoder; class IR_Decoder : private IR_FOX { friend IR_Encoder; @@ -200,7 +201,7 @@ private: //////////////////////////////////////////////////////////////////////// void noFunc(); volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов - + struct FrontStorage { // Структура для хранения времени и направления фронта/спада volatile uint32_t time; // Время volatile bool dir; // Направление (true = ↑; false = ↓) @@ -220,7 +221,7 @@ private: volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов //////////////////////////////////////////////////////////////////////// uint8_t* dataBuffer = nullptr; // Указатель на буффер данных - uint32_t prevRise,prevPrevRise, prevFall, prevPrevFall; // Время предыдущих фронтов/спадов + uint32_t prevRise, prevPrevRise, prevFall, prevPrevFall; // Время предыдущих фронтов/спадов uint16_t errorCounter = 0; // Счётчик ошибок int8_t preambFrontCounter = 0; // Счётчик __/``` ↑ преамбулы int16_t bufBitPos = 0; // Позиция для записи бита в буффер @@ -230,14 +231,14 @@ private: /// @param len Длина в байтах проверяемых данных /// @param crc Результат рассчёта crc (Выходной параметр) /// @return true если crc верно - bool crcCheck(uint8_t len, uint16_t &crc); + bool crcCheck(uint8_t len, uint16_t& crc); //////////////////////////////////////////////////////////////////////// bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации uint16_t i_dataBuffer; // Счётчик буфера данных uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData uint8_t i_syncBit; // Счётчик битов синхронизации uint8_t err_syncBit; // Счётчик ошибок синхронизации - + /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация /// @param Бит данных void writeToBuffer(bool); diff --git a/IR_config.h b/IR_config.h index 4614402..aa020f4 100644 --- a/IR_config.h +++ b/IR_config.h @@ -11,7 +11,7 @@ IR_MSG_ACCEPT с адреса 0 воспринимается всеми устройствами -Адресное пространство: +Адресное пространство: Излучатели контрольных точек: 1000 ~ 1999 Излучатели без обратной связиЖ 2000 ~ 2999 @@ -70,6 +70,7 @@ msg type: /* /////////////////////////////////////////////////////////////////////////////////////*/ +typedef uint16_t crc_t; #define bytePerPack 3 // колличество байтов в пакете #ifndef freeFrec @@ -89,13 +90,12 @@ msg type: #define addrBytes 2 #define msgBytes 1 #define crcBytes 2 -typedef uint16_t crc_t; #define poly1 0x31 #define poly2 0x8C #define syncBits 3U // количество битов синхронизации #define dataByteSizeMax (msgBytes + addrBytes + addrBytes + bytePerPack + crcBytes) -// размер msg в битах // размер короткой посылки в битах + // размер msg в битах // размер короткой посылки в битах #define dataBitSize ((8 + syncBits) * dataByteSizeMax) // размер посылки с данными в битах #define bufferBitSizeMax (dataBitSize) // Размер буффера в битах @@ -111,9 +111,9 @@ typedef uint16_t crc_t; #define bitTakts (bitActiveTakts+bitPauseTakts*2U) // Общая длительность бита в тактах #define bitTime (bitTakts*carrierPeriod) // Общая длительность бита -const auto viewValue = bitTime; #define tolerance 300U + class IR_FOX { private: bool isSending = false; @@ -132,12 +132,12 @@ protected: } return crc; } -// public: - /// @brief Вывод массива байт в строковом формате - /// @param d Указатель на массив - /// @param s Размер массива - /// @param mode Формат вывода DEC, BIN - /// @return Готовая для вывода строка + // public: + /// @brief Вывод массива байт в строковом формате + /// @param d Указатель на массив + /// @param s Размер массива + /// @param mode Формат вывода DEC, BIN + /// @return Готовая для вывода строка String printBytes(uint8_t* d, uint8_t s, uint8_t mode = 10) { String str = ""; uint8_t control = bitPerByte; From e0fbc8502ddc69f8deb20279485fd7d50da49e29 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 6 Feb 2024 17:14:59 +0300 Subject: [PATCH 10/51] MultiGen isr --- IR_Encoder.cpp | 149 +++++++++++++++++++++++++++++++++++-------------- IR_Encoder.h | 53 ++++++++++++------ IR_config.h | 6 +- 3 files changed, 148 insertions(+), 60 deletions(-) diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index cad54f2..dd7291d 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -3,12 +3,18 @@ IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) { ir_out = pin; + pinMode(ir_out, OUTPUT); addrSelf = addr; decoder = decPair; carrierTune = tune; halfPeriod = (carrierPeriod / 2) - carrierTune; + dataBitCounter = 0 - preambFronts; + signal = noSignal; }; + + + IR_Encoder::~IR_Encoder() {}; void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { @@ -102,34 +108,105 @@ void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t } void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { - /*tmp*/bool LOW_FIRST = false;/*tmp*/ + digitalToggle(9); digitalToggle(9); + isSending = true; + if (decoder != nullptr) { decoder->isPairSending = isSending; } + cli(); + // toggleCounter = bitTakts*2 - 1; + #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) + // #define preambToggle (3*2-1) + toggleCounter = preambToggle; + preambBitCounter = preambPulse; + dataBitCounter = 0; + syncBitCounter = 0; - if (decoder != nullptr) { decoder->isPairSending = true; } + signal = preamb; + isSending = true; + state = HIGH; + sei(); +} - bool prev = 1; - bool next; - send_EMPTY(preambPulse); // преамбула - for (uint16_t byteNum = 0; byteNum < len; byteNum++) { - sendByte(ptr[byteNum], &prev, LOW_FIRST); - if (byteNum < len - 1) { - next = ptr[byteNum + 1] & (LOW_FIRST ? 0b00000001 : 0b10000000); - } else { - next = 0; +void IR_Encoder::isr() { + if (!isSending) return; + + ir_out_virtual = !ir_out_virtual && state; + + + if (!toggleCounter) { + + state = !state; + + switch (signal) { + case noSignal: + return; + break; + + case preamb: + toggleCounter = preambToggle; + if (!state) { // Низкий уровень - конец периода генерации + preambBitCounter--; + if (!preambBitCounter) { // Конец преамбулы, переход на следующий этап + isSending = false; + } + } + break; + + case data: + signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 + break; + + case sync: + signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 + break; + + default: + return; + break; } - addSync(&prev, &next); - } - if (decoder != nullptr) { decoder->isPairSending = false; } + } else { toggleCounter--; } +} + + + + +void old() {/////////////////////////////////////////////////////// + // void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { + // /*tmp*/bool LOW_FIRST = false;/*tmp*/ + + // if (decoder != nullptr) { decoder->isPairSending = true; } + + // bool prev = 1; + // bool next; + + // send_EMPTY(preambPulse); // преамбула + // for (uint16_t byteNum = 0; byteNum < len; byteNum++) { + // sendByte(ptr[byteNum], &prev, LOW_FIRST); + // if (byteNum < len - 1) { + // next = ptr[byteNum + 1] & (LOW_FIRST ? 0b00000001 : 0b10000000); + // } else { + // next = 0; + // } + // addSync(&prev, &next); + // } + + // if (decoder != nullptr) { decoder->isPairSending = false; } + + // } } void IR_Encoder::sendByte(uint8_t byte, bool* prev, bool LOW_FIRST) { uint8_t mask = LOW_FIRST ? 0b00000001 : 0b10000000; for (uint8_t bitShift = 8; bitShift; bitShift--) { + digitalWrite(9, HIGH); + digitalWrite(9, LOW); byte& mask ? send_HIGH(prev) : send_LOW(); *prev = byte & mask; LOW_FIRST ? mask <<= 1 : mask >>= 1; + digitalWrite(9, HIGH); + digitalWrite(9, LOW); } } @@ -152,39 +229,29 @@ void IR_Encoder::addSync(bool* prev, bool* next) { } void IR_Encoder::send_HIGH(bool prevBite = 1) { - if (prevBite) { - meanderBlock(bitPauseTakts * 2, halfPeriod, LOW); - meanderBlock(bitActiveTakts, halfPeriod, HIGH); - } else { // более короткий HIGH после нуля - meanderBlock(bitTakts - (bitActiveTakts - bitPauseTakts), halfPeriod, LOW); - meanderBlock(bitActiveTakts - bitPauseTakts, halfPeriod, HIGH); - } + + // if (/* prevBite */1) { + // meanderBlock(bitPauseTakts * 2, halfPeriod, LOW); + // meanderBlock(bitActiveTakts, halfPeriod, HIGH); + // } else { // более короткий HIGH после нуля + // meanderBlock(bitTakts - (bitActiveTakts - bitPauseTakts), halfPeriod, LOW); + // meanderBlock(bitActiveTakts - bitPauseTakts, halfPeriod, HIGH); + // } + } void IR_Encoder::send_LOW() { - meanderBlock(bitPauseTakts, halfPeriod, LOW); - meanderBlock(bitActiveTakts, halfPeriod, LOW); - meanderBlock(bitPauseTakts, halfPeriod, HIGH); + // meanderBlock(bitPauseTakts, halfPeriod, LOW); + // meanderBlock(bitActiveTakts, halfPeriod, LOW); + // meanderBlock(bitPauseTakts, halfPeriod, HIGH); } void IR_Encoder::send_EMPTY(uint8_t count) { - for (size_t i = 0; i < count * 2; i++) { - meanderBlock(bitPauseTakts * 2 + bitActiveTakts, halfPeriod, prevPreambBit); - prevPreambBit = !prevPreambBit; - } + // for (size_t i = 0; i < count * 2; i++) { + // meanderBlock((bitPauseTakts * 2 + bitActiveTakts), halfPeriod, prevPreambBit); + // prevPreambBit = !prevPreambBit; + // } + // meanderBlock(bitPauseTakts * 2 + bitActiveTakts, halfPeriod, 0); //TODO: Отодвинуть преамбулу } -void IR_Encoder::meanderBlock(uint16_t count, uint16_t _period, bool high = true) { - for (uint16_t i = 0; i < count << 1; i++) { - if ((i & 1)) { // Если чётное - //PORTC &= ~(1 << 3); // LOW - digitalWrite(ir_out, high ? LOW : LOW); - } else { // Если не четное - //PORTC |= 1 << 3; // HIGH - digitalWrite(ir_out, high ? HIGH : LOW); - } - - delayMicroseconds(_period); - } -} \ No newline at end of file diff --git a/IR_Encoder.h b/IR_Encoder.h index 42ec69b..3cf5569 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -6,22 +6,16 @@ class IR_Decoder; class IR_Encoder : IR_FOX { friend IR_Decoder; + friend void isr(IR_Encoder& e); public: - /// @brief Вывод передатчика - uint8_t ir_out; - /// @brief Адрес передатчика - uint16_t addrSelf; + uint8_t ir_out; /// @brief Вывод передатчика + uint16_t addrSelf; /// @brief Адрес передатчика private: - /// @brief предыдущий бит преамбулы - bool prevPreambBit = true; + uint8_t carrierTune; /// @brief Подстройка несущей частоты + uint8_t halfPeriod; /// @brief полупериод несущей частоты - /// @brief Подстройка несущей частоты - uint8_t carrierTune; - - /// @brief полупериод несущей частоты - uint8_t halfPeriod; public: /// @brief Класс передатчика @@ -35,23 +29,50 @@ public: void sendData(uint16_t addrTo, T& data, bool needAccept = false); void sendACK(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false); void sendRequest(uint16_t addrTo, uint8_t addInfo = 0); - + void rawSend(uint8_t* ptr, uint8_t len); + void isr(); ~IR_Encoder(); + volatile bool ir_out_virtual; private: IR_Decoder* decoder; - void meanderBlock(uint16_t count, uint16_t _period, bool isNoPause = true); + void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType); void sendByte(uint8_t byte, bool* prev, bool LOW_FIRST); void addSync(bool* prev, bool* next); void send_HIGH(bool = 1); void send_LOW(); void send_EMPTY(uint8_t count); - void rawSend(uint8_t* ptr, uint8_t len); - void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType); + + enum SignalPart : uint8_t { + noSignal = 0, + preamb = 1, + data = 2, // 2 должен инвертироваться в sync + sync = (uint8_t)~(uint8_t)2U // 253 должен инвертироваться в data + }; + + + volatile bool isSending = false; + // volatile bool genState = HIGH; + + volatile bool state; /// @brief Текущий уровень генерации + volatile uint8_t toggleCounter; /// @brief Счётчик переключений + volatile uint8_t preambBitCounter; + volatile uint8_t dataBitCounter; + volatile uint8_t syncBitCounter; + + volatile uint8_t preambFrontCounter; + volatile uint8_t dataFrontCounter; + volatile uint8_t syncFrontCounter; + + // uint8_t bitSequence[2]; + // volatile uint32_t toggle_counter; + + SignalPart signal; + + }; - //////////////////////////////////////////////////////////////////////////////////////////////// template diff --git a/IR_config.h b/IR_config.h index aa020f4..bc996a9 100644 --- a/IR_config.h +++ b/IR_config.h @@ -106,10 +106,10 @@ typedef uint16_t crc_t; #define carrierPeriod (1000000U/carrierFrec) // период несущей в us // В процессе работы значения будут отклонятся в соответствии с предыдущим битом -#define bitActiveTakts 25U // длительность единицы в тактах -#define bitPauseTakts 6U // длительность нуля в тактах +#define bitActiveTakts 25U // длительность высокого уровня в тактах +#define bitPauseTakts 6U // длительность низкого уровня в тактах -#define bitTakts (bitActiveTakts+bitPauseTakts*2U) // Общая длительность бита в тактах +#define bitTakts (bitActiveTakts+(bitPauseTakts*2U)) // Общая длительность бита в тактах #define bitTime (bitTakts*carrierPeriod) // Общая длительность бита #define tolerance 300U From 8d5b2f6e3c7d049542441655ce6f1bad9dc8d59b Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 7 Feb 2024 18:00:13 +0300 Subject: [PATCH 11/51] bit generator --- IR_Encoder.cpp | 68 +++++++++++++++++++++++++++++++++----------------- IR_Encoder.h | 21 +++++++++++++--- 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index dd7291d..e187c44 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -13,9 +13,10 @@ IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* signal = noSignal; }; - - -IR_Encoder::~IR_Encoder() {}; +IR_Encoder::~IR_Encoder() { + delete [] bitHigh; + delete [] bitLow; +}; void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { uint8_t* ptr = new uint8_t[msgBytes + addrBytes + crcBytes] { 0 }; @@ -108,21 +109,28 @@ void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t } void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { + cli(); digitalToggle(9); digitalToggle(9); isSending = true; if (decoder != nullptr) { decoder->isPairSending = isSending; } - cli(); - // toggleCounter = bitTakts*2 - 1; - #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) - // #define preambToggle (3*2-1) - toggleCounter = preambToggle; - preambBitCounter = preambPulse; - dataBitCounter = 0; - syncBitCounter = 0; + // #define preambToggle 2*2-1 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + toggleCounter = preambToggle; // Первая генерация для первого signal + + preambBitCounter; + dataBitCounter = 3/* len * 8 */; + syncBitCounter = syncBits; + + preambFrontCounter = preambPulse * 2 - 1; // -1 за счёт генерации уже на этапе сразу после инициализации + dataFrontCounter = bitPerByte * 2; + syncFrontCounter; signal = preamb; isSending = true; state = HIGH; + + currentBit = bitHigh; sei(); } @@ -132,32 +140,43 @@ void IR_Encoder::isr() { ir_out_virtual = !ir_out_virtual && state; + if (toggleCounter == 0) { - if (!toggleCounter) { - - state = !state; - + IsrStart: switch (signal) { case noSignal: + isSending = false; return; break; case preamb: - toggleCounter = preambToggle; - if (!state) { // Низкий уровень - конец периода генерации - preambBitCounter--; - if (!preambBitCounter) { // Конец преамбулы, переход на следующий этап - isSending = false; - } + if (preambFrontCounter == 0) { // Конец преамбулы, переход на следующий signal + signal = data; + state = !LOW; // Инверсное состояние первой генерации следующего signal + goto IsrStart; // Применение новых параметров в этй же итерации прерывания + } else { + preambFrontCounter--; + toggleCounter = preambToggle; // Вторая и последующие генерации для этого signal } + break; case data: - signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 + if (dataFrontCounter == 0) { // Конец преамбулы, переход на следующий signal + signal = noSignal; + // state = HIGH; + isSending = false; + } else { + toggleCounter = currentBit[!state]; + dataFrontCounter--; + } + + + // signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 break; case sync: - signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 + // signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 break; default: @@ -165,6 +184,9 @@ void IR_Encoder::isr() { break; } + state = !state; + + } else { toggleCounter--; } } diff --git a/IR_Encoder.h b/IR_Encoder.h index 3cf5569..ae30c07 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -33,7 +33,7 @@ public: void isr(); ~IR_Encoder(); - volatile bool ir_out_virtual; + volatile bool ir_out_virtual; private: IR_Decoder* decoder; void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType); @@ -64,10 +64,23 @@ private: volatile uint8_t dataFrontCounter; volatile uint8_t syncFrontCounter; - // uint8_t bitSequence[2]; - // volatile uint32_t toggle_counter; + struct BitSequence { + uint8_t low; + uint8_t high; + }; + static inline uint8_t* bitHigh = new uint8_t[2] { + (bitPauseTakts * 2) * 2 - 1, + (bitActiveTakts) * 2 - 1 + }; + static inline uint8_t* bitLow = new uint8_t[2] { + (bitPauseTakts + bitActiveTakts) * 2 - 1, + (bitPauseTakts) * 2 - 1 + }; + uint8_t* currentBit; - SignalPart signal; + // uint8_t bitSequence[2]; + + volatile SignalPart signal; From b272b6031c514560774dc77e661f686bd664adc4 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Thu, 8 Feb 2024 17:18:33 +0300 Subject: [PATCH 12/51] signal generator --- IR_Decoder.cpp | 6 ++-- IR_Decoder.h | 1 - IR_Encoder.cpp | 89 +++++++++++++++++++++++++++++++++++--------------- IR_Encoder.h | 22 ++++++++----- IR_config.h | 6 ++-- 5 files changed, 82 insertions(+), 42 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index cb9cdfd..d652c9b 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -8,7 +8,7 @@ IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), addrSelf(addr), encoder(encPair) { // rawBuffer = new uint8_t[bufferRawSize] { 0 }; - dataBuffer = new uint8_t[bufferDataSize] { 0 }; + dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; prevRise = prevFall = prevPrevFall = prevPrevRise = 0; start_RX(); } @@ -255,7 +255,7 @@ void IR_Decoder::start_RX() { resetAvaliable(); isBufferOverflow = false; - memset(dataBuffer, 0x00, bufferDataSize); + memset(dataBuffer, 0x00, dataByteSizeMax); bufBitPos = 0; isData = true; @@ -266,7 +266,7 @@ void IR_Decoder::start_RX() { } void IR_Decoder::writeToBuffer(bool bit) { - if (i_dataBuffer >= bufferDataSize * 8 - 1) {// проверка переполнения + if (i_dataBuffer >= dataByteSizeMax * 8 - 1) {// проверка переполнения //TODO: Буффер переполнен! isBufferOverflow = true; } diff --git a/IR_Decoder.h b/IR_Decoder.h index 36e6cb8..40ed47d 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -197,7 +197,6 @@ private: volatile bool isPreamb = false; // флаг начальной последовости bool HIGH_FIRST = true; //TODO: порядок приходящих битов - const uint8_t bufferDataSize = dataByteSizeMax; // + crc //////////////////////////////////////////////////////////////////////// void noFunc(); volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index e187c44..7dc47f5 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -1,7 +1,12 @@ #include "IR_Encoder.h" #include "IR_Decoder.h" +#define LoopOut 12 +#define ISR_Out 10 +#define TestOut 13 + IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) { + sendBuffer = new uint8_t[dataByteSizeMax] { 0 }; ir_out = pin; pinMode(ir_out, OUTPUT); addrSelf = addr; @@ -16,6 +21,7 @@ IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* IR_Encoder::~IR_Encoder() { delete [] bitHigh; delete [] bitLow; + delete [] sendBuffer; }; void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { @@ -109,74 +115,105 @@ void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t } void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { - cli(); digitalToggle(9); digitalToggle(9); + memset(sendBuffer, 0x00, dataByteSizeMax); + memcpy(sendBuffer, ptr, len); + sendLen = len; + // *sendBuffer = 0b10010011; isSending = true; + + cli(); if (decoder != nullptr) { decoder->isPairSending = isSending; } // #define preambToggle 2*2-1 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< toggleCounter = preambToggle; // Первая генерация для первого signal - preambBitCounter; - dataBitCounter = 3/* len * 8 */; - syncBitCounter = syncBits; + dataBitCounter = bitPerByte - 1; + dataByteCounter = 0; preambFrontCounter = preambPulse * 2 - 1; // -1 за счёт генерации уже на этапе сразу после инициализации - dataFrontCounter = bitPerByte * 2; - syncFrontCounter; + dataSequenceCounter = bitPerByte * 2; + syncSequenceCounter = syncBits * 2; signal = preamb; isSending = true; state = HIGH; - currentBit = bitHigh; + currentBitSequence = bitHigh; sei(); } + void IR_Encoder::isr() { if (!isSending) return; ir_out_virtual = !ir_out_virtual && state; - if (toggleCounter == 0) { - + if (toggleCounter) { + toggleCounter--; + } else { IsrStart: switch (signal) { case noSignal: + // сброс счетчиков + // ... isSending = false; return; break; case preamb: - if (preambFrontCounter == 0) { // Конец преамбулы, переход на следующий signal + if (preambFrontCounter) { + preambFrontCounter--; + toggleCounter = preambToggle; // Вторая и последующие генерации для этого signal + } else {// Конец преамбулы, переход на следующий signal signal = data; state = !LOW; // Инверсное состояние первой генерации следующего signal goto IsrStart; // Применение новых параметров в этй же итерации прерывания - } else { - preambFrontCounter--; - toggleCounter = preambToggle; // Вторая и последующие генерации для этого signal } break; case data: - if (dataFrontCounter == 0) { // Конец преамбулы, переход на следующий signal - signal = noSignal; - // state = HIGH; - isSending = false; - } else { - toggleCounter = currentBit[!state]; - dataFrontCounter--; + if (dataSequenceCounter) { + if (!(dataSequenceCounter & 1U)) { // если чётный - смена бита + currentBitSequence = ((sendBuffer[dataByteCounter] >> dataBitCounter) & 1U) ? bitHigh : bitLow; // определение текущего бита + dataBitCounter--; + } + toggleCounter = currentBitSequence[!state]; + dataSequenceCounter--; + } else { // Конец data, переход на следующий signal + syncLastBit = !((sendBuffer[dataByteCounter]) & 1U); + dataByteCounter++; + dataBitCounter = bitPerByte - 1; + dataSequenceCounter = bitPerByte * 2; + signal = sync; + goto IsrStart; // Применение новых параметров в этй же итерации прерывания } - - - // signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 break; case sync: - // signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 + if (syncSequenceCounter) { + if (!(syncSequenceCounter & 1U)) { // если чётный - смена бита + if (syncSequenceCounter == 2) { // Если последний бит + currentBitSequence = ((sendBuffer[dataByteCounter]) & 0b10000000) ? bitLow : bitHigh; + } else { + currentBitSequence = syncLastBit ? bitLow : bitHigh; // определение текущего бита + syncLastBit = !syncLastBit; + } + } + toggleCounter = currentBitSequence[!state]; + syncSequenceCounter--; + } else { // Конец sync, переход на следующий signal + signal = data; + syncSequenceCounter = syncBits * 2; + + if (dataByteCounter >= sendLen) { // определение конца данных + signal = noSignal; + } + goto IsrStart; // Применение новых параметров в этй же итерации прерывания + } break; default: @@ -185,9 +222,7 @@ void IR_Encoder::isr() { } state = !state; - - - } else { toggleCounter--; } + } } diff --git a/IR_Encoder.h b/IR_Encoder.h index ae30c07..cdbdb9c 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -46,23 +46,27 @@ private: enum SignalPart : uint8_t { noSignal = 0, preamb = 1, - data = 2, // 2 должен инвертироваться в sync - sync = (uint8_t)~(uint8_t)2U // 253 должен инвертироваться в data + data = 2, + sync = 3 }; + uint8_t sendLen; + uint8_t* sendBuffer; /// @brief Буффер данных для отправки volatile bool isSending = false; // volatile bool genState = HIGH; - volatile bool state; /// @brief Текущий уровень генерации - volatile uint8_t toggleCounter; /// @brief Счётчик переключений - volatile uint8_t preambBitCounter; + volatile bool state; /// @brief Текущий уровень генерации + + volatile uint8_t dataByteCounter; + + volatile uint8_t toggleCounter; /// @brief Счётчик переключений volatile uint8_t dataBitCounter; - volatile uint8_t syncBitCounter; volatile uint8_t preambFrontCounter; - volatile uint8_t dataFrontCounter; - volatile uint8_t syncFrontCounter; + volatile uint8_t dataSequenceCounter; + volatile uint8_t syncSequenceCounter; + volatile bool syncLastBit; struct BitSequence { uint8_t low; @@ -76,7 +80,7 @@ private: (bitPauseTakts + bitActiveTakts) * 2 - 1, (bitPauseTakts) * 2 - 1 }; - uint8_t* currentBit; + uint8_t* currentBitSequence = bitLow; // uint8_t bitSequence[2]; diff --git a/IR_config.h b/IR_config.h index bc996a9..c4eaacb 100644 --- a/IR_config.h +++ b/IR_config.h @@ -96,8 +96,8 @@ typedef uint16_t crc_t; #define dataByteSizeMax (msgBytes + addrBytes + addrBytes + bytePerPack + crcBytes) // размер msg в битах // размер короткой посылки в битах -#define dataBitSize ((8 + syncBits) * dataByteSizeMax) // размер посылки с данными в битах -#define bufferBitSizeMax (dataBitSize) // Размер буффера в битах +// #define dataBitSize ((8 + syncBits) * dataByteSizeMax) // размер посылки с данными в битах +// #define bufferBitSizeMax (dataBitSize) // Размер буффера в битах //const auto x = bufferBitSizeMax; #define preambFronts (preambPulse*2) // количество фронтов преамбулы @@ -113,6 +113,8 @@ typedef uint16_t crc_t; #define bitTime (bitTakts*carrierPeriod) // Общая длительность бита #define tolerance 300U + #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) + class IR_FOX { private: From 9cd391bda730e7fc05185e3d430682dc2dafb6f7 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Thu, 8 Feb 2024 17:55:10 +0300 Subject: [PATCH 13/51] fix syncBit --- IR_Encoder.cpp | 9 ++++++++- IR_Encoder.h | 7 ++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 7dc47f5..e4de370 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -24,6 +24,13 @@ IR_Encoder::~IR_Encoder() { delete [] sendBuffer; }; +void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false) { + uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; + uint8_t msgType = + ((needAccept ? IR_MSG_DATA_ACCEPT : IR_MSG_DATA_NOACCEPT) << 5) | ((packSize - crcBytes) & IR_MASK_MSG_INFO); + _sendData(addrTo, data, len, msgType); +} + void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { uint8_t* ptr = new uint8_t[msgBytes + addrBytes + crcBytes] { 0 }; @@ -184,7 +191,7 @@ void IR_Encoder::isr() { toggleCounter = currentBitSequence[!state]; dataSequenceCounter--; } else { // Конец data, переход на следующий signal - syncLastBit = !((sendBuffer[dataByteCounter]) & 1U); + syncLastBit = ((sendBuffer[dataByteCounter]) & 1U); dataByteCounter++; dataBitCounter = bitPerByte - 1; dataSequenceCounter = bitPerByte * 2; diff --git a/IR_Encoder.h b/IR_Encoder.h index cdbdb9c..f5652e9 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -27,6 +27,7 @@ public: template void sendData(uint16_t addrTo, T& data, bool needAccept = false); + void sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false); void sendACK(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false); void sendRequest(uint16_t addrTo, uint8_t addInfo = 0); void rawSend(uint8_t* ptr, uint8_t len); @@ -46,8 +47,8 @@ private: enum SignalPart : uint8_t { noSignal = 0, preamb = 1, - data = 2, - sync = 3 + data = 2, + sync = 3 }; uint8_t sendLen; @@ -87,7 +88,6 @@ private: volatile SignalPart signal; - }; //////////////////////////////////////////////////////////////////////////////////////////////// @@ -102,3 +102,4 @@ void IR_Encoder::sendData(uint16_t addrTo, T& data, bool needAccept = false) { / _sendData(addrTo, data, len, msgType); } + From 9d315c8f23759b95eaf4632d25962c9e9857d26d Mon Sep 17 00:00:00 2001 From: DashyFox Date: Mon, 12 Feb 2024 11:34:24 +0300 Subject: [PATCH 14/51] more static --- IR_Encoder.cpp | 86 ++++++++++++++++++++++---------------------------- IR_Encoder.h | 3 +- 2 files changed, 39 insertions(+), 50 deletions(-) diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index e4de370..7f2800b 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -6,7 +6,7 @@ #define TestOut 13 IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) { - sendBuffer = new uint8_t[dataByteSizeMax] { 0 }; + // sendBuffer = new uint8_t[dataByteSizeMax] { 0 }; ir_out = pin; pinMode(ir_out, OUTPUT); addrSelf = addr; @@ -21,7 +21,7 @@ IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* IR_Encoder::~IR_Encoder() { delete [] bitHigh; delete [] bitLow; - delete [] sendBuffer; + // delete [] sendBuffer; }; void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false) { @@ -32,99 +32,87 @@ void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool nee } void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { - uint8_t* ptr = new uint8_t[msgBytes + addrBytes + crcBytes] { 0 }; - - ptr[0] = IR_MSG_ACCEPT << 5; - ptr[0] |= addInfo & IR_MASK_MSG_INFO; + memset(sendBuffer, 0x00, dataByteSizeMax); + sendBuffer[0] = IR_MSG_ACCEPT << 5; + sendBuffer[0] |= addInfo & IR_MASK_MSG_INFO; // addr_self if (!forAll) { - ptr[1] = addrSelf >> 8 & 0xFF; - ptr[2] = addrSelf & 0xFF; + sendBuffer[1] = addrSelf >> 8 & 0xFF; + sendBuffer[2] = addrSelf & 0xFF; } // data crc - ptr[3] = crc8(ptr, 0, 3, poly1) & 0xFF; - ptr[4] = crc8(ptr, 0, 4, poly2) & 0xFF; + sendBuffer[3] = crc8(sendBuffer, 0, 3, poly1) & 0xFF; + sendBuffer[4] = crc8(sendBuffer, 0, 4, poly2) & 0xFF; - rawSend(ptr, msgBytes + addrBytes + crcBytes); - - // освобождение ресурсов - delete ptr; - ptr = nullptr; + rawSend(sendBuffer, msgBytes + addrBytes + crcBytes); } void IR_Encoder::sendRequest(uint16_t addrTo, uint8_t addInfo) { - uint8_t* ptr = new uint8_t[msgBytes + addrBytes + crcBytes] { 0 }; - - ptr[0] = IR_MSG_REQUEST << 5; - ptr[0] |= addInfo & IR_MASK_MSG_INFO; + memset(sendBuffer, 0x00, dataByteSizeMax); + sendBuffer[0] = IR_MSG_REQUEST << 5; + sendBuffer[0] |= addInfo & IR_MASK_MSG_INFO; // addr_self - ptr[1] = addrSelf >> 8 & 0xFF; - ptr[2] = addrSelf & 0xFF; + sendBuffer[1] = addrSelf >> 8 & 0xFF; + sendBuffer[2] = addrSelf & 0xFF; //addr_to - ptr[3] = addrTo >> 8 & 0xFF; - ptr[4] = addrTo & 0xFF; + sendBuffer[3] = addrTo >> 8 & 0xFF; + sendBuffer[4] = addrTo & 0xFF; // data crc - ptr[5] = crc8(ptr, 0, 5, poly1) & 0xFF; - ptr[6] = crc8(ptr, 0, 6, poly2) & 0xFF; + sendBuffer[5] = crc8(sendBuffer, 0, 5, poly1) & 0xFF; + sendBuffer[6] = crc8(sendBuffer, 0, 6, poly2) & 0xFF; - rawSend(ptr, msgBytes + addrBytes + addrBytes + crcBytes); - - // освобождение ресурсов - delete ptr; - ptr = nullptr; + rawSend(sendBuffer, msgBytes + addrBytes + addrBytes + crcBytes); } void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType) { + memset(sendBuffer, 0x00, dataByteSizeMax); uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; uint8_t dataStart = msgBytes + addrBytes + addrBytes; - // создание массива для отправки - uint8_t* ptr = new uint8_t[packSize] { 0 }; - //memset(ptr, 0, sizeof(ptr)); - // формирование массива // msg_type - ptr[0] = msgType; + sendBuffer[0] = msgType; // addr_self - ptr[1] = addrSelf >> 8 & 0xFF; - ptr[2] = addrSelf & 0xFF; + sendBuffer[1] = addrSelf >> 8 & 0xFF; + sendBuffer[2] = addrSelf & 0xFF; // addr_to - ptr[3] = addrTo >> 8 & 0xFF; - ptr[4] = addrTo & 0xFF; + sendBuffer[3] = addrTo >> 8 & 0xFF; + sendBuffer[4] = addrTo & 0xFF; for (uint16_t i = dataStart; i < dataStart + len; i++) { - ptr[i] = ((uint8_t*)data)[i - dataStart]; + sendBuffer[i] = ((uint8_t*)data)[i - dataStart]; } // data crc - ptr[packSize - crcBytes] = crc8(ptr, 0, packSize - crcBytes, poly1) & 0xFF; - ptr[packSize - crcBytes + 1] = crc8(ptr, 0, packSize - crcBytes + 1, poly2) & 0xFF; + sendBuffer[packSize - crcBytes] = crc8(sendBuffer, 0, packSize - crcBytes, poly1) & 0xFF; + sendBuffer[packSize - crcBytes + 1] = crc8(sendBuffer, 0, packSize - crcBytes + 1, poly2) & 0xFF; if (decoder != nullptr) { decoder->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); decoder->addrWaitingFrom = addrTo; } // отправка - rawSend(ptr, packSize); - - // освобождение ресурсов - delete ptr; - ptr = nullptr; + rawSend(sendBuffer, packSize); } void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { + if(isSending){ + //TODO: Обработка повторной отправки + return; + } + digitalToggle(9); digitalToggle(9); - memset(sendBuffer, 0x00, dataByteSizeMax); - memcpy(sendBuffer, ptr, len); + // memset(sendBuffer, 0x00, dataByteSizeMax); + // memcpy(sendBuffer, ptr, len); sendLen = len; // *sendBuffer = 0b10010011; isSending = true; diff --git a/IR_Encoder.h b/IR_Encoder.h index f5652e9..3070a86 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -52,7 +52,8 @@ private: }; uint8_t sendLen; - uint8_t* sendBuffer; /// @brief Буффер данных для отправки + uint8_t sendBuffer[dataByteSizeMax] { 0 }; /// @brief Буффер данных для отправки + // uint8_t volatile bool isSending = false; // volatile bool genState = HIGH; From 1c79b812d32c6382d76985f9582e76a917f11d86 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Mon, 12 Feb 2024 16:41:16 +0300 Subject: [PATCH 15/51] testMultiBlind --- IR_Decoder.cpp | 12 +++++----- IR_Decoder.h | 5 +--- IR_Encoder.cpp | 64 +++++++++++++++++++++++++++++--------------------- IR_Encoder.h | 14 +++++------ IR_config.h | 22 +++++------------ 5 files changed, 56 insertions(+), 61 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index d652c9b..40a80a1 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -31,9 +31,9 @@ void IR_Decoder::isr() { } else { if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его firstUnHandledFront = firstUnHandledFront->next; - Serial.println(); - Serial.println("ERROR"); - Serial.println(); + // Serial.println(); + // Serial.println("ERROR"); + // Serial.println(); } } @@ -278,12 +278,12 @@ void IR_Decoder::writeToBuffer(bool bit) { isData = !isData; i_syncBit = 0; // сброс счетчика битов синхронизации err_syncBit = 0; // сброс счетчика ошибок синхронизации - Serial.print(" "); + // Serial.print(" "); } if (isData) { // Запись битов в dataBuffer - Serial.print(bit); + // Serial.print(bit); if (i_dataBuffer % 8 == 7) { // Serial.print("+"); @@ -314,7 +314,7 @@ void IR_Decoder::writeToBuffer(bool bit) { } ////////////////////// Проверка наличия битов синхранизации ////////////////////// isWrongPack = err_syncBit >= syncBits; - if (isWrongPack) Serial.print("****************"); + // if (isWrongPack) Serial.print("****************"); }//**************************************************************************************************// // Serial.print(bit); diff --git a/IR_Decoder.h b/IR_Decoder.h index 40ed47d..e2c58aa 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -21,8 +21,6 @@ #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) #define IR_timeout (riseTimeMax * (8 + syncBits +1)) // us // таймаут в 8 data + 3 sync + 1 -#define subBufferSize 7 //Буфер для складирования фронтов, пока их не обработают - class IR_Encoder; class IR_Decoder : private IR_FOX { @@ -179,8 +177,7 @@ private: const uint8_t isrPin; // Пин прерывания IR_Encoder* encoder; // Указатель на парный передатчик - bool isPairSending = false; // Флаг передачи парного передатчика - bool IsPairSendLOW = false; // + volatile uint16_t isPairSending = 0; // Флаг передачи парного передатчика volatile bool isRecive = false; // Флаг приёма diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 7f2800b..0a0cdd1 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -5,15 +5,16 @@ #define ISR_Out 10 #define TestOut 13 -IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) { +IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t decPairCount = 0, void* decPair = nullptr) { + // sendBuffer = new uint8_t[dataByteSizeMax] { 0 }; ir_out = pin; pinMode(ir_out, OUTPUT); - addrSelf = addr; - decoder = decPair; - carrierTune = tune; - halfPeriod = (carrierPeriod / 2) - carrierTune; - dataBitCounter = 0 - preambFronts; + id = addr; + + decoders = (IR_Decoder*)decPair; + decodersCount = decPairCount; + signal = noSignal; }; @@ -24,7 +25,7 @@ IR_Encoder::~IR_Encoder() { // delete [] sendBuffer; }; -void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false) { +void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false) { uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; uint8_t msgType = ((needAccept ? IR_MSG_DATA_ACCEPT : IR_MSG_DATA_NOACCEPT) << 5) | ((packSize - crcBytes) & IR_MASK_MSG_INFO); @@ -38,8 +39,8 @@ void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) // addr_self if (!forAll) { - sendBuffer[1] = addrSelf >> 8 & 0xFF; - sendBuffer[2] = addrSelf & 0xFF; + sendBuffer[1] = id >> 8 & 0xFF; + sendBuffer[2] = id & 0xFF; } // data crc @@ -55,8 +56,8 @@ void IR_Encoder::sendRequest(uint16_t addrTo, uint8_t addInfo) { sendBuffer[0] |= addInfo & IR_MASK_MSG_INFO; // addr_self - sendBuffer[1] = addrSelf >> 8 & 0xFF; - sendBuffer[2] = addrSelf & 0xFF; + sendBuffer[1] = id >> 8 & 0xFF; + sendBuffer[2] = id & 0xFF; //addr_to sendBuffer[3] = addrTo >> 8 & 0xFF; @@ -80,8 +81,8 @@ void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t sendBuffer[0] = msgType; // addr_self - sendBuffer[1] = addrSelf >> 8 & 0xFF; - sendBuffer[2] = addrSelf & 0xFF; + sendBuffer[1] = id >> 8 & 0xFF; + sendBuffer[2] = id & 0xFF; // addr_to sendBuffer[3] = addrTo >> 8 & 0xFF; @@ -95,33 +96,39 @@ void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t sendBuffer[packSize - crcBytes] = crc8(sendBuffer, 0, packSize - crcBytes, poly1) & 0xFF; sendBuffer[packSize - crcBytes + 1] = crc8(sendBuffer, 0, packSize - crcBytes + 1, poly2) & 0xFF; - if (decoder != nullptr) { - decoder->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); - decoder->addrWaitingFrom = addrTo; + if (decoders != nullptr) { + decoders->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); + decoders->addrWaitingFrom = addrTo; } // отправка rawSend(sendBuffer, packSize); } +void IR_Encoder::setDecoder_isSending() { + if (decodersCount && decoders != nullptr) { + for (uint8_t i = 0; i < decodersCount; i++) { + (decoders + i)->isPairSending ^= id; + } + + } +} + void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { - if(isSending){ + if (isSending) { //TODO: Обработка повторной отправки return; } - digitalToggle(9); digitalToggle(9); - // memset(sendBuffer, 0x00, dataByteSizeMax); - // memcpy(sendBuffer, ptr, len); + + sendLen = len; - // *sendBuffer = 0b10010011; + isSending = true; + // setDecoder_isSending(); + decoders->isPairSending ^= id; cli(); - if (decoder != nullptr) { decoder->isPairSending = isSending; } - // #define preambToggle 2*2-1 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - toggleCounter = preambToggle; // Первая генерация для первого signal dataBitCounter = bitPerByte - 1; @@ -152,9 +159,12 @@ void IR_Encoder::isr() { IsrStart: switch (signal) { case noSignal: + signal = preamb; // сброс счетчиков // ... isSending = false; + // setDecoder_isSending(); + decoders->isPairSending ^= id; return; break; @@ -228,7 +238,7 @@ void old() {/////////////////////////////////////////////////////// // void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { // /*tmp*/bool LOW_FIRST = false;/*tmp*/ - // if (decoder != nullptr) { decoder->isPairSending = true; } + // if (decoders != nullptr) { decoders->isPairSending = true; } // bool prev = 1; // bool next; @@ -244,7 +254,7 @@ void old() {/////////////////////////////////////////////////////// // addSync(&prev, &next); // } - // if (decoder != nullptr) { decoder->isPairSending = false; } + // if (decoders != nullptr) { decoders->isPairSending = false; } // } } diff --git a/IR_Encoder.h b/IR_Encoder.h index 3070a86..5d2e36d 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -10,11 +10,9 @@ class IR_Encoder : IR_FOX { public: uint8_t ir_out; /// @brief Вывод передатчика - uint16_t addrSelf; /// @brief Адрес передатчика + uint16_t id; /// @brief Адрес передатчика private: - uint8_t carrierTune; /// @brief Подстройка несущей частоты - uint8_t halfPeriod; /// @brief полупериод несущей частоты public: @@ -23,7 +21,7 @@ public: /// @param pin Вывод передатчика /// @param tune Подстройка несущей частоты /// @param decPair Приёмник, для которого отключается приём в момент передачи передатчиком - IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune, IR_Decoder* decPair = nullptr); + IR_Encoder(uint16_t addr, uint8_t pin, uint8_t decPairCount = 0, void* decPair = nullptr); template void sendData(uint16_t addrTo, T& data, bool needAccept = false); @@ -36,7 +34,7 @@ public: ~IR_Encoder(); volatile bool ir_out_virtual; private: - IR_Decoder* decoder; + void IR_Encoder::setDecoder_isSending(); void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType); void sendByte(uint8_t byte, bool* prev, bool LOW_FIRST); void addSync(bool* prev, bool* next); @@ -51,13 +49,13 @@ private: sync = 3 }; + IR_Decoder* decoders; + uint8_t decodersCount; + uint8_t sendLen; uint8_t sendBuffer[dataByteSizeMax] { 0 }; /// @brief Буффер данных для отправки - // uint8_t volatile bool isSending = false; - // volatile bool genState = HIGH; - volatile bool state; /// @brief Текущий уровень генерации volatile uint8_t dataByteCounter; diff --git a/IR_config.h b/IR_config.h index c4eaacb..40b3236 100644 --- a/IR_config.h +++ b/IR_config.h @@ -76,13 +76,9 @@ typedef uint16_t crc_t; #ifndef freeFrec #define freeFrec true #endif +#define subBufferSize 17 //Буфер для складирования фронтов, пока их не обработают (передатчик) -//#define carrierTune 4 #define preambPulse 3 -// 8 для gyverCore -// 4~5 для arduino nano - - ///////////////////////////////////////////////////////////////////////////////////// @@ -95,27 +91,21 @@ typedef uint16_t crc_t; #define syncBits 3U // количество битов синхронизации #define dataByteSizeMax (msgBytes + addrBytes + addrBytes + bytePerPack + crcBytes) - // размер msg в битах // размер короткой посылки в битах -// #define dataBitSize ((8 + syncBits) * dataByteSizeMax) // размер посылки с данными в битах -// #define bufferBitSizeMax (dataBitSize) // Размер буффера в битах -//const auto x = bufferBitSizeMax; -#define preambFronts (preambPulse*2) // количество фронтов преамбулы +#define preambFronts (preambPulse*2) // количество фронтов преамбулы (Приём) +#define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) // колличество переключений преамбулы (Передача) -#define carrierFrec 38000U // частота несущей -#define carrierPeriod (1000000U/carrierFrec) // период несущей в us +#define carrierFrec 38000U // частота несущей (Приём/Передача) +#define carrierPeriod (1000000U/carrierFrec) // период несущей в us (Приём) // В процессе работы значения будут отклонятся в соответствии с предыдущим битом -#define bitActiveTakts 25U // длительность высокого уровня в тактах +#define bitActiveTakts 25U // длительность высокого уровня в тактах #define bitPauseTakts 6U // длительность низкого уровня в тактах #define bitTakts (bitActiveTakts+(bitPauseTakts*2U)) // Общая длительность бита в тактах #define bitTime (bitTakts*carrierPeriod) // Общая длительность бита #define tolerance 300U - #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) - - class IR_FOX { private: bool isSending = false; From bfa978394f236d5bc2cc614a6500059e4eff2a8c Mon Sep 17 00:00:00 2001 From: DashyFox Date: Mon, 12 Feb 2024 18:00:21 +0300 Subject: [PATCH 16/51] multiBlind --- IR_Encoder.cpp | 39 +++++++++++++++++++++++---------------- IR_Encoder.h | 8 +++++--- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 0a0cdd1..a499640 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -5,19 +5,24 @@ #define ISR_Out 10 #define TestOut 13 -IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t decPairCount = 0, void* decPair = nullptr) { +IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, IR_Decoder* decPair = nullptr) { // sendBuffer = new uint8_t[dataByteSizeMax] { 0 }; ir_out = pin; pinMode(ir_out, OUTPUT); id = addr; - - decoders = (IR_Decoder*)decPair; - decodersCount = decPairCount; - - + this->decPair = decPair; signal = noSignal; + isSending = false; + if(decPair != nullptr){ + // blindDecoders = &decPair;/////////////////////////////////////////////////////////TODO: + // decodersCount = 1; + } }; +void IR_Encoder::setBlindDecoders(IR_Decoder* decoders[], uint8_t count){ + decodersCount = count; + blindDecoders = decoders; +} IR_Encoder::~IR_Encoder() { delete [] bitHigh; @@ -96,9 +101,11 @@ void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t sendBuffer[packSize - crcBytes] = crc8(sendBuffer, 0, packSize - crcBytes, poly1) & 0xFF; sendBuffer[packSize - crcBytes + 1] = crc8(sendBuffer, 0, packSize - crcBytes + 1, poly2) & 0xFF; - if (decoders != nullptr) { - decoders->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); - decoders->addrWaitingFrom = addrTo; + if (decPair != nullptr) { + decPair->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); + if (decPair->isWaitingAccept) { + decPair->addrWaitingFrom = addrTo; + } } // отправка rawSend(sendBuffer, packSize); @@ -106,9 +113,9 @@ void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t } void IR_Encoder::setDecoder_isSending() { - if (decodersCount && decoders != nullptr) { + if (decodersCount) { for (uint8_t i = 0; i < decodersCount; i++) { - (decoders + i)->isPairSending ^= id; + blindDecoders[i]->isPairSending ^= id; } } @@ -124,9 +131,8 @@ void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { sendLen = len; - isSending = true; - // setDecoder_isSending(); - decoders->isPairSending ^= id; + setDecoder_isSending(); + Serial.println("^"); cli(); toggleCounter = preambToggle; // Первая генерация для первого signal @@ -143,6 +149,7 @@ void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { state = HIGH; currentBitSequence = bitHigh; + isSending = true; sei(); } @@ -163,8 +170,8 @@ void IR_Encoder::isr() { // сброс счетчиков // ... isSending = false; - // setDecoder_isSending(); - decoders->isPairSending ^= id; + setDecoder_isSending(); + Serial.println("^^^"); return; break; diff --git a/IR_Encoder.h b/IR_Encoder.h index 5d2e36d..c9fb5e3 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -21,8 +21,9 @@ public: /// @param pin Вывод передатчика /// @param tune Подстройка несущей частоты /// @param decPair Приёмник, для которого отключается приём в момент передачи передатчиком - IR_Encoder(uint16_t addr, uint8_t pin, uint8_t decPairCount = 0, void* decPair = nullptr); + IR_Encoder(uint16_t addr, uint8_t pin, IR_Decoder* decPair = nullptr); + void IR_Encoder::setBlindDecoders(IR_Decoder* decoders[], uint8_t count); template void sendData(uint16_t addrTo, T& data, bool needAccept = false); void sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false); @@ -49,13 +50,14 @@ private: sync = 3 }; - IR_Decoder* decoders; + IR_Decoder* decPair; + IR_Decoder** blindDecoders; uint8_t decodersCount; uint8_t sendLen; uint8_t sendBuffer[dataByteSizeMax] { 0 }; /// @brief Буффер данных для отправки - volatile bool isSending = false; + volatile bool isSending; volatile bool state; /// @brief Текущий уровень генерации volatile uint8_t dataByteCounter; From 1ee3386c31377a0189e9406d13158e46812d86f2 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 13 Feb 2024 14:33:17 +0300 Subject: [PATCH 17/51] fix multiBlind --- IR_Decoder.cpp | 13 +------------ IR_Encoder.cpp | 16 ++++++++++------ IR_config.h | 2 ++ 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 40a80a1..e518db2 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -62,26 +62,15 @@ void IR_Decoder::tick() { //////////////////////////////////////////////////////////////////////////////////////////////////////////// if (currentFront.time - prevRise > IR_timeout) { // первый - // if (!currentFront.dir) { // ↓ errorCounter = 0; isRecive = true; isPreamb = true; - // preambFrontCounter = preambFronts - 1U; - // } else { // ↑ + riseSyncTime = bitTime /* 1100 */; start_RX(); preambFrontCounter = preambFronts - 1U; - // } - - // Serial.println(); - // Serial.print("currentFront.time: "); Serial.println(currentFront.time); - // Serial.print("currentFront.dir: "); Serial.println(currentFront.dir ? "UP" : "Down"); - // Serial.print("prevRise: "); Serial.println(prevRise); - // Serial.print("preambFrontCounter: "); Serial.println(preambFrontCounter); - - // prevRise = currentFront.time; } if (preambFrontCounter > 0) { // в преамбуле diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index a499640..711cb53 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -14,20 +14,24 @@ IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, IR_Decoder* decPair = nullptr this->decPair = decPair; signal = noSignal; isSending = false; + #if disablePairDec if(decPair != nullptr){ - // blindDecoders = &decPair;/////////////////////////////////////////////////////////TODO: - // decodersCount = 1; + blindDecoders = new IR_Decoder*[1]{decPair}; + decodersCount = 1; } + #endif }; void IR_Encoder::setBlindDecoders(IR_Decoder* decoders[], uint8_t count){ + #if disablePairDec + if(blindDecoders != nullptr) delete[] blindDecoders; + #endif decodersCount = count; blindDecoders = decoders; } IR_Encoder::~IR_Encoder() { - delete [] bitHigh; delete [] bitLow; - // delete [] sendBuffer; + delete [] bitHigh; }; void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false) { @@ -116,6 +120,7 @@ void IR_Encoder::setDecoder_isSending() { if (decodersCount) { for (uint8_t i = 0; i < decodersCount; i++) { blindDecoders[i]->isPairSending ^= id; + digitalToggle(9); digitalToggle(9); } } @@ -132,7 +137,7 @@ void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { sendLen = len; setDecoder_isSending(); - Serial.println("^"); + cli(); toggleCounter = preambToggle; // Первая генерация для первого signal @@ -171,7 +176,6 @@ void IR_Encoder::isr() { // ... isSending = false; setDecoder_isSending(); - Serial.println("^^^"); return; break; diff --git a/IR_config.h b/IR_config.h index 40b3236..ee9c774 100644 --- a/IR_config.h +++ b/IR_config.h @@ -80,6 +80,8 @@ typedef uint16_t crc_t; #define preambPulse 3 +#define disablePairDec false // Отключать парный приёмник, возможны баги, используйте setBlindDecoders() + ///////////////////////////////////////////////////////////////////////////////////// #define bitPerByte 8U // Колличество бит в байте From d065c7a0376f1ea958d7dddc2c0478d344fca163 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 13 Feb 2024 15:18:45 +0300 Subject: [PATCH 18/51] ErrorFix --- IR_Decoder.cpp | 218 ++++++++++++++++++++++++++----------------------- IR_Decoder.h | 31 +++++-- IR_Encoder.cpp | 1 - 3 files changed, 139 insertions(+), 111 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index e518db2..e21fe33 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -19,7 +19,7 @@ IR_Decoder::~IR_Decoder() { //////////////////////////////////// isr /////////////////////////////////////////// -void IR_Decoder::isr() { +void IR_Decoder::isr() { if (isPairSending) return; subBuffer[currentSubBufferIndex].next = nullptr; @@ -62,8 +62,7 @@ void IR_Decoder::tick() { //////////////////////////////////////////////////////////////////////////////////////////////////////////// if (currentFront.time - prevRise > IR_timeout) { // первый - - errorCounter = 0; + errors.reset(); isRecive = true; isPreamb = true; @@ -79,7 +78,7 @@ void IR_Decoder::tick() { if (risePeriod < riseTimeMin << 1) { // fix рваной единицы preambFrontCounter += 2; - errorCounter++; + errors.other++; } else { if (freeFrec) { riseSyncTime = (riseSyncTime + risePeriod / 2) / 2; } // tuner } @@ -104,107 +103,118 @@ void IR_Decoder::tick() { int8_t allCount = 0; bool invertErr = false; + if (!isPreamb) { + if (risePeriod < IR_timeout && !isBufferOverflow && risePeriod > riseTimeMin && !isWrongPack) { + // Мы в пределах таймаута и буффер не переполнен и fix дроблёных единиц - if (risePeriod < IR_timeout && !isBufferOverflow && risePeriod > riseTimeMin && !isWrongPack) { - // Мы в пределах таймаута и буффер не переполнен и fix дроблёных единиц + if (aroundRise(risePeriod)) { // тактирование есть, сигнал хороший - без ошибок(?) - if (aroundRise(risePeriod)) { // тактирование есть, сигнал хороший - без ошибок(?) - - if (highTime > riseTimeMin >> 1) { // 1 - #ifdef IRDEBUG - digitalWrite(wrHigh, 1); - #endif - writeToBuffer(HIGH); - } else { // 0 - #ifdef IRDEBUG - digitalWrite(wrLow, 1); - #endif - writeToBuffer(LOW); - } - - } else { // пропущены такты! сигнал средний // ошибка пропуска - highCount = ceil_div(highTime, riseTime); // предполагаемое колличество HIGH битов - lowCount = ceil_div(lowTime, riseTime); // предполагаемое колличество LOW битов - allCount = ceil_div(risePeriod, riseTime); // предполагаемое колличество всего битов - - if (highCount == 0 && highTime > riseTime / 3) { // fix короткой единицы (?)после пропуска нулей(?) - highCount++; - errorCounter++; - #ifdef IRDEBUG - errPulse(errOut, 2); - #endif - } - - if (lowCount + highCount > allCount) { // fix ошибочных сдвигов - if (lowCount > highCount) { // Лишние нули - lowCount = allCount - highCount; - #ifdef IRDEBUG - errPulse(errOut, 3); - #endif - } else if (lowCount < highCount) { // Лишние единицы - highCount = allCount - lowCount; - #ifdef IRDEBUG - errPulse(errOut, 4); - #endif - // неизвестный случай Инверсит след бит или соседние - // Очень редко - // TODO: Отловить проверить - } else if (lowCount == highCount) { - invertErr = true; - Serial.print("..."); - } - errorCounter += allCount; - } - - errorCounter += allCount; - #ifdef IRDEBUG - errPulse(errOut, 1); - #endif - - for (int8_t i = 0; i < lowCount && 8 - i; i++) { // отправка LOW битов, если есть - if (i == lowCount - 1 && invertErr) { - invertErr = false; - writeToBuffer(!LOW); - #ifdef IRDEBUG - digitalWrite(wrLow, 1); - #endif - } else { - writeToBuffer(LOW); - #ifdef IRDEBUG - digitalWrite(wrLow, 1); - #endif - } - } - - for (int8_t i = 0; i < highCount && 8 - i; i++) { // отправка HIGH битов, если есть - if (i == highCount - 1 && invertErr) { - invertErr = false; - writeToBuffer(!HIGH); - #ifdef IRDEBUG - digitalWrite(wrLow, 1); - #endif - } else { - writeToBuffer(HIGH); - #ifdef IRDEBUG + if (highTime > riseTimeMin >> 1) { // 1 + #ifdef IRDEBUG digitalWrite(wrHigh, 1); + #endif + writeToBuffer(HIGH); + } else { // 0 + #ifdef IRDEBUG + digitalWrite(wrLow, 1); + #endif + writeToBuffer(LOW); + } + + } else { // пропущены такты! сигнал средний // ошибка пропуска + highCount = ceil_div(highTime, riseTime); // предполагаемое колличество HIGH битов + lowCount = ceil_div(lowTime, riseTime); // предполагаемое колличество LOW битов + allCount = ceil_div(risePeriod, riseTime); // предполагаемое колличество всего битов + + if (highCount == 0 && highTime > riseTime / 3) { // fix короткой единицы (?)после пропуска нулей(?) + highCount++; + errors.other++; + #ifdef IRDEBUG + errPulse(errOut, 2); + #endif + } + + if (lowCount + highCount > allCount) { // fix ошибочных сдвигов + if (lowCount > highCount) { // Лишние нули + lowCount = allCount - highCount; + errors.lowSignal += lowCount; + #ifdef IRDEBUG + errPulse(errOut, 3); + #endif + } else if (lowCount < highCount) { // Лишние единицы + highCount = allCount - lowCount; + errors.highSignal += highCount; + #ifdef IRDEBUG + errPulse(errOut, 4); + #endif + // неизвестный случай Инверсит след бит или соседние + // Очень редко + // TODO: Отловить проверить + } else if (lowCount == highCount) { + invertErr = true; + // Serial.print("..."); + errors.other += allCount; + } + // errorCounter += allCount; + + } + + // errorCounter += allCount; + // errors.other+=allCount; + if (lowCount < highCount) { + errors.highSignal += highCount; + } else { + errors.lowSignal += lowCount; + } + + #ifdef IRDEBUG + errPulse(errOut, 1); #endif + + for (int8_t i = 0; i < lowCount && 8 - i; i++) { // отправка LOW битов, если есть + if (i == lowCount - 1 && invertErr) { + invertErr = false; + writeToBuffer(!LOW); + #ifdef IRDEBUG + digitalWrite(wrLow, 1); + #endif + } else { + writeToBuffer(LOW); + #ifdef IRDEBUG + digitalWrite(wrLow, 1); + #endif + } + } + + for (int8_t i = 0; i < highCount && 8 - i; i++) { // отправка HIGH битов, если есть + if (i == highCount - 1 && invertErr) { + invertErr = false; + writeToBuffer(!HIGH); + #ifdef IRDEBUG + digitalWrite(wrLow, 1); + #endif + } else { + writeToBuffer(HIGH); + #ifdef IRDEBUG + digitalWrite(wrHigh, 1); + #endif + } } } + #ifdef IRDEBUG + digitalWrite(wrHigh, 0); + digitalWrite(wrLow, 0); + #endif } - #ifdef IRDEBUG - digitalWrite(wrHigh, 0); - digitalWrite(wrLow, 0); - #endif } - if (risePeriod > riseTimeMax / 2 || highCount || lowCount) { // комплексный фикс рваной единицы prevPrevRise = prevRise; prevRise = currentFront.time; } else { - errorCounter++; - #ifdef IRDEBUG + errors.other++; + #ifdef IRDEBUG errPulse(errOut, 5); - #endif + #endif } } else { // Если ```\__ ↓ @@ -213,9 +223,9 @@ void IR_Decoder::tick() { prevPrevFall = prevFall; prevFall = currentFront.time; } else { - #ifdef IRDEBUG + #ifdef IRDEBUG //errPulse(errOut, 5); - #endif + #endif } } @@ -223,9 +233,9 @@ void IR_Decoder::tick() { prevRise = currentFront.time + riseTime; } -#ifdef IRDEBUG + #ifdef IRDEBUG digitalWrite(writeOp, isPreamb); -#endif + #endif //////////////////////////////////////////////////////////////////////////////////////////////////////////// firstUnHandledFront = firstUnHandledFront->next; //переместить флаг на следующий элемент для обработки (next or nullptr) } @@ -290,7 +300,7 @@ void IR_Decoder::writeToBuffer(bool bit) { i_syncBit++; } else { i_syncBit = 0; - errorCounter++; + errors.other++; // Serial.print("E"); err_syncBit++; // Serial.print("bit: "); Serial.println(bit); @@ -307,9 +317,9 @@ void IR_Decoder::writeToBuffer(bool bit) { }//**************************************************************************************************// // Serial.print(bit); -#ifdef IRDEBUG + #ifdef IRDEBUG bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); -#endif + #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -322,7 +332,7 @@ void IR_Decoder::writeToBuffer(bool bit) { const uint8_t dataSize = msgBytes + addrBytes; isCrcCorrect = crcCheck(dataSize, crcValue); if (isCrcCorrect && checkAddr(1, 2)) { - gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errors, riseSyncTime); gotAccept._isAvaliable = true; } } @@ -334,7 +344,7 @@ void IR_Decoder::writeToBuffer(bool bit) { isCrcCorrect = (crcCheck(dataSize, crcValue)); if (isCrcCorrect && checkAddr(3, 4)) { gotRequest._isAvaliable = true; - gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errors, riseSyncTime); } } break; @@ -348,10 +358,10 @@ void IR_Decoder::writeToBuffer(bool bit) { isCrcCorrect = crcCheck(dataSize, crcValue); if (isCrcCorrect && checkAddr(3, 4)) { gotData._isAvaliable = true; - gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); + gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errors, riseSyncTime); } else { gotRawData._isAvaliable = true; - gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); + gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errors, riseSyncTime); } } break; @@ -363,7 +373,7 @@ void IR_Decoder::writeToBuffer(bool bit) { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } -bool IR_Decoder::crcCheck(uint8_t len, crc_t &crc) { +bool IR_Decoder::crcCheck(uint8_t len, crc_t& crc) { bool crcOK = false; crc = 0; diff --git a/IR_Decoder.h b/IR_Decoder.h index e2c58aa..1006f78 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -51,6 +51,21 @@ public: ////////////////////////////////////////////////////////////////////////// + struct ErrorsStruct { + uint8_t lowSignal; + uint8_t highSignal; + uint8_t other; + + void reset() { + lowSignal = 0; + highSignal = 0; + other = 0; + } + uint16_t all() { return lowSignal + highSignal + other; } + + } errors; + +public: class InputData : protected IR_FOX { friend IR_Decoder; protected: @@ -62,13 +77,13 @@ public: uint8_t _dataRawSize = 0; uint16_t _crcPackVal = 0; uint16_t _crcCalcVal = 0; - uint16_t _errCount = 0; + ErrorsStruct _err; uint16_t _bitPeriod = 0; - void _set(uint8_t* ptr, uint8_t len, uint16_t crc, uint16_t err, uint16_t rTime) { + void _set(uint8_t* ptr, uint8_t len, uint16_t crc, ErrorsStruct err, uint16_t rTime) { _crcCalcVal = crc; _dataRawSize = len; - _errCount = err; + _err = err; _bitPeriod = rTime; if (_data != nullptr) { delete _data; _data = nullptr; } _data = new uint8_t[len]; @@ -86,7 +101,10 @@ public: uint8_t msgInfo() { return _msgType & IR_MASK_MSG_INFO; }; uint8_t msgType() { return (_msgType >> 5) & IR_MASK_MSG_TYPE; }; uint8_t msgRAW() { return _msgType; }; - uint16_t errorCount() { return _errCount; }; + uint16_t errorCount() { return _err.all(); }; + uint8_t errorLowSignal() { return _err.lowSignal; }; + uint8_t errorHighSignal() { return _err.highSignal; }; + uint8_t errorOther() { return _err.other; }; uint16_t crcIN() { return _crcPackVal; }; uint16_t crcCALC() { return _crcCalcVal; }; uint16_t tunerTime() { return _bitPeriod; }; @@ -174,6 +192,7 @@ public: private: + const uint8_t isrPin; // Пин прерывания IR_Encoder* encoder; // Указатель на парный передатчик @@ -282,10 +301,10 @@ private: // }; -#ifdef IRDEBUG + #ifdef IRDEBUG inline void errPulse(uint8_t pin, uint8_t count); inline void infoPulse(uint8_t pin, uint8_t count); -#endif + #endif }; \ No newline at end of file diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 711cb53..50a0197 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -120,7 +120,6 @@ void IR_Encoder::setDecoder_isSending() { if (decodersCount) { for (uint8_t i = 0; i < decodersCount; i++) { blindDecoders[i]->isPairSending ^= id; - digitalToggle(9); digitalToggle(9); } } From aedbe11af352b1be4fcf6f72f064c91493b7a854 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 13 Feb 2024 15:36:21 +0300 Subject: [PATCH 19/51] timer ini to static func --- IR_Encoder.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/IR_Encoder.h b/IR_Encoder.h index c9fb5e3..a7c6453 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -23,7 +23,19 @@ public: /// @param decPair Приёмник, для которого отключается приём в момент передачи передатчиком IR_Encoder(uint16_t addr, uint8_t pin, IR_Decoder* decPair = nullptr); - void IR_Encoder::setBlindDecoders(IR_Decoder* decoders[], uint8_t count); + static void timerSetup() { + // TIMER2 Ini + uint8_t oldSREG = SREG; // Save global interupts settings + cli(); + TCCR2A = (1 << WGM21); // Clear Timer On Compare (Сброс по совпадению) + TCCR2B = (1 << CS20); // Предделитель 1 + TIMSK2 |= (1 << OCIE2A); // Прерывание по совпадению + OCR2A = 465/* ((F_CPU / 38000) - 1) */; //38кГц + + SREG = oldSREG; // Return interrupt settings + } + + void IR_Encoder::setBlindDecoders(IR_Decoder* decoders [], uint8_t count); template void sendData(uint16_t addrTo, T& data, bool needAccept = false); void sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false); From 882bd56d49e77963f5d8e4c527389ac92bdc3234 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 14 Feb 2024 17:19:53 +0300 Subject: [PATCH 20/51] test 8Mhz fail --- IR_Encoder.cpp | 4 ---- IR_Encoder.h | 20 ++++++++++++++------ IR_config.h | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 50a0197..1847465 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -6,10 +6,6 @@ #define TestOut 13 IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, IR_Decoder* decPair = nullptr) { - - // sendBuffer = new uint8_t[dataByteSizeMax] { 0 }; - ir_out = pin; - pinMode(ir_out, OUTPUT); id = addr; this->decPair = decPair; signal = noSignal; diff --git a/IR_Encoder.h b/IR_Encoder.h index a7c6453..066e981 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -8,8 +8,6 @@ class IR_Encoder : IR_FOX { friend IR_Decoder; friend void isr(IR_Encoder& e); public: - - uint8_t ir_out; /// @brief Вывод передатчика uint16_t id; /// @brief Адрес передатчика private: @@ -27,10 +25,20 @@ public: // TIMER2 Ini uint8_t oldSREG = SREG; // Save global interupts settings cli(); - TCCR2A = (1 << WGM21); // Clear Timer On Compare (Сброс по совпадению) - TCCR2B = (1 << CS20); // Предделитель 1 - TIMSK2 |= (1 << OCIE2A); // Прерывание по совпадению - OCR2A = 465/* ((F_CPU / 38000) - 1) */; //38кГц + // DDRB |= (1 << PORTB3); //OC2A (17) + TCCR2A = 0; + TCCR2B = 0; + + // TCCR2A |= (1 << COM2A0); //Переключение состояния + + TCCR2A |= (1 << WGM21); // Clear Timer On Compare (Сброс по совпадению) + TCCR2B |= (1 << CS20); // Предделитель 1 + TIMSK2 |= (1 << OCIE2A); // Прерывание по совпадению + #if F_CPU == 16000000 + OCR2A = /* 465 */((F_CPU / (38000*2)) - 2); //38кГц + #elif F_CPU == 8000000 + OCR2A = ((F_CPU / (38000 * 2)) - 2); //38кГц Частота_мк / (Предделитель * Частота * 2) + #endif SREG = oldSREG; // Return interrupt settings } diff --git a/IR_config.h b/IR_config.h index ee9c774..a6e5ffa 100644 --- a/IR_config.h +++ b/IR_config.h @@ -76,7 +76,7 @@ typedef uint16_t crc_t; #ifndef freeFrec #define freeFrec true #endif -#define subBufferSize 17 //Буфер для складирования фронтов, пока их не обработают (передатчик) +#define subBufferSize 15 //Буфер для складирования фронтов, пока их не обработают (передатчик) #define preambPulse 3 From 408fea84ac349ea5b387300df25bc93a8d96d226 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 14 Feb 2024 17:51:28 +0300 Subject: [PATCH 21/51] no template --- IR_Encoder.cpp | 75 +++++++++++++++++++++++--------------------------- IR_Encoder.h | 20 +++++++------- 2 files changed, 45 insertions(+), 50 deletions(-) diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 1847465..3d96b21 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -11,15 +11,15 @@ IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, IR_Decoder* decPair = nullptr signal = noSignal; isSending = false; #if disablePairDec - if(decPair != nullptr){ - blindDecoders = new IR_Decoder*[1]{decPair}; + if (decPair != nullptr) { + blindDecoders = new IR_Decoder * [1] {decPair}; decodersCount = 1; } #endif }; -void IR_Encoder::setBlindDecoders(IR_Decoder* decoders[], uint8_t count){ +void IR_Encoder::setBlindDecoders(IR_Decoder* decoders [], uint8_t count) { #if disablePairDec - if(blindDecoders != nullptr) delete[] blindDecoders; + if (blindDecoders != nullptr) delete [] blindDecoders; #endif decodersCount = count; blindDecoders = decoders; @@ -31,10 +31,40 @@ IR_Encoder::~IR_Encoder() { }; void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false) { + constexpr uint8_t dataStart = msgBytes + addrBytes + addrBytes; + memset(sendBuffer, 0x00, dataByteSizeMax); uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; uint8_t msgType = ((needAccept ? IR_MSG_DATA_ACCEPT : IR_MSG_DATA_NOACCEPT) << 5) | ((packSize - crcBytes) & IR_MASK_MSG_INFO); - _sendData(addrTo, data, len, msgType); + + // формирование массива + // msg_type + sendBuffer[0] = msgType; + + // addr_self + sendBuffer[1] = id >> 8 & 0xFF; + sendBuffer[2] = id & 0xFF; + + // addr_to + sendBuffer[3] = addrTo >> 8 & 0xFF; + sendBuffer[4] = addrTo & 0xFF; + + for (uint16_t i = dataStart; i < dataStart + len; i++) { + sendBuffer[i] = ((uint8_t*)data)[i - dataStart]; + } + + // data crc + sendBuffer[packSize - crcBytes] = crc8(sendBuffer, 0, packSize - crcBytes, poly1) & 0xFF; + sendBuffer[packSize - crcBytes + 1] = crc8(sendBuffer, 0, packSize - crcBytes + 1, poly2) & 0xFF; + + if (decPair != nullptr) { + decPair->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); + if (decPair->isWaitingAccept) { + decPair->addrWaitingFrom = addrTo; + } + } + // отправка + rawSend(sendBuffer, packSize); } void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { @@ -75,42 +105,7 @@ void IR_Encoder::sendRequest(uint16_t addrTo, uint8_t addInfo) { rawSend(sendBuffer, msgBytes + addrBytes + addrBytes + crcBytes); } -void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType) { - memset(sendBuffer, 0x00, dataByteSizeMax); - uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; - uint8_t dataStart = msgBytes + addrBytes + addrBytes; - - // формирование массива - // msg_type - sendBuffer[0] = msgType; - - // addr_self - sendBuffer[1] = id >> 8 & 0xFF; - sendBuffer[2] = id & 0xFF; - - // addr_to - sendBuffer[3] = addrTo >> 8 & 0xFF; - sendBuffer[4] = addrTo & 0xFF; - - for (uint16_t i = dataStart; i < dataStart + len; i++) { - sendBuffer[i] = ((uint8_t*)data)[i - dataStart]; - } - - // data crc - sendBuffer[packSize - crcBytes] = crc8(sendBuffer, 0, packSize - crcBytes, poly1) & 0xFF; - sendBuffer[packSize - crcBytes + 1] = crc8(sendBuffer, 0, packSize - crcBytes + 1, poly2) & 0xFF; - - if (decPair != nullptr) { - decPair->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); - if (decPair->isWaitingAccept) { - decPair->addrWaitingFrom = addrTo; - } - } - // отправка - rawSend(sendBuffer, packSize); - -} void IR_Encoder::setDecoder_isSending() { if (decodersCount) { diff --git a/IR_Encoder.h b/IR_Encoder.h index 066e981..e4949d5 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -44,8 +44,8 @@ public: } void IR_Encoder::setBlindDecoders(IR_Decoder* decoders [], uint8_t count); - template - void sendData(uint16_t addrTo, T& data, bool needAccept = false); + // template + // void sendData(uint16_t addrTo, T& data, bool needAccept = false); void sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false); void sendACK(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false); void sendRequest(uint16_t addrTo, uint8_t addInfo = 0); @@ -113,14 +113,14 @@ private: //////////////////////////////////////////////////////////////////////////////////////////////// -template -void IR_Encoder::sendData(uint16_t addrTo, T& data, bool needAccept = false) { // TODO: переделать логику LOW_FIRST - uint8_t len = sizeof(T); - uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; +// template +// void IR_Encoder::sendData(uint16_t addrTo, T& data, bool needAccept = false) { // TODO: переделать логику LOW_FIRST +// uint8_t len = sizeof(T); +// uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; - uint8_t msgType = - ((needAccept ? IR_MSG_DATA_ACCEPT : IR_MSG_DATA_NOACCEPT) << 5) | ((packSize - crcBytes) & IR_MASK_MSG_INFO); +// uint8_t msgType = +// ((needAccept ? IR_MSG_DATA_ACCEPT : IR_MSG_DATA_NOACCEPT) << 5) | ((packSize - crcBytes) & IR_MASK_MSG_INFO); - _sendData(addrTo, data, len, msgType); -} +// _sendData(addrTo, data, len, msgType); +// } From b517e4e6adb97d6243bf0bf20d1ad2a224cde5bb Mon Sep 17 00:00:00 2001 From: DashyFox Date: Thu, 15 Feb 2024 16:50:21 +0300 Subject: [PATCH 22/51] debug startRX and m --- IR_Decoder.cpp | 118 ++++++++++++++++++++++++++++++------------------- IR_Decoder.h | 4 +- IR_Encoder.cpp | 7 +-- IR_Encoder.h | 4 +- IR_config.h | 22 ++++----- 5 files changed, 88 insertions(+), 67 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index e21fe33..fa13d11 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -1,6 +1,8 @@ #include "IR_Decoder.h" #include "IR_Encoder.h" +// #define IRDEBUG_INFO + #define checkAddr(h, l) (\ ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) == addrSelf) || \ ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) >= IR_Broadcast)\ @@ -31,9 +33,11 @@ void IR_Decoder::isr() { } else { if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его firstUnHandledFront = firstUnHandledFront->next; + #ifdef IRDEBUG_INFO // Serial.println(); // Serial.println("ERROR"); // Serial.println(); + #endif } } @@ -50,6 +54,36 @@ void IR_Decoder::isr() { //////////////////////////////////////////////////////////////////////////////////// +void IR_Decoder::start_RX() { + + #ifdef IRDEBUG_INFO + Serial.print("\n>"); + #endif + + errors.reset(); + + isBufferOverflow = false; + isCrcCorrect = false; + bufBitPos = 0; + isData = true; + i_dataBuffer = 0; + nextControlBit = bitPerByte; + i_syncBit = 0; + isWrongPack = false; + + isPreamb = true; + riseSyncTime = bitTime /* 1100 */; + + memset(dataBuffer, 0x00, dataByteSizeMax); +} + +void IR_Decoder::listen() { + if (isRecive && ((micros() - prevRise) > IR_timeout)) { + isRecive = false; + start_RX(); + } +} + void IR_Decoder::tick() { listen(); if (firstUnHandledFront == nullptr) return; //Если данных нет - ничего не делаем @@ -61,15 +95,12 @@ void IR_Decoder::tick() { interrupts(); //////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (currentFront.time - prevRise > IR_timeout) { // первый - errors.reset(); - isRecive = true; - isPreamb = true; - - riseSyncTime = bitTime /* 1100 */; - start_RX(); + if (currentFront.time - prevRise > IR_timeout * 2 /* && !isRecive */) { // первый preambFrontCounter = preambFronts - 1U; - + + if (!currentFront.dir) { + isRecive = true; + } } if (preambFrontCounter > 0) { // в преамбуле @@ -240,33 +271,12 @@ void IR_Decoder::tick() { firstUnHandledFront = firstUnHandledFront->next; //переместить флаг на следующий элемент для обработки (next or nullptr) } -void IR_Decoder::listen() { - if (isRecive && micros() - prevRise > IR_timeout * 2) { - isRecive = false; - } -} - -void IR_Decoder::start_RX() { - // Serial.println(); - // Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN)); - // Serial.println(); - - - resetAvaliable(); - isBufferOverflow = false; - memset(dataBuffer, 0x00, dataByteSizeMax); - - bufBitPos = 0; - isData = true; - i_dataBuffer = 0; - nextControlBit = bitPerByte; - i_syncBit = 0; - isWrongPack = false; -} - void IR_Decoder::writeToBuffer(bool bit) { - if (i_dataBuffer >= dataByteSizeMax * 8 - 1) {// проверка переполнения + if (i_dataBuffer > dataByteSizeMax * 8) {// проверка переполнения //TODO: Буффер переполнен! + #ifdef IRDEBUG_INFO + Serial.println("OverBuf"); + #endif isBufferOverflow = true; } if (isBufferOverflow || isPreamb || isWrongPack) return; @@ -277,12 +287,16 @@ void IR_Decoder::writeToBuffer(bool bit) { isData = !isData; i_syncBit = 0; // сброс счетчика битов синхронизации err_syncBit = 0; // сброс счетчика ошибок синхронизации - // Serial.print(" "); + #ifdef IRDEBUG_INFO + Serial.print(" "); + #endif } if (isData) { // Запись битов в dataBuffer - // Serial.print(bit); + #ifdef IRDEBUG_INFO + Serial.print(bit); + #endif if (i_dataBuffer % 8 == 7) { // Serial.print("+"); @@ -312,8 +326,10 @@ void IR_Decoder::writeToBuffer(bool bit) { i_syncBit++; } ////////////////////// Проверка наличия битов синхранизации ////////////////////// - isWrongPack = err_syncBit >= syncBits; - // if (isWrongPack) Serial.print("****************"); + isWrongPack = (err_syncBit >= syncBits); + #ifdef IRDEBUG_INFO + if (isWrongPack) Serial.print("****************"); + #endif }//**************************************************************************************************// // Serial.print(bit); @@ -324,12 +340,20 @@ void IR_Decoder::writeToBuffer(bool bit) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //const auto testval = bufferBitSizeMax; + #ifdef IRDEBUG_INFO + if (isData) { + if (i_dataBuffer == ((msgBytes)*bitPerByte)) { Serial.print(" -> "); Serial.print(dataBuffer[0] & IR_MASK_MSG_INFO); Serial.print(" ->"); } + if (i_dataBuffer == ((msgBytes + addrBytes) * bitPerByte)) { Serial.print(" |"); } + if (i_dataBuffer == ((msgBytes + addrBytes + addrBytes) * bitPerByte)) { Serial.print(" ->"); } + if (i_dataBuffer == ((dataBuffer[0] & IR_MASK_MSG_INFO) * bitPerByte)) { Serial.print(" <-"); } + } + #endif if ((i_dataBuffer >= (8 * msgBytes)) && !isCrcCorrect) { uint16_t crcValue; switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { case IR_MSG_ACCEPT: if (i_dataBuffer >= ((msgBytes + addrBytes + crcBytes) * bitPerByte)) { - const uint8_t dataSize = msgBytes + addrBytes; + constexpr uint8_t dataSize = msgBytes + addrBytes; isCrcCorrect = crcCheck(dataSize, crcValue); if (isCrcCorrect && checkAddr(1, 2)) { gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errors, riseSyncTime); @@ -340,8 +364,8 @@ void IR_Decoder::writeToBuffer(bool bit) { case IR_MSG_REQUEST: if (i_dataBuffer >= ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte)) { - const uint8_t dataSize = msgBytes + addrBytes + addrBytes; - isCrcCorrect = (crcCheck(dataSize, crcValue)); + constexpr uint8_t dataSize = msgBytes + addrBytes + addrBytes; + isCrcCorrect = crcCheck(dataSize, crcValue); if (isCrcCorrect && checkAddr(3, 4)) { gotRequest._isAvaliable = true; gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errors, riseSyncTime); @@ -353,15 +377,23 @@ void IR_Decoder::writeToBuffer(bool bit) { case IR_MSG_DATA_ACCEPT: case IR_MSG_DATA_NOACCEPT: if (i_dataBuffer >= ((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte) { - // Serial.println("OK"); + #ifdef IRDEBUG_INFO + Serial.print(" IN "); + #endif const uint8_t dataSize = (dataBuffer[0] & IR_MASK_MSG_INFO); isCrcCorrect = crcCheck(dataSize, crcValue); if (isCrcCorrect && checkAddr(3, 4)) { + #ifdef IRDEBUG_INFO + Serial.println(" OK "); + #endif gotData._isAvaliable = true; gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errors, riseSyncTime); } else { gotRawData._isAvaliable = true; gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errors, riseSyncTime); + #ifdef IRDEBUG_INFO + Serial.println(" NOT OK "); + #endif } } break; @@ -392,10 +424,6 @@ bool IR_Decoder::crcCheck(uint8_t len, crc_t& crc) { return crcOK; } -void IR_Decoder::resetAvaliable() { - isCrcCorrect = false; -} - uint16_t IR_Decoder::ceil_div(uint16_t val, uint16_t divider) { int ret = val / divider; if ((val << 4) / divider - (ret << 4) >= 8) diff --git a/IR_Decoder.h b/IR_Decoder.h index 1006f78..fa4cb81 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -190,10 +190,10 @@ public: /// @brief Контейнер с информацией подстройки RawTune gotTune; + const uint8_t isrPin; // Пин прерывания private: - const uint8_t isrPin; // Пин прерывания IR_Encoder* encoder; // Указатель на парный передатчик volatile uint16_t isPairSending = 0; // Флаг передачи парного передатчика @@ -261,8 +261,6 @@ private: /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных void start_RX(); - /// @brief Сброс флагов доступности данных - void resetAvaliable(); /// @brief Целочисленное деление с округлением вверх /// @param val Значение diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 3d96b21..0eaf6b3 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -31,6 +31,7 @@ IR_Encoder::~IR_Encoder() { }; void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false) { + if (len > bytePerPack) { return; } constexpr uint8_t dataStart = msgBytes + addrBytes + addrBytes; memset(sendBuffer, 0x00, dataByteSizeMax); uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; @@ -122,14 +123,10 @@ void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { return; } - - - sendLen = len; - setDecoder_isSending(); - cli(); + sendLen = len; toggleCounter = preambToggle; // Первая генерация для первого signal dataBitCounter = bitPerByte - 1; diff --git a/IR_Encoder.h b/IR_Encoder.h index e4949d5..8d86781 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -6,7 +6,6 @@ class IR_Decoder; class IR_Encoder : IR_FOX { friend IR_Decoder; - friend void isr(IR_Encoder& e); public: uint16_t id; /// @brief Адрес передатчика @@ -35,7 +34,7 @@ public: TCCR2B |= (1 << CS20); // Предделитель 1 TIMSK2 |= (1 << OCIE2A); // Прерывание по совпадению #if F_CPU == 16000000 - OCR2A = /* 465 */((F_CPU / (38000*2)) - 2); //38кГц + OCR2A = /* 465 */((F_CPU / (38000 * 2)) - 2); //38кГц #elif F_CPU == 8000000 OCR2A = ((F_CPU / (38000 * 2)) - 2); //38кГц Частота_мк / (Предделитель * Частота * 2) #endif @@ -56,7 +55,6 @@ public: volatile bool ir_out_virtual; private: void IR_Encoder::setDecoder_isSending(); - void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType); void sendByte(uint8_t byte, bool* prev, bool LOW_FIRST); void addSync(bool* prev, bool* next); void send_HIGH(bool = 1); diff --git a/IR_config.h b/IR_config.h index a6e5ffa..73904e7 100644 --- a/IR_config.h +++ b/IR_config.h @@ -39,16 +39,16 @@ msg type:                                         // | xxx..... | = тип сообщения                                         // | ...xxxxx | = длина (максимум 32 бита)                                         //  ---------- */ -#define IR_MSG_ 0U // | 000..... | = = ?? -#define IR_MSG_ACCEPT 1U // | 001..... | = */ /* = подтверждение -#define IR_MSG_REQUEST 2U // | 010..... | = */ /* = запрос -#define IR_MSG_ 3U // | 011..... | = */ /* = ?? -#define IR_MSG_ 4U // | 100..... | = */ /* = ?? -#define IR_MSG_ 5U // | 101..... | = */ /* = ?? -#define IR_MSG_DATA_NOACCEPT 6U // | 110..... | = */ /* = данные, не требующие подтверждения - //                                      // | \\\xxxxx | = = L длина данных -#define IR_MSG_DATA_ACCEPT 7U // | 111..... | = */ /* = данные требующие подтверждения -//                                      // | \\\xxxxx | = = L длина данных +#define IR_MSG_ 0U // | 000..... | = Задний сигнал машинки +#define IR_MSG_ACCEPT 1U // | 001..... | = подтверждение +#define IR_MSG_REQUEST 2U // | 010..... | = запрос +#define IR_MSG_ 3U // | 011..... | = ?? +#define IR_MSG_ 4U // | 100..... | = ?? +#define IR_MSG_ 5U // | 101..... | = ?? +#define IR_MSG_DATA_NOACCEPT 6U // | 110..... | = данные, не требующие подтверждения +;// // | \\\xxxxx | = длина данных +#define IR_MSG_DATA_ACCEPT 7U // | 111..... | = данные требующие подтверждения +;//                                     // | \\\xxxxx | = длина данных /*   // ---------- /```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\ @@ -72,7 +72,7 @@ msg type: /////////////////////////////////////////////////////////////////////////////////////*/ typedef uint16_t crc_t; -#define bytePerPack 3 // колличество байтов в пакете +#define bytePerPack 16 // колличество байтов в пакете #ifndef freeFrec #define freeFrec true #endif From 4a8195e5614278fbdc98c12195c9ff6ba73abc1a Mon Sep 17 00:00:00 2001 From: DashyFox Date: Thu, 15 Feb 2024 17:01:53 +0300 Subject: [PATCH 23/51] Clean --- IR_Decoder.cpp | 2 ++ IR_Decoder.h | 31 ------------------------------- 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index fa13d11..3d7cff9 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -405,6 +405,8 @@ void IR_Decoder::writeToBuffer(bool bit) { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } + + bool IR_Decoder::crcCheck(uint8_t len, crc_t& crc) { bool crcOK = false; diff --git a/IR_Decoder.h b/IR_Decoder.h index fa4cb81..364c38c 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -267,37 +267,6 @@ private: /// @param divider Делитель /// @return Результат uint16_t ceil_div(uint16_t val, uint16_t divider); - //uint16_t sma = 0; - void SMA(uint16_t); - - //TODO: Сделать функцию медианы - void medi(uint16_t); - - // class Medi { - // public: - // uint16_t* arr; - // uint8_t size; - // uint8_t center; - - // Medi(uint8_t _size) : size(_size - 1) { - // arr = new uint16_t[size] { 0 }; - // center = size / 2; - // }; - - // void add(uint16_t newVal) { - // _add(newVal, center); - // } - - // void _add(uint16_t newVal, int8_t pos, bool f) { - // if (pos < 0 || pos > size) return; - - // if (newVal < arr[pos]) _add(newVal, pos-1, f); - // if (newVal > arr[pos]) _add(newVal, pos+1, f); - // } - - // ~Medi() { delete arr; } - // }; - #ifdef IRDEBUG inline void errPulse(uint8_t pin, uint8_t count); From a143dcf80d3f28eebf9926975510a2d0402acdc3 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Fri, 16 Feb 2024 09:28:09 +0300 Subject: [PATCH 24/51] add packToOutClass func --- IR_Decoder.cpp | 101 ++++++++++++++++++++++++++++--------------------- IR_Decoder.h | 2 + 2 files changed, 60 insertions(+), 43 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 3d7cff9..ab92032 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -1,7 +1,7 @@ #include "IR_Decoder.h" #include "IR_Encoder.h" -// #define IRDEBUG_INFO +#define IRDEBUG_INFO #define checkAddr(h, l) (\ ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) == addrSelf) || \ @@ -79,7 +79,7 @@ void IR_Decoder::start_RX() { void IR_Decoder::listen() { if (isRecive && ((micros() - prevRise) > IR_timeout)) { - isRecive = false; + isRecive = false; start_RX(); } } @@ -97,7 +97,7 @@ void IR_Decoder::tick() { if (currentFront.time - prevRise > IR_timeout * 2 /* && !isRecive */) { // первый preambFrontCounter = preambFronts - 1U; - + if (!currentFront.dir) { isRecive = true; } @@ -326,10 +326,13 @@ void IR_Decoder::writeToBuffer(bool bit) { i_syncBit++; } ////////////////////// Проверка наличия битов синхранизации ////////////////////// - isWrongPack = (err_syncBit >= syncBits); - #ifdef IRDEBUG_INFO - if (isWrongPack) Serial.print("****************"); - #endif + if (isWrongPack = (err_syncBit >= syncBits)) { + start_RX(); + #ifdef IRDEBUG_INFO + Serial.print("****************"); + #endif + }; + }//**************************************************************************************************// // Serial.print(bit); @@ -348,54 +351,38 @@ void IR_Decoder::writeToBuffer(bool bit) { if (i_dataBuffer == ((dataBuffer[0] & IR_MASK_MSG_INFO) * bitPerByte)) { Serial.print(" <-"); } } #endif + if ((i_dataBuffer >= (8 * msgBytes)) && !isCrcCorrect) { uint16_t crcValue; switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { case IR_MSG_ACCEPT: - if (i_dataBuffer >= ((msgBytes + addrBytes + crcBytes) * bitPerByte)) { - constexpr uint8_t dataSize = msgBytes + addrBytes; - isCrcCorrect = crcCheck(dataSize, crcValue); - if (isCrcCorrect && checkAddr(1, 2)) { - gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errors, riseSyncTime); - gotAccept._isAvaliable = true; - } - } + packToOutClass( + ((msgBytes + addrBytes + crcBytes) * bitPerByte), // endBitOffset + (msgBytes + addrBytes), // bytesToCheck + 1, // addressForCheckOffset + &gotAccept // objFine + ); break; case IR_MSG_REQUEST: - if (i_dataBuffer >= ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte)) { - constexpr uint8_t dataSize = msgBytes + addrBytes + addrBytes; - isCrcCorrect = crcCheck(dataSize, crcValue); - if (isCrcCorrect && checkAddr(3, 4)) { - gotRequest._isAvaliable = true; - gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errors, riseSyncTime); - } - } + packToOutClass( + ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte), // endBitOffset + (msgBytes + addrBytes + addrBytes), // bytesToCheck + 3, // addressForCheckOffset + &gotRequest // objFine + ); break; case IR_MSG_DATA_ACCEPT: case IR_MSG_DATA_NOACCEPT: - if (i_dataBuffer >= ((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte) { - #ifdef IRDEBUG_INFO - Serial.print(" IN "); - #endif - const uint8_t dataSize = (dataBuffer[0] & IR_MASK_MSG_INFO); - isCrcCorrect = crcCheck(dataSize, crcValue); - if (isCrcCorrect && checkAddr(3, 4)) { - #ifdef IRDEBUG_INFO - Serial.println(" OK "); - #endif - gotData._isAvaliable = true; - gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errors, riseSyncTime); - } else { - gotRawData._isAvaliable = true; - gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errors, riseSyncTime); - #ifdef IRDEBUG_INFO - Serial.println(" NOT OK "); - #endif - } - } + packToOutClass( + (((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte), // endBitOffset + (dataBuffer[0] & IR_MASK_MSG_INFO), // bytesToCheck + 3, // addressForCheckOffset + &gotData, // objFine + &gotRawData // objWrong + ); break; default: @@ -405,6 +392,34 @@ void IR_Decoder::writeToBuffer(bool bit) { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } +void IR_Decoder::packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, InputData* objFine, InputData* objWrong = nullptr) { + uint16_t crcValue; + InputData* objResult = nullptr; + if (i_dataBuffer >= endBitOffset) { + #ifdef IRDEBUG_INFO + Serial.print(" IN "); + #endif + isCrcCorrect = crcCheck(bytesToCheck, crcValue); + if (isCrcCorrect && checkAddr(addressForCheckOffset, addressForCheckOffset + 1)) { + #ifdef IRDEBUG_INFO + Serial.println(" OK "); + #endif + objResult = objFine; + } else { + objResult = objWrong; + #ifdef IRDEBUG_INFO + Serial.println(" NOT OK "); + #endif + } + if (objWrong != nullptr) { + objResult->_isAvaliable = true; + objResult->_set(dataBuffer, bytesToCheck + crcBytes, crcValue, errors, riseSyncTime); + } + isRecive = false; + start_RX(); + } +} + bool IR_Decoder::crcCheck(uint8_t len, crc_t& crc) { diff --git a/IR_Decoder.h b/IR_Decoder.h index 364c38c..7b96fec 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -257,11 +257,13 @@ private: /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация /// @param Бит данных void writeToBuffer(bool); + void packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, InputData* objFine, InputData* objWrong = nullptr); //////////////////////////////////////////////////////////////////////// /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных void start_RX(); + /// @brief Целочисленное деление с округлением вверх /// @param val Значение /// @param divider Делитель From a0ca86909de08d0a90ca2b0d9be39a4cb57f81ee Mon Sep 17 00:00:00 2001 From: DashyFox Date: Fri, 16 Feb 2024 16:06:53 +0300 Subject: [PATCH 25/51] fix forever loop --- IR_Decoder.cpp | 25 ++++++++++++++++--------- IR_Decoder.h | 15 +++------------ 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index ab92032..85aa165 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -1,7 +1,7 @@ #include "IR_Decoder.h" #include "IR_Encoder.h" -#define IRDEBUG_INFO +// #define IRDEBUG_INFO #define checkAddr(h, l) (\ ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) == addrSelf) || \ @@ -12,7 +12,7 @@ IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair // rawBuffer = new uint8_t[bufferRawSize] { 0 }; dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; prevRise = prevFall = prevPrevFall = prevPrevRise = 0; - start_RX(); + // start_RX(); } IR_Decoder::~IR_Decoder() { @@ -78,27 +78,33 @@ void IR_Decoder::start_RX() { } void IR_Decoder::listen() { - if (isRecive && ((micros() - prevRise) > IR_timeout)) { + if (isRecive && ((micros() - prevRise) > IR_timeout * 2)) { isRecive = false; start_RX(); } } void IR_Decoder::tick() { - listen(); - if (firstUnHandledFront == nullptr) return; //Если данных нет - ничего не делаем - FrontStorage currentFront; - //найти следующий необработанный фронт/спад noInterrupts(); - currentFront = *((FrontStorage*)firstUnHandledFront); + listen(); + if (firstUnHandledFront == nullptr) { interrupts(); return; } //Если данных нет - ничего не делаем + currentFront = *((FrontStorage*)firstUnHandledFront); //найти следующий необработанный фронт/спад interrupts(); //////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (currentFront.time - prevRise > IR_timeout * 2 /* && !isRecive */) { // первый + if (currentFront.time > prevRise && currentFront.time - prevRise > IR_timeout * 2 && !isRecive) { // первый preambFrontCounter = preambFronts - 1U; + if (!currentFront.dir) { + #ifdef IRDEBUG_INFO + // Serial.print(" currentFront.time: "); Serial.print(currentFront.time); + // Serial.print(" currentFront.dir: "); Serial.print(currentFront.dir ? "UP" : "DOWN"); + // Serial.print(" next: "); Serial.print(currentFront.next == nullptr); + // Serial.print(" prevRise: "); Serial.print(prevRise); + // Serial.print(" SUB: "); Serial.println(currentFront.time - prevRise); + #endif isRecive = true; } } @@ -328,6 +334,7 @@ void IR_Decoder::writeToBuffer(bool bit) { ////////////////////// Проверка наличия битов синхранизации ////////////////////// if (isWrongPack = (err_syncBit >= syncBits)) { start_RX(); + firstUnHandledFront = firstUnHandledFront->next; #ifdef IRDEBUG_INFO Serial.print("****************"); #endif diff --git a/IR_Decoder.h b/IR_Decoder.h index 7b96fec..ac130a2 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -218,18 +218,9 @@ private: volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов struct FrontStorage { // Структура для хранения времени и направления фронта/спада - volatile uint32_t time; // Время - volatile bool dir; // Направление (true = ↑; false = ↓) - volatile FrontStorage* next; // Указатель на следующий связанный фронт/спад, или nullptr если конец - - // Операторо присвоения - FrontStorage& operator= (FrontStorage& val) { - this->next = val.next; - this->time = val.time; - this->dir = val.dir; - - return *this; - } + volatile uint32_t time = 0; // Время + volatile bool dir = false; // Направление (true = ↑; false = ↓) + volatile FrontStorage* next = nullptr; // Указатель на следующий связанный фронт/спад, или nullptr если конец }; volatile FrontStorage* lastFront = nullptr; // Указатель последнего фронта/спада volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада From fa767899c213c5b004f690eb776c96572e51e6f1 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Fri, 16 Feb 2024 16:23:54 +0300 Subject: [PATCH 26/51] fix fix --- IR_Decoder.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 85aa165..e45b638 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -333,10 +333,11 @@ void IR_Decoder::writeToBuffer(bool bit) { } ////////////////////// Проверка наличия битов синхранизации ////////////////////// if (isWrongPack = (err_syncBit >= syncBits)) { - start_RX(); - firstUnHandledFront = firstUnHandledFront->next; - #ifdef IRDEBUG_INFO + // start_RX(); + // firstUnHandledFront = firstUnHandledFront->next; + // firstUnHandledFront = nullptr; Serial.print("****************"); + #ifdef IRDEBUG_INFO #endif }; From 8269cbdbfbd1154789685653859dc462dbfa40f2 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Fri, 16 Feb 2024 16:24:40 +0300 Subject: [PATCH 27/51] fix fix --- IR_Decoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index e45b638..3a59f33 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -336,8 +336,8 @@ void IR_Decoder::writeToBuffer(bool bit) { // start_RX(); // firstUnHandledFront = firstUnHandledFront->next; // firstUnHandledFront = nullptr; - Serial.print("****************"); #ifdef IRDEBUG_INFO + Serial.print("****************"); #endif }; From 60143050110f32c804d3d948d9c0a0cfc74b4667 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Fri, 16 Feb 2024 16:57:50 +0300 Subject: [PATCH 28/51] static array for out class --- IR_Decoder.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/IR_Decoder.h b/IR_Decoder.h index ac130a2..c69f2a6 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -73,7 +73,7 @@ public: uint8_t _msgType = 0; uint16_t _addrFrom = 0; uint16_t _addrTo = 0; - uint8_t* _data = nullptr; + uint8_t _data[bytePerPack]; uint8_t _dataRawSize = 0; uint16_t _crcPackVal = 0; uint16_t _crcCalcVal = 0; @@ -85,9 +85,7 @@ public: _dataRawSize = len; _err = err; _bitPeriod = rTime; - if (_data != nullptr) { delete _data; _data = nullptr; } - _data = new uint8_t[len]; - for (uint8_t i = 0; i < len; i++) { _data[i] = ptr[i]; } + for (uint8_t i = 0; i < len && len Date: Fri, 16 Feb 2024 17:05:14 +0300 Subject: [PATCH 29/51] earse array --- IR_Decoder.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/IR_Decoder.h b/IR_Decoder.h index c69f2a6..bcec29a 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -85,7 +85,8 @@ public: _dataRawSize = len; _err = err; _bitPeriod = rTime; - for (uint8_t i = 0; i < len && len Date: Fri, 16 Feb 2024 17:12:38 +0300 Subject: [PATCH 30/51] fix size arr --- IR_Decoder.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IR_Decoder.h b/IR_Decoder.h index bcec29a..659515b 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -73,7 +73,7 @@ public: uint8_t _msgType = 0; uint16_t _addrFrom = 0; uint16_t _addrTo = 0; - uint8_t _data[bytePerPack]; + uint8_t _data[dataByteSizeMax]; uint8_t _dataRawSize = 0; uint16_t _crcPackVal = 0; uint16_t _crcCalcVal = 0; @@ -85,8 +85,8 @@ public: _dataRawSize = len; _err = err; _bitPeriod = rTime; - memset(_data, 0, bytePerPack); - for (uint8_t i = 0; i < len && len < bytePerPack; i++) { _data[i] = ptr[i]; } + memset(_data, 0, dataByteSizeMax); + memcpy(_data, ptr, min(len, dataByteSizeMax)); _msgType = _data[0]; ini(); _isAvaliable = true; From 8b07f544caab4d607ac6d0768132cf40c41fed62 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Fri, 16 Feb 2024 17:23:16 +0300 Subject: [PATCH 31/51] fix end of data detect --- IR_Decoder.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 3a59f33..f9257e6 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -1,7 +1,7 @@ #include "IR_Decoder.h" #include "IR_Encoder.h" -// #define IRDEBUG_INFO +#define IRDEBUG_INFO #define checkAddr(h, l) (\ ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) == addrSelf) || \ @@ -403,7 +403,7 @@ void IR_Decoder::writeToBuffer(bool bit) { void IR_Decoder::packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, InputData* objFine, InputData* objWrong = nullptr) { uint16_t crcValue; InputData* objResult = nullptr; - if (i_dataBuffer >= endBitOffset) { + if (i_dataBuffer == endBitOffset) { #ifdef IRDEBUG_INFO Serial.print(" IN "); #endif @@ -424,7 +424,6 @@ void IR_Decoder::packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint objResult->_set(dataBuffer, bytesToCheck + crcBytes, crcValue, errors, riseSyncTime); } isRecive = false; - start_RX(); } } From 8525f8330cdeec55a4dcbc47fe38b35b656432b9 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Fri, 16 Feb 2024 17:51:34 +0300 Subject: [PATCH 32/51] new pack info --- IR_config.h | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/IR_config.h b/IR_config.h index 73904e7..ba61120 100644 --- a/IR_config.h +++ b/IR_config.h @@ -19,11 +19,10 @@ IR_MSG_ACCEPT с адреса 0 воспринимается всеми устр - /```````````````````````````````````````````````` data pack `````````````````````````````````````````````\                                                                                                                                             {``````````} [````````````````````````] [````````````````````] [````````````````````````] [``````````````] -{ msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [ data bytes ] [ CRC Bytes ] +{ msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ] {..........} [........................] [....................] [........................] [..............]                                                                                                            { aka size } [addr_self_H][addr_self_L] [addr_to_H][addr_to_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ] @@ -37,9 +36,11 @@ msg type:                                         // | 01234567 |                                         //  ----------                                         // | xxx..... | = тип сообщения -                                        // | ...xxxxx | = длина (максимум 32 бита) +                                        // | ...xxxxx | = длина (максимум 31 бита)                                         //  ---------- */ #define IR_MSG_ 0U // | 000..... | = Задний сигнал машинки +;// // | \\\x---- | = нужна ли адресация +;// // | \\\-xxxx | = длина данных (Равна нулю при отсутствии сквозных команд) #define IR_MSG_ACCEPT 1U // | 001..... | = подтверждение #define IR_MSG_REQUEST 2U // | 010..... | = запрос #define IR_MSG_ 3U // | 011..... | = ?? @@ -63,6 +64,34 @@ msg type: |                                                  |          |                                                                             |     \__________________________________________________/          \_____________________________________________________________________________/     + + +/`````````````````````` Задний сигнал машинки без адресации ``````````````````````\        В (IR_MASK_MSG_INFO & 15U) содержится количество байт +                                                                                           сквозных команд, максимум 15 +{``````````} [````````````````````````] [````````````````````````] [``````````````]        Если полезных байт информации нет, отправляется один +{ msg type } [ addr_self uint16_t ] [====== data bytes ======] [ CRC Bytes ]        байт нулей +{..........} [........................] [........................] [..............]         +                                                                                            +{ 0000xxxx } [addr_self_H][addr_self_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]         +|     0           1            2            3                         |       |             +\_____________________________________________________________________/       |             +|                                                                             |             +\_____________________________________________________________________________/             + + + +/```````````````````````````````````` Задний сигнал машинки с адресацией ````````````````````````````````````\  +                                                                                     +{``````````} [````````````````````````] [````````````````````````] [````````````````````````] [``````````````]  +{ msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]  +{..........} [........................] [........................] [........................] [..............]  +                                                                                                                +{ 0001xxxx } [addr_self_H][addr_self_L] [addr_self_H][addr_self_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]  +|     0           1            2              3           4            5                         |       |      +\________________________________________________________________________________________________/       |      +|                                                                                                        |      +\________________________________________________________________________________________________________/      + */ #define IR_MASK_MSG_TYPE 0b00000111 From ba1d22ac29cb2c6c48661b34f9cb49a246873771 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Mon, 19 Feb 2024 10:07:21 +0300 Subject: [PATCH 33/51] clean --- IR_Decoder.h | 26 +++++------------ IR_config.h | 82 +++++++++++++++++++++++++++++++--------------------- 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/IR_Decoder.h b/IR_Decoder.h index 659515b..4a36fb1 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -51,19 +51,7 @@ public: ////////////////////////////////////////////////////////////////////////// - struct ErrorsStruct { - uint8_t lowSignal; - uint8_t highSignal; - uint8_t other; - - void reset() { - lowSignal = 0; - highSignal = 0; - other = 0; - } - uint16_t all() { return lowSignal + highSignal + other; } - - } errors; + public: class InputData : protected IR_FOX { @@ -121,12 +109,12 @@ public: uint8_t dataRawSize() { return _dataRawSize; }; uint8_t* dataRaw() { return _data; }; bool isNeedAccept() { return ((_msgType >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; - String printRawData(uint8_t mode = 10) { - return printBytes(dataRaw(), dataRawSize(), mode); - } - String printData(uint8_t mode = 10) { - return printBytes(data(), dataSize(), mode); - } + // String printRawData(uint8_t mode = 10) { + // return printBytes(dataRaw(), dataRawSize(), mode); + // } + // String printData(uint8_t mode = 10) { + // return printBytes(data(), dataSize(), mode); + // } ~Data() {}; private: void ini() override { diff --git a/IR_config.h b/IR_config.h index ba61120..368a77f 100644 --- a/IR_config.h +++ b/IR_config.h @@ -138,9 +138,23 @@ typedef uint16_t crc_t; #define tolerance 300U class IR_FOX { -private: - bool isSending = false; +public: + struct ErrorsStruct { + uint8_t lowSignal; + uint8_t highSignal; + uint8_t other; + + void reset() { + lowSignal = 0; + highSignal = 0; + other = 0; + } + uint16_t all() { return lowSignal + highSignal + other; } + + }; + protected: + ErrorsStruct errors; uint8_t crc8(uint8_t* data, uint8_t start, uint8_t end, uint8_t poly) { //TODO: сделать возможность межбайтовой проверки uint8_t crc = 0xff; size_t i, j; @@ -155,41 +169,43 @@ protected: } return crc; } + + // public: - /// @brief Вывод массива байт в строковом формате - /// @param d Указатель на массив - /// @param s Размер массива - /// @param mode Формат вывода DEC, BIN - /// @return Готовая для вывода строка - String printBytes(uint8_t* d, uint8_t s, uint8_t mode = 10) { - String str = ""; - uint8_t control = bitPerByte; - uint8_t* _data = d; - switch (mode) { - case 2: - for (size_t i = 0; i < s * 8; i++) { - if (i == control) { - str += " "; - control += bitPerByte; - } + // /// @brief Вывод массива байт в строковом формате + // /// @param d Указатель на массив + // /// @param s Размер массива + // /// @param mode Формат вывода DEC, BIN + // /// @return Готовая для вывода строка + // String printBytes(uint8_t* d, uint8_t s, uint8_t mode = 10) { + // String str = ""; + // uint8_t control = bitPerByte; + // uint8_t* _data = d; + // switch (mode) { + // case 2: + // for (size_t i = 0; i < s * 8; i++) { + // if (i == control) { + // str += " "; + // control += bitPerByte; + // } - str += _data[(i / 8)] >> (7 - (i % 8)) & 1; - } - break; - case 10: - for (size_t i = 0; i < s; i++) { - str += _data[i]; - str += " "; - } + // str += _data[(i / 8)] >> (7 - (i % 8)) & 1; + // } + // break; + // case 10: + // for (size_t i = 0; i < s; i++) { + // str += _data[i]; + // str += " "; + // } - break; + // break; - default: - break; - } + // default: + // break; + // } - str += " "; - return str; - } + // str += " "; + // return str; + // } }; From e4aa7b47c51cc121cbbb60f3888c3810308f6c19 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Mon, 19 Feb 2024 15:45:11 +0300 Subject: [PATCH 34/51] refactor --- IR_Decoder.cpp | 24 +++---- IR_Decoder.h | 174 +++++++------------------------------------------ IR_Output.h | 133 +++++++++++++++++++++++++++++++++++++ IR_config.h | 16 ++--- 4 files changed, 178 insertions(+), 169 deletions(-) create mode 100644 IR_Output.h diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index f9257e6..29a3830 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -4,11 +4,11 @@ #define IRDEBUG_INFO #define checkAddr(h, l) (\ - ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) == addrSelf) || \ + ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) == id) || \ ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) >= IR_Broadcast)\ ) -IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), addrSelf(addr), encoder(encPair) { +IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), id(addr), encoder(encPair) { // rawBuffer = new uint8_t[bufferRawSize] { 0 }; dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; prevRise = prevFall = prevPrevFall = prevPrevRise = 0; @@ -124,7 +124,7 @@ void IR_Decoder::tick() { // Serial.print("preambFrontCounter: "); Serial.println(preambFrontCounter); } else { if (isPreamb) {// первый фронт после - gotTune._set(riseSyncTime); + gotTune.set(dataBuffer, 1, 0, errors, riseSyncTime); } isPreamb = false; } @@ -367,7 +367,7 @@ void IR_Decoder::writeToBuffer(bool bit) { packToOutClass( ((msgBytes + addrBytes + crcBytes) * bitPerByte), // endBitOffset (msgBytes + addrBytes), // bytesToCheck - 1, // addressForCheckOffset + 1, // addressForCheck_Offset &gotAccept // objFine ); break; @@ -376,7 +376,7 @@ void IR_Decoder::writeToBuffer(bool bit) { packToOutClass( ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte), // endBitOffset (msgBytes + addrBytes + addrBytes), // bytesToCheck - 3, // addressForCheckOffset + 3, // addressForCheck_Offset &gotRequest // objFine ); break; @@ -387,7 +387,7 @@ void IR_Decoder::writeToBuffer(bool bit) { packToOutClass( (((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte), // endBitOffset (dataBuffer[0] & IR_MASK_MSG_INFO), // bytesToCheck - 3, // addressForCheckOffset + 3, // addressForCheck_Offset &gotData, // objFine &gotRawData // objWrong ); @@ -400,9 +400,9 @@ void IR_Decoder::writeToBuffer(bool bit) { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } -void IR_Decoder::packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, InputData* objFine, InputData* objWrong = nullptr) { +void IR_Decoder::packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, IDataPack* objFine, IDataPack* objWrong = nullptr) { uint16_t crcValue; - InputData* objResult = nullptr; + IDataPack* objResult = nullptr; if (i_dataBuffer == endBitOffset) { #ifdef IRDEBUG_INFO Serial.print(" IN "); @@ -420,8 +420,8 @@ void IR_Decoder::packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint #endif } if (objWrong != nullptr) { - objResult->_isAvaliable = true; - objResult->_set(dataBuffer, bytesToCheck + crcBytes, crcValue, errors, riseSyncTime); + objResult->isAvaliable = true; + objResult->set(dataBuffer, bytesToCheck + crcBytes, crcValue, errors, riseSyncTime); } isRecive = false; } @@ -442,7 +442,9 @@ bool IR_Decoder::crcCheck(uint8_t len, crc_t& crc) { dataBuffer[len + 1] == (crc & 0xFF) ) { crcOK = true; - } else { crcOK = false; } + } else { + crcOK = false; + } return crcOK; diff --git a/IR_Decoder.h b/IR_Decoder.h index 4a36fb1..b7ad346 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -1,5 +1,6 @@ #pragma once #include "IR_config.h" +#include "IR_Output.h" //#define IRDEBUG @@ -26,182 +27,55 @@ class IR_Encoder; class IR_Decoder : private IR_FOX { friend IR_Encoder; public: - uint16_t addrSelf; + uint16_t id; + Data gotData; /// @brief Контейнер с данными + Data gotRawData; + Accept gotAccept; /// @brief Контейнер с подтверждением + Request gotRequest; /// @brief Контейнер с запросом + RawTune gotTune; /// @brief Контейнер с информацией подстройки + + const uint8_t isrPin; // Пин прерывания + + ////////////////////////////////////////////////////////////////////////// /// @brief Конструктор /// @param isrPin Номер вывода прерывания/данных от приёмника (2 или 3 для atmega 328p) /// @param addr Адрес приёмника /// @param encPair Указатель на передатчик, работающий в паре IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr); + ~IR_Decoder(); - // @brief Функция прерывания - void isr(); - - /// @brief Обработка приёмника, необходима для работы - void tick(); - + void isr(); ///@brief Функция прерывания + void tick(); /// @brief Обработка приёмника, необходима для работы // @return Буффер переполнился bool isOverflow() { return isBufferOverflow; }; + /// @brief Флаг приёма /// @return Возвращает true, если происходит приём пакета bool isReciving() { return isRecive; }; + // @brief Слушатель для работы isReciving() void listen(); ////////////////////////////////////////////////////////////////////////// - - -public: - class InputData : protected IR_FOX { - friend IR_Decoder; - protected: - bool _isAvaliable = false; - uint8_t _msgType = 0; - uint16_t _addrFrom = 0; - uint16_t _addrTo = 0; - uint8_t _data[dataByteSizeMax]; - uint8_t _dataRawSize = 0; - uint16_t _crcPackVal = 0; - uint16_t _crcCalcVal = 0; - ErrorsStruct _err; - uint16_t _bitPeriod = 0; - - void _set(uint8_t* ptr, uint8_t len, uint16_t crc, ErrorsStruct err, uint16_t rTime) { - _crcCalcVal = crc; - _dataRawSize = len; - _err = err; - _bitPeriod = rTime; - memset(_data, 0, dataByteSizeMax); - memcpy(_data, ptr, min(len, dataByteSizeMax)); - _msgType = _data[0]; - ini(); - _isAvaliable = true; - } - - private: - virtual void ini(); - - public: - bool avaliable() { return _isAvaliable; }; - uint8_t msgInfo() { return _msgType & IR_MASK_MSG_INFO; }; - uint8_t msgType() { return (_msgType >> 5) & IR_MASK_MSG_TYPE; }; - uint8_t msgRAW() { return _msgType; }; - uint16_t errorCount() { return _err.all(); }; - uint8_t errorLowSignal() { return _err.lowSignal; }; - uint8_t errorHighSignal() { return _err.highSignal; }; - uint8_t errorOther() { return _err.other; }; - uint16_t crcIN() { return _crcPackVal; }; - uint16_t crcCALC() { return _crcCalcVal; }; - uint16_t tunerTime() { return _bitPeriod; }; - void resetAvaliable() { _isAvaliable = false; }; - }; - - ////////////////////////////////////////////////////////////////////////// - - class Data : public InputData { - public: - uint16_t addrFrom() { return _addrFrom; }; - uint16_t addrTo() { return _addrTo; }; - uint8_t dataSize() { return _dataRawSize - (msgBytes + addrBytes + addrBytes + crcBytes); }; - uint8_t* data() { return &_data[msgBytes + addrBytes + addrBytes]; }; - uint8_t dataRawSize() { return _dataRawSize; }; - uint8_t* dataRaw() { return _data; }; - bool isNeedAccept() { return ((_msgType >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; - // String printRawData(uint8_t mode = 10) { - // return printBytes(dataRaw(), dataRawSize(), mode); - // } - // String printData(uint8_t mode = 10) { - // return printBytes(data(), dataSize(), mode); - // } - ~Data() {}; - private: - void ini() override { - _addrFrom = (_data[1] << 8) | _data[2]; - _addrTo = (_data[3] << 8) | _data[4]; - _crcPackVal = (_data[_dataRawSize - 2] << 8) | _data[_dataRawSize - 1]; - } - }; - - // class RawData : public Data { - // }; - - class Accept : public InputData { - public: - uint16_t addrFrom() { return _addrFrom; }; - - private: - void ini() override { - _addrFrom = (_data[1] << 8) | _data[2]; - _crcPackVal = (_data[3] << 8) | _data[4]; - } - }; - - class Request : public Accept { - public: - uint16_t addrTo() { return _addrTo; }; - private: - void ini() override { - _addrFrom = (_data[1] << 8) | _data[2]; - _addrTo = (_data[3] << 8) | _data[4]; - _crcPackVal = (_data[5] << 8) | _data[6]; - } - }; - - class RawTune { - friend IR_Decoder; - private: - bool _isAvaliable = false; - uint16_t _errCount = 0; - uint16_t _tune = 0; - public: - bool avaliable() { return _isAvaliable; }; - uint16_t getTune() { return _tune; }; - uint16_t errorCount() { return _errCount; }; - void resetAvaliable() { _isAvaliable = false; }; - private: - void _set(uint16_t val) { - _tune = val; - _isAvaliable = true; - } - }; - - /// @brief Контейнер с данными - Data gotData; - Data gotRawData; - /// @brief Контейнер с подтверждением - Accept gotAccept; - /// @brief Контейнер с запросом - Request gotRequest; - /// @brief Контейнер с информацией подстройки - RawTune gotTune; - - const uint8_t isrPin; // Пин прерывания - private: - - IR_Encoder* encoder; // Указатель на парный передатчик volatile uint16_t isPairSending = 0; // Флаг передачи парного передатчика - - volatile bool isRecive = false; // Флаг приёма - + volatile bool isPreamb = false; // флаг начальной последовости bool isWaitingAccept = false; // Флаг ожидания подтверждения - uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение - - uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс - bool isCrcCorrect = false; // Флаг корректности crc bool isBufferOverflow = false; // Флаг переполнения буффера данных bool isWrongPack = false; // Флаг битого пакета - volatile bool isPreamb = false; // флаг начальной последовости - bool HIGH_FIRST = true; //TODO: порядок приходящих битов + uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение + uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс + + // bool HIGH_FIRST = true; //TODO: порядок приходящих битов //////////////////////////////////////////////////////////////////////// - void noFunc(); volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов struct FrontStorage { // Структура для хранения времени и направления фронта/спада @@ -225,6 +99,7 @@ private: /// @param crc Результат рассчёта crc (Выходной параметр) /// @return true если crc верно bool crcCheck(uint8_t len, uint16_t& crc); + //////////////////////////////////////////////////////////////////////// bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации uint16_t i_dataBuffer; // Счётчик буфера данных @@ -235,13 +110,12 @@ private: /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация /// @param Бит данных void writeToBuffer(bool); - void packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, InputData* objFine, InputData* objWrong = nullptr); + void packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, IDataPack* objFine, IDataPack* objWrong = nullptr); //////////////////////////////////////////////////////////////////////// /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных void start_RX(); - /// @brief Целочисленное деление с округлением вверх /// @param val Значение /// @param divider Делитель @@ -254,4 +128,4 @@ private: #endif -}; \ No newline at end of file + }; \ No newline at end of file diff --git a/IR_Output.h b/IR_Output.h new file mode 100644 index 0000000..9a79ce7 --- /dev/null +++ b/IR_Output.h @@ -0,0 +1,133 @@ +#pragma once +#include "IR_config.h" +class IR_Decoder; + +class IDataPack : protected IR_FOX { + friend IR_Decoder; +protected: + inline static uint8_t data[dataByteSizeMax]{0}; + + bool isAvaliable = false; + + void* msgPtr = nullptr; + void* addrFromPtr = nullptr; + void* addrToPtr = nullptr; + void* dataPtr = nullptr; + void* crcPtr = nullptr; + + + + uint8_t msgByte = 0; + uint8_t packRawSize = 0; // полная длина пакета + + ErrorsStruct err; + uint16_t bitPeriod = 0; + uint16_t crcPackVal = 0; + uint16_t crcCalcVal = 0; + + ///////////// смещения //////////////// + uint8_t crcOffset; + //переопределяемые дочерними классами// + uint8_t msgOffset; + uint8_t addrFromOffset; + uint8_t addrToOffset; + uint8_t dataOffset; + ////////////////////////////////////// + + void set(uint8_t* ptr, uint8_t len, uint16_t crc, ErrorsStruct err, uint16_t rTime) { + memset(IDataPack::data, 0, dataByteSizeMax); + memcpy(data, ptr, min(len, dataByteSizeMax)); + packRawSize = len; + + bitPeriod = rTime; + err = err; + crcCalcVal = crc; + crcOffset = packRawSize - crcBytes; + + msgByte = *(uint8_t*)msgPtr; + isAvaliable = true; + + msgPtr = (data + msgOffset); + addrFromPtr = (data + addrFromOffset); + addrToPtr = (data + addrToOffset); + dataPtr = (data + dataOffset); + crcPtr = (data + crcOffset); + + } + +public: + bool avaliable() { return isAvaliable; }; + uint8_t getMsgInfo() { return msgByte & IR_MASK_MSG_INFO; }; + uint8_t getMsgType() { return (msgByte >> 5) & IR_MASK_MSG_TYPE; }; + uint8_t getMsgRAW() { return msgByte; }; + uint16_t getErrorCount() { return err.all(); }; + uint8_t getErrorLowSignal() { return err.lowSignal; }; + uint8_t getErrorHighSignal() { return err.highSignal; }; + uint8_t getErrorOther() { return err.other; }; + uint16_t getTunerTime() { return bitPeriod; }; + void resetAvaliable() { isAvaliable = false; }; +}; + +////////////////////////////////////////////////////////////////////////// + +class Data : public IDataPack { +public: + Data() { + msgOffset = 0; + addrFromOffset = 1; + addrToOffset = 3; + dataOffset = 5; + + } + + +public: + uint16_t getAddrFrom() { return *(uint16_t*)addrFromPtr; }; + uint16_t getAddrTo() { return *(uint16_t*)addrToPtr; }; + uint8_t getDataSize() { return packRawSize - (msgBytes + addrBytes + addrBytes + crcBytes); }; + uint8_t* getDataPrt() { return (uint8_t*)dataPtr; }; + uint8_t getDataRawSize() { return packRawSize; }; + uint8_t* getDataRawPtr() { return data; }; + uint16_t getCrcIN() { return *(uint16_t*)crcPtr; }; + uint16_t getCrcCALC() { return crcCalcVal; }; + bool isNeedAccept() { return ((msgByte >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; + ~Data() {}; +}; + +// class RawData : public Data { +// }; + +class Accept : public IDataPack { +public: + Accept() { + msgOffset = 0; + addrFromOffset = 1; + } + + uint16_t getAddrFrom() { return *(uint16_t*)addrFromPtr; }; + uint16_t getCrcIN() { return *(uint16_t*)crcPtr; }; + uint16_t getCrcCALC() { return crcCalcVal; }; + +}; + +class Request : public IDataPack { +public: + Request() { + msgOffset = 0; + addrFromOffset = 1; + addrToOffset = 3; + } + + uint16_t getAddrFrom() { return *(uint16_t*)addrFromPtr; }; + uint16_t getAddrTo() { return *(uint16_t*)addrToPtr; }; + uint16_t getCrcIN() { return *(uint16_t*)crcPtr; }; + uint16_t getCrcCALC() { return crcCalcVal; }; +}; + +class RawTune : public IDataPack { +public: + RawTune() { + msgOffset = 0; + } + +}; \ No newline at end of file diff --git a/IR_config.h b/IR_config.h index 368a77f..a106116 100644 --- a/IR_config.h +++ b/IR_config.h @@ -22,10 +22,10 @@ IR_MSG_ACCEPT с адреса 0 воспринимается всеми устр /```````````````````````````````````````````````` data pack `````````````````````````````````````````````\                                                                                                                                             {``````````} [````````````````````````] [````````````````````] [````````````````````````] [``````````````] -{ msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ] +{ msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ] {..........} [........................] [....................] [........................] [..............]                                                                                                            -{ aka size } [addr_self_H][addr_self_L] [addr_to_H][addr_to_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ] +{ aka size } [addr_from_H][addr_from_L] [addr_to_H][addr_to_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ] |     0           1            2              3         4          5                         |       |     \____________________________________________________________________________________________/       |     |                                                                                                    |     @@ -55,10 +55,10 @@ msg type: /```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\                                                                                                                        {``````````} [````````````````````````] [``````````````]      {``````````} [````````````````````````] [````````````````````````] [``````````````] -{ msg type } [ addr_self uint16_t ] [ CRC Bytes ]      { msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] +{ msg type } [ addr_from uint16_t ] [ CRC Bytes ]      { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] {..........} [........................] [..............]      {..........} [........................] [........................] [..............]                                                                                                                                                   -{ 001..... } [addr_self_H][addr_self_L] [ crc1 ][ crc2 ]      { 010..... } [addr_self_H][addr_self_L] [addr_self_H][addr_self_L] [ crc1 ][ crc2 ] +{ 001..... } [addr_from_H][addr_from_L] [ crc1 ][ crc2 ]      { 010..... } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [ crc1 ][ crc2 ] |     0            1           2           3       4          |     0            1           2              3           4           5       6     \__________________________________________/       |          \_____________________________________________________________________/       |     |                                                  |          |                                                                             |     @@ -69,10 +69,10 @@ msg type: /`````````````````````` Задний сигнал машинки без адресации ``````````````````````\        В (IR_MASK_MSG_INFO & 15U) содержится количество байт                                                                                            сквозных команд, максимум 15 {``````````} [````````````````````````] [````````````````````````] [``````````````]        Если полезных байт информации нет, отправляется один -{ msg type } [ addr_self uint16_t ] [====== data bytes ======] [ CRC Bytes ]        байт нулей +{ msg type } [ addr_from uint16_t ] [====== data bytes ======] [ CRC Bytes ]        байт нулей {..........} [........................] [........................] [..............]                                                                                                     -{ 0000xxxx } [addr_self_H][addr_self_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]         +{ 0000xxxx } [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]         |     0           1            2            3                         |       |             \_____________________________________________________________________/       |             |                                                                             |             @@ -83,10 +83,10 @@ msg type: /```````````````````````````````````` Задний сигнал машинки с адресацией ````````````````````````````````````\                                                                                       {``````````} [````````````````````````] [````````````````````````] [````````````````````````] [``````````````]  -{ msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]  +{ msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]  {..........} [........................] [........................] [........................] [..............]                                                                                                                  -{ 0001xxxx } [addr_self_H][addr_self_L] [addr_self_H][addr_self_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]  +{ 0001xxxx } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]  |     0           1            2              3           4            5                         |       |      \________________________________________________________________________________________________/       |      |                                                                                                        |      From 27dd448cb03845ae6f1633462e2e54cacdd2713d Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 20 Feb 2024 15:00:00 +0300 Subject: [PATCH 35/51] refactor --- IR_Decoder.cpp | 105 +++++++++++++++++++--------- IR_Decoder.h | 15 ++-- IR_Output.h | 182 ++++++++++++++++++++++++------------------------- IR_config.h | 26 ++++++- 4 files changed, 192 insertions(+), 136 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 29a3830..6803bcc 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -9,10 +9,8 @@ ) IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), id(addr), encoder(encPair) { - // rawBuffer = new uint8_t[bufferRawSize] { 0 }; dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; prevRise = prevFall = prevPrevFall = prevPrevRise = 0; - // start_RX(); } IR_Decoder::~IR_Decoder() { @@ -35,7 +33,7 @@ void IR_Decoder::isr() { firstUnHandledFront = firstUnHandledFront->next; #ifdef IRDEBUG_INFO // Serial.println(); - // Serial.println("ERROR"); + Serial.println(" ISR BUFFER OVERFLOW "); // Serial.println(); #endif } @@ -124,7 +122,7 @@ void IR_Decoder::tick() { // Serial.print("preambFrontCounter: "); Serial.println(preambFrontCounter); } else { if (isPreamb) {// первый фронт после - gotTune.set(dataBuffer, 1, 0, errors, riseSyncTime); + gotTune.set(riseSyncTime); } isPreamb = false; } @@ -350,7 +348,7 @@ void IR_Decoder::writeToBuffer(bool bit) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //const auto testval = bufferBitSizeMax; + #ifdef IRDEBUG_INFO if (isData) { if (i_dataBuffer == ((msgBytes)*bitPerByte)) { Serial.print(" -> "); Serial.print(dataBuffer[0] & IR_MASK_MSG_INFO); Serial.print(" ->"); } @@ -363,21 +361,46 @@ void IR_Decoder::writeToBuffer(bool bit) { if ((i_dataBuffer >= (8 * msgBytes)) && !isCrcCorrect) { uint16_t crcValue; switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { + + case IR_MSG_BACK: + packToOutClass( + (((dataBuffer[0] & (IR_MASK_MSG_INFO >> 1)) + crcBytes)), // packSize + gotData, // obj + PackOffsets { + 0, // msgOffset + 1, // addrFromOffset + NULL, // addrToOffset + 3, // dataOffset + NULL // crcOffset + } + ); + break; + case IR_MSG_ACCEPT: packToOutClass( - ((msgBytes + addrBytes + crcBytes) * bitPerByte), // endBitOffset - (msgBytes + addrBytes), // bytesToCheck - 1, // addressForCheck_Offset - &gotAccept // objFine + ((msgBytes + addrBytes + crcBytes)), // packSize + gotAccept, // obj + PackOffsets { + 0, // msgOffset + 1, // addrFromOffset + NULL, // addrToOffset + NULL, // dataOffset + 3 // crcOffset + } ); break; case IR_MSG_REQUEST: packToOutClass( - ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte), // endBitOffset - (msgBytes + addrBytes + addrBytes), // bytesToCheck - 3, // addressForCheck_Offset - &gotRequest // objFine + ((msgBytes + addrBytes + addrBytes + crcBytes)), // packSize + gotRequest, // obj + PackOffsets { + 0, // msgOffset + 1, // addrFromOffset + 3, // addrToOffset + NULL, // dataOffset + 5 // crcOffset + } ); break; @@ -385,11 +408,15 @@ void IR_Decoder::writeToBuffer(bool bit) { case IR_MSG_DATA_ACCEPT: case IR_MSG_DATA_NOACCEPT: packToOutClass( - (((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte), // endBitOffset - (dataBuffer[0] & IR_MASK_MSG_INFO), // bytesToCheck - 3, // addressForCheck_Offset - &gotData, // objFine - &gotRawData // objWrong + (((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)), // packSize + gotData, // obj + PackOffsets { + 0, // msgOffset + 1, // addrFromOffset + 3, // addrToOffset + 5, // dataOffset + NULL // crcOffset + } ); break; @@ -400,29 +427,39 @@ void IR_Decoder::writeToBuffer(bool bit) { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } -void IR_Decoder::packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, IDataPack* objFine, IDataPack* objWrong = nullptr) { - uint16_t crcValue; - IDataPack* objResult = nullptr; - if (i_dataBuffer == endBitOffset) { +void IR_Decoder::packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets) { + + if (i_dataBuffer == packSize * bitPerByte) { + PackOutInfo packInfo; #ifdef IRDEBUG_INFO Serial.print(" IN "); #endif - isCrcCorrect = crcCheck(bytesToCheck, crcValue); - if (isCrcCorrect && checkAddr(addressForCheckOffset, addressForCheckOffset + 1)) { - #ifdef IRDEBUG_INFO - Serial.println(" OK "); - #endif - objResult = objFine; + isCrcCorrect = crcCheck(packSize - crcBytes, packInfo.crc); + if (isCrcCorrect) { + // if ((addressForCheckOffset >= 0 ? checkAddr(addressForCheckOffset, addressForCheckOffset + 1) : 1)) {// адрес верен + // #ifdef IRDEBUG_INFO + // Serial.println(" OK "); + // #endif + + // } else { // адресс не верен + // #ifdef IRDEBUG_INFO + // Serial.println(" NOT MY "); + // #endif + // } + + packInfo.ptr = dataBuffer; + packInfo.packSize = packSize; + packInfo.offsets = offsets; + packInfo.offsets.crcOffset = packInfo.packSize - crcBytes; + packInfo.err = errors; + packInfo.rTime = riseSyncTime; + obj.set(packInfo); } else { - objResult = objWrong; #ifdef IRDEBUG_INFO - Serial.println(" NOT OK "); + Serial.println(" CRC WRONG "); #endif } - if (objWrong != nullptr) { - objResult->isAvaliable = true; - objResult->set(dataBuffer, bytesToCheck + crcBytes, crcValue, errors, riseSyncTime); - } + isRecive = false; } } diff --git a/IR_Decoder.h b/IR_Decoder.h index b7ad346..17f16cd 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -28,10 +28,11 @@ class IR_Decoder : private IR_FOX { friend IR_Encoder; public: uint16_t id; - Data gotData; /// @brief Контейнер с данными - Data gotRawData; - Accept gotAccept; /// @brief Контейнер с подтверждением - Request gotRequest; /// @brief Контейнер с запросом + + Data gotData = Data(id); /// @brief Контейнер с данными + Data gotRawData = Data(id); + Accept gotAccept = Accept(id); /// @brief Контейнер с подтверждением + Request gotRequest = Request(id); /// @brief Контейнер с запросом RawTune gotTune; /// @brief Контейнер с информацией подстройки const uint8_t isrPin; // Пин прерывания @@ -73,8 +74,6 @@ private: uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс - // bool HIGH_FIRST = true; //TODO: порядок приходящих битов - //////////////////////////////////////////////////////////////////////// volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов @@ -110,7 +109,7 @@ private: /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация /// @param Бит данных void writeToBuffer(bool); - void packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, IDataPack* objFine, IDataPack* objWrong = nullptr); + void packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets); //////////////////////////////////////////////////////////////////////// /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных @@ -128,4 +127,4 @@ private: #endif - }; \ No newline at end of file +}; \ No newline at end of file diff --git a/IR_Output.h b/IR_Output.h index 9a79ce7..ff5a9fe 100644 --- a/IR_Output.h +++ b/IR_Output.h @@ -4,130 +4,126 @@ class IR_Decoder; class IDataPack : protected IR_FOX { friend IR_Decoder; -protected: - inline static uint8_t data[dataByteSizeMax]{0}; - - bool isAvaliable = false; - - void* msgPtr = nullptr; - void* addrFromPtr = nullptr; - void* addrToPtr = nullptr; - void* dataPtr = nullptr; - void* crcPtr = nullptr; - - - - uint8_t msgByte = 0; - uint8_t packRawSize = 0; // полная длина пакета - - ErrorsStruct err; - uint16_t bitPeriod = 0; - uint16_t crcPackVal = 0; - uint16_t crcCalcVal = 0; - - ///////////// смещения //////////////// - uint8_t crcOffset; - //переопределяемые дочерними классами// - uint8_t msgOffset; - uint8_t addrFromOffset; - uint8_t addrToOffset; - uint8_t dataOffset; - ////////////////////////////////////// - - void set(uint8_t* ptr, uint8_t len, uint16_t crc, ErrorsStruct err, uint16_t rTime) { - memset(IDataPack::data, 0, dataByteSizeMax); - memcpy(data, ptr, min(len, dataByteSizeMax)); - packRawSize = len; - - bitPeriod = rTime; - err = err; - crcCalcVal = crc; - crcOffset = packRawSize - crcBytes; - - msgByte = *(uint8_t*)msgPtr; - isAvaliable = true; - - msgPtr = (data + msgOffset); - addrFromPtr = (data + addrFromOffset); - addrToPtr = (data + addrToOffset); - dataPtr = (data + dataOffset); - crcPtr = (data + crcOffset); - - } +public: + IDataPack(uint16_t id) : id(id) {}; public: bool avaliable() { return isAvaliable; }; - uint8_t getMsgInfo() { return msgByte & IR_MASK_MSG_INFO; }; - uint8_t getMsgType() { return (msgByte >> 5) & IR_MASK_MSG_TYPE; }; - uint8_t getMsgRAW() { return msgByte; }; + uint8_t getMsgInfo() { return msgPtr[0] & IR_MASK_MSG_INFO; }; + uint8_t getMsgType() { return (msgPtr[0] >> 5) & IR_MASK_MSG_TYPE; }; + uint8_t getMsgRAW() { return msgPtr[0]; }; uint16_t getErrorCount() { return err.all(); }; uint8_t getErrorLowSignal() { return err.lowSignal; }; uint8_t getErrorHighSignal() { return err.highSignal; }; uint8_t getErrorOther() { return err.other; }; + // uint16_t getCrcIN() { return crcPtr[0] << 8 | crcPtr[1]; }; + // uint16_t getCrcCALC() { return crcCalcVal; }; uint16_t getTunerTime() { return bitPeriod; }; void resetAvaliable() { isAvaliable = false; }; + +protected: + uint16_t id; + inline static uint8_t data[dataByteSizeMax] { 0 }; + + bool isAvaliable = false; + + uint8_t* msgPtr = nullptr; + uint8_t* addrFromPtr = nullptr; + uint8_t* addrToPtr = nullptr; + uint8_t* dataPtr = nullptr; + uint8_t* crcPtr = nullptr; + + ErrorsStruct err; + uint8_t packRawSize; + uint16_t bitPeriod; + uint16_t crcCalcVal; + + virtual bool checkAddress(PackOutInfo* packInfo) { return true; }; + + void set(PackOutInfo packInfo) { + + if (checkAddress(&packInfo)) { + onPackAddressCorrect(&packInfo); + } else { + onPackAddressIncorrect(&packInfo); + } + } + + virtual void onPackAddressCorrect(PackOutInfo* packInfo) { + memset(IDataPack::data, 0, dataByteSizeMax); + memcpy(data, packInfo->ptr, min(packInfo->packSize, dataByteSizeMax)); + err = packInfo->err; + bitPeriod = packInfo->rTime; + crcCalcVal = packInfo->crc; + packRawSize = packInfo->packSize; + + msgPtr = (data + packInfo->offsets.msgOffset); + addrFromPtr = (data + packInfo->offsets.addrFromOffset); + addrToPtr = (data + packInfo->offsets.addrToOffset); + dataPtr = (data + packInfo->offsets.dataOffset); + crcPtr = (data + packInfo->offsets.crcOffset); + + isAvaliable = true; + } + virtual void onPackAddressIncorrect(PackOutInfo* packInfo) {} + }; ////////////////////////////////////////////////////////////////////////// class Data : public IDataPack { + using IDataPack::IDataPack; public: - Data() { - msgOffset = 0; - addrFromOffset = 1; - addrToOffset = 3; - dataOffset = 5; - - } - - -public: - uint16_t getAddrFrom() { return *(uint16_t*)addrFromPtr; }; - uint16_t getAddrTo() { return *(uint16_t*)addrToPtr; }; + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; + uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; uint8_t getDataSize() { return packRawSize - (msgBytes + addrBytes + addrBytes + crcBytes); }; - uint8_t* getDataPrt() { return (uint8_t*)dataPtr; }; + uint8_t* getDataPrt() { return dataPtr; }; uint8_t getDataRawSize() { return packRawSize; }; uint8_t* getDataRawPtr() { return data; }; - uint16_t getCrcIN() { return *(uint16_t*)crcPtr; }; - uint16_t getCrcCALC() { return crcCalcVal; }; - bool isNeedAccept() { return ((msgByte >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; - ~Data() {}; + bool isNeedAccept() { return ((msgPtr[0] >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; + +private: + bool checkAddress(PackOutInfo* packInfo) override { + bool ret; + + uint8_t addrOffset = packInfo->offsets.addrToOffset; + uint16_t address = (packInfo->ptr[addrOffset] << 8) | (packInfo->ptr[addrOffset + 1]); + + checkaddressRuleApply(address, id, ret); + + return ret; + } + }; // class RawData : public Data { // }; class Accept : public IDataPack { + using IDataPack::IDataPack; public: - Accept() { - msgOffset = 0; - addrFromOffset = 1; - } - - uint16_t getAddrFrom() { return *(uint16_t*)addrFromPtr; }; - uint16_t getCrcIN() { return *(uint16_t*)crcPtr; }; - uint16_t getCrcCALC() { return crcCalcVal; }; - + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; }; class Request : public IDataPack { + using IDataPack::IDataPack; public: - Request() { - msgOffset = 0; - addrFromOffset = 1; - addrToOffset = 3; - } - - uint16_t getAddrFrom() { return *(uint16_t*)addrFromPtr; }; - uint16_t getAddrTo() { return *(uint16_t*)addrToPtr; }; - uint16_t getCrcIN() { return *(uint16_t*)crcPtr; }; - uint16_t getCrcCALC() { return crcCalcVal; }; + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; + uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; }; -class RawTune : public IDataPack { +class RawTune { + friend IR_Decoder; public: - RawTune() { - msgOffset = 0; - } + bool avaliable() { return isAvaliable; }; + uint16_t getTunerTime() { return bitPeriod; }; + void resetAvaliable() { isAvaliable = false; }; +protected: + bool isAvaliable; + uint16_t bitPeriod; + void set(uint16_t time) { + bitPeriod = time; + isAvaliable = true; + } }; \ No newline at end of file diff --git a/IR_config.h b/IR_config.h index a106116..885be00 100644 --- a/IR_config.h +++ b/IR_config.h @@ -38,7 +38,7 @@ msg type:                                         // | xxx..... | = тип сообщения                                         // | ...xxxxx | = длина (максимум 31 бита)                                         //  ---------- */ -#define IR_MSG_ 0U // | 000..... | = Задний сигнал машинки +#define IR_MSG_BACK 0U // | 000..... | = Задний сигнал машинки ;// // | \\\x---- | = нужна ли адресация ;// // | \\\-xxxx | = длина данных (Равна нулю при отсутствии сквозных команд) #define IR_MSG_ACCEPT 1U // | 001..... | = подтверждение @@ -139,6 +139,14 @@ typedef uint16_t crc_t; class IR_FOX { public: + struct PackOffsets { + uint8_t msgOffset; + uint8_t addrFromOffset; + uint8_t addrToOffset; + uint8_t dataOffset; + uint8_t crcOffset; + }; + struct ErrorsStruct { uint8_t lowSignal; uint8_t highSignal; @@ -153,8 +161,24 @@ public: }; + struct PackOutInfo { + uint8_t* ptr; + uint8_t packSize; + PackOffsets offsets; + uint16_t crc; + ErrorsStruct err; + uint16_t rTime; + }; + protected: ErrorsStruct errors; + + void checkaddressRuleApply(uint16_t &address, uint16_t &id, bool &flag) { + flag = false; + flag |= address == id; + flag |= address >= IR_Broadcast; + } + uint8_t crc8(uint8_t* data, uint8_t start, uint8_t end, uint8_t poly) { //TODO: сделать возможность межбайтовой проверки uint8_t crc = 0xff; size_t i, j; From ff7b5dcaa4cd8e583af87d05823528c0c9bb6373 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 20 Feb 2024 15:00:42 +0300 Subject: [PATCH 36/51] add back --- IR_Encoder.cpp | 39 +++++++++++++++++++++++++++++++++++++++ IR_Encoder.h | 22 +++++----------------- IR_config.h | 38 -------------------------------------- 3 files changed, 44 insertions(+), 55 deletions(-) diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 0eaf6b3..64a9837 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -106,7 +106,46 @@ void IR_Encoder::sendRequest(uint16_t addrTo, uint8_t addInfo) { rawSend(sendBuffer, msgBytes + addrBytes + addrBytes + crcBytes); } +void IR_Encoder::sendBack(uint8_t* data = nullptr, uint8_t len = 0){ + _sendBack(false, 0, data, len); +} +void IR_Encoder::sendBackTo(uint16_t addrTo, uint8_t* data = nullptr, uint8_t len = 0){ + _sendBack(true, addrTo, data, len); +} + +void IR_Encoder::_sendBack(bool isAdressed ,uint16_t addrTo,uint8_t* data, uint8_t len){ + if (len > bytePerPack) { return; } + memset(sendBuffer, 0x00, dataByteSizeMax); + constexpr uint8_t dataStart = msgBytes + addrBytes; + + uint8_t packSize = msgBytes + addrBytes + len + crcBytes; + uint8_t msgType = + (IR_MSG_BACK << 5) | (isAdressed << 4U) | ((packSize - crcBytes) & (IR_MASK_MSG_INFO>>1)); + + // формирование массива + // msg_type + sendBuffer[0] = msgType; + + // addr_from or data + sendBuffer[1] = id >> 8 & 0xFF; + sendBuffer[2] = id & 0xFF; + + // addr_to + sendBuffer[3] = addrTo >> 8 & 0xFF; + sendBuffer[4] = addrTo & 0xFF; + + for (uint16_t i = dataStart; i < dataStart + len; i++) { + sendBuffer[i] = ((uint8_t*)data)[i - dataStart]; + } + + // data crc + sendBuffer[packSize - crcBytes] = crc8(sendBuffer, 0, packSize - crcBytes, poly1) & 0xFF; + sendBuffer[packSize - crcBytes + 1] = crc8(sendBuffer, 0, packSize - crcBytes + 1, poly2) & 0xFF; + + // отправка + rawSend(sendBuffer, packSize); +} void IR_Encoder::setDecoder_isSending() { if (decodersCount) { diff --git a/IR_Encoder.h b/IR_Encoder.h index 8d86781..2712b3b 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -43,17 +43,19 @@ public: } void IR_Encoder::setBlindDecoders(IR_Decoder* decoders [], uint8_t count); - // template - // void sendData(uint16_t addrTo, T& data, bool needAccept = false); + void rawSend(uint8_t* ptr, uint8_t len); void sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false); void sendACK(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false); void sendRequest(uint16_t addrTo, uint8_t addInfo = 0); - void rawSend(uint8_t* ptr, uint8_t len); + void sendBack(uint8_t* data = nullptr, uint8_t len = 0); + void sendBackTo(uint16_t addrTo, uint8_t* data = nullptr, uint8_t len = 0); void isr(); ~IR_Encoder(); volatile bool ir_out_virtual; private: + void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t* data, uint8_t len); + void IR_Encoder::setDecoder_isSending(); void sendByte(uint8_t byte, bool* prev, bool LOW_FIRST); void addSync(bool* prev, bool* next); @@ -101,24 +103,10 @@ private: (bitPauseTakts) * 2 - 1 }; uint8_t* currentBitSequence = bitLow; - - // uint8_t bitSequence[2]; - volatile SignalPart signal; }; -//////////////////////////////////////////////////////////////////////////////////////////////// -// template -// void IR_Encoder::sendData(uint16_t addrTo, T& data, bool needAccept = false) { // TODO: переделать логику LOW_FIRST -// uint8_t len = sizeof(T); -// uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; - -// uint8_t msgType = -// ((needAccept ? IR_MSG_DATA_ACCEPT : IR_MSG_DATA_NOACCEPT) << 5) | ((packSize - crcBytes) & IR_MASK_MSG_INFO); - -// _sendData(addrTo, data, len, msgType); -// } diff --git a/IR_config.h b/IR_config.h index 885be00..cc0ccfd 100644 --- a/IR_config.h +++ b/IR_config.h @@ -194,42 +194,4 @@ protected: return crc; } - - // public: - // /// @brief Вывод массива байт в строковом формате - // /// @param d Указатель на массив - // /// @param s Размер массива - // /// @param mode Формат вывода DEC, BIN - // /// @return Готовая для вывода строка - // String printBytes(uint8_t* d, uint8_t s, uint8_t mode = 10) { - // String str = ""; - // uint8_t control = bitPerByte; - // uint8_t* _data = d; - // switch (mode) { - // case 2: - // for (size_t i = 0; i < s * 8; i++) { - // if (i == control) { - // str += " "; - // control += bitPerByte; - // } - - // str += _data[(i / 8)] >> (7 - (i % 8)) & 1; - // } - // break; - // case 10: - // for (size_t i = 0; i < s; i++) { - // str += _data[i]; - // str += " "; - // } - - // break; - - // default: - // break; - // } - - // str += " "; - // return str; - // } - }; From 024888e84166936a283c4e6e02262eb38f1fb8fb Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 20 Feb 2024 16:35:02 +0300 Subject: [PATCH 37/51] addr check flag added --- IR_Decoder.cpp | 113 ++++++++++++++++++++++++++++--------------------- IR_Decoder.h | 10 ++--- IR_Output.h | 49 +++++++++++++-------- IR_config.h | 7 ++- 4 files changed, 105 insertions(+), 74 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 6803bcc..98a493e 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -1,7 +1,7 @@ #include "IR_Decoder.h" #include "IR_Encoder.h" -#define IRDEBUG_INFO + #define checkAddr(h, l) (\ ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) == id) || \ @@ -360,26 +360,49 @@ void IR_Decoder::writeToBuffer(bool bit) { if ((i_dataBuffer >= (8 * msgBytes)) && !isCrcCorrect) { uint16_t crcValue; + uint8_t packSize; switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { case IR_MSG_BACK: - packToOutClass( - (((dataBuffer[0] & (IR_MASK_MSG_INFO >> 1)) + crcBytes)), // packSize - gotData, // obj - PackOffsets { - 0, // msgOffset - 1, // addrFromOffset - NULL, // addrToOffset - 3, // dataOffset - NULL // crcOffset - } - ); + packSize = (dataBuffer[0] & (IR_MASK_MSG_INFO >> 1)) + crcBytes; + if (i_dataBuffer != packSize * bitPerByte) break; + + if ((dataBuffer[0] & 0b00010000)) { // С адресацией + packToOutClass( + packSize, // packSize + gotData, // obj + PackOffsets { + 0, // msgOffset + 1, // addrFromOffset + 3, // addrToOffset + 5, // dataOffset + NULL // crcOffset + }, + true + ); + } else { // Без адресации + packToOutClass( + packSize, // packSize + gotData, // obj + PackOffsets { + 0, // msgOffset + 1, // addrFromOffset + 3, // addrToOffset + 3, // dataOffset + NULL // crcOffset + }, + false + ); + } break; case IR_MSG_ACCEPT: + packSize = msgBytes + addrBytes + crcBytes; + if (i_dataBuffer != packSize * bitPerByte) break; + packToOutClass( - ((msgBytes + addrBytes + crcBytes)), // packSize - gotAccept, // obj + packSize, // packSize + gotAccept, // obj PackOffsets { 0, // msgOffset 1, // addrFromOffset @@ -391,9 +414,12 @@ void IR_Decoder::writeToBuffer(bool bit) { break; case IR_MSG_REQUEST: + packSize = msgBytes + addrBytes + addrBytes + crcBytes; + if (i_dataBuffer != packSize * bitPerByte) break; + packToOutClass( - ((msgBytes + addrBytes + addrBytes + crcBytes)), // packSize - gotRequest, // obj + packSize, // packSize + gotRequest, // obj PackOffsets { 0, // msgOffset 1, // addrFromOffset @@ -407,8 +433,11 @@ void IR_Decoder::writeToBuffer(bool bit) { case IR_MSG_DATA_ACCEPT: case IR_MSG_DATA_NOACCEPT: + packSize = (dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes; + if (i_dataBuffer != packSize * bitPerByte) break; + packToOutClass( - (((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)), // packSize + packSize, // packSize gotData, // obj PackOffsets { 0, // msgOffset @@ -427,41 +456,27 @@ void IR_Decoder::writeToBuffer(bool bit) { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } -void IR_Decoder::packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets) { - - if (i_dataBuffer == packSize * bitPerByte) { - PackOutInfo packInfo; +void IR_Decoder::packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets, bool isNeedAddressCheck = true) { + PackOutInfo packInfo; + #ifdef IRDEBUG_INFO + Serial.print(" IN "); + #endif + isCrcCorrect = crcCheck(packSize - crcBytes, packInfo.crc); + if (isCrcCorrect) { + packInfo.ptr = dataBuffer; + packInfo.packSize = packSize; + packInfo.offsets = offsets; + packInfo.offsets.crcOffset = packInfo.packSize - crcBytes; + packInfo.err = errors; + packInfo.rTime = riseSyncTime; + obj.set(packInfo, isNeedAddressCheck); + } else { #ifdef IRDEBUG_INFO - Serial.print(" IN "); + Serial.println(" CRC WRONG "); #endif - isCrcCorrect = crcCheck(packSize - crcBytes, packInfo.crc); - if (isCrcCorrect) { - // if ((addressForCheckOffset >= 0 ? checkAddr(addressForCheckOffset, addressForCheckOffset + 1) : 1)) {// адрес верен - // #ifdef IRDEBUG_INFO - // Serial.println(" OK "); - // #endif - - // } else { // адресс не верен - // #ifdef IRDEBUG_INFO - // Serial.println(" NOT MY "); - // #endif - // } - - packInfo.ptr = dataBuffer; - packInfo.packSize = packSize; - packInfo.offsets = offsets; - packInfo.offsets.crcOffset = packInfo.packSize - crcBytes; - packInfo.err = errors; - packInfo.rTime = riseSyncTime; - obj.set(packInfo); - } else { - #ifdef IRDEBUG_INFO - Serial.println(" CRC WRONG "); - #endif - } - - isRecive = false; } + + isRecive = false; } diff --git a/IR_Decoder.h b/IR_Decoder.h index 17f16cd..2fe387a 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -29,10 +29,10 @@ class IR_Decoder : private IR_FOX { public: uint16_t id; - Data gotData = Data(id); /// @brief Контейнер с данными - Data gotRawData = Data(id); - Accept gotAccept = Accept(id); /// @brief Контейнер с подтверждением - Request gotRequest = Request(id); /// @brief Контейнер с запросом + Data gotData = Data(&id); /// @brief Контейнер с данными + Data gotRawData = Data(&id); + Accept gotAccept = Accept(&addrWaitingFrom); /// @brief Контейнер с подтверждением + Request gotRequest = Request(&id); /// @brief Контейнер с запросом RawTune gotTune; /// @brief Контейнер с информацией подстройки const uint8_t isrPin; // Пин прерывания @@ -109,7 +109,7 @@ private: /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация /// @param Бит данных void writeToBuffer(bool); - void packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets); + void packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets, bool isNeedAddressCheck = true); //////////////////////////////////////////////////////////////////////// /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных diff --git a/IR_Output.h b/IR_Output.h index ff5a9fe..a8ad807 100644 --- a/IR_Output.h +++ b/IR_Output.h @@ -5,7 +5,7 @@ class IR_Decoder; class IDataPack : protected IR_FOX { friend IR_Decoder; public: - IDataPack(uint16_t id) : id(id) {}; + IDataPack(uint16_t* id) : id(id) {}; public: bool avaliable() { return isAvaliable; }; @@ -22,7 +22,7 @@ public: void resetAvaliable() { isAvaliable = false; }; protected: - uint16_t id; + uint16_t* id; inline static uint8_t data[dataByteSizeMax] { 0 }; bool isAvaliable = false; @@ -38,14 +38,29 @@ protected: uint16_t bitPeriod; uint16_t crcCalcVal; - virtual bool checkAddress(PackOutInfo* packInfo) { return true; }; + virtual bool checkAddress(PackOutInfo* packInfo) { + bool ret; - void set(PackOutInfo packInfo) { + uint8_t targetAddrOffset = packInfo->offsets.addrToOffset; + uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); - if (checkAddress(&packInfo)) { + checkaddressRuleApply(address, *id, ret); + + return ret; + }; + + void set(PackOutInfo packInfo, bool isNeedAddressCheck) { + + if (!isNeedAddressCheck || checkAddress(&packInfo)) { onPackAddressCorrect(&packInfo); + #ifdef IRDEBUG_INFO + Serial.println(" OK "); + #endif } else { onPackAddressIncorrect(&packInfo); + #ifdef IRDEBUG_INFO + Serial.println(" NOT MY "); + #endif } } @@ -81,19 +96,6 @@ public: uint8_t getDataRawSize() { return packRawSize; }; uint8_t* getDataRawPtr() { return data; }; bool isNeedAccept() { return ((msgPtr[0] >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; - -private: - bool checkAddress(PackOutInfo* packInfo) override { - bool ret; - - uint8_t addrOffset = packInfo->offsets.addrToOffset; - uint16_t address = (packInfo->ptr[addrOffset] << 8) | (packInfo->ptr[addrOffset + 1]); - - checkaddressRuleApply(address, id, ret); - - return ret; - } - }; // class RawData : public Data { @@ -103,6 +105,17 @@ class Accept : public IDataPack { using IDataPack::IDataPack; public: uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; +private: + bool checkAddress(PackOutInfo* packInfo) override { + bool ret; + + uint8_t targetAddrOffset = packInfo->offsets.addrFromOffset; + uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); + + ret = address == *id; + + return ret; + } }; class Request : public IDataPack { diff --git a/IR_config.h b/IR_config.h index cc0ccfd..52097de 100644 --- a/IR_config.h +++ b/IR_config.h @@ -1,5 +1,7 @@ #pragma once #include + +#define IRDEBUG_INFO /*////////////////////////////////////////////////////////////////////////////////////// Для работы в паре положить декодер в энкодер @@ -38,7 +40,7 @@ msg type:                                         // | xxx..... | = тип сообщения                                         // | ...xxxxx | = длина (максимум 31 бита)                                         //  ---------- */ -#define IR_MSG_BACK 0U // | 000..... | = Задний сигнал машинки +#define IR_MSG_BACK 0U // | 0000B.... | = Задний сигнал машинки ;// // | \\\x---- | = нужна ли адресация ;// // | \\\-xxxx | = длина данных (Равна нулю при отсутствии сквозных команд) #define IR_MSG_ACCEPT 1U // | 001..... | = подтверждение @@ -173,8 +175,9 @@ public: protected: ErrorsStruct errors; - void checkaddressRuleApply(uint16_t &address, uint16_t &id, bool &flag) { + void checkaddressRuleApply(uint16_t address, uint16_t id, bool &flag) { flag = false; + flag |= id == 0; flag |= address == id; flag |= address >= IR_Broadcast; } From f007e2cf6e67a9ffd1d678b8fb1af17255bea7b1 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 21 Feb 2024 12:41:11 +0300 Subject: [PATCH 38/51] Class Out back to Decoder.h --- IR_Decoder.h | 157 +++++++++++++++++++++++++++++++++++++++++++++++++-- IR_Output.h | 142 ---------------------------------------------- 2 files changed, 152 insertions(+), 147 deletions(-) diff --git a/IR_Decoder.h b/IR_Decoder.h index 2fe387a..da82eb2 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -1,6 +1,5 @@ #pragma once #include "IR_config.h" -#include "IR_Output.h" //#define IRDEBUG @@ -26,13 +25,161 @@ class IR_Encoder; class IR_Decoder : private IR_FOX { friend IR_Encoder; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + class IDataPack : protected IR_FOX { + friend IR_Decoder; + public: + IDataPack(IR_Decoder* dec) : dec(dec) {}; + + public: + bool avaliable() { return isAvaliable; }; + uint8_t getMsgInfo() { return msgPtr[0] & IR_MASK_MSG_INFO; }; + uint8_t getMsgType() { return (msgPtr[0] >> 5) & IR_MASK_MSG_TYPE; }; + uint8_t getMsgRAW() { return msgPtr[0]; }; + uint16_t getErrorCount() { return err.all(); }; + uint8_t getErrorLowSignal() { return err.lowSignal; }; + uint8_t getErrorHighSignal() { return err.highSignal; }; + uint8_t getErrorOther() { return err.other; }; + // uint16_t getCrcIN() { return crcPtr[0] << 8 | crcPtr[1]; }; + // uint16_t getCrcCALC() { return crcCalcVal; }; + uint16_t getTunerTime() { return bitPeriod; }; + void resetAvaliable() { isAvaliable = false; }; + + protected: + IR_Decoder* dec; + inline static uint8_t data[dataByteSizeMax] { 0 }; + + bool isAvaliable = false; + + uint8_t* msgPtr = nullptr; + uint8_t* addrFromPtr = nullptr; + uint8_t* addrToPtr = nullptr; + uint8_t* dataPtr = nullptr; + uint8_t* crcPtr = nullptr; + + ErrorsStruct err; + uint8_t packRawSize; + uint16_t bitPeriod; + uint16_t crcCalcVal; + + virtual bool checkAddress(PackOutInfo* packInfo) { + bool ret; + + uint8_t targetAddrOffset = packInfo->offsets.addrToOffset; + uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); + + checkaddressRuleApply(address, dec->id, ret); + + return ret; + }; + + void set(PackOutInfo packInfo, bool isNeedAddressCheck) { + + if (!isNeedAddressCheck || checkAddress(&packInfo)) { + onPackAddressCorrect(&packInfo); + #ifdef IRDEBUG_INFO + Serial.println(" OK "); + #endif + } else { + onPackAddressIncorrect(&packInfo); + #ifdef IRDEBUG_INFO + Serial.println(" NOT MY "); + #endif + } + } + + virtual void onPackAddressCorrect(PackOutInfo* packInfo) { + memset(IDataPack::data, 0, dataByteSizeMax); + memcpy(data, packInfo->ptr, min(packInfo->packSize, dataByteSizeMax)); + err = packInfo->err; + bitPeriod = packInfo->rTime; + crcCalcVal = packInfo->crc; + packRawSize = packInfo->packSize; + + msgPtr = (data + packInfo->offsets.msgOffset); + addrFromPtr = (data + packInfo->offsets.addrFromOffset); + addrToPtr = (data + packInfo->offsets.addrToOffset); + dataPtr = (data + packInfo->offsets.dataOffset); + crcPtr = (data + packInfo->offsets.crcOffset); + + isAvaliable = true; + } + virtual void onPackAddressIncorrect(PackOutInfo* packInfo) {} + + }; + + ////////////////////////////////////////////////////////////////////////// + + class Data : public IDataPack { + using IDataPack::IDataPack; + public: + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; + uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; + uint8_t getDataSize() { return packRawSize - (msgBytes + addrBytes + addrBytes + crcBytes); }; + uint8_t* getDataPrt() { return dataPtr; }; + uint8_t getDataRawSize() { return packRawSize; }; + uint8_t* getDataRawPtr() { return data; }; + bool isNeedAccept() { return ((msgPtr[0] >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; + }; + + // class RawData : public Data { + // }; + + class Accept : public IDataPack { + using IDataPack::IDataPack; + public: + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; + private: + bool checkAddress(PackOutInfo* packInfo) override { + bool ret; + + uint8_t targetAddrOffset = packInfo->offsets.addrFromOffset; + uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); + + ret = address == dec->addrWaitingFrom; + + return ret; + } + }; + + class Request : public IDataPack { + using IDataPack::IDataPack; + public: + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; + uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; + }; + + class RawTune { + friend IR_Decoder; + public: + bool avaliable() { return isAvaliable; }; + uint16_t getTunerTime() { return bitPeriod; }; + void resetAvaliable() { isAvaliable = false; }; + protected: + bool isAvaliable; + uint16_t bitPeriod; + + void set(uint16_t time) { + bitPeriod = time; + isAvaliable = true; + } + }; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + public: uint16_t id; - Data gotData = Data(&id); /// @brief Контейнер с данными - Data gotRawData = Data(&id); - Accept gotAccept = Accept(&addrWaitingFrom); /// @brief Контейнер с подтверждением - Request gotRequest = Request(&id); /// @brief Контейнер с запросом + Data gotData = Data(this); /// @brief Контейнер с данными + Data gotRawData = Data(this); + Accept gotAccept = Accept(this); /// @brief Контейнер с подтверждением + Request gotRequest = Request(this); /// @brief Контейнер с запросом RawTune gotTune; /// @brief Контейнер с информацией подстройки const uint8_t isrPin; // Пин прерывания diff --git a/IR_Output.h b/IR_Output.h index a8ad807..e69de29 100644 --- a/IR_Output.h +++ b/IR_Output.h @@ -1,142 +0,0 @@ -#pragma once -#include "IR_config.h" -class IR_Decoder; - -class IDataPack : protected IR_FOX { - friend IR_Decoder; -public: - IDataPack(uint16_t* id) : id(id) {}; - -public: - bool avaliable() { return isAvaliable; }; - uint8_t getMsgInfo() { return msgPtr[0] & IR_MASK_MSG_INFO; }; - uint8_t getMsgType() { return (msgPtr[0] >> 5) & IR_MASK_MSG_TYPE; }; - uint8_t getMsgRAW() { return msgPtr[0]; }; - uint16_t getErrorCount() { return err.all(); }; - uint8_t getErrorLowSignal() { return err.lowSignal; }; - uint8_t getErrorHighSignal() { return err.highSignal; }; - uint8_t getErrorOther() { return err.other; }; - // uint16_t getCrcIN() { return crcPtr[0] << 8 | crcPtr[1]; }; - // uint16_t getCrcCALC() { return crcCalcVal; }; - uint16_t getTunerTime() { return bitPeriod; }; - void resetAvaliable() { isAvaliable = false; }; - -protected: - uint16_t* id; - inline static uint8_t data[dataByteSizeMax] { 0 }; - - bool isAvaliable = false; - - uint8_t* msgPtr = nullptr; - uint8_t* addrFromPtr = nullptr; - uint8_t* addrToPtr = nullptr; - uint8_t* dataPtr = nullptr; - uint8_t* crcPtr = nullptr; - - ErrorsStruct err; - uint8_t packRawSize; - uint16_t bitPeriod; - uint16_t crcCalcVal; - - virtual bool checkAddress(PackOutInfo* packInfo) { - bool ret; - - uint8_t targetAddrOffset = packInfo->offsets.addrToOffset; - uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); - - checkaddressRuleApply(address, *id, ret); - - return ret; - }; - - void set(PackOutInfo packInfo, bool isNeedAddressCheck) { - - if (!isNeedAddressCheck || checkAddress(&packInfo)) { - onPackAddressCorrect(&packInfo); - #ifdef IRDEBUG_INFO - Serial.println(" OK "); - #endif - } else { - onPackAddressIncorrect(&packInfo); - #ifdef IRDEBUG_INFO - Serial.println(" NOT MY "); - #endif - } - } - - virtual void onPackAddressCorrect(PackOutInfo* packInfo) { - memset(IDataPack::data, 0, dataByteSizeMax); - memcpy(data, packInfo->ptr, min(packInfo->packSize, dataByteSizeMax)); - err = packInfo->err; - bitPeriod = packInfo->rTime; - crcCalcVal = packInfo->crc; - packRawSize = packInfo->packSize; - - msgPtr = (data + packInfo->offsets.msgOffset); - addrFromPtr = (data + packInfo->offsets.addrFromOffset); - addrToPtr = (data + packInfo->offsets.addrToOffset); - dataPtr = (data + packInfo->offsets.dataOffset); - crcPtr = (data + packInfo->offsets.crcOffset); - - isAvaliable = true; - } - virtual void onPackAddressIncorrect(PackOutInfo* packInfo) {} - -}; - -////////////////////////////////////////////////////////////////////////// - -class Data : public IDataPack { - using IDataPack::IDataPack; -public: - uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; - uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; - uint8_t getDataSize() { return packRawSize - (msgBytes + addrBytes + addrBytes + crcBytes); }; - uint8_t* getDataPrt() { return dataPtr; }; - uint8_t getDataRawSize() { return packRawSize; }; - uint8_t* getDataRawPtr() { return data; }; - bool isNeedAccept() { return ((msgPtr[0] >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; -}; - -// class RawData : public Data { -// }; - -class Accept : public IDataPack { - using IDataPack::IDataPack; -public: - uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; -private: - bool checkAddress(PackOutInfo* packInfo) override { - bool ret; - - uint8_t targetAddrOffset = packInfo->offsets.addrFromOffset; - uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); - - ret = address == *id; - - return ret; - } -}; - -class Request : public IDataPack { - using IDataPack::IDataPack; -public: - uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; - uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; -}; - -class RawTune { - friend IR_Decoder; -public: - bool avaliable() { return isAvaliable; }; - uint16_t getTunerTime() { return bitPeriod; }; - void resetAvaliable() { isAvaliable = false; }; -protected: - bool isAvaliable; - uint16_t bitPeriod; - - void set(uint16_t time) { - bitPeriod = time; - isAvaliable = true; - } -}; \ No newline at end of file From 37f49e0d826032279532dffc68e38fa08e07c0ff Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 21 Feb 2024 17:07:36 +0300 Subject: [PATCH 39/51] add DataBack and refactor out classes --- IR_Decoder.cpp | 19 ++---- IR_Decoder.h | 181 ++++++++++++++++++++++++++++++------------------- 2 files changed, 117 insertions(+), 83 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 98a493e..fc88fee 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -2,12 +2,6 @@ #include "IR_Encoder.h" - -#define checkAddr(h, l) (\ - ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) == id) || \ - ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) >= IR_Broadcast)\ - ) - IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), id(addr), encoder(encPair) { dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; prevRise = prevFall = prevPrevFall = prevPrevRise = 0; @@ -52,7 +46,7 @@ void IR_Decoder::isr() { //////////////////////////////////////////////////////////////////////////////////// -void IR_Decoder::start_RX() { +void IR_Decoder::firstRX() { #ifdef IRDEBUG_INFO Serial.print("\n>"); @@ -78,7 +72,7 @@ void IR_Decoder::start_RX() { void IR_Decoder::listen() { if (isRecive && ((micros() - prevRise) > IR_timeout * 2)) { isRecive = false; - start_RX(); + firstRX(); } } @@ -331,9 +325,6 @@ void IR_Decoder::writeToBuffer(bool bit) { } ////////////////////// Проверка наличия битов синхранизации ////////////////////// if (isWrongPack = (err_syncBit >= syncBits)) { - // start_RX(); - // firstUnHandledFront = firstUnHandledFront->next; - // firstUnHandledFront = nullptr; #ifdef IRDEBUG_INFO Serial.print("****************"); #endif @@ -370,7 +361,7 @@ void IR_Decoder::writeToBuffer(bool bit) { if ((dataBuffer[0] & 0b00010000)) { // С адресацией packToOutClass( packSize, // packSize - gotData, // obj + gotBackData, // obj PackOffsets { 0, // msgOffset 1, // addrFromOffset @@ -383,7 +374,7 @@ void IR_Decoder::writeToBuffer(bool bit) { } else { // Без адресации packToOutClass( packSize, // packSize - gotData, // obj + gotBackData, // obj PackOffsets { 0, // msgOffset 1, // addrFromOffset @@ -438,7 +429,7 @@ void IR_Decoder::writeToBuffer(bool bit) { packToOutClass( packSize, // packSize - gotData, // obj + gotData, // obj PackOffsets { 0, // msgOffset 1, // addrFromOffset diff --git a/IR_Decoder.h b/IR_Decoder.h index da82eb2..cf309b3 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -36,62 +36,42 @@ class IR_Decoder : private IR_FOX { IDataPack(IR_Decoder* dec) : dec(dec) {}; public: - bool avaliable() { return isAvaliable; }; - uint8_t getMsgInfo() { return msgPtr[0] & IR_MASK_MSG_INFO; }; - uint8_t getMsgType() { return (msgPtr[0] >> 5) & IR_MASK_MSG_TYPE; }; - uint8_t getMsgRAW() { return msgPtr[0]; }; - uint16_t getErrorCount() { return err.all(); }; - uint8_t getErrorLowSignal() { return err.lowSignal; }; - uint8_t getErrorHighSignal() { return err.highSignal; }; - uint8_t getErrorOther() { return err.other; }; + bool avaliable() { if (isAvaliable) { isAvaliable = false; return true; } else { return isAvaliable; }; }; + virtual uint8_t getMsgInfo() { return msgPtr[0] & IR_MASK_MSG_INFO; }; + virtual uint8_t getMsgType() { return (msgPtr[0] >> 5) & IR_MASK_MSG_TYPE; }; + virtual uint8_t getMsgRAW() { return msgPtr[0]; }; + virtual uint16_t getErrorCount() { return err.all(); }; + virtual uint8_t getErrorLowSignal() { return err.lowSignal; }; + virtual uint8_t getErrorHighSignal() { return err.highSignal; }; + virtual uint8_t getErrorOther() { return err.other; }; // uint16_t getCrcIN() { return crcPtr[0] << 8 | crcPtr[1]; }; // uint16_t getCrcCALC() { return crcCalcVal; }; - uint16_t getTunerTime() { return bitPeriod; }; + virtual uint16_t getTunerTime() { return bitPeriod; }; void resetAvaliable() { isAvaliable = false; }; protected: - IR_Decoder* dec; inline static uint8_t data[dataByteSizeMax] { 0 }; + inline static uint8_t* msgPtr; + inline static uint8_t* addrFromPtr; + inline static uint8_t* addrToPtr; + inline static uint8_t* dataPtr; + inline static uint8_t* crcPtr; + + inline static ErrorsStruct err; + inline static uint8_t packRawSize; + inline static uint16_t bitPeriod; + inline static uint16_t crcCalcVal; + + IR_Decoder* dec; bool isAvaliable = false; - - uint8_t* msgPtr = nullptr; - uint8_t* addrFromPtr = nullptr; - uint8_t* addrToPtr = nullptr; - uint8_t* dataPtr = nullptr; - uint8_t* crcPtr = nullptr; - - ErrorsStruct err; - uint8_t packRawSize; - uint16_t bitPeriod; - uint16_t crcCalcVal; - virtual bool checkAddress(PackOutInfo* packInfo) { bool ret; - uint8_t targetAddrOffset = packInfo->offsets.addrToOffset; uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); - checkaddressRuleApply(address, dec->id, ret); - return ret; }; - - void set(PackOutInfo packInfo, bool isNeedAddressCheck) { - - if (!isNeedAddressCheck || checkAddress(&packInfo)) { - onPackAddressCorrect(&packInfo); - #ifdef IRDEBUG_INFO - Serial.println(" OK "); - #endif - } else { - onPackAddressIncorrect(&packInfo); - #ifdef IRDEBUG_INFO - Serial.println(" NOT MY "); - #endif - } - } - virtual void onPackAddressCorrect(PackOutInfo* packInfo) { memset(IDataPack::data, 0, dataByteSizeMax); memcpy(data, packInfo->ptr, min(packInfo->packSize, dataByteSizeMax)); @@ -105,52 +85,113 @@ class IR_Decoder : private IR_FOX { addrToPtr = (data + packInfo->offsets.addrToOffset); dataPtr = (data + packInfo->offsets.dataOffset); crcPtr = (data + packInfo->offsets.crcOffset); - - isAvaliable = true; } + virtual void onPackAddressIncorrect(PackOutInfo* packInfo) {} + virtual void afterSet() {} + void set(PackOutInfo packInfo, bool isNeedAddressCheck) { + isAvaliable = false; + if (!isNeedAddressCheck || checkAddress(&packInfo)) { + onPackAddressCorrect(&packInfo); + #ifdef IRDEBUG_INFO + Serial.println(" OK "); + #endif + isAvaliable = true; + } else { + onPackAddressIncorrect(&packInfo); + #ifdef IRDEBUG_INFO + Serial.println(" NOT MY "); + #endif + } + afterSet(); + } }; - ////////////////////////////////////////////////////////////////////////// - - class Data : public IDataPack { - using IDataPack::IDataPack; +public: + /////////////////////////////////////////////////////////////////////////////////////////////////////////// + class HasAddrFrom { public: - uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; - uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; - uint8_t getDataSize() { return packRawSize - (msgBytes + addrBytes + addrBytes + crcBytes); }; - uint8_t* getDataPrt() { return dataPtr; }; - uint8_t getDataRawSize() { return packRawSize; }; - uint8_t* getDataRawPtr() { return data; }; - bool isNeedAccept() { return ((msgPtr[0] >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; + virtual uint16_t getAddrFrom() { return IDataPack::addrFromPtr[0] << 8 | IDataPack::addrFromPtr[1]; }; }; - // class RawData : public Data { - // }; + class HasAddrTo { + public: + virtual uint16_t getAddrTo() { return IDataPack::addrToPtr[0] << 8 | IDataPack::addrToPtr[1]; }; + }; - class Accept : public IDataPack { + class HasData { + public: + virtual uint8_t getDataSize() { return (uint8_t)(IDataPack::crcPtr - IDataPack::dataPtr); }; + virtual uint8_t* getDataPrt() { return IDataPack::dataPtr; }; + virtual uint8_t getDataRawSize() { return IDataPack::packRawSize; }; + virtual uint8_t* getDataRawPtr() { return IDataPack::data; }; + }; + class IAcceptable { + public: + virtual bool isNeedAccept(); + }; + class AnyData : public IDataPack, public HasAddrFrom, public HasAddrTo, public HasData { + using IDataPack::IDataPack; + }; + /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + class Data : public AnyData, public IAcceptable { + using AnyData::AnyData; + public: + bool isNeedAccept() override { return ((IDataPack::msgPtr[0] >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; + private: + void afterSet() override { + if (Data::IDataPack::isAvaliable && isNeedAccept()) { + dec->isWaitingAcceptSend = true; + dec->addrWaitingSendgTo = getAddrFrom(); + Serial.print("\n Need to accept to "); + Serial.println(dec->addrWaitingSendgTo); + } + } + }; + + class BackData : public AnyData { + using AnyData::AnyData; + public: + bool isAddressed() { return IDataPack::msgPtr[0] & 0b00010000; }; + uint8_t getMsgInfo() { return IDataPack::msgPtr[0] & (IR_MASK_MSG_INFO >> 1); }; + uint16_t getAddrTo() override { + if (isAddressed()) { + return IDataPack::addrToPtr[0] << 8 | IDataPack::addrToPtr[1]; + } else { + return IR_Broadcast; + } + }; + }; + + class Accept : public IDataPack, public HasAddrFrom { using IDataPack::IDataPack; public: - uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; + private: bool checkAddress(PackOutInfo* packInfo) override { bool ret; - uint8_t targetAddrOffset = packInfo->offsets.addrFromOffset; uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); - ret = address == dec->addrWaitingFrom; - return ret; } }; - class Request : public IDataPack { + class Request : public IDataPack, public HasAddrFrom, public HasAddrTo { using IDataPack::IDataPack; public: - uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; - uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; + + private: + // void afterSet() override { + // if (isAvaliable) { + // dec->isWaitingAcceptSend = true; + // dec->addrWaitingSendgTo = getAddrFrom(); + // Serial.print("\n Need to accept to "); + // Serial.println(dec->addrWaitingSendgTo); + // } + // } }; class RawTune { @@ -177,7 +218,7 @@ public: uint16_t id; Data gotData = Data(this); /// @brief Контейнер с данными - Data gotRawData = Data(this); + BackData gotBackData = BackData(this); Accept gotAccept = Accept(this); /// @brief Контейнер с подтверждением Request gotRequest = Request(this); /// @brief Контейнер с запросом RawTune gotTune; /// @brief Контейнер с информацией подстройки @@ -201,24 +242,26 @@ public: /// @brief Флаг приёма /// @return Возвращает true, если происходит приём пакета - bool isReciving() { return isRecive; }; + // bool isReciving() { return isRecive; }; //TODO: Некорректно работает // @brief Слушатель для работы isReciving() void listen(); ////////////////////////////////////////////////////////////////////////// + bool isWaitingAccept = false; // Флаг ожидания подтверждения + bool isWaitingAcceptSend = false; // Флаг ожидания отправки подтверждения + uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение + uint16_t addrWaitingSendgTo = 0; // Адрес, кому нужно отправить подтверждение private: IR_Encoder* encoder; // Указатель на парный передатчик volatile uint16_t isPairSending = 0; // Флаг передачи парного передатчика volatile bool isRecive = false; // Флаг приёма volatile bool isPreamb = false; // флаг начальной последовости - bool isWaitingAccept = false; // Флаг ожидания подтверждения bool isCrcCorrect = false; // Флаг корректности crc bool isBufferOverflow = false; // Флаг переполнения буффера данных bool isWrongPack = false; // Флаг битого пакета - uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс //////////////////////////////////////////////////////////////////////// @@ -260,7 +303,7 @@ private: //////////////////////////////////////////////////////////////////////// /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных - void start_RX(); + void firstRX(); /// @brief Целочисленное деление с округлением вверх /// @param val Значение From 686f2a7ffe9219d305c73ce5754cd1b57aad8aff Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 21 Feb 2024 17:08:53 +0300 Subject: [PATCH 40/51] fix Accept --- IR_Encoder.cpp | 14 +++++++------- IR_Encoder.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 64a9837..1c8c594 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -68,7 +68,7 @@ void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool need rawSend(sendBuffer, packSize); } -void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { +void IR_Encoder::sendAccept(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { memset(sendBuffer, 0x00, dataByteSizeMax); sendBuffer[0] = IR_MSG_ACCEPT << 5; sendBuffer[0] |= addInfo & IR_MASK_MSG_INFO; @@ -106,22 +106,22 @@ void IR_Encoder::sendRequest(uint16_t addrTo, uint8_t addInfo) { rawSend(sendBuffer, msgBytes + addrBytes + addrBytes + crcBytes); } -void IR_Encoder::sendBack(uint8_t* data = nullptr, uint8_t len = 0){ +void IR_Encoder::sendBack(uint8_t* data = nullptr, uint8_t len = 0) { _sendBack(false, 0, data, len); } -void IR_Encoder::sendBackTo(uint16_t addrTo, uint8_t* data = nullptr, uint8_t len = 0){ +void IR_Encoder::sendBackTo(uint16_t addrTo, uint8_t* data = nullptr, uint8_t len = 0) { _sendBack(true, addrTo, data, len); } -void IR_Encoder::_sendBack(bool isAdressed ,uint16_t addrTo,uint8_t* data, uint8_t len){ +void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t* data, uint8_t len) { if (len > bytePerPack) { return; } memset(sendBuffer, 0x00, dataByteSizeMax); - constexpr uint8_t dataStart = msgBytes + addrBytes; + uint8_t dataStart = msgBytes + addrBytes + (isAdressed ? addrBytes : 0); - uint8_t packSize = msgBytes + addrBytes + len + crcBytes; + uint8_t packSize = msgBytes + addrBytes + (isAdressed ? addrBytes : 0) + min(1, len) + crcBytes; uint8_t msgType = - (IR_MSG_BACK << 5) | (isAdressed << 4U) | ((packSize - crcBytes) & (IR_MASK_MSG_INFO>>1)); + (IR_MSG_BACK << 5) | (isAdressed << 4U) | ((packSize - crcBytes) & (IR_MASK_MSG_INFO >> 1)); // формирование массива // msg_type diff --git a/IR_Encoder.h b/IR_Encoder.h index 2712b3b..b791ffe 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -45,7 +45,7 @@ public: void IR_Encoder::setBlindDecoders(IR_Decoder* decoders [], uint8_t count); void rawSend(uint8_t* ptr, uint8_t len); void sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false); - void sendACK(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false); + void sendAccept(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false); void sendRequest(uint16_t addrTo, uint8_t addInfo = 0); void sendBack(uint8_t* data = nullptr, uint8_t len = 0); void sendBackTo(uint16_t addrTo, uint8_t* data = nullptr, uint8_t len = 0); From 462c69ce96913d427536b98b7f45f5d36bb2a8a0 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 21 Feb 2024 17:14:05 +0300 Subject: [PATCH 41/51] debug upd --- .vscode/arduino.json | 8 +- IR-Protocol.ino | 295 +++++++++++++++++++++++++++++++++++++++++++ IR.ino | 9 -- IR_Output.h | 0 4 files changed, 300 insertions(+), 12 deletions(-) create mode 100644 IR-Protocol.ino delete mode 100644 IR.ino delete mode 100644 IR_Output.h diff --git a/.vscode/arduino.json b/.vscode/arduino.json index 35ff5f8..18d4f10 100644 --- a/.vscode/arduino.json +++ b/.vscode/arduino.json @@ -1,5 +1,7 @@ { - "port": "COM3", - "board": "arduino:avr:uno", - "sketch": "IR.ino" + "board": "GyverCore:avr:nano", + "sketch": "Car.ino", + "port": "COM2", + "configuration": "boot=old,clock=external_16,serial=default,compiler_version=avrgcc5,timers=yes_millis,init=enable,es=disabled,bod=bod_2_7,co=disabled", + "programmer": "arduinoasisp" } \ No newline at end of file diff --git a/IR-Protocol.ino b/IR-Protocol.ino new file mode 100644 index 0000000..40917e5 --- /dev/null +++ b/IR-Protocol.ino @@ -0,0 +1,295 @@ +#include "IR_Decoder.h" +#include "IR_Encoder.h" +#include "TimerStatic.h" +#include "MemoryCheck.h" +/////////////// Pinout /////////////// + +#define encForward_PIN 5 +#define encBackward_PIN 6 + +#define LoopOut 12 +#define ISR_Out 10 + +#define TestOut 13 + +//////////////// Ini ///////////////// + +#define INFO "Машинка" +#define SERIAL_SPEED 115200 + +//////////////// Var ///////////////// + +IR_Decoder decForward(2, 555); +IR_Decoder decBackward(3, 777); + +IR_Decoder* blindFromForward [] { &decBackward }; +IR_Encoder encForward(42, encForward_PIN, &decForward); + +IR_Encoder encBackward(321, encBackward_PIN); +IR_Encoder encTree(325, A2); + +//////////////////////// Функции прерываний //////////////////////// + +void decForwardISR() { + decForward.isr(); +} + +void decBackwardISR() { + decBackward.isr(); +} + +static uint8_t* portOut; +ISR(TIMER2_COMPA_vect) { + encForward.isr(); + encBackward.isr(); + // encTree.isr(); + //TODO: Сделать выбор порта + *portOut = (*portOut & 0b11001111) | + ( + encForward.ir_out_virtual << 5U + | encBackward.ir_out_virtual << 6U + // | encTree.ir_out_virtual << 2U + ); +} +///////////////////////////////////////////////////////////////////// +uint8_t data0 [] = { }; +uint8_t data1 [] = { 42 }; +uint8_t data2 [] = { 42 , 127 }; +uint8_t data3 [] = { 42 , 127, 137 }; +uint8_t data4 [] = { 42 , 127, 137, 255 }; + +uint32_t loopTimer; +uint8_t sig = 255; + +uint16_t targetAddr = IR_Broadcast; +Timer t1(730, millis, []() { + + // Serial.println(sig); + + switch (sig) { + case 0: + encForward.sendData(targetAddr, data0, sizeof(data0)); + break; + case 1: + encForward.sendData(targetAddr, data1, sizeof(data1)); + break; + case 2: + encForward.sendData(targetAddr, data2, sizeof(data2)); + break; + case 3: + encForward.sendData(targetAddr, data3, sizeof(data3)); + break; + case 4: + encForward.sendData(targetAddr, data4, sizeof(data4)); + break; + + case 10: + encForward.sendData(targetAddr, data0, sizeof(data0), true); + break; + case 11: + encForward.sendData(targetAddr, data1, sizeof(data1), true); + break; + case 12: + encForward.sendData(targetAddr, data2, sizeof(data2), true); + break; + case 13: + encForward.sendData(targetAddr, data3, sizeof(data3), true); + break; + case 14: + encForward.sendData(targetAddr, data4, sizeof(data4), true); + break; + + + + case 20: + encForward.sendBack(); + break; + case 21: + encForward.sendBack(data1, sizeof(data1)); + break; + case 22: + encForward.sendBack(data2, sizeof(data2)); + break; + case 23: + encForward.sendBack(data3, sizeof(data3)); + break; + case 24: + encForward.sendBack(data4, sizeof(data4)); + break; + + case 30: + encForward.sendBackTo(targetAddr, data0, sizeof(data0)); + break; + case 31: + encForward.sendBackTo(targetAddr, data1, sizeof(data1)); + break; + case 32: + encForward.sendBackTo(targetAddr, data2, sizeof(data2)); + break; + case 33: + encForward.sendBackTo(targetAddr, data3, sizeof(data3)); + break; + case 34: + encForward.sendBackTo(targetAddr, data4, sizeof(data4)); + break; + + case 41: + encForward.sendRequest(targetAddr); + break; + case 42: + encForward.sendAccept(targetAddr); + break; + + + default: + break; + } + // encBackward.sendData(IR_Broadcast, data2); + // encTree.sendData(IR_Broadcast, rawData3); +}); +Timer t2(500, millis, []() { + digitalToggle(13); +}); +///////////////////////////////////////////////////////////////////// +void setup() { + IR_Encoder::timerSetup(); + portOut = &PORTD; + + Serial.begin(SERIAL_SPEED); + Serial.println(F(INFO)); + + pinMode(A0, INPUT_PULLUP); + pinMode(A1, INPUT_PULLUP); + pinMode(A2, INPUT_PULLUP); + pinMode(A3, INPUT_PULLUP); + + pinMode(LoopOut, OUTPUT); + pinMode(ISR_Out, OUTPUT); + + pinMode(2, INPUT_PULLUP); + pinMode(3, INPUT_PULLUP); + + pinMode(8, OUTPUT); + pinMode(9, OUTPUT); + pinMode(11, OUTPUT); + pinMode(13, OUTPUT); + pinMode(encForward_PIN, OUTPUT); + pinMode(encBackward_PIN, OUTPUT); + pinMode(13, OUTPUT); + + + + encForward.setBlindDecoders(blindFromForward, sizeof(blindFromForward) / sizeof(IR_Decoder*)); + + + attachInterrupt(0, decForwardISR, CHANGE); // D2 + attachInterrupt(1, decBackwardISR, CHANGE); // D3 +} + +void loop() { + digitalToggle(LoopOut); + Timer::tick(); + + decForward.tick(); + decBackward.tick(); + + status(decForward); + status(decBackward); + + + // Serial.println(micros() - loopTimer); + // loopTimer = micros(); + // delayMicroseconds(120*5); + + if (Serial.available()) { + uint8_t in = Serial.parseInt(); + switch (in) { + case 100: + targetAddr = IR_Broadcast; + break; + case 101: + targetAddr = 555; + break; + case 102: + targetAddr = 777; + break; + + default: + sig = in; + break; + } + } +} + + + + + + +//test +void status(IR_Decoder& dec) { + // if (dec.gotTune.avaliable()) { + // Serial.print(" Tune "); Serial.print(&dec == &decForward ? "decForward" : (&dec == &decBackward ? "decBackward" : "??")); Serial.print(": "); + + // Serial.println(dec.gotTune.getTune()); + + // Serial.println(); + // dec.gotTune.resetAvaliable(); + // } + + IR_Decoder::AnyData* infoArr [] = { &dec.gotData, &dec.gotBackData }; + + for (auto&& obj : infoArr) { + if (obj->avaliable()) { + String str; + if (obj->getDataPrt()[1]) { + str += ("Data on pin "); str += (dec.isrPin); str += "\n"; + + uint8_t msg = obj->getMsgRAW(); + str += (" MSG: "); + for (size_t i = 0; i < 8; i++) { + if (i == 3) str += " "; + str += (msg >> (7 - i)) & 1U; + } + + str += "\n"; + + str += (" DATA SIZE: "); str += (obj->getDataSize()); str += "\n"; + str += (" ADDRESS FROM: "); str += (obj->getAddrFrom()); str += "\n"; + str += (" ADDRESS TO: "); str += (obj->getAddrTo()); str += "\n"; + // str += (" CRC PACK: "); str += (obj->getCrcIN()); str += "\n"; + // str += (" CRC CALC: "); str += (obj->getCrcCALC()); str += "\n"; + str += "\n"; + + for (size_t i = 0; i < obj->getDataSize(); i++) { + switch (i) { + // case 0: + // str += (" ADDR: "); + // break; + // case 1: + // str += (" CMD: "); + // break; + + default: + str += (" Data["); str += (i); str += ("]: "); + break; + } + str += (obj->getDataPrt()[i]); str += "\n"; + } + + + str += ("\n*******ErrAll: "); str += (obj->getErrorCount()); str += "\n"; + str += ("**ErrDistance: "); str += ((int)(obj->getErrorHighSignal() - obj->getErrorLowSignal())); str += "\n"; + + str += "\n"; + } else { + str += ("SELF"); str += "\n"; + str += "\n"; + } + obj->resetAvaliable(); + Serial.write(str.c_str()); + } + } +} + + diff --git a/IR.ino b/IR.ino deleted file mode 100644 index 1250a8d..0000000 --- a/IR.ino +++ /dev/null @@ -1,9 +0,0 @@ -#define SerialSpeed 115200 - -void setup() { - Serial.begin(SerialSpeed); -} - -void loop() { - -} \ No newline at end of file diff --git a/IR_Output.h b/IR_Output.h deleted file mode 100644 index e69de29..0000000 From 6f5bbac83c36606d9e53f1a4a67496994dcf1fe7 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Thu, 22 Feb 2024 14:01:27 +0300 Subject: [PATCH 42/51] refactor --- .gitignore | 3 +- .vscode/arduino.json | 7 - IR-Protocol.ino | 140 ++++---- IR_Decoder.h | 536 ++++++++++++---------------- IR_Decoder.cpp => IR_DecoderRaw.cpp | 177 ++------- IR_DecoderRaw.h | 114 ++++++ IR_Encoder.cpp | 36 +- IR_Encoder.h | 14 +- IR_config.h | 11 +- 9 files changed, 470 insertions(+), 568 deletions(-) delete mode 100644 .vscode/arduino.json rename IR_Decoder.cpp => IR_DecoderRaw.cpp (73%) create mode 100644 IR_DecoderRaw.h diff --git a/.gitignore b/.gitignore index d833061..75ec3f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -.vscode/* -!.vscode/arduino.json \ No newline at end of file +.vscode/* \ No newline at end of file diff --git a/.vscode/arduino.json b/.vscode/arduino.json deleted file mode 100644 index 18d4f10..0000000 --- a/.vscode/arduino.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "board": "GyverCore:avr:nano", - "sketch": "Car.ino", - "port": "COM2", - "configuration": "boot=old,clock=external_16,serial=default,compiler_version=avrgcc5,timers=yes_millis,init=enable,es=disabled,bod=bod_2_7,co=disabled", - "programmer": "arduinoasisp" -} \ No newline at end of file diff --git a/IR-Protocol.ino b/IR-Protocol.ino index 40917e5..d812e06 100644 --- a/IR-Protocol.ino +++ b/IR-Protocol.ino @@ -1,4 +1,4 @@ -#include "IR_Decoder.h" +#include "IR_DecoderRaw.h" #include "IR_Encoder.h" #include "TimerStatic.h" #include "MemoryCheck.h" @@ -19,14 +19,12 @@ //////////////// Var ///////////////// -IR_Decoder decForward(2, 555); -IR_Decoder decBackward(3, 777); +IR_DecoderRaw decForward(2, 555); +IR_DecoderRaw decBackward(3, 777); -IR_Decoder* blindFromForward [] { &decBackward }; -IR_Encoder encForward(42, encForward_PIN, &decForward); - -IR_Encoder encBackward(321, encBackward_PIN); -IR_Encoder encTree(325, A2); +IR_Encoder encForward(42, encForward_PIN, &decBackward); +// IR_Encoder encBackward(321, encBackward_PIN); +// IR_Encoder encTree(325, A2); //////////////////////// Функции прерываний //////////////////////// @@ -41,13 +39,13 @@ void decBackwardISR() { static uint8_t* portOut; ISR(TIMER2_COMPA_vect) { encForward.isr(); - encBackward.isr(); + // encBackward.isr(); // encTree.isr(); //TODO: Сделать выбор порта *portOut = (*portOut & 0b11001111) | ( encForward.ir_out_virtual << 5U - | encBackward.ir_out_virtual << 6U + // | encBackward.ir_out_virtual << 6U // | encTree.ir_out_virtual << 2U ); } @@ -179,7 +177,8 @@ void setup() { - encForward.setBlindDecoders(blindFromForward, sizeof(blindFromForward) / sizeof(IR_Decoder*)); + IR_DecoderRaw* blindFromForward [] { &decForward, &decBackward }; + encForward.setBlindDecoders(blindFromForward, sizeof(blindFromForward) / sizeof(IR_DecoderRaw*)); attachInterrupt(0, decForwardISR, CHANGE); // D2 @@ -227,69 +226,64 @@ void loop() { //test -void status(IR_Decoder& dec) { - // if (dec.gotTune.avaliable()) { - // Serial.print(" Tune "); Serial.print(&dec == &decForward ? "decForward" : (&dec == &decBackward ? "decBackward" : "??")); Serial.print(": "); - - // Serial.println(dec.gotTune.getTune()); - - // Serial.println(); - // dec.gotTune.resetAvaliable(); - // } - - IR_Decoder::AnyData* infoArr [] = { &dec.gotData, &dec.gotBackData }; - - for (auto&& obj : infoArr) { - if (obj->avaliable()) { - String str; - if (obj->getDataPrt()[1]) { - str += ("Data on pin "); str += (dec.isrPin); str += "\n"; - - uint8_t msg = obj->getMsgRAW(); - str += (" MSG: "); - for (size_t i = 0; i < 8; i++) { - if (i == 3) str += " "; - str += (msg >> (7 - i)) & 1U; - } - - str += "\n"; - - str += (" DATA SIZE: "); str += (obj->getDataSize()); str += "\n"; - str += (" ADDRESS FROM: "); str += (obj->getAddrFrom()); str += "\n"; - str += (" ADDRESS TO: "); str += (obj->getAddrTo()); str += "\n"; - // str += (" CRC PACK: "); str += (obj->getCrcIN()); str += "\n"; - // str += (" CRC CALC: "); str += (obj->getCrcCALC()); str += "\n"; - str += "\n"; - - for (size_t i = 0; i < obj->getDataSize(); i++) { - switch (i) { - // case 0: - // str += (" ADDR: "); - // break; - // case 1: - // str += (" CMD: "); - // break; - - default: - str += (" Data["); str += (i); str += ("]: "); - break; - } - str += (obj->getDataPrt()[i]); str += "\n"; - } - - - str += ("\n*******ErrAll: "); str += (obj->getErrorCount()); str += "\n"; - str += ("**ErrDistance: "); str += ((int)(obj->getErrorHighSignal() - obj->getErrorLowSignal())); str += "\n"; - - str += "\n"; - } else { - str += ("SELF"); str += "\n"; - str += "\n"; - } - obj->resetAvaliable(); - Serial.write(str.c_str()); - } +void status(IR_DecoderRaw& dec) { + if (dec.available()) { + Serial.println("LOOP RAW DATA"); } + + + // IR_DecoderRaw::AnyData* infoArr [] = { &dec.gotData, &dec.gotBackData }; + // for (auto&& obj : infoArr) { + // if (obj->available()) { + // String str; + // if (obj->getDataPrt()[1]) { + // str += ("Data on pin "); str += (dec.isrPin); str += "\n"; + + // uint8_t msg = obj->getMsgRAW(); + // str += (" MSG: "); + // for (size_t i = 0; i < 8; i++) { + // if (i == 3) str += " "; + // str += (msg >> (7 - i)) & 1U; + // } + + // str += "\n"; + + // str += (" DATA SIZE: "); str += (obj->getDataSize()); str += "\n"; + // str += (" ADDRESS FROM: "); str += (obj->getAddrFrom()); str += "\n"; + // str += (" ADDRESS TO: "); str += (obj->getAddrTo()); str += "\n"; + // // str += (" CRC PACK: "); str += (obj->getCrcIN()); str += "\n"; + // // str += (" CRC CALC: "); str += (obj->getCrcCALC()); str += "\n"; + // str += "\n"; + + // for (size_t i = 0; i < obj->getDataSize(); i++) { + // switch (i) { + // // case 0: + // // str += (" ADDR: "); + // // break; + // // case 1: + // // str += (" CMD: "); + // // break; + + // default: + // str += (" Data["); str += (i); str += ("]: "); + // break; + // } + // str += (obj->getDataPrt()[i]); str += "\n"; + // } + + + // str += ("\n*******ErrAll: "); str += (obj->getErrorCount()); str += "\n"; + // str += ("**ErrDistance: "); str += ((int)(obj->getErrorHighSignal() - obj->getErrorLowSignal())); str += "\n"; + + // str += "\n"; + // } else { + // str += ("SELF"); str += "\n"; + // str += "\n"; + // } + // obj->resetAvailable(); + // Serial.write(str.c_str()); + // } + // } } diff --git a/IR_Decoder.h b/IR_Decoder.h index cf309b3..11095d6 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -1,320 +1,230 @@ #pragma once #include "IR_config.h" -//#define IRDEBUG - -#ifdef IRDEBUG -#define wrHigh A3 // Запись HIGH инициирована // green -#define wrLow A3 // Запись LOW инициирована // blue -#define writeOp 13 // Операция записи, 1 пульс для 0 и 2 для 1 // orange -// Исправленные ошибки // purle -// 1 пульс: fix -#define errOut A3 -#endif - -///////////////////////////////////////////////////////////////////////////////////////////////// - -#define riseTime riseSyncTime //* bitTime */ 893U // TODO: Должно высчитываться медианой -#define riseTolerance tolerance /* 250U */ // погрешность -#define riseTimeMax (riseTime + riseTolerance) -#define riseTimeMin (riseTime - riseTolerance) -#define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) -#define IR_timeout (riseTimeMax * (8 + syncBits +1)) // us // таймаут в 8 data + 3 sync + 1 + // class IR_Decoder -class IR_Encoder; -class IR_Decoder : private IR_FOX { - friend IR_Encoder; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - class IDataPack : protected IR_FOX { - friend IR_Decoder; - public: - IDataPack(IR_Decoder* dec) : dec(dec) {}; - - public: - bool avaliable() { if (isAvaliable) { isAvaliable = false; return true; } else { return isAvaliable; }; }; - virtual uint8_t getMsgInfo() { return msgPtr[0] & IR_MASK_MSG_INFO; }; - virtual uint8_t getMsgType() { return (msgPtr[0] >> 5) & IR_MASK_MSG_TYPE; }; - virtual uint8_t getMsgRAW() { return msgPtr[0]; }; - virtual uint16_t getErrorCount() { return err.all(); }; - virtual uint8_t getErrorLowSignal() { return err.lowSignal; }; - virtual uint8_t getErrorHighSignal() { return err.highSignal; }; - virtual uint8_t getErrorOther() { return err.other; }; - // uint16_t getCrcIN() { return crcPtr[0] << 8 | crcPtr[1]; }; - // uint16_t getCrcCALC() { return crcCalcVal; }; - virtual uint16_t getTunerTime() { return bitPeriod; }; - void resetAvaliable() { isAvaliable = false; }; - - protected: - inline static uint8_t data[dataByteSizeMax] { 0 }; - - inline static uint8_t* msgPtr; - inline static uint8_t* addrFromPtr; - inline static uint8_t* addrToPtr; - inline static uint8_t* dataPtr; - inline static uint8_t* crcPtr; - - inline static ErrorsStruct err; - inline static uint8_t packRawSize; - inline static uint16_t bitPeriod; - inline static uint16_t crcCalcVal; - - IR_Decoder* dec; - bool isAvaliable = false; - virtual bool checkAddress(PackOutInfo* packInfo) { - bool ret; - uint8_t targetAddrOffset = packInfo->offsets.addrToOffset; - uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); - checkaddressRuleApply(address, dec->id, ret); - return ret; - }; - virtual void onPackAddressCorrect(PackOutInfo* packInfo) { - memset(IDataPack::data, 0, dataByteSizeMax); - memcpy(data, packInfo->ptr, min(packInfo->packSize, dataByteSizeMax)); - err = packInfo->err; - bitPeriod = packInfo->rTime; - crcCalcVal = packInfo->crc; - packRawSize = packInfo->packSize; - - msgPtr = (data + packInfo->offsets.msgOffset); - addrFromPtr = (data + packInfo->offsets.addrFromOffset); - addrToPtr = (data + packInfo->offsets.addrToOffset); - dataPtr = (data + packInfo->offsets.dataOffset); - crcPtr = (data + packInfo->offsets.crcOffset); - } - - virtual void onPackAddressIncorrect(PackOutInfo* packInfo) {} - virtual void afterSet() {} - - void set(PackOutInfo packInfo, bool isNeedAddressCheck) { - isAvaliable = false; - if (!isNeedAddressCheck || checkAddress(&packInfo)) { - onPackAddressCorrect(&packInfo); - #ifdef IRDEBUG_INFO - Serial.println(" OK "); - #endif - isAvaliable = true; - } else { - onPackAddressIncorrect(&packInfo); - #ifdef IRDEBUG_INFO - Serial.println(" NOT MY "); - #endif - } - afterSet(); - } - }; - -public: - /////////////////////////////////////////////////////////////////////////////////////////////////////////// - class HasAddrFrom { - public: - virtual uint16_t getAddrFrom() { return IDataPack::addrFromPtr[0] << 8 | IDataPack::addrFromPtr[1]; }; - }; - - class HasAddrTo { - public: - virtual uint16_t getAddrTo() { return IDataPack::addrToPtr[0] << 8 | IDataPack::addrToPtr[1]; }; - }; - - class HasData { - public: - virtual uint8_t getDataSize() { return (uint8_t)(IDataPack::crcPtr - IDataPack::dataPtr); }; - virtual uint8_t* getDataPrt() { return IDataPack::dataPtr; }; - virtual uint8_t getDataRawSize() { return IDataPack::packRawSize; }; - virtual uint8_t* getDataRawPtr() { return IDataPack::data; }; - }; - class IAcceptable { - public: - virtual bool isNeedAccept(); - }; - class AnyData : public IDataPack, public HasAddrFrom, public HasAddrTo, public HasData { - using IDataPack::IDataPack; - }; - /////////////////////////////////////////////////////////////////////////////////////////////////////////// - - class Data : public AnyData, public IAcceptable { - using AnyData::AnyData; - public: - bool isNeedAccept() override { return ((IDataPack::msgPtr[0] >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; - private: - void afterSet() override { - if (Data::IDataPack::isAvaliable && isNeedAccept()) { - dec->isWaitingAcceptSend = true; - dec->addrWaitingSendgTo = getAddrFrom(); - Serial.print("\n Need to accept to "); - Serial.println(dec->addrWaitingSendgTo); - } - } - }; - - class BackData : public AnyData { - using AnyData::AnyData; - public: - bool isAddressed() { return IDataPack::msgPtr[0] & 0b00010000; }; - uint8_t getMsgInfo() { return IDataPack::msgPtr[0] & (IR_MASK_MSG_INFO >> 1); }; - uint16_t getAddrTo() override { - if (isAddressed()) { - return IDataPack::addrToPtr[0] << 8 | IDataPack::addrToPtr[1]; - } else { - return IR_Broadcast; - } - }; - }; - - class Accept : public IDataPack, public HasAddrFrom { - using IDataPack::IDataPack; - public: - - private: - bool checkAddress(PackOutInfo* packInfo) override { - bool ret; - uint8_t targetAddrOffset = packInfo->offsets.addrFromOffset; - uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); - ret = address == dec->addrWaitingFrom; - return ret; - } - }; - - class Request : public IDataPack, public HasAddrFrom, public HasAddrTo { - using IDataPack::IDataPack; - public: - - private: - // void afterSet() override { - // if (isAvaliable) { - // dec->isWaitingAcceptSend = true; - // dec->addrWaitingSendgTo = getAddrFrom(); - // Serial.print("\n Need to accept to "); - // Serial.println(dec->addrWaitingSendgTo); - // } - // } - }; - - class RawTune { - friend IR_Decoder; - public: - bool avaliable() { return isAvaliable; }; - uint16_t getTunerTime() { return bitPeriod; }; - void resetAvaliable() { isAvaliable = false; }; - protected: - bool isAvaliable; - uint16_t bitPeriod; - - void set(uint16_t time) { - bitPeriod = time; - isAvaliable = true; - } - }; - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -public: - uint16_t id; - - Data gotData = Data(this); /// @brief Контейнер с данными - BackData gotBackData = BackData(this); - Accept gotAccept = Accept(this); /// @brief Контейнер с подтверждением - Request gotRequest = Request(this); /// @brief Контейнер с запросом - RawTune gotTune; /// @brief Контейнер с информацией подстройки - - const uint8_t isrPin; // Пин прерывания - - ////////////////////////////////////////////////////////////////////////// - /// @brief Конструктор - /// @param isrPin Номер вывода прерывания/данных от приёмника (2 или 3 для atmega 328p) - /// @param addr Адрес приёмника - /// @param encPair Указатель на передатчик, работающий в паре - IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr); - - ~IR_Decoder(); - - void isr(); ///@brief Функция прерывания - void tick(); /// @brief Обработка приёмника, необходима для работы - - // @return Буффер переполнился - bool isOverflow() { return isBufferOverflow; }; - - /// @brief Флаг приёма - /// @return Возвращает true, если происходит приём пакета - // bool isReciving() { return isRecive; }; //TODO: Некорректно работает - - // @brief Слушатель для работы isReciving() - void listen(); - - ////////////////////////////////////////////////////////////////////////// - - bool isWaitingAccept = false; // Флаг ожидания подтверждения - bool isWaitingAcceptSend = false; // Флаг ожидания отправки подтверждения - uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение - uint16_t addrWaitingSendgTo = 0; // Адрес, кому нужно отправить подтверждение -private: - IR_Encoder* encoder; // Указатель на парный передатчик - volatile uint16_t isPairSending = 0; // Флаг передачи парного передатчика - volatile bool isRecive = false; // Флаг приёма - volatile bool isPreamb = false; // флаг начальной последовости - bool isCrcCorrect = false; // Флаг корректности crc - bool isBufferOverflow = false; // Флаг переполнения буффера данных - bool isWrongPack = false; // Флаг битого пакета - - uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс - - //////////////////////////////////////////////////////////////////////// - volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов - - struct FrontStorage { // Структура для хранения времени и направления фронта/спада - volatile uint32_t time = 0; // Время - volatile bool dir = false; // Направление (true = ↑; false = ↓) - volatile FrontStorage* next = nullptr; // Указатель на следующий связанный фронт/спад, или nullptr если конец - }; - volatile FrontStorage* lastFront = nullptr; // Указатель последнего фронта/спада - volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада - volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов - //////////////////////////////////////////////////////////////////////// - uint8_t* dataBuffer = nullptr; // Указатель на буффер данных - uint32_t prevRise, prevPrevRise, prevFall, prevPrevFall; // Время предыдущих фронтов/спадов - uint16_t errorCounter = 0; // Счётчик ошибок - int8_t preambFrontCounter = 0; // Счётчик __/``` ↑ преамбулы - int16_t bufBitPos = 0; // Позиция для записи бита в буффер - -private: - /// @brief Проверка CRC. Проверяет len байт со значением crc, пришедшим в пакете - /// @param len Длина в байтах проверяемых данных - /// @param crc Результат рассчёта crc (Выходной параметр) - /// @return true если crc верно - bool crcCheck(uint8_t len, uint16_t& crc); - - //////////////////////////////////////////////////////////////////////// - bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации - uint16_t i_dataBuffer; // Счётчик буфера данных - uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData - uint8_t i_syncBit; // Счётчик битов синхронизации - uint8_t err_syncBit; // Счётчик ошибок синхронизации - - /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация - /// @param Бит данных - void writeToBuffer(bool); - void packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets, bool isNeedAddressCheck = true); - //////////////////////////////////////////////////////////////////////// - - /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных - void firstRX(); - - /// @brief Целочисленное деление с округлением вверх - /// @param val Значение - /// @param divider Делитель - /// @return Результат - uint16_t ceil_div(uint16_t val, uint16_t divider); - - #ifdef IRDEBUG - inline void errPulse(uint8_t pin, uint8_t count); - inline void infoPulse(uint8_t pin, uint8_t count); - #endif -}; \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// class IDataPack : protected IR_FOX { +// friend IR_Decoder; +// public: +// IDataPack(IR_Decoder* dec) : dec(dec) {}; + +// public: +// bool available() { if (isAvailable) { isAvailable = false; return true; } else { return isAvailable; }; }; +// virtual uint8_t getMsgInfo() { return msgPtr[0] & IR_MASK_MSG_INFO; }; +// virtual uint8_t getMsgType() { return (msgPtr[0] >> 5) & IR_MASK_MSG_TYPE; }; +// virtual uint8_t getMsgRAW() { return msgPtr[0]; }; +// virtual uint16_t getErrorCount() { return err.all(); }; +// virtual uint8_t getErrorLowSignal() { return err.lowSignal; }; +// virtual uint8_t getErrorHighSignal() { return err.highSignal; }; +// virtual uint8_t getErrorOther() { return err.other; }; +// // uint16_t getCrcIN() { return crcPtr[0] << 8 | crcPtr[1]; }; +// // uint16_t getCrcCALC() { return crcCalcVal; }; +// virtual uint16_t getTunerTime() { return bitPeriod; }; +// void resetAvailable() { isAvailable = false; }; + +// protected: +// inline static uint8_t data[dataByteSizeMax] { 0 }; + +// inline static uint8_t* msgPtr; +// inline static uint8_t* addrFromPtr; +// inline static uint8_t* addrToPtr; +// inline static uint8_t* dataPtr; +// inline static uint8_t* crcPtr; + +// inline static ErrorsStruct err; +// inline static uint8_t packRawSize; +// inline static uint16_t bitPeriod; +// inline static uint16_t crcCalcVal; + +// IR_Decoder* dec; +// bool isAvailable = false; +// virtual bool checkAddress(PackOutInfo* packInfo) { +// bool ret; +// uint8_t targetAddrOffset = packInfo->offsets.addrToOffset; +// uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); +// checkaddressRuleApply(address, dec->id, ret); +// return ret; +// }; +// virtual void onPackAddressCorrect(PackOutInfo* packInfo) { +// memset(IDataPack::data, 0, dataByteSizeMax); +// memcpy(data, packInfo->ptr, min(packInfo->packSize, dataByteSizeMax)); +// err = packInfo->err; +// bitPeriod = packInfo->rTime; +// crcCalcVal = packInfo->crc; +// packRawSize = packInfo->packSize; + +// msgPtr = (data + packInfo->offsets.msgOffset); +// addrFromPtr = (data + packInfo->offsets.addrFromOffset); +// addrToPtr = (data + packInfo->offsets.addrToOffset); +// dataPtr = (data + packInfo->offsets.dataOffset); +// crcPtr = (data + packInfo->offsets.crcOffset); +// } + +// virtual void onPackAddressIncorrect(PackOutInfo* packInfo) {} +// virtual void afterSet() {} + +// void set(PackOutInfo packInfo, bool isNeedAddressCheck) { +// isAvailable = false; +// if (!isNeedAddressCheck || checkAddress(&packInfo)) { +// onPackAddressCorrect(&packInfo); +// #ifdef IRDEBUG_INFO +// Serial.println(" OK "); +// #endif +// isAvailable = true; +// } else { +// onPackAddressIncorrect(&packInfo); +// #ifdef IRDEBUG_INFO +// Serial.println(" NOT MY "); +// #endif +// } +// afterSet(); +// } +// }; + +// public: +// /////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class HasAddrFrom { +// public: +// virtual uint16_t getAddrFrom() { return IDataPack::addrFromPtr[0] << 8 | IDataPack::addrFromPtr[1]; }; +// }; + +// class HasAddrTo { +// public: +// virtual uint16_t getAddrTo() { return IDataPack::addrToPtr[0] << 8 | IDataPack::addrToPtr[1]; }; +// }; + +// class HasData { +// public: +// virtual uint8_t getDataSize() { return (uint8_t)(IDataPack::crcPtr - IDataPack::dataPtr); }; +// virtual uint8_t* getDataPrt() { return IDataPack::dataPtr; }; +// virtual uint8_t getDataRawSize() { return IDataPack::packRawSize; }; +// virtual uint8_t* getDataRawPtr() { return IDataPack::data; }; +// }; +// class IAcceptable { +// public: +// virtual bool isNeedAccept(); +// }; +// class AnyData : public IDataPack, public HasAddrFrom, public HasAddrTo, public HasData { +// using IDataPack::IDataPack; +// }; +// /////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// class Data : public AnyData, public IAcceptable { +// using AnyData::AnyData; +// public: +// bool isNeedAccept() override { return ((IDataPack::msgPtr[0] >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; +// private: +// void afterSet() override { +// if (Data::IDataPack::isAvailable && isNeedAccept()) { +// dec->addrWaitingSendgTo = getAddrFrom(); +// dec->startWaitingSendToTime = millis(); +// dec->isWaitingAcceptSend = true; +// Serial.print("\n Need to accept to "); +// Serial.println(dec->addrWaitingSendgTo); +// } +// } +// }; + +// class BackData : public AnyData { +// using AnyData::AnyData; +// public: +// bool isAddressed() { return IDataPack::msgPtr[0] & 0b00010000; }; +// uint8_t getMsgInfo() { return IDataPack::msgPtr[0] & (IR_MASK_MSG_INFO >> 1); }; +// uint16_t getAddrTo() override { +// if (isAddressed()) { +// return IDataPack::addrToPtr[0] << 8 | IDataPack::addrToPtr[1]; +// } else { +// return IR_Broadcast; +// } +// }; +// }; + +// class Accept : public IDataPack, public HasAddrFrom { +// using IDataPack::IDataPack; +// public: + +// private: +// bool checkAddress(PackOutInfo* packInfo) override { +// bool ret; +// uint8_t targetAddrOffset = packInfo->offsets.addrFromOffset; +// uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); +// ret = address == dec->addrWaitingFrom; +// return ret; +// } +// }; + +// class Request : public IDataPack, public HasAddrFrom, public HasAddrTo { +// using IDataPack::IDataPack; +// public: + +// private: +// // void afterSet() override { +// // if (isAvailable) { +// // dec->isWaitingAcceptSend = true; +// // dec->addrWaitingSendgTo = getAddrFrom(); +// // Serial.print("\n Need to accept to "); +// // Serial.println(dec->addrWaitingSendgTo); +// // } +// // } +// }; + +// class RawTune { +// friend IR_Decoder; +// public: +// bool available() { return isAvailable; }; +// uint16_t getTunerTime() { return bitPeriod; }; +// void resetAvailable() { isAvailable = false; }; +// protected: +// bool isAvailable; +// uint16_t bitPeriod; + +// void set(uint16_t time) { +// bitPeriod = time; +// isAvailable = true; +// } +// }; + +// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/IR_Decoder.cpp b/IR_DecoderRaw.cpp similarity index 73% rename from IR_Decoder.cpp rename to IR_DecoderRaw.cpp index fc88fee..51c38fe 100644 --- a/IR_Decoder.cpp +++ b/IR_DecoderRaw.cpp @@ -1,19 +1,17 @@ -#include "IR_Decoder.h" +#include "IR_DecoderRaw.h" #include "IR_Encoder.h" -IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), id(addr), encoder(encPair) { - dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; +IR_DecoderRaw::IR_DecoderRaw(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), id(addr), encoder(encPair) { prevRise = prevFall = prevPrevFall = prevPrevRise = 0; -} - -IR_Decoder::~IR_Decoder() { - delete dataBuffer; + if (encPair != nullptr) { + encPair->decPair = this; + } } //////////////////////////////////// isr /////////////////////////////////////////// -void IR_Decoder::isr() { +void IR_DecoderRaw::isr() { if (isPairSending) return; subBuffer[currentSubBufferIndex].next = nullptr; @@ -40,22 +38,22 @@ void IR_Decoder::isr() { lastFront = &subBuffer[currentSubBufferIndex]; } - currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++; // Закольцовка буффера } //////////////////////////////////////////////////////////////////////////////////// -void IR_Decoder::firstRX() { +void IR_DecoderRaw::firstRX() { #ifdef IRDEBUG_INFO Serial.print("\n>"); #endif errors.reset(); + packSize = 0; isBufferOverflow = false; - isCrcCorrect = false; + isAvailable = false; bufBitPos = 0; isData = true; i_dataBuffer = 0; @@ -69,17 +67,17 @@ void IR_Decoder::firstRX() { memset(dataBuffer, 0x00, dataByteSizeMax); } -void IR_Decoder::listen() { +void IR_DecoderRaw::listenEnd() { if (isRecive && ((micros() - prevRise) > IR_timeout * 2)) { isRecive = false; firstRX(); } } -void IR_Decoder::tick() { +void IR_DecoderRaw::tick() { FrontStorage currentFront; noInterrupts(); - listen(); + listenEnd(); if (firstUnHandledFront == nullptr) { interrupts(); return; } //Если данных нет - ничего не делаем currentFront = *((FrontStorage*)firstUnHandledFront); //найти следующий необработанный фронт/спад interrupts(); @@ -116,7 +114,7 @@ void IR_Decoder::tick() { // Serial.print("preambFrontCounter: "); Serial.println(preambFrontCounter); } else { if (isPreamb) {// первый фронт после - gotTune.set(riseSyncTime); + // gotTune.set(riseSyncTime); } isPreamb = false; } @@ -269,7 +267,7 @@ void IR_Decoder::tick() { firstUnHandledFront = firstUnHandledFront->next; //переместить флаг на следующий элемент для обработки (next or nullptr) } -void IR_Decoder::writeToBuffer(bool bit) { +void IR_DecoderRaw::writeToBuffer(bool bit) { if (i_dataBuffer > dataByteSizeMax * 8) {// проверка переполнения //TODO: Буффер переполнен! #ifdef IRDEBUG_INFO @@ -290,15 +288,15 @@ void IR_Decoder::writeToBuffer(bool bit) { #endif } - if (isData) { // Запись битов в dataBuffer #ifdef IRDEBUG_INFO Serial.print(bit); #endif - if (i_dataBuffer % 8 == 7) { - // Serial.print("+"); - } + // if (i_dataBuffer % 8 == 7) { + // // Serial.print("+"); + // } + dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer % 8); // Запись в буффер i_dataBuffer++; bufBitPos++; @@ -349,130 +347,23 @@ void IR_Decoder::writeToBuffer(bool bit) { } #endif - if ((i_dataBuffer >= (8 * msgBytes)) && !isCrcCorrect) { - uint16_t crcValue; - uint8_t packSize; - switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { - - case IR_MSG_BACK: - packSize = (dataBuffer[0] & (IR_MASK_MSG_INFO >> 1)) + crcBytes; - if (i_dataBuffer != packSize * bitPerByte) break; - - if ((dataBuffer[0] & 0b00010000)) { // С адресацией - packToOutClass( - packSize, // packSize - gotBackData, // obj - PackOffsets { - 0, // msgOffset - 1, // addrFromOffset - 3, // addrToOffset - 5, // dataOffset - NULL // crcOffset - }, - true - ); - } else { // Без адресации - packToOutClass( - packSize, // packSize - gotBackData, // obj - PackOffsets { - 0, // msgOffset - 1, // addrFromOffset - 3, // addrToOffset - 3, // dataOffset - NULL // crcOffset - }, - false - ); - } - break; - - case IR_MSG_ACCEPT: - packSize = msgBytes + addrBytes + crcBytes; - if (i_dataBuffer != packSize * bitPerByte) break; - - packToOutClass( - packSize, // packSize - gotAccept, // obj - PackOffsets { - 0, // msgOffset - 1, // addrFromOffset - NULL, // addrToOffset - NULL, // dataOffset - 3 // crcOffset - } - ); - break; - - case IR_MSG_REQUEST: - packSize = msgBytes + addrBytes + addrBytes + crcBytes; - if (i_dataBuffer != packSize * bitPerByte) break; - - packToOutClass( - packSize, // packSize - gotRequest, // obj - PackOffsets { - 0, // msgOffset - 1, // addrFromOffset - 3, // addrToOffset - NULL, // dataOffset - 5 // crcOffset - } - ); - break; - - - case IR_MSG_DATA_ACCEPT: - case IR_MSG_DATA_NOACCEPT: - packSize = (dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes; - if (i_dataBuffer != packSize * bitPerByte) break; - - packToOutClass( - packSize, // packSize - gotData, // obj - PackOffsets { - 0, // msgOffset - 1, // addrFromOffset - 3, // addrToOffset - 5, // dataOffset - NULL // crcOffset - } - ); - break; - - default: - break; + if (!isAvailable && isData) { + if (i_dataBuffer == 8 * msgBytes) {// Ппервый байт + packSize = (dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes; + Serial.print(" ["); Serial.print(packSize); Serial.print("] "); } - }/**/ + + if (packSize && (i_dataBuffer == packSize*bitPerByte)) { // Конец + isAvailable = crcCheck(packSize - crcBytes, crcValue); + Serial.print(" END DATA "); + isRecive = false; + } + } + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } -void IR_Decoder::packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets, bool isNeedAddressCheck = true) { - PackOutInfo packInfo; - #ifdef IRDEBUG_INFO - Serial.print(" IN "); - #endif - isCrcCorrect = crcCheck(packSize - crcBytes, packInfo.crc); - if (isCrcCorrect) { - packInfo.ptr = dataBuffer; - packInfo.packSize = packSize; - packInfo.offsets = offsets; - packInfo.offsets.crcOffset = packInfo.packSize - crcBytes; - packInfo.err = errors; - packInfo.rTime = riseSyncTime; - obj.set(packInfo, isNeedAddressCheck); - } else { - #ifdef IRDEBUG_INFO - Serial.println(" CRC WRONG "); - #endif - } - - isRecive = false; -} - - - -bool IR_Decoder::crcCheck(uint8_t len, crc_t& crc) { +bool IR_DecoderRaw::crcCheck(uint8_t len, crc_t& crc) { bool crcOK = false; crc = 0; @@ -493,7 +384,7 @@ bool IR_Decoder::crcCheck(uint8_t len, crc_t& crc) { return crcOK; } -uint16_t IR_Decoder::ceil_div(uint16_t val, uint16_t divider) { +uint16_t IR_DecoderRaw::ceil_div(uint16_t val, uint16_t divider) { int ret = val / divider; if ((val << 4) / divider - (ret << 4) >= 8) ret++; @@ -504,7 +395,7 @@ uint16_t IR_Decoder::ceil_div(uint16_t val, uint16_t divider) { // IRDEBUG FUNC #ifdef IRDEBUG -inline void IR_Decoder::errPulse(uint8_t pin, uint8_t count) { +inline void IR_DecoderRaw::errPulse(uint8_t pin, uint8_t count) { for (size_t i = 0; i < count; i++) { digitalWrite(pin, 1); digitalWrite(pin, 0); @@ -512,7 +403,7 @@ inline void IR_Decoder::errPulse(uint8_t pin, uint8_t count) { digitalWrite(pin, 0); } -inline void IR_Decoder::infoPulse(uint8_t pin, uint8_t count) { +inline void IR_DecoderRaw::infoPulse(uint8_t pin, uint8_t count) { for (size_t i = 0; i < count; i++) { digitalWrite(pin, 1); digitalWrite(pin, 0); diff --git a/IR_DecoderRaw.h b/IR_DecoderRaw.h new file mode 100644 index 0000000..56c6989 --- /dev/null +++ b/IR_DecoderRaw.h @@ -0,0 +1,114 @@ +#pragma once +#include "IR_config.h" + +//#define IRDEBUG + +#ifdef IRDEBUG +#define wrHigh A3 // Запись HIGH инициирована // green +#define wrLow A3 // Запись LOW инициирована // blue +#define writeOp 13 // Операция записи, 1 пульс для 0 и 2 для 1 // orange +// Исправленные ошибки // purle +// 1 пульс: fix +#define errOut A3 +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////// + +#define riseTime riseSyncTime //* bitTime */ 893U // TODO: Должно высчитываться медианой +#define riseTolerance tolerance /* 250U */ // погрешность +#define riseTimeMax (riseTime + riseTolerance) +#define riseTimeMin (riseTime - riseTolerance) +#define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) +#define IR_timeout (riseTimeMax * (8 + syncBits +1)) // us // таймаут в 8 data + 3 sync + 1 + + +class IR_Encoder; +class IR_DecoderRaw : private IR_FOX { + friend IR_Encoder; +public: + const uint8_t isrPin; // Пин прерывания + + ////////////////////////////////////////////////////////////////////////// + /// @brief Конструктор + /// @param isrPin Номер вывода прерывания/данных от приёмника (2 или 3 для atmega 328p) + /// @param addr Адрес приёмника + /// @param encPair Указатель на передатчик, работающий в паре + IR_DecoderRaw(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr); + + void isr(); // Функция прерывания + void tick(); // Обработка приёмника, необходима для работы + bool available() { if(isAvailable) {isAvailable = false; return true;} else { return false;}}; + bool isOverflow() { return isBufferOverflow; }; // Буффер переполнился + bool isReciving() { return isBufferOverflow; }; // Возвращает true, если происходит приём пакета + + ////////////////////////////////////////////////////////////////////////// + +private: + uint16_t id; + bool isAvailable = false; + uint16_t packSize; + uint16_t crcValue; + IR_Encoder* encoder; // Указатель на парный передатчик + volatile uint16_t isPairSending = 0; // Флаг передачи парного передатчика + volatile bool isRecive = false; // Флаг приёма + volatile bool isPreamb = false; // флаг начальной последовости + bool isBufferOverflow = false; // Флаг переполнения буффера данных + bool isWrongPack = false; // Флаг битого пакета + + uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс + + //////////////////////////////////////////////////////////////////////// + volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов + + struct FrontStorage { // Структура для хранения времени и направления фронта/спада + volatile uint32_t time = 0; // Время + volatile bool dir = false; // Направление (true = ↑; false = ↓) + volatile FrontStorage* next = nullptr; // Указатель на следующий связанный фронт/спад, или nullptr если конец + }; + volatile FrontStorage* lastFront = nullptr; // Указатель последнего фронта/спада + volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада + volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов + //////////////////////////////////////////////////////////////////////// + uint8_t dataBuffer[dataByteSizeMax]{0}; // Буффер данных + uint32_t prevRise, prevPrevRise, prevFall, prevPrevFall; // Время предыдущих фронтов/спадов + uint16_t errorCounter = 0; // Счётчик ошибок + int8_t preambFrontCounter = 0; // Счётчик __/``` ↑ преамбулы + int16_t bufBitPos = 0; // Позиция для записи бита в буффер + +private: + void listenEnd(); // @brief Слушатель для работы isReciving() + + /// @brief Проверка CRC. Проверяет len байт со значением crc, пришедшим в пакете + /// @param len Длина в байтах проверяемых данных + /// @param crc Результат рассчёта crc (Выходной параметр) + /// @return true если crc верно + bool crcCheck(uint8_t len, uint16_t& crc); + + //////////////////////////////////////////////////////////////////////// + bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации + uint16_t i_dataBuffer; // Счётчик буфера данных + uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData + uint8_t i_syncBit; // Счётчик битов синхронизации + uint8_t err_syncBit; // Счётчик ошибок синхронизации + + /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация + /// @param Бит данных + void writeToBuffer(bool); + //////////////////////////////////////////////////////////////////////// + + + void firstRX(); /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных + + /// @brief Целочисленное деление с округлением вверх + /// @param val Значение + /// @param divider Делитель + /// @return Результат + uint16_t ceil_div(uint16_t val, uint16_t divider); + + #ifdef IRDEBUG + inline void errPulse(uint8_t pin, uint8_t count); + inline void infoPulse(uint8_t pin, uint8_t count); + #endif + + +}; \ No newline at end of file diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 1c8c594..661e633 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -1,23 +1,26 @@ #include "IR_Encoder.h" -#include "IR_Decoder.h" +#include "IR_DecoderRaw.h" #define LoopOut 12 #define ISR_Out 10 #define TestOut 13 -IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, IR_Decoder* decPair = nullptr) { +IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, IR_DecoderRaw* decPair = nullptr) { id = addr; this->decPair = decPair; signal = noSignal; isSending = false; #if disablePairDec if (decPair != nullptr) { - blindDecoders = new IR_Decoder * [1] {decPair}; + blindDecoders = new IR_DecoderRaw * [1] {decPair}; decodersCount = 1; } #endif + if (decPair != nullptr) { + decPair->encoder = this; + } }; -void IR_Encoder::setBlindDecoders(IR_Decoder* decoders [], uint8_t count) { +void IR_Encoder::setBlindDecoders(IR_DecoderRaw* decoders [], uint8_t count) { #if disablePairDec if (blindDecoders != nullptr) delete [] blindDecoders; #endif @@ -58,26 +61,29 @@ void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool need sendBuffer[packSize - crcBytes] = crc8(sendBuffer, 0, packSize - crcBytes, poly1) & 0xFF; sendBuffer[packSize - crcBytes + 1] = crc8(sendBuffer, 0, packSize - crcBytes + 1, poly2) & 0xFF; - if (decPair != nullptr) { - decPair->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); - if (decPair->isWaitingAccept) { - decPair->addrWaitingFrom = addrTo; - } - } + // if (decPair != nullptr) { + // decPair->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); + // if (decPair->isWaitingAccept) { + // decPair->addrWaitingFrom = addrTo; + // } + // } + // отправка rawSend(sendBuffer, packSize); } -void IR_Encoder::sendAccept(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { +void IR_Encoder::sendAccept(uint16_t addrTo, uint8_t addInfo) { memset(sendBuffer, 0x00, dataByteSizeMax); sendBuffer[0] = IR_MSG_ACCEPT << 5; sendBuffer[0] |= addInfo & IR_MASK_MSG_INFO; // addr_self - if (!forAll) { - sendBuffer[1] = id >> 8 & 0xFF; - sendBuffer[2] = id & 0xFF; - } + sendBuffer[1] = id >> 8 & 0xFF; + sendBuffer[2] = id & 0xFF; + + Serial.print("\nRAW Accept to "); + Serial.println(addrTo); + // data crc sendBuffer[3] = crc8(sendBuffer, 0, 3, poly1) & 0xFF; diff --git a/IR_Encoder.h b/IR_Encoder.h index b791ffe..65462f2 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -3,9 +3,9 @@ //TODO: Отложенная передача после завершения приема -class IR_Decoder; +class IR_DecoderRaw; class IR_Encoder : IR_FOX { - friend IR_Decoder; + friend IR_DecoderRaw; public: uint16_t id; /// @brief Адрес передатчика @@ -18,7 +18,7 @@ public: /// @param pin Вывод передатчика /// @param tune Подстройка несущей частоты /// @param decPair Приёмник, для которого отключается приём в момент передачи передатчиком - IR_Encoder(uint16_t addr, uint8_t pin, IR_Decoder* decPair = nullptr); + IR_Encoder(uint16_t addr, uint8_t pin, IR_DecoderRaw* decPair = nullptr); static void timerSetup() { // TIMER2 Ini @@ -42,10 +42,10 @@ public: SREG = oldSREG; // Return interrupt settings } - void IR_Encoder::setBlindDecoders(IR_Decoder* decoders [], uint8_t count); + void IR_Encoder::setBlindDecoders(IR_DecoderRaw* decoders [], uint8_t count); void rawSend(uint8_t* ptr, uint8_t len); void sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false); - void sendAccept(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false); + void sendAccept(uint16_t addrTo, uint8_t addInfo = 0); void sendRequest(uint16_t addrTo, uint8_t addInfo = 0); void sendBack(uint8_t* data = nullptr, uint8_t len = 0); void sendBackTo(uint16_t addrTo, uint8_t* data = nullptr, uint8_t len = 0); @@ -70,8 +70,8 @@ private: sync = 3 }; - IR_Decoder* decPair; - IR_Decoder** blindDecoders; + IR_DecoderRaw* decPair; + IR_DecoderRaw** blindDecoders; uint8_t decodersCount; uint8_t sendLen; diff --git a/IR_config.h b/IR_config.h index 52097de..97ee536 100644 --- a/IR_config.h +++ b/IR_config.h @@ -40,18 +40,14 @@ msg type:                                         // | xxx..... | = тип сообщения                                         // | ...xxxxx | = длина (максимум 31 бита)                                         //  ---------- */ -#define IR_MSG_BACK 0U // | 0000B.... | = Задний сигнал машинки -;// // | \\\x---- | = нужна ли адресация -;// // | \\\-xxxx | = длина данных (Равна нулю при отсутствии сквозных команд) +#define IR_MSG_BACK 0U // | 000...... | = Задний сигнал машинки #define IR_MSG_ACCEPT 1U // | 001..... | = подтверждение #define IR_MSG_REQUEST 2U // | 010..... | = запрос #define IR_MSG_ 3U // | 011..... | = ?? -#define IR_MSG_ 4U // | 100..... | = ?? +#define IR_MSG_BACK_TO 4U // | 100..... | = Задний сигнал машинки c адресацией #define IR_MSG_ 5U // | 101..... | = ?? #define IR_MSG_DATA_NOACCEPT 6U // | 110..... | = данные, не требующие подтверждения -;// // | \\\xxxxx | = длина данных #define IR_MSG_DATA_ACCEPT 7U // | 111..... | = данные требующие подтверждения -;//                                     // | \\\xxxxx | = длина данных /*   // ---------- /```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\ @@ -163,10 +159,9 @@ public: }; - struct PackOutInfo { + struct PackInfo { uint8_t* ptr; uint8_t packSize; - PackOffsets offsets; uint16_t crc; ErrorsStruct err; uint16_t rTime; From e35bf7ae23d3fd42b66c8cc8effd96c16e29812e Mon Sep 17 00:00:00 2001 From: DashyFox Date: Thu, 22 Feb 2024 16:52:55 +0300 Subject: [PATCH 43/51] refactor --- IR-Protocol.ino | 12 ++++----- IR_Decoder.h | 64 ++++++++++++++++++++++++++++------------------- IR_DecoderRaw.cpp | 11 ++++++-- IR_DecoderRaw.h | 6 +++-- IR_Encoder.cpp | 4 +-- IR_config.h | 14 +++++------ PacketTypes.h | 59 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 124 insertions(+), 46 deletions(-) create mode 100644 PacketTypes.h diff --git a/IR-Protocol.ino b/IR-Protocol.ino index d812e06..bc499f5 100644 --- a/IR-Protocol.ino +++ b/IR-Protocol.ino @@ -1,4 +1,4 @@ -#include "IR_DecoderRaw.h" +#include "IR_Decoder.h" #include "IR_Encoder.h" #include "TimerStatic.h" #include "MemoryCheck.h" @@ -19,8 +19,8 @@ //////////////// Var ///////////////// -IR_DecoderRaw decForward(2, 555); -IR_DecoderRaw decBackward(3, 777); +IR_Decoder decForward(2, 555); +IR_Decoder decBackward(3, 777); IR_Encoder encForward(42, encForward_PIN, &decBackward); // IR_Encoder encBackward(321, encBackward_PIN); @@ -226,10 +226,8 @@ void loop() { //test -void status(IR_DecoderRaw& dec) { - if (dec.available()) { - Serial.println("LOOP RAW DATA"); - } +void status(IR_Decoder& dec) { + // IR_DecoderRaw::AnyData* infoArr [] = { &dec.gotData, &dec.gotBackData }; diff --git a/IR_Decoder.h b/IR_Decoder.h index 11095d6..4859f02 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -1,33 +1,45 @@ #pragma once -#include "IR_config.h" - - // class IR_Decoder - - - - - - - - - - - - - - - - - - - - - - - +#include "IR_DecoderRaw.h" +#include "PacketTypes.h" +class IR_Decoder : public IR_DecoderRaw { +public: + IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : + IR_DecoderRaw(isrPin, addr, encPair), + gotData(Data(&packInfo)) { + } + + Data gotData; + + void tick() { + IR_DecoderRaw::tick(); + if (available()) { + Serial.println("PARSING RAW DATA"); + + switch (packInfo.buffer[0] & IR_MASK_MSG_TYPE) { + case IR_MSG_DATA_NOACCEPT: + + break; + case IR_MSG_DATA_ACCEPT: + break; + case IR_MSG_BACK: + break; + case IR_MSG_BACK_TO: + break; + case IR_MSG_REQUEST: + break; + case IR_MSG_ACCEPT: + break; + + default: + break; + } + + } + } +}; diff --git a/IR_DecoderRaw.cpp b/IR_DecoderRaw.cpp index 51c38fe..5849f22 100644 --- a/IR_DecoderRaw.cpp +++ b/IR_DecoderRaw.cpp @@ -349,14 +349,21 @@ void IR_DecoderRaw::writeToBuffer(bool bit) { if (!isAvailable && isData) { if (i_dataBuffer == 8 * msgBytes) {// Ппервый байт - packSize = (dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes; + packSize = dataBuffer[0] & IR_MASK_MSG_INFO; Serial.print(" ["); Serial.print(packSize); Serial.print("] "); } if (packSize && (i_dataBuffer == packSize*bitPerByte)) { // Конец - isAvailable = crcCheck(packSize - crcBytes, crcValue); Serial.print(" END DATA "); + + packInfo.buffer = dataBuffer; + packInfo.crc = crcValue; + packInfo.err = errors; + packInfo.packSize = packSize; + packInfo.rTime = riseSyncTime; + isRecive = false; + isAvailable = crcCheck(packSize - crcBytes, crcValue); } } diff --git a/IR_DecoderRaw.h b/IR_DecoderRaw.h index 56c6989..515d9fe 100644 --- a/IR_DecoderRaw.h +++ b/IR_DecoderRaw.h @@ -23,7 +23,7 @@ class IR_Encoder; -class IR_DecoderRaw : private IR_FOX { +class IR_DecoderRaw : public IR_FOX { friend IR_Encoder; public: const uint8_t isrPin; // Пин прерывания @@ -42,8 +42,10 @@ public: bool isReciving() { return isBufferOverflow; }; // Возвращает true, если происходит приём пакета ////////////////////////////////////////////////////////////////////////// - +protected: + PackInfo packInfo; private: + ErrorsStruct errors; uint16_t id; bool isAvailable = false; uint16_t packSize; diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 661e633..0848086 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -39,7 +39,7 @@ void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool need memset(sendBuffer, 0x00, dataByteSizeMax); uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; uint8_t msgType = - ((needAccept ? IR_MSG_DATA_ACCEPT : IR_MSG_DATA_NOACCEPT) << 5) | ((packSize - crcBytes) & IR_MASK_MSG_INFO); + ((needAccept ? IR_MSG_DATA_ACCEPT : IR_MSG_DATA_NOACCEPT) << 5) | (packSize & IR_MASK_MSG_INFO); // формирование массива // msg_type @@ -127,7 +127,7 @@ void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t* data, uint uint8_t packSize = msgBytes + addrBytes + (isAdressed ? addrBytes : 0) + min(1, len) + crcBytes; uint8_t msgType = - (IR_MSG_BACK << 5) | (isAdressed << 4U) | ((packSize - crcBytes) & (IR_MASK_MSG_INFO >> 1)); + (IR_MSG_BACK << 5) | (isAdressed << 4U) | ((packSize) & (IR_MASK_MSG_INFO >> 1)); // формирование массива // msg_type diff --git a/IR_config.h b/IR_config.h index 97ee536..19fafa4 100644 --- a/IR_config.h +++ b/IR_config.h @@ -146,9 +146,9 @@ public: }; struct ErrorsStruct { - uint8_t lowSignal; - uint8_t highSignal; - uint8_t other; + uint8_t lowSignal = 0; + uint8_t highSignal= 0; + uint8_t other= 0; void reset() { lowSignal = 0; @@ -160,11 +160,11 @@ public: }; struct PackInfo { - uint8_t* ptr; - uint8_t packSize; - uint16_t crc; + uint8_t* buffer = nullptr; + uint8_t packSize = 0; + uint16_t crc= 0; ErrorsStruct err; - uint16_t rTime; + uint16_t rTime = 0; }; protected: diff --git a/PacketTypes.h b/PacketTypes.h new file mode 100644 index 0000000..b75693a --- /dev/null +++ b/PacketTypes.h @@ -0,0 +1,59 @@ +#pragma once +#include "IR_config.h" + +class IOffsets { +public: + uint8_t msgOffset; + uint8_t addressFromOffset; + uint8_t addressToOffset; + uint8_t DataOffset; +}; + +class IPackInfo { +public: + IR_FOX::PackInfo* packInfo; +}; + +class IBaseEmptyPack : virtual public IOffsets, virtual public IPackInfo {}; + +class IEmptyPack : virtual protected IBaseEmptyPack { + bool isAvailable; + +public: + IEmptyPack(IR_FOX::PackInfo* _packInfo) { packInfo = _packInfo; } + virtual bool available() { if (isAvailable) { isAvailable = false; return true; } else { return false; } }; + virtual uint8_t getMsgInfo() { return packInfo->buffer[0] & IR_MASK_MSG_INFO; }; + virtual uint8_t getMsgType() { return (packInfo->buffer[0] >> 5) & IR_MASK_MSG_TYPE; }; + virtual uint8_t getMsgRAW() { return packInfo->buffer[0]; }; + virtual uint16_t getErrorCount() { return packInfo->err.all(); }; + virtual uint8_t getErrorLowSignal() { return packInfo->err.lowSignal; }; + virtual uint8_t getErrorHighSignal() { return packInfo->err.highSignal; }; + virtual uint8_t getErrorOther() { return packInfo->err.other; }; + virtual uint16_t getTunerTime() { return packInfo->rTime; }; +}; + +class IHasAddresFrom : virtual protected IBaseEmptyPack { + virtual uint16_t getAddrFrom() { return packInfo->buffer[addressFromOffset] | packInfo->buffer[addressFromOffset + 1]; }; +}; + +class IHasAddresTo : virtual protected IBaseEmptyPack { + virtual uint16_t getAddrTo() { return packInfo->buffer[addressToOffset] | packInfo->buffer[addressToOffset + 1]; }; +}; + +class IHasAddresData : virtual protected IBaseEmptyPack { + virtual uint8_t getDataSize() { return /* packInfo->buffer[packInfo->packSize-2] */0; };//TODO: + virtual uint8_t* getDataPrt() { return packInfo->buffer + DataOffset; }; + virtual uint8_t getDataRawSize() { return packInfo->packSize; }; + virtual uint8_t* getDataRawPtr() { return packInfo->buffer; }; +}; + + + +class Data : + virtual public IEmptyPack, + virtual public IHasAddresFrom { +public: + Data(IR_FOX::PackInfo* packInfo) : IEmptyPack(packInfo) { + msgOffset = 0; + } +}; \ No newline at end of file From 1dc702f05da0ad73a3a70091d57a1ac2dfd0f453 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Mon, 26 Feb 2024 11:38:35 +0300 Subject: [PATCH 44/51] refactor working --- IR-Protocol.ino | 86 +++++++++++++++++++++++------------------------ IR_Decoder.h | 28 +++------------ IR_DecoderRaw.cpp | 6 ++-- IR_config.h | 82 ++++++++++++++++++++++---------------------- PacketTypes.h | 47 ++++++++++++++++++++------ 5 files changed, 128 insertions(+), 121 deletions(-) diff --git a/IR-Protocol.ino b/IR-Protocol.ino index bc499f5..1897beb 100644 --- a/IR-Protocol.ino +++ b/IR-Protocol.ino @@ -230,58 +230,56 @@ void status(IR_Decoder& dec) { - // IR_DecoderRaw::AnyData* infoArr [] = { &dec.gotData, &dec.gotBackData }; - // for (auto&& obj : infoArr) { - // if (obj->available()) { - // String str; - // if (obj->getDataPrt()[1]) { - // str += ("Data on pin "); str += (dec.isrPin); str += "\n"; + if (dec.gotData.available()) { + String str; + if (/* dec.gotData.getDataPrt()[1] */1) { + str += ("Data on pin "); str += (dec.isrPin); str += "\n"; - // uint8_t msg = obj->getMsgRAW(); - // str += (" MSG: "); - // for (size_t i = 0; i < 8; i++) { - // if (i == 3) str += " "; - // str += (msg >> (7 - i)) & 1U; - // } + uint8_t msg = dec.gotData.getMsgRAW(); + str += (" MSG: "); + for (size_t i = 0; i < 8; i++) { + if (i == 3) str += " "; + str += (msg >> (7 - i)) & 1U; + } - // str += "\n"; + str += "\n"; - // str += (" DATA SIZE: "); str += (obj->getDataSize()); str += "\n"; - // str += (" ADDRESS FROM: "); str += (obj->getAddrFrom()); str += "\n"; - // str += (" ADDRESS TO: "); str += (obj->getAddrTo()); str += "\n"; - // // str += (" CRC PACK: "); str += (obj->getCrcIN()); str += "\n"; - // // str += (" CRC CALC: "); str += (obj->getCrcCALC()); str += "\n"; - // str += "\n"; + str += (" DATA SIZE: "); str += (dec.gotData.getDataSize()); str += "\n"; + str += (" ADDRESS FROM: "); str += (dec.gotData.getAddrFrom()); str += "\n"; + str += (" ADDRESS TO: "); str += (dec.gotData.getAddrTo()); str += "\n"; + // str += (" CRC PACK: "); str += (dec.gotData.getCrcIN()); str += "\n"; + // str += (" CRC CALC: "); str += (dec.gotData.getCrcCALC()); str += "\n"; + str += "\n"; - // for (size_t i = 0; i < obj->getDataSize(); i++) { - // switch (i) { - // // case 0: - // // str += (" ADDR: "); - // // break; - // // case 1: - // // str += (" CMD: "); - // // break; + for (size_t i = 0; i < min(10, dec.gotData.getDataSize()); i++) { + switch (i) { + // case 0: + // str += (" ADDR: "); + // break; + // case 1: + // str += (" CMD: "); + // break; - // default: - // str += (" Data["); str += (i); str += ("]: "); - // break; - // } - // str += (obj->getDataPrt()[i]); str += "\n"; - // } + default: + str += (" Data["); str += (i); str += ("]: "); + break; + } + str += (dec.gotData.getDataPrt()[i]); str += "\n"; + } - // str += ("\n*******ErrAll: "); str += (obj->getErrorCount()); str += "\n"; - // str += ("**ErrDistance: "); str += ((int)(obj->getErrorHighSignal() - obj->getErrorLowSignal())); str += "\n"; + str += ("\n*******ErrAll: "); str += (dec.gotData.getErrorCount()); str += "\n"; + str += ("**ErrDistance: "); str += ((int)(dec.gotData.getErrorHighSignal() - dec.gotData.getErrorLowSignal())); str += "\n"; - // str += "\n"; - // } else { - // str += ("SELF"); str += "\n"; - // str += "\n"; - // } - // obj->resetAvailable(); - // Serial.write(str.c_str()); - // } - // } + str += "\n"; + } else { + str += ("SELF"); str += "\n"; + str += "\n"; + } + // obj->resetAvailable(); + Serial.write(str.c_str()); + } + } diff --git a/IR_Decoder.h b/IR_Decoder.h index 4859f02..1de1d0e 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -4,11 +4,9 @@ class IR_Decoder : public IR_DecoderRaw { public: - IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : - IR_DecoderRaw(isrPin, addr, encPair), - gotData(Data(&packInfo)) { + IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : IR_DecoderRaw(isrPin, addr, encPair) { } - + Data gotData; void tick() { @@ -16,9 +14,9 @@ public: if (available()) { Serial.println("PARSING RAW DATA"); - switch (packInfo.buffer[0] & IR_MASK_MSG_TYPE) { + switch (packInfo.buffer[0] >> 5 & IR_MASK_MSG_TYPE) { case IR_MSG_DATA_NOACCEPT: - + gotData.set(&packInfo); break; case IR_MSG_DATA_ACCEPT: break; @@ -34,28 +32,10 @@ public: default: break; } - } } - - }; - - - - - - - - - - - - - - - // class IDataPack : protected IR_FOX { // friend IR_Decoder; // public: diff --git a/IR_DecoderRaw.cpp b/IR_DecoderRaw.cpp index 5849f22..d82a40e 100644 --- a/IR_DecoderRaw.cpp +++ b/IR_DecoderRaw.cpp @@ -96,6 +96,7 @@ void IR_DecoderRaw::tick() { // Serial.print(" SUB: "); Serial.println(currentFront.time - prevRise); #endif isRecive = true; + isWrongPack = false; } } @@ -326,6 +327,7 @@ void IR_DecoderRaw::writeToBuffer(bool bit) { #ifdef IRDEBUG_INFO Serial.print("****************"); #endif + isRecive = false; }; }//**************************************************************************************************// @@ -343,7 +345,7 @@ void IR_DecoderRaw::writeToBuffer(bool bit) { if (i_dataBuffer == ((msgBytes)*bitPerByte)) { Serial.print(" -> "); Serial.print(dataBuffer[0] & IR_MASK_MSG_INFO); Serial.print(" ->"); } if (i_dataBuffer == ((msgBytes + addrBytes) * bitPerByte)) { Serial.print(" |"); } if (i_dataBuffer == ((msgBytes + addrBytes + addrBytes) * bitPerByte)) { Serial.print(" ->"); } - if (i_dataBuffer == ((dataBuffer[0] & IR_MASK_MSG_INFO) * bitPerByte)) { Serial.print(" <-"); } + if (i_dataBuffer == (((dataBuffer[0] & IR_MASK_MSG_INFO)-2) * bitPerByte)) { Serial.print(" <-"); } } #endif @@ -353,7 +355,7 @@ void IR_DecoderRaw::writeToBuffer(bool bit) { Serial.print(" ["); Serial.print(packSize); Serial.print("] "); } - if (packSize && (i_dataBuffer == packSize*bitPerByte)) { // Конец + if (packSize && (i_dataBuffer == packSize * bitPerByte)) { // Конец Serial.print(" END DATA "); packInfo.buffer = dataBuffer; diff --git a/IR_config.h b/IR_config.h index 19fafa4..f2a315c 100644 --- a/IR_config.h +++ b/IR_config.h @@ -48,55 +48,55 @@ msg type: #define IR_MSG_ 5U // | 101..... | = ?? #define IR_MSG_DATA_NOACCEPT 6U // | 110..... | = данные, не требующие подтверждения #define IR_MSG_DATA_ACCEPT 7U // | 111..... | = данные требующие подтверждения -/*   // ---------- + /*   // ---------- -/```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\ -                                                                                                                       -{``````````} [````````````````````````] [``````````````]      {``````````} [````````````````````````] [````````````````````````] [``````````````] -{ msg type } [ addr_from uint16_t ] [ CRC Bytes ]      { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] -{..........} [........................] [..............]      {..........} [........................] [........................] [..............] -                                                                                                                                                  -{ 001..... } [addr_from_H][addr_from_L] [ crc1 ][ crc2 ]      { 010..... } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [ crc1 ][ crc2 ] -|     0            1           2           3       4          |     0            1           2              3           4           5       6     -\__________________________________________/       |          \_____________________________________________________________________/       |     -|                                                  |          |                                                                             |     -\__________________________________________________/          \_____________________________________________________________________________/     + /```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\ +                                                                                                                        + {``````````} [````````````````````````] [``````````````]      {``````````} [````````````````````````] [````````````````````````] [``````````````] + { msg type } [ addr_from uint16_t ] [ CRC Bytes ]      { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] + {..........} [........................] [..............]      {..........} [........................] [........................] [..............] +                                                                                                                                                   + { 001..... } [addr_from_H][addr_from_L] [ crc1 ][ crc2 ]      { 010..... } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [ crc1 ][ crc2 ] + |     0            1           2           3       4          |     0            1           2              3           4           5       6     + \__________________________________________/       |          \_____________________________________________________________________/       |     + |                                                  |          |                                                                             |     + \__________________________________________________/          \_____________________________________________________________________________/     -/`````````````````````` Задний сигнал машинки без адресации ``````````````````````\        В (IR_MASK_MSG_INFO & 15U) содержится количество байт -                                                                                           сквозных команд, максимум 15 -{``````````} [````````````````````````] [````````````````````````] [``````````````]        Если полезных байт информации нет, отправляется один -{ msg type } [ addr_from uint16_t ] [====== data bytes ======] [ CRC Bytes ]        байт нулей -{..........} [........................] [........................] [..............]         -                                                                                            -{ 0000xxxx } [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]         -|     0           1            2            3                         |       |             -\_____________________________________________________________________/       |             -|                                                                             |             -\_____________________________________________________________________________/             + /`````````````````````` Задний сигнал машинки без адресации ``````````````````````\        В (IR_MASK_MSG_INFO & 15U) содержится количество байт +                                                                                            сквозных команд, максимум 15 + {``````````} [````````````````````````] [````````````````````````] [``````````````]        Если полезных байт информации нет, отправляется один + { msg type } [ addr_from uint16_t ] [====== data bytes ======] [ CRC Bytes ]        байт нулей + {..........} [........................] [........................] [..............]         +                                                                                             + { 0000xxxx } [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]         + |     0           1            2            3                         |       |             + \_____________________________________________________________________/       |             + |                                                                             |             + \_____________________________________________________________________________/             -/```````````````````````````````````` Задний сигнал машинки с адресацией ````````````````````````````````````\  -                                                                                     -{``````````} [````````````````````````] [````````````````````````] [````````````````````````] [``````````````]  -{ msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]  -{..........} [........................] [........................] [........................] [..............]  -                                                                                                                -{ 0001xxxx } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]  -|     0           1            2              3           4            5                         |       |      -\________________________________________________________________________________________________/       |      -|                                                                                                        |      -\________________________________________________________________________________________________________/      + /```````````````````````````````````` Задний сигнал машинки с адресацией ````````````````````````````````````\  +                                                                                      + {``````````} [````````````````````````] [````````````````````````] [````````````````````````] [``````````````]  + { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]  + {..........} [........................] [........................] [........................] [..............]  +                                                                                                                 + { 0001xxxx } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]  + |     0           1            2              3           4            5                         |       |      + \________________________________________________________________________________________________/       |      + |                                                                                                        |      + \________________________________________________________________________________________________________/      -*/ + */ #define IR_MASK_MSG_TYPE 0b00000111 #define IR_MASK_MSG_INFO 0b00011111 -/* -/////////////////////////////////////////////////////////////////////////////////////*/ + /* + /////////////////////////////////////////////////////////////////////////////////////*/ typedef uint16_t crc_t; #define bytePerPack 16 // колличество байтов в пакете @@ -147,8 +147,8 @@ public: struct ErrorsStruct { uint8_t lowSignal = 0; - uint8_t highSignal= 0; - uint8_t other= 0; + uint8_t highSignal = 0; + uint8_t other = 0; void reset() { lowSignal = 0; @@ -162,7 +162,7 @@ public: struct PackInfo { uint8_t* buffer = nullptr; uint8_t packSize = 0; - uint16_t crc= 0; + uint16_t crc = 0; ErrorsStruct err; uint16_t rTime = 0; }; @@ -170,7 +170,7 @@ public: protected: ErrorsStruct errors; - void checkaddressRuleApply(uint16_t address, uint16_t id, bool &flag) { + void checkaddressRuleApply(uint16_t address, uint16_t id, bool& flag) { flag = false; flag |= id == 0; flag |= address == id; diff --git a/PacketTypes.h b/PacketTypes.h index b75693a..c2ec819 100644 --- a/PacketTypes.h +++ b/PacketTypes.h @@ -2,7 +2,7 @@ #include "IR_config.h" class IOffsets { -public: +protected: uint8_t msgOffset; uint8_t addressFromOffset; uint8_t addressToOffset; @@ -14,14 +14,34 @@ public: IR_FOX::PackInfo* packInfo; }; -class IBaseEmptyPack : virtual public IOffsets, virtual public IPackInfo {}; +class IBaseEmptyPack : virtual public IOffsets, virtual public IPackInfo { +}; +class IR_Decoder; class IEmptyPack : virtual protected IBaseEmptyPack { + friend IR_Decoder; bool isAvailable; +protected: + virtual void set(IR_FOX::PackInfo *packInfo) { + IBaseEmptyPack::IPackInfo::packInfo = packInfo; + Serial.print(" SET "); + + Serial.print("\n*******ErrAll: "); Serial.println(packInfo->err.all()); + Serial.print("**ErrDistance: "); Serial.println((int)(packInfo->err.highSignal - packInfo->err.lowSignal)); + + isAvailable = true; + } + public: - IEmptyPack(IR_FOX::PackInfo* _packInfo) { packInfo = _packInfo; } - virtual bool available() { if (isAvailable) { isAvailable = false; return true; } else { return false; } }; + virtual bool available() { + if (isAvailable) { + isAvailable = false; + return true; + } else { + return false; + } + }; virtual uint8_t getMsgInfo() { return packInfo->buffer[0] & IR_MASK_MSG_INFO; }; virtual uint8_t getMsgType() { return (packInfo->buffer[0] >> 5) & IR_MASK_MSG_TYPE; }; virtual uint8_t getMsgRAW() { return packInfo->buffer[0]; }; @@ -33,27 +53,34 @@ public: }; class IHasAddresFrom : virtual protected IBaseEmptyPack { - virtual uint16_t getAddrFrom() { return packInfo->buffer[addressFromOffset] | packInfo->buffer[addressFromOffset + 1]; }; +public: + virtual uint16_t getAddrFrom() { return (packInfo->buffer[addressFromOffset]<<8) | packInfo->buffer[addressFromOffset + 1]; }; }; class IHasAddresTo : virtual protected IBaseEmptyPack { - virtual uint16_t getAddrTo() { return packInfo->buffer[addressToOffset] | packInfo->buffer[addressToOffset + 1]; }; +public: + virtual uint16_t getAddrTo() { return (packInfo->buffer[addressToOffset]<<8) | packInfo->buffer[addressToOffset + 1]; }; }; class IHasAddresData : virtual protected IBaseEmptyPack { - virtual uint8_t getDataSize() { return /* packInfo->buffer[packInfo->packSize-2] */0; };//TODO: +public: + virtual uint8_t getDataSize() { return &(packInfo->buffer[packInfo->packSize - 2]) - &(packInfo->buffer[DataOffset]); }; // TODO: virtual uint8_t* getDataPrt() { return packInfo->buffer + DataOffset; }; virtual uint8_t getDataRawSize() { return packInfo->packSize; }; virtual uint8_t* getDataRawPtr() { return packInfo->buffer; }; }; - class Data : virtual public IEmptyPack, - virtual public IHasAddresFrom { + virtual public IHasAddresFrom, + virtual public IHasAddresTo, + virtual public IHasAddresData { public: - Data(IR_FOX::PackInfo* packInfo) : IEmptyPack(packInfo) { + Data() { msgOffset = 0; + addressFromOffset = 1; + addressToOffset = 3; + DataOffset = 5; } }; \ No newline at end of file From 1f62eb8c0a45590aa4b5447d5a0a01fd31246b8e Mon Sep 17 00:00:00 2001 From: DashyFox Date: Mon, 26 Feb 2024 15:42:27 +0300 Subject: [PATCH 45/51] fix forever loop ? --- IR_DecoderRaw.cpp | 23 ++++++++++++++--------- IR_DecoderRaw.h | 15 ++++++++------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/IR_DecoderRaw.cpp b/IR_DecoderRaw.cpp index d82a40e..63c1659 100644 --- a/IR_DecoderRaw.cpp +++ b/IR_DecoderRaw.cpp @@ -46,7 +46,7 @@ void IR_DecoderRaw::isr() { void IR_DecoderRaw::firstRX() { #ifdef IRDEBUG_INFO - Serial.print("\n>"); + Serial.print("\nRX>"); #endif errors.reset(); @@ -67,8 +67,9 @@ void IR_DecoderRaw::firstRX() { memset(dataBuffer, 0x00, dataByteSizeMax); } -void IR_DecoderRaw::listenEnd() { +void IR_DecoderRaw::listenStart() { if (isRecive && ((micros() - prevRise) > IR_timeout * 2)) { + Serial.print("\nlis>"); isRecive = false; firstRX(); } @@ -77,10 +78,11 @@ void IR_DecoderRaw::listenEnd() { void IR_DecoderRaw::tick() { FrontStorage currentFront; noInterrupts(); - listenEnd(); + listenStart(); if (firstUnHandledFront == nullptr) { interrupts(); return; } //Если данных нет - ничего не делаем currentFront = *((FrontStorage*)firstUnHandledFront); //найти следующий необработанный фронт/спад interrupts(); + if (currentFront.next == nullptr) { isRecive = false; return; } //////////////////////////////////////////////////////////////////////////////////////////////////////////// if (currentFront.time > prevRise && currentFront.time - prevRise > IR_timeout * 2 && !isRecive) { // первый @@ -97,11 +99,11 @@ void IR_DecoderRaw::tick() { #endif isRecive = true; isWrongPack = false; - } + } } if (preambFrontCounter > 0) { // в преамбуле - uint32_t risePeriod = currentFront.time - prevRise; + risePeriod = currentFront.time - prevRise; if (currentFront.dir && risePeriod < IR_timeout) { // __/``` ↑ и мы в внутри пакета if (risePeriod < riseTimeMin << 1) { // fix рваной единицы @@ -276,7 +278,10 @@ void IR_DecoderRaw::writeToBuffer(bool bit) { #endif isBufferOverflow = true; } - if (isBufferOverflow || isPreamb || isWrongPack) return; + if (isBufferOverflow || isPreamb || isWrongPack) { + isRecive = false; + return; + } // Переключение флага, data или syncBit if (bufBitPos == nextControlBit) { @@ -327,7 +332,7 @@ void IR_DecoderRaw::writeToBuffer(bool bit) { #ifdef IRDEBUG_INFO Serial.print("****************"); #endif - isRecive = false; + }; }//**************************************************************************************************// @@ -345,11 +350,11 @@ void IR_DecoderRaw::writeToBuffer(bool bit) { if (i_dataBuffer == ((msgBytes)*bitPerByte)) { Serial.print(" -> "); Serial.print(dataBuffer[0] & IR_MASK_MSG_INFO); Serial.print(" ->"); } if (i_dataBuffer == ((msgBytes + addrBytes) * bitPerByte)) { Serial.print(" |"); } if (i_dataBuffer == ((msgBytes + addrBytes + addrBytes) * bitPerByte)) { Serial.print(" ->"); } - if (i_dataBuffer == (((dataBuffer[0] & IR_MASK_MSG_INFO)-2) * bitPerByte)) { Serial.print(" <-"); } + if (i_dataBuffer == (((dataBuffer[0] & IR_MASK_MSG_INFO) - 2) * bitPerByte)) { Serial.print(" <-"); } } #endif - if (!isAvailable && isData) { + if (!isAvailable && isData && !isWrongPack) { if (i_dataBuffer == 8 * msgBytes) {// Ппервый байт packSize = dataBuffer[0] & IR_MASK_MSG_INFO; Serial.print(" ["); Serial.print(packSize); Serial.print("] "); diff --git a/IR_DecoderRaw.h b/IR_DecoderRaw.h index 515d9fe..93a25a6 100644 --- a/IR_DecoderRaw.h +++ b/IR_DecoderRaw.h @@ -23,7 +23,7 @@ class IR_Encoder; -class IR_DecoderRaw : public IR_FOX { +class IR_DecoderRaw : virtual public IR_FOX { friend IR_Encoder; public: const uint8_t isrPin; // Пин прерывания @@ -37,17 +37,17 @@ public: void isr(); // Функция прерывания void tick(); // Обработка приёмника, необходима для работы - bool available() { if(isAvailable) {isAvailable = false; return true;} else { return false;}}; + bool available() { if (isAvailable) { isAvailable = false; return true; } else { return false; } }; bool isOverflow() { return isBufferOverflow; }; // Буффер переполнился bool isReciving() { return isBufferOverflow; }; // Возвращает true, если происходит приём пакета ////////////////////////////////////////////////////////////////////////// protected: PackInfo packInfo; + uint16_t id; private: ErrorsStruct errors; - uint16_t id; - bool isAvailable = false; + bool isAvailable = false; uint16_t packSize; uint16_t crcValue; IR_Encoder* encoder; // Указатель на парный передатчик @@ -71,14 +71,15 @@ private: volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов //////////////////////////////////////////////////////////////////////// - uint8_t dataBuffer[dataByteSizeMax]{0}; // Буффер данных + uint8_t dataBuffer[dataByteSizeMax] { 0 }; // Буффер данных uint32_t prevRise, prevPrevRise, prevFall, prevPrevFall; // Время предыдущих фронтов/спадов + uint32_t risePeriod; uint16_t errorCounter = 0; // Счётчик ошибок int8_t preambFrontCounter = 0; // Счётчик __/``` ↑ преамбулы int16_t bufBitPos = 0; // Позиция для записи бита в буффер private: - void listenEnd(); // @brief Слушатель для работы isReciving() + void listenStart(); // @brief Слушатель для работы isReciving() /// @brief Проверка CRC. Проверяет len байт со значением crc, пришедшим в пакете /// @param len Длина в байтах проверяемых данных @@ -98,7 +99,7 @@ private: void writeToBuffer(bool); //////////////////////////////////////////////////////////////////////// - + void firstRX(); /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных /// @brief Целочисленное деление с округлением вверх From 4d92acf15bc8d32c5e26e3d0cf4a2f9d7612c12e Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 27 Feb 2024 10:28:20 +0300 Subject: [PATCH 46/51] non virtual --- IR-Protocol.ino | 55 ++++++- IR_Decoder.h | 208 ++------------------------ IR_DecoderRaw.cpp | 8 +- IR_Encoder.cpp | 2 +- IR_config.h | 81 +++++----- PacketTypes.h | 368 +++++++++++++++++++++++++++++++++++++--------- 6 files changed, 411 insertions(+), 311 deletions(-) diff --git a/IR-Protocol.ino b/IR-Protocol.ino index 1897beb..943ebf1 100644 --- a/IR-Protocol.ino +++ b/IR-Protocol.ino @@ -116,7 +116,7 @@ Timer t1(730, millis, []() { break; case 30: - encForward.sendBackTo(targetAddr, data0, sizeof(data0)); + encForward.sendBackTo(targetAddr); break; case 31: encForward.sendBackTo(targetAddr, data1, sizeof(data1)); @@ -227,9 +227,6 @@ void loop() { //test void status(IR_Decoder& dec) { - - - if (dec.gotData.available()) { String str; if (/* dec.gotData.getDataPrt()[1] */1) { @@ -279,6 +276,56 @@ void status(IR_Decoder& dec) { // obj->resetAvailable(); Serial.write(str.c_str()); } + + if (dec.gotBackData.available()) { + String str; + if (/* dec.gotData.getDataPrt()[1] */1) { + str += ("BackData on pin "); str += (dec.isrPin); str += "\n"; + + uint8_t msg = dec.gotBackData.getMsgRAW(); + str += (" MSG: "); + for (size_t i = 0; i < 8; i++) { + if (i == 3) str += " "; + str += (msg >> (7 - i)) & 1U; + } + + str += "\n"; + + str += (" DATA SIZE: "); str += (dec.gotBackData.getDataSize()); str += "\n"; + str += (" ADDRESS FROM: "); str += (dec.gotBackData.getAddrFrom()); str += "\n"; + // str += (" ADDRESS TO: "); str += (dec.gotBackData.getAddrTo()); str += "\n"; + // str += (" CRC PACK: "); str += (dec.gotBackData.getCrcIN()); str += "\n"; + // str += (" CRC CALC: "); str += (dec.gotBackData.getCrcCALC()); str += "\n"; + str += "\n"; + + for (size_t i = 0; i < min(10, dec.gotBackData.getDataSize()); i++) { + switch (i) { + // case 0: + // str += (" ADDR: "); + // break; + // case 1: + // str += (" CMD: "); + // break; + + default: + str += (" Data["); str += (i); str += ("]: "); + break; + } + str += (dec.gotBackData.getDataPrt()[i]); str += "\n"; + } + + + str += ("\n*******ErrAll: "); str += (dec.gotBackData.getErrorCount()); str += "\n"; + str += ("**ErrDistance: "); str += ((int)(dec.gotBackData.getErrorHighSignal() - dec.gotBackData.getErrorLowSignal())); str += "\n"; + + str += "\n"; + } else { + str += ("SELF"); str += "\n"; + str += "\n"; + } + // obj->resetAvailable(); + Serial.write(str.c_str()); + } } diff --git a/IR_Decoder.h b/IR_Decoder.h index 1de1d0e..1370d12 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -4,219 +4,43 @@ class IR_Decoder : public IR_DecoderRaw { public: + PacketTypes::Data gotData; + PacketTypes::DataBack gotBackData; + PacketTypes::Accept gotAccept; + PacketTypes::Request gotRequest; + IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : IR_DecoderRaw(isrPin, addr, encPair) { } - Data gotData; - void tick() { IR_DecoderRaw::tick(); if (available()) { + #ifdef IRDEBUG_INFO Serial.println("PARSING RAW DATA"); - + #endif + bool isNeenAccept = false; switch (packInfo.buffer[0] >> 5 & IR_MASK_MSG_TYPE) { - case IR_MSG_DATA_NOACCEPT: - gotData.set(&packInfo); - break; case IR_MSG_DATA_ACCEPT: + isNeenAccept = true; + case IR_MSG_DATA_NOACCEPT: + gotData.set(&packInfo, id); break; case IR_MSG_BACK: - break; case IR_MSG_BACK_TO: + gotBackData.set(&packInfo, id); break; case IR_MSG_REQUEST: + gotRequest.set(&packInfo, id); break; case IR_MSG_ACCEPT: + gotAccept.set(&packInfo, id); break; default: break; } + + } } }; - -// class IDataPack : protected IR_FOX { -// friend IR_Decoder; -// public: -// IDataPack(IR_Decoder* dec) : dec(dec) {}; - -// public: -// bool available() { if (isAvailable) { isAvailable = false; return true; } else { return isAvailable; }; }; -// virtual uint8_t getMsgInfo() { return msgPtr[0] & IR_MASK_MSG_INFO; }; -// virtual uint8_t getMsgType() { return (msgPtr[0] >> 5) & IR_MASK_MSG_TYPE; }; -// virtual uint8_t getMsgRAW() { return msgPtr[0]; }; -// virtual uint16_t getErrorCount() { return err.all(); }; -// virtual uint8_t getErrorLowSignal() { return err.lowSignal; }; -// virtual uint8_t getErrorHighSignal() { return err.highSignal; }; -// virtual uint8_t getErrorOther() { return err.other; }; -// // uint16_t getCrcIN() { return crcPtr[0] << 8 | crcPtr[1]; }; -// // uint16_t getCrcCALC() { return crcCalcVal; }; -// virtual uint16_t getTunerTime() { return bitPeriod; }; -// void resetAvailable() { isAvailable = false; }; - -// protected: -// inline static uint8_t data[dataByteSizeMax] { 0 }; - -// inline static uint8_t* msgPtr; -// inline static uint8_t* addrFromPtr; -// inline static uint8_t* addrToPtr; -// inline static uint8_t* dataPtr; -// inline static uint8_t* crcPtr; - -// inline static ErrorsStruct err; -// inline static uint8_t packRawSize; -// inline static uint16_t bitPeriod; -// inline static uint16_t crcCalcVal; - -// IR_Decoder* dec; -// bool isAvailable = false; -// virtual bool checkAddress(PackOutInfo* packInfo) { -// bool ret; -// uint8_t targetAddrOffset = packInfo->offsets.addrToOffset; -// uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); -// checkaddressRuleApply(address, dec->id, ret); -// return ret; -// }; -// virtual void onPackAddressCorrect(PackOutInfo* packInfo) { -// memset(IDataPack::data, 0, dataByteSizeMax); -// memcpy(data, packInfo->ptr, min(packInfo->packSize, dataByteSizeMax)); -// err = packInfo->err; -// bitPeriod = packInfo->rTime; -// crcCalcVal = packInfo->crc; -// packRawSize = packInfo->packSize; - -// msgPtr = (data + packInfo->offsets.msgOffset); -// addrFromPtr = (data + packInfo->offsets.addrFromOffset); -// addrToPtr = (data + packInfo->offsets.addrToOffset); -// dataPtr = (data + packInfo->offsets.dataOffset); -// crcPtr = (data + packInfo->offsets.crcOffset); -// } - -// virtual void onPackAddressIncorrect(PackOutInfo* packInfo) {} -// virtual void afterSet() {} - -// void set(PackOutInfo packInfo, bool isNeedAddressCheck) { -// isAvailable = false; -// if (!isNeedAddressCheck || checkAddress(&packInfo)) { -// onPackAddressCorrect(&packInfo); -// #ifdef IRDEBUG_INFO -// Serial.println(" OK "); -// #endif -// isAvailable = true; -// } else { -// onPackAddressIncorrect(&packInfo); -// #ifdef IRDEBUG_INFO -// Serial.println(" NOT MY "); -// #endif -// } -// afterSet(); -// } -// }; - -// public: -// /////////////////////////////////////////////////////////////////////////////////////////////////////////// -// class HasAddrFrom { -// public: -// virtual uint16_t getAddrFrom() { return IDataPack::addrFromPtr[0] << 8 | IDataPack::addrFromPtr[1]; }; -// }; - -// class HasAddrTo { -// public: -// virtual uint16_t getAddrTo() { return IDataPack::addrToPtr[0] << 8 | IDataPack::addrToPtr[1]; }; -// }; - -// class HasData { -// public: -// virtual uint8_t getDataSize() { return (uint8_t)(IDataPack::crcPtr - IDataPack::dataPtr); }; -// virtual uint8_t* getDataPrt() { return IDataPack::dataPtr; }; -// virtual uint8_t getDataRawSize() { return IDataPack::packRawSize; }; -// virtual uint8_t* getDataRawPtr() { return IDataPack::data; }; -// }; -// class IAcceptable { -// public: -// virtual bool isNeedAccept(); -// }; -// class AnyData : public IDataPack, public HasAddrFrom, public HasAddrTo, public HasData { -// using IDataPack::IDataPack; -// }; -// /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// class Data : public AnyData, public IAcceptable { -// using AnyData::AnyData; -// public: -// bool isNeedAccept() override { return ((IDataPack::msgPtr[0] >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; -// private: -// void afterSet() override { -// if (Data::IDataPack::isAvailable && isNeedAccept()) { -// dec->addrWaitingSendgTo = getAddrFrom(); -// dec->startWaitingSendToTime = millis(); -// dec->isWaitingAcceptSend = true; -// Serial.print("\n Need to accept to "); -// Serial.println(dec->addrWaitingSendgTo); -// } -// } -// }; - -// class BackData : public AnyData { -// using AnyData::AnyData; -// public: -// bool isAddressed() { return IDataPack::msgPtr[0] & 0b00010000; }; -// uint8_t getMsgInfo() { return IDataPack::msgPtr[0] & (IR_MASK_MSG_INFO >> 1); }; -// uint16_t getAddrTo() override { -// if (isAddressed()) { -// return IDataPack::addrToPtr[0] << 8 | IDataPack::addrToPtr[1]; -// } else { -// return IR_Broadcast; -// } -// }; -// }; - -// class Accept : public IDataPack, public HasAddrFrom { -// using IDataPack::IDataPack; -// public: - -// private: -// bool checkAddress(PackOutInfo* packInfo) override { -// bool ret; -// uint8_t targetAddrOffset = packInfo->offsets.addrFromOffset; -// uint16_t address = (packInfo->ptr[targetAddrOffset] << 8) | (packInfo->ptr[targetAddrOffset + 1]); -// ret = address == dec->addrWaitingFrom; -// return ret; -// } -// }; - -// class Request : public IDataPack, public HasAddrFrom, public HasAddrTo { -// using IDataPack::IDataPack; -// public: - -// private: -// // void afterSet() override { -// // if (isAvailable) { -// // dec->isWaitingAcceptSend = true; -// // dec->addrWaitingSendgTo = getAddrFrom(); -// // Serial.print("\n Need to accept to "); -// // Serial.println(dec->addrWaitingSendgTo); -// // } -// // } -// }; - -// class RawTune { -// friend IR_Decoder; -// public: -// bool available() { return isAvailable; }; -// uint16_t getTunerTime() { return bitPeriod; }; -// void resetAvailable() { isAvailable = false; }; -// protected: -// bool isAvailable; -// uint16_t bitPeriod; - -// void set(uint16_t time) { -// bitPeriod = time; -// isAvailable = true; -// } -// }; - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/IR_DecoderRaw.cpp b/IR_DecoderRaw.cpp index 63c1659..401da09 100644 --- a/IR_DecoderRaw.cpp +++ b/IR_DecoderRaw.cpp @@ -69,7 +69,7 @@ void IR_DecoderRaw::firstRX() { void IR_DecoderRaw::listenStart() { if (isRecive && ((micros() - prevRise) > IR_timeout * 2)) { - Serial.print("\nlis>"); + // Serial.print("\nlis>"); isRecive = false; firstRX(); } @@ -99,7 +99,7 @@ void IR_DecoderRaw::tick() { #endif isRecive = true; isWrongPack = false; - } + } } if (preambFrontCounter > 0) { // в преамбуле @@ -357,11 +357,15 @@ void IR_DecoderRaw::writeToBuffer(bool bit) { if (!isAvailable && isData && !isWrongPack) { if (i_dataBuffer == 8 * msgBytes) {// Ппервый байт packSize = dataBuffer[0] & IR_MASK_MSG_INFO; + #ifdef IRDEBUG_INFO Serial.print(" ["); Serial.print(packSize); Serial.print("] "); + #endif } if (packSize && (i_dataBuffer == packSize * bitPerByte)) { // Конец + #ifdef IRDEBUG_INFO Serial.print(" END DATA "); + #endif packInfo.buffer = dataBuffer; packInfo.crc = crcValue; diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 0848086..1737913 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -127,7 +127,7 @@ void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t* data, uint uint8_t packSize = msgBytes + addrBytes + (isAdressed ? addrBytes : 0) + min(1, len) + crcBytes; uint8_t msgType = - (IR_MSG_BACK << 5) | (isAdressed << 4U) | ((packSize) & (IR_MASK_MSG_INFO >> 1)); + ((isAdressed ? IR_MSG_BACK_TO : IR_MSG_BACK)<<5) | ((packSize) & (IR_MASK_MSG_INFO >> 1)); // формирование массива // msg_type diff --git a/IR_config.h b/IR_config.h index f2a315c..e3adc1d 100644 --- a/IR_config.h +++ b/IR_config.h @@ -48,55 +48,55 @@ msg type: #define IR_MSG_ 5U // | 101..... | = ?? #define IR_MSG_DATA_NOACCEPT 6U // | 110..... | = данные, не требующие подтверждения #define IR_MSG_DATA_ACCEPT 7U // | 111..... | = данные требующие подтверждения - /*   // ---------- +;/*   // ---------- - /```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\ -                                                                                                                        - {``````````} [````````````````````````] [``````````````]      {``````````} [````````````````````````] [````````````````````````] [``````````````] - { msg type } [ addr_from uint16_t ] [ CRC Bytes ]      { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] - {..........} [........................] [..............]      {..........} [........................] [........................] [..............] -                                                                                                                                                   - { 001..... } [addr_from_H][addr_from_L] [ crc1 ][ crc2 ]      { 010..... } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [ crc1 ][ crc2 ] - |     0            1           2           3       4          |     0            1           2              3           4           5       6     - \__________________________________________/       |          \_____________________________________________________________________/       |     - |                                                  |          |                                                                             |     - \__________________________________________________/          \_____________________________________________________________________________/     +/```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\ +                                                                                                                       +{``````````} [````````````````````````] [``````````````]      {``````````} [````````````````````````] [````````````````````````] [``````````````] +{ msg type } [ addr_from uint16_t ] [ CRC Bytes ]      { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] +{..........} [........................] [..............]      {..........} [........................] [........................] [..............] +                                                                                                                                                  +{ 001..... } [addr_from_H][addr_from_L] [ crc1 ][ crc2 ]      { 010..... } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [ crc1 ][ crc2 ] +|     0            1           2           3       4          |     0            1           2              3           4           5       6     +\__________________________________________/       |          \_____________________________________________________________________/       |     +|                                                  |          |                                                                             |     +\__________________________________________________/          \_____________________________________________________________________________/     - /`````````````````````` Задний сигнал машинки без адресации ``````````````````````\        В (IR_MASK_MSG_INFO & 15U) содержится количество байт -                                                                                            сквозных команд, максимум 15 - {``````````} [````````````````````````] [````````````````````````] [``````````````]        Если полезных байт информации нет, отправляется один - { msg type } [ addr_from uint16_t ] [====== data bytes ======] [ CRC Bytes ]        байт нулей - {..........} [........................] [........................] [..............]         -                                                                                             - { 0000xxxx } [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]         - |     0           1            2            3                         |       |             - \_____________________________________________________________________/       |             - |                                                                             |             - \_____________________________________________________________________________/             +/`````````````````````` Задний сигнал машинки без адресации ``````````````````````\        В (IR_MASK_MSG_INFO & 15U) содержится количество байт +                                                                                           сквозных команд, максимум 15 +{``````````} [````````````````````````] [````````````````````````] [``````````````]        Если полезных байт информации нет, отправляется один +{ msg type } [ addr_from uint16_t ] [====== data bytes ======] [ CRC Bytes ]        байт нулей +{..........} [........................] [........................] [..............]         +                                                                                            +{ 0000xxxx } [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]         +|     0           1            2            3                         |       |             +\_____________________________________________________________________/       |             +|                                                                             |             +\_____________________________________________________________________________/             - /```````````````````````````````````` Задний сигнал машинки с адресацией ````````````````````````````````````\  -                                                                                      - {``````````} [````````````````````````] [````````````````````````] [````````````````````````] [``````````````]  - { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]  - {..........} [........................] [........................] [........................] [..............]  -                                                                                                                 - { 0001xxxx } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]  - |     0           1            2              3           4            5                         |       |      - \________________________________________________________________________________________________/       |      - |                                                                                                        |      - \________________________________________________________________________________________________________/      +/```````````````````````````````````` Задний сигнал машинки с адресацией ````````````````````````````````````\  +                                                                                     +{``````````} [````````````````````````] [````````````````````````] [````````````````````````] [``````````````]  +{ msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]  +{..........} [........................] [........................] [........................] [..............]  +                                                                                                                +{ 0001xxxx } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]  +|     0           1            2              3           4            5                         |       |      +\________________________________________________________________________________________________/       |      +|                                                                                                        |      +\________________________________________________________________________________________________________/      - */ +*/ #define IR_MASK_MSG_TYPE 0b00000111 #define IR_MASK_MSG_INFO 0b00011111 - /* - /////////////////////////////////////////////////////////////////////////////////////*/ +/* +/////////////////////////////////////////////////////////////////////////////////////*/ typedef uint16_t crc_t; #define bytePerPack 16 // колличество байтов в пакете @@ -167,16 +167,15 @@ public: uint16_t rTime = 0; }; -protected: - ErrorsStruct errors; - - void checkaddressRuleApply(uint16_t address, uint16_t id, bool& flag) { + static void checkaddressRuleApply(uint16_t address, uint16_t id, bool& flag) { flag = false; flag |= id == 0; flag |= address == id; flag |= address >= IR_Broadcast; } +protected: + ErrorsStruct errors; uint8_t crc8(uint8_t* data, uint8_t start, uint8_t end, uint8_t poly) { //TODO: сделать возможность межбайтовой проверки uint8_t crc = 0xff; size_t i, j; diff --git a/PacketTypes.h b/PacketTypes.h index c2ec819..d5bbce2 100644 --- a/PacketTypes.h +++ b/PacketTypes.h @@ -1,86 +1,312 @@ #pragma once #include "IR_config.h" -class IOffsets { -protected: - uint8_t msgOffset; - uint8_t addressFromOffset; - uint8_t addressToOffset; - uint8_t DataOffset; -}; - -class IPackInfo { -public: - IR_FOX::PackInfo* packInfo; -}; - -class IBaseEmptyPack : virtual public IOffsets, virtual public IPackInfo { -}; - class IR_Decoder; -class IEmptyPack : virtual protected IBaseEmptyPack { - friend IR_Decoder; - bool isAvailable; +namespace PacketTypes { + class BasePack { + friend IR_Decoder; + protected: + bool isAvailable; + bool isRawAvailable; + bool isNeedAccept; -protected: - virtual void set(IR_FOX::PackInfo *packInfo) { - IBaseEmptyPack::IPackInfo::packInfo = packInfo; - Serial.print(" SET "); + uint8_t msgOffset; + uint8_t addressFromOffset; + uint8_t addressToOffset; + uint8_t DataOffset; - Serial.print("\n*******ErrAll: "); Serial.println(packInfo->err.all()); - Serial.print("**ErrDistance: "); Serial.println((int)(packInfo->err.highSignal - packInfo->err.lowSignal)); + IR_FOX::PackInfo* packInfo; + uint16_t id; - isAvailable = true; - } + virtual bool checkAddress(); + void set(IR_FOX::PackInfo* packInfo, uint16_t id) { + this->packInfo = packInfo; + this->id = id; -public: - virtual bool available() { - if (isAvailable) { - isAvailable = false; - return true; - } else { - return false; + if (isAvailable = checkAddress()) { + isAvailable = true; + isRawAvailable = true; + Serial.print(" OK "); + } else { + isRawAvailable = true; + Serial.print(" NOT-OK "); + } + } + + + static uint16_t _getAddrFrom(BasePack* obj) { + return (obj->packInfo->buffer[obj->addressFromOffset] << 8) | obj->packInfo->buffer[obj->addressFromOffset + 1]; + }; + static uint16_t _getAddrTo(BasePack* obj) { + return (obj->packInfo->buffer[obj->addressToOffset] << 8) | obj->packInfo->buffer[obj->addressToOffset + 1]; + }; + + static uint8_t _getDataSize(BasePack* obj) { + return obj->packInfo->packSize - crcBytes - obj->DataOffset; + }; + static uint8_t* _getDataPrt(BasePack* obj) { + return obj->packInfo->buffer + obj->DataOffset; + }; + static uint8_t _getDataRawSize(BasePack* obj) { + return obj->packInfo->packSize; + }; + static uint8_t* _getDataRawPtr(BasePack* obj) { + return obj->packInfo->buffer; + }; + + + public: + bool available() { if (isAvailable) { isAvailable = false; isRawAvailable = false; return true; } else { return false; } }; + bool availableRaw() { if (isRawAvailable) { isRawAvailable = false; return true; } else { return false; } }; + uint8_t getMsgInfo() { return packInfo->buffer[0] & IR_MASK_MSG_INFO; }; + uint8_t getMsgType() { return (packInfo->buffer[0] >> 5) & IR_MASK_MSG_TYPE; }; + uint8_t getMsgRAW() { return packInfo->buffer[0]; }; + uint16_t getErrorCount() { return packInfo->err.all(); }; + uint8_t getErrorLowSignal() { return packInfo->err.lowSignal; }; + uint8_t getErrorHighSignal() { return packInfo->err.highSignal; }; + uint8_t getErrorOther() { return packInfo->err.other; }; + uint16_t getTunerTime() { return packInfo->rTime; }; + }; + + + class Data : public BasePack { + public: + Data() { + msgOffset = 0; + addressFromOffset = 1; + addressToOffset = 3; + DataOffset = 5; + } + + uint16_t getAddrFrom() { return _getAddrFrom(this); }; + uint16_t getAddrTo() { return _getAddrTo(this); }; + + uint8_t getDataSize() { return _getDataSize(this); }; + uint8_t* getDataPrt() { return _getDataPrt(this); }; + uint8_t getDataRawSize() { return _getDataRawSize(this); }; + uint8_t* getDataRawPtr() { return _getDataRawPtr(this); }; + + private: + bool checkAddress() override { + bool ret; + IR_FOX::checkaddressRuleApply(getAddrTo(), this->id, ret); + return ret; } }; - virtual uint8_t getMsgInfo() { return packInfo->buffer[0] & IR_MASK_MSG_INFO; }; - virtual uint8_t getMsgType() { return (packInfo->buffer[0] >> 5) & IR_MASK_MSG_TYPE; }; - virtual uint8_t getMsgRAW() { return packInfo->buffer[0]; }; - virtual uint16_t getErrorCount() { return packInfo->err.all(); }; - virtual uint8_t getErrorLowSignal() { return packInfo->err.lowSignal; }; - virtual uint8_t getErrorHighSignal() { return packInfo->err.highSignal; }; - virtual uint8_t getErrorOther() { return packInfo->err.other; }; - virtual uint16_t getTunerTime() { return packInfo->rTime; }; -}; -class IHasAddresFrom : virtual protected IBaseEmptyPack { -public: - virtual uint16_t getAddrFrom() { return (packInfo->buffer[addressFromOffset]<<8) | packInfo->buffer[addressFromOffset + 1]; }; -}; + class DataBack : public BasePack { + public: + DataBack() { + msgOffset = 0; + addressFromOffset = 1; + addressToOffset = 3; + DataOffset = 3; + } -class IHasAddresTo : virtual protected IBaseEmptyPack { -public: - virtual uint16_t getAddrTo() { return (packInfo->buffer[addressToOffset]<<8) | packInfo->buffer[addressToOffset + 1]; }; -}; + uint16_t getAddrFrom() { return _getAddrFrom(this); }; + uint16_t getAddrTo() { return _getAddrTo(this); }; -class IHasAddresData : virtual protected IBaseEmptyPack { -public: - virtual uint8_t getDataSize() { return &(packInfo->buffer[packInfo->packSize - 2]) - &(packInfo->buffer[DataOffset]); }; // TODO: - virtual uint8_t* getDataPrt() { return packInfo->buffer + DataOffset; }; - virtual uint8_t getDataRawSize() { return packInfo->packSize; }; - virtual uint8_t* getDataRawPtr() { return packInfo->buffer; }; -}; + uint8_t getDataSize() { return _getDataSize(this); }; + uint8_t* getDataPrt() { return _getDataPrt(this); }; + uint8_t getDataRawSize() { return _getDataRawSize(this); }; + uint8_t* getDataRawPtr() { return _getDataRawPtr(this); }; + private: + bool checkAddress() override { + bool ret; + if (getMsgType() == IR_MSG_BACK_TO) { + DataOffset = 5; + IR_FOX::checkaddressRuleApply((packInfo->buffer[addressToOffset] << 8) | packInfo->buffer[addressToOffset + 1], this->id, ret); + } else { + DataOffset = 3; + ret = true; + } + return ret; + } + }; + class Accept : public BasePack { + public: + Accept() { + msgOffset = 0; + addressFromOffset = 1; + DataOffset = 1; + } -class Data : - virtual public IEmptyPack, - virtual public IHasAddresFrom, - virtual public IHasAddresTo, - virtual public IHasAddresData { -public: - Data() { - msgOffset = 0; - addressFromOffset = 1; - addressToOffset = 3; - DataOffset = 5; - } -}; \ No newline at end of file + uint16_t getAddrFrom() { return _getAddrFrom(this); }; + private: + bool checkAddress() override { return true; } + }; + + class Request : public BasePack { + public: + Request() { + msgOffset = 0; + addressFromOffset = 1; + addressToOffset = 3; + DataOffset = 3; + } + + uint16_t getAddrFrom() { return _getAddrFrom(this); }; + uint16_t getAddrTo() { return _getAddrTo(this); }; + + private: + bool checkAddress() override { + bool ret; + IR_FOX::checkaddressRuleApply(getAddrTo(), this->id, ret); + return ret; + } + }; + +} + +// class IOffsets { +// protected: +// uint8_t msgOffset; +// uint8_t addressFromOffset; +// uint8_t addressToOffset; +// uint8_t DataOffset; +// }; + +// class IPackInfo { +// public: +// IR_FOX::PackInfo* packInfo; +// }; + +// class IBaseEmptyPack : virtual public IOffsets, virtual public IPackInfo { +// }; + +// class IR_Decoder; +// class IEmptyPack : virtual protected IBaseEmptyPack, virtual public IR_FOX { +// friend IR_Decoder; +// bool isAvailable; +// bool isRawAvailable; +// bool isNeedAccept; + +// protected: +// uint16_t id; + +// virtual bool checkAddress() {}; + +// virtual void set(IR_FOX::PackInfo* packInfo, uint16_t id, bool isNeedAccept = false) { +// IBaseEmptyPack::IPackInfo::packInfo = packInfo; +// this->id = id; +// this->isNeedAccept = isNeedAccept; + +// if (isAvailable = checkAddress()) { +// isAvailable = true; +// isRawAvailable = true; +// Serial.print(" OK "); +// } else { +// isRawAvailable = true; +// Serial.print(" NOT-OK "); +// } +// } + +// public: +// virtual bool available() { if (isAvailable) { isAvailable = false; isRawAvailable = false; return true; } else { return false; } }; +// virtual bool availableRaw() { if (isRawAvailable) { isRawAvailable = false; return true; } else { return false; } }; +// virtual uint8_t getMsgInfo() { return packInfo->buffer[0] & IR_MASK_MSG_INFO; }; +// virtual uint8_t getMsgType() { return (packInfo->buffer[0] >> 5) & IR_MASK_MSG_TYPE; }; +// virtual uint8_t getMsgRAW() { return packInfo->buffer[0]; }; +// virtual uint16_t getErrorCount() { return packInfo->err.all(); }; +// virtual uint8_t getErrorLowSignal() { return packInfo->err.lowSignal; }; +// virtual uint8_t getErrorHighSignal() { return packInfo->err.highSignal; }; +// virtual uint8_t getErrorOther() { return packInfo->err.other; }; +// virtual uint16_t getTunerTime() { return packInfo->rTime; }; +// }; + +// class IHasAddresFrom : virtual protected IBaseEmptyPack { +// public: +// virtual uint16_t getAddrFrom() { return (packInfo->buffer[addressFromOffset] << 8) | packInfo->buffer[addressFromOffset + 1]; }; +// }; + +// class IHasAddresTo : virtual protected IBaseEmptyPack { +// public: +// virtual uint16_t getAddrTo() { return (packInfo->buffer[addressToOffset] << 8) | packInfo->buffer[addressToOffset + 1]; }; +// }; + +// class IHasAddresData : virtual protected IBaseEmptyPack { +// public: +// virtual uint8_t getDataSize() { return packInfo->packSize - crcBytes - DataOffset; }; +// virtual uint8_t* getDataPrt() { return packInfo->buffer + DataOffset; }; +// virtual uint8_t getDataRawSize() { return packInfo->packSize; }; +// virtual uint8_t* getDataRawPtr() { return packInfo->buffer; }; +// }; + +// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// class Data : +// virtual public IEmptyPack, +// virtual public IHasAddresFrom, +// virtual public IHasAddresTo, +// virtual public IHasAddresData { +// public: +// Data() { +// msgOffset = 0; +// addressFromOffset = 1; +// addressToOffset = 3; +// DataOffset = 5; +// } +// protected: +// bool checkAddress() override { +// bool ret; +// checkaddressRuleApply(getAddrTo(), this->id, ret); +// return ret; +// } +// }; + +// class DataBack : +// virtual public IEmptyPack, +// virtual public IHasAddresFrom, +// virtual public IHasAddresData { +// public: +// DataBack() { +// msgOffset = 0; +// addressFromOffset = 1; +// addressToOffset = 3; +// DataOffset = 3; +// } +// protected: +// bool checkAddress() override { +// bool ret; +// if (getMsgType() == IR_MSG_BACK_TO) { +// DataOffset = 5; +// checkaddressRuleApply((packInfo->buffer[addressToOffset] << 8) | packInfo->buffer[addressToOffset + 1], this->id, ret); +// } else { +// DataOffset = 3; +// ret = true; +// } +// return ret; +// } +// }; + +// class Request : +// virtual public IEmptyPack, +// virtual public IHasAddresFrom, +// virtual public IHasAddresTo { +// public: +// Request() { +// msgOffset = 0; +// addressFromOffset = 1; +// addressToOffset = 3; +// DataOffset = 3; +// } +// protected: +// bool checkAddress() override { +// bool ret; +// checkaddressRuleApply(getAddrTo(), this->id, ret); +// return ret; +// } +// }; + +// class Accept : +// virtual public IEmptyPack, +// virtual public IHasAddresFrom { +// public: +// Accept() { +// msgOffset = 0; +// addressFromOffset = 1; +// DataOffset = 1; +// } +// protected: +// }; From 96432374655ea48d90335273c2fcd0bd7146d0de Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 27 Feb 2024 11:38:23 +0300 Subject: [PATCH 47/51] add Accept logic --- IR_Decoder.h | 25 +++++++++++++++++++------ IR_DecoderRaw.h | 2 +- IR_Encoder.cpp | 14 +++++++------- IR_Encoder.h | 4 ++-- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/IR_Decoder.h b/IR_Decoder.h index 1370d12..58f23b1 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -1,16 +1,23 @@ #pragma once #include "IR_DecoderRaw.h" #include "PacketTypes.h" +#include "IR_Encoder.h" class IR_Decoder : public IR_DecoderRaw { + uint32_t acceptSendTimer; + bool isWaitingAcceptSend; + uint16_t addrAcceptSendTo; + + + public: + PacketTypes::Data gotData; PacketTypes::DataBack gotBackData; PacketTypes::Accept gotAccept; PacketTypes::Request gotRequest; - IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : IR_DecoderRaw(isrPin, addr, encPair) { - } + IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : IR_DecoderRaw(isrPin, addr, encPair) {} void tick() { IR_DecoderRaw::tick(); @@ -18,10 +25,9 @@ public: #ifdef IRDEBUG_INFO Serial.println("PARSING RAW DATA"); #endif - bool isNeenAccept = false; + isWaitingAcceptSend = false; switch (packInfo.buffer[0] >> 5 & IR_MASK_MSG_TYPE) { case IR_MSG_DATA_ACCEPT: - isNeenAccept = true; case IR_MSG_DATA_NOACCEPT: gotData.set(&packInfo, id); break; @@ -39,8 +45,15 @@ public: default: break; } - - + if (gotData.isAvailable && (gotData.getMsgType() == IR_MSG_DATA_ACCEPT)) { + acceptSendTimer = millis(); + addrAcceptSendTo = gotData.getAddrFrom(); + if(addrAcceptSendTo && addrAcceptSendTo < IR_Broadcast) isWaitingAcceptSend = true; + } + } + if (isWaitingAcceptSend && millis() - acceptSendTimer > 75) { + encoder->sendAccept(addrAcceptSendTo); + isWaitingAcceptSend = false; } } }; diff --git a/IR_DecoderRaw.h b/IR_DecoderRaw.h index 93a25a6..e0a24e3 100644 --- a/IR_DecoderRaw.h +++ b/IR_DecoderRaw.h @@ -45,12 +45,12 @@ public: protected: PackInfo packInfo; uint16_t id; + IR_Encoder* encoder; // Указатель на парный передатчик private: ErrorsStruct errors; bool isAvailable = false; uint16_t packSize; uint16_t crcValue; - IR_Encoder* encoder; // Указатель на парный передатчик volatile uint16_t isPairSending = 0; // Флаг передачи парного передатчика volatile bool isRecive = false; // Флаг приёма volatile bool isPreamb = false; // флаг начальной последовости diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 1737913..204a927 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -72,17 +72,17 @@ void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool need rawSend(sendBuffer, packSize); } -void IR_Encoder::sendAccept(uint16_t addrTo, uint8_t addInfo) { +void IR_Encoder::sendAccept(uint16_t addrTo) { memset(sendBuffer, 0x00, dataByteSizeMax); sendBuffer[0] = IR_MSG_ACCEPT << 5; - sendBuffer[0] |= addInfo & IR_MASK_MSG_INFO; + sendBuffer[0] |= msgBytes + addrBytes + crcBytes & IR_MASK_MSG_INFO; // размер пакета // addr_self sendBuffer[1] = id >> 8 & 0xFF; sendBuffer[2] = id & 0xFF; - Serial.print("\nRAW Accept to "); - Serial.println(addrTo); + // Serial.print("\nRAW Accept to "); + // Serial.println(addrTo); // data crc @@ -92,10 +92,10 @@ void IR_Encoder::sendAccept(uint16_t addrTo, uint8_t addInfo) { rawSend(sendBuffer, msgBytes + addrBytes + crcBytes); } -void IR_Encoder::sendRequest(uint16_t addrTo, uint8_t addInfo) { +void IR_Encoder::sendRequest(uint16_t addrTo) { memset(sendBuffer, 0x00, dataByteSizeMax); sendBuffer[0] = IR_MSG_REQUEST << 5; - sendBuffer[0] |= addInfo & IR_MASK_MSG_INFO; + sendBuffer[0] |= msgBytes + addrBytes + addrBytes + crcBytes & IR_MASK_MSG_INFO; // addr_self sendBuffer[1] = id >> 8 & 0xFF; @@ -127,7 +127,7 @@ void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t* data, uint uint8_t packSize = msgBytes + addrBytes + (isAdressed ? addrBytes : 0) + min(1, len) + crcBytes; uint8_t msgType = - ((isAdressed ? IR_MSG_BACK_TO : IR_MSG_BACK)<<5) | ((packSize) & (IR_MASK_MSG_INFO >> 1)); + ((isAdressed ? IR_MSG_BACK_TO : IR_MSG_BACK) << 5) | ((packSize) & (IR_MASK_MSG_INFO >> 1)); // формирование массива // msg_type diff --git a/IR_Encoder.h b/IR_Encoder.h index 65462f2..a3eab06 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -45,8 +45,8 @@ public: void IR_Encoder::setBlindDecoders(IR_DecoderRaw* decoders [], uint8_t count); void rawSend(uint8_t* ptr, uint8_t len); void sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false); - void sendAccept(uint16_t addrTo, uint8_t addInfo = 0); - void sendRequest(uint16_t addrTo, uint8_t addInfo = 0); + void sendAccept(uint16_t addrTo); + void sendRequest(uint16_t addrTo); void sendBack(uint8_t* data = nullptr, uint8_t len = 0); void sendBackTo(uint16_t addrTo, uint8_t* data = nullptr, uint8_t len = 0); void isr(); From 9af3e95ec85aac4c97acf14618e1abb9f65abf92 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 27 Feb 2024 12:29:00 +0300 Subject: [PATCH 48/51] add customByte to Accept --- IR-Protocol.ino | 2 +- IR_Encoder.cpp | 17 ++++++++++------- IR_Encoder.h | 2 +- IR_config.h | 18 +++++++++--------- PacketTypes.h | 10 +++------- 5 files changed, 24 insertions(+), 25 deletions(-) diff --git a/IR-Protocol.ino b/IR-Protocol.ino index 943ebf1..f0b7e60 100644 --- a/IR-Protocol.ino +++ b/IR-Protocol.ino @@ -14,7 +14,7 @@ //////////////// Ini ///////////////// -#define INFO "Машинка" +#define INFO "IR_FOX TEST" #define SERIAL_SPEED 115200 //////////////// Var ///////////////// diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 204a927..12b40e9 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -72,10 +72,11 @@ void IR_Encoder::sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool need rawSend(sendBuffer, packSize); } -void IR_Encoder::sendAccept(uint16_t addrTo) { +void IR_Encoder::sendAccept(uint16_t addrTo, uint8_t customByte = 0) { + constexpr uint8_t packsize = msgBytes + addrBytes + 1U + crcBytes; memset(sendBuffer, 0x00, dataByteSizeMax); sendBuffer[0] = IR_MSG_ACCEPT << 5; - sendBuffer[0] |= msgBytes + addrBytes + crcBytes & IR_MASK_MSG_INFO; // размер пакета + sendBuffer[0] |= packsize & IR_MASK_MSG_INFO; // размер пакета // addr_self sendBuffer[1] = id >> 8 & 0xFF; @@ -84,18 +85,20 @@ void IR_Encoder::sendAccept(uint16_t addrTo) { // Serial.print("\nRAW Accept to "); // Serial.println(addrTo); + sendBuffer[3] = customByte; // data crc - sendBuffer[3] = crc8(sendBuffer, 0, 3, poly1) & 0xFF; - sendBuffer[4] = crc8(sendBuffer, 0, 4, poly2) & 0xFF; + sendBuffer[4] = crc8(sendBuffer, 0, 4, poly1) & 0xFF; + sendBuffer[5] = crc8(sendBuffer, 0, 5, poly2) & 0xFF; - rawSend(sendBuffer, msgBytes + addrBytes + crcBytes); + rawSend(sendBuffer, packsize); } void IR_Encoder::sendRequest(uint16_t addrTo) { + constexpr uint8_t packsize = msgBytes + addrBytes + addrBytes + crcBytes; memset(sendBuffer, 0x00, dataByteSizeMax); sendBuffer[0] = IR_MSG_REQUEST << 5; - sendBuffer[0] |= msgBytes + addrBytes + addrBytes + crcBytes & IR_MASK_MSG_INFO; + sendBuffer[0] |= packsize & IR_MASK_MSG_INFO; // addr_self sendBuffer[1] = id >> 8 & 0xFF; @@ -109,7 +112,7 @@ void IR_Encoder::sendRequest(uint16_t addrTo) { sendBuffer[5] = crc8(sendBuffer, 0, 5, poly1) & 0xFF; sendBuffer[6] = crc8(sendBuffer, 0, 6, poly2) & 0xFF; - rawSend(sendBuffer, msgBytes + addrBytes + addrBytes + crcBytes); + rawSend(sendBuffer, packsize); } void IR_Encoder::sendBack(uint8_t* data = nullptr, uint8_t len = 0) { diff --git a/IR_Encoder.h b/IR_Encoder.h index a3eab06..be2c400 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -45,7 +45,7 @@ public: void IR_Encoder::setBlindDecoders(IR_DecoderRaw* decoders [], uint8_t count); void rawSend(uint8_t* ptr, uint8_t len); void sendData(uint16_t addrTo, uint8_t* data, uint8_t len, bool needAccept = false); - void sendAccept(uint16_t addrTo); + void sendAccept(uint16_t addrTo, uint8_t customByte = 0); void sendRequest(uint16_t addrTo); void sendBack(uint8_t* data = nullptr, uint8_t len = 0); void sendBackTo(uint16_t addrTo, uint8_t* data = nullptr, uint8_t len = 0); diff --git a/IR_config.h b/IR_config.h index e3adc1d..2a478e6 100644 --- a/IR_config.h +++ b/IR_config.h @@ -52,15 +52,15 @@ msg type: /```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\                                                                                                                        -{``````````} [````````````````````````] [``````````````]      {``````````} [````````````````````````] [````````````````````````] [``````````````] -{ msg type } [ addr_from uint16_t ] [ CRC Bytes ]      { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] -{..........} [........................] [..............]      {..........} [........................] [........................] [..............] -                                                                                                                                                  -{ 001..... } [addr_from_H][addr_from_L] [ crc1 ][ crc2 ]      { 010..... } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [ crc1 ][ crc2 ] -|     0            1           2           3       4          |     0            1           2              3           4           5       6     -\__________________________________________/       |          \_____________________________________________________________________/       |     -|                                                  |          |                                                                             |     -\__________________________________________________/          \_____________________________________________________________________________/     +{``````````} [````````````````````````] [``````````````````] [``````````````]      {``````````} [````````````````````````] [````````````````````````] [``````````````] +{ msg type } [ addr_from uint16_t ] [=== customByte ===] [ CRC Bytes ]      { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] +{..........} [........................] [..................] [..............]      {..........} [........................] [........................] [..............] +                                                                                                                                                             +{ 001..... } [addr_from_H][addr_from_L] [=== customByte ===] [ crc1 ][ crc2 ]      { 010..... } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [ crc1 ][ crc2 ] +|     0            1           2                  3              4       5          |     0            1           2              3           4           5       6     +\________________________________________________________________/       |          \_____________________________________________________________________/       |     +|                                                                        |          |                                                                             |     +\________________________________________________________________________/          \_____________________________________________________________________________/     diff --git a/PacketTypes.h b/PacketTypes.h index d5bbce2..28ab8eb 100644 --- a/PacketTypes.h +++ b/PacketTypes.h @@ -50,10 +50,6 @@ namespace PacketTypes { static uint8_t _getDataRawSize(BasePack* obj) { return obj->packInfo->packSize; }; - static uint8_t* _getDataRawPtr(BasePack* obj) { - return obj->packInfo->buffer; - }; - public: bool available() { if (isAvailable) { isAvailable = false; isRawAvailable = false; return true; } else { return false; } }; @@ -66,6 +62,7 @@ namespace PacketTypes { uint8_t getErrorHighSignal() { return packInfo->err.highSignal; }; uint8_t getErrorOther() { return packInfo->err.other; }; uint16_t getTunerTime() { return packInfo->rTime; }; + uint8_t* getDataRawPtr() { return packInfo->buffer; }; }; @@ -84,7 +81,6 @@ namespace PacketTypes { uint8_t getDataSize() { return _getDataSize(this); }; uint8_t* getDataPrt() { return _getDataPrt(this); }; uint8_t getDataRawSize() { return _getDataRawSize(this); }; - uint8_t* getDataRawPtr() { return _getDataRawPtr(this); }; private: bool checkAddress() override { @@ -109,7 +105,6 @@ namespace PacketTypes { uint8_t getDataSize() { return _getDataSize(this); }; uint8_t* getDataPrt() { return _getDataPrt(this); }; uint8_t getDataRawSize() { return _getDataRawSize(this); }; - uint8_t* getDataRawPtr() { return _getDataRawPtr(this); }; private: bool checkAddress() override { bool ret; @@ -129,10 +124,11 @@ namespace PacketTypes { Accept() { msgOffset = 0; addressFromOffset = 1; - DataOffset = 1; + DataOffset = 3; } uint16_t getAddrFrom() { return _getAddrFrom(this); }; + uint8_t getCustomByte() { return packInfo->buffer[DataOffset]; }; private: bool checkAddress() override { return true; } }; From 523bb0712c3db0b25321b6c3dfe05d3d1fbcb93c Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 27 Feb 2024 12:32:04 +0300 Subject: [PATCH 49/51] noDebug --- IR_config.h | 2 +- PacketTypes.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/IR_config.h b/IR_config.h index 2a478e6..5d35176 100644 --- a/IR_config.h +++ b/IR_config.h @@ -1,7 +1,7 @@ #pragma once #include -#define IRDEBUG_INFO +// #define IRDEBUG_INFO /*////////////////////////////////////////////////////////////////////////////////////// Для работы в паре положить декодер в энкодер diff --git a/PacketTypes.h b/PacketTypes.h index 28ab8eb..4bb8e58 100644 --- a/PacketTypes.h +++ b/PacketTypes.h @@ -26,10 +26,14 @@ namespace PacketTypes { if (isAvailable = checkAddress()) { isAvailable = true; isRawAvailable = true; + #ifdef IRDEBUG_INFO Serial.print(" OK "); + #endif } else { isRawAvailable = true; + #ifdef IRDEBUG_INFO Serial.print(" NOT-OK "); + #endif } } From 909fac5d1ac97e1058be71563633584c687d9d99 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 27 Feb 2024 12:45:52 +0300 Subject: [PATCH 50/51] add acceptDelay change --- IR-Protocol.ino | 260 +++++++++++++++++++++++++++++++----------------- IR_Decoder.h | 9 +- 2 files changed, 174 insertions(+), 95 deletions(-) diff --git a/IR-Protocol.ino b/IR-Protocol.ino index f0b7e60..bd17df6 100644 --- a/IR-Protocol.ino +++ b/IR-Protocol.ino @@ -60,7 +60,7 @@ uint32_t loopTimer; uint8_t sig = 255; uint16_t targetAddr = IR_Broadcast; -Timer t1(730, millis, []() { +Timer t1(500, millis, []() { // Serial.println(sig); @@ -227,106 +227,178 @@ void loop() { //test void status(IR_Decoder& dec) { - if (dec.gotData.available()) { - String str; - if (/* dec.gotData.getDataPrt()[1] */1) { - str += ("Data on pin "); str += (dec.isrPin); str += "\n"; + if (dec.gotData.available()) { + String str; + if (/* dec.gotData.getDataPrt()[1] */1) { + str += ("Data on pin "); str += (dec.isrPin); str += "\n"; - uint8_t msg = dec.gotData.getMsgRAW(); - str += (" MSG: "); - for (size_t i = 0; i < 8; i++) { - if (i == 3) str += " "; - str += (msg >> (7 - i)) & 1U; - } - - str += "\n"; - - str += (" DATA SIZE: "); str += (dec.gotData.getDataSize()); str += "\n"; - str += (" ADDRESS FROM: "); str += (dec.gotData.getAddrFrom()); str += "\n"; - str += (" ADDRESS TO: "); str += (dec.gotData.getAddrTo()); str += "\n"; - // str += (" CRC PACK: "); str += (dec.gotData.getCrcIN()); str += "\n"; - // str += (" CRC CALC: "); str += (dec.gotData.getCrcCALC()); str += "\n"; - str += "\n"; - - for (size_t i = 0; i < min(10, dec.gotData.getDataSize()); i++) { - switch (i) { - // case 0: - // str += (" ADDR: "); - // break; - // case 1: - // str += (" CMD: "); - // break; - - default: - str += (" Data["); str += (i); str += ("]: "); - break; - } - str += (dec.gotData.getDataPrt()[i]); str += "\n"; - } - - - str += ("\n*******ErrAll: "); str += (dec.gotData.getErrorCount()); str += "\n"; - str += ("**ErrDistance: "); str += ((int)(dec.gotData.getErrorHighSignal() - dec.gotData.getErrorLowSignal())); str += "\n"; - - str += "\n"; - } else { - str += ("SELF"); str += "\n"; - str += "\n"; + uint8_t msg = dec.gotData.getMsgRAW(); + str += (" MSG: "); + for (size_t i = 0; i < 8; i++) { + if (i == 3) str += " "; + str += (msg >> (7 - i)) & 1U; } - // obj->resetAvailable(); - Serial.write(str.c_str()); - } - if (dec.gotBackData.available()) { - String str; - if (/* dec.gotData.getDataPrt()[1] */1) { - str += ("BackData on pin "); str += (dec.isrPin); str += "\n"; + str += "\n"; - uint8_t msg = dec.gotBackData.getMsgRAW(); - str += (" MSG: "); - for (size_t i = 0; i < 8; i++) { - if (i == 3) str += " "; - str += (msg >> (7 - i)) & 1U; + str += (" DATA SIZE: "); str += (dec.gotData.getDataSize()); str += "\n"; + str += (" ADDRESS FROM: "); str += (dec.gotData.getAddrFrom()); str += "\n"; + str += (" ADDRESS TO: "); str += (dec.gotData.getAddrTo()); str += "\n"; + // str += (" CRC PACK: "); str += (dec.gotData.getCrcIN()); str += "\n"; + // str += (" CRC CALC: "); str += (dec.gotData.getCrcCALC()); str += "\n"; + str += "\n"; + + for (size_t i = 0; i < min(10, dec.gotData.getDataSize()); i++) { + switch (i) { + // case 0: + // str += (" ADDR: "); + // break; + // case 1: + // str += (" CMD: "); + // break; + + default: + str += (" Data["); str += (i); str += ("]: "); + break; } - - str += "\n"; - - str += (" DATA SIZE: "); str += (dec.gotBackData.getDataSize()); str += "\n"; - str += (" ADDRESS FROM: "); str += (dec.gotBackData.getAddrFrom()); str += "\n"; - // str += (" ADDRESS TO: "); str += (dec.gotBackData.getAddrTo()); str += "\n"; - // str += (" CRC PACK: "); str += (dec.gotBackData.getCrcIN()); str += "\n"; - // str += (" CRC CALC: "); str += (dec.gotBackData.getCrcCALC()); str += "\n"; - str += "\n"; - - for (size_t i = 0; i < min(10, dec.gotBackData.getDataSize()); i++) { - switch (i) { - // case 0: - // str += (" ADDR: "); - // break; - // case 1: - // str += (" CMD: "); - // break; - - default: - str += (" Data["); str += (i); str += ("]: "); - break; - } - str += (dec.gotBackData.getDataPrt()[i]); str += "\n"; - } - - - str += ("\n*******ErrAll: "); str += (dec.gotBackData.getErrorCount()); str += "\n"; - str += ("**ErrDistance: "); str += ((int)(dec.gotBackData.getErrorHighSignal() - dec.gotBackData.getErrorLowSignal())); str += "\n"; - - str += "\n"; - } else { - str += ("SELF"); str += "\n"; - str += "\n"; + str += (dec.gotData.getDataPrt()[i]); str += "\n"; } - // obj->resetAvailable(); - Serial.write(str.c_str()); + + + str += ("\n*******ErrAll: "); str += (dec.gotData.getErrorCount()); str += "\n"; + str += ("**ErrDistance: "); str += ((int)(dec.gotData.getErrorHighSignal() - dec.gotData.getErrorLowSignal())); str += "\n"; + + str += "\n"; + } else { + str += ("SELF"); str += "\n"; + str += "\n"; } - + // obj->resetAvailable(); + Serial.write(str.c_str()); + } + + if (dec.gotBackData.available()) { + String str; + if (/* dec.gotData.getDataPrt()[1] */1) { + str += ("BackData on pin "); str += (dec.isrPin); str += "\n"; + + uint8_t msg = dec.gotBackData.getMsgRAW(); + str += (" MSG: "); + for (size_t i = 0; i < 8; i++) { + if (i == 3) str += " "; + str += (msg >> (7 - i)) & 1U; + } + + str += "\n"; + + str += (" DATA SIZE: "); str += (dec.gotBackData.getDataSize()); str += "\n"; + str += (" ADDRESS FROM: "); str += (dec.gotBackData.getAddrFrom()); str += "\n"; + // str += (" ADDRESS TO: "); str += (dec.gotBackData.getAddrTo()); str += "\n"; + // str += (" CRC PACK: "); str += (dec.gotBackData.getCrcIN()); str += "\n"; + // str += (" CRC CALC: "); str += (dec.gotBackData.getCrcCALC()); str += "\n"; + str += "\n"; + + for (size_t i = 0; i < min(10, dec.gotBackData.getDataSize()); i++) { + switch (i) { + // case 0: + // str += (" ADDR: "); + // break; + // case 1: + // str += (" CMD: "); + // break; + + default: + str += (" Data["); str += (i); str += ("]: "); + break; + } + str += (dec.gotBackData.getDataPrt()[i]); str += "\n"; + } + + + str += ("\n*******ErrAll: "); str += (dec.gotBackData.getErrorCount()); str += "\n"; + str += ("**ErrDistance: "); str += ((int)(dec.gotBackData.getErrorHighSignal() - dec.gotBackData.getErrorLowSignal())); str += "\n"; + + str += "\n"; + } else { + str += ("SELF"); str += "\n"; + str += "\n"; + } + // obj->resetAvailable(); + Serial.write(str.c_str()); + } + + if (dec.gotAccept.available()) { + String str; + if (/* dec.gotData.getDataPrt()[1] */1) { + str += ("Accept on pin "); str += (dec.isrPin); str += "\n"; + + uint8_t msg = dec.gotAccept.getMsgRAW(); + str += (" MSG: "); + for (size_t i = 0; i < 8; i++) { + if (i == 3) str += " "; + str += (msg >> (7 - i)) & 1U; + } + + str += "\n"; + + // str += (" DATA SIZE: "); str += (dec.gotAccept.getDataSize()); str += "\n"; + str += (" ADDRESS FROM: "); str += (dec.gotAccept.getAddrFrom()); str += "\n"; + // str += (" ADDRESS TO: "); str += (dec.gotAccept.getAddrTo()); str += "\n"; + // str += (" CRC PACK: "); str += (dec.gotAccept.getCrcIN()); str += "\n"; + // str += (" CRC CALC: "); str += (dec.gotAccept.getCrcCALC()); str += "\n"; + str += "\n"; + + str += (" Data["); str += (dec.gotAccept.getCustomByte()); str += ("]: \n"); + + + + str += ("\n*******ErrAll: "); str += (dec.gotAccept.getErrorCount()); str += "\n"; + str += ("**ErrDistance: "); str += ((int)(dec.gotAccept.getErrorHighSignal() - dec.gotAccept.getErrorLowSignal())); str += "\n"; + + str += "\n"; + } else { + str += ("SELF"); str += "\n"; + str += "\n"; + } + // obj->resetAvailable(); + Serial.write(str.c_str()); + } + + if (dec.gotRequest.available()) { + String str; + if (/* dec.gotData.getDataPrt()[1] */1) { + str += ("Request on pin "); str += (dec.isrPin); str += "\n"; + + uint8_t msg = dec.gotRequest.getMsgRAW(); + str += (" MSG: "); + for (size_t i = 0; i < 8; i++) { + if (i == 3) str += " "; + str += (msg >> (7 - i)) & 1U; + } + + str += "\n"; + + // str += (" DATA SIZE: "); str += (dec.gotRequest.getDataSize()); str += "\n"; + str += (" ADDRESS FROM: "); str += (dec.gotRequest.getAddrFrom()); str += "\n"; + str += (" ADDRESS TO: "); str += (dec.gotRequest.getAddrTo()); str += "\n"; + // str += (" CRC PACK: "); str += (dec.gotRequest.getCrcIN()); str += "\n"; + // str += (" CRC CALC: "); str += (dec.gotRequest.getCrcCALC()); str += "\n"; + str += "\n"; + + + str += ("\n*******ErrAll: "); str += (dec.gotRequest.getErrorCount()); str += "\n"; + str += ("**ErrDistance: "); str += ((int)(dec.gotRequest.getErrorHighSignal() - dec.gotRequest.getErrorLowSignal())); str += "\n"; + + str += "\n"; + } else { + str += ("SELF"); str += "\n"; + str += "\n"; + } + // obj->resetAvailable(); + Serial.write(str.c_str()); + } + + } diff --git a/IR_Decoder.h b/IR_Decoder.h index 58f23b1..8cdd767 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -8,7 +8,7 @@ class IR_Decoder : public IR_DecoderRaw { bool isWaitingAcceptSend; uint16_t addrAcceptSendTo; - + uint16_t acceptDelay = 75; public: @@ -56,4 +56,11 @@ public: isWaitingAcceptSend = false; } } + + void setAcceptDelay(uint16_t acceptDelay){ + this->acceptDelay = acceptDelay; + } + uint16_t getAcceptDelay(){ + return this->acceptDelay; + } }; From 0166bbfa22e9c0f96453fb65962488729339afad Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 27 Feb 2024 13:02:30 +0300 Subject: [PATCH 51/51] add crcID for accept --- IR-Protocol.ino | 4 ++-- IR_Decoder.h | 10 ++++++---- IR_config.h | 4 +++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/IR-Protocol.ino b/IR-Protocol.ino index bd17df6..2333e7e 100644 --- a/IR-Protocol.ino +++ b/IR-Protocol.ino @@ -348,11 +348,11 @@ void status(IR_Decoder& dec) { // str += (" CRC CALC: "); str += (dec.gotAccept.getCrcCALC()); str += "\n"; str += "\n"; - str += (" Data["); str += (dec.gotAccept.getCustomByte()); str += ("]: \n"); + str += (" Data: "); str += (dec.gotAccept.getCustomByte()); - str += ("\n*******ErrAll: "); str += (dec.gotAccept.getErrorCount()); str += "\n"; + str += ("\n\n*******ErrAll: "); str += (dec.gotAccept.getErrorCount()); str += "\n"; str += ("**ErrDistance: "); str += ((int)(dec.gotAccept.getErrorHighSignal() - dec.gotAccept.getErrorLowSignal())); str += "\n"; str += "\n"; diff --git a/IR_Decoder.h b/IR_Decoder.h index 8cdd767..32ecb79 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -9,6 +9,7 @@ class IR_Decoder : public IR_DecoderRaw { uint16_t addrAcceptSendTo; uint16_t acceptDelay = 75; + uint8_t acceptCustomByte; public: @@ -48,19 +49,20 @@ public: if (gotData.isAvailable && (gotData.getMsgType() == IR_MSG_DATA_ACCEPT)) { acceptSendTimer = millis(); addrAcceptSendTo = gotData.getAddrFrom(); - if(addrAcceptSendTo && addrAcceptSendTo < IR_Broadcast) isWaitingAcceptSend = true; + acceptCustomByte = crc8(gotData.getDataPrt(), 0, gotData.getDataSize(), poly1); + if (addrAcceptSendTo && addrAcceptSendTo < IR_Broadcast) isWaitingAcceptSend = true; } } if (isWaitingAcceptSend && millis() - acceptSendTimer > 75) { - encoder->sendAccept(addrAcceptSendTo); + encoder->sendAccept(addrAcceptSendTo, acceptCustomByte); isWaitingAcceptSend = false; } } - void setAcceptDelay(uint16_t acceptDelay){ + void setAcceptDelay(uint16_t acceptDelay) { this->acceptDelay = acceptDelay; } - uint16_t getAcceptDelay(){ + uint16_t getAcceptDelay() { return this->acceptDelay; } }; diff --git a/IR_config.h b/IR_config.h index 5d35176..0a20143 100644 --- a/IR_config.h +++ b/IR_config.h @@ -50,7 +50,7 @@ msg type: #define IR_MSG_DATA_ACCEPT 7U // | 111..... | = данные требующие подтверждения ;/*   // ---------- -/```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\ +/``````````````````````````````` подтверждение `````````````````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\                                                                                                                        {``````````} [````````````````````````] [``````````````````] [``````````````]      {``````````} [````````````````````````] [````````````````````````] [``````````````] { msg type } [ addr_from uint16_t ] [=== customByte ===] [ CRC Bytes ]      { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] @@ -62,6 +62,8 @@ msg type: |                                                                        |          |                                                                             |     \________________________________________________________________________/          \_____________________________________________________________________________/     +customByte - контрольная сумма принятых данных по poly1 + /`````````````````````` Задний сигнал машинки без адресации ``````````````````````\        В (IR_MASK_MSG_INFO & 15U) содержится количество байт