mirror of
https://github.com/Theaninova/Arduino-IRremote.git
synced 2025-12-11 08:56:14 +00:00
Broken the source in to manageable chunks - 2KLOC files are not fun to debug!
Utterly failed to reduce the MARK_?? functions back down to MACROs - every time I try, the decoders start failing ...However, I have found a considerable number of bugs in the toolchain, so I'm starting to wonder if the fault is not mine.
This commit is contained in:
1636
IRremote.cpp
1636
IRremote.cpp
File diff suppressed because it is too large
Load Diff
47
IRremote.h
47
IRremote.h
@@ -1,3 +1,49 @@
|
||||
#define DEBUG
|
||||
#undef DEBUG
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int MATCH_SPACE (int measured_ticks, int desired_us) ;
|
||||
int MATCH_MARK (int measured_ticks, int desired_us) ;
|
||||
int MATCH (int measured, int desired) ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Debug directives
|
||||
#ifdef DEBUG
|
||||
# define DBG_PRINT(...) Serial.print(__VA_ARGS__)
|
||||
# define DBG_PRINTLN(...) Serial.println(__VA_ARGS__)
|
||||
#else
|
||||
# define DBG_PRINT(...)
|
||||
# define DBG_PRINTLN(...)
|
||||
#endif
|
||||
|
||||
///int MATCH (int measured, int desired);
|
||||
///int MATCH_MARK (int measured_ticks, int desired_us);
|
||||
///int MATCH_SPACE (int measured_ticks, int desired_us);
|
||||
|
||||
#define SEND_NEC
|
||||
#define DECODE_NEC
|
||||
#define SEND_WHYNTER
|
||||
#define DECODE_WHYNTER
|
||||
#define SEND_SONY
|
||||
#define DECODE_SONY
|
||||
#define DECODE_SANYO
|
||||
#define SEND_RC5
|
||||
#define DECODE_RC5
|
||||
#define SEND_RC6
|
||||
#define DECODE_RC6
|
||||
#define SEND_PANASONIC
|
||||
#define DECODE_PANASONIC
|
||||
#define SEND_JVC
|
||||
#define DECODE_JVC
|
||||
#define SEND_SAMSUNG
|
||||
#define DECODE_SAMSUNG
|
||||
#define DECODE_LG
|
||||
#define DECODE_MITSUBISHI
|
||||
#define SEND_AIWA_RC_T501
|
||||
#define DECODE_AIWA_RC_T501
|
||||
#define SEND_SHARP
|
||||
#define SEND_DISH
|
||||
|
||||
/*
|
||||
* IRremote
|
||||
* Version 0.1 July, 2009
|
||||
@@ -42,7 +88,6 @@ enum decode_type_t {
|
||||
LG = 12,
|
||||
WHYNTER = 13,
|
||||
AIWA_RC_T501 = 14,
|
||||
|
||||
};
|
||||
|
||||
// Results returned from the decoder
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
#ifndef IRremoteint_h
|
||||
#define IRremoteint_h
|
||||
|
||||
#ifdef IR_GLOBAL
|
||||
# define EXTERN
|
||||
#else
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
@@ -141,7 +147,7 @@ typedef struct {
|
||||
irparams_t;
|
||||
|
||||
// Defined in IRremote.cpp
|
||||
extern volatile irparams_t irparams;
|
||||
EXTERN volatile irparams_t irparams;
|
||||
|
||||
// IR detector output is active low
|
||||
#define MARK 0
|
||||
|
||||
76
irISR.cpp
Normal file
76
irISR.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//+=============================================================================
|
||||
// TIMER2 interrupt code to collect raw data.
|
||||
// Widths of alternating SPACE, MARK are recorded in rawbuf.
|
||||
// Recorded in ticks of 50 microseconds.
|
||||
// rawlen counts the number of entries recorded so far.
|
||||
// First entry is the SPACE between transmissions.
|
||||
// As soon as a SPACE gets long, ready is set, state switches to IDLE, timing of SPACE continues.
|
||||
// As soon as first MARK arrives, gap width is recorded, ready is cleared, and new logging starts
|
||||
//
|
||||
ISR (TIMER_INTR_NAME)
|
||||
{
|
||||
TIMER_RESET;
|
||||
|
||||
uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin);
|
||||
|
||||
irparams.timer++; // One more 50us tick
|
||||
if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_STOP ; // Buffer overflow
|
||||
|
||||
switch(irparams.rcvstate) {
|
||||
case STATE_IDLE: // In the middle of a gap
|
||||
if (irdata == MARK) {
|
||||
if (irparams.timer < GAP_TICKS) {
|
||||
// Not big enough to be a gap.
|
||||
irparams.timer = 0;
|
||||
}
|
||||
else {
|
||||
// gap just ended, record duration and start recording transmission
|
||||
irparams.rawlen = 0;
|
||||
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
|
||||
irparams.timer = 0;
|
||||
irparams.rcvstate = STATE_MARK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_MARK: // timing MARK
|
||||
if (irdata == SPACE) { // MARK ended, record time
|
||||
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
|
||||
irparams.timer = 0;
|
||||
irparams.rcvstate = STATE_SPACE;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_SPACE: // timing SPACE
|
||||
if (irdata == MARK) { // SPACE just ended, record it
|
||||
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
|
||||
irparams.timer = 0;
|
||||
irparams.rcvstate = STATE_MARK;
|
||||
}
|
||||
else { // SPACE
|
||||
if (irparams.timer > GAP_TICKS) {
|
||||
// big SPACE, indicates gap between codes
|
||||
// Mark current code as ready for processing
|
||||
// Switch to STOP
|
||||
// Don't reset timer; keep counting space width
|
||||
irparams.rcvstate = STATE_STOP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_STOP: // waiting, measuring gap
|
||||
if (irdata == MARK) irparams.timer = 0 ; // reset gap timer
|
||||
break;
|
||||
}
|
||||
|
||||
if (irparams.blinkflag) {
|
||||
if (irdata == MARK) BLINKLED_ON() ; // turn pin 13 LED on
|
||||
else BLINKLED_OFF() ; // turn pin 13 LED off
|
||||
}
|
||||
}
|
||||
|
||||
195
irRecv.cpp
Normal file
195
irRecv.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//+=============================================================================
|
||||
IRrecv::IRrecv (int recvpin)
|
||||
{
|
||||
irparams.recvpin = recvpin;
|
||||
irparams.blinkflag = 0;
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// initialization
|
||||
//
|
||||
void IRrecv::enableIRIn ( )
|
||||
{
|
||||
cli();
|
||||
// setup pulse clock timer interrupt
|
||||
//Prescale /8 (16M/8 = 0.5 microseconds per tick)
|
||||
// Therefore, the timer interval can range from 0.5 to 128 microseconds
|
||||
// depending on the reset value (255 to 0)
|
||||
TIMER_CONFIG_NORMAL();
|
||||
|
||||
//Timer2 Overflow Interrupt Enable
|
||||
TIMER_ENABLE_INTR;
|
||||
|
||||
TIMER_RESET;
|
||||
|
||||
sei(); // enable interrupts
|
||||
|
||||
// initialize state machine variables
|
||||
irparams.rcvstate = STATE_IDLE;
|
||||
irparams.rawlen = 0;
|
||||
|
||||
// set pin modes
|
||||
pinMode(irparams.recvpin, INPUT);
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// enable/disable blinking of pin 13 on IR processing
|
||||
//
|
||||
void IRrecv::blink13 (int blinkflag)
|
||||
{
|
||||
irparams.blinkflag = blinkflag;
|
||||
if (blinkflag) pinMode(BLINKLED, OUTPUT) ;
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
void IRrecv::resume ( )
|
||||
{
|
||||
irparams.rcvstate = STATE_IDLE;
|
||||
irparams.rawlen = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//+=============================================================================
|
||||
// Decodes the received IR message
|
||||
// Returns 0 if no data ready, 1 if data ready.
|
||||
// Results of decoding are stored in results
|
||||
int IRrecv::decode (decode_results *results)
|
||||
{
|
||||
results->rawbuf = irparams.rawbuf;
|
||||
results->rawlen = irparams.rawlen;
|
||||
|
||||
if (irparams.rcvstate != STATE_STOP) return false ;
|
||||
|
||||
#ifdef DECODE_NEC
|
||||
DBG_PRINTLN("Attempting NEC decode");
|
||||
if (decodeNEC(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_SONY
|
||||
DBG_PRINTLN("Attempting Sony decode");
|
||||
if (decodeSony(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_SANYO
|
||||
DBG_PRINTLN("Attempting Sanyo decode");
|
||||
if (decodeSanyo(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_MITSUBISHI
|
||||
DBG_PRINTLN("Attempting Mitsubishi decode");
|
||||
if (decodeMitsubishi(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_RC5
|
||||
DBG_PRINTLN("Attempting RC5 decode");
|
||||
if (decodeRC5(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_RC6
|
||||
DBG_PRINTLN("Attempting RC6 decode");
|
||||
if (decodeRC6(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_PANASONIC
|
||||
DBG_PRINTLN("Attempting Panasonic decode");
|
||||
if (decodePanasonic(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_LG
|
||||
DBG_PRINTLN("Attempting LG decode");
|
||||
if (decodeLG(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_JVC
|
||||
DBG_PRINTLN("Attempting JVC decode");
|
||||
if (decodeJVC(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_SAMSUNG
|
||||
DBG_PRINTLN("Attempting SAMSUNG decode");
|
||||
if (decodeSAMSUNG(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef DECODE_WHYNTER
|
||||
DBG_PRINTLN("Attempting Whynter decode");
|
||||
if (decodeWhynter(results)) return true ;
|
||||
#endif
|
||||
|
||||
#ifdef AIWA_RC_T501
|
||||
DBG_PRINTLN("Attempting Aiwa RC-T501 decode");
|
||||
if (decodeAiwaRCT501(results)) return true ;
|
||||
#endif
|
||||
|
||||
// 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.
|
||||
if (decodeHash(results)) return true ;
|
||||
// Throw away and start over
|
||||
resume();
|
||||
return false;
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// hashdecode - decode an arbitrary IR code.
|
||||
// Instead of decoding using a standard encoding scheme
|
||||
// (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
|
||||
//
|
||||
// The algorithm: look at the sequence of MARK signals, and see if each one
|
||||
// is shorter (0), the same length (1), or longer (2) than the previous.
|
||||
// Do the same with the SPACE signals. Hszh the resulting sequence of 0's,
|
||||
// 1's, and 2's to a 32-bit value. This will give a unique value for each
|
||||
// different code (probably), for most code systems.
|
||||
//
|
||||
// http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
|
||||
//
|
||||
// Compare two tick values, returning 0 if newval is shorter,
|
||||
// 1 if newval is equal, and 2 if newval is longer
|
||||
// Use a tolerance of 20%
|
||||
//
|
||||
int IRrecv::compare (unsigned int oldval, unsigned int newval)
|
||||
{
|
||||
if (newval < oldval * .8) return 0 ;
|
||||
else if (oldval < newval * .8) return 2 ;
|
||||
else return 1 ;
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
|
||||
// Converts the raw code values into a 32-bit hash code.
|
||||
// Hopefully this code is unique for each button.
|
||||
// This isn't a "real" decoding, just an arbitrary value.
|
||||
//
|
||||
#define FNV_PRIME_32 16777619
|
||||
#define FNV_BASIS_32 2166136261
|
||||
|
||||
long IRrecv::decodeHash (decode_results *results)
|
||||
{
|
||||
// Require at least 6 samples to prevent triggering on noise
|
||||
if (results->rawlen < 6) return false ;
|
||||
long hash = FNV_BASIS_32;
|
||||
for (int i = 1; (i + 2) < results->rawlen; i++) {
|
||||
int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
|
||||
// Add value into the hash
|
||||
hash = (hash * FNV_PRIME_32) ^ value;
|
||||
}
|
||||
|
||||
results->value = hash;
|
||||
results->bits = 32;
|
||||
results->decode_type = UNKNOWN;
|
||||
|
||||
return true;
|
||||
}
|
||||
66
irSend.cpp
Normal file
66
irSend.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//+=============================================================================
|
||||
void IRsend::sendRaw (unsigned int buf[], int len, int hz)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(hz);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (i & 1) space(buf[i]) ;
|
||||
else mark (buf[i]) ;
|
||||
}
|
||||
|
||||
space(0); // Always end with the LED off
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// Sends an IR mark for the specified number of microseconds.
|
||||
// The mark output is modulated at the PWM frequency.
|
||||
//
|
||||
void IRsend::mark (int time)
|
||||
{
|
||||
TIMER_ENABLE_PWM; // Enable pin 3 PWM output
|
||||
if (time > 0) delayMicroseconds(time);
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// Leave pin off for time (given in microseconds)
|
||||
// Sends an IR space for the specified number of microseconds.
|
||||
// A space is no output, so the PWM output is disabled.
|
||||
//
|
||||
void IRsend::space (int time)
|
||||
{
|
||||
TIMER_DISABLE_PWM; // Disable pin 3 PWM output
|
||||
if (time > 0) delayMicroseconds(time);
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// Enables IR output. The khz value controls the modulation frequency in kilohertz.
|
||||
// The IR output will be on pin 3 (OC2B).
|
||||
// This routine is designed for 36-40KHz; if you use it for other values, it's up to you
|
||||
// to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.)
|
||||
// TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B
|
||||
// controlling the duty cycle.
|
||||
// There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A)
|
||||
// To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin.
|
||||
// A few hours staring at the ATmega documentation and this will all make sense.
|
||||
// See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details.
|
||||
//
|
||||
void IRsend::enableIROut (int khz)
|
||||
{
|
||||
// Disable the Timer2 Interrupt (which is used for receiving IR)
|
||||
TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt
|
||||
|
||||
pinMode(TIMER_PWM_PIN, OUTPUT);
|
||||
digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low
|
||||
|
||||
// COM2A = 00: disconnect OC2A
|
||||
// COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted
|
||||
// WGM2 = 101: phase-correct PWM with OCRA as top
|
||||
// CS2 = 000: no prescaling
|
||||
// The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A.
|
||||
TIMER_CONFIG_KHZ(khz);
|
||||
}
|
||||
|
||||
108
ir_Aiwa.cpp
Normal file
108
ir_Aiwa.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// AAA IIIII W W AAA
|
||||
// A A I W W A A
|
||||
// AAAAA I W W W AAAAA
|
||||
// A A I W W W A A
|
||||
// A A IIIII WWW A A
|
||||
//==============================================================================
|
||||
|
||||
// Baszed off the RC-T501 RCU
|
||||
// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501
|
||||
|
||||
#define AIWA_RC_T501_HZ 38
|
||||
#define AIWA_RC_T501_BITS 15
|
||||
#define AIWA_RC_T501_PRE_BITS 26
|
||||
#define AIWA_RC_T501_POST_BITS 1
|
||||
#define AIWA_RC_T501_SUM_BITS (AIWA_RC_T501_PRE_BITS + AIWA_RC_T501_BITS + AIWA_RC_T501_POST_BITS)
|
||||
#define AIWA_RC_T501_HDR_MARK 8800
|
||||
#define AIWA_RC_T501_HDR_SPACE 4500
|
||||
#define AIWA_RC_T501_BIT_MARK 500
|
||||
#define AIWA_RC_T501_ONE_SPACE 600
|
||||
#define AIWA_RC_T501_ZERO_SPACE 1700
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef SEND_AIWA_RC_T501
|
||||
void IRsend::sendAiwaRCT501 (int code)
|
||||
{
|
||||
unsigned long pre = 0x0227EEC0; // 26-bits
|
||||
int mask;
|
||||
|
||||
// Set IR carrier frequency
|
||||
enableIROut(AIWA_RC_T501_HZ);
|
||||
|
||||
// Header
|
||||
mark(AIWA_RC_T501_HDR_MARK);
|
||||
space(AIWA_RC_T501_HDR_SPACE);
|
||||
|
||||
// Send "pre" data
|
||||
for (unsigned long mask = 1 << (26 - 1); mask; mask >>= 1) {
|
||||
mark(AIWA_RC_T501_BIT_MARK);
|
||||
if (pre & mask) space(AIWA_RC_T501_ONE_SPACE) ;
|
||||
else space(AIWA_RC_T501_ZERO_SPACE) ;
|
||||
}
|
||||
|
||||
//-v- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK!
|
||||
// it only send 15bits and ignores the top bit
|
||||
// then uses TOPBIT which is bit-31 to check the bit code
|
||||
// I suspect TOPBIT should be changed to 0x00008000
|
||||
// Skip firts code bit
|
||||
code <<= 1;
|
||||
// Send code
|
||||
for (int i = 0; i < 15; i++) {
|
||||
mark(AIWA_RC_T501_BIT_MARK);
|
||||
if (code & TOPBIT) space(AIWA_RC_T501_ONE_SPACE) ;
|
||||
else space(AIWA_RC_T501_ZERO_SPACE) ;
|
||||
code <<= 1;
|
||||
}
|
||||
//-^- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK!
|
||||
|
||||
// POST-DATA, 1 bit, 0x0
|
||||
mark(AIWA_RC_T501_BIT_MARK);
|
||||
space(AIWA_RC_T501_ZERO_SPACE);
|
||||
|
||||
mark(AIWA_RC_T501_BIT_MARK);
|
||||
space(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef DECODE_AIWA_RC_T501
|
||||
long IRrecv::decodeAiwaRCT501 (decode_results *results)
|
||||
{
|
||||
int data = 0;
|
||||
int offset = 1; // skip first garbage read
|
||||
|
||||
// Check SIZE
|
||||
if (irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) return false ;
|
||||
|
||||
// Check HDR
|
||||
if (!MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
|
||||
// Check HDR space
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_HDR_SPACE)) return false ;
|
||||
offset++;
|
||||
|
||||
offset += 26; // skip pre-data - optional
|
||||
while(offset < irparams.rawlen - 4) {
|
||||
if (MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_BIT_MARK)) offset++ ;
|
||||
else return false ;
|
||||
|
||||
// ONE & ZERO
|
||||
if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ONE_SPACE)) data = (data << 1) | 1 ;
|
||||
else if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ZERO_SPACE)) data <<= 1 ;
|
||||
else break ; // End of one & zero detected
|
||||
offset++;
|
||||
}
|
||||
|
||||
results->bits = (offset - 1) / 2;
|
||||
if (results->bits < 42) return false ;
|
||||
results->value = data;
|
||||
results->decode_type = AIWA_RC_T501;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
55
ir_Dish.cpp
Normal file
55
ir_Dish.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// DDDD IIIII SSSS H H
|
||||
// D D I S H H
|
||||
// D D I SSS HHHHH
|
||||
// D D I S H H
|
||||
// DDDD IIIII SSSS H H
|
||||
//==============================================================================
|
||||
|
||||
// Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand )
|
||||
//
|
||||
// The sned function needs to be repeated 4 times
|
||||
//
|
||||
// Only send the last for characters of the hex.
|
||||
// I.E. Use 0x1C10 instead of 0x0000000000001C10 as listed in the LIRC file.
|
||||
//
|
||||
// Here is the LIRC file I found that seems to match the remote codes from the
|
||||
// oscilloscope:
|
||||
// DISH NETWORK (echostar 301):
|
||||
// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx
|
||||
|
||||
#define DISH_BITS 16
|
||||
|
||||
#define DISH_HDR_MARK 400
|
||||
#define DISH_HDR_SPACE 6100
|
||||
#define DISH_BIT_MARK 400
|
||||
#define DISH_ONE_SPACE 1700
|
||||
#define DISH_ZERO_SPACE 2800
|
||||
#define DISH_RPT_SPACE 6200
|
||||
#define DISH_TOP_BIT 0x8000
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef SEND_DISH
|
||||
void IRsend::sendDISH (unsigned long data, int nbits)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(56);
|
||||
|
||||
mark(DISH_HDR_MARK);
|
||||
space(DISH_HDR_SPACE);
|
||||
|
||||
for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) {
|
||||
if (data & mask) {
|
||||
mark(DISH_BIT_MARK);
|
||||
space(DISH_ONE_SPACE);
|
||||
} else {
|
||||
mark(DISH_BIT_MARK);
|
||||
space(DISH_ZERO_SPACE);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
97
ir_JVC.cpp
Normal file
97
ir_JVC.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// JJJJJ V V CCCC
|
||||
// J V V C
|
||||
// J V V C
|
||||
// J J V V C
|
||||
// J V CCCC
|
||||
//==============================================================================
|
||||
|
||||
#define JVC_BITS 16
|
||||
#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
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef SEND_JVC
|
||||
void IRsend::sendJVC (unsigned long data, int nbits, int repeat)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(38);
|
||||
|
||||
// Only send the Header if this is NOT a repeat command
|
||||
if (!repeat){
|
||||
mark(JVC_HDR_MARK);
|
||||
space(JVC_HDR_SPACE);
|
||||
}
|
||||
|
||||
// Data
|
||||
for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) {
|
||||
if (data & mask) {
|
||||
mark(JVC_BIT_MARK);
|
||||
space(JVC_ONE_SPACE);
|
||||
} else {
|
||||
mark(JVC_BIT_MARK);
|
||||
space(JVC_ZERO_SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
// Footer
|
||||
mark(JVC_BIT_MARK);
|
||||
space(0); // Always end with the LED off
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef DECODE_JVC
|
||||
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 true;
|
||||
}
|
||||
|
||||
// Initial mark
|
||||
if (!MATCH_MARK(results->rawbuf[offset], JVC_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
|
||||
if (irparams.rawlen < 2 * JVC_BITS + 1 ) return false ;
|
||||
|
||||
// Initial space
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], JVC_HDR_SPACE)) return false ;
|
||||
offset++;
|
||||
|
||||
for (int i = 0; i < JVC_BITS; i++) {
|
||||
if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return false ;
|
||||
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 false ;
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Stop bit
|
||||
if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return false ;
|
||||
|
||||
// Success
|
||||
results->bits = JVC_BITS;
|
||||
results->value = data;
|
||||
results->decode_type = JVC;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
54
ir_LG.cpp
Normal file
54
ir_LG.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// L GGGG
|
||||
// L G
|
||||
// L G GG
|
||||
// L G G
|
||||
// LLLLL GGG
|
||||
//==============================================================================
|
||||
|
||||
#define LG_BITS 28
|
||||
|
||||
#define LG_HDR_MARK 8000
|
||||
#define LG_HDR_SPACE 4000
|
||||
#define LG_BIT_MARK 600
|
||||
#define LG_ONE_SPACE 1600
|
||||
#define LG_ZERO_SPACE 550
|
||||
#define LG_RPT_LENGTH 60000
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef DECODE_LG
|
||||
long IRrecv::decodeLG (decode_results *results)
|
||||
{
|
||||
long data = 0;
|
||||
int offset = 1; // Skip first space
|
||||
|
||||
// Initial mark
|
||||
if (!MATCH_MARK(results->rawbuf[offset], LG_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
if (irparams.rawlen < 2 * LG_BITS + 1 ) return false ;
|
||||
// Initial space
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], LG_HDR_SPACE)) return false ;
|
||||
offset++;
|
||||
for (int i = 0; i < LG_BITS; i++) {
|
||||
if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return false ;
|
||||
offset++;
|
||||
if (MATCH_SPACE(results->rawbuf[offset], LG_ONE_SPACE)) data = (data << 1) | 1 ;
|
||||
else if (MATCH_SPACE(results->rawbuf[offset], LG_ZERO_SPACE)) data <<= 1 ;
|
||||
else return false ;
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Stop bit
|
||||
if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return false ;
|
||||
|
||||
// Success
|
||||
results->bits = LG_BITS;
|
||||
results->value = data;
|
||||
results->decode_type = LG;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
85
ir_Mitsubishi.cpp
Normal file
85
ir_Mitsubishi.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// MMMMM IIIII TTTTT SSSS U U BBBB IIIII SSSS H H IIIII
|
||||
// M M M I T S U U B B I S H H I
|
||||
// M M M I T SSS U U BBBB I SSS HHHHH I
|
||||
// M M I T S U U B B I S H H I
|
||||
// M M IIIII T SSSS UUU BBBBB IIIII SSSS H H IIIII
|
||||
//==============================================================================
|
||||
|
||||
// Looks like Sony except for timings, 48 chars of data and time/space different
|
||||
|
||||
#define MITSUBISHI_BITS 16
|
||||
|
||||
// Mitsubishi RM 75501
|
||||
// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
|
||||
// #define MITSUBISHI_HDR_MARK 250 // seen range 3500
|
||||
#define MITSUBISHI_HDR_SPACE 350 // 7*50+100
|
||||
#define MITSUBISHI_ONE_MARK 1950 // 41*50-100
|
||||
#define MITSUBISHI_ZERO_MARK 750 // 17*50-100
|
||||
// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
||||
// #define MITSUBISHI_RPT_LENGTH 45000
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef DECODE_MITSUBISHI
|
||||
long IRrecv::decodeMitsubishi (decode_results *results)
|
||||
{
|
||||
// Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2);
|
||||
long data = 0;
|
||||
if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2) return false ;
|
||||
int offset = 0; // Skip first space
|
||||
// Initial space
|
||||
|
||||
#if 0
|
||||
// Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay
|
||||
Serial.print("IR Gap: ");
|
||||
Serial.println( results->rawbuf[offset]);
|
||||
Serial.println( "test against:");
|
||||
Serial.println(results->rawbuf[offset]);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// Not seeing double keys from Mitsubishi
|
||||
if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) {
|
||||
// Serial.print("IR Gap found: ");
|
||||
results->bits = 0;
|
||||
results->value = REPEAT;
|
||||
results->decode_type = MITSUBISHI;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
offset++;
|
||||
|
||||
// Typical
|
||||
// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
|
||||
|
||||
// Initial Space
|
||||
if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) return false ;
|
||||
offset++;
|
||||
|
||||
while (offset + 1 < irparams.rawlen) {
|
||||
if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ONE_MARK)) data = (data << 1) | 1 ;
|
||||
else if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ZERO_MARK)) data <<= 1 ;
|
||||
else return false ;
|
||||
offset++;
|
||||
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) break ;
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Success
|
||||
results->bits = (offset - 1) / 2;
|
||||
if (results->bits < MITSUBISHI_BITS) {
|
||||
results->bits = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
results->value = data;
|
||||
results->decode_type = MITSUBISHI;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
98
ir_NEC.cpp
Normal file
98
ir_NEC.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// N N EEEEE CCCC
|
||||
// NN N E C
|
||||
// N N N EEE C
|
||||
// N NN E C
|
||||
// N N EEEEE CCCC
|
||||
//==============================================================================
|
||||
|
||||
#define NEC_BITS 32
|
||||
#define NEC_HDR_MARK 9000
|
||||
#define NEC_HDR_SPACE 4500
|
||||
#define NEC_BIT_MARK 560
|
||||
#define NEC_ONE_SPACE 1690
|
||||
#define NEC_ZERO_SPACE 560
|
||||
#define NEC_RPT_SPACE 2250
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef SEND_NEC
|
||||
void IRsend::sendNEC (unsigned long data, int nbits)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(38);
|
||||
|
||||
// Header
|
||||
mark(NEC_HDR_MARK);
|
||||
space(NEC_HDR_SPACE);
|
||||
|
||||
// Data
|
||||
for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) {
|
||||
if (data & mask) {
|
||||
mark(NEC_BIT_MARK);
|
||||
space(NEC_ONE_SPACE);
|
||||
} else {
|
||||
mark(NEC_BIT_MARK);
|
||||
space(NEC_ZERO_SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
// Footer
|
||||
mark(NEC_BIT_MARK);
|
||||
space(0); // Always end with the LED off
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
// NECs have a repeat only 4 items long
|
||||
//
|
||||
#ifdef DECODE_NEC
|
||||
long IRrecv::decodeNEC (decode_results *results)
|
||||
{
|
||||
long data = 0; // We decode in to here; Start with nothing
|
||||
int offset = 1; // Index in to results; Skip first entry!?
|
||||
|
||||
// Check header "mark"
|
||||
if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
|
||||
// Check for repeat
|
||||
if ( (irparams.rawlen == 4)
|
||||
&& MATCH_SPACE(results->rawbuf[offset ], NEC_RPT_SPACE)
|
||||
&& MATCH_MARK (results->rawbuf[offset+1], NEC_BIT_MARK )
|
||||
) {
|
||||
results->bits = 0;
|
||||
results->value = REPEAT;
|
||||
results->decode_type = NEC;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check we have enough data
|
||||
if (irparams.rawlen < (2 * NEC_BITS) + 4) return false ;
|
||||
|
||||
// Check header "space"
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) return false ;
|
||||
offset++;
|
||||
|
||||
// Build the data
|
||||
for (int i = 0; i < NEC_BITS; i++) {
|
||||
// Check data "mark"
|
||||
if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) return false ;
|
||||
offset++;
|
||||
// Suppend this bit
|
||||
if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE )) data = (data << 1) | 1 ;
|
||||
else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) data = (data << 1) | 0 ;
|
||||
else return false ;
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Success
|
||||
results->bits = NEC_BITS;
|
||||
results->value = data;
|
||||
results->decode_type = NEC;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
80
ir_Panasonic.cpp
Normal file
80
ir_Panasonic.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// PPPP AAA N N AAA SSSS OOO N N IIIII CCCC
|
||||
// P P A A NN N A A S O O NN N I C
|
||||
// PPPP AAAAA N N N AAAAA SSS O O N N N I C
|
||||
// P A A N NN A A S O O N NN I C
|
||||
// P A A N N A A SSSS OOO N N IIIII CCCC
|
||||
//==============================================================================
|
||||
|
||||
#define PANASONIC_BITS 48
|
||||
#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
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef SEND_PANASONIC
|
||||
void IRsend::sendPanasonic (unsigned int address, unsigned long data)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(35);
|
||||
|
||||
// Header
|
||||
mark(PANASONIC_HDR_MARK);
|
||||
space(PANASONIC_HDR_SPACE);
|
||||
|
||||
// Address
|
||||
for (unsigned long mask = 1 << (16 - 1); mask; mask >>= 1) {
|
||||
mark(PANASONIC_BIT_MARK);
|
||||
if (address & mask) space(PANASONIC_ONE_SPACE) ;
|
||||
else space(PANASONIC_ZERO_SPACE) ;
|
||||
}
|
||||
|
||||
// Data
|
||||
for (unsigned long mask = 1 << (32 - 1); mask; mask >>= 1) {
|
||||
mark(PANASONIC_BIT_MARK);
|
||||
if (data & mask) space(PANASONIC_ONE_SPACE) ;
|
||||
else space(PANASONIC_ZERO_SPACE) ;
|
||||
}
|
||||
|
||||
// Footer
|
||||
mark(PANASONIC_BIT_MARK);
|
||||
space(0); // Always end with the LED off
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef DECODE_PANASONIC
|
||||
long IRrecv::decodePanasonic (decode_results *results)
|
||||
{
|
||||
unsigned long long data = 0;
|
||||
int offset = 1;
|
||||
|
||||
if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_SPACE)) return false ;
|
||||
offset++;
|
||||
|
||||
// decode address
|
||||
for (int i = 0; i < PANASONIC_BITS; i++) {
|
||||
if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK)) return false ;
|
||||
|
||||
if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ONE_SPACE )) data = (data << 1) | 1 ;
|
||||
else if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ZERO_SPACE)) data = (data << 1) | 0 ;
|
||||
else return false ;
|
||||
offset++;
|
||||
}
|
||||
|
||||
results->value = (unsigned long)data;
|
||||
results->panasonicAddress = (unsigned int)(data >> 32);
|
||||
results->decode_type = PANASONIC;
|
||||
results->bits = PANASONIC_BITS;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
196
ir_RC5_RC6.cpp
Normal file
196
ir_RC5_RC6.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//+=============================================================================
|
||||
// Gets one undecoded level at a time from the raw buffer.
|
||||
// The RC5/6 decoding is easier if the data is broken into time intervals.
|
||||
// E.g. if the buffer has MARK for 2 time intervals and SPACE for 1,
|
||||
// successive calls to getRClevel will return MARK, MARK, SPACE.
|
||||
// offset and used are updated to keep track of the current position.
|
||||
// t1 is the time interval for a single bit in microseconds.
|
||||
// Returns -1 for error (measured time interval is not a multiple of t1).
|
||||
//
|
||||
int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int t1)
|
||||
{
|
||||
if (*offset >= results->rawlen) return SPACE ; // After end of recorded buffer, assume SPACE.
|
||||
int width = results->rawbuf[*offset];
|
||||
int val = ((*offset) % 2) ? MARK : SPACE;
|
||||
int correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS;
|
||||
|
||||
int avail;
|
||||
if (MATCH(width, t1 + correction)) avail = 1 ;
|
||||
else if (MATCH(width, 2*t1 + correction)) avail = 2 ;
|
||||
else if (MATCH(width, 3*t1 + correction)) avail = 3 ;
|
||||
else return -1 ;
|
||||
|
||||
(*used)++;
|
||||
if (*used >= avail) {
|
||||
*used = 0;
|
||||
(*offset)++;
|
||||
}
|
||||
|
||||
DBG_PRINTLN( (val == MARK) ? "MARK" : "SPACE" );
|
||||
return val;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// RRRR CCCC 55555
|
||||
// R R C 5
|
||||
// RRRR C 5555
|
||||
// R R C 5
|
||||
// R R CCCC 5555
|
||||
//
|
||||
// NB: First bit must be a one (start bit)
|
||||
//
|
||||
#define MIN_RC5_SAMPLES 11
|
||||
#define RC5_T1 889
|
||||
#define RC5_RPT_LENGTH 46000
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef SEND_RC5
|
||||
void IRsend::sendRC5 (unsigned long data, int nbits)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(36);
|
||||
|
||||
// Start
|
||||
mark(RC5_T1);
|
||||
space(RC5_T1);
|
||||
mark(RC5_T1);
|
||||
|
||||
// Data
|
||||
for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) {
|
||||
if (data & mask) {
|
||||
space(RC5_T1); // 1 is space, then mark
|
||||
mark(RC5_T1);
|
||||
} else {
|
||||
mark(RC5_T1);
|
||||
space(RC5_T1);
|
||||
}
|
||||
}
|
||||
|
||||
space(0); // Always end with the LED off
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef DECODE_RC5
|
||||
long IRrecv::decodeRC5 (decode_results *results)
|
||||
{
|
||||
if (irparams.rawlen < MIN_RC5_SAMPLES + 2) return false ;
|
||||
int offset = 1; // Skip gap space
|
||||
long data = 0;
|
||||
int used = 0;
|
||||
// Get start bits
|
||||
if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ;
|
||||
if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return false ;
|
||||
if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ;
|
||||
int nbits;
|
||||
for (nbits = 0; offset < irparams.rawlen; nbits++) {
|
||||
int levelA = getRClevel(results, &offset, &used, RC5_T1);
|
||||
int levelB = getRClevel(results, &offset, &used, RC5_T1);
|
||||
|
||||
if (levelA == SPACE && levelB == MARK) data = (data << 1) | 1 ; // 1 bit
|
||||
else if (levelA == MARK && levelB == SPACE) data <<= 1 ; // zero bit
|
||||
else return false ;
|
||||
}
|
||||
|
||||
// Success
|
||||
results->bits = nbits;
|
||||
results->value = data;
|
||||
results->decode_type = RC5;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
// RRRR CCCC 6666
|
||||
// R R C 6
|
||||
// RRRR C 6666
|
||||
// R R C 6 6
|
||||
// R R CCCC 666
|
||||
//
|
||||
// NB : Caller needs to take care of flipping the toggle bit
|
||||
//
|
||||
#define MIN_RC6_SAMPLES 1
|
||||
#define RC6_HDR_MARK 2666
|
||||
#define RC6_HDR_SPACE 889
|
||||
#define RC6_T1 444
|
||||
#define RC6_RPT_LENGTH 46000
|
||||
|
||||
#ifdef SEND_RC6
|
||||
void IRsend::sendRC6 (unsigned long data, int nbits)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(36);
|
||||
|
||||
// Header
|
||||
mark(RC6_HDR_MARK);
|
||||
space(RC6_HDR_SPACE);
|
||||
|
||||
// Start bit
|
||||
mark(RC6_T1);
|
||||
space(RC6_T1);
|
||||
|
||||
// Data
|
||||
for (unsigned long i = 1, mask = 1 << (nbits - 1); mask; i++, mask >>= 1) {
|
||||
// The fourth bit we send is a "double width trailer bit"
|
||||
int t = (i == 4) ? (RC6_T1 * 2) : (RC6_T1) ;
|
||||
if (data & mask) {
|
||||
mark(t);
|
||||
space(t);
|
||||
} else {
|
||||
space(t);
|
||||
mark(t);
|
||||
}
|
||||
}
|
||||
|
||||
space(0); // Always end with the LED off
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef DECODE_RC6
|
||||
long IRrecv::decodeRC6 (decode_results *results)
|
||||
{
|
||||
if (results->rawlen < MIN_RC6_SAMPLES) return false ;
|
||||
int offset = 1; // Skip first space
|
||||
|
||||
// Initial mark
|
||||
if (!MATCH_MARK(results->rawbuf[offset], RC6_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], RC6_HDR_SPACE)) return false ;
|
||||
offset++;
|
||||
|
||||
long data = 0;
|
||||
int used = 0;
|
||||
|
||||
// Get start bit (1)
|
||||
if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return false ;
|
||||
if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return false ;
|
||||
int nbits;
|
||||
for (nbits = 0; offset < results->rawlen; nbits++) {
|
||||
int levelA, levelB; // Next two levels
|
||||
levelA = getRClevel(results, &offset, &used, RC6_T1);
|
||||
if (nbits == 3) {
|
||||
// T bit is double wide; make sure second half matches
|
||||
if (levelA != getRClevel(results, &offset, &used, RC6_T1)) return false;
|
||||
}
|
||||
levelB = getRClevel(results, &offset, &used, RC6_T1);
|
||||
if (nbits == 3) {
|
||||
// T bit is double wide; make sure second half matches
|
||||
if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return false;
|
||||
}
|
||||
if (levelA == MARK && levelB == SPACE) data = (data << 1) | 1 ; // 1-bit (reversed compared to RC5)
|
||||
else if (levelA == SPACE && levelB == MARK) data <<= 1 ; // zero bit
|
||||
else return false ; // Error
|
||||
}
|
||||
|
||||
// Success
|
||||
results->bits = nbits;
|
||||
results->value = data;
|
||||
results->decode_type = RC6;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
94
ir_Samsung.cpp
Normal file
94
ir_Samsung.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// SSSS AAA MMM SSSS U U N N GGGG
|
||||
// S A A M M M S U U NN N G
|
||||
// SSS AAAAA M M M SSS U U N N N G GG
|
||||
// S A A M M S U U N NN G G
|
||||
// SSSS A A M M SSSS UUU N N GGG
|
||||
//==============================================================================
|
||||
|
||||
#define SAMSUNG_BITS 32
|
||||
#define SAMSUNG_HDR_MARK 5000
|
||||
#define SAMSUNG_HDR_SPACE 5000
|
||||
#define SAMSUNG_BIT_MARK 560
|
||||
#define SAMSUNG_ONE_SPACE 1600
|
||||
#define SAMSUNG_ZERO_SPACE 560
|
||||
#define SAMSUNG_RPT_SPACE 2250
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef SEND_SAMSUNG
|
||||
void IRsend::sendSAMSUNG (unsigned long data, int nbits)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(38);
|
||||
|
||||
// Header
|
||||
mark(SAMSUNG_HDR_MARK);
|
||||
space(SAMSUNG_HDR_SPACE);
|
||||
|
||||
// Data
|
||||
for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) {
|
||||
if (data & mask) {
|
||||
mark(SAMSUNG_BIT_MARK);
|
||||
space(SAMSUNG_ONE_SPACE);
|
||||
} else {
|
||||
mark(SAMSUNG_BIT_MARK);
|
||||
space(SAMSUNG_ZERO_SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
// Footer
|
||||
mark(SAMSUNG_BIT_MARK);
|
||||
space(0); // Always end with the LED off
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
// SAMSUNGs have a repeat only 4 items long
|
||||
//
|
||||
#ifdef DECODE_SAMSUNG
|
||||
long IRrecv::decodeSAMSUNG (decode_results *results)
|
||||
{
|
||||
long data = 0;
|
||||
int offset = 1; // Skip first space
|
||||
|
||||
// Initial mark
|
||||
if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
|
||||
// Check for repeat
|
||||
if (irparams.rawlen == 4 &&
|
||||
MATCH_SPACE(results->rawbuf[offset], SAMSUNG_RPT_SPACE) &&
|
||||
MATCH_MARK(results->rawbuf[offset+1], SAMSUNG_BIT_MARK)) {
|
||||
results->bits = 0;
|
||||
results->value = REPEAT;
|
||||
results->decode_type = SAMSUNG;
|
||||
return true;
|
||||
}
|
||||
if (irparams.rawlen < 2 * SAMSUNG_BITS + 4) return false ;
|
||||
|
||||
// Initial space
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) return false ;
|
||||
offset++;
|
||||
|
||||
for (int i = 0; i < SAMSUNG_BITS; i++) {
|
||||
if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_BIT_MARK)) return false ;
|
||||
|
||||
offset++;
|
||||
|
||||
if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ONE_SPACE)) data = (data << 1) | 1 ;
|
||||
else if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ZERO_SPACE)) data <<= 1 ;
|
||||
else return false ;
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Success
|
||||
results->bits = SAMSUNG_BITS;
|
||||
results->value = data;
|
||||
results->decode_type = SAMSUNG;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
79
ir_Sanyo.cpp
Normal file
79
ir_Sanyo.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// SSSS AAA N N Y Y OOO
|
||||
// S A A NN N Y Y O O
|
||||
// SSS AAAAA N N N Y O O
|
||||
// S A A N NN Y O O
|
||||
// SSSS A A N N Y OOO
|
||||
//==============================================================================
|
||||
|
||||
// I think this is a Sanyo decoder: Serial = SA 8650B
|
||||
// Looks like Sony except for timings, 48 chars of data and time/space different
|
||||
|
||||
#define SANYO_BITS 12
|
||||
|
||||
#define SANYO_HDR_MARK 3500 // seen range 3500
|
||||
#define SANYO_HDR_SPACE 950 // seen 950
|
||||
#define SANYO_ONE_MARK 2400 // seen 2400
|
||||
#define SANYO_ZERO_MARK 700 // seen 700
|
||||
#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
||||
#define SANYO_RPT_LENGTH 45000
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef DECODE_SANYO
|
||||
long IRrecv::decodeSanyo (decode_results *results)
|
||||
{
|
||||
long data = 0;
|
||||
if (irparams.rawlen < 2 * SANYO_BITS + 2) return false ;
|
||||
int offset = 0; // Skip first space
|
||||
// Initial space
|
||||
|
||||
#if 0
|
||||
// Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay
|
||||
Serial.print("IR Gap: ");
|
||||
Serial.println( results->rawbuf[offset]);
|
||||
Serial.println( "test against:");
|
||||
Serial.println(results->rawbuf[offset]);
|
||||
#endif
|
||||
|
||||
if (results->rawbuf[offset] < SANYO_DOUBLE_SPACE_USECS) {
|
||||
// Serial.print("IR Gap found: ");
|
||||
results->bits = 0;
|
||||
results->value = REPEAT;
|
||||
results->decode_type = SANYO;
|
||||
return true;
|
||||
}
|
||||
offset++;
|
||||
|
||||
// Initial mark
|
||||
if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
|
||||
// Skip Second Mark
|
||||
if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
|
||||
while (offset + 1 < irparams.rawlen) {
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], SANYO_HDR_SPACE)) break ;
|
||||
offset++;
|
||||
if (MATCH_MARK(results->rawbuf[offset], SANYO_ONE_MARK)) data = (data << 1) | 1 ;
|
||||
else if (MATCH_MARK(results->rawbuf[offset], SANYO_ZERO_MARK)) data <<= 1 ;
|
||||
else return false ;
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Success
|
||||
results->bits = (offset - 1) / 2;
|
||||
if (results->bits < 12) {
|
||||
results->bits = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
results->value = data;
|
||||
results->decode_type = SANYO;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
71
ir_Sharp.cpp
Normal file
71
ir_Sharp.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// SSSS H H AAA RRRR PPPP
|
||||
// S H H A A R R P P
|
||||
// SSS HHHHH AAAAA RRRR PPPP
|
||||
// S H H A A R R P
|
||||
// SSSS H H A A R R P
|
||||
//==============================================================================
|
||||
|
||||
// Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand )
|
||||
//
|
||||
// The send function has the necessary repeat built in because of the need to
|
||||
// invert the signal.
|
||||
//
|
||||
// Sharp protocol documentation:
|
||||
// http://www.sbprojects.com/knowledge/ir/sharp.htm
|
||||
//
|
||||
// Here is the LIRC file I found that seems to match the remote codes from the
|
||||
// oscilloscope:
|
||||
// Sharp LCD TV:
|
||||
// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA
|
||||
|
||||
#define SHARP_BITS 15
|
||||
|
||||
#define SHARP_BIT_MARK 245
|
||||
#define SHARP_ONE_SPACE 1805
|
||||
#define SHARP_ZERO_SPACE 795
|
||||
#define SHARP_GAP 600000
|
||||
#define SHARP_TOGGLE_MASK 0x3FF
|
||||
#define SHARP_RPT_SPACE 3000
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef SEND_SHARP
|
||||
void IRsend::sendSharpRaw (unsigned long data, int nbits)
|
||||
{
|
||||
unsigned long invertdata = data ^ SHARP_TOGGLE_MASK;
|
||||
enableIROut(38);
|
||||
|
||||
// Sending codes in bursts of 3 (normal, inverted, normal) makes transmission
|
||||
// much more reliable. That's the exact behaviour of CD-S6470 remote control.
|
||||
for (int n = 0; n < 3; n++) {
|
||||
for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) {
|
||||
if (data & mask) {
|
||||
mark(SHARP_BIT_MARK);
|
||||
space(SHARP_ONE_SPACE);
|
||||
} else {
|
||||
mark(SHARP_BIT_MARK);
|
||||
space(SHARP_ZERO_SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
mark(SHARP_BIT_MARK);
|
||||
space(SHARP_ZERO_SPACE);
|
||||
delay(40);
|
||||
|
||||
data = data ^ SHARP_TOGGLE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// Sharp send compatible with data obtained through decodeSharp()
|
||||
// ^^^^^^^^^^^^^ FUNCTION MISSING!
|
||||
//
|
||||
void IRsend::sendSharp (unsigned int address, unsigned int command)
|
||||
{
|
||||
sendSharpRaw((address << 10) | (command << 2) | 2, 15);
|
||||
}
|
||||
|
||||
#endif
|
||||
95
ir_Sony.cpp
Normal file
95
ir_Sony.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// SSSS OOO N N Y Y
|
||||
// S O O NN N Y Y
|
||||
// SSS O O N N N Y
|
||||
// S O O N NN Y
|
||||
// SSSS OOO N N Y
|
||||
//==============================================================================
|
||||
|
||||
#define SONY_BITS 12
|
||||
#define SONY_HDR_MARK 2400
|
||||
#define SONY_HDR_SPACE 600
|
||||
#define SONY_ONE_MARK 1200
|
||||
#define SONY_ZERO_MARK 600
|
||||
#define SONY_RPT_LENGTH 45000
|
||||
#define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef SEND_SONY
|
||||
void IRsend::sendSony (unsigned long data, int nbits)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(40);
|
||||
|
||||
// Header
|
||||
mark(SONY_HDR_MARK);
|
||||
space(SONY_HDR_SPACE);
|
||||
|
||||
// Data
|
||||
for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) {
|
||||
if (data & mask) {
|
||||
mark(SONY_ONE_MARK);
|
||||
space(SONY_HDR_SPACE);
|
||||
} else {
|
||||
mark(SONY_ZERO_MARK);
|
||||
space(SONY_HDR_SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
// We will have ended with LED off
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef DECODE_SONY
|
||||
long IRrecv::decodeSony (decode_results *results)
|
||||
{
|
||||
long data = 0;
|
||||
if (irparams.rawlen < 2 * SONY_BITS + 2) return false ;
|
||||
int offset = 0; // Dont skip first space, check its size
|
||||
|
||||
// Some Sony's deliver repeats fast after first
|
||||
// unfortunately can't spot difference from of repeat from two fast clicks
|
||||
if (results->rawbuf[offset] < SONY_DOUBLE_SPACE_USECS) {
|
||||
// Serial.print("IR Gap found: ");
|
||||
results->bits = 0;
|
||||
results->value = REPEAT;
|
||||
|
||||
# ifdef DECODE_SANYO
|
||||
results->decode_type = SANYO;
|
||||
# else
|
||||
results->decode_type = UNKNOWN;
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
offset++;
|
||||
|
||||
// Initial mark
|
||||
if (!MATCH_MARK(results->rawbuf[offset], SONY_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
|
||||
while (offset + 1 < irparams.rawlen) {
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], SONY_HDR_SPACE)) break ;
|
||||
offset++;
|
||||
if (MATCH_MARK(results->rawbuf[offset], SONY_ONE_MARK)) data = (data << 1) | 1 ;
|
||||
else if (MATCH_MARK(results->rawbuf[offset], SONY_ZERO_MARK)) data <<= 1 ;
|
||||
else return false ;
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Success
|
||||
results->bits = (offset - 1) / 2;
|
||||
if (results->bits < 12) {
|
||||
results->bits = 0;
|
||||
return false;
|
||||
}
|
||||
results->value = data;
|
||||
results->decode_type = SONY;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
96
ir_Whynter.cpp
Normal file
96
ir_Whynter.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// W W H H Y Y N N TTTTT EEEEE RRRRR
|
||||
// W W H H Y Y NN N T E R R
|
||||
// W W W HHHHH Y N N N T EEE RRRR
|
||||
// W W W H H Y N NN T E R R
|
||||
// WWW H H Y N N T EEEEE R R
|
||||
//==============================================================================
|
||||
|
||||
#define WHYNTER_BITS 32
|
||||
#define WHYNTER_HDR_MARK 2850
|
||||
#define WHYNTER_HDR_SPACE 2850
|
||||
#define WHYNTER_BIT_MARK 750
|
||||
#define WHYNTER_ONE_MARK 750
|
||||
#define WHYNTER_ONE_SPACE 2150
|
||||
#define WHYNTER_ZERO_MARK 750
|
||||
#define WHYNTER_ZERO_SPACE 750
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef SEND_WHYNTER
|
||||
void IRsend::sendWhynter (unsigned long data, int nbits)
|
||||
{
|
||||
// Set IR carrier frequency
|
||||
enableIROut(38);
|
||||
|
||||
// Start
|
||||
mark(WHYNTER_ZERO_MARK);
|
||||
space(WHYNTER_ZERO_SPACE);
|
||||
|
||||
// Header
|
||||
mark(WHYNTER_HDR_MARK);
|
||||
space(WHYNTER_HDR_SPACE);
|
||||
|
||||
// Data
|
||||
for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) {
|
||||
if (data & mask) {
|
||||
mark(WHYNTER_ONE_MARK);
|
||||
space(WHYNTER_ONE_SPACE);
|
||||
} else {
|
||||
mark(WHYNTER_ZERO_MARK);
|
||||
space(WHYNTER_ZERO_SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
// Footer
|
||||
mark(WHYNTER_ZERO_MARK);
|
||||
space(WHYNTER_ZERO_SPACE); // Always end with the LED off
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
#ifdef DECODE_WHYNTER
|
||||
long IRrecv::decodeWhynter (decode_results *results)
|
||||
{
|
||||
long data = 0;
|
||||
|
||||
if (irparams.rawlen < 2 * WHYNTER_BITS + 6) return false ;
|
||||
|
||||
int offset = 1; // skip initial space
|
||||
|
||||
// sequence begins with a bit mark and a zero space
|
||||
if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return false ;
|
||||
offset++;
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE)) return false ;
|
||||
offset++;
|
||||
|
||||
// header mark and space
|
||||
if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_HDR_MARK)) return false ;
|
||||
offset++;
|
||||
if (!MATCH_SPACE(results->rawbuf[offset], WHYNTER_HDR_SPACE)) return false ;
|
||||
offset++;
|
||||
|
||||
// data bits
|
||||
for (int i = 0; i < WHYNTER_BITS; i++) {
|
||||
if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return false ;
|
||||
offset++;
|
||||
|
||||
if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ONE_SPACE)) data = (data << 1) | 1 ;
|
||||
else if (MATCH_SPACE(results->rawbuf[offset],WHYNTER_ZERO_SPACE)) data <<= 1 ;
|
||||
else return false ;
|
||||
offset++;
|
||||
}
|
||||
|
||||
// trailing mark
|
||||
if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return false ;
|
||||
|
||||
// Success
|
||||
results->bits = WHYNTER_BITS;
|
||||
results->value = data;
|
||||
results->decode_type = WHYNTER;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user