mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2025-05-04 07:10:16 +00:00
check sync bits, fix rare invert error
This commit is contained in:
parent
b05b9dc9d5
commit
6691915aa0
161
IR_Decoder.cpp
161
IR_Decoder.cpp
@ -7,57 +7,73 @@
|
||||
)
|
||||
|
||||
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("****************");
|
||||
}//**************************************************************************************************//
|
||||
|
||||
// Serial.print(bit);
|
||||
#ifdef IRDEBUG
|
||||
bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1);
|
||||
#endif
|
||||
|
||||
// if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; }
|
||||
|
||||
|
||||
|
||||
@ -78,13 +94,6 @@ void IR_Decoder::writeToBuffer(bool bit) {
|
||||
|
||||
|
||||
/*
|
||||
#ifdef IRDEBUG
|
||||
bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1);
|
||||
#endif
|
||||
|
||||
if (isBufferOverflow) { //TODO: Буффер переполнен!
|
||||
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//const auto testval = bufferBitSizeMax;
|
||||
if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) {
|
||||
@ -138,42 +147,42 @@ void IR_Decoder::writeToBuffer(bool bit) {
|
||||
|
||||
}
|
||||
|
||||
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 }; // Буффер по максимуму
|
||||
// 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;
|
||||
// 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;
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
// 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,19 +372,35 @@ void IR_Decoder::tick() {
|
||||
#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);
|
||||
@ -427,7 +466,7 @@ void IR_Decoder::isr() { // в прерывании вызываем isr()
|
||||
}
|
||||
|
||||
|
||||
currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++;
|
||||
currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++; // Закольцовка буффера
|
||||
}
|
||||
|
||||
|
||||
|
14
IR_Decoder.h
14
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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user