mirror of
				https://github.com/Show-maket/IR-protocol.git
				synced 2025-10-30 18:42:35 +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