8000 Added panasonic and JVC protocol · Chelland/Arduino-IRremote@753e52e · GitHub
[go: up one dir, main page]

Skip to content

Commit 753e52e

Browse files
committed
Added panasonic and JVC protocol
Most work already done by zenwheel, but the sendPanasonic command didn't work. Sending and decoding is confirmed to work with using both the JVC and Panasonic protocol. The library has also been updated to work with Arduino IDE 1.0.
1 parent fb741e9 commit 753e52e

File tree

11 files changed

+220
-6
lines changed

11 files changed

+220
-6
lines changed

IRremote.cpp

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* Interrupt code based on NECIRrcv by Joe Knapp
1010
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
1111
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
12+
*
13+
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
1214
*/
1315

1416
#include "IRremote.h"
@@ -167,7 +169,55 @@ void IRsend::sendRC6(unsigned long data, int nbits)
167169
}
168170
space(0); // Turn off at end
169171
}
170-
172+
void IRsend::sendPanasonic(unsigned int address, unsigned long data) {
173+
enableIROut(38);
174+
mark(PANASONIC_HDR_MARK);
175+
space(PANASONIC_HDR_SPACE);
176+
177+
for(int i=0;i<16;i++)
178+
{
179+
mark(PANASONIC_BIT_MARK);
180+
if (address & 0x8000) {
181+
space(PANASONIC_ONE_SPACE);
182+
} else {
183+
space(PANASONIC_ZERO_SPACE);
184+
}
185+
address <<= 1;
186+
}
187+
for (int i=0; i < 32; i++) {
188+
mark(PANASONIC_BIT_MARK);
189+
if (data & TOPBIT) {
190+
space(PANASONIC_ONE_SPACE);
191+
} else {
192+
space(PANASONIC_ZERO_SPACE);
193+
}
194+
data <<= 1;
195+
}
196+
mark(PANASONIC_BIT_MARK);
197+
space(0);
198+
}
199+
void IRsend::sendJVC(unsigned long data, int nbits, int repeat)
200+
{
201+
enableIROut(38);
202+
data = data << (32 - nbits);
203+
if (!repeat){
204+
mark(JVC_HDR_MARK);
205+
space(JVC_HDR_SPACE);
206+
}
207+
for (int i = 0; i < nbits; i++) {
208+
if (data & TOPBIT) {
209+
mark(JVC_BIT_MARK);
210+
space(JVC_ONE_SPACE);
211+
}
212+
else {
213+
mark(JVC_BIT_MARK);
214+
space(JVC_ZERO_SPACE);
215+
}
216+
data <<= 1;
217+
}
218+
mark(JVC_BIT_MARK);
219+
space(0);
220+
}
171221
void IRsend::mark(int time) {
172222
// Sends an IR mark for the specified number of microseconds.
173223
// The mark output is modulated at the PWM frequency.
@@ -362,6 +412,18 @@ int IRrecv::decode(decode_results *results) {
362412
if (decodeRC6(results)) {
363413
return DECODED;
364414
}
415+
#ifdef DEBUG
416+
Serial.println("Attempting Panasonic decode");
417+
#endif
418+
if (decodePanasonic(results)) {
419+
return DECODED;
420+
}
421+
#ifdef DEBUG
422+
Serial.println("Attempting JVC decode");
423+
#endif
424+
if (decodeJVC(results)) {
425+
return DECODED;
426+
}
365427
// decodeHash returns a hash on any input.
366428
// Thus, it needs to be last in the list.
367429
// If you add any decodes, add them before this.
@@ -592,6 +654,90 @@ long IRrecv::decodeRC6(decode_results *results) {
592654
results->decode_type = RC6;
593655
return DECODED;
594656
}
657+
long IRrecv::decodePanasonic(decode_results *results) {
658+
unsigned long long data = 0;
659+
int offset = 1;
660+
661+
if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_MARK)) {
662+
return ERR;
663+
}
664+
offset++;
665+
if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_SPACE)) {
666+
return ERR;
667+
}
668+
offset++;
669+
670+
// decode address
671+
for (int i = 0; i < PANASONIC_BITS; i++) {
672+
if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK)) {
673+
return ERR;
674+
}
675+
if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ONE_SPACE)) {
676+
data = (data << 1) | 1;
677+
} else if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ZERO_SPACE)) {
678+
data <<= 1;
679+
} else {
680+
return ERR;
681+
}
682+
offset++;
683+
}
684+
results->value = (unsigned long)data;
685+
results->panasonicAddress = (unsigned int)(data >> 32);
686+
results->decode_type = PANASONIC;
687+
results->bits = PANASONIC_BITS;
688+
return DECODED;
689+
}
690+
long IRrecv::decodeJVC(decode_results *results) {
691+
long data = 0;
692+
int offset = 1; // Skip first space
693+
// Check for repeat
694+
if (irparams.rawlen - 1 == 33 &&
695+
MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK) &&
696+
MATCH_MARK(results->rawbuf[irparams.rawlen-1], JVC_BIT_MARK)) {
697+
results->bits = 0;
698+
results->value = REPEAT;
699+
results->decode_type = JVC;
700+
return DECODED;
701+
}
702+
// Initial mark
703+
if (!MATCH_MARK(results->rawbuf[offset], JVC_HDR_MARK)) {
704+
return ERR;
705+
}
706+
offset++;
707+
if (irparams.rawlen < 2 * JVC_BITS + 1 ) {
708+
return ERR;
709+
}
710+
// Initial space
711+
if (!MATCH_SPACE(results->rawbuf[offset], JVC_HDR_SPACE)) {
712+
return ERR;
713+
}
714+
offset++;
715+
for (int i = 0; i < JVC_BITS; i++) {
716+
if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) {
717+
return ERR;
718+
}
719+
offset++;
720+
if (MATCH_SPACE(results->rawbuf[offset], JVC_ONE_SPACE)) {
721+
data = (data << 1) | 1;
722+
}
723+
else if (MATCH_SPACE(results->rawbuf[offset], JVC_ZERO_SPACE)) {
724+
data <<= 1;
725+
}
726+
else {
727+
return ERR;
728+
}
729+
offset++;
730+
}
731+
//Stop bit
732+
if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)){
733+
return ERR;
734+
}
735+
// Success
736+
results->bits = JVC_BITS;
737+
results->value = data;
738+
results->decode_type = JVC;
739+
return DECODED;
740+
}
595741

596742
/* -----------------------------------------------------------------------
597743
* hashdecode - decode an arbitrary IR code.

IRremote.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* Interrupt code based on NECIRrcv by Joe Knapp
88
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
99
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
10+
*
11+
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
1012
*/
1113

1214
#ifndef IRremote_h
@@ -24,6 +26,7 @@
2426
class decode_results {
2527
public:
2628
int decode_type; // NEC, SONY, RC5, UNKNOWN
29+
unsigned int panasonicAddress; // This is only used for decoding Panasonic data
2730
unsigned long value; // Decoded value
2831
int bits; // Number of bits in decoded value
2932
volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks
@@ -37,6 +40,8 @@ class decode_results {
3740
#define RC6 4
3841
#define DISH 5
3942
#define SHARP 6
43+
#define PANASONIC 7
44+
#define JVC 8
4045
#define UNKNOWN -1
4146

4247
// Decoded value for NEC when a repeat code is received
@@ -58,6 +63,8 @@ class IRrecv
5863
long decodeSony(decode_results *results);
5964
long decodeRC5(decode_results *results);
6065
long decodeRC6(decode_results *results);
66+
long decodePanasonic(decode_results *results);
67+
long decodeJVC(decode_results *results);
6168
long decodeHash(decode_results *results);
6269
int compare(unsigned int oldval, unsigned int newval);
6370

@@ -82,6 +89,8 @@ class IRsend
8289
void sendRC6(unsigned long data, int nbits);
8390
void sendDISH(unsigned long data, int nbits);
8491
void sendSharp(unsigned long data, int nbits);
92+
void sendPanasonic(unsigned int address, unsigned long data);
93+
void sendJVC(unsigned long data, int nbits, int repeat); // *Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does.
8594
// private:
8695
void enableIROut(int khz);
8796
VIRTUAL void mark(int usec);
@@ -92,7 +101,7 @@ class IRsend
92101
// Some useful constants
93102

94103
#define USECPERTICK 50 // microseconds per clock interrupt tick
95-
#define RAWBUF 76 // Length of raw duration buffer
104+
#define RAWBUF 100 // Length of raw duration buffer
96105

97106
// Marks tend to be 100us too long, and spaces 100us too short
98107
// when received due to sensor lag.

IRremoteInt.h

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@
99
* Interrupt code based on NECIRrcv by Joe Knapp
1010
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
1111
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
12+
*
13+
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
1214
*/
1315

1416
#ifndef IRremoteint_h
1517
#define IRremoteint_h
1618

17-
#include <WProgram.h>
19+
#if defined(ARDUINO) && ARDUINO >= 100
20+
#include "Arduino.h"
21+
#else
22+
#include "WProgram.h"
23+
#endif
1824

1925
// define which timer to use
2026
//
@@ -115,6 +121,19 @@
115121
#define DISH_RPT_SPACE 6200
116122
#define DISH_TOP_BIT 0x8000
117123

124+
#define PANASONIC_HDR_MARK 3502
125+
#define PANASONIC_HDR_SPACE 1750
126+
#define PANASONIC_BIT_MARK 502
127+
#define PANASONIC_ONE_SPACE 1244
128+
#define PANASONIC_ZERO_SPACE 400
< 10000 code>129+
130+
#define JVC_HDR_MARK 8000
131+
#define JVC_HDR_SPACE 4000
132+
#define JVC_BIT_MARK 600
133+
#define JVC_ONE_SPACE 1600
134+
#define JVC_ZERO_SPACE 550
135+
#define JVC_RPT_LENGTH 60000
136+
118137
#define SHARP_BITS 15
119138
#define DISH_BITS 16
120139

@@ -129,9 +148,9 @@
129148
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
130149

131150
#ifndef DEBUG
132-
#define MATCH(measured_ticks, desired_us) ((measured_ticks) >= TICKS_LOW(desired_us) && (measured_ticks) <= TICKS_HIGH(desired_us))
133-
#define MATCH_MARK(measured_ticks, desired_us) MATCH(measured_ticks, (desired_us) + MARK_EXCESS)
134-
#define MATCH_SPACE(measured_ticks, desired_us) MATCH((measured_ticks), (desired_us) - MARK_EXCESS)
151+
int MATCH(int measured, int desired) {return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired);}
152+
int MATCH_MARK(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us + MARK_EXCESS));}
153+
int MATCH_SPACE(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us - MARK_EXCESS));}
135154
// Debugging versions are in IRremote.cpp
136155
#endif
137156

@@ -165,6 +184,8 @@ extern volatile irparams_t irparams;
165184
#define SONY_BITS 12
166185
#define MIN_RC5_SAMPLES 11
167186
#define MIN_RC6_SAMPLES 1
187+
#define PANASONIC_BITS 48
188+
#define JVC_BITS 16
168189

169190

170191

File renamed without changes.

examples/IRrecvDump/IRrecvDump.pde renamed to examples/IRrecvDump/IRrecvDump.ino

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Version 0.1 July, 2009
55
* Copyright 2009 Ken Shirriff
66
* http://arcfn.com
7+
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
78
*/
89

910
#include <IRremote.h>
@@ -42,6 +43,14 @@ void dump(decode_results *results) {
4243
else if (results->decode_type == RC6) {
4344
Serial.print("Decoded RC6: ");
4445
}
46+
else if (results->decode_type == PANASONIC) {
47+
Serial.print("Decoded PANASONIC - Address: ");
48+
Serial.print(results->panasonicAddress,HEX);
49+
Serial.print(" Value: ");
50+
}
51+
else if (results->decode_type == JVC) {
52+
Serial.print("Decoded JVC: ");
53+
}
4554
Serial.print(results->value, HEX);
4655
Serial.print(" (");
4756
Serial.print(results->bits, DEC);
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)
0