mirror of
				https://github.com/Show-maket/IR-protocol.git
				synced 2025-10-30 18:42:35 +00:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			STM32-opti
			...
			7bf71d1d52
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7bf71d1d52 | |||
| 38f3ecac3a | |||
| dec8467280 | |||
| bc9563fbb5 | |||
| 021e1e290d | |||
| 89d14919c9 | |||
| 403b8e6850 | |||
| d0c3138c52 | 
| @ -61,6 +61,7 @@ void IR_Decoder::tick() | |||||||
| void IR_Decoder::_tick() | void IR_Decoder::_tick() | ||||||
| { | { | ||||||
|     IR_DecoderRaw::tick(); |     IR_DecoderRaw::tick(); | ||||||
|  |  | ||||||
|     if (availableRaw()) |     if (availableRaw()) | ||||||
|     { |     { | ||||||
| #ifdef IRDEBUG_INFO | #ifdef IRDEBUG_INFO | ||||||
| @ -103,3 +104,7 @@ void IR_Decoder::_tick() | |||||||
|         isWaitingAcceptSend = false; |         isWaitingAcceptSend = false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool IR_Decoder::isReceive(uint8_t type) { | ||||||
|  |     return (msgTypeReceive & 0b11111000) && ((msgTypeReceive & IR_MASK_MSG_TYPE) == type); | ||||||
|  | }  | ||||||
|  | |||||||
| @ -32,6 +32,8 @@ public: | |||||||
|     void enable(); |     void enable(); | ||||||
|     void disable(); |     void disable(); | ||||||
|      |      | ||||||
|  |     bool isReceive(uint8_t type); | ||||||
|  |  | ||||||
|     ~IR_Decoder(); |     ~IR_Decoder(); | ||||||
|  |  | ||||||
|     static void tick(); |     static void tick(); | ||||||
|  | |||||||
| @ -112,16 +112,37 @@ void IR_DecoderRaw::firstRX() | |||||||
|  |  | ||||||
| void IR_DecoderRaw::listenStart() | void IR_DecoderRaw::listenStart() | ||||||
| { | { | ||||||
|     if (isRecive && ((micros() - prevRise) > IR_timeout * 2)) |     if (isReciveRaw && ((micros() - prevRise) > IR_timeout * 2)) | ||||||
|     { |     { | ||||||
|         // Serial.print("\nlis>"); |         // Serial.print("\nlis>"); | ||||||
|         isRecive = false; |         isReciveRaw = false; | ||||||
|         firstRX(); |         firstRX(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // ---- быстрая проверка конца пакета --------------------------------- | ||||||
|  | inline void IR_DecoderRaw::checkTimeout() | ||||||
|  | { | ||||||
|  |     if (!isRecive) return;     // уже не принимаем – нечего проверять | ||||||
|  |  | ||||||
|  |     if (micros() - lastEdgeTime > IR_timeout * 2U) | ||||||
|  |     { | ||||||
|  |         isRecive = false;      // приём завершён | ||||||
|  |         msgTypeReceive = 0; | ||||||
|  |         // firstRX();             // подготовка к новому пакету | ||||||
|  |         lastEdgeTime = micros(); // защита от повторного срабатывания | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | // ==================================================================== | ||||||
|  |  | ||||||
| void IR_DecoderRaw::tick() | void IR_DecoderRaw::tick() | ||||||
| { | { | ||||||
|  |     // FrontStorage *currentFrontPtr; | ||||||
|  |     // noInterrupts(); | ||||||
|  |     // currentFrontPtr = subBuffer.pop(); | ||||||
|  |     // interrupts(); | ||||||
|  |  | ||||||
|     FrontStorage currentFront; |     FrontStorage currentFront; | ||||||
|     noInterrupts(); |     noInterrupts(); | ||||||
|     listenStart(); |     listenStart(); | ||||||
| @ -130,12 +151,24 @@ void IR_DecoderRaw::tick() | |||||||
|     if (currentFrontPtr == nullptr) |     if (currentFrontPtr == nullptr) | ||||||
|     { |     { | ||||||
|         isSubBufferOverflow = false; |         isSubBufferOverflow = false; | ||||||
|  |         checkTimeout();          // <--- новое место проверки | ||||||
|         interrupts(); |         interrupts(); | ||||||
|         return; |         return; | ||||||
|     } // Если данных нет - ничего не делаем |     } // Если данных нет - ничего не делаем | ||||||
|     currentFront = *currentFrontPtr; |     currentFront = *currentFrontPtr; | ||||||
|     interrupts(); |     interrupts(); | ||||||
|  |  | ||||||
|  |     // ---------- буфер пуст: фронтов нет, проверяем тайм-аут ---------- | ||||||
|  |     // if (currentFrontPtr == nullptr) | ||||||
|  |     // { | ||||||
|  |     //     isSubBufferOverflow = false; | ||||||
|  |     //     return; | ||||||
|  |     // } | ||||||
|  |  | ||||||
|  |     // // ---------- есть фронт: продолжаем обработку ---------- | ||||||
|  |     // FrontStorage currentFront = *currentFrontPtr; | ||||||
|  |     lastEdgeTime = currentFront.time;     // запоминаем любой фронт | ||||||
|  |  | ||||||
|     //////////////////////////////////////////////////////////////////////////////////////////////////////////// |     //////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|     if (currentFront.dir) |     if (currentFront.dir) | ||||||
| @ -197,7 +230,7 @@ void IR_DecoderRaw::tick() | |||||||
|     digitalWrite(errOut, currentFront.dir); |     digitalWrite(errOut, currentFront.dir); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     if (currentFront.time > prevRise && currentFront.time - prevRise > IR_timeout * 2 && !isRecive) |     if (currentFront.time > prevRise && currentFront.time - prevRise > IR_timeout * 2 && !isReciveRaw) | ||||||
|     { // первый |     { // первый | ||||||
| #ifdef IRDEBUG | #ifdef IRDEBUG | ||||||
|         errPulse(up, 50); |         errPulse(up, 50); | ||||||
| @ -209,6 +242,7 @@ void IR_DecoderRaw::tick() | |||||||
|         isPreamb = true; |         isPreamb = true; | ||||||
|  |  | ||||||
|         isRecive = true; |         isRecive = true; | ||||||
|  |         isReciveRaw = true; | ||||||
|         isWrongPack = false; |         isWrongPack = false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -441,6 +475,8 @@ void IR_DecoderRaw::writeToBuffer(bool bit) | |||||||
|     if (isBufferOverflow || isPreamb || isWrongPack) |     if (isBufferOverflow || isPreamb || isWrongPack) | ||||||
|     { |     { | ||||||
|         isRecive = false; |         isRecive = false; | ||||||
|  |         isReciveRaw = false; | ||||||
|  |         msgTypeReceive = 0; | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -564,6 +600,8 @@ void IR_DecoderRaw::writeToBuffer(bool bit) | |||||||
|             packInfo.rTime = riseSyncTime; |             packInfo.rTime = riseSyncTime; | ||||||
|  |  | ||||||
|             isRecive = false; |             isRecive = false; | ||||||
|  |             isReciveRaw = false; | ||||||
|  |             msgTypeReceive = 0; | ||||||
|             isAvailable = crcCheck(packSize - crcBytes, crcValue); |             isAvailable = crcCheck(packSize - crcBytes, crcValue); | ||||||
|  |  | ||||||
| #ifdef BRUTEFORCE_CHECK | #ifdef BRUTEFORCE_CHECK | ||||||
| @ -594,6 +632,12 @@ void IR_DecoderRaw::writeToBuffer(bool bit) | |||||||
|         OUT_BRUTEFORCE:; |         OUT_BRUTEFORCE:; | ||||||
| #endif | #endif | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (packSize && (i_dataBuffer == 8)) { | ||||||
|  |             msgTypeReceive = (dataBuffer[0]>>5) | 0b11111000; | ||||||
|  |             // SerialUSB.println(msgTypeReceive & IR_MASK_MSG_TYPE); | ||||||
|  |  | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  | |||||||
| @ -31,9 +31,10 @@ class IR_DecoderRaw : virtual public IR_FOX | |||||||
|     friend IR_Encoder; |     friend IR_Encoder; | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|     PackInfo packInfo; | PackInfo packInfo; | ||||||
|     IR_Encoder *encoder; // Указатель на парный передатчик | uint8_t msgTypeReceive = 0; | ||||||
|     bool availableRaw(); | IR_Encoder *encoder; // Указатель на парный передатчик | ||||||
|  | bool availableRaw(); | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     ////////////////////////////////////////////////////////////////////////// |     ////////////////////////////////////////////////////////////////////////// | ||||||
| @ -48,7 +49,7 @@ public: | |||||||
|  |  | ||||||
|     inline bool isOverflow() { return isBufferOverflow; }; // Буффер переполнился |     inline bool isOverflow() { return isBufferOverflow; }; // Буффер переполнился | ||||||
|     bool isSubOverflow(); |     bool isSubOverflow(); | ||||||
|     inline bool isReciving() { return isBufferOverflow; }; // Возвращает true, если происходит приём пакета |     volatile inline bool isReciving() { return isRecive; }; // Возвращает true, если происходит приём пакета | ||||||
|  |  | ||||||
|     ////////////////////////////////////////////////////////////////////////// |     ////////////////////////////////////////////////////////////////////////// | ||||||
| private: | private: | ||||||
| @ -65,6 +66,8 @@ private: | |||||||
|  |  | ||||||
|     uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс |     uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс | ||||||
|  |  | ||||||
|  |     volatile uint32_t lastEdgeTime = 0;   // время последнего фронта | ||||||
|  |  | ||||||
|     //////////////////////////////////////////////////////////////////////// |     //////////////////////////////////////////////////////////////////////// | ||||||
|     volatile uint32_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов |     volatile uint32_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов | ||||||
|  |  | ||||||
| @ -100,7 +103,9 @@ private: | |||||||
|     int16_t bufBitPos = 0;         // Позиция для записи бита в буффер |     int16_t bufBitPos = 0;         // Позиция для записи бита в буффер | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     void listenStart(); // @brief Слушатель для работы isReciving() | bool isReciveRaw; | ||||||
|  |     void listenStart(); | ||||||
|  |     void checkTimeout();                  //  | ||||||
|  |  | ||||||
|     /// @brief Проверка CRC. Проверяет len байт со значением crc, пришедшим в пакете |     /// @brief Проверка CRC. Проверяет len байт со значением crc, пришедшим в пакете | ||||||
|     /// @param len Длина в байтах проверяемых данных |     /// @param len Длина в байтах проверяемых данных | ||||||
|  | |||||||
							
								
								
									
										156
									
								
								IR_Encoder.cpp
									
									
									
									
									
								
							
							
						
						
									
										156
									
								
								IR_Encoder.cpp
									
									
									
									
									
								
							| @ -38,6 +38,8 @@ IR_Encoder::IR_Encoder(uint8_t pin, uint16_t addr, IR_DecoderRaw *decPair, bool | |||||||
|         last->next = this; |         last->next = this; | ||||||
|         } |         } | ||||||
|         last = this; |         last = this; | ||||||
|  |          | ||||||
|  |         pinMode(pin, OUTPUT); | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|   |   | ||||||
| @ -126,20 +128,21 @@ void IR_Encoder::setBlindDecoders(IR_DecoderRaw *decoders[], uint8_t count) | |||||||
|  |  | ||||||
| IR_Encoder::~IR_Encoder(){}; | IR_Encoder::~IR_Encoder(){}; | ||||||
|  |  | ||||||
| void IR_Encoder::sendData(uint16_t addrTo, uint8_t dataByte, bool needAccept) | IR_SendResult IR_Encoder::sendData(uint16_t addrTo, uint8_t dataByte, bool needAccept) | ||||||
| { | { | ||||||
|     sendData(addrTo, &dataByte, 1, needAccept); |     return sendData(addrTo, &dataByte, 1, needAccept); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_Encoder::sendData(uint16_t addrTo, uint8_t *data, uint8_t len, bool needAccept){ | IR_SendResult IR_Encoder::sendData(uint16_t addrTo, uint8_t *data, uint8_t len, bool needAccept){ | ||||||
|     sendDataFULL(id, addrTo, data, len, needAccept); |     return sendDataFULL(id, addrTo, data, len, needAccept); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_Encoder::sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8_t *data, uint8_t len, bool needAccept) | IR_SendResult IR_Encoder::sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8_t *data, uint8_t len, bool needAccept) | ||||||
| { | { | ||||||
|     if (len > bytePerPack) |     if (len > bytePerPack) | ||||||
|     { |     { | ||||||
|         return; |         Serial.println("IR Pack to big"); | ||||||
|  |         return IR_SendResult(false, 0); | ||||||
|     } |     } | ||||||
|     constexpr uint8_t dataStart = msgBytes + addrBytes + addrBytes; |     constexpr uint8_t dataStart = msgBytes + addrBytes + addrBytes; | ||||||
|     memset(sendBuffer, 0x00, dataByteSizeMax); |     memset(sendBuffer, 0x00, dataByteSizeMax); | ||||||
| @ -168,6 +171,19 @@ void IR_Encoder::sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8_t *data, | |||||||
|     sendBuffer[packSize - crcBytes] = crc8(sendBuffer, 0, packSize - crcBytes, poly1) & 0xFF; |     sendBuffer[packSize - crcBytes] = crc8(sendBuffer, 0, packSize - crcBytes, poly1) & 0xFF; | ||||||
|     sendBuffer[packSize - crcBytes + 1] = crc8(sendBuffer, 0, packSize - crcBytes + 1, poly2) & 0xFF; |     sendBuffer[packSize - crcBytes + 1] = crc8(sendBuffer, 0, packSize - crcBytes + 1, poly2) & 0xFF; | ||||||
|  |  | ||||||
|  |     //* вывод итогового буфера | ||||||
|  |     // Serial.print("IR SEND [len="); | ||||||
|  |     // Serial.print(packSize); | ||||||
|  |     // Serial.print("] : "); | ||||||
|  |     // for (uint8_t i = 0; i < packSize; i++) | ||||||
|  |     // { | ||||||
|  |     //     if (sendBuffer[i] < 0x10) | ||||||
|  |     //         Serial.print('0'); | ||||||
|  |     //     Serial.print(sendBuffer[i], HEX); | ||||||
|  |     //     Serial.print(' '); | ||||||
|  |     // } | ||||||
|  |     // Serial.println(); | ||||||
|  |  | ||||||
|     // if (decPair != nullptr) { |     // if (decPair != nullptr) { | ||||||
|     //     decPair->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); |     //     decPair->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT); | ||||||
|     //     if (decPair->isWaitingAccept) { |     //     if (decPair->isWaitingAccept) { | ||||||
| @ -177,9 +193,14 @@ void IR_Encoder::sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8_t *data, | |||||||
|  |  | ||||||
|     // отправка |     // отправка | ||||||
|     rawSend(sendBuffer, packSize); |     rawSend(sendBuffer, packSize); | ||||||
|  |      | ||||||
|  |     // Возвращаем результат отправки | ||||||
|  |     uint32_t sendTime = calculateSendTime(packSize); | ||||||
|  |     return IR_SendResult(true, sendTime); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_Encoder::sendAccept(uint16_t addrTo, uint8_t customByte) |  | ||||||
|  | IR_SendResult IR_Encoder::sendAccept(uint16_t addrTo, uint8_t customByte) | ||||||
| { | { | ||||||
|     constexpr uint8_t packsize = msgBytes + addrBytes + 1U + crcBytes; |     constexpr uint8_t packsize = msgBytes + addrBytes + 1U + crcBytes; | ||||||
|     memset(sendBuffer, 0x00, dataByteSizeMax); |     memset(sendBuffer, 0x00, dataByteSizeMax); | ||||||
| @ -200,9 +221,13 @@ void IR_Encoder::sendAccept(uint16_t addrTo, uint8_t customByte) | |||||||
|     sendBuffer[5] = crc8(sendBuffer, 0, 5, poly2) & 0xFF; |     sendBuffer[5] = crc8(sendBuffer, 0, 5, poly2) & 0xFF; | ||||||
|  |  | ||||||
|     rawSend(sendBuffer, packsize); |     rawSend(sendBuffer, packsize); | ||||||
|  |      | ||||||
|  |     // Возвращаем результат отправки | ||||||
|  |     uint32_t sendTime = calculateSendTime(packsize); | ||||||
|  |     return IR_SendResult(true, sendTime); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_Encoder::sendRequest(uint16_t addrTo) | IR_SendResult IR_Encoder::sendRequest(uint16_t addrTo) | ||||||
| { | { | ||||||
|     constexpr uint8_t packsize = msgBytes + addrBytes + addrBytes + crcBytes; |     constexpr uint8_t packsize = msgBytes + addrBytes + addrBytes + crcBytes; | ||||||
|     memset(sendBuffer, 0x00, dataByteSizeMax); |     memset(sendBuffer, 0x00, dataByteSizeMax); | ||||||
| @ -222,28 +247,32 @@ void IR_Encoder::sendRequest(uint16_t addrTo) | |||||||
|     sendBuffer[6] = crc8(sendBuffer, 0, 6, poly2) & 0xFF; |     sendBuffer[6] = crc8(sendBuffer, 0, 6, poly2) & 0xFF; | ||||||
|  |  | ||||||
|     rawSend(sendBuffer, packsize); |     rawSend(sendBuffer, packsize); | ||||||
|  |      | ||||||
|  |     // Возвращаем результат отправки | ||||||
|  |     uint32_t sendTime = calculateSendTime(packsize); | ||||||
|  |     return IR_SendResult(true, sendTime); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_Encoder::sendBack(uint8_t data) | IR_SendResult IR_Encoder::sendBack(uint8_t data) | ||||||
| { | { | ||||||
|     _sendBack(false, 0, &data, 1); |     return _sendBack(false, 0, &data, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_Encoder::sendBack(uint8_t *data, uint8_t len) | IR_SendResult IR_Encoder::sendBack(uint8_t *data, uint8_t len) | ||||||
| { | { | ||||||
|     _sendBack(false, 0, data, len); |     return _sendBack(false, 0, data, len); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_Encoder::sendBackTo(uint16_t addrTo, uint8_t *data, uint8_t len) | IR_SendResult IR_Encoder::sendBackTo(uint16_t addrTo, uint8_t *data, uint8_t len) | ||||||
| { | { | ||||||
|     _sendBack(true, addrTo, data, len); |     return _sendBack(true, addrTo, data, len); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len) | IR_SendResult IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len) | ||||||
| { | { | ||||||
|     if (len > bytePerPack) |     if (len > bytePerPack) | ||||||
|     { |     { | ||||||
|         return; |         return IR_SendResult(false, 0); | ||||||
|     } |     } | ||||||
|     memset(sendBuffer, 0x00, dataByteSizeMax); |     memset(sendBuffer, 0x00, dataByteSizeMax); | ||||||
|     uint8_t dataStart = msgBytes + addrBytes + (isAdressed ? addrBytes : 0); |     uint8_t dataStart = msgBytes + addrBytes + (isAdressed ? addrBytes : 0); | ||||||
| @ -275,6 +304,10 @@ void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint | |||||||
|  |  | ||||||
|     // отправка |     // отправка | ||||||
|     rawSend(sendBuffer, packSize); |     rawSend(sendBuffer, packSize); | ||||||
|  |      | ||||||
|  |     // Возвращаем результат отправки | ||||||
|  |     uint32_t sendTime = calculateSendTime(packSize); | ||||||
|  |     return IR_SendResult(true, sendTime); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_Encoder::setDecoder_isSending() | void IR_Encoder::setDecoder_isSending() | ||||||
| @ -299,6 +332,12 @@ void IR_Encoder::rawSend(uint8_t *ptr, uint8_t len) | |||||||
|         // TODO: Обработка повторной отправки |         // TODO: Обработка повторной отправки | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     // Проверка на переполнение буфера | ||||||
|  |     if (len > dataByteSizeMax) | ||||||
|  |     { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|     // Serial.println("START"); |     // Serial.println("START"); | ||||||
|     setDecoder_isSending(); |     setDecoder_isSending(); | ||||||
|  |  | ||||||
| @ -483,6 +522,91 @@ uint8_t IR_Encoder::bitLow[2] = { | |||||||
|     (bitPauseTakts / 2 + bitActiveTakts) * 2 - 1, |     (bitPauseTakts / 2 + bitActiveTakts) * 2 - 1, | ||||||
|     (bitPauseTakts)-1}; |     (bitPauseTakts)-1}; | ||||||
|  |  | ||||||
|  | uint32_t IR_Encoder::calculateSendTime(uint8_t packSize) const | ||||||
|  | { | ||||||
|  |     // Расчет времени отправки пакета в миллисекундах | ||||||
|  |      | ||||||
|  |     // Время преамбулы: preambPulse * 2 фронта * bitTakts тактов | ||||||
|  |     uint32_t preambTime = preambPulse * 2 * bitTakts; | ||||||
|  |      | ||||||
|  |     // Время данных: количество бит * bitTakts тактов | ||||||
|  |     uint32_t dataTime = packSize * 8 * bitTakts; | ||||||
|  |      | ||||||
|  |     // Время синхронизации: syncBits * 2 фронта * bitTakts тактов | ||||||
|  |     uint32_t syncTime = syncBits * 2 * bitTakts; | ||||||
|  |      | ||||||
|  |     // Общее время в тактах | ||||||
|  |     uint32_t totalTakts = preambTime + dataTime + syncTime; | ||||||
|  |      | ||||||
|  |     // Конвертируем в миллисекунды | ||||||
|  |     // carrierPeriod - период несущей в микросекундах | ||||||
|  |     // totalTakts * carrierPeriod / 1000 = время в миллисекундах | ||||||
|  |     uint32_t sendTimeMs = (totalTakts * carrierPeriod) / 1000; | ||||||
|  |      | ||||||
|  |     return sendTimeMs; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Функции для тестирования времени отправки без фактической отправки | ||||||
|  |  | ||||||
|  | uint32_t IR_Encoder::testSendTime(uint16_t addrTo, uint8_t dataByte, bool needAccept) const | ||||||
|  | { | ||||||
|  |     return testSendTime(addrTo, &dataByte, 1, needAccept); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint32_t IR_Encoder::testSendTime(uint16_t addrTo, uint8_t *data, uint8_t len, bool needAccept) const | ||||||
|  | { | ||||||
|  |     return testSendTimeFULL(id, addrTo, data, len, needAccept); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint32_t IR_Encoder::testSendTimeFULL(uint16_t addrFrom, uint16_t addrTo, uint8_t *data, uint8_t len, bool needAccept) const | ||||||
|  | { | ||||||
|  |     if (len > bytePerPack) | ||||||
|  |     { | ||||||
|  |         return 0; // Возвращаем 0 для недопустимого размера | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; | ||||||
|  |     return calculateSendTime(packSize); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint32_t IR_Encoder::testSendAccept(uint16_t addrTo, uint8_t customByte) const | ||||||
|  | { | ||||||
|  |     constexpr uint8_t packsize = msgBytes + addrBytes + 1U + crcBytes; | ||||||
|  |     return calculateSendTime(packsize); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint32_t IR_Encoder::testSendRequest(uint16_t addrTo) const | ||||||
|  | { | ||||||
|  |     constexpr uint8_t packsize = msgBytes + addrBytes + addrBytes + crcBytes; | ||||||
|  |     return calculateSendTime(packsize); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint32_t IR_Encoder::testSendBack(uint8_t data) const | ||||||
|  | { | ||||||
|  |     return testSendBack(false, 0, &data, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint32_t IR_Encoder::testSendBack(uint8_t *data, uint8_t len) const | ||||||
|  | { | ||||||
|  |     return testSendBack(false, 0, data, len); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint32_t IR_Encoder::testSendBackTo(uint16_t addrTo, uint8_t *data, uint8_t len) const | ||||||
|  | { | ||||||
|  |     return testSendBack(true, addrTo, data, len); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint32_t IR_Encoder::testSendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len) const | ||||||
|  | { | ||||||
|  |     if (len > bytePerPack) | ||||||
|  |     { | ||||||
|  |         return 0; // Возвращаем 0 для недопустимого размера | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     uint8_t packSize = msgBytes + addrBytes + (isAdressed ? addrBytes : 0) + min(uint8_t(1), len) + crcBytes; | ||||||
|  |     return calculateSendTime(packSize); | ||||||
|  | } | ||||||
|  |  | ||||||
| // uint8_t* IR_Encoder::bitHigh = new uint8_t[2]{ | // uint8_t* IR_Encoder::bitHigh = new uint8_t[2]{ | ||||||
| //         (bitPauseTakts) * 2 - 0, | //         (bitPauseTakts) * 2 - 0, | ||||||
| //         (bitActiveTakts) * 2 - 0}; | //         (bitActiveTakts) * 2 - 0}; | ||||||
|  | |||||||
							
								
								
									
										41
									
								
								IR_Encoder.h
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								IR_Encoder.h
									
									
									
									
									
								
							| @ -3,6 +3,15 @@ | |||||||
|  |  | ||||||
| // TODO: Отложенная передача после завершения приема | // TODO: Отложенная передача после завершения приема | ||||||
|  |  | ||||||
|  | // Структура для возврата результата отправки | ||||||
|  | struct IR_SendResult { | ||||||
|  |     bool success;           // Флаг успешности отправки | ||||||
|  |     uint32_t sendTimeMs;    // Время отправки пакета в миллисекундах | ||||||
|  |      | ||||||
|  |     IR_SendResult(bool success = false, uint32_t sendTimeMs = 0)  | ||||||
|  |         : success(success), sendTimeMs(sendTimeMs) {} | ||||||
|  | }; | ||||||
|  |  | ||||||
| class IR_DecoderRaw; | class IR_DecoderRaw; | ||||||
| class IR_Encoder : public IR_FOX | class IR_Encoder : public IR_FOX | ||||||
| { | { | ||||||
| @ -30,17 +39,29 @@ public: | |||||||
|     void setBlindDecoders(IR_DecoderRaw *decoders[], uint8_t count); |     void setBlindDecoders(IR_DecoderRaw *decoders[], uint8_t count); | ||||||
|     void rawSend(uint8_t *ptr, uint8_t len); |     void rawSend(uint8_t *ptr, uint8_t len); | ||||||
|  |  | ||||||
|     void sendData(uint16_t addrTo, uint8_t dataByte, bool needAccept = false); |     IR_SendResult sendData(uint16_t addrTo, uint8_t dataByte, bool needAccept = false); | ||||||
|     void sendData(uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0, bool needAccept = false); |     IR_SendResult sendData(uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0, bool needAccept = false); | ||||||
|     void sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0, bool needAccept = false); |     IR_SendResult sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0, bool needAccept = false); | ||||||
|  |  | ||||||
|  |  | ||||||
|     void sendAccept(uint16_t addrTo, uint8_t customByte = 0); |     IR_SendResult sendAccept(uint16_t addrTo, uint8_t customByte = 0); | ||||||
|     void sendRequest(uint16_t addrTo); |     IR_SendResult sendRequest(uint16_t addrTo); | ||||||
|  |  | ||||||
|     void sendBack(uint8_t data); |     IR_SendResult sendBack(uint8_t data); | ||||||
|     void sendBack(uint8_t *data = nullptr, uint8_t len = 0); |     IR_SendResult sendBack(uint8_t *data = nullptr, uint8_t len = 0); | ||||||
|     void sendBackTo(uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0); |     IR_SendResult sendBackTo(uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0); | ||||||
|  |  | ||||||
|  |     // Функция для тестирования времени отправки без фактической отправки | ||||||
|  |     uint32_t testSendTime(uint16_t addrTo, uint8_t dataByte, bool needAccept = false) const; | ||||||
|  |     uint32_t testSendTime(uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0, bool needAccept = false) const; | ||||||
|  |     uint32_t testSendTimeFULL(uint16_t addrFrom, uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0, bool needAccept = false) const; | ||||||
|  |     uint32_t testSendAccept(uint16_t addrTo, uint8_t customByte = 0) const; | ||||||
|  |     uint32_t testSendRequest(uint16_t addrTo) const; | ||||||
|  |     uint32_t testSendBack(uint8_t data) const; | ||||||
|  |     uint32_t testSendBack(uint8_t *data = nullptr, uint8_t len = 0) const; | ||||||
|  |     uint32_t testSendBackTo(uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0) const; | ||||||
|  |  | ||||||
|  |     inline bool isBusy() const { return isSending;} | ||||||
|  |  | ||||||
|  |  | ||||||
|     ~IR_Encoder(); |     ~IR_Encoder(); | ||||||
| @ -48,11 +69,13 @@ public: | |||||||
|  |  | ||||||
|     void _isr(); |     void _isr(); | ||||||
| private: | private: | ||||||
|     void _sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len); |     IR_SendResult _sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len); | ||||||
|  |  | ||||||
|     void setDecoder_isSending(); |     void setDecoder_isSending(); | ||||||
|     void sendByte(uint8_t byte, bool *prev, bool LOW_FIRST); |     void sendByte(uint8_t byte, bool *prev, bool LOW_FIRST); | ||||||
|     void addSync(bool *prev, bool *next); |     void addSync(bool *prev, bool *next); | ||||||
|  |     uint32_t calculateSendTime(uint8_t packSize) const; | ||||||
|  |     uint32_t testSendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len) const; | ||||||
|     void send_HIGH(bool = 1); |     void send_HIGH(bool = 1); | ||||||
|     void send_LOW(); |     void send_LOW(); | ||||||
|     void send_EMPTY(uint8_t count); |     void send_EMPTY(uint8_t count); | ||||||
|  | |||||||
| @ -52,7 +52,7 @@ msg type: | |||||||
|                                         //  | 01234567 | |                                         //  | 01234567 | | ||||||
|                                         //   ---------- |                                         //   ---------- | ||||||
|                                         //  | xxx..... | = тип сообщения |                                         //  | xxx..... | = тип сообщения | ||||||
|                                         //  | ...xxxxx | = длина (максимум 31 бита) |                                         //  | ...xxxxx | = длина (максимум 31 бита) - не больше 24 байт на тело пакета | ||||||
|                                         //   ---------- */ |                                         //   ---------- */ | ||||||
| #define IR_MSG_BACK 0U          //  | 000...... | = Задний сигнал машинки | #define IR_MSG_BACK 0U          //  | 000...... | = Задний сигнал машинки | ||||||
| #define IR_MSG_ACCEPT 1U        //  | 001..... | = подтверждение | #define IR_MSG_ACCEPT 1U        //  | 001..... | = подтверждение | ||||||
| @ -116,13 +116,13 @@ msg type: | |||||||
| typedef uint16_t crc_t; | typedef uint16_t crc_t; | ||||||
|  |  | ||||||
| // #define BRUTEFORCE_CHECK                            // Перепроверяет пакет на 1 битные ошибки //TODO: зависает | // #define BRUTEFORCE_CHECK                            // Перепроверяет пакет на 1 битные ошибки //TODO: зависает | ||||||
| #define bytePerPack 16 // колличество байтов в пакете | #define bytePerPack (31) // колличество байтов в пакете | ||||||
| #ifndef freeFrec | #ifndef freeFrec | ||||||
| #define freeFrec false | #define freeFrec false | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef subBufferSize | #ifndef subBufferSize | ||||||
| #define subBufferSize 50 // Буфер для складирования фронтов, пока их не обработают (передатчик) | #define subBufferSize 250 // Буфер для складирования фронтов, пока их не обработают (передатчик) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #define preambPulse 3 | #define preambPulse 3 | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	