mirror of
https://github.com/Theaninova/Arduino-IRremote.git
synced 2025-12-11 08:56:14 +00:00
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.
This commit is contained in:
148
IRremote.cpp
148
IRremote.cpp
@@ -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(38);
|
||||
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.
|
||||
|
||||
11
IRremote.h
11
IRremote.h
@@ -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.
|
||||
|
||||
@@ -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
|
||||
//
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
29
examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino
Normal file
29
examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user