This commit is contained in:
DashyFox 2024-02-13 15:18:45 +03:00
parent 1ee3386c31
commit d065c7a037
3 changed files with 139 additions and 111 deletions

View File

@ -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;

View File

@ -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
}; };

View File

@ -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);
} }
} }