mirror of
				https://github.com/Show-maket/IR-protocol.git
				synced 2025-10-30 18:42:35 +00:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			d1c84ba18a
			...
			RPI
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 01e2da6334 | |||
| 5efa3d3ba5 | |||
| e8e2cd60c2 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,5 +1,5 @@ | |||||||
| .vscode/* | .vscode/* | ||||||
| bin/* | bin/* | ||||||
|  | !.vscode/arduino.json | ||||||
| !.vscode/launch.json | !.vscode/launch.json | ||||||
| log/* | log/* | ||||||
| /.vscode |  | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								.vscode/arduino.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.vscode/arduino.json
									
									
									
									
										vendored
									
									
								
							| @ -1,5 +1,8 @@ | |||||||
| { | { | ||||||
|     "board": "STMicroelectronics:stm32:GenF4", |     "configuration": "flash=2097152_0,freq=133,opt=Small,rtti=Disabled,stackprotect=Disabled,exceptions=Disabled,dbgport=Disabled,dbglvl=None,usbstack=picosdk,ipbtstack=ipv4only,uploadmethod=default", | ||||||
|  |     "board": "rp2040:rp2040:rpipico", | ||||||
|     "port": "COM17", |     "port": "COM17", | ||||||
|     "prebuild": "if exist bin rd /s /q bin" |     "output": "bin", | ||||||
|  |     "prebuild": "if exist bin rd /s /q bin", | ||||||
|  |     "sketch": "IR-protocol.ino" | ||||||
| } | } | ||||||
							
								
								
									
										277
									
								
								IR-protocol.ino
									
									
									
									
									
								
							
							
						
						
									
										277
									
								
								IR-protocol.ino
									
									
									
									
									
								
							| @ -1,27 +1,44 @@ | |||||||
| #include "IR_Decoder.h" | #include "IR_Decoder.h" | ||||||
| #include "IR_Encoder.h" | #include "IR_Encoder.h" | ||||||
| #include "TimerStatic.h" | #include "TimerStatic.h" | ||||||
| #include "MemoryCheck.h" | // #include "MemoryCheck.h" | ||||||
| /////////////// Pinout /////////////// | /////////////// Pinout /////////////// | ||||||
|  |  | ||||||
| #define dec0_PIN PIN_KT1_IN | #define dec0_PIN 0 | ||||||
| #define dec1_PIN PIN_KT2_IN | #define dec1_PIN 1 | ||||||
| #define dec2_PIN PIN_KT3_IN | #define dec2_PIN 2 | ||||||
| #define dec3_PIN PIN_KT4_IN | #define dec3_PIN 3 | ||||||
| #define dec4_PIN PIN_KT5_IN | #define dec4_PIN 4 | ||||||
| #define dec5_PIN PIN_KT6_IN | #define dec5_PIN 5 | ||||||
| #define dec6_PIN PIN_KT7_IN | #define dec6_PIN 6 | ||||||
| #define dec7_PIN PIN_KT8_IN | #define dec7_PIN 7 | ||||||
| // #define dec8_PIN PB8 | #define dec8_PIN 8 | ||||||
| // #define dec9_PIN PB9 | #define dec9_PIN 9 | ||||||
| // #define dec10_PIN PB10 | #define dec10_PIN 10 | ||||||
| // #define dec11_PIN PB11 | #define dec11_PIN 11 | ||||||
| // #define dec12_PIN PB12 | #define dec12_PIN 12 | ||||||
| // #define dec13_PIN PB13 | #define dec13_PIN 13 | ||||||
| // #define dec14_PIN PB14 | #define dec14_PIN 14 | ||||||
| // #define dec15_PIN PB15 | #define dec15_PIN 15 | ||||||
|  |  | ||||||
| #define LoopOut PC13 | #define LoopOut 16 | ||||||
|  | #define LoopOut1 17 | ||||||
|  |  | ||||||
|  | #define dec_ISR(n) \ | ||||||
|  |     void dec_##n##_ISR() { dec##n.isr(); } | ||||||
|  | #define dec_Ini(n)                      \ | ||||||
|  |     IR_Decoder dec##n(dec##n##_PIN, n); \ | ||||||
|  |     dec_ISR(n) | ||||||
|  |  | ||||||
|  | #define decPinMode(n) pinMode(dec##n##_PIN, INPUT_PULLUP); | ||||||
|  | #define decAttach(n) attachInterrupt(dec##n##_PIN, dec_##n##_ISR, CHANGE); | ||||||
|  | #define decSetup(n) /* decPinMode(n); */ decAttach(n); | ||||||
|  | #define decTick(n) dec##n.tick(); | ||||||
|  | #define decStat(n) rx_flag |= statusSimple(dec##n); | ||||||
|  |  | ||||||
|  | void digitalToggle(uint8_t pin){ | ||||||
|  |     digitalWrite(pin, !digitalRead(pin)); | ||||||
|  | } | ||||||
|  |  | ||||||
| //////////////// Ini ///////////////// | //////////////// Ini ///////////////// | ||||||
|  |  | ||||||
| @ -31,11 +48,11 @@ | |||||||
| //////////////// Var ///////////////// | //////////////// Var ///////////////// | ||||||
| // IR_Encoder encForward(PA5, 42 /* , &decBackward */); | // IR_Encoder encForward(PA5, 42 /* , &decBackward */); | ||||||
|  |  | ||||||
| IR_Encoder enc0(PIN_KT8_OUT, 42 /* , &decBackward */); | IR_Encoder enc0(18, 42 /* , &decBackward */); | ||||||
| // IR_Encoder enc1(PA1, 127 /* , &decBackward */); | IR_Encoder enc1(19, 127 /* , &decBackward */); | ||||||
| // IR_Encoder enc2(PA2, 137 /* , &decBackward */); | IR_Encoder enc2(20, 137 /* , &decBackward */); | ||||||
| // IR_Encoder enc3(PA3, 777 /* , &decBackward */); | IR_Encoder enc3(21, 777 /* , &decBackward */); | ||||||
| // IR_Encoder enc10(PA4, 555 /* , &decBackward */); | // IR_Encoder enc10(PC15, 555 /* , &decBackward */); | ||||||
| // IR_Encoder enc11(PC14, 127 /* , &decBackward */); | // IR_Encoder enc11(PC14, 127 /* , &decBackward */); | ||||||
| // IR_Encoder enc12(PC13, 137 /* , &decBackward */); | // IR_Encoder enc12(PC13, 137 /* , &decBackward */); | ||||||
| // IR_Encoder enc13(PA12, 777 /* , &decBackward */); | // IR_Encoder enc13(PA12, 777 /* , &decBackward */); | ||||||
| @ -47,51 +64,26 @@ IR_Encoder enc0(PIN_KT8_OUT, 42 /* , &decBackward */); | |||||||
| void EncoderISR() | void EncoderISR() | ||||||
| { | { | ||||||
|     IR_Encoder::isr(); |     IR_Encoder::isr(); | ||||||
|  |     // digitalToggle(LoopOut); | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------- | //------------------------------------------------------------------- | ||||||
|  |  | ||||||
| IR_Decoder dec0(dec0_PIN, 0); | dec_Ini(0); | ||||||
| void dec_0_ISR() { dec0.isr(); } | dec_Ini(1); | ||||||
|  | dec_Ini(2); | ||||||
| IR_Decoder dec1(dec1_PIN, 1); | dec_Ini(3); | ||||||
| void dec_1_ISR() { dec1.isr(); } | dec_Ini(4); | ||||||
|  | dec_Ini(5); | ||||||
| IR_Decoder dec2(dec2_PIN, 2); | dec_Ini(6); | ||||||
| void dec_2_ISR() { dec2.isr(); } | dec_Ini(7); | ||||||
|  | dec_Ini(8); | ||||||
| IR_Decoder dec3(dec3_PIN, 3); | dec_Ini(9); | ||||||
| void dec_3_ISR() { dec3.isr(); } | dec_Ini(10); | ||||||
|  | dec_Ini(11); | ||||||
| IR_Decoder dec4(dec4_PIN, 4); | dec_Ini(12); | ||||||
| void dec_4_ISR() { dec4.isr(); } | dec_Ini(13); | ||||||
|  |  | ||||||
| IR_Decoder dec5(dec5_PIN, 5); |  | ||||||
| void dec_5_ISR() { dec5.isr(); } |  | ||||||
|  |  | ||||||
| IR_Decoder dec6(dec6_PIN, 6); |  | ||||||
| void dec_6_ISR() { dec6.isr(); } |  | ||||||
|  |  | ||||||
| IR_Decoder dec7(dec7_PIN, 7); |  | ||||||
| void dec_7_ISR() { dec7.isr(); } |  | ||||||
|  |  | ||||||
| // IR_Decoder dec8(dec8_PIN, 8); |  | ||||||
| // void dec_8_ISR() { dec8.isr(); } |  | ||||||
|  |  | ||||||
| // IR_Decoder dec9(dec9_PIN, 9); |  | ||||||
| // void dec_9_ISR() { dec9.isr(); } |  | ||||||
|  |  | ||||||
| // IR_Decoder dec10(dec10_PIN, 10); |  | ||||||
| // void dec_10_ISR() { dec10.isr(); } |  | ||||||
|  |  | ||||||
| // IR_Decoder dec11(dec11_PIN, 11); |  | ||||||
| // void dec_11_ISR() { dec11.isr(); } |  | ||||||
|  |  | ||||||
| // IR_Decoder dec12(dec12_PIN, 12); |  | ||||||
| // void dec_12_ISR() { dec12.isr(); } |  | ||||||
|  |  | ||||||
| // IR_Decoder dec13(dec13_PIN, 13); |  | ||||||
| // void dec_13_ISR() { dec13.isr(); } |  | ||||||
|  |  | ||||||
| ///////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////// | ||||||
| uint8_t data0[] = {}; | uint8_t data0[] = {}; | ||||||
| @ -103,14 +95,13 @@ uint8_t data4[] = {42, 127, 137, 255}; | |||||||
| uint32_t loopTimer; | uint32_t loopTimer; | ||||||
| uint8_t sig = 0; | uint8_t sig = 0; | ||||||
| uint16_t targetAddr = IR_Broadcast; | uint16_t targetAddr = IR_Broadcast; | ||||||
|  |  | ||||||
| Timer t1(500, millis, []() | Timer t1(500, millis, []() | ||||||
|          { |          { | ||||||
|              // Serial.println( digitalPinToBitMask(enc0.getPin()), BIN); |              // Serial.println( digitalPinToBitMask(enc0.getPin()), BIN); | ||||||
|             //  enc0.sendData(IR_Broadcast, data4, sizeof(data4)); |              enc0.sendData(IR_Broadcast, data4, sizeof(data4)); | ||||||
|             //  enc1.sendData(IR_Broadcast, data3, sizeof(data3)); |              enc1.sendData(IR_Broadcast, data3, sizeof(data3)); | ||||||
|             //  enc2.sendData(IR_Broadcast, data2, sizeof(data2)); |              enc2.sendData(IR_Broadcast, data2, sizeof(data2)); | ||||||
|             //  enc3.sendData(IR_Broadcast, data1, sizeof(data1)); |              enc3.sendData(IR_Broadcast, data1, sizeof(data1)); | ||||||
|             //  enc10.sendData(IR_Broadcast, data4, sizeof(data4)); |             //  enc10.sendData(IR_Broadcast, data4, sizeof(data4)); | ||||||
|              //  enc11.sendData(IR_Broadcast, data3, sizeof(data3)); |              //  enc11.sendData(IR_Broadcast, data3, sizeof(data3)); | ||||||
|              //  enc12.sendData(IR_Broadcast, data2, sizeof(data2)); |              //  enc12.sendData(IR_Broadcast, data2, sizeof(data2)); | ||||||
| @ -197,78 +188,114 @@ Timer t1(500, millis, []() | |||||||
|              // encBackward.sendData(IR_Broadcast, data2); |              // encBackward.sendData(IR_Broadcast, data2); | ||||||
|              // encTree.sendData(IR_Broadcast, rawData3); |              // encTree.sendData(IR_Broadcast, rawData3); | ||||||
|          }); |          }); | ||||||
|  |  | ||||||
| // Timer t2(50, millis, []() | // Timer t2(50, millis, []() | ||||||
| //          { digitalToggle(LED_BUILTIN); }); | //          { digitalToggle(LED_BUILTIN); }); | ||||||
|  |  | ||||||
| Timer signalDetectTimer; | Timer signalDetectTimer; | ||||||
| ///////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////// | ||||||
| HardwareTimer IR_Timer(TIM3); | // HardwareTimer IR_Timer(TIM3); | ||||||
|  | // RPI_PICO_Timer  IR_Timer(0); | ||||||
|  | struct repeating_timer timer; | ||||||
|  |  | ||||||
|  | bool TimerISRHandler(struct repeating_timer *t){ | ||||||
|  |     (void) t; | ||||||
|  |     EncoderISR(); | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
| void setup() | void setup() | ||||||
| { | { | ||||||
|     IR_Timer.setOverflow(carrierFrec * 2, HERTZ_FORMAT); |     pinMode(LoopOut1, OUTPUT); | ||||||
|     IR_Timer.attachInterrupt(1, EncoderISR); |     add_repeating_timer_us(6, TimerISRHandler, NULL, &timer); | ||||||
|     NVIC_SetPriority(IRQn_Type::TIM3_IRQn, 0); |  | ||||||
|     IR_Timer.resume(); |     // IR_Timer.setOverflow(carrierFrec * 2, HERTZ_FORMAT); | ||||||
|  |     // IR_Timer.attachInterrupt(1, EncoderISR); | ||||||
|  |     // NVIC_SetPriority(IRQn_Type::TIM3_IRQn, 0); | ||||||
|  |     // IR_Timer.resume(); | ||||||
|  |  | ||||||
|     Serial.begin(SERIAL_SPEED); |     Serial.begin(SERIAL_SPEED); | ||||||
|     Serial.println(F(INFO)); |     Serial.println(F(INFO)); | ||||||
|  |  | ||||||
|     pinMode(LoopOut, OUTPUT); |     pinMode(LoopOut, OUTPUT); | ||||||
|  |     // pinMode(SignalDetectLed, OUTPUT); | ||||||
|  |  | ||||||
|     pinMode(dec0_PIN, INPUT_PULLUP); |  | ||||||
|     pinMode(dec1_PIN, INPUT_PULLUP); |     pinMode(dec1_PIN, INPUT_PULLUP); | ||||||
|     pinMode(dec2_PIN, INPUT_PULLUP); |     // pinMode(dec2_PIN, INPUT_PULLUP); | ||||||
|     pinMode(dec3_PIN, INPUT_PULLUP); |  | ||||||
|     pinMode(dec4_PIN, INPUT_PULLUP); |  | ||||||
|     pinMode(dec5_PIN, INPUT_PULLUP); |  | ||||||
|     pinMode(dec6_PIN, INPUT_PULLUP); |  | ||||||
|     pinMode(dec7_PIN, INPUT_PULLUP); |  | ||||||
|     // pinMode(dec8_PIN, INPUT_PULLUP); |  | ||||||
|     // pinMode(dec9_PIN, INPUT_PULLUP); |  | ||||||
|     // pinMode(dec10_PIN, INPUT_PULLUP); |  | ||||||
|     // pinMode(dec11_PIN, INPUT_PULLUP); |  | ||||||
|     // pinMode(dec12_PIN, INPUT_PULLUP); |  | ||||||
|     // pinMode(dec13_PIN, INPUT_PULLUP); |  | ||||||
|  |  | ||||||
|     attachInterrupt(dec0_PIN, dec_0_ISR, CHANGE); |     static IR_DecoderRaw *blind[]{ | ||||||
|     attachInterrupt(dec1_PIN, dec_1_ISR, CHANGE); |         &dec0, | ||||||
|     attachInterrupt(dec2_PIN, dec_2_ISR, CHANGE); |         &dec1, | ||||||
|     attachInterrupt(dec3_PIN, dec_3_ISR, CHANGE); |         &dec2, | ||||||
|     attachInterrupt(dec4_PIN, dec_4_ISR, CHANGE); |         &dec3, | ||||||
|     attachInterrupt(dec5_PIN, dec_5_ISR, CHANGE); |         &dec4, | ||||||
|     attachInterrupt(dec6_PIN, dec_6_ISR, CHANGE); |         &dec5, | ||||||
|     attachInterrupt(dec7_PIN, dec_7_ISR, CHANGE); |         &dec6, | ||||||
|     // attachInterrupt(dec8_PIN, dec_8_ISR, CHANGE); |         &dec7, | ||||||
|     // attachInterrupt(dec9_PIN, dec_9_ISR, CHANGE); |         &dec8, | ||||||
|     // attachInterrupt(dec10_PIN, dec_10_ISR, CHANGE); |         &dec9, | ||||||
|     // attachInterrupt(dec11_PIN, dec_11_ISR, CHANGE); |         &dec10, | ||||||
|     // attachInterrupt(dec12_PIN, dec_12_ISR, CHANGE); |         &dec11, | ||||||
|     // attachInterrupt(dec13_PIN, dec_13_ISR, CHANGE); |         &dec12, | ||||||
|  |         &dec13, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     // enc0.setBlindDecoders(blind, sizeof(blind) / sizeof(IR_DecoderRaw *)); | ||||||
|  |     // enc1.setBlindDecoders(blind, sizeof(blind) / sizeof(IR_DecoderRaw *)); | ||||||
|  |     // enc2.setBlindDecoders(blind, sizeof(blind) / sizeof(IR_DecoderRaw *)); | ||||||
|  |     // enc3.setBlindDecoders(blind, sizeof(blind) / sizeof(IR_DecoderRaw *)); | ||||||
|  |     // enc10.setBlindDecoders(blind, sizeof(blind) / sizeof(IR_DecoderRaw *)); | ||||||
|  |  | ||||||
|  |     decSetup(0); | ||||||
|  |     // decSetup(1); | ||||||
|  |     // decSetup(2); | ||||||
|  |     // decSetup(3); | ||||||
|  |     // decSetup(4); | ||||||
|  |     // decSetup(5); | ||||||
|  |     // decSetup(6); | ||||||
|  |     // decSetup(7); | ||||||
|  |     // decSetup(8); | ||||||
|  |     // decSetup(9); | ||||||
|  |     // decSetup(10); | ||||||
|  |     decSetup(11); | ||||||
|  |     decSetup(12); | ||||||
|  |     decSetup(13); | ||||||
| } | } | ||||||
|  |  | ||||||
| void loop() | void loop() | ||||||
| { | { | ||||||
|     digitalToggle(LoopOut); |     digitalToggle(LoopOut); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void loop1() | ||||||
|  | { | ||||||
|     Timer::tick(); |     Timer::tick(); | ||||||
|     IR_Decoder::tick(); |     IR_Decoder::tick(); | ||||||
|  |  | ||||||
|     bool rx_flag = false; |     bool rx_flag; | ||||||
|     rx_flag |= status(dec0); |     decStat(0); | ||||||
|     rx_flag |= status(dec1); |     decStat(1); | ||||||
|     rx_flag |= status(dec2); |     decStat(2); | ||||||
|     rx_flag |= status(dec3); |     decStat(3); | ||||||
|     rx_flag |= status(dec4); |     decStat(4); | ||||||
|     rx_flag |= status(dec5); |     decStat(5); | ||||||
|     rx_flag |= status(dec6); |     decStat(6); | ||||||
|     rx_flag |= status(dec7); |     decStat(7); | ||||||
|     // rx_flag |= status(dec8); |     decStat(8); | ||||||
|     // rx_flag |= status(dec9); |     decStat(9); | ||||||
|     // rx_flag |= status(dec10); |     decStat(10); | ||||||
|     // rx_flag |= status(dec11); |     decStat(11); | ||||||
|     // rx_flag |= status(dec12); |     decStat(12); | ||||||
|     // rx_flag |= status(dec13); |     decStat(13); | ||||||
|  |  | ||||||
|  |     // status(decForward); | ||||||
|  |     // status(decBackward); | ||||||
|  |  | ||||||
|  |     // Serial.println(micros() - loopTimer); | ||||||
|  |     // loopTimer = micros(); | ||||||
|  |     // delayMicroseconds(120*5); | ||||||
|  |  | ||||||
|     if (Serial.available()) |     if (Serial.available()) | ||||||
|     { |     { | ||||||
| @ -284,14 +311,25 @@ void loop() | |||||||
|         case 102: |         case 102: | ||||||
|             targetAddr = 777; |             targetAddr = 777; | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         default: |         default: | ||||||
|             sig = in; |             sig = in; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  |         Serial.println(in); | ||||||
|     } |     } | ||||||
|  |     digitalToggle(LoopOut1); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Timer statusSimpleDelay; | Timer statusSimpleDelay; | ||||||
| bool statusSimple(IR_Decoder &dec) | bool statusSimple(IR_Decoder &dec) | ||||||
| { | { | ||||||
| @ -317,12 +355,12 @@ void detectSignal() | |||||||
| } | } | ||||||
|  |  | ||||||
| // test | // test | ||||||
| bool status(IR_Decoder &dec) | void status(IR_Decoder &dec) | ||||||
| { | { | ||||||
|     if (dec.gotData.available()) |     if (dec.gotData.available()) | ||||||
|     { |     { | ||||||
|         detectSignal(); |         detectSignal(); | ||||||
|         // Serial.println(micros()); |         Serial.println(micros()); | ||||||
|         String str; |         String str; | ||||||
|         if (/* dec.gotData.getDataPrt()[1] */ 1) |         if (/* dec.gotData.getDataPrt()[1] */ 1) | ||||||
|         { |         { | ||||||
| @ -568,5 +606,4 @@ bool status(IR_Decoder &dec) | |||||||
|         // obj->resetAvailable(); |         // obj->resetAvailable(); | ||||||
|         Serial.write(str.c_str()); |         Serial.write(str.c_str()); | ||||||
|     } |     } | ||||||
|     return false; |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,50 +1,17 @@ | |||||||
| #include "IR_Decoder.h" | #include "IR_Decoder.h" | ||||||
|  |  | ||||||
| std::list<IR_Decoder *> &IR_Decoder::get_dec_list() // определение функции | std::list<IR_Decoder*>& IR_Decoder::get_dec_list() // определение функции | ||||||
| { | { | ||||||
|     static std::list<IR_Decoder *> dec_list; // статическая локальная переменная |     static std::list<IR_Decoder*> dec_list; // статическая локальная переменная | ||||||
|     return dec_list; // возвращается ссылка на переменную |     return dec_list; // возвращается ссылка на переменную | ||||||
| } | } | ||||||
|  |  | ||||||
| // IR_Decoder::IR_Decoder() {}; | IR_Decoder::IR_Decoder(const uint8_t pin, uint16_t addr, IR_Encoder *encPair) | ||||||
| IR_Decoder::IR_Decoder(const uint8_t pin, uint16_t addr, IR_Encoder *encPair, bool autoHandle) |  | ||||||
|     : IR_DecoderRaw(pin, addr, encPair) |     : IR_DecoderRaw(pin, addr, encPair) | ||||||
| { | { | ||||||
|     get_dec_list().push_back(this); |     get_dec_list().push_back(this); | ||||||
|     if(autoHandle){ |  | ||||||
|         enable(); |  | ||||||
|     } |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| void IR_Decoder::enable() |  | ||||||
| { |  | ||||||
|     auto &dec_list = get_dec_list(); |  | ||||||
|     if (std::find(dec_list.begin(), dec_list.end(), this) == dec_list.end()) |  | ||||||
|     { |  | ||||||
|         dec_list.push_back(this); |  | ||||||
|     } |  | ||||||
|     pinMode(pin, INPUT_PULLUP); |  | ||||||
|     attachInterrupt(pin, (*this)(), CHANGE); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void IR_Decoder::disable() |  | ||||||
| { |  | ||||||
|     detachInterrupt(pin); |  | ||||||
|     pinMode(pin, INPUT); |  | ||||||
|     auto &dec_list = get_dec_list(); |  | ||||||
|     auto it = std::find(dec_list.begin(), dec_list.end(), this); |  | ||||||
|     if (it != dec_list.end()) |  | ||||||
|     { |  | ||||||
|         dec_list.erase(it); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| std::function<void()> IR_Decoder::operator()() |  | ||||||
| { |  | ||||||
|     return std::bind(&IR_Decoder::isr, this); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| IR_Decoder::~IR_Decoder() | IR_Decoder::~IR_Decoder() | ||||||
| { | { | ||||||
|     IR_Decoder::get_dec_list().remove(this); |     IR_Decoder::get_dec_list().remove(this); | ||||||
| @ -61,7 +28,6 @@ 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 | ||||||
| @ -98,13 +64,9 @@ void IR_Decoder::_tick() | |||||||
|         } |         } | ||||||
|         gotRaw.set(&packInfo, id); |         gotRaw.set(&packInfo, id); | ||||||
|     } |     } | ||||||
|     if (isWaitingAcceptSend && millis() - acceptSendTimer > acceptDelay) |     if (isWaitingAcceptSend && millis() - acceptSendTimer > 75) | ||||||
|     { |     { | ||||||
|         encoder->sendAccept(addrAcceptSendTo, acceptCustomByte); |         encoder->sendAccept(addrAcceptSendTo, acceptCustomByte); | ||||||
|         isWaitingAcceptSend = false; |         isWaitingAcceptSend = false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| bool IR_Decoder::isReceive(uint8_t type) { |  | ||||||
|     return (msgTypeReceive & 0b11111000) && ((msgTypeReceive & IR_MASK_MSG_TYPE) == type); |  | ||||||
| }  |  | ||||||
|  | |||||||
							
								
								
									
										13
									
								
								IR_Decoder.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								IR_Decoder.h
									
									
									
									
									
								
							| @ -14,7 +14,7 @@ private: | |||||||
|     bool isWaitingAcceptSend; |     bool isWaitingAcceptSend; | ||||||
|     uint16_t addrAcceptSendTo; |     uint16_t addrAcceptSendTo; | ||||||
|  |  | ||||||
|     uint16_t acceptDelay = IR_ResponseDelay; |     uint16_t acceptDelay = 75; | ||||||
|     uint8_t acceptCustomByte; |     uint8_t acceptCustomByte; | ||||||
|  |  | ||||||
| public: | public: | ||||||
| @ -24,16 +24,7 @@ public: | |||||||
|     PacketTypes::Request gotRequest; |     PacketTypes::Request gotRequest; | ||||||
|     PacketTypes::BasePack gotRaw; |     PacketTypes::BasePack gotRaw; | ||||||
|  |  | ||||||
|     // IR_Decoder(); |     IR_Decoder(const uint8_t pin, uint16_t addr, IR_Encoder *encPair = nullptr); | ||||||
|     IR_Decoder(const uint8_t pin, uint16_t addr = 0, IR_Encoder *encPair = nullptr, bool autoHandle = true); |  | ||||||
|  |  | ||||||
|     std::function<void()> operator()(); |  | ||||||
|  |  | ||||||
|     void enable(); |  | ||||||
|     void disable(); |  | ||||||
|      |  | ||||||
|     bool isReceive(uint8_t type); |  | ||||||
|  |  | ||||||
|     ~IR_Decoder(); |     ~IR_Decoder(); | ||||||
|  |  | ||||||
|     static void tick(); |     static void tick(); | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ | |||||||
| IR_DecoderRaw::IR_DecoderRaw(const uint8_t pin, uint16_t addr, IR_Encoder *encPair) : encoder(encPair) | IR_DecoderRaw::IR_DecoderRaw(const uint8_t pin, uint16_t addr, IR_Encoder *encPair) : encoder(encPair) | ||||||
| { | { | ||||||
|     setPin(pin); |     setPin(pin); | ||||||
|  |     pinMode(pin, INPUT_PULLUP); | ||||||
|     id = addr; |     id = addr; | ||||||
|     prevRise = prevFall = prevPrevFall = prevPrevRise = 0; |     prevRise = prevFall = prevPrevFall = prevPrevRise = 0; | ||||||
|     if (encPair != nullptr) |     if (encPair != nullptr) | ||||||
| @ -47,7 +48,7 @@ volatile uint32_t time_; | |||||||
|  |  | ||||||
| void IR_DecoderRaw::isr() | void IR_DecoderRaw::isr() | ||||||
| { | { | ||||||
|     // Serial.print("ISR\n"); |  | ||||||
|     if(isPairSending){ |     if(isPairSending){ | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| @ -58,7 +59,6 @@ void IR_DecoderRaw::isr() | |||||||
|     interrupts(); |     interrupts(); | ||||||
|     if (time_ < oldTime) |     if (time_ < oldTime) | ||||||
|     { |     { | ||||||
|  |  | ||||||
| #ifdef IRDEBUG | #ifdef IRDEBUG | ||||||
|         Serial.print("\n"); |         Serial.print("\n"); | ||||||
|         Serial.print("count:         "); |         Serial.print("count:         "); | ||||||
| @ -75,7 +75,8 @@ void IR_DecoderRaw::isr() | |||||||
|     oldTime = time_; |     oldTime = time_; | ||||||
|  |  | ||||||
|     FrontStorage edge; |     FrontStorage edge; | ||||||
|     edge.dir = port->IDR & mask; |     // edge.dir = port->IDR & mask; | ||||||
|  |     edge.dir = digitalRead(pin); | ||||||
|     edge.time = time_; |     edge.time = time_; | ||||||
|  |  | ||||||
|     subBuffer.push(edge); |     subBuffer.push(edge); | ||||||
| @ -112,37 +113,16 @@ void IR_DecoderRaw::firstRX() | |||||||
|  |  | ||||||
| void IR_DecoderRaw::listenStart() | void IR_DecoderRaw::listenStart() | ||||||
| { | { | ||||||
|     if (isReciveRaw && ((micros() - prevRise) > IR_timeout * 2)) |     if (isRecive && ((micros() - prevRise) > IR_timeout * 2)) | ||||||
|     { |     { | ||||||
|         // Serial.print("\nlis>"); |         // Serial.print("\nlis>"); | ||||||
|         isReciveRaw = false; |         isRecive = 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(); | ||||||
| @ -151,24 +131,12 @@ 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) | ||||||
| @ -230,7 +198,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 && !isReciveRaw) |     if (currentFront.time > prevRise && currentFront.time - prevRise > IR_timeout * 2 && !isRecive) | ||||||
|     { // первый |     { // первый | ||||||
| #ifdef IRDEBUG | #ifdef IRDEBUG | ||||||
|         errPulse(up, 50); |         errPulse(up, 50); | ||||||
| @ -242,7 +210,6 @@ void IR_DecoderRaw::tick() | |||||||
|         isPreamb = true; |         isPreamb = true; | ||||||
|  |  | ||||||
|         isRecive = true; |         isRecive = true; | ||||||
|         isReciveRaw = true; |  | ||||||
|         isWrongPack = false; |         isWrongPack = false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -475,8 +442,6 @@ void IR_DecoderRaw::writeToBuffer(bool bit) | |||||||
|     if (isBufferOverflow || isPreamb || isWrongPack) |     if (isBufferOverflow || isPreamb || isWrongPack) | ||||||
|     { |     { | ||||||
|         isRecive = false; |         isRecive = false; | ||||||
|         isReciveRaw = false; |  | ||||||
|         msgTypeReceive = 0; |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -600,8 +565,6 @@ 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 | ||||||
| @ -632,12 +595,6 @@ 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); |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  | |||||||
| @ -23,7 +23,6 @@ | |||||||
| #define riseTimeMin (riseTime - riseTolerance) | #define riseTimeMin (riseTime - riseTolerance) | ||||||
| #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) | #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) | ||||||
| #define IR_timeout (riseTimeMax * (8 + syncBits + 1)) // us // таймаут в 8 data + 3 sync + 1 | #define IR_timeout (riseTimeMax * (8 + syncBits + 1)) // us // таймаут в 8 data + 3 sync + 1 | ||||||
| constexpr uint16_t IR_ResponseDelay = ((uint16_t)(((bitTime+riseTolerance) * (8 + syncBits + 1))*2.7735))/1000; |  | ||||||
|  |  | ||||||
| class IR_Encoder; | class IR_Encoder; | ||||||
| class IR_DecoderRaw : virtual public IR_FOX | class IR_DecoderRaw : virtual public IR_FOX | ||||||
| @ -31,10 +30,9 @@ class IR_DecoderRaw : virtual public IR_FOX | |||||||
|     friend IR_Encoder; |     friend IR_Encoder; | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
| PackInfo packInfo; |     PackInfo packInfo; | ||||||
| uint8_t msgTypeReceive = 0; |     IR_Encoder *encoder; // Указатель на парный передатчик | ||||||
| IR_Encoder *encoder; // Указатель на парный передатчик |     bool availableRaw(); | ||||||
| bool availableRaw(); |  | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     ////////////////////////////////////////////////////////////////////////// |     ////////////////////////////////////////////////////////////////////////// | ||||||
| @ -49,7 +47,7 @@ public: | |||||||
|  |  | ||||||
|     inline bool isOverflow() { return isBufferOverflow; }; // Буффер переполнился |     inline bool isOverflow() { return isBufferOverflow; }; // Буффер переполнился | ||||||
|     bool isSubOverflow(); |     bool isSubOverflow(); | ||||||
|     volatile inline bool isReciving() { return isRecive; }; // Возвращает true, если происходит приём пакета |     inline bool isReciving() { return isBufferOverflow; }; // Возвращает true, если происходит приём пакета | ||||||
|  |  | ||||||
|     ////////////////////////////////////////////////////////////////////////// |     ////////////////////////////////////////////////////////////////////////// | ||||||
| private: | private: | ||||||
| @ -66,8 +64,6 @@ private: | |||||||
|  |  | ||||||
|     uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс |     uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс | ||||||
|  |  | ||||||
|     volatile uint32_t lastEdgeTime = 0;   // время последнего фронта |  | ||||||
|  |  | ||||||
|     //////////////////////////////////////////////////////////////////////// |     //////////////////////////////////////////////////////////////////////// | ||||||
|     volatile uint32_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов |     volatile uint32_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов | ||||||
|  |  | ||||||
| @ -103,9 +99,7 @@ private: | |||||||
|     int16_t bufBitPos = 0;         // Позиция для записи бита в буффер |     int16_t bufBitPos = 0;         // Позиция для записи бита в буффер | ||||||
|  |  | ||||||
| private: | private: | ||||||
| bool isReciveRaw; |     void listenStart(); // @brief Слушатель для работы isReciving() | ||||||
|     void listenStart(); |  | ||||||
|     void checkTimeout();                  //  |  | ||||||
|  |  | ||||||
|     /// @brief Проверка CRC. Проверяет len байт со значением crc, пришедшим в пакете |     /// @brief Проверка CRC. Проверяет len байт со значением crc, пришедшим в пакете | ||||||
|     /// @param len Длина в байтах проверяемых данных |     /// @param len Длина в байтах проверяемых данных | ||||||
|  | |||||||
							
								
								
									
										310
									
								
								IR_Encoder.cpp
									
									
									
									
									
								
							
							
						
						
									
										310
									
								
								IR_Encoder.cpp
									
									
									
									
									
								
							| @ -5,12 +5,16 @@ | |||||||
| #define ISR_Out 10 | #define ISR_Out 10 | ||||||
| #define TestOut 13 | #define TestOut 13 | ||||||
|  |  | ||||||
| IR_Encoder *IR_Encoder::head = nullptr; | std::list<IR_Encoder*>& IR_Encoder::get_enc_list() // определение функции | ||||||
| IR_Encoder *IR_Encoder::last = nullptr; | { | ||||||
|  |     static std::list<IR_Encoder*> dec_list; // статическая локальная переменная | ||||||
|  |     return dec_list; // возвращается ссылка на переменную | ||||||
|  | } | ||||||
|  |  | ||||||
| IR_Encoder::IR_Encoder(uint8_t pin, uint16_t addr, IR_DecoderRaw *decPair, bool autoHandle) | IR_Encoder::IR_Encoder(uint8_t pin, uint16_t addr, IR_DecoderRaw *decPair) | ||||||
| { | { | ||||||
|     setPin(pin); |     setPin(pin); | ||||||
|  |     pinMode(pin,OUTPUT); | ||||||
|     id = addr; |     id = addr; | ||||||
|     this->decPair = decPair; |     this->decPair = decPair; | ||||||
|     signal = noSignal; |     signal = noSignal; | ||||||
| @ -18,7 +22,8 @@ IR_Encoder::IR_Encoder(uint8_t pin, uint16_t addr, IR_DecoderRaw *decPair, bool | |||||||
| #if disablePairDec | #if disablePairDec | ||||||
|     if (decPair != nullptr) |     if (decPair != nullptr) | ||||||
|     { |     { | ||||||
|         blindDecoders = new IR_DecoderRaw *[1]{decPair}; |         blindDecoders = new IR_DecoderRaw *[1] | ||||||
|  |         { decPair }; | ||||||
|         decodersCount = 1; |         decodersCount = 1; | ||||||
|     } |     } | ||||||
| #endif | #endif | ||||||
| @ -26,96 +31,9 @@ IR_Encoder::IR_Encoder(uint8_t pin, uint16_t addr, IR_DecoderRaw *decPair, bool | |||||||
|     { |     { | ||||||
|         decPair->encoder = this; |         decPair->encoder = this; | ||||||
|     } |     } | ||||||
|  |     get_enc_list().push_back(this); | ||||||
|     if (autoHandle) |  | ||||||
|     { |  | ||||||
|         if (IR_Encoder::head == nullptr) |  | ||||||
|         { |  | ||||||
|         IR_Encoder::head = this; |  | ||||||
|         } |  | ||||||
|         if (last != nullptr) |  | ||||||
|         { |  | ||||||
|         last->next = this; |  | ||||||
|         } |  | ||||||
|         last = this; |  | ||||||
|          |  | ||||||
|         pinMode(pin, OUTPUT); |  | ||||||
|     } |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| HardwareTimer* IR_Encoder::IR_Timer = nullptr; |  | ||||||
|  |  | ||||||
| inline HardwareTimer* IR_Encoder::get_IR_Timer(){return IR_Encoder::IR_Timer;} |  | ||||||
|  |  | ||||||
| void IR_Encoder::begin(HardwareTimer* timer, uint8_t channel, IRQn_Type IRQn, uint8_t priority, void(*isrCallback)()){ |  | ||||||
|     IR_Timer = timer; |  | ||||||
|     if(IR_Timer == nullptr) return; |  | ||||||
|     IR_Timer->setOverflow(carrierFrec * 2, HERTZ_FORMAT); |  | ||||||
|     IR_Timer->attachInterrupt(channel, (isrCallback == nullptr ? IR_Encoder::isr : isrCallback)); |  | ||||||
|     NVIC_SetPriority(IRQn, priority); |  | ||||||
|     IR_Timer->resume(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void IR_Encoder::enable() |  | ||||||
| { |  | ||||||
|     bool exist = false; |  | ||||||
|     IR_Encoder *current = IR_Encoder::head; |  | ||||||
|     while (current != nullptr) |  | ||||||
|     { |  | ||||||
|         exist = (current == this); |  | ||||||
|         if (exist) break; |  | ||||||
|         current = current->next; |  | ||||||
|     } |  | ||||||
|     if (!exist) |  | ||||||
|     { |  | ||||||
|         if (IR_Encoder::head == nullptr) |  | ||||||
|         { |  | ||||||
|             IR_Encoder::head = this; |  | ||||||
|             last = this; |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|         { |  | ||||||
|             last->next = this; |  | ||||||
|             last = this; |  | ||||||
|         } |  | ||||||
|         this->next = nullptr; // Указываем, что следующий за этим элементом — nullptr |  | ||||||
|     } |  | ||||||
|     pinMode(pin, OUTPUT); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void IR_Encoder::disable() |  | ||||||
| { |  | ||||||
|     IR_Encoder *current = IR_Encoder::head; |  | ||||||
|     IR_Encoder *prev = nullptr; |  | ||||||
|  |  | ||||||
|     while (current != nullptr) |  | ||||||
|     { |  | ||||||
|         if (current == this) break; |  | ||||||
|         prev = current; |  | ||||||
|         current = current->next; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (current != nullptr) // Элемент найден в списке |  | ||||||
|     { |  | ||||||
|         if (prev != nullptr) |  | ||||||
|         { |  | ||||||
|             prev->next = current->next; // Убираем текущий элемент из списка |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|         { |  | ||||||
|             IR_Encoder::head = current->next; // Удаляемый элемент был первым |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (current == last) |  | ||||||
|         { |  | ||||||
|             last = prev; // Если удаляется последний элемент, обновляем last |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     pinMode(pin, INPUT); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void IR_Encoder::setBlindDecoders(IR_DecoderRaw *decoders[], uint8_t count) | void IR_Encoder::setBlindDecoders(IR_DecoderRaw *decoders[], uint8_t count) | ||||||
| { | { | ||||||
| #if disablePairDec | #if disablePairDec | ||||||
| @ -126,23 +44,26 @@ void IR_Encoder::setBlindDecoders(IR_DecoderRaw *decoders[], uint8_t count) | |||||||
|     blindDecoders = decoders; |     blindDecoders = decoders; | ||||||
| } | } | ||||||
|  |  | ||||||
| IR_Encoder::~IR_Encoder(){}; | IR_Encoder::~IR_Encoder() | ||||||
|  |  | ||||||
| IR_SendResult IR_Encoder::sendData(uint16_t addrTo, uint8_t dataByte, bool needAccept) |  | ||||||
| { | { | ||||||
|     return sendData(addrTo, &dataByte, 1, needAccept); |     delete[] bitLow; | ||||||
|  |     delete[] bitHigh; | ||||||
|  |     get_enc_list().remove(this); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void IR_Encoder::sendData(uint16_t addrTo, uint8_t dataByte, bool needAccept) | ||||||
|  | { | ||||||
|  |     uint8_t *dataPtr = new uint8_t[1]; | ||||||
|  |     dataPtr[0] = dataByte; | ||||||
|  |     sendData(addrTo, dataPtr, 1, needAccept); | ||||||
|  |     delete[] dataPtr; | ||||||
| } | } | ||||||
|  |  | ||||||
| IR_SendResult IR_Encoder::sendData(uint16_t addrTo, uint8_t *data, uint8_t len, bool needAccept){ | void IR_Encoder::sendData(uint16_t addrTo, uint8_t *data, uint8_t len, bool needAccept) | ||||||
|     return sendDataFULL(id, addrTo, data, len, 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) | ||||||
|     { |     { | ||||||
|         Serial.println("IR Pack to big"); |         return; | ||||||
|         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); | ||||||
| @ -155,8 +76,8 @@ IR_SendResult IR_Encoder::sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8 | |||||||
|     sendBuffer[0] = msgType; |     sendBuffer[0] = msgType; | ||||||
|  |  | ||||||
|     // addr_self |     // addr_self | ||||||
|     sendBuffer[1] = addrFrom >> 8 & 0xFF; |     sendBuffer[1] = id >> 8 & 0xFF; | ||||||
|     sendBuffer[2] = addrFrom & 0xFF; |     sendBuffer[2] = id & 0xFF; | ||||||
|  |  | ||||||
|     // addr_to |     // addr_to | ||||||
|     sendBuffer[3] = addrTo >> 8 & 0xFF; |     sendBuffer[3] = addrTo >> 8 & 0xFF; | ||||||
| @ -171,19 +92,6 @@ IR_SendResult IR_Encoder::sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8 | |||||||
|     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) { | ||||||
| @ -193,14 +101,9 @@ IR_SendResult IR_Encoder::sendDataFULL(uint16_t addrFrom, uint16_t addrTo, uint8 | |||||||
|  |  | ||||||
|     // отправка |     // отправка | ||||||
|     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); | ||||||
| @ -221,13 +124,9 @@ IR_SendResult 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); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| IR_SendResult IR_Encoder::sendRequest(uint16_t addrTo) | void 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); | ||||||
| @ -247,32 +146,28 @@ IR_SendResult 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); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| IR_SendResult IR_Encoder::sendBack(uint8_t data) | void IR_Encoder::sendBack(uint8_t data) | ||||||
| { | { | ||||||
|     return _sendBack(false, 0, &data, 1); |     _sendBack(false, 0, &data, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| IR_SendResult IR_Encoder::sendBack(uint8_t *data, uint8_t len) | void IR_Encoder::sendBack(uint8_t *data , uint8_t len) | ||||||
| { | { | ||||||
|     return _sendBack(false, 0, data, len); |     _sendBack(false, 0, data, len); | ||||||
| } | } | ||||||
|  |  | ||||||
| IR_SendResult IR_Encoder::sendBackTo(uint16_t addrTo, uint8_t *data, uint8_t len) | void IR_Encoder::sendBackTo(uint16_t addrTo, uint8_t *data, uint8_t len) | ||||||
| { | { | ||||||
|     return _sendBack(true, addrTo, data, len); |     _sendBack(true, addrTo, data, len); | ||||||
| } | } | ||||||
|  |  | ||||||
| IR_SendResult IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len) | void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len) | ||||||
| { | { | ||||||
|     if (len > bytePerPack) |     if (len > bytePerPack) | ||||||
|     { |     { | ||||||
|         return IR_SendResult(false, 0); |         return; | ||||||
|     } |     } | ||||||
|     memset(sendBuffer, 0x00, dataByteSizeMax); |     memset(sendBuffer, 0x00, dataByteSizeMax); | ||||||
|     uint8_t dataStart = msgBytes + addrBytes + (isAdressed ? addrBytes : 0); |     uint8_t dataStart = msgBytes + addrBytes + (isAdressed ? addrBytes : 0); | ||||||
| @ -304,10 +199,6 @@ IR_SendResult IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t *d | |||||||
|  |  | ||||||
|     // отправка |     // отправка | ||||||
|     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() | ||||||
| @ -317,10 +208,6 @@ void IR_Encoder::setDecoder_isSending() | |||||||
|         for (uint8_t i = 0; i < decodersCount; i++) |         for (uint8_t i = 0; i < decodersCount; i++) | ||||||
|         { |         { | ||||||
|             blindDecoders[i]->isPairSending ^= id; |             blindDecoders[i]->isPairSending ^= id; | ||||||
|             // Serial.print("setDecoder_isSending()   id = "); |  | ||||||
|             // Serial.print(id); |  | ||||||
|             // Serial.print("   isPairSending = "); |  | ||||||
|             // Serial.println(blindDecoders[i]->isPairSending); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -333,12 +220,6 @@ void IR_Encoder::rawSend(uint8_t *ptr, uint8_t len) | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Проверка на переполнение буфера |  | ||||||
|     if (len > dataByteSizeMax) |  | ||||||
|     { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|     // Serial.println("START"); |  | ||||||
|     setDecoder_isSending(); |     setDecoder_isSending(); | ||||||
|  |  | ||||||
|     // noInterrupts(); |     // noInterrupts(); | ||||||
| @ -361,13 +242,10 @@ void IR_Encoder::rawSend(uint8_t *ptr, uint8_t len) | |||||||
|     // interrupts(); |     // interrupts(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_Encoder::isr() | void IR_Encoder::isr(){ | ||||||
| { |     //  Serial.println(get_enc_list().size()); | ||||||
|     IR_Encoder *current = IR_Encoder::head; |     for(const auto &element : get_enc_list()){ | ||||||
|     while (current != nullptr) |         element->_isr(); | ||||||
|     { |  | ||||||
|       current->_isr(); |  | ||||||
|       current = current->next; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -378,8 +256,10 @@ void IR_Encoder::_isr() | |||||||
|  |  | ||||||
|     ir_out_virtual = !ir_out_virtual && state; |     ir_out_virtual = !ir_out_virtual && state; | ||||||
|  |  | ||||||
|     port->ODR &= ~(mask); |     // port->ODR &= ~(mask); | ||||||
|     port->ODR |= mask & (ir_out_virtual ? (uint16_t)0xFFFF : (uint16_t)0x0000); |     // port->ODR |= mask & (ir_out_virtual ? (uint16_t)0xFFFF : (uint16_t)0x0000); | ||||||
|  |     digitalWrite(pin, ir_out_virtual); | ||||||
|  |     | ||||||
|  |  | ||||||
|     if (toggleCounter) |     if (toggleCounter) | ||||||
|     { |     { | ||||||
| @ -395,9 +275,7 @@ void IR_Encoder::_isr() | |||||||
|             // сброс счетчиков |             // сброс счетчиков | ||||||
|             // ... |             // ... | ||||||
|             isSending = false; |             isSending = false; | ||||||
|             // Serial.println("STOP"); |  | ||||||
|             setDecoder_isSending(); |             setDecoder_isSending(); | ||||||
|             // Serial.println(); |  | ||||||
|             return; |             return; | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
| @ -515,101 +393,9 @@ void IR_Encoder::addSync(bool *prev, bool *next) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| uint8_t IR_Encoder::bitHigh[2] = { | uint8_t* IR_Encoder::bitHigh = new uint8_t[2]{ | ||||||
|         (bitPauseTakts) * 2 - 1, |         (bitPauseTakts) * 2 - 1, | ||||||
|         (bitActiveTakts) * 2 - 1}; |         (bitActiveTakts) * 2 - 1}; | ||||||
| uint8_t IR_Encoder::bitLow[2] = { | uint8_t* IR_Encoder::bitLow = new uint8_t[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]{ |  | ||||||
| //         (bitPauseTakts) * 2 - 0, |  | ||||||
| //         (bitActiveTakts) * 2 - 0}; |  | ||||||
| // uint8_t* IR_Encoder::bitLow = new uint8_t[2]{ |  | ||||||
| //         (bitPauseTakts/2 + bitActiveTakts) * 2 - 0, |  | ||||||
| //         (bitPauseTakts) - 0}; |  | ||||||
							
								
								
									
										65
									
								
								IR_Encoder.h
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								IR_Encoder.h
									
									
									
									
									
								
							| @ -3,79 +3,48 @@ | |||||||
|  |  | ||||||
| // 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 : IR_FOX | ||||||
| { | { | ||||||
|     friend IR_DecoderRaw; |     friend IR_DecoderRaw; | ||||||
|     static IR_Encoder *head; |  | ||||||
|     static IR_Encoder *last; |  | ||||||
|     IR_Encoder *next; |  | ||||||
| public: | public: | ||||||
|     static HardwareTimer* IR_Timer; |  | ||||||
| private: | private: | ||||||
|     // uint16_t id; /// @brief Адрес передатчика |     uint16_t id; /// @brief Адрес передатчика | ||||||
| public: | public: | ||||||
|  |      | ||||||
|     /// @brief Класс передатчика |     /// @brief Класс передатчика | ||||||
|     /// @param addr Адрес передатчика |     /// @param addr Адрес передатчика | ||||||
|     /// @param pin  Вывод передатчика |     /// @param pin  Вывод передатчика | ||||||
|     /// @param decPair Приёмник, для которого отключается приём в момент передачи передатчиком |     /// @param decPair Приёмник, для которого отключается приём в момент передачи передатчиком | ||||||
|     IR_Encoder(uint8_t pin, uint16_t addr = 0, IR_DecoderRaw *decPair = nullptr, bool autoHandle = true); |     IR_Encoder(uint8_t pin, uint16_t addr, IR_DecoderRaw *decPair = nullptr); | ||||||
|     static void isr(); |     static void isr(); | ||||||
|     static void begin(HardwareTimer* timer, uint8_t channel, IRQn_Type IRQn, uint8_t priority, void(*isrCallback)() = nullptr); |  | ||||||
|     static HardwareTimer* get_IR_Timer(); |  | ||||||
|  |  | ||||||
|     void enable(); |  | ||||||
|     void disable(); |  | ||||||
|  |  | ||||||
|     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); | ||||||
|  |  | ||||||
|     IR_SendResult sendData(uint16_t addrTo, uint8_t dataByte, bool needAccept = false); |     void 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); |     void 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); |     void sendBack(uint8_t data); | ||||||
|     IR_SendResult sendRequest(uint16_t addrTo); |     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;} |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     ~IR_Encoder(); |     ~IR_Encoder(); | ||||||
|     volatile bool ir_out_virtual; |     volatile bool ir_out_virtual; | ||||||
|  |  | ||||||
|     void _isr(); |  | ||||||
| private: | private: | ||||||
|     IR_SendResult _sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len); |     static std::list<IR_Encoder*>& get_enc_list(); | ||||||
|  |     void _sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len); | ||||||
|  |     void _isr(); | ||||||
|  |  | ||||||
|     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); | ||||||
| @ -113,8 +82,8 @@ private: | |||||||
|         uint8_t low; |         uint8_t low; | ||||||
|         uint8_t high; |         uint8_t high; | ||||||
|     }; |     }; | ||||||
|     static uint8_t bitHigh[2]; |     static uint8_t *bitHigh; | ||||||
|     static uint8_t bitLow[2]; |     static uint8_t *bitLow; | ||||||
|     uint8_t *currentBitSequence = bitLow; |     uint8_t *currentBitSequence = bitLow; | ||||||
|     volatile SignalPart signal; |     volatile SignalPart signal; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -2,8 +2,9 @@ | |||||||
|  |  | ||||||
| void IR_FOX::setPin(uint8_t pin){ | void IR_FOX::setPin(uint8_t pin){ | ||||||
|     this->pin = pin; |     this->pin = pin; | ||||||
|     port = digitalPinToPort(pin); |     // port = digitalPinToPort(pin); | ||||||
|     mask = digitalPinToBitMask(pin); |     // mask = digitalPinToBitMask(pin); | ||||||
|  |     // pinMode(pin, INPUT_PULLUP); | ||||||
| } | } | ||||||
|  |  | ||||||
| void IR_FOX::checkAddressRuleApply(uint16_t address, uint16_t id, bool &flag) | void IR_FOX::checkAddressRuleApply(uint16_t address, uint16_t id, bool &flag) | ||||||
|  | |||||||
							
								
								
									
										46
									
								
								IR_config.h
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								IR_config.h
									
									
									
									
									
								
							| @ -8,32 +8,19 @@ | |||||||
|  |  | ||||||
| */ | */ | ||||||
| // Адресация с 1 до 65 499 | // Адресация с 1 до 65 499 | ||||||
| #define IR_Broadcast 65000 // 65 500 ~ 65 535 - широковещательные пакеты (всем) | #define IR_Broadcast 65000 // 65 500 ~ 65 535 - широковещательные пакеты (всем), возможно разделить на 35 типов | ||||||
| /* | /* | ||||||
| *Адресное пространство: | Адрес 0 запрещен и зарезервирован под NULL, либо тесты | ||||||
|     Адрес 0 запрещен и зарезервирован под NULL, либо тесты | IR_MSG_ACCEPT с адреса 0 воспринимается всеми устройствами | ||||||
|     IR_MSG_ACCEPT с адреса 0 воспринимается всеми устройствами |  | ||||||
| */  |  | ||||||
| //**** Контрольные точки ****** |  | ||||||
| #define IR_MAX_ADDR_CPU 63999 |  | ||||||
| #define IR_MIN_ADDR_CPU 32000 |  | ||||||
|  |  | ||||||
| // //***** Группы машинок ******** |  | ||||||
| // #define IR_MAX_CAR_GROUP 31999 |  | ||||||
| // #define IR_MIN_CAR_GROUP 30000 |  | ||||||
|  |  | ||||||
| // //********** FREE ************* | Адресное пространство: | ||||||
| // #define IR_MAX_FREE 31999 |  | ||||||
| // #define IR_MIN_FREE 2000 | Излучатели контрольных точек: 1000 ~ 1999 | ||||||
|  | Излучатели без обратной связиЖ 2000 ~ 2999 | ||||||
|  | Излучатели светофоров: 3000 ~ 3999 | ||||||
|  |  | ||||||
| //********* Машинки *********** |  | ||||||
| #define IR_MAX_CAR 31999 |  | ||||||
| #define IR_MIN_CAR 1 |  | ||||||
|  |  | ||||||
| //***** Пульты управления ***** |  | ||||||
| #define IR_MAX_CONTROLLER 64999 |  | ||||||
| #define IR_MIN_CONTROLLER 64000 |  | ||||||
| /* |  | ||||||
|  |  | ||||||
| /```````````````````````````````````````````````` data pack `````````````````````````````````````````````\                                   | /```````````````````````````````````````````````` data pack `````````````````````````````````````````````\                                   | ||||||
|                                                                                                           |                                                                                                           | ||||||
| @ -52,7 +39,7 @@ msg type: | |||||||
|                                         //  | 01234567 | |                                         //  | 01234567 | | ||||||
|                                         //   ---------- |                                         //   ---------- | ||||||
|                                         //  | xxx..... | = тип сообщения |                                         //  | xxx..... | = тип сообщения | ||||||
|                                         //  | ...xxxxx | = длина (максимум 31 бита) - не больше 24 байт на тело пакета |                                         //  | ...xxxxx | = длина (максимум 31 бита) | ||||||
|                                         //   ---------- */ |                                         //   ---------- */ | ||||||
| #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 +103,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 (31) // колличество байтов в пакете | #define bytePerPack 16 // колличество байтов в пакете | ||||||
| #ifndef freeFrec | #ifndef freeFrec | ||||||
| #define freeFrec false | #define freeFrec false | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef subBufferSize | #ifndef subBufferSize | ||||||
| #define subBufferSize 250 // Буфер для складирования фронтов, пока их не обработают (передатчик) | #define subBufferSize 50 // Буфер для складирования фронтов, пока их не обработают (передатчик) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #define preambPulse 3 | #define preambPulse 3 | ||||||
| @ -155,11 +142,6 @@ typedef uint16_t crc_t; | |||||||
| #define bitTime (bitTakts * carrierPeriod)        // Общая длительность бита | #define bitTime (bitTakts * carrierPeriod)        // Общая длительность бита | ||||||
| #define tolerance 300U | #define tolerance 300U | ||||||
|  |  | ||||||
| constexpr uint16_t test_all_Time = bitTime; |  | ||||||
| constexpr uint16_t test_all_Takts = bitTakts * 2; |  | ||||||
| constexpr uint16_t test_hi = ((bitPauseTakts) * 2 - 0) + ((bitActiveTakts) * 2 - 0); |  | ||||||
| constexpr uint16_t test_low = ((bitPauseTakts / 2 + bitActiveTakts) * 2 - 0) + ((bitPauseTakts)-0); |  | ||||||
|  |  | ||||||
| class IR_FOX | class IR_FOX | ||||||
| { | { | ||||||
| public: | public: | ||||||
| @ -196,16 +178,16 @@ public: | |||||||
|         uint16_t rTime = 0; |         uint16_t rTime = 0; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     inline uint16_t getId() const { return id; } |     inline uint16_t getId() { return id; } | ||||||
|     inline void setId(uint16_t id) { this->id = id; } |     inline void setId(uint16_t id) { this->id = id; } | ||||||
|     static void checkAddressRuleApply(uint16_t address, uint16_t id, bool &flag); |     static void checkAddressRuleApply(uint16_t address, uint16_t id, bool &flag); | ||||||
|     void setPin(uint8_t pin); |     void setPin(uint8_t pin); | ||||||
|     inline uint8_t getPin() { return pin; }; |     inline uint8_t getPin(){return pin;}; | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|     uint16_t id; |     uint16_t id; | ||||||
|     uint8_t pin; |     uint8_t pin; | ||||||
|     GPIO_TypeDef *port; |     // GPIO_TypeDef *port; | ||||||
|     uint16_t mask; |     uint16_t mask; | ||||||
|     ErrorsStruct errors; |     ErrorsStruct errors; | ||||||
|     uint8_t crc8(uint8_t *data, uint8_t start, uint8_t end, uint8_t poly); |     uint8_t crc8(uint8_t *data, uint8_t start, uint8_t end, uint8_t poly); | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user