mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2025-06-27 20:59:37 +00:00
v1.00
This commit is contained in:
186
IR_Encoder.cpp
Normal file
186
IR_Encoder.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
#include "IR_Encoder.h"
|
||||
#include "IR_Decoder.h"
|
||||
|
||||
#define halfPeriod ((carrierPeriod / 2) - 5) //13 //8 // 14 при работе с регистрами, 14 -6 = 8 для digitalWrite()
|
||||
const auto _x_ = halfPeriod;
|
||||
|
||||
IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, IR_Decoder* decPair) : ir_out(pin), addrSelf(addr), decoder(decPair) {};
|
||||
IR_Encoder::~IR_Encoder() {};
|
||||
|
||||
void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) {
|
||||
uint8_t* ptr = new uint8_t[msgBytes + addrBytes + crcBytes] { 0 };
|
||||
|
||||
ptr[0] = IR_MSG_ACCEPT << 5;
|
||||
ptr[0] |= addInfo & IR_MASK_MSG_INFO;
|
||||
|
||||
// addr_self
|
||||
if (!forAll) {
|
||||
ptr[1] = addrSelf >> 8 & 0xFF;
|
||||
ptr[2] = addrSelf & 0xFF;
|
||||
}
|
||||
|
||||
// data crc
|
||||
ptr[3] = crc8(ptr, 0, 3, poly1) & 0xFF;
|
||||
ptr[4] = crc8(ptr, 0, 4, poly2) & 0xFF;
|
||||
|
||||
rawSend(ptr, msgBytes + addrBytes + crcBytes);
|
||||
|
||||
// освобождение ресурсов
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
void IR_Encoder::sendRequest(uint16_t addrTo, uint8_t addInfo) {
|
||||
uint8_t* ptr = new uint8_t[msgBytes + addrBytes + crcBytes] { 0 };
|
||||
|
||||
ptr[0] = IR_MSG_REQUEST << 5;
|
||||
ptr[0] |= addInfo & IR_MASK_MSG_INFO;
|
||||
|
||||
// addr_self
|
||||
ptr[1] = addrSelf >> 8 & 0xFF;
|
||||
ptr[2] = addrSelf & 0xFF;
|
||||
|
||||
//addr_to
|
||||
ptr[3] = addrTo >> 8 & 0xFF;
|
||||
ptr[4] = addrTo & 0xFF;
|
||||
|
||||
// data crc
|
||||
ptr[5] = crc8(ptr, 0, 5, poly1) & 0xFF;
|
||||
ptr[6] = crc8(ptr, 0, 6, poly2) & 0xFF;
|
||||
|
||||
rawSend(ptr, msgBytes + addrBytes + addrBytes + crcBytes);
|
||||
|
||||
// освобождение ресурсов
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType) {
|
||||
|
||||
uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes;
|
||||
uint8_t dataStart = msgBytes + addrBytes + addrBytes;
|
||||
|
||||
// создание массива для отправки
|
||||
uint8_t* ptr = new uint8_t[packSize] { 0 };
|
||||
//memset(ptr, 0, sizeof(ptr));
|
||||
|
||||
// формирование массива
|
||||
// msg_type
|
||||
ptr[0] = msgType;
|
||||
|
||||
// addr_self
|
||||
ptr[1] = addrSelf >> 8 & 0xFF;
|
||||
ptr[2] = addrSelf & 0xFF;
|
||||
|
||||
// addr_to
|
||||
ptr[3] = addrTo >> 8 & 0xFF;
|
||||
ptr[4] = addrTo & 0xFF;
|
||||
|
||||
for (uint16_t i = dataStart; i < dataStart + len; i++) {
|
||||
ptr[i] = ((uint8_t*)data)[i - dataStart];
|
||||
}
|
||||
|
||||
// data crc
|
||||
ptr[packSize - crcBytes] = crc8(ptr, 0, packSize - crcBytes, poly1) & 0xFF;
|
||||
ptr[packSize - crcBytes + 1] = crc8(ptr, 0, packSize - crcBytes + 1, poly2) & 0xFF;
|
||||
|
||||
if (decoder != nullptr) {
|
||||
decoder->isWaitingAccept = ((msgType >> 5) & IR_MASK_MSG_TYPE == IR_MSG_DATA_ACCEPT);
|
||||
decoder->addrWaitingFrom = addrTo;
|
||||
}
|
||||
// отправка
|
||||
rawSend(ptr, packSize);
|
||||
|
||||
// освобождение ресурсов
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
|
||||
}
|
||||
|
||||
void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) {
|
||||
/*tmp*/bool LOW_FIRST = false;/*tmp*/
|
||||
|
||||
if (decoder != nullptr) { decoder->isPairSending = true; }
|
||||
|
||||
bool prev = 1;
|
||||
bool next;
|
||||
|
||||
send_EMPTY(preambPulse); // преамбула
|
||||
for (uint16_t byteNum = 0; byteNum < len; byteNum++) {
|
||||
sendByte(ptr[byteNum], &prev, LOW_FIRST);
|
||||
if (byteNum < len - 1) {
|
||||
next = ptr[byteNum + 1] & (LOW_FIRST ? 0b00000001 : 0b10000000);
|
||||
} else {
|
||||
next = 0;
|
||||
}
|
||||
addSync(&prev, &next);
|
||||
}
|
||||
|
||||
if (decoder != nullptr) { decoder->isPairSending = false; }
|
||||
|
||||
}
|
||||
|
||||
void IR_Encoder::sendByte(uint8_t byte, bool* prev, bool LOW_FIRST) {
|
||||
uint8_t mask = LOW_FIRST ? 0b00000001 : 0b10000000;
|
||||
for (uint8_t bitShift = 8; bitShift; bitShift--) {
|
||||
byte& mask ? send_HIGH(prev) : send_LOW();
|
||||
*prev = byte & mask;
|
||||
LOW_FIRST ? mask <<= 1 : mask >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void IR_Encoder::addSync(bool* prev, bool* next) {
|
||||
switch (syncBits) {
|
||||
case 0: break;
|
||||
case 1:
|
||||
*prev ? send_LOW() : send_HIGH();
|
||||
*prev = !*prev;
|
||||
break;
|
||||
default:
|
||||
for (int16_t i = 0; i < syncBits - 1; i++) {
|
||||
*prev ? send_LOW() : send_HIGH();
|
||||
*prev = !*prev;
|
||||
}
|
||||
*next ? send_LOW() : send_HIGH(0);
|
||||
*prev = !*next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void IR_Encoder::send_HIGH(bool prevBite = 1) {
|
||||
if (prevBite) {
|
||||
meanderBlock(bitPauseTakts * 2, halfPeriod, LOW);
|
||||
meanderBlock(bitActiveTakts, halfPeriod, HIGH);
|
||||
} else { // более короткий HIGH после нуля
|
||||
meanderBlock(bitTakts - (bitActiveTakts - bitPauseTakts), halfPeriod, LOW);
|
||||
meanderBlock(bitActiveTakts - bitPauseTakts, halfPeriod, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
void IR_Encoder::send_LOW() {
|
||||
meanderBlock(bitPauseTakts, halfPeriod, LOW);
|
||||
meanderBlock(bitActiveTakts, halfPeriod, LOW);
|
||||
meanderBlock(bitPauseTakts, halfPeriod, HIGH);
|
||||
}
|
||||
|
||||
void IR_Encoder::send_EMPTY(uint8_t count) {
|
||||
for (size_t i = 0; i < count * 2; i++) {
|
||||
meanderBlock(bitPauseTakts * 2 + bitActiveTakts, halfPeriod, prevPreambBit);
|
||||
prevPreambBit = !prevPreambBit;
|
||||
}
|
||||
}
|
||||
|
||||
void IR_Encoder::meanderBlock(uint16_t count, uint16_t _period, bool high = true) {
|
||||
for (uint16_t i = 0; i < count << 1; i++) {
|
||||
|
||||
if ((i & 1)) { // Если чётное
|
||||
//PORTC &= ~(1 << 3); // LOW
|
||||
digitalWrite(ir_out, high ? LOW : LOW);
|
||||
} else { // Если не четное
|
||||
//PORTC |= 1 << 3; // HIGH
|
||||
digitalWrite(ir_out, high ? HIGH : LOW);
|
||||
}
|
||||
|
||||
delayMicroseconds(_period);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user