mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2025-05-04 07:10:16 +00:00
ErrorFix
This commit is contained in:
parent
1ee3386c31
commit
d065c7a037
216
IR_Decoder.cpp
216
IR_Decoder.cpp
@ -62,8 +62,7 @@ void IR_Decoder::tick() {
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (currentFront.time - prevRise > IR_timeout) { // первый
|
if (currentFront.time - prevRise > IR_timeout) { // первый
|
||||||
|
errors.reset();
|
||||||
errorCounter = 0;
|
|
||||||
isRecive = true;
|
isRecive = true;
|
||||||
isPreamb = true;
|
isPreamb = true;
|
||||||
|
|
||||||
@ -79,7 +78,7 @@ void IR_Decoder::tick() {
|
|||||||
|
|
||||||
if (risePeriod < riseTimeMin << 1) { // fix рваной единицы
|
if (risePeriod < riseTimeMin << 1) { // fix рваной единицы
|
||||||
preambFrontCounter += 2;
|
preambFrontCounter += 2;
|
||||||
errorCounter++;
|
errors.other++;
|
||||||
} else {
|
} else {
|
||||||
if (freeFrec) { riseSyncTime = (riseSyncTime + risePeriod / 2) / 2; } // tuner
|
if (freeFrec) { riseSyncTime = (riseSyncTime + risePeriod / 2) / 2; } // tuner
|
||||||
}
|
}
|
||||||
@ -104,107 +103,118 @@ void IR_Decoder::tick() {
|
|||||||
int8_t allCount = 0;
|
int8_t allCount = 0;
|
||||||
bool invertErr = false;
|
bool invertErr = false;
|
||||||
|
|
||||||
|
if (!isPreamb) {
|
||||||
|
if (risePeriod < IR_timeout && !isBufferOverflow && risePeriod > riseTimeMin && !isWrongPack) {
|
||||||
|
// Мы в пределах таймаута и буффер не переполнен и fix дроблёных единиц
|
||||||
|
|
||||||
if (risePeriod < IR_timeout && !isBufferOverflow && risePeriod > riseTimeMin && !isWrongPack) {
|
if (aroundRise(risePeriod)) { // тактирование есть, сигнал хороший - без ошибок(?)
|
||||||
// Мы в пределах таймаута и буффер не переполнен и fix дроблёных единиц
|
|
||||||
|
|
||||||
if (aroundRise(risePeriod)) { // тактирование есть, сигнал хороший - без ошибок(?)
|
if (highTime > riseTimeMin >> 1) { // 1
|
||||||
|
#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++;
|
|
||||||
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
|
|
||||||
digitalWrite(wrHigh, 1);
|
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
|
#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) { // комплексный фикс рваной единицы
|
if (risePeriod > riseTimeMax / 2 || highCount || lowCount) { // комплексный фикс рваной единицы
|
||||||
prevPrevRise = prevRise;
|
prevPrevRise = prevRise;
|
||||||
prevRise = currentFront.time;
|
prevRise = currentFront.time;
|
||||||
} else {
|
} else {
|
||||||
errorCounter++;
|
errors.other++;
|
||||||
#ifdef IRDEBUG
|
#ifdef IRDEBUG
|
||||||
errPulse(errOut, 5);
|
errPulse(errOut, 5);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // Если ```\__ ↓
|
} else { // Если ```\__ ↓
|
||||||
@ -213,9 +223,9 @@ void IR_Decoder::tick() {
|
|||||||
prevPrevFall = prevFall;
|
prevPrevFall = prevFall;
|
||||||
prevFall = currentFront.time;
|
prevFall = currentFront.time;
|
||||||
} else {
|
} else {
|
||||||
#ifdef IRDEBUG
|
#ifdef IRDEBUG
|
||||||
//errPulse(errOut, 5);
|
//errPulse(errOut, 5);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,9 +233,9 @@ void IR_Decoder::tick() {
|
|||||||
prevRise = currentFront.time + riseTime;
|
prevRise = currentFront.time + riseTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef IRDEBUG
|
#ifdef IRDEBUG
|
||||||
digitalWrite(writeOp, isPreamb);
|
digitalWrite(writeOp, isPreamb);
|
||||||
#endif
|
#endif
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
firstUnHandledFront = firstUnHandledFront->next; //переместить флаг на следующий элемент для обработки (next or nullptr)
|
firstUnHandledFront = firstUnHandledFront->next; //переместить флаг на следующий элемент для обработки (next or nullptr)
|
||||||
}
|
}
|
||||||
@ -290,7 +300,7 @@ void IR_Decoder::writeToBuffer(bool bit) {
|
|||||||
i_syncBit++;
|
i_syncBit++;
|
||||||
} else {
|
} else {
|
||||||
i_syncBit = 0;
|
i_syncBit = 0;
|
||||||
errorCounter++;
|
errors.other++;
|
||||||
// Serial.print("E");
|
// Serial.print("E");
|
||||||
err_syncBit++;
|
err_syncBit++;
|
||||||
// Serial.print("bit: "); Serial.println(bit);
|
// Serial.print("bit: "); Serial.println(bit);
|
||||||
@ -307,9 +317,9 @@ void IR_Decoder::writeToBuffer(bool bit) {
|
|||||||
}//**************************************************************************************************//
|
}//**************************************************************************************************//
|
||||||
|
|
||||||
// Serial.print(bit);
|
// Serial.print(bit);
|
||||||
#ifdef IRDEBUG
|
#ifdef IRDEBUG
|
||||||
bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1);
|
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;
|
const uint8_t dataSize = msgBytes + addrBytes;
|
||||||
isCrcCorrect = crcCheck(dataSize, crcValue);
|
isCrcCorrect = crcCheck(dataSize, crcValue);
|
||||||
if (isCrcCorrect && checkAddr(1, 2)) {
|
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;
|
gotAccept._isAvaliable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,7 +344,7 @@ void IR_Decoder::writeToBuffer(bool bit) {
|
|||||||
isCrcCorrect = (crcCheck(dataSize, crcValue));
|
isCrcCorrect = (crcCheck(dataSize, crcValue));
|
||||||
if (isCrcCorrect && checkAddr(3, 4)) {
|
if (isCrcCorrect && checkAddr(3, 4)) {
|
||||||
gotRequest._isAvaliable = true;
|
gotRequest._isAvaliable = true;
|
||||||
gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime);
|
gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errors, riseSyncTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -348,10 +358,10 @@ void IR_Decoder::writeToBuffer(bool bit) {
|
|||||||
isCrcCorrect = crcCheck(dataSize, crcValue);
|
isCrcCorrect = crcCheck(dataSize, crcValue);
|
||||||
if (isCrcCorrect && checkAddr(3, 4)) {
|
if (isCrcCorrect && checkAddr(3, 4)) {
|
||||||
gotData._isAvaliable = true;
|
gotData._isAvaliable = true;
|
||||||
gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime);
|
gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errors, riseSyncTime);
|
||||||
} else {
|
} else {
|
||||||
gotRawData._isAvaliable = true;
|
gotRawData._isAvaliable = true;
|
||||||
gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime);
|
gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errors, riseSyncTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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;
|
bool crcOK = false;
|
||||||
|
|
||||||
crc = 0;
|
crc = 0;
|
||||||
|
31
IR_Decoder.h
31
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 {
|
class InputData : protected IR_FOX {
|
||||||
friend IR_Decoder;
|
friend IR_Decoder;
|
||||||
protected:
|
protected:
|
||||||
@ -62,13 +77,13 @@ public:
|
|||||||
uint8_t _dataRawSize = 0;
|
uint8_t _dataRawSize = 0;
|
||||||
uint16_t _crcPackVal = 0;
|
uint16_t _crcPackVal = 0;
|
||||||
uint16_t _crcCalcVal = 0;
|
uint16_t _crcCalcVal = 0;
|
||||||
uint16_t _errCount = 0;
|
ErrorsStruct _err;
|
||||||
uint16_t _bitPeriod = 0;
|
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;
|
_crcCalcVal = crc;
|
||||||
_dataRawSize = len;
|
_dataRawSize = len;
|
||||||
_errCount = err;
|
_err = err;
|
||||||
_bitPeriod = rTime;
|
_bitPeriod = rTime;
|
||||||
if (_data != nullptr) { delete _data; _data = nullptr; }
|
if (_data != nullptr) { delete _data; _data = nullptr; }
|
||||||
_data = new uint8_t[len];
|
_data = new uint8_t[len];
|
||||||
@ -86,7 +101,10 @@ public:
|
|||||||
uint8_t msgInfo() { return _msgType & IR_MASK_MSG_INFO; };
|
uint8_t msgInfo() { return _msgType & IR_MASK_MSG_INFO; };
|
||||||
uint8_t msgType() { return (_msgType >> 5) & IR_MASK_MSG_TYPE; };
|
uint8_t msgType() { return (_msgType >> 5) & IR_MASK_MSG_TYPE; };
|
||||||
uint8_t msgRAW() { return _msgType; };
|
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 crcIN() { return _crcPackVal; };
|
||||||
uint16_t crcCALC() { return _crcCalcVal; };
|
uint16_t crcCALC() { return _crcCalcVal; };
|
||||||
uint16_t tunerTime() { return _bitPeriod; };
|
uint16_t tunerTime() { return _bitPeriod; };
|
||||||
@ -174,6 +192,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const uint8_t isrPin; // Пин прерывания
|
const uint8_t isrPin; // Пин прерывания
|
||||||
|
|
||||||
IR_Encoder* encoder; // Указатель на парный передатчик
|
IR_Encoder* encoder; // Указатель на парный передатчик
|
||||||
@ -282,10 +301,10 @@ private:
|
|||||||
// };
|
// };
|
||||||
|
|
||||||
|
|
||||||
#ifdef IRDEBUG
|
#ifdef IRDEBUG
|
||||||
inline void errPulse(uint8_t pin, uint8_t count);
|
inline void errPulse(uint8_t pin, uint8_t count);
|
||||||
inline void infoPulse(uint8_t pin, uint8_t count);
|
inline void infoPulse(uint8_t pin, uint8_t count);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
@ -120,7 +120,6 @@ void IR_Encoder::setDecoder_isSending() {
|
|||||||
if (decodersCount) {
|
if (decodersCount) {
|
||||||
for (uint8_t i = 0; i < decodersCount; i++) {
|
for (uint8_t i = 0; i < decodersCount; i++) {
|
||||||
blindDecoders[i]->isPairSending ^= id;
|
blindDecoders[i]->isPairSending ^= id;
|
||||||
digitalToggle(9); digitalToggle(9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user