Merge pull request #7 from TKJElectronics/master

Added panasonic and JVC protocol and updated the library for Arduino IDE 1.0
This commit is contained in:
Ken Shirriff
2012-06-05 23:00:07 -07:00
12 changed files with 237 additions and 14 deletions

View File

@@ -9,6 +9,8 @@
* Interrupt code based on NECIRrcv by Joe Knapp
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
*
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
*/
#include "IRremote.h"
@@ -167,7 +169,55 @@ void IRsend::sendRC6(unsigned long data, int nbits)
}
space(0); // Turn off at end
}
void IRsend::sendPanasonic(unsigned int address, unsigned long data) {
enableIROut(35);
mark(PANASONIC_HDR_MARK);
space(PANASONIC_HDR_SPACE);
for(int i=0;i<16;i++)
{
mark(PANASONIC_BIT_MARK);
if (address & 0x8000) {
space(PANASONIC_ONE_SPACE);
} else {
space(PANASONIC_ZERO_SPACE);
}
address <<= 1;
}
for (int i=0; i < 32; i++) {
mark(PANASONIC_BIT_MARK);
if (data & TOPBIT) {
space(PANASONIC_ONE_SPACE);
} else {
space(PANASONIC_ZERO_SPACE);
}
data <<= 1;
}
mark(PANASONIC_BIT_MARK);
space(0);
}
void IRsend::sendJVC(unsigned long data, int nbits, int repeat)
{
enableIROut(38);
data = data << (32 - nbits);
if (!repeat){
mark(JVC_HDR_MARK);
space(JVC_HDR_SPACE);
}
for (int i = 0; i < nbits; i++) {
if (data & TOPBIT) {
mark(JVC_BIT_MARK);
space(JVC_ONE_SPACE);
}
else {
mark(JVC_BIT_MARK);
space(JVC_ZERO_SPACE);
}
data <<= 1;
}
mark(JVC_BIT_MARK);
space(0);
}
void IRsend::mark(int time) {
// Sends an IR mark for the specified number of microseconds.
// The mark output is modulated at the PWM frequency.
@@ -362,6 +412,18 @@ int IRrecv::decode(decode_results *results) {
if (decodeRC6(results)) {
return DECODED;
}
#ifdef DEBUG
Serial.println("Attempting Panasonic decode");
#endif
if (decodePanasonic(results)) {
return DECODED;
}
#ifdef DEBUG
Serial.println("Attempting JVC decode");
#endif
if (decodeJVC(results)) {
return DECODED;
}
// decodeHash returns a hash on any input.
// Thus, it needs to be last in the list.
// If you add any decodes, add them before this.
@@ -592,6 +654,90 @@ long IRrecv::decodeRC6(decode_results *results) {
results->decode_type = RC6;
return DECODED;
}
long IRrecv::decodePanasonic(decode_results *results) {
unsigned long long data = 0;
int offset = 1;
if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_MARK)) {
return ERR;
}
offset++;
if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_SPACE)) {
return ERR;
}
offset++;
// decode address
for (int i = 0; i < PANASONIC_BITS; i++) {
if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK)) {
return ERR;
}
if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ONE_SPACE)) {
data = (data << 1) | 1;
} else if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ZERO_SPACE)) {
data <<= 1;
} else {
return ERR;
}
offset++;
}
results->value = (unsigned long)data;
results->panasonicAddress = (unsigned int)(data >> 32);
results->decode_type = PANASONIC;
results->bits = PANASONIC_BITS;
return DECODED;
}
long IRrecv::decodeJVC(decode_results *results) {
long data = 0;
int offset = 1; // Skip first space
// Check for repeat
if (irparams.rawlen - 1 == 33 &&
MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK) &&
MATCH_MARK(results->rawbuf[irparams.rawlen-1], JVC_BIT_MARK)) {
results->bits = 0;
results->value = REPEAT;
results->decode_type = JVC;
return DECODED;
}
// Initial mark
if (!MATCH_MARK(results->rawbuf[offset], JVC_HDR_MARK)) {
return ERR;
}
offset++;
if (irparams.rawlen < 2 * JVC_BITS + 1 ) {
return ERR;
}
// Initial space
if (!MATCH_SPACE(results->rawbuf[offset], JVC_HDR_SPACE)) {
return ERR;
}
offset++;
for (int i = 0; i < JVC_BITS; i++) {
if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) {
return ERR;
}
offset++;
if (MATCH_SPACE(results->rawbuf[offset], JVC_ONE_SPACE)) {
data = (data << 1) | 1;
}
else if (MATCH_SPACE(results->rawbuf[offset], JVC_ZERO_SPACE)) {
data <<= 1;
}
else {
return ERR;
}
offset++;
}
//Stop bit
if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)){
return ERR;
}
// Success
results->bits = JVC_BITS;
results->value = data;
results->decode_type = JVC;
return DECODED;
}
/* -----------------------------------------------------------------------
* hashdecode - decode an arbitrary IR code.

View File

@@ -7,6 +7,8 @@
* Interrupt code based on NECIRrcv by Joe Knapp
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
*
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
*/
#ifndef IRremote_h
@@ -24,6 +26,7 @@
class decode_results {
public:
int decode_type; // NEC, SONY, RC5, UNKNOWN
unsigned int panasonicAddress; // This is only used for decoding Panasonic data
unsigned long value; // Decoded value
int bits; // Number of bits in decoded value
volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks
@@ -37,6 +40,8 @@ public:
#define RC6 4
#define DISH 5
#define SHARP 6
#define PANASONIC 7
#define JVC 8
#define UNKNOWN -1
// Decoded value for NEC when a repeat code is received
@@ -58,6 +63,8 @@ private:
long decodeSony(decode_results *results);
long decodeRC5(decode_results *results);
long decodeRC6(decode_results *results);
long decodePanasonic(decode_results *results);
long decodeJVC(decode_results *results);
long decodeHash(decode_results *results);
int compare(unsigned int oldval, unsigned int newval);
@@ -82,6 +89,8 @@ public:
void sendRC6(unsigned long data, int nbits);
void sendDISH(unsigned long data, int nbits);
void sendSharp(unsigned long data, int nbits);
void sendPanasonic(unsigned int address, unsigned long data);
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.
// private:
void enableIROut(int khz);
VIRTUAL void mark(int usec);
@@ -92,7 +101,7 @@ public:
// Some useful constants
#define USECPERTICK 50 // microseconds per clock interrupt tick
#define RAWBUF 76 // Length of raw duration buffer
#define RAWBUF 100 // Length of raw duration buffer
// Marks tend to be 100us too long, and spaces 100us too short
// when received due to sensor lag.

View File

@@ -9,12 +9,18 @@
* Interrupt code based on NECIRrcv by Joe Knapp
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
*
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
*/
#ifndef IRremoteint_h
#define IRremoteint_h
#include <WProgram.h>
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
// define which timer to use
//
@@ -23,7 +29,7 @@
// to switch IRremote to use a different timer.
// Arduino Mega
#if defined(__AVR_ATmega1280__)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
//#define IR_USE_TIMER1 // tx = pin 11
#define IR_USE_TIMER2 // tx = pin 9
//#define IR_USE_TIMER3 // tx = pin 5
@@ -115,6 +121,19 @@
#define DISH_RPT_SPACE 6200
#define DISH_TOP_BIT 0x8000
#define PANASONIC_HDR_MARK 3502
#define PANASONIC_HDR_SPACE 1750
#define PANASONIC_BIT_MARK 502
#define PANASONIC_ONE_SPACE 1244
#define PANASONIC_ZERO_SPACE 400
#define JVC_HDR_MARK 8000
#define JVC_HDR_SPACE 4000
#define JVC_BIT_MARK 600
#define JVC_ONE_SPACE 1600
#define JVC_ZERO_SPACE 550
#define JVC_RPT_LENGTH 60000
#define SHARP_BITS 15
#define DISH_BITS 16
@@ -129,9 +148,9 @@
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
#ifndef DEBUG
#define MATCH(measured_ticks, desired_us) ((measured_ticks) >= TICKS_LOW(desired_us) && (measured_ticks) <= TICKS_HIGH(desired_us))
#define MATCH_MARK(measured_ticks, desired_us) MATCH(measured_ticks, (desired_us) + MARK_EXCESS)
#define MATCH_SPACE(measured_ticks, desired_us) MATCH((measured_ticks), (desired_us) - MARK_EXCESS)
int MATCH(int measured, int desired) {return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired);}
int MATCH_MARK(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us + MARK_EXCESS));}
int MATCH_SPACE(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us - MARK_EXCESS));}
// Debugging versions are in IRremote.cpp
#endif
@@ -165,6 +184,8 @@ extern volatile irparams_t irparams;
#define SONY_BITS 12
#define MIN_RC5_SAMPLES 11
#define MIN_RC6_SAMPLES 1
#define PANASONIC_BITS 48
#define JVC_BITS 16
@@ -202,7 +223,7 @@ extern volatile irparams_t irparams;
#endif
#if defined(CORE_OC2B_PIN)
#define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */
#elif defined(__AVR_ATmega1280__)
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN 9 /* Arduino Mega */
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
#define TIMER_PWM_PIN 14 /* Sanguino */
@@ -234,7 +255,7 @@ extern volatile irparams_t irparams;
})
#if defined(CORE_OC1A_PIN)
#define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */
#elif defined(__AVR_ATmega1280__)
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN 11 /* Arduino Mega */
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
#define TIMER_PWM_PIN 13 /* Sanguino */
@@ -266,7 +287,7 @@ extern volatile irparams_t irparams;
})
#if defined(CORE_OC3A_PIN)
#define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */
#elif defined(__AVR_ATmega1280__)
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN 5 /* Arduino Mega */
#else
#error "Please add OC3A pin number here\n"
@@ -334,7 +355,7 @@ extern volatile irparams_t irparams;
})
#if defined(CORE_OC4A_PIN)
#define TIMER_PWM_PIN CORE_OC4A_PIN
#elif defined(__AVR_ATmega1280__)
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN 6 /* Arduino Mega */
#else
#error "Please add OC4A pin number here\n"
@@ -364,7 +385,7 @@ extern volatile irparams_t irparams;
})
#if defined(CORE_OC5A_PIN)
#define TIMER_PWM_PIN CORE_OC5A_PIN
#elif defined(__AVR_ATmega1280__)
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN 46 /* Arduino Mega */
#else
#error "Please add OC5A pin number here\n"
@@ -381,7 +402,7 @@ extern volatile irparams_t irparams;
#define BLINKLED CORE_LED0_PIN
#define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
#define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
#elif defined(__AVR_ATmega1280__)
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define BLINKLED 13
#define BLINKLED_ON() (PORTB |= B10000000)
#define BLINKLED_OFF() (PORTB &= B01111111)

View File

@@ -4,6 +4,7 @@
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
*/
#include <IRremote.h>
@@ -42,6 +43,14 @@ void dump(decode_results *results) {
else if (results->decode_type == RC6) {
Serial.print("Decoded RC6: ");
}
else if (results->decode_type == PANASONIC) {
Serial.print("Decoded PANASONIC - Address: ");
Serial.print(results->panasonicAddress,HEX);
Serial.print(" Value: ");
}
else if (results->decode_type == JVC) {
Serial.print("Decoded JVC: ");
}
Serial.print(results->value, HEX);
Serial.print(" (");
Serial.print(results->bits, DEC);

View File

@@ -0,0 +1,29 @@
/*
* IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
* An IR LED must be connected to Arduino PWM pin 3.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
*/
#include <IRremote.h>
#define PanasonicAddress 0x4004 // Panasonic address (Pre data)
#define PanasonicPower 0x100BCBD // Panasonic Power button
#define JVCPower 0xC5E8
IRsend irsend;
void setup()
{
}
void loop() {
irsend.sendPanasonic(PanasonicAddress,PanasonicPower); // This should turn your TV on and off
irsend.sendJVC(JVCPower, 16,0); // hex value, 16 bits, no repeat
delayMicroseconds(50); // see http://www.sbprojects.com/knowledge/ir/jvc.php for information
irsend.sendJVC(JVCPower, 16,1); // hex value, 16 bits, repeat
delayMicroseconds(50);
}

View File

@@ -24,6 +24,11 @@ sendSony KEYWORD2
sendRaw KEYWORD2
sendRC5 KEYWORD2
sendRC6 KEYWORD2
sendDISH KEYWORD2
sendSharp KEYWORD2
sendPanasonic KEYWORD2
sendJVC KEYWORD2
#
#######################################
# Constants (LITERAL1)
@@ -33,5 +38,9 @@ NEC LITERAL1
SONY LITERAL1
RC5 LITERAL1
RC6 LITERAL1
DISH LITERAL1
SHARP LITERAL1
PANASONIC LITERAL1
JVC LITERAL1
UNKNOWN LITERAL1
REPEAT LITERAL1
REPEAT LITERAL1