diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index f8ab807..9393188 100644 --- a/IR_Encoder.cpp +++ b/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 = this; + + pinMode(pin, OUTPUT); } }; @@ -126,21 +128,21 @@ void IR_Encoder::setBlindDecoders(IR_DecoderRaw *decoders[], uint8_t count) 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){ - sendDataFULL(id, addrTo, data, len, needAccept); +IR_SendResult IR_Encoder::sendData(uint16_t addrTo, uint8_t *data, uint8_t len, bool 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) { Serial.println("IR Pack to big"); - return; + return IR_SendResult(false, 0); } constexpr uint8_t dataStart = msgBytes + addrBytes + addrBytes; memset(sendBuffer, 0x00, dataByteSizeMax); @@ -191,10 +193,14 @@ void IR_Encoder::sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8_t *data, // отправка 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; memset(sendBuffer, 0x00, dataByteSizeMax); @@ -215,9 +221,13 @@ void IR_Encoder::sendAccept(uint16_t addrTo, uint8_t customByte) sendBuffer[5] = crc8(sendBuffer, 0, 5, poly2) & 0xFF; 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; memset(sendBuffer, 0x00, dataByteSizeMax); @@ -237,28 +247,32 @@ void IR_Encoder::sendRequest(uint16_t addrTo) sendBuffer[6] = crc8(sendBuffer, 0, 6, poly2) & 0xFF; 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) { - return; + return IR_SendResult(false, 0); } memset(sendBuffer, 0x00, dataByteSizeMax); uint8_t dataStart = msgBytes + addrBytes + (isAdressed ? addrBytes : 0); @@ -290,6 +304,10 @@ void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint // отправка rawSend(sendBuffer, packSize); + + // Возвращаем результат отправки + uint32_t sendTime = calculateSendTime(packSize); + return IR_SendResult(true, sendTime); } void IR_Encoder::setDecoder_isSending() @@ -314,6 +332,12 @@ void IR_Encoder::rawSend(uint8_t *ptr, uint8_t len) // TODO: Обработка повторной отправки return; } + + // Проверка на переполнение буфера + if (len > dataByteSizeMax) + { + return; + } // Serial.println("START"); setDecoder_isSending(); @@ -498,6 +522,91 @@ uint8_t IR_Encoder::bitLow[2] = { (bitPauseTakts / 2 + bitActiveTakts) * 2 - 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]{ // (bitPauseTakts) * 2 - 0, // (bitActiveTakts) * 2 - 0}; diff --git a/IR_Encoder.h b/IR_Encoder.h index 8910c12..39b0334 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -3,6 +3,15 @@ // 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_Encoder : public IR_FOX { @@ -30,17 +39,27 @@ public: void setBlindDecoders(IR_DecoderRaw *decoders[], uint8_t count); void rawSend(uint8_t *ptr, uint8_t len); - void 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); - void sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0, bool needAccept = false); + IR_SendResult sendData(uint16_t addrTo, uint8_t dataByte, bool needAccept = false); + IR_SendResult sendData(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); - void sendRequest(uint16_t addrTo); + IR_SendResult sendAccept(uint16_t addrTo, uint8_t customByte = 0); + IR_SendResult sendRequest(uint16_t addrTo); - void sendBack(uint8_t data); - void sendBack(uint8_t *data = nullptr, uint8_t len = 0); - void sendBackTo(uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0); + IR_SendResult sendBack(uint8_t data); + IR_SendResult sendBack(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;} @@ -50,11 +69,13 @@ public: void _isr(); 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 sendByte(uint8_t byte, bool *prev, bool LOW_FIRST); 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_LOW(); void send_EMPTY(uint8_t count);