Added decodeDistanceWidthData() and therfore changed ir_DistanceProtocol.hpp to ir_DistanceWidthProtocol.hpp and DECODE_DISTANCE to DECODE_DISTANCE_WIDTH.
This commit is contained in:
parent
d51b540cb2
commit
fd7f47745d
|
@ -18,7 +18,7 @@ jobs:
|
|||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@master
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
|
|
|
@ -96,6 +96,14 @@ Protocols can be switched off and on by defining macros before the line `#includ
|
|||
- Actively maintained.
|
||||
- Allows receiving and sending of **raw timing data**.
|
||||
|
||||
## New features with version 4.x
|
||||
- New universal **Pulse Distance Width decoder** added, which covers some previous unknown protocols.
|
||||
- Printout of code how to send received command by `IrReceiver.printIRSendUsage(&Serial)`.
|
||||
- Support for more than 64 bit data for universal decoder and sender.
|
||||
|
||||
# Converting your 3.x program to the 4.x version
|
||||
- You must replace `#define DECODE_DISTANCE_WIDTH` by `#define DECODE_DISTANCE_WIDTH` (only if you explicitly enabled this decoder).
|
||||
|
||||
## New features with version 3.x
|
||||
- **Any pin** can be used for sending / receiving.
|
||||
- Feedback LED can be activated for sending / receiving.
|
||||
|
|
|
@ -12,7 +12,9 @@ See also the commit log at github: https://github.com/Arduino-IRremote/Arduino-I
|
|||
- Support for ATtiny816 - Thanks to elockman.
|
||||
- Added Bang&Olufsen protocol. #1030.
|
||||
- 3. parameter of function "void begin(uint_fast8_t aSendPin, bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin)" is not optional anymore
|
||||
and function is now only available if IR_SEND_PIN is not defined. #1033.
|
||||
and this function is now only available if IR_SEND_PIN is not defined. #1033.
|
||||
- Added decodeDistanceWidthData() and therfore changed ir_DistanceProtocol.hpp to ir_DistanceWidthProtocol.hpp and DECODE_DISTANCE to DECODE_DISTANCE_WIDTH.
|
||||
- Fixed bug in sendSony() for command parameter > 0x7F;
|
||||
|
||||
## 3.9.0
|
||||
- Improved documentation with the help of [ElectronicsArchiver}(https://github.com/ElectronicsArchiver).
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
*/
|
||||
//#define DECODE_LG
|
||||
//#define DECODE_NEC
|
||||
//#define DECODE_DISTANCE
|
||||
//#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols
|
||||
// etc. see IRremote.hpp
|
||||
//
|
||||
|
||||
|
|
|
@ -40,8 +40,10 @@
|
|||
*/
|
||||
//#define DECODE_LG
|
||||
//#define DECODE_NEC
|
||||
//#define DECODE_DISTANCE
|
||||
//#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols
|
||||
#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604. Code does not fit in program memory of ATtiny85 etc.
|
||||
#define DECODE_BEO // Bang & Olufsen protocol always must be enabled explicitly.
|
||||
#endif
|
||||
#if defined(DECODE_BEO)
|
||||
#define RECORD_GAP_MICROS 16000 // always get the complete frame in the receive buffer
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* it sends multiple Samsung32 frames with appropriate delays in between.
|
||||
* This serves as a Netflix-key emulation for my old Samsung H5273 TV.
|
||||
*
|
||||
* Tested on a digispark ATTiny85 board using AttinyCore https://github.com/SpenceKonde/ATTinyCore
|
||||
*
|
||||
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
|
||||
*
|
||||
************************************************************************************
|
||||
|
@ -42,6 +44,51 @@
|
|||
// USB- 3.6V Z-Diode IR Output (4) PB4 3| |6 PB1 (1) Feedback LED
|
||||
// GND 4| |5 PB0 (0) IR Input
|
||||
// +----+
|
||||
|
||||
/* SAUMSUMG REMOTE CODES (Model: BN59-01180A)
|
||||
* Power Button - 0x2
|
||||
* Power Off - 0x98
|
||||
* 1 - 0x4
|
||||
* 2 - 0x5
|
||||
* 3 - 0x6
|
||||
* 4 - 0x8
|
||||
* 5 - 0x9
|
||||
* 6 - 0xa
|
||||
* 7 - 0xc
|
||||
* 8 - 0xd
|
||||
* 9 - 0xe
|
||||
* CH List - 0x6b
|
||||
* Vol + - 0x7
|
||||
* Vol - - 0xb
|
||||
* Mute - 0xf
|
||||
* Source - 0x1
|
||||
* Ch + - 0x12
|
||||
* Ch - - 0x10
|
||||
* Menu - 0x1a
|
||||
* Home - 0x79
|
||||
* MagicInfo Player - 0x30
|
||||
* Tools - 0x4b
|
||||
* Info - 0x1f
|
||||
* Up arrow - 0x60
|
||||
* Left arrow - 0x65
|
||||
* Right arrow - 0x62
|
||||
* Down arrow - 0x61
|
||||
* Return - 0x58
|
||||
* Exit - 0x2d
|
||||
* A - 0x6c
|
||||
* B - 0x14
|
||||
* C - 0x15
|
||||
* D - 0x16
|
||||
* Set - 0xab
|
||||
* Unset - 0xac
|
||||
* Lock - 0x77
|
||||
* Stop (square) - 0x46
|
||||
* Rewind (arrows) - 0x45
|
||||
* Play (triangle) - 0x47
|
||||
* Pause (bars) - 0x4a
|
||||
* Fast Forward (arrows) - 0x48
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// select only Samsung protocol for sending and receiving
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
// select only NEC and the universal decoder for pulse distance protocols
|
||||
#define DECODE_NEC // Includes Apple and Onkyo
|
||||
#define DECODE_DISTANCE // in case NEC is not received correctly
|
||||
#define DECODE_DISTANCE_WIDTH // In case NEC is not received correctly. Universal decoder for pulse distance width protocols
|
||||
|
||||
//#define EXCLUDE_UNIVERSAL_PROTOCOLS // Saves up to 1000 bytes program memory.
|
||||
//#define EXCLUDE_EXOTIC_PROTOCOLS
|
||||
|
|
|
@ -51,13 +51,15 @@
|
|||
//#define DECODE_MAGIQUEST
|
||||
//#define DECODE_WHYNTER
|
||||
|
||||
//#define DECODE_DISTANCE // universal decoder for pulse distance protocols
|
||||
//#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols
|
||||
//#define DECODE_HASH // special decoder for all protocols
|
||||
|
||||
//#define DECODE_BEO // This protocol must always be enabled manually, i.e. it is NOT enabled if no protocol is defined
|
||||
|
||||
//#define DEBUG // Activate this for lots of lovely debug output from the decoders.
|
||||
|
||||
//#define RAW_BUFFER_LENGTH 180 // Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100.
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc.
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
#define DECODE_RC6
|
||||
#define DECODE_SONY
|
||||
|
||||
#define DECODE_DISTANCE // universal decoder for pulse distance protocols
|
||||
#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols
|
||||
#define DECODE_HASH // special decoder for all protocols
|
||||
#endif
|
||||
|
||||
|
@ -154,6 +154,42 @@ void setup() {
|
|||
|
||||
}
|
||||
|
||||
void checkReceivedArray(uint32_t *aRawDataArrayPointer, uint8_t aArraySize) {
|
||||
// wait until signal has received
|
||||
delay((RECORD_GAP_MICROS / 1000) + 1);
|
||||
|
||||
if (IrReceiver.decode()) {
|
||||
// Print a short summary of received data
|
||||
#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604
|
||||
IrReceiver.printIRResultShort(&Serial);
|
||||
IrReceiver.printIRSendUsage(&Serial);
|
||||
#else
|
||||
IrReceiver.printIRResultMinimal(&Serial);
|
||||
#endif
|
||||
#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604
|
||||
if (IrReceiver.decodedIRData.protocol == UNKNOWN || digitalRead(DEBUG_BUTTON_PIN) == LOW) {
|
||||
// We have an unknown protocol, print more info
|
||||
IrReceiver.printIRResultRawFormatted(&Serial, true);
|
||||
}
|
||||
#endif
|
||||
if (IrReceiver.decodedIRData.protocol == PULSE_DISTANCE || IrReceiver.decodedIRData.protocol == PULSE_DISTANCE_WIDTH) {
|
||||
for (uint_fast8_t i = 0; i < aArraySize; ++i) {
|
||||
if (IrReceiver.decodedIRData.decodedRawDataArray[i] != *aRawDataArrayPointer) {
|
||||
Serial.print(F("ERROR: Received data=0x"));
|
||||
Serial.print(IrReceiver.decodedIRData.decodedRawDataArray[i], HEX);
|
||||
Serial.print(F(" != sent data=0x"));
|
||||
Serial.println(*aRawDataArrayPointer, HEX);
|
||||
}
|
||||
aRawDataArrayPointer++;
|
||||
}
|
||||
}
|
||||
IrReceiver.resume();
|
||||
} else {
|
||||
Serial.println(F("No data received"));
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void checkReceive(uint16_t aSentAddress, uint16_t aSentCommand) {
|
||||
// wait until signal has received
|
||||
delay((RECORD_GAP_MICROS / 1000) + 1);
|
||||
|
@ -179,28 +215,26 @@ void checkReceive(uint16_t aSentAddress, uint16_t aSentCommand) {
|
|||
IrReceiver.printIRResultRawFormatted(&Serial, true);
|
||||
}
|
||||
#endif
|
||||
if (IrReceiver.decodedIRData.protocol != PULSE_DISTANCE) {
|
||||
if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
|
||||
Serial.println(F("ERROR: Unknown protocol"));
|
||||
} else {
|
||||
/*
|
||||
* Check address
|
||||
*/
|
||||
if (IrReceiver.decodedIRData.address != aSentAddress) {
|
||||
Serial.print(F("ERROR: Received address=0x"));
|
||||
Serial.print(IrReceiver.decodedIRData.address, HEX);
|
||||
Serial.print(F(" != sent address=0x"));
|
||||
Serial.println(aSentAddress, HEX);
|
||||
}
|
||||
/*
|
||||
* Check command
|
||||
*/
|
||||
if (IrReceiver.decodedIRData.command != aSentCommand) {
|
||||
Serial.print(F("ERROR: Received command=0x"));
|
||||
Serial.print(IrReceiver.decodedIRData.command, HEX);
|
||||
Serial.print(F(" != sent command=0x"));
|
||||
Serial.println(aSentCommand, HEX);
|
||||
}
|
||||
if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
|
||||
Serial.println(F("ERROR: Unknown protocol"));
|
||||
} else {
|
||||
/*
|
||||
* Check address
|
||||
*/
|
||||
if (IrReceiver.decodedIRData.address != aSentAddress) {
|
||||
Serial.print(F("ERROR: Received address=0x"));
|
||||
Serial.print(IrReceiver.decodedIRData.address, HEX);
|
||||
Serial.print(F(" != sent address=0x"));
|
||||
Serial.println(aSentAddress, HEX);
|
||||
}
|
||||
/*
|
||||
* Check command
|
||||
*/
|
||||
if (IrReceiver.decodedIRData.command != aSentCommand) {
|
||||
Serial.print(F("ERROR: Received command=0x"));
|
||||
Serial.print(IrReceiver.decodedIRData.command, HEX);
|
||||
Serial.print(F(" != sent command=0x"));
|
||||
Serial.println(aSentCommand, HEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +334,7 @@ void loop() {
|
|||
delay(DELAY_AFTER_SEND);
|
||||
|
||||
#if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO)
|
||||
Serial.println(F("Send Panasonic 0xB, 0x10 as 48 bit PulseDistance using ProtocolConstants"));
|
||||
Serial.println(F("Send Panasonic 0xB, 0x10 as 48 bit generic PulseDistance using ProtocolConstants"));
|
||||
Serial.flush();
|
||||
uint32_t tRawData[] = { 0xB02002, 0xA010 }; // LSB of tRawData[0] is sent first
|
||||
IrSender.sendPulseDistanceWidthFromArray(&KaseikyoProtocolConstants, &tRawData[0], 48, NO_REPEATS); // Panasonic is a Kaseikyo variant
|
||||
|
@ -328,13 +362,60 @@ void loop() {
|
|||
delay(DELAY_AFTER_SEND);
|
||||
#endif
|
||||
|
||||
Serial.println(F("Send generic 56 bit PulseDistance 0x43D8613C and 0x3BC3BC LSB first"));
|
||||
#if defined(DISTANCE_DO_MSB_DECODING)
|
||||
Serial.println(F("Send generic 52 bit PulseDistance 0x43D8613C and 0x3BC3B MSB first"));
|
||||
Serial.flush();
|
||||
uint32_t tRawData1[] = { 0x43D8613C, 0x3BC3BC }; // LSB of tRawData1[0] is sent first
|
||||
IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1700, 550, 600, &tRawData1[0], 56, PROTOCOL_IS_LSB_FIRST,
|
||||
tRawData[0] = 0x43D8613C; // MSB of tRawData[0] is sent first
|
||||
tRawData[1] = 0x3BC3B;
|
||||
IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1700, 550, 600, &tRawData[0], 52, PROTOCOL_IS_MSB_FIRST,
|
||||
SEND_STOP_BIT, 0, NO_REPEATS);
|
||||
checkReceive(0x0, 0x0); // No real check, only printing of received result
|
||||
checkReceivedArray(tRawData, 2);
|
||||
delay(DELAY_AFTER_SEND);
|
||||
|
||||
Serial.println(F("Send generic 52 bit PulseDistanceWidth 0x43D8613C and 0x3BC3B MSB first"));
|
||||
Serial.flush();
|
||||
// Real PulseDistanceWidth (constant bit length) does not require a stop bit
|
||||
IrSender.sendPulseDistanceWidthFromArray(38, 300, 600, 600, 300, 300, 600, &tRawData[0], 52, PROTOCOL_IS_MSB_FIRST,
|
||||
SEND_NO_STOP_BIT, 0, 0);
|
||||
checkReceivedArray(tRawData, 2);
|
||||
delay(DELAY_AFTER_SEND);
|
||||
#else
|
||||
Serial.println(F("Send generic 52 bit PulseDistance 0x43D8613C and 0x3BC3B LSB first"));
|
||||
Serial.flush();
|
||||
tRawData[0] = 0x43D8613C; // MSB of tRawData[0] is sent first
|
||||
tRawData[1] = 0x3BC3B;
|
||||
IrSender.sendPulseDistanceWidthFromArray(38, 8900, 4450, 550, 1700, 550, 600, &tRawData[0], 52, PROTOCOL_IS_LSB_FIRST,
|
||||
SEND_STOP_BIT, 0, NO_REPEATS);
|
||||
checkReceivedArray(tRawData, 2);
|
||||
delay(DELAY_AFTER_SEND);
|
||||
|
||||
Serial.println(F("Send generic 52 bit PulseDistanceWidth 0x43D8613C and 0x3BC3B LSB first"));
|
||||
Serial.flush();
|
||||
// Real PulseDistanceWidth (constant bit length) does not require a stop bit
|
||||
IrSender.sendPulseDistanceWidthFromArray(38, 300, 600, 600, 300, 300, 600, &tRawData[0], 52, PROTOCOL_IS_LSB_FIRST,
|
||||
SEND_NO_STOP_BIT, 0, 0);
|
||||
checkReceivedArray(tRawData, 2);
|
||||
delay(DELAY_AFTER_SEND);
|
||||
#endif
|
||||
|
||||
#if defined(DECODE_MAGIQUEST)
|
||||
|
||||
Serial.println(F("Send MagiQuest 0x6BCDFF00, 0x176 as generic 55 bit PulseDistanceWidth MSB first"));
|
||||
Serial.flush();
|
||||
tRawData[0] = 0x01AF37FC; // We have 1 header (start) bit and 7 start bits and 31 address bits for MagiQuest, so 0x6BCDFF00 is shifted six right
|
||||
tRawData[1] = 0x017619; // 19 is the checksum
|
||||
IrSender.sendPulseDistanceWidthFromArray(38, 287, 864, 576, 576, 287, 864, &tRawData[0], 55, PROTOCOL_IS_MSB_FIRST,
|
||||
SEND_NO_STOP_BIT, 0, 0);
|
||||
checkReceive(0xFF00, 0x176);
|
||||
if (IrReceiver.decodedIRData.decodedRawData != 0x6BCDFF00) {
|
||||
Serial.print(F("ERROR: Received address=0x"));
|
||||
Serial.print(IrReceiver.decodedIRData.decodedRawData, HEX);
|
||||
Serial.println(F(" != sent address=0x6BCDFF00"));
|
||||
Serial.println();
|
||||
}
|
||||
delay(DELAY_AFTER_SEND);
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -387,7 +468,7 @@ void loop() {
|
|||
#if defined(DECODE_SONY)
|
||||
Serial.println(F("Send Sony/SIRCS with 7 command and 5 address bits"));
|
||||
Serial.flush();
|
||||
IrSender.sendSony(sAddress & 0x1F, sCommand & 0x7F, sRepeats);
|
||||
IrSender.sendSony(sAddress & 0x1F, sCommand, sRepeats);
|
||||
checkReceive(sAddress & 0x1F, sCommand & 0x7F);
|
||||
delay(DELAY_AFTER_SEND);
|
||||
|
||||
|
@ -399,7 +480,7 @@ void loop() {
|
|||
|
||||
Serial.println(F("Send Sony/SIRCS with 7 command and 13 address bits"));
|
||||
Serial.flush();
|
||||
IrSender.sendSony(sAddress & 0x1FFF, sCommand & 0x7F, sRepeats, SIRCS_20_PROTOCOL);
|
||||
IrSender.sendSony(sAddress & 0x1FFF, sCommand, sRepeats, SIRCS_20_PROTOCOL);
|
||||
checkReceive(sAddress & 0x1FFF, sCommand & 0x7F);
|
||||
delay(DELAY_AFTER_SEND);
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
START ../src/UnitTest.cpp from Aug 30 2022
|
||||
Using library version 3.9.0
|
||||
Ready to receive IR signals of protocols: NEC/NEC2/Onkyo/Apple, Panasonic/Kaseikyo, Denon/Sharp, Sony, RC5, RC6, LG, JVC, Samsung, Whynter, Lego Power Functions, Bosewave , MagiQuest, Pulse Distance, Hash at pin 2
|
||||
START ../src/UnitTest.cpp from Nov 7 2022
|
||||
Using library version 4.0.0
|
||||
Ready to receive IR signals of protocols: NEC/NEC2/Onkyo/Apple, Panasonic/Kaseikyo, Denon/Sharp, Sony, RC5, RC6, LG, JVC, Samsung, Bang & Olufsen, Bosewave , MagiQuest, Pulse Distance Width, Hash at pin 2
|
||||
Ready to send IR signals at pin 3
|
||||
Send signal mark duration for 38kHz is 8 us, pulse correction is 3000 ns, total period is 26 us
|
||||
5000 us is the (minimum) gap, after which the start of a new IR packet is assumed
|
||||
|
@ -174,30 +174,70 @@ rawData[100]:
|
|||
+ 450
|
||||
Sum: 53150
|
||||
|
||||
Send generic 56 bit PulseDistance 0x43D8613C and 0x3BC3BC LSB first
|
||||
Protocol=PulseDistance Raw-Data=0x3BC3BC 56 bits LSB first
|
||||
Send with:
|
||||
uint32_t tRawData[]={0x43D8613C, 0x3BC3BC};
|
||||
IrSender.sendPulseDistanceWidthFromArray(38, 8850, 4450, 600, 1650, 600, 600, &tRawData[0], 56, PROTOCOL_IS_LSB_FIRST, SEND_STOP_BIT, <millisofRepeatPeriod>, <numberOfRepeats>);
|
||||
rawData[116]:
|
||||
-1068600
|
||||
+8850,-4450
|
||||
+ 500,- 600 + 550,- 600 + 550,-1650 + 600,-1650
|
||||
+ 550,-1650 + 600,-1650 + 600,- 550 + 600,- 550
|
||||
+ 600,-1650 + 550,- 600 + 550,- 600 + 550,- 600
|
||||
+ 550,- 600 + 550,-1650 + 550,-1700 + 600,- 550
|
||||
+ 600,- 550 + 600,- 550 + 600,- 550 + 550,-1650
|
||||
+ 600,-1650 + 600,- 550 + 600,-1650 + 550,-1650
|
||||
+ 600,-1650 + 600,-1650 + 550,- 600 + 550,- 550
|
||||
+ 600,- 600 + 550,- 600 + 550,-1650 + 600,- 550
|
||||
+ 550,- 600 + 600,- 600 + 550,-1650 + 600,-1650
|
||||
+ 550,-1700 + 600,-1650 + 550,- 600 + 550,-1650
|
||||
+ 550,-1700 + 600,-1600 + 600,- 550 + 600,- 600
|
||||
+ 550,- 550 + 600,- 600 + 550,-1650 + 550,-1700
|
||||
+ 600,-1600 + 600,-1650 + 550,- 600 + 600,-1650
|
||||
+ 600,-1650 + 600,-1650 + 600,- 550 + 550,- 600
|
||||
Send generic 52 bit PulseDistance 0x43D8613C and 0x3BC3B MSB first
|
||||
Protocol=UNKNOWN Hash=0x51DB63E0 54 bits (incl. gap and start) received
|
||||
rawData[108]:
|
||||
-1082850
|
||||
+8850,-4400
|
||||
+ 600,- 550 + 600,-1650 + 500,- 650 + 550,- 600
|
||||
+ 550,- 600 + 550,- 600 + 550,-1650 + 600,-1650
|
||||
+ 600,-1650 + 600,-1650 + 550,- 600 + 550,-1650
|
||||
+ 600,-1650 + 550,- 600 + 600,- 600 + 550,- 550
|
||||
+ 600,- 600 + 550,-1650 + 600,-1650 + 600,- 550
|
||||
+ 600,- 550 + 550,- 600 + 550,- 600 + 550,-1650
|
||||
+ 550,- 600 + 600,- 600 + 550,-1650 + 550,-1700
|
||||
+ 600,-1650 + 550,-1700 + 550,- 600 + 550,- 600
|
||||
+ 600,- 550 + 550,- 600 + 600,-1600 + 600,-1650
|
||||
+ 550,-1700 + 600,- 550 + 550,-1700 + 550,-1650
|
||||
+ 600,-1650 + 600,-1650 + 550,- 600 + 600,- 550
|
||||
+ 600,- 550 + 550,- 750 + 400,-1650 + 550,-1700
|
||||
+ 600,-1650 + 550,- 600 + 600,-1600 + 600,-1650
|
||||
+ 550
|
||||
Sum: 108550
|
||||
Sum: 101850
|
||||
|
||||
Send generic 52 bit PulseDistanceWidth 0x43D8613C and 0x3BC3B MSB first
|
||||
Protocol=PulseDistanceWidth Raw-Data=0x3BC3B 52 bits MSB first
|
||||
Send with:
|
||||
uint32_t tRawData[]={0x43D8613C, 0x3BC3B};
|
||||
IrSender.sendPulseDistanceWidthFromArray(38, 350, 600, 650, 300, 350, 600, &tRawData[0], 52, PROTOCOL_IS_MSB_FIRST, SEND_NO_STOP_BIT, <millisofRepeatPeriod>, <numberOfRepeats>);
|
||||
rawData[106]:
|
||||
-1079150
|
||||
+ 350,- 600
|
||||
+ 300,- 600 + 600,- 300 + 350,- 550 + 350,- 550
|
||||
+ 350,- 550 + 300,- 600 + 650,- 250 + 650,- 250
|
||||
+ 650,- 250 + 650,- 250 + 300,- 600 + 650,- 250
|
||||
+ 650,- 250 + 300,- 600 + 350,- 550 + 350,- 550
|
||||
+ 350,- 550 + 650,- 250 + 650,- 250 + 350,- 550
|
||||
+ 300,- 600 + 350,- 550 + 350,- 550 + 600,- 300
|
||||
+ 350,- 550 + 350,- 600 + 600,- 300 + 600,- 300
|
||||
+ 600,- 300 + 600,- 300 + 300,- 600 + 300,- 600
|
||||
+ 350,- 550 + 350,- 550 + 650,- 300 + 600,- 300
|
||||
+ 600,- 300 + 300,- 600 + 600,- 300 + 600,- 300
|
||||
+ 600,- 300 + 600,- 300 + 300,- 600 + 300,- 600
|
||||
+ 300,- 600 + 350,- 550 + 650,- 250 + 650,- 250
|
||||
+ 650,- 250 + 300,- 600 + 650,- 250 + 650
|
||||
Sum: 47600
|
||||
|
||||
Send MagiQuest 0x6BCDFF00, 0x176 as generic 55 bit PulseDistanceWidth MSB first
|
||||
Protocol=MagiQuest Address=0xFF00 Command=0x176 Raw-Data=0x6BCDFF00 56 bits MSB first
|
||||
Send with: IrSender.sendMagiQuest(0x6BCDFF00, 0x176, <numberOfRepeats>);
|
||||
rawData[112]:
|
||||
-1096650
|
||||
+ 300,- 850 + 300,- 850 + 300,- 850 + 350,- 800
|
||||
+ 300,- 900 + 250,- 900 + 250,- 900 + 300,- 850
|
||||
+ 550,- 600 + 550,- 550 + 350,- 800 + 600,- 600
|
||||
+ 200,- 950 + 550,- 600 + 550,- 600 + 550,- 600
|
||||
+ 550,- 600 + 250,- 900 + 300,- 850 + 550,- 600
|
||||
+ 550,- 600 + 300,- 850 + 550,- 600 + 550,- 600
|
||||
+ 550,- 600 + 550,- 600 + 550,- 600 + 550,- 600
|
||||
+ 550,- 600 + 550,- 600 + 550,- 600 + 300,- 800
|
||||
+ 350,- 850 + 300,- 850 + 300,- 850 + 300,- 850
|
||||
+ 300,- 850 + 300,- 850 + 300,- 850 + 550,- 600
|
||||
+ 300,- 850 + 550,- 600 + 550,- 600 + 550,- 600
|
||||
+ 300,- 850 + 550,- 600 + 550,- 600 + 250,- 900
|
||||
+ 250,- 900 + 300,- 900 + 250,- 850 + 550,- 600
|
||||
+ 600,- 550 + 300,- 900 + 250,- 850 + 550
|
||||
Sum: 63850
|
||||
|
||||
Send Onkyo (NEC with 16 bit command)
|
||||
Protocol=Onkyo Address=0xFFF1 Command=0x7676 Raw-Data=0x7676FFF1 32 bits LSB first
|
||||
|
|
|
@ -39,10 +39,11 @@
|
|||
*/
|
||||
typedef enum {
|
||||
UNKNOWN = 0,
|
||||
#if defined(SUPPORT_PULSE_WIDTH_DECODING) // The only known pulse width protocol is Sony
|
||||
#if defined(SUPPORT_PULSE_WIDTH_DECODING) // The only known pulse width protocol is Sony and this is decoded by the sony decoder
|
||||
PULSE_WIDTH,
|
||||
#endif
|
||||
PULSE_DISTANCE,
|
||||
PULSE_DISTANCE_WIDTH,
|
||||
APPLE,
|
||||
DENON,
|
||||
JVC,
|
||||
|
@ -75,6 +76,7 @@ typedef enum {
|
|||
const char string_Unknown[] PROGMEM = "UNKNOWN";
|
||||
const char string_PulseWidth[] PROGMEM = "PulseWidth";
|
||||
const char string_PulseDistance[] PROGMEM = "PulseDistance";
|
||||
const char string_PulseDistanceWidth[] PROGMEM = "PulseDistanceWidth";
|
||||
const char string_Apple[] PROGMEM = "Apple";
|
||||
const char string_Denon[] PROGMEM = "Denon";
|
||||
const char string_JVC[] PROGMEM = "JVC";
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
#ifndef _IR_RECEIVE_HPP
|
||||
#define _IR_RECEIVE_HPP
|
||||
|
||||
#if defined(DEBUG) && !defined(LOCAL_DEBUG)
|
||||
#define LOCAL_DEBUG
|
||||
#else
|
||||
//#define LOCAL_DEBUG // This enables debug output only for this file
|
||||
#endif
|
||||
|
||||
/** \addtogroup Receiving Receiving IR data for multiple protocols
|
||||
* @{
|
||||
*/
|
||||
|
@ -216,7 +222,11 @@ void IRrecv::initDecodedIRData() {
|
|||
irparams.OverflowFlag = false;
|
||||
irparams.rawlen = 0; // otherwise we have OverflowFlag again at next ISR call
|
||||
decodedIRData.flags = IRDATA_FLAGS_WAS_OVERFLOW;
|
||||
IR_DEBUG_PRINTLN(F("Overflow happened"));
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Overflow happened, try to increase the \"RAW_BUFFER_LENGTH\" value of "));
|
||||
Serial.print(RAW_BUFFER_LENGTH);
|
||||
Serial.println(F(" with #define RAW_BUFFER_LENGTH=<biggerValue>"));
|
||||
#endif
|
||||
|
||||
} else {
|
||||
decodedIRData.flags = IRDATA_FLAGS_EMPTY;
|
||||
|
@ -378,8 +388,8 @@ bool IRrecv::decode() {
|
|||
/*
|
||||
* Try the universal decoder for pulse distance protocols
|
||||
*/
|
||||
#if defined(DECODE_DISTANCE)
|
||||
IR_TRACE_PRINTLN(F("Attempting universal Distance decode"));
|
||||
#if defined(DECODE_DISTANCE_WIDTH)
|
||||
IR_TRACE_PRINTLN(F("Attempting universal Distance Width decode"));
|
||||
if (decodeDistance()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -426,79 +436,96 @@ bool IRrecv::decodePulseWidthData(uint_fast8_t aNumberOfBits, uint_fast8_t aStar
|
|||
|
||||
if (aMSBfirst) {
|
||||
/*
|
||||
* MSB first is currently optimized out by the compiler, since it is never used.
|
||||
* MSB first is currently optimized out by the compiler, since it is never used :-).
|
||||
*/
|
||||
for (uint_fast8_t i = 0; i < aNumberOfBits; i++) {
|
||||
unsigned int tMarkTicks = *tRawBufPointer++;
|
||||
// Check for variable length mark indicating a 0 or 1
|
||||
if (matchMark(*tRawBufPointer, aOneMarkMicros)) {
|
||||
if (matchMark(tMarkTicks, aOneMarkMicros)) {
|
||||
tDecodedData = (tDecodedData << 1) | 1;
|
||||
IR_TRACE_PRINT('1');
|
||||
} else if (matchMark(*tRawBufPointer, aZeroMarkMicros)) {
|
||||
} else if (matchMark(tMarkTicks, aZeroMarkMicros)) {
|
||||
tDecodedData = (tDecodedData << 1) | 0;
|
||||
IR_TRACE_PRINT('0');
|
||||
} else {
|
||||
IR_DEBUG_PRINT(F("Mark="));
|
||||
IR_DEBUG_PRINT(*tRawBufPointer * MICROS_PER_TICK);
|
||||
IR_DEBUG_PRINT(F(" is not "));
|
||||
IR_DEBUG_PRINT(aOneMarkMicros);
|
||||
IR_DEBUG_PRINT(F(" or "));
|
||||
IR_DEBUG_PRINT(aZeroMarkMicros);
|
||||
IR_DEBUG_PRINT(' ');
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Mark="));
|
||||
Serial.print(tMarkTicks * MICROS_PER_TICK);
|
||||
Serial.print(F(" is not "));
|
||||
Serial.print(aOneMarkMicros);
|
||||
Serial.print(F(" or "));
|
||||
Serial.print(aZeroMarkMicros);
|
||||
Serial.print(F(". Index="));
|
||||
Serial.print(i);
|
||||
Serial.print(' ');
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
tRawBufPointer++;
|
||||
|
||||
// If we have no stop bit, assume that last space, which is not recorded, is correct, since we can not check it
|
||||
if (tRawBufPointer < &decodedIRData.rawDataPtr->rawbuf[decodedIRData.rawDataPtr->rawlen]) {
|
||||
// Check for constant length space
|
||||
if (!matchSpace(*tRawBufPointer, aBitSpaceMicros)) {
|
||||
IR_DEBUG_PRINT(F("Space="));
|
||||
IR_DEBUG_PRINT(*tRawBufPointer * MICROS_PER_TICK);
|
||||
IR_DEBUG_PRINT(F(" is not "));
|
||||
IR_DEBUG_PRINT(aBitSpaceMicros);
|
||||
IR_DEBUG_PRINT(' ');
|
||||
unsigned int tSpaceTicks = *tRawBufPointer++;
|
||||
if (!matchSpace(tSpaceTicks, aBitSpaceMicros)) {
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Space="));
|
||||
Serial.print(tSpaceTicks * MICROS_PER_TICK);
|
||||
Serial.print(F(" is not "));
|
||||
Serial.print(aBitSpaceMicros);
|
||||
Serial.print(F(". Index="));
|
||||
Serial.print(i);
|
||||
Serial.print(' ');
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
tRawBufPointer++;
|
||||
}
|
||||
}
|
||||
IR_TRACE_PRINTLN(F(""));
|
||||
} else {
|
||||
// LSB first
|
||||
for (uint32_t tMask = 1UL; aNumberOfBits > 0; tMask <<= 1, aNumberOfBits--) {
|
||||
|
||||
uint32_t tMask = 1UL;
|
||||
for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
|
||||
// Check for variable length mark indicating a 0 or 1
|
||||
if (matchMark(*tRawBufPointer, aOneMarkMicros)) {
|
||||
unsigned int tMarkTicks = *tRawBufPointer++;
|
||||
if (matchMark(tMarkTicks, aOneMarkMicros)) {
|
||||
tDecodedData |= tMask; // set the bit
|
||||
IR_TRACE_PRINT('1');
|
||||
} else if (matchMark(*tRawBufPointer, aZeroMarkMicros)) {
|
||||
} else if (matchMark(tMarkTicks, aZeroMarkMicros)) {
|
||||
// do not set the bit
|
||||
IR_TRACE_PRINT('0');
|
||||
} else {
|
||||
IR_DEBUG_PRINT(F("Mark="));
|
||||
IR_DEBUG_PRINT(*tRawBufPointer * MICROS_PER_TICK);
|
||||
IR_DEBUG_PRINT(F(" is not "));
|
||||
IR_DEBUG_PRINT(aOneMarkMicros);
|
||||
IR_DEBUG_PRINT(F(" or "));
|
||||
IR_DEBUG_PRINT(aZeroMarkMicros);
|
||||
IR_DEBUG_PRINT(' ');
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Mark="));
|
||||
Serial.print(tMarkTicks * MICROS_PER_TICK);
|
||||
Serial.print(F(" is not "));
|
||||
Serial.print(aOneMarkMicros);
|
||||
Serial.print(F(" or "));
|
||||
Serial.print(aZeroMarkMicros);
|
||||
Serial.print(F(". Index="));
|
||||
Serial.print(aNumberOfBits - i);
|
||||
Serial.print(' ');
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
tRawBufPointer++;
|
||||
|
||||
// If we have no stop bit, assume that last space, which is not recorded, is correct, since we can not check it
|
||||
if (tRawBufPointer < &decodedIRData.rawDataPtr->rawbuf[decodedIRData.rawDataPtr->rawlen]) {
|
||||
// Check for constant length space here
|
||||
if (!matchSpace(*tRawBufPointer, aBitSpaceMicros)) {
|
||||
IR_DEBUG_PRINT(F("Space="));
|
||||
IR_DEBUG_PRINT(*tRawBufPointer * MICROS_PER_TICK);
|
||||
IR_DEBUG_PRINT(F(" is not "));
|
||||
IR_DEBUG_PRINT(aBitSpaceMicros);
|
||||
IR_DEBUG_PRINT(' ');
|
||||
unsigned int tSpaceTicks = *tRawBufPointer++;
|
||||
if (!matchSpace(tSpaceTicks, aBitSpaceMicros)) {
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Space="));
|
||||
Serial.print(tSpaceTicks * MICROS_PER_TICK);
|
||||
Serial.print(F(" is not "));
|
||||
Serial.print(aBitSpaceMicros);
|
||||
Serial.print(F(". Index="));
|
||||
Serial.print(aNumberOfBits - i);
|
||||
Serial.print(' ');
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
tRawBufPointer++;
|
||||
}
|
||||
tMask <<= 1;
|
||||
}
|
||||
IR_TRACE_PRINTLN(F(""));
|
||||
}
|
||||
|
@ -507,15 +534,7 @@ bool IRrecv::decodePulseWidthData(uint_fast8_t aNumberOfBits, uint_fast8_t aStar
|
|||
}
|
||||
|
||||
/**
|
||||
* Decode pulse distance protocols.
|
||||
* The mark (pulse) has constant length, the length of the space determines the bit value.
|
||||
* Each bit looks like: MARK + SPACE_1 -> 1
|
||||
* or : MARK + SPACE_0 -> 0
|
||||
*
|
||||
* Input is IrReceiver.decodedIRData.rawDataPtr->rawbuf[]
|
||||
* Output is IrReceiver.decodedIRData.decodedRawData
|
||||
*
|
||||
* @param aStartOffset must point to a mark
|
||||
* Decode pulse distance protocols for PulsePauseWidthProtocolConstants.
|
||||
* @return true if decoding was successful
|
||||
*/
|
||||
bool IRrecv::decodePulseDistanceData(PulsePauseWidthProtocolConstants *aProtocolConstants, uint_fast8_t aNumberOfBits,
|
||||
|
@ -546,21 +565,26 @@ bool IRrecv::decodePulseDistanceData(uint_fast8_t aNumberOfBits, uint_fast8_t aS
|
|||
uint32_t tMask = 1UL;
|
||||
for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
|
||||
// Check for constant length mark
|
||||
if (!matchMark(*tRawBufPointer, aBitMarkMicros)) {
|
||||
IR_DEBUG_PRINT(F("Mark="));
|
||||
IR_DEBUG_PRINT(*tRawBufPointer * MICROS_PER_TICK);
|
||||
IR_DEBUG_PRINT(F(" is not "));
|
||||
IR_DEBUG_PRINT(aBitMarkMicros);
|
||||
IR_DEBUG_PRINT(' ');
|
||||
unsigned int tMarkTicks = *tRawBufPointer++;
|
||||
if (!matchMark(tMarkTicks, aBitMarkMicros)) {
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Mark="));
|
||||
Serial.print(tMarkTicks * MICROS_PER_TICK);
|
||||
Serial.print(F(" is not "));
|
||||
Serial.print(aBitMarkMicros);
|
||||
Serial.print(F(". Index="));
|
||||
Serial.print(aNumberOfBits - i);
|
||||
Serial.print(' ');
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
tRawBufPointer++;
|
||||
|
||||
if (aMSBfirst) {
|
||||
tDecodedData <<= 1;
|
||||
}
|
||||
// Check for variable length space indicating a 0 or 1
|
||||
if (matchSpace(*tRawBufPointer, aOneSpaceMicros)) {
|
||||
unsigned int tSpaceTicks = *tRawBufPointer++;
|
||||
if (matchSpace(tSpaceTicks, aOneSpaceMicros)) {
|
||||
// set the bit
|
||||
if (aMSBfirst) {
|
||||
tDecodedData |= 1;
|
||||
|
@ -568,20 +592,23 @@ bool IRrecv::decodePulseDistanceData(uint_fast8_t aNumberOfBits, uint_fast8_t aS
|
|||
tDecodedData |= tMask;
|
||||
}
|
||||
IR_TRACE_PRINT('1');
|
||||
} else if (matchSpace(*tRawBufPointer, aZeroSpaceMicros)) {
|
||||
} else if (matchSpace(tSpaceTicks, aZeroSpaceMicros)) {
|
||||
// do not set the bit
|
||||
IR_TRACE_PRINT('0');
|
||||
} else {
|
||||
IR_DEBUG_PRINT(F("Space="));
|
||||
IR_DEBUG_PRINT(*tRawBufPointer * MICROS_PER_TICK);
|
||||
IR_DEBUG_PRINT(F(" is not "));
|
||||
IR_DEBUG_PRINT(aOneSpaceMicros);
|
||||
IR_DEBUG_PRINT(F(" or "));
|
||||
IR_DEBUG_PRINT(aZeroSpaceMicros);
|
||||
IR_DEBUG_PRINT(' ');
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Space="));
|
||||
Serial.print(tSpaceTicks * MICROS_PER_TICK);
|
||||
Serial.print(F(" is not "));
|
||||
Serial.print(aOneSpaceMicros);
|
||||
Serial.print(F(" or "));
|
||||
Serial.print(aZeroSpaceMicros);
|
||||
Serial.print(F(". Index="));
|
||||
Serial.print(aNumberOfBits - i);
|
||||
Serial.print(' ');
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
tRawBufPointer++;
|
||||
tMask <<= 1;
|
||||
}
|
||||
IR_TRACE_PRINTLN(F(""));
|
||||
|
@ -590,6 +617,77 @@ bool IRrecv::decodePulseDistanceData(uint_fast8_t aNumberOfBits, uint_fast8_t aS
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode pulse distance width protocols like MagiQuest.
|
||||
* Assume, that the sum of mark (pulse) and space has constant length, the length of the mark (or space) determines the bit value.
|
||||
* Therefore we only require the timing of the mark for the one.
|
||||
*
|
||||
* Input is IrReceiver.decodedIRData.rawDataPtr->rawbuf[]
|
||||
* Output is IrReceiver.decodedIRData.decodedRawData
|
||||
*
|
||||
* @param aStartOffset must point to a mark
|
||||
* @return true if decoding was successful
|
||||
*/
|
||||
bool IRrecv::decodeDistanceWidthData(uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset, unsigned int aOneMarkMicros,
|
||||
unsigned int aBitPeriodMicros, bool aMSBfirst) {
|
||||
|
||||
unsigned int *tRawBufPointer = &decodedIRData.rawDataPtr->rawbuf[aStartOffset];
|
||||
uint32_t tDecodedData = 0;
|
||||
|
||||
IR_TRACE_PRINT(F("DistanceWidt StartOffset="));
|
||||
IR_TRACE_PRINT(aStartOffset);
|
||||
IR_TRACE_PRINT(F(" NumberOfBits="));
|
||||
IR_TRACE_PRINTLN(aNumberOfBits);
|
||||
|
||||
uint32_t tMask = 1UL;
|
||||
for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
|
||||
// get one mark and space pair
|
||||
unsigned int tMarkTicks = *tRawBufPointer++;
|
||||
unsigned int tSpaceTicks = *tRawBufPointer++; // maybe buffer overflow for last bit, but we do not evaluate this value :-)
|
||||
|
||||
IR_TRACE_PRINT(F("Mark="));
|
||||
IR_TRACE_PRINT(tMarkTicks * MICROS_PER_TICK);
|
||||
IR_TRACE_PRINT(F(" space="));
|
||||
IR_TRACE_PRINTLN(tSpaceTicks * MICROS_PER_TICK);
|
||||
|
||||
// Check for constant period but not for last bit
|
||||
if (i != 1 && !matchMark(tMarkTicks + tSpaceTicks, aBitPeriodMicros)) {
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Mark="));
|
||||
Serial.print(tMarkTicks * MICROS_PER_TICK);
|
||||
Serial.print(F(" + space="));
|
||||
Serial.print(tSpaceTicks * MICROS_PER_TICK);
|
||||
Serial.print(F(" match not "));
|
||||
Serial.print(aBitPeriodMicros);
|
||||
Serial.print(F(". Index="));
|
||||
Serial.print(aNumberOfBits - i);
|
||||
Serial.print(' ');
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aMSBfirst) {
|
||||
tDecodedData <<= 1;
|
||||
}
|
||||
if (matchMark(tMarkTicks, aOneMarkMicros)) {
|
||||
// It's a 1 -> set the bit
|
||||
if (aMSBfirst) {
|
||||
tDecodedData |= 1;
|
||||
} else {
|
||||
tDecodedData |= tMask;
|
||||
}
|
||||
IR_TRACE_PRINTLN('1');
|
||||
} else {
|
||||
// do not set the bit
|
||||
IR_TRACE_PRINTLN('0');
|
||||
}
|
||||
tMask <<= 1;
|
||||
}
|
||||
|
||||
decodedIRData.decodedRawData = tDecodedData;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Static variables for the getBiphaselevel function
|
||||
*/
|
||||
|
@ -760,13 +858,17 @@ bool IRrecv::decodeHashOld(decode_results *aResults) {
|
|||
bool IRrecv::checkHeader(PulsePauseWidthProtocolConstants *aProtocolConstants) {
|
||||
// Check header "mark" and "space"
|
||||
if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], aProtocolConstants->HeaderMarkMicros)) {
|
||||
IR_DEBUG_PRINT(::getProtocolString(aProtocolConstants->ProtocolIndex));
|
||||
IR_DEBUG_PRINTLN(F(": Header mark length is wrong"));
|
||||
#if defined(TRACE)
|
||||
Serial.print(::getProtocolString(aProtocolConstants->ProtocolIndex));
|
||||
Serial.println(F(": Header mark length is wrong"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
if (!matchSpace(decodedIRData.rawDataPtr->rawbuf[2], aProtocolConstants->HeaderSpaceMicros)) {
|
||||
IR_DEBUG_PRINT(::getProtocolString(aProtocolConstants->ProtocolIndex));
|
||||
IR_DEBUG_PRINTLN(F(": Header space length is wrong"));
|
||||
#if defined(TRACE)
|
||||
Serial.print(::getProtocolString(aProtocolConstants->ProtocolIndex));
|
||||
Serial.println(F(": Header space length is wrong"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -795,9 +897,9 @@ bool matchTicks(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros) {
|
|||
bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros)) && (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros)));
|
||||
#if defined(TRACE)
|
||||
if (passed) {
|
||||
Serial.println(F("?; passed"));
|
||||
Serial.println(F(" => passed"));
|
||||
} else {
|
||||
Serial.println(F("?; FAILED"));
|
||||
Serial.println(F(" => FAILED"));
|
||||
}
|
||||
#endif
|
||||
return passed;
|
||||
|
@ -823,14 +925,14 @@ bool matchMark(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros) {
|
|||
Serial.print(F(" <= "));
|
||||
Serial.print(TICKS_HIGH(aMatchValueMicros + MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC);
|
||||
#endif
|
||||
// compensate for marks exceeded by demodulator hardware
|
||||
// compensate for marks exceeded by demodulator hardware
|
||||
bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros + MARK_EXCESS_MICROS))
|
||||
&& (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros + MARK_EXCESS_MICROS)));
|
||||
#if defined(TRACE)
|
||||
if (passed) {
|
||||
Serial.println(F("?; passed"));
|
||||
Serial.println(F(" => passed"));
|
||||
} else {
|
||||
Serial.println(F("?; FAILED"));
|
||||
Serial.println(F(" => FAILED"));
|
||||
}
|
||||
#endif
|
||||
return passed;
|
||||
|
@ -856,14 +958,14 @@ bool matchSpace(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros) {
|
|||
Serial.print(F(" <= "));
|
||||
Serial.print(TICKS_HIGH(aMatchValueMicros - MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC);
|
||||
#endif
|
||||
// compensate for spaces shortened by demodulator hardware
|
||||
// compensate for spaces shortened by demodulator hardware
|
||||
bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros - MARK_EXCESS_MICROS))
|
||||
&& (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros - MARK_EXCESS_MICROS)));
|
||||
#if defined(TRACE)
|
||||
if (passed) {
|
||||
Serial.println(F("?; passed"));
|
||||
Serial.println(F(" => passed"));
|
||||
} else {
|
||||
Serial.println(F("?; FAILED"));
|
||||
Serial.println(F(" => FAILED"));
|
||||
}
|
||||
#endif
|
||||
return passed;
|
||||
|
@ -956,11 +1058,11 @@ void printActiveIRProtocols(Print *aSerial) {
|
|||
#if defined(DECODE_MAGIQUEST)
|
||||
aSerial->print(F("MagiQuest, "));
|
||||
#endif
|
||||
#if defined(DECODE_DISTANCE)
|
||||
#if defined(DECODE_DISTANCE_WIDTH)
|
||||
# if defined(SUPPORT_PULSE_WIDTH_DECODING) // The only known pulse width protocol is Sony
|
||||
aSerial->print(F("Universal Distance, "));
|
||||
aSerial->print(F("Universal Pulse Distance Width, "));
|
||||
# else
|
||||
aSerial->print(F("Pulse Distance, "));
|
||||
aSerial->print(F("Pulse Distance Width, "));
|
||||
# endif
|
||||
#endif
|
||||
#if defined(DECODE_HASH)
|
||||
|
@ -1002,8 +1104,8 @@ void printIRResultShort(Print *aSerial, IRData *aIRDataPtr, bool aPrintRepeatGap
|
|||
aSerial->print((aIRDataPtr->rawDataPtr->rawlen + 1) / 2, DEC);
|
||||
aSerial->println(F(" bits (incl. gap and start) received"));
|
||||
} else {
|
||||
#if defined(DECODE_DISTANCE)
|
||||
if(aIRDataPtr->protocol != PULSE_DISTANCE) {
|
||||
#if defined(DECODE_DISTANCE_WIDTH)
|
||||
if (aIRDataPtr->protocol != PULSE_DISTANCE && aIRDataPtr->protocol != PULSE_DISTANCE_WIDTH) {
|
||||
#endif
|
||||
/*
|
||||
* New decoders have address and command
|
||||
|
@ -1030,7 +1132,7 @@ void printIRResultShort(Print *aSerial, IRData *aIRDataPtr, bool aPrintRepeatGap
|
|||
aSerial->print(F(" Toggle=1"));
|
||||
}
|
||||
}
|
||||
#if defined(DECODE_DISTANCE)
|
||||
#if defined(DECODE_DISTANCE_WIDTH)
|
||||
}
|
||||
#endif
|
||||
if (aIRDataPtr->flags & (IRDATA_FLAGS_IS_AUTO_REPEAT | IRDATA_FLAGS_IS_REPEAT)) {
|
||||
|
@ -1087,9 +1189,9 @@ void IRrecv::printIRSendUsage(Print *aSerial) {
|
|||
|
||||
void printIRSendUsage(Print *aSerial, IRData *aIRDataPtr) {
|
||||
if (aIRDataPtr->protocol != UNKNOWN && (aIRDataPtr->flags & (IRDATA_FLAGS_IS_AUTO_REPEAT | IRDATA_FLAGS_IS_REPEAT)) == 0x00) {
|
||||
#if defined(DECODE_DISTANCE)
|
||||
#if defined(DECODE_DISTANCE_WIDTH)
|
||||
aSerial->print(F("Send with:"));
|
||||
if (aIRDataPtr->protocol == PULSE_DISTANCE) {
|
||||
if (aIRDataPtr->protocol == PULSE_DISTANCE || aIRDataPtr->protocol == PULSE_DISTANCE_WIDTH) {
|
||||
aSerial->println();
|
||||
aSerial->print(F(" uint32_t tRawData[]={0x"));
|
||||
uint_fast8_t tNumberOf32BitChunks = ((aIRDataPtr->numberOfBits - 1) / 32) + 1;
|
||||
|
@ -1107,54 +1209,69 @@ void printIRSendUsage(Print *aSerial, IRData *aIRDataPtr) {
|
|||
aSerial->print(F("Send with: IrSender.send"));
|
||||
#endif
|
||||
|
||||
#if defined(DECODE_DISTANCE)
|
||||
if (aIRDataPtr->protocol != PULSE_DISTANCE) {
|
||||
#if defined(DECODE_DISTANCE_WIDTH)
|
||||
if (aIRDataPtr->protocol != PULSE_DISTANCE && aIRDataPtr->protocol != PULSE_DISTANCE_WIDTH) {
|
||||
#endif
|
||||
aSerial->print(getProtocolString(aIRDataPtr->protocol));
|
||||
aSerial->print(F("(0x"));
|
||||
aSerial->print(getProtocolString(aIRDataPtr->protocol));
|
||||
aSerial->print(F("(0x"));
|
||||
#if defined(DECODE_MAGIQUEST)
|
||||
if (aIRDataPtr->protocol == MAGIQUEST) {
|
||||
aSerial->print(aIRDataPtr->decodedRawData, HEX);
|
||||
} else {
|
||||
aSerial->print(aIRDataPtr->address, HEX);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* New decoders have address and command
|
||||
*/
|
||||
if (aIRDataPtr->protocol == MAGIQUEST) {
|
||||
aSerial->print(aIRDataPtr->decodedRawData, HEX);
|
||||
} else {
|
||||
aSerial->print(aIRDataPtr->address, HEX);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* New decoders have address and command
|
||||
*/
|
||||
aSerial->print(aIRDataPtr->address, HEX);
|
||||
#endif
|
||||
|
||||
aSerial->print(F(", 0x"));
|
||||
aSerial->print(aIRDataPtr->command, HEX);
|
||||
aSerial->print(F(", <numberOfRepeats>"));
|
||||
aSerial->print(F(", 0x"));
|
||||
aSerial->print(aIRDataPtr->command, HEX);
|
||||
aSerial->print(F(", <numberOfRepeats>"));
|
||||
|
||||
if (aIRDataPtr->flags & IRDATA_FLAGS_EXTRA_INFO) {
|
||||
aSerial->print(F(", 0x"));
|
||||
aSerial->print(aIRDataPtr->extra, HEX);
|
||||
}
|
||||
#if defined(DECODE_DISTANCE)
|
||||
if (aIRDataPtr->flags & IRDATA_FLAGS_EXTRA_INFO) {
|
||||
aSerial->print(F(", 0x"));
|
||||
aSerial->print(aIRDataPtr->extra, HEX);
|
||||
}
|
||||
#if defined(DECODE_DISTANCE_WIDTH)
|
||||
} else {
|
||||
aSerial->print("PulseDistanceWidthFromArray(38, ");
|
||||
aSerial->print((aIRDataPtr->extra >> 8) * MICROS_PER_TICK); // aHeaderMarkMicros
|
||||
aSerial->print(F(", "));
|
||||
aSerial->print((aIRDataPtr->extra & 0xFF) * MICROS_PER_TICK); // aHeaderSpaceMicros
|
||||
aSerial->print((aIRDataPtr->extra & 0xFF) * MICROS_PER_TICK);// aHeaderSpaceMicros
|
||||
aSerial->print(F(", "));
|
||||
aSerial->print((aIRDataPtr->address >> 8) * MICROS_PER_TICK); // aOneMarkMicros
|
||||
|
||||
// address = tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << 8) | tSpaceTicksLong
|
||||
// command = tMarkTicksShort << 8) | tSpaceTicksShort
|
||||
aSerial->print((aIRDataPtr->address >> 8) * MICROS_PER_TICK);// aOneMarkMicros
|
||||
aSerial->print(F(", "));
|
||||
aSerial->print((aIRDataPtr->address & 0xFF) * MICROS_PER_TICK); // aOneSpaceMicros
|
||||
if (aIRDataPtr->protocol == PULSE_DISTANCE) {
|
||||
aSerial->print((aIRDataPtr->address & 0xFF) * MICROS_PER_TICK);// aOneSpaceMicros
|
||||
} else {
|
||||
aSerial->print((aIRDataPtr->command & 0xFF) * MICROS_PER_TICK);// aOneSpaceMicros
|
||||
}
|
||||
aSerial->print(F(", "));
|
||||
aSerial->print((aIRDataPtr->command >> 8) * MICROS_PER_TICK); // aZeroMarkMicros
|
||||
aSerial->print((aIRDataPtr->command >> 8) * MICROS_PER_TICK);// aZeroMarkMicros
|
||||
aSerial->print(F(", "));
|
||||
aSerial->print((aIRDataPtr->command & 0xFF) * MICROS_PER_TICK); // aZeroSpaceMicros
|
||||
if (aIRDataPtr->protocol == PULSE_DISTANCE) {
|
||||
aSerial->print((aIRDataPtr->command & 0xFF) * MICROS_PER_TICK);// aZeroSpaceMicros
|
||||
}else {
|
||||
aSerial->print((aIRDataPtr->address & 0xFF) * MICROS_PER_TICK);// aZeroSpaceMicros
|
||||
}
|
||||
aSerial->print(F(", &tRawData[0], "));
|
||||
aSerial->print(aIRDataPtr->numberOfBits); // aNumberOfBits
|
||||
#if defined(DISTANCE_DO_MSB_DECODING)
|
||||
aSerial->print(F(", PROTOCOL_IS_MSB_FIRST"));
|
||||
#else
|
||||
aSerial->print(F(", PROTOCOL_IS_LSB_FIRST"));
|
||||
#endif
|
||||
aSerial->print(F(", SEND_STOP_BIT"));
|
||||
aSerial->print(aIRDataPtr->numberOfBits);// aNumberOfBits
|
||||
if (aIRDataPtr->flags & IRDATA_FLAGS_IS_MSB_FIRST) {
|
||||
aSerial->print(F(", PROTOCOL_IS_MSB_FIRST"));
|
||||
} else {
|
||||
aSerial->print(F(", PROTOCOL_IS_LSB_FIRST"));
|
||||
}
|
||||
if (aIRDataPtr->protocol == PULSE_DISTANCE) {
|
||||
aSerial->print(F(", SEND_STOP_BIT"));
|
||||
} else {
|
||||
aSerial->print(F(", SEND_NO_STOP_BIT")); // assume no stop bit like for Magiquest.
|
||||
}
|
||||
aSerial->print(F(", <millisofRepeatPeriod>, <numberOfRepeats>"));
|
||||
}
|
||||
#endif
|
||||
|
@ -1222,7 +1339,7 @@ void IRrecv::printIRResultRawFormatted(Print *aSerial, bool aOutputMicrosecondsI
|
|||
#if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
|
||||
uint_fast8_t i;
|
||||
#else
|
||||
unsigned int i;
|
||||
unsigned int i;
|
||||
#endif
|
||||
|
||||
// Newline is printed every 8. value, if tCounterForNewline % 8 == 0
|
||||
|
@ -1237,7 +1354,7 @@ void IRrecv::printIRResultRawFormatted(Print *aSerial, bool aOutputMicrosecondsI
|
|||
#if defined(DECODE_MAGIQUEST)
|
||||
decodedIRData.protocol == MAGIQUEST ||
|
||||
#endif
|
||||
false) {
|
||||
false) {
|
||||
tCounterForNewline = 0; // no or 8 start bits
|
||||
}
|
||||
#endif
|
||||
|
@ -1316,7 +1433,7 @@ void IRrecv::compensateAndPrintIRResultAsCArray(Print *aSerial, bool aOutputMicr
|
|||
#if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
|
||||
uint_fast8_t i;
|
||||
#else
|
||||
unsigned int i;
|
||||
unsigned int i;
|
||||
#endif
|
||||
for (i = 1; i < decodedIRData.rawDataPtr->rawlen; i++) {
|
||||
uint32_t tDuration = decodedIRData.rawDataPtr->rawbuf[i] * MICROS_PER_TICK;
|
||||
|
@ -1367,7 +1484,7 @@ void IRrecv::compensateAndStoreIRResultInArray(uint8_t *aArrayPtr) {
|
|||
#if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
|
||||
uint_fast8_t i;
|
||||
#else
|
||||
unsigned int i;
|
||||
unsigned int i;
|
||||
#endif
|
||||
for (i = 1; i < decodedIRData.rawDataPtr->rawlen; i++) {
|
||||
uint32_t tDuration = decodedIRData.rawDataPtr->rawbuf[i] * MICROS_PER_TICK;
|
||||
|
@ -1416,41 +1533,19 @@ void IRrecv::printIRResultAsCVariables(Print *aSerial) {
|
|||
/*
|
||||
* !!Must be the same order as in decode_type_t in IRProtocol.h!!!
|
||||
*/
|
||||
const char * const ProtocolNames[] PROGMEM =
|
||||
{
|
||||
string_Unknown,
|
||||
const char *const ProtocolNames[]
|
||||
PROGMEM = { string_Unknown,
|
||||
#if defined(SUPPORT_PULSE_WIDTH_DECODING) // The only known pulse width protocol is Sony
|
||||
string_PulseWidth,
|
||||
#endif
|
||||
string_PulseDistance,
|
||||
string_Apple,
|
||||
string_Denon,
|
||||
string_JVC,
|
||||
string_LG,
|
||||
string_LG2,
|
||||
string_NEC,
|
||||
string_NEC2,
|
||||
string_Onkyo,
|
||||
string_Panasonic,
|
||||
string_Kaseikyo,
|
||||
string_Kaseikyo_Denon,
|
||||
string_Kaseikyo_Sharp,
|
||||
string_Kaseikyo_JVC,
|
||||
string_Kaseikyo_Mitsubishi,
|
||||
string_RC5,
|
||||
string_RC6,
|
||||
string_Samsung,
|
||||
string_SamsungLG,
|
||||
string_Sharp,
|
||||
string_Sony
|
||||
string_PulseDistance, string_PulseDistanceWidth, string_Apple, string_Denon, string_JVC, string_LG, string_LG2, string_NEC,
|
||||
string_NEC2, string_Onkyo, string_Panasonic, string_Kaseikyo, string_Kaseikyo_Denon, string_Kaseikyo_Sharp,
|
||||
string_Kaseikyo_JVC, string_Kaseikyo_Mitsubishi, string_RC5, string_RC6, string_Samsung, string_SamsungLG, string_Sharp,
|
||||
string_Sony
|
||||
#if !defined(EXCLUDE_EXOTIC_PROTOCOLS)
|
||||
, string_BangOlufsen,
|
||||
string_BoseWave,
|
||||
string_Lego,
|
||||
string_MagiQuest,
|
||||
string_Whynter
|
||||
, string_BangOlufsen, string_BoseWave, string_Lego, string_MagiQuest, string_Whynter
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
#if defined(__AVR__)
|
||||
const __FlashStringHelper* IRrecv::getProtocolString() {
|
||||
|
@ -1459,12 +1554,12 @@ const __FlashStringHelper* IRrecv::getProtocolString() {
|
|||
}
|
||||
|
||||
const __FlashStringHelper* getProtocolString(decode_type_t aProtocol) {
|
||||
const char* tProtocolStringPtr = (char*) pgm_read_word(&ProtocolNames[aProtocol]);
|
||||
return((__FlashStringHelper *) (tProtocolStringPtr));
|
||||
const char *tProtocolStringPtr = (char*) pgm_read_word(&ProtocolNames[aProtocol]);
|
||||
return ((__FlashStringHelper*) (tProtocolStringPtr));
|
||||
}
|
||||
#else
|
||||
const char* IRrecv::getProtocolString() {
|
||||
// call no class function with same name
|
||||
// call no class function with same name
|
||||
return ::getProtocolString(decodedIRData.protocol);
|
||||
}
|
||||
|
||||
|
@ -1494,9 +1589,10 @@ const char* getProtocolString(decode_type_t aProtocol) {
|
|||
//#define _IR_MEASURE_TIMING
|
||||
//#define _IR_TIMING_TEST_PIN 7 // do not forget to execute: "pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);" if activated by line above
|
||||
#if defined(TIMER_INTR_NAME)
|
||||
ISR (TIMER_INTR_NAME) // for ISR definitions
|
||||
ISR (TIMER_INTR_NAME) // for ISR definitions
|
||||
#else
|
||||
ISR () // for functions definitions which are called by separate (board specific) ISR
|
||||
ISR()
|
||||
// for functions definitions which are called by separate (board specific) ISR
|
||||
#endif
|
||||
{
|
||||
#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
|
||||
|
@ -1608,13 +1704,13 @@ ISR () // for functions definitions which are called by separate (board specific
|
|||
uint8_t bitreverseOneByte(uint8_t aValue) {
|
||||
// uint8_t tReversedValue;
|
||||
// return __builtin_avr_insert_bits(0x01234567, aValue, tReversedValue);
|
||||
// 76543210
|
||||
// 76543210
|
||||
aValue = (aValue >> 4) | (aValue << 4); // Swap in groups of 4
|
||||
// 32107654
|
||||
// 32107654
|
||||
aValue = ((aValue & 0xcc) >> 2) | ((aValue & 0x33) << 2); // Swap in groups of 2
|
||||
// 10325476
|
||||
// 10325476
|
||||
aValue = ((aValue & 0xaa) >> 1) | ((aValue & 0x55) << 1); // Swap bit pairs
|
||||
// 01234567
|
||||
// 01234567
|
||||
return aValue;
|
||||
}
|
||||
|
||||
|
@ -1666,14 +1762,14 @@ bool IRrecv::decode(decode_results *aResults) {
|
|||
#if defined(DECODE_NEC)
|
||||
IR_DEBUG_PRINTLN(F("Attempting old NEC decode"));
|
||||
if (decodeNECMSB(aResults)) {
|
||||
return true ;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DECODE_SONY)
|
||||
IR_DEBUG_PRINTLN(F("Attempting old Sony decode"));
|
||||
if (decodeSonyMSB(aResults)) {
|
||||
return true ;
|
||||
if (decodeSonyMSB(aResults)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1684,17 +1780,17 @@ bool IRrecv::decode(decode_results *aResults) {
|
|||
aResults->value = decodedIRData.decodedRawData;
|
||||
aResults->decode_type = RC5;
|
||||
|
||||
return true ;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DECODE_RC6)
|
||||
IR_DEBUG_PRINTLN(F("Attempting RC6 decode"));
|
||||
if (decodeRC6()) {
|
||||
if (decodeRC6()) {
|
||||
aResults->bits = decodedIRData.numberOfBits;
|
||||
aResults->value = decodedIRData.decodedRawData;
|
||||
aResults->decode_type = RC6;
|
||||
return true ;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1702,27 +1798,27 @@ bool IRrecv::decode(decode_results *aResults) {
|
|||
|
||||
#if defined(DECODE_LG)
|
||||
IR_DEBUG_PRINTLN(F("Attempting old LG decode"));
|
||||
if (decodeLGMSB(aResults)) { return true ;}
|
||||
if (decodeLGMSB(aResults)) {return true;}
|
||||
#endif
|
||||
|
||||
#if defined(DECODE_JVC)
|
||||
IR_DEBUG_PRINTLN(F("Attempting old JVC decode"));
|
||||
if (decodeJVCMSB(aResults)) {
|
||||
return true ;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DECODE_SAMSUNG)
|
||||
IR_DEBUG_PRINTLN(F("Attempting old SAMSUNG decode"));
|
||||
if (decodeSAMSUNG(aResults)) {
|
||||
return true ;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DECODE_DENON)
|
||||
IR_DEBUG_PRINTLN(F("Attempting old Denon decode"));
|
||||
if (decodeDenonOld(aResults)) {
|
||||
return true ;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1738,4 +1834,7 @@ bool IRrecv::decode(decode_results *aResults) {
|
|||
}
|
||||
|
||||
/** @}*/
|
||||
#if defined(LOCAL_DEBUG)
|
||||
#undef LOCAL_DEBUG
|
||||
#endif
|
||||
#endif // _IR_RECEIVE_HPP
|
||||
|
|
|
@ -32,6 +32,12 @@
|
|||
#ifndef _IR_SEND_HPP
|
||||
#define _IR_SEND_HPP
|
||||
|
||||
#if defined(DEBUG) && !defined(LOCAL_DEBUG)
|
||||
#define LOCAL_DEBUG
|
||||
#else
|
||||
#define LOCAL_DEBUG // This enables debug output only for this file
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This improves readability of code by avoiding a lot of #if defined clauses
|
||||
*/
|
||||
|
@ -368,6 +374,19 @@ void IRsend::sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, unsigne
|
|||
uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
|
||||
uint_fast8_t tNumberOf32BitChunks = ((aNumberOfBits - 1) / 32) + 1;
|
||||
|
||||
#if defined(LOCAL_DEBUG)
|
||||
// fist data
|
||||
Serial.print(F("Data[0]=0x"));
|
||||
Serial.print(aDecodedRawDataArray[0], HEX);
|
||||
if (tNumberOf32BitChunks > 1) {
|
||||
Serial.print(F(" Data[1]=0x"));
|
||||
Serial.print(aDecodedRawDataArray[1], HEX);
|
||||
}
|
||||
Serial.print(F(" #="));
|
||||
Serial.println(aNumberOfBits);
|
||||
Serial.flush();
|
||||
#endif
|
||||
|
||||
while (tNumberOfCommands > 0) {
|
||||
unsigned long tStartOfFrameMillis = millis();
|
||||
|
||||
|
@ -377,25 +396,24 @@ void IRsend::sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, unsigne
|
|||
|
||||
for (uint_fast8_t i = 0; i < tNumberOf32BitChunks; ++i) {
|
||||
uint8_t tNumberOfBitsForOneSend;
|
||||
bool tSendStopBit;
|
||||
if (aNumberOfBits > 32) {
|
||||
tNumberOfBitsForOneSend = 32;
|
||||
} else {
|
||||
tNumberOfBitsForOneSend = aNumberOfBits;
|
||||
}
|
||||
|
||||
// Manage stop bit
|
||||
bool tSendStopBit;
|
||||
if (i == (tNumberOf32BitChunks - 1)) {
|
||||
// End of data
|
||||
tNumberOfBitsForOneSend = aNumberOfBits;
|
||||
tSendStopBit = aSendStopBit;
|
||||
} else {
|
||||
// intermediate data
|
||||
tNumberOfBitsForOneSend = 32;
|
||||
tSendStopBit = false;
|
||||
}
|
||||
|
||||
sendPulseDistanceWidthData(aOneMarkMicros, aOneSpaceMicros, aZeroMarkMicros, aZeroSpaceMicros, aDecodedRawDataArray[i],
|
||||
tNumberOfBitsForOneSend, aMSBFirst, tSendStopBit);
|
||||
|
||||
aNumberOfBits -= 32;
|
||||
}
|
||||
|
||||
|
@ -415,7 +433,7 @@ void IRsend::sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, unsigne
|
|||
}
|
||||
|
||||
/**
|
||||
* Sends PulseDistance data from array
|
||||
* Sends PulseDistance data from array using PulsePauseWidthProtocolConstants
|
||||
* For LSB First the LSB of array[0] is sent first then all bits until MSB of array[0]. Next is LSB of array[1] and so on.
|
||||
* The output always ends with a space
|
||||
* Stop bit is always sent
|
||||
|
@ -585,6 +603,13 @@ void IRsend::sendPulseDistanceWidthData(PulsePauseWidthProtocolConstants *aProto
|
|||
void IRsend::sendPulseDistanceWidthData(unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros,
|
||||
unsigned int aZeroSpaceMicros, uint32_t aData, uint_fast8_t aNumberOfBits, bool aMSBFirst, bool aSendStopBit) {
|
||||
|
||||
#if defined(LOCAL_DEBUG)
|
||||
// Even printing this short messages (at 115200) disturbs the send timing :-(
|
||||
// Serial.print(aData, HEX);
|
||||
// Serial.print('|');
|
||||
// Serial.println(aNumberOfBits);
|
||||
#endif
|
||||
|
||||
// if (aMSBFirst) { // Send the MSB first.
|
||||
// For MSBFirst, send data from MSB to LSB until mask bit is shifted out
|
||||
uint32_t tMask = 1UL << (aNumberOfBits - 1);
|
||||
|
@ -901,4 +926,7 @@ unsigned int IRsend::getPulseCorrectionNanos() {
|
|||
}
|
||||
|
||||
/** @}*/
|
||||
#if defined(LOCAL_DEBUG)
|
||||
#undef LOCAL_DEBUG
|
||||
#endif
|
||||
#endif // _IR_SEND_HPP
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
# if (!(defined(DECODE_DENON) || defined(DECODE_JVC) || defined(DECODE_KASEIKYO) \
|
||||
|| defined(DECODE_PANASONIC) || defined(DECODE_LG) || defined(DECODE_NEC) || defined(DECODE_SAMSUNG) \
|
||||
|| defined(DECODE_SONY) || defined(DECODE_RC5) || defined(DECODE_RC6) \
|
||||
|| defined(DECODE_DISTANCE) || defined(DECODE_HASH) || defined(DECODE_BOSEWAVE) \
|
||||
|| defined(DECODE_DISTANCE_WIDTH) || defined(DECODE_HASH) || defined(DECODE_BOSEWAVE) \
|
||||
|| defined(DECODE_LEGO_PF) || defined(DECODE_MAGIQUEST) || defined(DECODE_WHYNTER)))
|
||||
/*
|
||||
* If no protocol is explicitly enabled, we enable all protocols
|
||||
|
@ -122,7 +122,7 @@
|
|||
# endif
|
||||
|
||||
# if !defined(EXCLUDE_UNIVERSAL_PROTOCOLS)
|
||||
#define DECODE_DISTANCE // universal decoder for pulse distance protocols - requires up to 750 bytes additional program memory
|
||||
#define DECODE_DISTANCE_WIDTH // universal decoder for pulse distance width protocols - requires up to 750 bytes additional program memory
|
||||
#define DECODE_HASH // special decoder for all protocols - requires up to 250 bytes additional program memory
|
||||
# endif
|
||||
# endif
|
||||
|
@ -324,8 +324,8 @@
|
|||
#include "ir_Sony.hpp"
|
||||
#include "ir_Others.hpp"
|
||||
#include "ir_Pronto.hpp" // pronto is an universal decoder and encoder
|
||||
# if defined(DECODE_DISTANCE) // universal decoder for pulse distance protocols - requires up to 750 bytes additional program memory
|
||||
#include "ir_DistanceProtocol.hpp"
|
||||
# if defined(DECODE_DISTANCE_WIDTH) // universal decoder for pulse distance width protocols - requires up to 750 bytes additional program memory
|
||||
#include <ir_DistanceWidthProtocol.hpp>
|
||||
# endif
|
||||
|
||||
#endif // #if !defined(USE_IRREMOTE_HPP_AS_PLAIN_INCLUDE)
|
||||
|
|
|
@ -148,16 +148,16 @@ struct irparams_struct {
|
|||
*/
|
||||
struct IRData {
|
||||
decode_type_t protocol; ///< UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
|
||||
uint16_t address; ///< Decoded address, Distance protocol (OneMarkTicks << 8) | OneSpaceTicks
|
||||
uint16_t command; ///< Decoded command, Distance protocol (ZeroMarkTicks << 8) | ZeroSpaceTicks
|
||||
uint16_t address; ///< Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << 8) | tSpaceTicksLong
|
||||
uint16_t command; ///< Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort
|
||||
uint16_t extra; ///< Contains upper 16 bit of Magiquest WandID, Kaseikyo unknown vendor ID and Distance protocol (HeaderMarkTicks << 8) | HeaderSpaceTicks.
|
||||
uint16_t numberOfBits; ///< Number of bits received for data (address + command + parity) - to determine protocol length if different length are possible.
|
||||
uint8_t flags; ///< See IRDATA_FLAGS_* definitions above
|
||||
uint32_t decodedRawData; ///< Up to 32 bit decoded raw data, to be used for send functions.
|
||||
#if defined(DECODE_DISTANCE)
|
||||
#if defined(DECODE_DISTANCE_WIDTH)
|
||||
uint32_t decodedRawDataArray[RAW_DATA_ARRAY_SIZE]; ///< 32 bit decoded raw data, to be used for send function.
|
||||
#endif
|
||||
irparams_struct *rawDataPtr; ///< Pointer of the raw timing data to be decoded. Mainly the data buffer filled by receiving ISR.
|
||||
irparams_struct *rawDataPtr; ///< Pointer of the raw timing data to be decoded. Mainly the OverflowFlag and the data buffer filled by receiving ISR.
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -254,6 +254,9 @@ public:
|
|||
bool decodePulseWidthData(uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset, unsigned int aOneMarkMicros,
|
||||
unsigned int aZeroMarkMicros, unsigned int aBitSpaceMicros, bool aMSBfirst);
|
||||
|
||||
bool decodeDistanceWidthData(uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset, unsigned int aOneMarkMicros,
|
||||
unsigned int aBitPeriodMicros, bool aMSBfirst);
|
||||
|
||||
bool decodeBiPhaseData(uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset, uint_fast8_t aStartClockCount,
|
||||
uint_fast8_t aValueOfSpaceToMarkTransition, unsigned int aBiphaseTimeUnit);
|
||||
|
||||
|
|
|
@ -310,10 +310,11 @@ bool isTinyReceiverIdle() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets IR_INPUT_PIN mode to INPUT_PULLUP, if required, sets feedback LED output mode and call enablePCIInterruptForTinyReceiver()
|
||||
* Sets IR_INPUT_PIN mode to INPUT, and if IR_FEEDBACK_LED_PIN is defined, sets feedback LED output mode.
|
||||
* Then call enablePCIInterruptForTinyReceiver()
|
||||
*/
|
||||
bool initPCIInterruptForTinyReceiver() {
|
||||
pinModeFast(IR_INPUT_PIN, INPUT_PULLUP);
|
||||
pinModeFast(IR_INPUT_PIN, INPUT);
|
||||
|
||||
#if !defined(NO_LED_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)
|
||||
pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT);
|
||||
|
|
|
@ -1,28 +1,37 @@
|
|||
/*
|
||||
* ir_DistanceProtocol.hpp
|
||||
* ir_DistanceWidthProtocol.hpp
|
||||
*
|
||||
* Contains only the decoder functions!
|
||||
*
|
||||
* This decoder tries to decode a pulse width or pulse distance protocol.
|
||||
* This decoder tries to decode a pulse distance or pulse distance width with constant period (or pulse width - not enabled yet) protocol.
|
||||
* 1. Analyze all space and mark length
|
||||
* 2. Decide if we have an pulse width or distance protocol
|
||||
* 2. Decide which protocol we have
|
||||
* 3. Try to decode with the mark and space data found in step 1
|
||||
* 4. Assume one start bit / header and one stop bit, since pulse distance data must have a stop bit!
|
||||
* No data and address decoding, only raw data as result.
|
||||
*
|
||||
* Pulse distance data can be sent with the generic function:
|
||||
* Pulse distance data can be sent with the generic function as in SendDemo example line 155:
|
||||
* https://github.com/Arduino-IRremote/Arduino-IRremote/blob/d51b540cb2ddf1424888d2d9e6b62fe1ef46859d/examples/SendDemo/SendDemo.ino#L155
|
||||
* void sendPulseDistanceWidthData(unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros,
|
||||
* unsigned int aZeroSpaceMicros, uint32_t aData, uint8_t aNumberOfBits, bool aMSBfirst, bool aSendStopBit = false)
|
||||
* The header must be sent manually with:
|
||||
* IrSender.mark(MarkMicros)
|
||||
* IrSender.space(SpaceMicros);
|
||||
* see also: SendDemo example line 150
|
||||
*
|
||||
* Or send it by filling a DecodedRawDataArray and with the sendPulseDistanceWidthFromArray() function as in SendDemo example line 175:
|
||||
* https://github.com/Arduino-IRremote/Arduino-IRremote/blob/d51b540cb2ddf1424888d2d9e6b62fe1ef46859d/examples/SendDemo/SendDemo.ino#L175
|
||||
* sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, unsigned int aHeaderMarkMicros,
|
||||
* unsigned int aHeaderSpaceMicros, unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros,
|
||||
* unsigned int aZeroSpaceMicros, uint32_t *aDecodedRawDataArray, unsigned int aNumberOfBits, bool aMSBFirst,
|
||||
* bool aSendStopBit, unsigned int aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats)
|
||||
*
|
||||
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
|
||||
*
|
||||
************************************************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Armin Joachimsmeyer
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
|
@ -42,9 +51,8 @@
|
|||
*
|
||||
************************************************************************************
|
||||
*/
|
||||
#ifndef _IR_DISTANCE_HPP
|
||||
#define _IR_DISTANCE_HPP
|
||||
|
||||
#ifndef _IR_DISTANCE_WIDTH_HPP
|
||||
#define _IR_DISTANCE_WIDTH_HPP
|
||||
|
||||
// accept durations up to 50 * 50 (MICROS_PER_TICK) 2500 microseconds
|
||||
#define DURATION_ARRAY_SIZE 50
|
||||
|
@ -62,7 +70,6 @@
|
|||
* @{
|
||||
*/
|
||||
// see: https://www.mikrocontroller.net/articles/IRMP_-_english#Codings
|
||||
|
||||
#if defined(LOCAL_DEBUG)
|
||||
void printDurations(uint8_t aArray[], uint8_t aMaxIndex) {
|
||||
for (uint_fast8_t i = 0; i <= aMaxIndex; i++) {
|
||||
|
@ -73,10 +80,14 @@ void printDurations(uint8_t aArray[], uint8_t aMaxIndex) {
|
|||
Serial.println();
|
||||
}
|
||||
Serial.print(i);
|
||||
Serial.print(F(":"));
|
||||
Serial.print(F(": "));
|
||||
}
|
||||
Serial.print(aArray[i]);
|
||||
if (aArray[i] != 0) {
|
||||
Serial.print(' ');
|
||||
Serial.print(i * (uint16_t)MICROS_PER_TICK);
|
||||
}
|
||||
Serial.print(F(" | "));
|
||||
Serial.print(aArray[i]);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
@ -125,13 +136,13 @@ bool aggregateArrayCounts(uint8_t aArray[], uint8_t aMaxIndex, uint8_t *aShortIn
|
|||
* No data and address decoding, only raw data as result.
|
||||
*/
|
||||
bool IRrecv::decodeDistance() {
|
||||
uint8_t tDurationArray[DURATION_ARRAY_SIZE];
|
||||
uint8_t tDurationArray[DURATION_ARRAY_SIZE]; // For up to 49 ticks / 2450 us
|
||||
|
||||
/*
|
||||
* Accept only protocols with at least 8 bits
|
||||
*/
|
||||
if (decodedIRData.rawDataPtr->rawlen < (2 * 8) + 4) {
|
||||
IR_DEBUG_PRINT(F("PULSE_DISTANCE: "));
|
||||
IR_DEBUG_PRINT(F("PULSE_DISTANCE_WIDTH: "));
|
||||
IR_DEBUG_PRINT(F("Data length="));
|
||||
IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen);
|
||||
IR_DEBUG_PRINTLN(F(" is less than 20"));
|
||||
|
@ -145,12 +156,12 @@ bool IRrecv::decodeDistance() {
|
|||
|
||||
uint8_t tMaxDurationIndex = 0;
|
||||
/*
|
||||
* Count number of mark durations. Skip leading start and trailing stop bit.
|
||||
* Count number of mark durations up to 49 ticks. Skip leading start and trailing stop bit.
|
||||
*/
|
||||
for (i = 3; i < (uint_fast8_t) decodedIRData.rawDataPtr->rawlen - 2; i += 2) {
|
||||
uint8_t tDurationTicks = decodedIRData.rawDataPtr->rawbuf[i];
|
||||
if (tDurationTicks < sizeof(tDurationArray)) {
|
||||
tDurationArray[tDurationTicks]++;
|
||||
tDurationArray[tDurationTicks]++; // count duration if less than DURATION_ARRAY_SIZE (50)
|
||||
if (tMaxDurationIndex < tDurationTicks) {
|
||||
tMaxDurationIndex = tDurationTicks;
|
||||
}
|
||||
|
@ -169,8 +180,10 @@ bool IRrecv::decodeDistance() {
|
|||
#endif
|
||||
|
||||
if (!tSuccess) {
|
||||
IR_DEBUG_PRINT(F("PULSE_DISTANCE: "));
|
||||
IR_DEBUG_PRINTLN(F("Mark aggregation failed, more than 2 distinct mark duration values found"));
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("PULSE_DISTANCE_WIDTH: "));
|
||||
Serial.println(F("Mark aggregation failed, more than 2 distinct mark duration values found"));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Reset duration array
|
||||
|
@ -202,19 +215,13 @@ bool IRrecv::decodeDistance() {
|
|||
#endif
|
||||
|
||||
if (!tSuccess) {
|
||||
IR_DEBUG_PRINT(F("PULSE_DISTANCE: "));
|
||||
IR_DEBUG_PRINTLN(F("Space aggregation failed, more than 2 distinct space duration values found"));
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("PULSE_DISTANCE_WIDTH: "));
|
||||
Serial.println(F("Space aggregation failed, more than 2 distinct space duration values found"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// skip leading start bit and trailing stop bit for decoding.
|
||||
uint16_t tNumberOfBits = (decodedIRData.rawDataPtr->rawlen / 2) - 2;
|
||||
// Store data to reproduce frame for sending
|
||||
decodedIRData.numberOfBits = tNumberOfBits;
|
||||
decodedIRData.extra = (decodedIRData.rawDataPtr->rawbuf[1] << 8) | decodedIRData.rawDataPtr->rawbuf[2];
|
||||
decodedIRData.address = (tMarkTicksShort << 8) | tSpaceTicksLong;
|
||||
decodedIRData.command = (tMarkTicksShort << 8) | tSpaceTicksShort;
|
||||
|
||||
/*
|
||||
* Print characteristics of this protocol. Durations are in ticks.
|
||||
* Number of bits, start bit, start pause, short mark, long mark, short space, long space
|
||||
|
@ -227,51 +234,79 @@ bool IRrecv::decodeDistance() {
|
|||
* Sony: 12|15|20, 48, 12, 12, 24, 12, 0 // the only known pulse width protocol
|
||||
*/
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Protocol constants for a " STR(MICROS_PER_TICK) " us tick: "));
|
||||
Serial.print(decodedIRData.numberOfBits);
|
||||
Serial.print(F(" bits, "));
|
||||
Serial.print(decodedIRData.rawDataPtr->rawbuf[1]);
|
||||
Serial.print(F("ProtocolConstants: "));
|
||||
Serial.print(decodedIRData.rawDataPtr->rawbuf[1] * MICROS_PER_TICK);
|
||||
Serial.print(F(", "));
|
||||
Serial.print(decodedIRData.rawDataPtr->rawbuf[2]);
|
||||
Serial.print(decodedIRData.rawDataPtr->rawbuf[2] * MICROS_PER_TICK);
|
||||
Serial.print(F(", "));
|
||||
Serial.print(tMarkTicksLong);
|
||||
Serial.print(tMarkTicksShort * MICROS_PER_TICK);
|
||||
Serial.print(F(", "));
|
||||
Serial.println(tSpaceTicksLong);
|
||||
Serial.print(tSpaceTicksLong * MICROS_PER_TICK);
|
||||
Serial.print(F(", "));
|
||||
Serial.print(tMarkTicksShort);
|
||||
if (tMarkTicksLong == 0) {
|
||||
Serial.print(tMarkTicksShort * MICROS_PER_TICK);
|
||||
} else {
|
||||
Serial.print(tMarkTicksLong * MICROS_PER_TICK);
|
||||
}
|
||||
Serial.print(F(", "));
|
||||
Serial.print(tSpaceTicksShort);
|
||||
Serial.print(tSpaceTicksShort * MICROS_PER_TICK);
|
||||
Serial.println();
|
||||
#endif
|
||||
uint8_t tStartIndex = 3;
|
||||
// skip leading start bit for decoding.
|
||||
uint16_t tNumberOfBits = (decodedIRData.rawDataPtr->rawlen / 2) - 1;
|
||||
if (tSpaceTicksLong > 0 && tMarkTicksLong == 0) {
|
||||
// For PULSE DISTANCE a stop bit is mandatory, for PULSE_DISTANCE_WIDTH it is not required!
|
||||
tNumberOfBits--; // Correct for stop bit
|
||||
}
|
||||
decodedIRData.numberOfBits = tNumberOfBits;
|
||||
uint8_t tNumberOfAdditionalLong = (tNumberOfBits - 1) / 32;
|
||||
|
||||
/*
|
||||
* decide, if we have an pulse width or distance protocol
|
||||
*/
|
||||
if (tSpaceTicksLong > 0) {
|
||||
/*
|
||||
* For PULSE DISTANCE a stop bit is mandatory!
|
||||
*/
|
||||
decodedIRData.protocol = PULSE_DISTANCE;
|
||||
|
||||
/*
|
||||
* Here short and long space duration found. Decode in 32 bit chunks.
|
||||
* Only the last chunk can contain less than 32 bits
|
||||
*/
|
||||
for (uint_fast8_t i = 0; i <= tNumberOfAdditionalLong; ++i) {
|
||||
uint8_t tNumberOfBitsForOneDecode = tNumberOfBits;
|
||||
if (tNumberOfBitsForOneDecode > 32) {
|
||||
tNumberOfBitsForOneDecode = 32;
|
||||
}
|
||||
if (!decodePulseDistanceData(tNumberOfBitsForOneDecode, tStartIndex, tMarkTicksShort * MICROS_PER_TICK,
|
||||
tSpaceTicksLong * MICROS_PER_TICK, tSpaceTicksShort * MICROS_PER_TICK,
|
||||
bool tResult;
|
||||
if (tMarkTicksLong > 0) {
|
||||
decodedIRData.protocol = PULSE_DISTANCE_WIDTH;
|
||||
/*
|
||||
* Here we have 2 space and 2 mark durations like MagiQuest
|
||||
* The longer mark is mostly the mark of the coded 1
|
||||
*/
|
||||
tResult = decodeDistanceWidthData(tNumberOfBitsForOneDecode, tStartIndex, tMarkTicksLong * MICROS_PER_TICK,
|
||||
(tMarkTicksLong + tSpaceTicksShort) * MICROS_PER_TICK,
|
||||
#if defined(DISTANCE_DO_MSB_DECODING)
|
||||
true
|
||||
true
|
||||
#else
|
||||
false
|
||||
false
|
||||
#endif
|
||||
);
|
||||
|
||||
} else {
|
||||
decodedIRData.protocol = PULSE_DISTANCE;
|
||||
tResult = decodePulseDistanceData(tNumberOfBitsForOneDecode, tStartIndex, tMarkTicksShort * MICROS_PER_TICK,
|
||||
tSpaceTicksLong * MICROS_PER_TICK, tSpaceTicksShort * MICROS_PER_TICK,
|
||||
#if defined(DISTANCE_DO_MSB_DECODING)
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
);
|
||||
}
|
||||
if (!tResult) {
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(decodedIRData.protocol);
|
||||
Serial.println(F(": Decode failed"));
|
||||
#endif
|
||||
)) {
|
||||
IR_DEBUG_PRINT(F("PULSE_DISTANCE: "));
|
||||
IR_DEBUG_PRINTLN(F("Decode failed"));
|
||||
return false;
|
||||
} else {
|
||||
// fill array with decoded data
|
||||
|
@ -281,11 +316,12 @@ bool IRrecv::decodeDistance() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
if (tMarkTicksLong == 0) {
|
||||
IR_DEBUG_PRINT(F("PULSE_DISTANCE: "));
|
||||
IR_DEBUG_PRINTLN(F("Only 1 distinct duration value for each space and mark found"));
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("PULSE_DISTANCE: "));
|
||||
Serial.println(F("Only 1 distinct duration value for each space and mark found"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -304,9 +340,11 @@ bool IRrecv::decodeDistance() {
|
|||
tNumberOfBitsForOneDecode = 32;
|
||||
}
|
||||
if (!decodePulseWidthData(tNumberOfBitsForOneDecode, tStartIndex, tMarkTicksLong * MICROS_PER_TICK,
|
||||
tMarkTicksShort * MICROS_PER_TICK, tSpaceTicksShort * MICROS_PER_TICK, DISTANCE_DO_MSB_DECODING)) {
|
||||
IR_DEBUG_PRINT(F("PULSE_WIDTH: "));
|
||||
IR_DEBUG_PRINTLN(F("Decode failed"));
|
||||
tMarkTicksShort * MICROS_PER_TICK, tSpaceTicksShort * MICROS_PER_TICK, DISTANCE_DO_MSB_DECODING)) {
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("PULSE_WIDTH: "));
|
||||
Serial.println(F("Decode failed"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
tStartIndex += 64;
|
||||
|
@ -320,13 +358,24 @@ bool IRrecv::decodeDistance() {
|
|||
}
|
||||
|
||||
#if defined(DISTANCE_DO_MSB_DECODING)
|
||||
decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST | IRDATA_FLAGS_EXTRA_INFO;
|
||||
decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST | IRDATA_FLAGS_EXTRA_INFO;
|
||||
#else
|
||||
decodedIRData.flags = IRDATA_FLAGS_EXTRA_INFO;
|
||||
decodedIRData.flags = IRDATA_FLAGS_EXTRA_INFO;
|
||||
#endif
|
||||
// Store data to reproduce frame for sending
|
||||
decodedIRData.extra = (decodedIRData.rawDataPtr->rawbuf[1] << 8) | decodedIRData.rawDataPtr->rawbuf[2];
|
||||
if (tMarkTicksLong == 0) {
|
||||
decodedIRData.address = (tMarkTicksShort << 8) | tSpaceTicksLong;
|
||||
} else {
|
||||
decodedIRData.address = (tMarkTicksLong << 8) | tSpaceTicksLong;
|
||||
}
|
||||
decodedIRData.command = (tMarkTicksShort << 8) | tSpaceTicksShort;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
#endif // _IR_DISTANCE_HPP
|
||||
#if defined(LOCAL_DEBUG)
|
||||
#undef LOCAL_DEBUG
|
||||
#endif
|
||||
#endif // _IR_DISTANCE_WIDTH_HPP
|
|
@ -32,6 +32,12 @@
|
|||
#ifndef _IR_KASEIKYO_HPP
|
||||
#define _IR_KASEIKYO_HPP
|
||||
|
||||
#if defined(DEBUG) && !defined(LOCAL_DEBUG)
|
||||
#define LOCAL_DEBUG
|
||||
#else
|
||||
//#define LOCAL_DEBUG // This enables debug output only for this file
|
||||
#endif
|
||||
|
||||
/** \addtogroup Decoder Decoders and encoders for different protocols
|
||||
* @{
|
||||
*/
|
||||
|
@ -66,7 +72,7 @@
|
|||
#define KASEIKYO_ADDRESS_BITS 12
|
||||
#define KASEIKYO_COMMAND_BITS 8
|
||||
#define KASEIKYO_PARITY_BITS 8
|
||||
#define KASEIKYO_BITS (KASEIKYO_VENDOR_ID_BITS + KASEIKYO_VENDOR_ID_PARITY_BITS + KASEIKYO_ADDRESS_BITS + KASEIKYO_COMMAND_BITS + KASEIKYO_PARITY_BITS)
|
||||
#define KASEIKYO_BITS (KASEIKYO_VENDOR_ID_BITS + KASEIKYO_VENDOR_ID_PARITY_BITS + KASEIKYO_ADDRESS_BITS + KASEIKYO_COMMAND_BITS + KASEIKYO_PARITY_BITS) // 48
|
||||
#define KASEIKYO_UNIT 432 // 16 pulses of 37 kHz (432,432432) - Pronto 0x70 | 0x10
|
||||
|
||||
#define KASEIKYO_HEADER_MARK (8 * KASEIKYO_UNIT) // 3456
|
||||
|
@ -160,7 +166,7 @@ void IRsend::sendKaseikyo_JVC(uint16_t aAddress, uint8_t aCommand, int_fast8_t a
|
|||
bool IRrecv::decodeKaseikyo() {
|
||||
|
||||
decode_type_t tProtocol;
|
||||
// Check we have enough data (100)- +4 for initial gap, start bit mark and space + stop bit mark
|
||||
// Check we have enough data (96 + 4) 4 for initial gap, start bit mark and space + stop bit mark
|
||||
if (decodedIRData.rawDataPtr->rawlen != ((2 * KASEIKYO_BITS) + 4)) {
|
||||
IR_DEBUG_PRINT(F("Kaseikyo: "));
|
||||
IR_DEBUG_PRINT(F("Data length="));
|
||||
|
@ -175,8 +181,10 @@ bool IRrecv::decodeKaseikyo() {
|
|||
|
||||
// decode first 16 Vendor ID bits
|
||||
if (!decodePulseDistanceData(&KaseikyoProtocolConstants, KASEIKYO_VENDOR_ID_BITS)) {
|
||||
IR_DEBUG_PRINT(F("Kaseikyo: "));
|
||||
IR_DEBUG_PRINTLN(F("Vendor ID decode failed"));
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Kaseikyo: "));
|
||||
Serial.println(F("Vendor ID decode failed"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -205,8 +213,10 @@ bool IRrecv::decodeKaseikyo() {
|
|||
if (!decodePulseDistanceData(&KaseikyoProtocolConstants,
|
||||
KASEIKYO_VENDOR_ID_PARITY_BITS + KASEIKYO_ADDRESS_BITS + KASEIKYO_COMMAND_BITS + KASEIKYO_PARITY_BITS,
|
||||
3 + (2 * KASEIKYO_VENDOR_ID_BITS))) {
|
||||
IR_DEBUG_PRINT(F("Kaseikyo: "));
|
||||
IR_DEBUG_PRINTLN(F("VendorID parity, address, command + parity decode failed"));
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Kaseikyo: "));
|
||||
Serial.println(F("VendorID parity, address, command + parity decode failed"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -221,13 +231,15 @@ bool IRrecv::decodeKaseikyo() {
|
|||
if (tVendorParity != (tValue.UByte.LowByte & 0xF)) {
|
||||
decodedIRData.flags = IRDATA_FLAGS_PARITY_FAILED | IRDATA_FLAGS_IS_LSB_FIRST;
|
||||
|
||||
IR_DEBUG_PRINT(F("Kaseikyo: "));
|
||||
IR_DEBUG_PRINT(F("4 bit VendorID parity is not correct. expected=0x"));
|
||||
IR_DEBUG_PRINT(tVendorParity, HEX);
|
||||
IR_DEBUG_PRINT(F(" received=0x"));
|
||||
IR_DEBUG_PRINT(decodedIRData.decodedRawData, HEX);
|
||||
IR_DEBUG_PRINT(F(" VendorID=0x"));
|
||||
IR_DEBUG_PRINTLN(tVendorId, HEX);
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Kaseikyo: "));
|
||||
Serial.print(F("4 bit VendorID parity is not correct. expected=0x"));
|
||||
Serial.print(tVendorParity, HEX);
|
||||
Serial.print(F(" received=0x"));
|
||||
Serial.print(decodedIRData.decodedRawData, HEX);
|
||||
Serial.print(F(" VendorID=0x"));
|
||||
Serial.println(tVendorId, HEX);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (tProtocol == KASEIKYO) {
|
||||
|
@ -238,15 +250,17 @@ bool IRrecv::decodeKaseikyo() {
|
|||
if (tValue.UByte.HighByte != tParity) {
|
||||
decodedIRData.flags |= IRDATA_FLAGS_PARITY_FAILED;
|
||||
|
||||
IR_DEBUG_PRINT(F("Kaseikyo: "));
|
||||
IR_DEBUG_PRINT(F("8 bit Parity is not correct. expected=0x"));
|
||||
IR_DEBUG_PRINT(tParity, HEX);
|
||||
IR_DEBUG_PRINT(F(" received=0x"));
|
||||
IR_DEBUG_PRINT(decodedIRData.decodedRawData >> KASEIKYO_COMMAND_BITS, HEX);
|
||||
IR_DEBUG_PRINT(F(" address=0x"));
|
||||
IR_DEBUG_PRINT(decodedIRData.address, HEX);
|
||||
IR_DEBUG_PRINT(F(" command=0x"));
|
||||
IR_DEBUG_PRINTLN(decodedIRData.command, HEX);
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Kaseikyo: "));
|
||||
Serial.print(F("8 bit Parity is not correct. expected=0x"));
|
||||
Serial.print(tParity, HEX);
|
||||
Serial.print(F(" received=0x"));
|
||||
Serial.print(decodedIRData.decodedRawData >> KASEIKYO_COMMAND_BITS, HEX);
|
||||
Serial.print(F(" address=0x"));
|
||||
Serial.print(decodedIRData.address, HEX);
|
||||
Serial.print(F(" command=0x"));
|
||||
Serial.println(decodedIRData.command, HEX);
|
||||
#endif
|
||||
}
|
||||
|
||||
decodedIRData.numberOfBits = KASEIKYO_BITS;
|
||||
|
@ -265,4 +279,7 @@ bool IRrecv::decodeKaseikyo() {
|
|||
*/
|
||||
|
||||
/** @}*/
|
||||
#if defined(LOCAL_DEBUG)
|
||||
#undef LOCAL_DEBUG
|
||||
#endif
|
||||
#endif // _IR_KASEIKYO_HPP
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
+ 500,- 650 + 500,- 650 + 500,- 650 + 200,- 900 // Checksum (+ sum of the 5 bytes before == 0)
|
||||
+ 250,- 850 + 500,- 650 + 300,- 800 + 500
|
||||
*/
|
||||
// MSB first, 8 start bits (zero), 31 wand id bits, 9 magnitude bits 8 checksum bits and no stop bit
|
||||
// MSB first, 8 start bits (zero), 31 wand id bits, 9 magnitude bits 8 checksum bits and no stop bit => 56 bits
|
||||
#if !defined (DOXYGEN)
|
||||
// MagiQuest packet is both Wand ID and magnitude of swish and flick
|
||||
union magiquest_t {
|
||||
|
@ -118,23 +118,33 @@ MAGIQUEST_ONE_MARK, MAGIQUEST_ONE_SPACE, MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPA
|
|||
NULL };
|
||||
//+=============================================================================
|
||||
//
|
||||
/**
|
||||
* @param aWandId 31 bit ID
|
||||
* @param aMagnitude 9 bit Magnitude
|
||||
*/
|
||||
void IRsend::sendMagiQuest(uint32_t aWandId, uint16_t aMagnitude) {
|
||||
|
||||
// Set IR carrier frequency
|
||||
enableIROut(38);
|
||||
|
||||
// 8 start bits
|
||||
sendPulseDistanceWidthData(&MagiQuestProtocolConstants, 0, 8);
|
||||
aMagnitude &= 0x1FF; // we have 9 bit
|
||||
LongUnion tWandId;
|
||||
tWandId.ULong = aWandId << 1;
|
||||
uint8_t tChecksum = (tWandId.Bytes[0]) + tWandId.Bytes[1] + tWandId.Bytes[2] + tWandId.Bytes[3];
|
||||
tChecksum += aMagnitude + (aMagnitude >> 8);
|
||||
tChecksum = ~tChecksum + 1;
|
||||
// Data
|
||||
sendPulseDistanceWidthData(&MagiQuestProtocolConstants, aWandId, MAGIQUEST_WAND_ID_BITS);
|
||||
|
||||
// 8 start bits
|
||||
sendPulseDistanceWidthData(&MagiQuestProtocolConstants, 0, 8);
|
||||
// 48 bit data
|
||||
sendPulseDistanceWidthData(&MagiQuestProtocolConstants, aWandId, MAGIQUEST_WAND_ID_BITS); // send only 31 bit, do not send MSB here
|
||||
sendPulseDistanceWidthData(&MagiQuestProtocolConstants, aMagnitude, MAGIQUEST_MAGNITUDE_BITS);
|
||||
sendPulseDistanceWidthData(&MagiQuestProtocolConstants, tChecksum, MAGIQUEST_CHECKSUM_BITS);
|
||||
#if defined(LOCAL_DEBUG)
|
||||
// must be after sending, in order not to destroy the send timing
|
||||
Serial.print(F("MagiQuest checksum=0x"));
|
||||
Serial.println(tChecksum, HEX);
|
||||
#endif
|
||||
IrReceiver.restartAfterSend();
|
||||
}
|
||||
|
||||
|
@ -142,17 +152,20 @@ void IRsend::sendMagiQuest(uint32_t aWandId, uint16_t aMagnitude) {
|
|||
//
|
||||
/*
|
||||
* decodes a 56 bit result, which is not really compatible with standard decoder layout
|
||||
* magnitude is stored in Command
|
||||
* magnitude is stored in command
|
||||
* 31 bit wand_id is stored in decodedRawData
|
||||
* lower 16 bit of wand_id is stored in address
|
||||
*/
|
||||
bool IRrecv::decodeMagiQuest() {
|
||||
magiquest_t data; // Somewhere to build our code
|
||||
|
||||
unsigned int tMark;
|
||||
unsigned int tSpace;
|
||||
unsigned int tMarkTicks;
|
||||
unsigned int tSpaceTicks;
|
||||
|
||||
#if defined(LOCAL_DEBUG)
|
||||
char bitstring[(MAGIQUEST_BITS + 1)];
|
||||
bitstring[MAGIQUEST_BITS] = '\0';
|
||||
char tDebugBitstring[(MAGIQUEST_BITS + 1)];
|
||||
tDebugBitstring[MAGIQUEST_BITS] = '\0';
|
||||
char * tDebugBitstringPtr = tDebugBitstring;
|
||||
#endif
|
||||
|
||||
// Check we have the right amount of data, magnitude and ID bits and 8 start bits + 0 stop bit
|
||||
|
@ -164,50 +177,49 @@ bool IRrecv::decodeMagiQuest() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Decode each bit
|
||||
// Decode the 56 bits in one loop using uint64
|
||||
data.llword = 0;
|
||||
uint_fast8_t tIndex = 1; // Skip the gap between frames
|
||||
unsigned int *tRawBufPointer = &decodedIRData.rawDataPtr->rawbuf[1];
|
||||
for (uint_fast8_t i = 0; i < MAGIQUEST_BITS; i++) {
|
||||
// get one mark and space pair
|
||||
tMark = decodedIRData.rawDataPtr->rawbuf[tIndex++];
|
||||
tSpace = decodedIRData.rawDataPtr->rawbuf[tIndex++]; // buffer overflow for last bit, but we do not evaluate this value :-)
|
||||
tMarkTicks = *tRawBufPointer++;;
|
||||
tSpaceTicks = *tRawBufPointer++;; // buffer overflow for last bit, but we do not evaluate this value :-)
|
||||
|
||||
IR_TRACE_PRINT(F("MagiQuest: mark="));
|
||||
IR_TRACE_PRINT(tMark * MICROS_PER_TICK);
|
||||
IR_TRACE_PRINT(tMarkTicks * MICROS_PER_TICK);
|
||||
IR_TRACE_PRINT(F(" space="));
|
||||
IR_TRACE_PRINTLN(tSpace * MICROS_PER_TICK);
|
||||
IR_TRACE_PRINTLN(tSpaceTicks * MICROS_PER_TICK);
|
||||
|
||||
// We have no stop bit, so assume that last space, which is not recorded, is correct, since we can not check it
|
||||
if (i == (MAGIQUEST_BITS - 1) || matchMark(tMark + tSpace, MAGIQUEST_PERIOD)) {
|
||||
if (!matchMark(tMark, MAGIQUEST_ONE_MARK)) {
|
||||
if (i == (MAGIQUEST_BITS - 1) || matchMark(tMarkTicks + tSpaceTicks, MAGIQUEST_PERIOD)) {
|
||||
if (!matchMark(tMarkTicks, MAGIQUEST_ONE_MARK)) {
|
||||
// It's a 0
|
||||
data.llword <<= 1;
|
||||
#if defined(LOCAL_DEBUG)
|
||||
bitstring[(tIndex / 2) - 1] = '0';
|
||||
*tDebugBitstringPtr++ = '0';
|
||||
#endif
|
||||
} else {
|
||||
// It's a 1
|
||||
data.llword = (data.llword << 1) | 1;
|
||||
#if defined(LOCAL_DEBUG)
|
||||
bitstring[(tIndex / 2) - 1] = '1';
|
||||
*tDebugBitstringPtr++ = '1';
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Mark and space does not match the constant MagiQuest period. Index="));
|
||||
Serial.println(i);
|
||||
// Serial.println(tIndex - 2);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.println(bitstring);
|
||||
Serial.println(tDebugBitstring);
|
||||
#endif
|
||||
|
||||
// Success
|
||||
decodedIRData.protocol = MAGIQUEST;
|
||||
decodedIRData.numberOfBits = tIndex / 2;
|
||||
decodedIRData.numberOfBits = MAGIQUEST_BITS;
|
||||
decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST;
|
||||
|
||||
LongUnion tWandId;
|
||||
|
@ -217,8 +229,8 @@ bool IRrecv::decodeMagiQuest() {
|
|||
if (tChecksum != 0) {
|
||||
decodedIRData.flags |= IRDATA_FLAGS_PARITY_FAILED;
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Checksum "));
|
||||
Serial.print(tChecksum);
|
||||
Serial.print(F("Checksum 0x"));
|
||||
Serial.print(tChecksum, HEX);
|
||||
Serial.println(F(" is not 0"));
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ uint8_t sLastSendToggleValue = 1; // To start first command with toggle 0
|
|||
************************************/
|
||||
|
||||
/**
|
||||
* @param aCommand If aCommand is >=64 then we switch automatically to RC5X
|
||||
* @param aCommand If aCommand is >=0x40 then we switch automatically to RC5X
|
||||
*/
|
||||
void IRsend::sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle) {
|
||||
// Set IR carrier frequency
|
||||
|
@ -82,7 +82,7 @@ void IRsend::sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRe
|
|||
uint16_t tIRData = ((aAddress & 0x1F) << RC5_COMMAND_BITS);
|
||||
|
||||
if (aCommand < 0x40) {
|
||||
// auto discovery of RC5, set field bit to 1
|
||||
// Auto discovery of RC5X, set field bit to 1
|
||||
tIRData |= 1 << (RC5_TOGGLE_BIT + RC5_ADDRESS_BITS + RC5_COMMAND_BITS);
|
||||
} else {
|
||||
// Mask bit 7 of command and let field bit 0
|
||||
|
|
|
@ -92,7 +92,7 @@ SONY_SPACE, SONY_ZERO_MARK, SONY_SPACE, PROTOCOL_IS_LSB_FIRST, SEND_NO_STOP_BIT,
|
|||
* @param numberOfBits should be one of SIRCS_12_PROTOCOL, SIRCS_15_PROTOCOL, SIRCS_20_PROTOCOL. Not checked! 20 -> send 13 address bits
|
||||
*/
|
||||
void IRsend::sendSony(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint8_t numberOfBits) {
|
||||
uint32_t tData = (uint32_t) aAddress << 7 | aCommand;
|
||||
uint32_t tData = (uint32_t) aAddress << 7 | (aCommand & 0x7F);
|
||||
// send 5, 8, 13 address bits LSB first
|
||||
sendPulseDistanceWidth(&SonyProtocolConstants, tData, numberOfBits, aNumberOfRepeats);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue