mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2025-05-04 07:10:16 +00:00
MultiGen isr
This commit is contained in:
parent
02410cc78c
commit
e0fbc8502d
147
IR_Encoder.cpp
147
IR_Encoder.cpp
@ -3,12 +3,18 @@
|
|||||||
|
|
||||||
IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) {
|
IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) {
|
||||||
ir_out = pin;
|
ir_out = pin;
|
||||||
|
pinMode(ir_out, OUTPUT);
|
||||||
addrSelf = addr;
|
addrSelf = addr;
|
||||||
decoder = decPair;
|
decoder = decPair;
|
||||||
carrierTune = tune;
|
carrierTune = tune;
|
||||||
halfPeriod = (carrierPeriod / 2) - carrierTune;
|
halfPeriod = (carrierPeriod / 2) - carrierTune;
|
||||||
|
dataBitCounter = 0 - preambFronts;
|
||||||
|
|
||||||
|
signal = noSignal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
IR_Encoder::~IR_Encoder() {};
|
IR_Encoder::~IR_Encoder() {};
|
||||||
|
|
||||||
void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) {
|
void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) {
|
||||||
@ -102,34 +108,105 @@ void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) {
|
void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) {
|
||||||
/*tmp*/bool LOW_FIRST = false;/*tmp*/
|
digitalToggle(9); digitalToggle(9);
|
||||||
|
isSending = true;
|
||||||
|
if (decoder != nullptr) { decoder->isPairSending = isSending; }
|
||||||
|
cli();
|
||||||
|
// toggleCounter = bitTakts*2 - 1;
|
||||||
|
#define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1)
|
||||||
|
// #define preambToggle (3*2-1)
|
||||||
|
toggleCounter = preambToggle;
|
||||||
|
preambBitCounter = preambPulse;
|
||||||
|
dataBitCounter = 0;
|
||||||
|
syncBitCounter = 0;
|
||||||
|
|
||||||
if (decoder != nullptr) { decoder->isPairSending = true; }
|
signal = preamb;
|
||||||
|
isSending = true;
|
||||||
|
state = HIGH;
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
bool prev = 1;
|
|
||||||
bool next;
|
|
||||||
|
|
||||||
send_EMPTY(preambPulse); // преамбула
|
void IR_Encoder::isr() {
|
||||||
for (uint16_t byteNum = 0; byteNum < len; byteNum++) {
|
if (!isSending) return;
|
||||||
sendByte(ptr[byteNum], &prev, LOW_FIRST);
|
|
||||||
if (byteNum < len - 1) {
|
ir_out_virtual = !ir_out_virtual && state;
|
||||||
next = ptr[byteNum + 1] & (LOW_FIRST ? 0b00000001 : 0b10000000);
|
|
||||||
} else {
|
|
||||||
next = 0;
|
if (!toggleCounter) {
|
||||||
|
|
||||||
|
state = !state;
|
||||||
|
|
||||||
|
switch (signal) {
|
||||||
|
case noSignal:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case preamb:
|
||||||
|
toggleCounter = preambToggle;
|
||||||
|
if (!state) { // Низкий уровень - конец периода генерации
|
||||||
|
preambBitCounter--;
|
||||||
|
if (!preambBitCounter) { // Конец преамбулы, переход на следующий этап
|
||||||
|
isSending = false;
|
||||||
}
|
}
|
||||||
addSync(&prev, &next);
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case data:
|
||||||
|
signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sync:
|
||||||
|
signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoder != nullptr) { decoder->isPairSending = false; }
|
} else { toggleCounter--; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void old() {///////////////////////////////////////////////////////
|
||||||
|
// 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) {
|
void IR_Encoder::sendByte(uint8_t byte, bool* prev, bool LOW_FIRST) {
|
||||||
uint8_t mask = LOW_FIRST ? 0b00000001 : 0b10000000;
|
uint8_t mask = LOW_FIRST ? 0b00000001 : 0b10000000;
|
||||||
for (uint8_t bitShift = 8; bitShift; bitShift--) {
|
for (uint8_t bitShift = 8; bitShift; bitShift--) {
|
||||||
|
digitalWrite(9, HIGH);
|
||||||
|
digitalWrite(9, LOW);
|
||||||
byte& mask ? send_HIGH(prev) : send_LOW();
|
byte& mask ? send_HIGH(prev) : send_LOW();
|
||||||
*prev = byte & mask;
|
*prev = byte & mask;
|
||||||
LOW_FIRST ? mask <<= 1 : mask >>= 1;
|
LOW_FIRST ? mask <<= 1 : mask >>= 1;
|
||||||
|
digitalWrite(9, HIGH);
|
||||||
|
digitalWrite(9, LOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,39 +229,29 @@ void IR_Encoder::addSync(bool* prev, bool* next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IR_Encoder::send_HIGH(bool prevBite = 1) {
|
void IR_Encoder::send_HIGH(bool prevBite = 1) {
|
||||||
if (prevBite) {
|
|
||||||
meanderBlock(bitPauseTakts * 2, halfPeriod, LOW);
|
// if (/* prevBite */1) {
|
||||||
meanderBlock(bitActiveTakts, halfPeriod, HIGH);
|
// meanderBlock(bitPauseTakts * 2, halfPeriod, LOW);
|
||||||
} else { // более короткий HIGH после нуля
|
// meanderBlock(bitActiveTakts, halfPeriod, HIGH);
|
||||||
meanderBlock(bitTakts - (bitActiveTakts - bitPauseTakts), halfPeriod, LOW);
|
// } else { // более короткий HIGH после нуля
|
||||||
meanderBlock(bitActiveTakts - bitPauseTakts, halfPeriod, HIGH);
|
// meanderBlock(bitTakts - (bitActiveTakts - bitPauseTakts), halfPeriod, LOW);
|
||||||
}
|
// meanderBlock(bitActiveTakts - bitPauseTakts, halfPeriod, HIGH);
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IR_Encoder::send_LOW() {
|
void IR_Encoder::send_LOW() {
|
||||||
meanderBlock(bitPauseTakts, halfPeriod, LOW);
|
// meanderBlock(bitPauseTakts, halfPeriod, LOW);
|
||||||
meanderBlock(bitActiveTakts, halfPeriod, LOW);
|
// meanderBlock(bitActiveTakts, halfPeriod, LOW);
|
||||||
meanderBlock(bitPauseTakts, halfPeriod, HIGH);
|
// meanderBlock(bitPauseTakts, halfPeriod, HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IR_Encoder::send_EMPTY(uint8_t count) {
|
void IR_Encoder::send_EMPTY(uint8_t count) {
|
||||||
for (size_t i = 0; i < count * 2; i++) {
|
// for (size_t i = 0; i < count * 2; i++) {
|
||||||
meanderBlock(bitPauseTakts * 2 + bitActiveTakts, halfPeriod, prevPreambBit);
|
// meanderBlock((bitPauseTakts * 2 + bitActiveTakts), halfPeriod, prevPreambBit);
|
||||||
prevPreambBit = !prevPreambBit;
|
// prevPreambBit = !prevPreambBit;
|
||||||
}
|
// }
|
||||||
|
// meanderBlock(bitPauseTakts * 2 + bitActiveTakts, halfPeriod, 0); //TODO: Отодвинуть преамбулу
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
53
IR_Encoder.h
53
IR_Encoder.h
@ -6,22 +6,16 @@
|
|||||||
class IR_Decoder;
|
class IR_Decoder;
|
||||||
class IR_Encoder : IR_FOX {
|
class IR_Encoder : IR_FOX {
|
||||||
friend IR_Decoder;
|
friend IR_Decoder;
|
||||||
|
friend void isr(IR_Encoder& e);
|
||||||
public:
|
public:
|
||||||
/// @brief Вывод передатчика
|
|
||||||
uint8_t ir_out;
|
|
||||||
|
|
||||||
/// @brief Адрес передатчика
|
uint8_t ir_out; /// @brief Вывод передатчика
|
||||||
uint16_t addrSelf;
|
uint16_t addrSelf; /// @brief Адрес передатчика
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// @brief предыдущий бит преамбулы
|
uint8_t carrierTune; /// @brief Подстройка несущей частоты
|
||||||
bool prevPreambBit = true;
|
uint8_t halfPeriod; /// @brief полупериод несущей частоты
|
||||||
|
|
||||||
/// @brief Подстройка несущей частоты
|
|
||||||
uint8_t carrierTune;
|
|
||||||
|
|
||||||
/// @brief полупериод несущей частоты
|
|
||||||
uint8_t halfPeriod;
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @brief Класс передатчика
|
/// @brief Класс передатчика
|
||||||
@ -35,23 +29,50 @@ public:
|
|||||||
void sendData(uint16_t addrTo, T& data, bool needAccept = false);
|
void sendData(uint16_t addrTo, T& data, bool needAccept = false);
|
||||||
void sendACK(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false);
|
void sendACK(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false);
|
||||||
void sendRequest(uint16_t addrTo, uint8_t addInfo = 0);
|
void sendRequest(uint16_t addrTo, uint8_t addInfo = 0);
|
||||||
|
void rawSend(uint8_t* ptr, uint8_t len);
|
||||||
|
void isr();
|
||||||
|
|
||||||
~IR_Encoder();
|
~IR_Encoder();
|
||||||
|
volatile bool ir_out_virtual;
|
||||||
private:
|
private:
|
||||||
IR_Decoder* decoder;
|
IR_Decoder* decoder;
|
||||||
void meanderBlock(uint16_t count, uint16_t _period, bool isNoPause = true);
|
void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType);
|
||||||
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);
|
||||||
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);
|
||||||
void rawSend(uint8_t* ptr, uint8_t len);
|
|
||||||
void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType);
|
enum SignalPart : uint8_t {
|
||||||
|
noSignal = 0,
|
||||||
|
preamb = 1,
|
||||||
|
data = 2, // 2 должен инвертироваться в sync
|
||||||
|
sync = (uint8_t)~(uint8_t)2U // 253 должен инвертироваться в data
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
volatile bool isSending = false;
|
||||||
|
// volatile bool genState = HIGH;
|
||||||
|
|
||||||
|
volatile bool state; /// @brief Текущий уровень генерации
|
||||||
|
volatile uint8_t toggleCounter; /// @brief Счётчик переключений
|
||||||
|
volatile uint8_t preambBitCounter;
|
||||||
|
volatile uint8_t dataBitCounter;
|
||||||
|
volatile uint8_t syncBitCounter;
|
||||||
|
|
||||||
|
volatile uint8_t preambFrontCounter;
|
||||||
|
volatile uint8_t dataFrontCounter;
|
||||||
|
volatile uint8_t syncFrontCounter;
|
||||||
|
|
||||||
|
// uint8_t bitSequence[2];
|
||||||
|
// volatile uint32_t toggle_counter;
|
||||||
|
|
||||||
|
SignalPart signal;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -106,10 +106,10 @@ typedef uint16_t crc_t;
|
|||||||
#define carrierPeriod (1000000U/carrierFrec) // период несущей в us
|
#define carrierPeriod (1000000U/carrierFrec) // период несущей в us
|
||||||
|
|
||||||
// В процессе работы значения будут отклонятся в соответствии с предыдущим битом
|
// В процессе работы значения будут отклонятся в соответствии с предыдущим битом
|
||||||
#define bitActiveTakts 25U // длительность единицы в тактах
|
#define bitActiveTakts 25U // длительность высокого уровня в тактах
|
||||||
#define bitPauseTakts 6U // длительность нуля в тактах
|
#define bitPauseTakts 6U // длительность низкого уровня в тактах
|
||||||
|
|
||||||
#define bitTakts (bitActiveTakts+bitPauseTakts*2U) // Общая длительность бита в тактах
|
#define bitTakts (bitActiveTakts+(bitPauseTakts*2U)) // Общая длительность бита в тактах
|
||||||
#define bitTime (bitTakts*carrierPeriod) // Общая длительность бита
|
#define bitTime (bitTakts*carrierPeriod) // Общая длительность бита
|
||||||
#define tolerance 300U
|
#define tolerance 300U
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user