Skip to content

Commit 65ab27e

Browse files
committed
Extended DEBUG output
1 parent d06e806 commit 65ab27e

File tree

13 files changed

+67
-42
lines changed

13 files changed

+67
-42
lines changed

README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ The new decoders for **NEC, Panasonic, Sony, Samsung and JVC** `IrReceiver.decod
9595
If you read the first binary sequence backwards (right to left), you get the second sequence.
9696

9797
# FAQ
98-
- IR does not work right when I use Neopixels (aka WS2811/WS2812/WS2812B) or other libraries blocking interrupts for a longer time (> 50 us).<br/>
98+
- IR does not work right when I use **Neopixels** (aka WS2811/WS2812/WS2812B) or other libraries blocking interrupts for a longer time (> 50 us).<br/>
9999
Whether you use the Adafruit Neopixel lib, or FastLED, interrupts get disabled on many lower end CPUs like the basic Arduinos for longer than 50 µs.
100100
In turn, this stops the IR interrupt handler from running when it needs to. There are some solutions to this on some processors,
101101
[see this page from Marc MERLIN](http://marc.merlins.org/perso/arduino/post_2017-04-03_Arduino-328P-Uno-Teensy3_1-ESP8266-ESP32-IR-and-Neopixels.html)
@@ -105,6 +105,7 @@ If you can live with the NEC protocol, you can try the MinimalReceiver example,
105105
- You can use **multiple IR receiver** by just connecting the output pins of several IR receivers together.
106106
The IR receivers use an NPN transistor as output device with just a 30k resistor to VCC.
107107
This is almost "open collector" and allows connecting of several output pins to one Arduino input pin.
108+
- The **minimal CPU frequency** for receiving is 4 MHz, since the 50 us timer ISR takes around 12 us on a 16 MHz ATmega.
108109

109110
# Minimal version
110111
For applications only requiring NEC protocol, there is a receiver which has very **small codesize of 500 bytes and does NOT require any timer**. See the MinimalReceiver and IRDispatcherDemo example how to use it. Mapping of pins to interrupts can be found [here](https://github.com/Arduino-IRremote/Arduino-IRremote/tree/master/src/TinyIRReceiver.cpp.h#L307).
@@ -115,7 +116,14 @@ This library was never designed to handle long codes like the ones used by air c
115116
See [Recording long Infrared Remote control signals with Arduino](https://www.analysir.com/blog/2014/03/19/air-conditioners-problems-recording-long-infrared-remote-control-signals-arduino).<br/>
116117
The main reason is, that it was designed to fit inside MCUs with relatively low levels of resources and was intended to work as a library together with other applications which also require some resources of the MCU to operate.
117118

118-
## Hints
119+
## Protocol=UNKNOWN
120+
If you see something like `Protocol=UNKNOWN Hash=0x13BD886C 35 bits received` as output of e.g. the ReceiveDemo example, you either have a problem with decoding a protocol, or an unsupported protocol.
121+
122+
- If you have an **odd number of bits** received, it is likely, that your receiver circuit has problems. Maybe because the IR signal is too weak.
123+
- If you see timings like `+ 600,- 600 + 550,- 150 + 200,- 100 + 750,- 550` then one 450 µs space was split into two 150 and 100 µs spaces with a spike / error signal of 200 µs between. Maybe because of a defective receiver or a weak signal in conjunction with another light emitting source nearby.
124+
- To see more info supporting you to find the reason for your UNKNOWN protocol, you must enable the line `//#define DEBUG` in IRremoteInt.h.
125+
126+
## How to deal with protocols not supported by IRremote
119127
If you do not know which protocol your IR transmitter uses, you have several choices.
120128
- Use the [IRreceiveDump example](examples/ReceiveDump) to dump out the IR timing.
121129
You can then reproduce/send this timing with the [SendRawDemo example](examples/SendRawDemo).
@@ -127,11 +135,12 @@ If you do not know which protocol your IR transmitter uses, you have several cho
127135
- Use [IrScrutinizer](http://www.harctoolbox.org/IrScrutinizer.html).
128136
It can automatically generate a send sketch for your protocol by exporting as "Arduino Raw". It supports IRremote,
129137
the old [IRLib](https://github.com/cyborg5/IRLib) and [Infrared4Arduino](https://github.com/bengtmartensson/Infrared4Arduino).
138+
139+
# Hints
130140
- To **increase strength of sent output signal** you can increase the current through the send diode, and/or use 2 diodes in series,
131141
since one IR diode requires only 1.5 volt.
132142
- The line \#include "ATtinySerialOut.h" in PinDefinitionsAndMore.h (requires the library to be installed) saves 370 bytes program space and 38 bytes RAM for **Digispark boards** as well as enables serial output at 8MHz.
133143
- The default software generated PWM has **problems on ATtinies running with 8 MHz**. The PWM frequency is around 30 instead of 38 kHz and RC6 is not reliable. You can switch to timer PWM generation by `#define SEND_PWM_BY_TIMER`.
134-
- Minimal CPU frequency for receiving is 4 MHz, since the 50 us timer ISR takes around 12 us on a 16 MHz ATmega.
135144

136145
# Examples
137146
In order to fit the examples to the 8K flash of ATtiny85 and ATtiny88, the [Arduino library ATtinySerialOut](https://github.com/ArminJo/ATtinySerialOut) is required for this CPU's.
@@ -143,7 +152,7 @@ This examples are a good starting point.
143152
More complete examples for the advanced user.
144153

145154
### UnitTest
146-
ReceiveDemo + SendDemo in one program. Receiving while sending.
155+
ReceiveDemo + SendDemo in one program. **Receiving while sending**.
147156

148157
### ReceiveAndSend
149158
Record and play back last received IR signal at button press.

examples/ReceiveDemo/ReceiveDemo.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ void loop() {
121121
* and up to 32 bit raw data in IrReceiver.decodedIRData.decodedRawData
122122
*/
123123
if (IrReceiver.decode()) {
124+
Serial.println();
124125
#if FLASHEND <= 0x1FFF // For less equal than 8k flash, like ATtiny85
125126
// Print a minimal summary of received data
126127
IrReceiver.printIRResultMinimal(&Serial);
@@ -158,7 +159,6 @@ void loop() {
158159
# endif
159160
#endif // FLASHEND > 0x1FFF
160161

161-
Serial.println();
162162
/*
163163
* !!!Important!!! Enable receiving of the next value,
164164
* since receiving has stopped after the end of the current received data packet.

examples/SendDemo/SendDemo.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void setup() {
5959
#if defined(ARDUINO_ARCH_STM32) || defined(ESP8266)
6060
Serial.println(IR_SEND_PIN_STRING);
6161
#else
62-
Serial.print(IR_SEND_PIN);
62+
Serial.println(IR_SEND_PIN);
6363
#endif
6464

6565
#if !defined(SEND_PWM_BY_TIMER) && !defined(USE_NO_SEND_PWM) && !defined(ESP32) // for esp32 we use PWM generation by ledcWrite() for each pin

examples/UnitTest/UnitTest.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ void setup() {
110110
#if defined(ARDUINO_ARCH_STM32) || defined(ESP8266)
111111
Serial.println(IR_SEND_PIN_STRING);
112112
#else
113-
Serial.print(IR_SEND_PIN);
113+
Serial.println(IR_SEND_PIN);
114114
#endif
115115

116116
#if FLASHEND > 0x1FFF && !defined(SEND_PWM_BY_TIMER) && !defined(USE_NO_SEND_PWM) && !defined(ESP32) // for esp32 we use PWM generation by ledcWrite() for each pin

src/ir_Denon.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ bool IRrecv::decodeDenon() {
135135
// we have no start bit, so check for the exact amount of data bits
136136
// Check we have the right amount of data (32). The + 2 is for initial gap + stop bit mark
137137
if (decodedIRData.rawDataPtr->rawlen != (2 * DENON_BITS) + 2) {
138+
DBG_PRINT(F("Denon: "));
139+
DBG_PRINT("Data length=");
140+
DBG_PRINT(decodedIRData.rawDataPtr->rawlen);
141+
DBG_PRINTLN(" is not 32");
138142
return false;
139143
}
140144

src/ir_JVC.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,12 @@ void IRsend::sendJVC(uint8_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfR
100100
*/
101101
bool IRrecv::decodeJVC() {
102102

103-
// Check we have the right amount of data (36 or 34). The +4 is for initial gap, start bit mark and space + stop bit mark.
103+
// Check we have the right amount of data (36 or 34). The +4 is for initial gap, start bit mark and space + stop bit mark. +2 is for repeats
104104
if (decodedIRData.rawDataPtr->rawlen != ((2 * JVC_BITS) + 4) && decodedIRData.rawDataPtr->rawlen != ((2 * JVC_BITS) + 2)) {
105-
// no debug output, since this check is mainly to determine the received protocol
105+
DBG_PRINT(F("JVC: "));
106+
DBG_PRINT("Data length=");
107+
DBG_PRINT(decodedIRData.rawDataPtr->rawlen);
108+
DBG_PRINTLN(" is not 34 or 36");
106109
return false;
107110
}
108111

@@ -127,8 +130,8 @@ bool IRrecv::decodeJVC() {
127130
// Check header "mark" and "space"
128131
if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], JVC_HEADER_MARK)
129132
|| !matchSpace(decodedIRData.rawDataPtr->rawbuf[2], JVC_HEADER_SPACE)) {
130-
// DBG_PRINT("JVC: ");
131-
// DBG_PRINTLN("Header mark or space length is wrong");
133+
DBG_PRINT("JVC: ");
134+
DBG_PRINTLN("Header mark or space length is wrong");
132135
return false;
133136
}
134137

src/ir_Kaseikyo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ bool IRrecv::decodeKaseikyo() {
138138
decode_type_t tProtocol;
139139
// Check we have enough data (100)- +4 for initial gap, start bit mark and space + stop bit mark
140140
if (decodedIRData.rawDataPtr->rawlen != ((2 * KASEIKYO_BITS) + 4)) {
141+
DBG_PRINT(F("Kaseikyo: "));
142+
DBG_PRINT("Data length=");
143+
DBG_PRINT(decodedIRData.rawDataPtr->rawlen);
144+
DBG_PRINTLN(" is not 100");
141145
return false;
142146
}
143147

src/ir_LG.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ bool IRrecv::decodeLG() {
146146

147147
// Check we have the right amount of data (60). The +4 is for initial gap, start bit mark and space + stop bit mark.
148148
if (decodedIRData.rawDataPtr->rawlen != ((2 * LG_BITS) + 4) && (decodedIRData.rawDataPtr->rawlen != 4)) {
149-
// no debug output, since this check is mainly to determine the received protocol
149+
DBG_PRINT(F("LG: "));
150+
DBG_PRINT("Data length=");
151+
DBG_PRINT(decodedIRData.rawDataPtr->rawlen);
152+
DBG_PRINTLN(" is not 60 or 4");
150153
return false;
151154
}
152155

src/ir_NEC.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,10 @@ bool IRrecv::decodeNEC() {
190190

191191
// Check we have the right amount of data (68). The +4 is for initial gap, start bit mark and space + stop bit mark.
192192
if (decodedIRData.rawDataPtr->rawlen != ((2 * NEC_BITS) + 4) && (decodedIRData.rawDataPtr->rawlen != 4)) {
193-
// no debug output, since this check is mainly to determine the received protocol
193+
DBG_PRINT(F("NEC: "));
194+
DBG_PRINT("Data length=");
195+
DBG_PRINT(decodedIRData.rawDataPtr->rawlen);
196+
DBG_PRINTLN(" is not 68 or 4");
194197
return false;
195198
}
196199

src/ir_RC5_RC6.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,17 @@ bool IRrecv::decodeRC5() {
136136
// Check we have the right amount of data (11 to 26). The +2 is for initial gap and start bit mark.
137137
if (decodedIRData.rawDataPtr->rawlen < MIN_RC5_MARKS + 2 && decodedIRData.rawDataPtr->rawlen > ((2 * RC5_BITS) + 2)) {
138138
// no debug output, since this check is mainly to determine the received protocol
139-
TRACE_PRINT(F("RC5: "));
140-
TRACE_PRINT("Data length=");
141-
TRACE_PRINT(decodedIRData.rawDataPtr->rawlen);
142-
TRACE_PRINTLN(" is not between 11 and 26");
139+
DBG_PRINT(F("RC5: "));
140+
DBG_PRINT("Data length=");
141+
DBG_PRINT(decodedIRData.rawDataPtr->rawlen);
142+
DBG_PRINTLN(" is not between 11 and 26");
143143
return false;
144144
}
145145

146146
// Check start bit, the first space is included in the gap
147147
if (getBiphaselevel() != MARK) {
148-
TRACE_PRINT(F("RC5: "));
149-
TRACE_PRINTLN("first getBiphaselevel() is not MARK");
148+
DBG_PRINT(F("RC5: "));
149+
DBG_PRINTLN("first getBiphaselevel() is not MARK");
150150
return false;
151151
}
152152

@@ -165,8 +165,8 @@ bool IRrecv::decodeRC5() {
165165
tDecodedRawData = (tDecodedRawData << 1) | 0;
166166
} else {
167167
// TRACE_PRINT since I saw this too often
168-
TRACE_PRINT(F("RC5: "));
169-
TRACE_PRINTLN(F("Decode failed"));
168+
DBG_PRINT(F("RC5: "));
169+
DBG_PRINTLN(F("Decode failed"));
170170
return false;
171171
}
172172
}
@@ -349,16 +349,19 @@ bool IRrecv::decodeRC6() {
349349

350350
// Check we have the right amount of data (). The +3 for initial gap, start bit mark and space
351351
if (decodedIRData.rawDataPtr->rawlen < MIN_RC6_MARKS + 3 && decodedIRData.rawDataPtr->rawlen > ((2 * RC6_BITS) + 3)) {
352-
// no debug output, since this check is mainly to determine the received protocol
352+
DBG_PRINT(F("RC6: "));
353+
DBG_PRINT("Data length=");
354+
DBG_PRINT(decodedIRData.rawDataPtr->rawlen);
355+
DBG_PRINTLN(" is not between 15 and 45");
353356
return false;
354357
}
355358

356359
// Check header "mark" and "space", this must be done for repeat and data
357360
if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], RC6_HEADER_MARK)
358361
|| !matchSpace(decodedIRData.rawDataPtr->rawbuf[2], RC6_HEADER_SPACE)) {
359362
// no debug output, since this check is mainly to determine the received protocol
360-
TRACE_PRINT(F("RC6: "));
361-
TRACE_PRINTLN("Header mark or space length is wrong");
363+
DBG_PRINT(F("RC6: "));
364+
DBG_PRINTLN("Header mark or space length is wrong");
362365
return false;
363366
}
364367

@@ -367,13 +370,13 @@ bool IRrecv::decodeRC6() {
367370

368371
// Process first bit, which is known to be a 1 (mark->space)
369372
if (getBiphaselevel() != MARK) {
370-
TRACE_PRINT(F("RC6: "));
371-
TRACE_PRINTLN("first getBiphaselevel() is not MARK");
373+
DBG_PRINT(F("RC6: "));
374+
DBG_PRINTLN("first getBiphaselevel() is not MARK");
372375
return false;
373376
}
374377
if (getBiphaselevel() != SPACE) {
375-
TRACE_PRINT(F("RC6: "));
376-
TRACE_PRINTLN("second getBiphaselevel() is not SPACE");
378+
DBG_PRINT(F("RC6: "));
379+
DBG_PRINTLN("second getBiphaselevel() is not SPACE");
377380
return false;
378381
}
379382

0 commit comments

Comments
 (0)