From 9ba6628f04c21d26181d4211d752482220294782 Mon Sep 17 00:00:00 2001 From: PaulStoffregen Date: Sun, 20 Jan 2013 06:48:13 -0800 Subject: [PATCH 001/768] Add support for Teensy 3.0 --- IRremote.cpp | 4 ++-- IRremoteInt.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 21a5acb87..79546aaa2 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -225,7 +225,7 @@ void IRsend::mark(int time) { // Sends an IR mark for the specified number of microseconds. // The mark output is modulated at the PWM frequency. TIMER_ENABLE_PWM; // Enable pin 3 PWM output - delayMicroseconds(time); + if (time > 0) delayMicroseconds(time); } /* Leave pin off for time (given in microseconds) */ @@ -233,7 +233,7 @@ void IRsend::space(int time) { // Sends an IR space for the specified number of microseconds. // A space is no output, so the PWM output is disabled. TIMER_DISABLE_PWM; // Disable pin 3 PWM output - delayMicroseconds(time); + if (time > 0) delayMicroseconds(time); } void IRsend::enableIROut(int khz) { diff --git a/IRremoteInt.h b/IRremoteInt.h index e6bcd00e7..c083b50e2 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -46,6 +46,10 @@ //#define IR_USE_TIMER3 // tx = pin 9 #define IR_USE_TIMER4_HS // tx = pin 10 +// Teensy 3.0 +#elif defined(__MK20DX128__) + #define IR_USE_TIMER_CMT // tx = pin 5 + // Teensy++ 1.0 & 2.0 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) //#define IR_USE_TIMER1 // tx = pin 25 @@ -426,6 +430,54 @@ extern volatile irparams_t irparams; #endif +// defines for special carrier modulator timer +#elif defined(IR_USE_TIMER_CMT) +#define TIMER_RESET ({ \ + uint8_t tmp = CMT_MSC; \ + CMT_CMD2 = 30; \ +}) +#define TIMER_ENABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_DSE|PORT_PCR_SRE +#define TIMER_DISABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE +#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) +#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) +#define TIMER_INTR_NAME cmt_isr +#ifdef ISR +#undef ISR +#endif +#define ISR(f) void f(void) +#if F_BUS == 48000000 +#define CMT_PPS_VAL 5 +#else +#define CMT_PPS_VAL 2 +#endif +#define TIMER_CONFIG_KHZ(val) ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ + CMT_PPS = CMT_PPS_VAL; \ + CMT_CGH1 = 2667 / val; \ + CMT_CGL1 = 5333 / val; \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = 0; \ + CMT_OC = 0x60; \ + CMT_MSC = 0x01; \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + CMT_PPS = CMT_PPS_VAL; \ + CMT_CGH1 = 1; \ + CMT_CGL1 = 1; \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = 19; \ + CMT_OC = 0; \ + CMT_MSC = 0x03; \ +}) +#define TIMER_PWM_PIN 5 + + #else // unknown timer #error "Internal code configuration error, no known IR_USE_TIMER# defined\n" #endif From acc1b6b86e9e7d69cd1b2a535b6a9f2f317fbaa7 Mon Sep 17 00:00:00 2001 From: Xun Yang Date: Fri, 14 Jun 2013 17:15:28 +0200 Subject: [PATCH 002/768] Fixed MATCH, MATCH_MARK, MATCH_SPACE when both IRremoteInt.h and IRremoteInt.h are included in sketch --- IRremote.cpp | 5 +++++ IRremoteInt.h | 7 ------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 21a5acb87..0b7092c9d 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -65,6 +65,11 @@ int MATCH_SPACE(int measured_ticks, int desired_us) { Serial.println(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); return measured_ticks >= TICKS_LOW(desired_us - MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS); } +#else +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 void IRsend::sendNEC(unsigned long data, int nbits) diff --git a/IRremoteInt.h b/IRremoteInt.h index e6bcd00e7..0efdbddd3 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -172,13 +172,6 @@ #define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK)) #define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1)) -#ifndef DEBUG -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 - // receiver states #define STATE_IDLE 2 #define STATE_MARK 3 From a6bf23d71d0bcacfad667c71a2f012472496f928 Mon Sep 17 00:00:00 2001 From: Joshua Noble Date: Thu, 18 Jul 2013 11:21:21 -0700 Subject: [PATCH 003/768] adding Attiny84 --- IRremoteInt.h | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index e6bcd00e7..719fca820 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -61,6 +61,9 @@ #elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) #define IR_USE_TIMER1 // tx = pin 9 +#elif defined( __AVR_ATtinyX4__ ) + #define IR_USE_TIMER1 // tx = pin 6 + // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc #else //#define IR_USE_TIMER1 // tx = pin 9 @@ -90,24 +93,24 @@ // Pulse parms are *50-100 for the Mark and *50+100 for the space // First MARK is the one after the long gap // pulse parameters in usec -#define NEC_HDR_MARK 9000 -#define NEC_HDR_SPACE 4500 -#define NEC_BIT_MARK 560 -#define NEC_ONE_SPACE 1600 -#define NEC_ZERO_SPACE 560 -#define NEC_RPT_SPACE 2250 - -#define SONY_HDR_MARK 2400 -#define SONY_HDR_SPACE 600 -#define SONY_ONE_MARK 1200 -#define SONY_ZERO_MARK 600 +#define NEC_HDR_MARK 9000 +#define NEC_HDR_SPACE 4500 +#define NEC_BIT_MARK 560 +#define NEC_ONE_SPACE 1600 +#define NEC_ZERO_SPACE 560 +#define NEC_RPT_SPACE 2250 + +#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 // SA 8650B -#define SANYO_HDR_MARK 3500 // seen range 3500 -#define SANYO_HDR_SPACE 950 // seen 950 -#define SANYO_ONE_MARK 2400 // seen 2400 +#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 @@ -115,21 +118,21 @@ // 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_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 -#define RC5_T1 889 -#define RC5_RPT_LENGTH 46000 +#define RC5_T1 889 +#define RC5_RPT_LENGTH 46000 -#define RC6_HDR_MARK 2666 -#define RC6_HDR_SPACE 889 -#define RC6_T1 444 -#define RC6_RPT_LENGTH 46000 +#define RC6_HDR_MARK 2666 +#define RC6_HDR_SPACE 889 +#define RC6_T1 444 +#define RC6_RPT_LENGTH 46000 #define SHARP_BIT_MARK 245 #define SHARP_ONE_SPACE 1805 @@ -291,6 +294,8 @@ extern volatile irparams_t irparams; #define TIMER_PWM_PIN 11 /* Arduino Mega */ #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) #define TIMER_PWM_PIN 13 /* Sanguino */ +#elif defined(__AVR_ATtinyX4__) +#define TIMER_PWM_PIN 6 /* ATTiny84 */ #else #define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */ #endif From e22a69116415232a03c18d7cd517b6da0e2bd6ac Mon Sep 17 00:00:00 2001 From: Joshua Noble Date: Tue, 23 Jul 2013 16:50:20 -0700 Subject: [PATCH 004/768] updating timer interrupt name for Attiny84 --- IRremoteInt.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index 719fca820..3ff620b59 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -274,7 +274,13 @@ extern volatile irparams_t irparams; #define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) #define TIMER_DISABLE_INTR (TIMSK1 = 0) #endif -#define TIMER_INTR_NAME TIMER1_COMPA_vect + +#if defined(__AVR_ATtinyX4__) + #define TIMER_INTR_NAME TIM1_COMPA_vect +#else + #define TIMER_INTR_NAME TIMER1_COMPA_vect +#endif + #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR1A = _BV(WGM11); \ From 1c57c6a9b00033b9b0a72ef32b3b322c9e10a436 Mon Sep 17 00:00:00 2001 From: "lumbric (antares)" Date: Thu, 20 Feb 2014 21:35:50 +0100 Subject: [PATCH 005/768] adding Panasonic and JVC types for IRrecord --- examples/IRrecord/IRrecord.ino | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/examples/IRrecord/IRrecord.ino b/examples/IRrecord/IRrecord.ino index caf86de3d..bf290fa39 100644 --- a/examples/IRrecord/IRrecord.ino +++ b/examples/IRrecord/IRrecord.ino @@ -80,6 +80,12 @@ void storeCode(decode_results *results) { else if (codeType == SONY) { Serial.print("Received SONY: "); } + else if (codeType == PANASONIC) { + Serial.print("Received PANASONIC: "); + } + else if (codeType == JVC) { + Serial.print("Received JVC: "); + } else if (codeType == RC5) { Serial.print("Received RC5: "); } @@ -114,6 +120,16 @@ void sendCode(int repeat) { Serial.print("Sent Sony "); Serial.println(codeValue, HEX); } + else if (codeType == PANASONIC) { + irsend.sendPanasonic(codeValue, codeLen); + Serial.print("Sent Panasonic"); + Serial.println(codeValue, HEX); + } + else if (codeType == JVC) { + irsend.sendPanasonic(codeValue, codeLen); + Serial.print("Sent JVC"); + Serial.println(codeValue, HEX); + } else if (codeType == RC5 || codeType == RC6) { if (!repeat) { // Flip the toggle bit for a new button press From 0de2d18bdbb18cf6068584f33d1c76fea3dac4df Mon Sep 17 00:00:00 2001 From: sstefanov Date: Fri, 23 May 2014 12:20:39 +0300 Subject: [PATCH 006/768] Added Samsung protocol --- IRremote.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ IRremote.h | 3 ++ IRremoteInt.h | 75 +++++++++++++++++++++-------------------------- 3 files changed, 117 insertions(+), 42 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 21a5acb87..5f394cce4 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -65,6 +65,11 @@ int MATCH_SPACE(int measured_ticks, int desired_us) { Serial.println(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); return measured_ticks >= TICKS_LOW(desired_us - MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS); } +#else +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 void IRsend::sendNEC(unsigned long data, int nbits) @@ -221,6 +226,27 @@ void IRsend::sendJVC(unsigned long data, int nbits, int repeat) mark(JVC_BIT_MARK); space(0); } + +void IRsend::sendSAMSUNG(unsigned long data, int nbits) +{ + enableIROut(38); + mark(SAMSUNG_HDR_MARK); + space(SAMSUNG_HDR_SPACE); + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + mark(SAMSUNG_BIT_MARK); + space(SAMSUNG_ONE_SPACE); + } + else { + mark(SAMSUNG_BIT_MARK); + space(SAMSUNG_ZERO_SPACE); + } + data <<= 1; + } + mark(SAMSUNG_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. @@ -439,6 +465,12 @@ int IRrecv::decode(decode_results *results) { if (decodeJVC(results)) { return DECODED; } +#ifdef DEBUG + Serial.println("Attempting SAMSUNG decode"); +#endif + if (decodeSAMSUNG(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. @@ -896,6 +928,55 @@ long IRrecv::decodeJVC(decode_results *results) { return DECODED; } +// SAMSUNGs have a repeat only 4 items long +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 ERR; + } + 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 DECODED; + } + if (irparams.rawlen < 2 * SAMSUNG_BITS + 4) { + return ERR; + } + // Initial space + if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) { + return ERR; + } + offset++; + for (int i = 0; i < SAMSUNG_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_BIT_MARK)) { + return ERR; + } + 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 ERR; + } + offset++; + } + // Success + results->bits = SAMSUNG_BITS; + results->value = data; + results->decode_type = SAMSUNG; + return DECODED; +} + /* ----------------------------------------------------------------------- * hashdecode - decode an arbitrary IR code. * Instead of decoding using a standard encoding scheme diff --git a/IRremote.h b/IRremote.h index 0e5fdf2cd..b6267112d 100644 --- a/IRremote.h +++ b/IRremote.h @@ -45,6 +45,7 @@ class decode_results { #define JVC 8 #define SANYO 9 #define MITSUBISHI 10 +#define SAMSUNG 11 #define UNKNOWN -1 // Decoded value for NEC when a repeat code is received @@ -70,6 +71,7 @@ class IRrecv long decodeRC6(decode_results *results); long decodePanasonic(decode_results *results); long decodeJVC(decode_results *results); + long decodeSAMSUNG(decode_results *results); long decodeHash(decode_results *results); int compare(unsigned int oldval, unsigned int newval); @@ -100,6 +102,7 @@ class IRsend 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 sendSAMSUNG(unsigned long data, int nbits); void enableIROut(int khz); VIRTUAL void mark(int usec); VIRTUAL void space(int usec); diff --git a/IRremoteInt.h b/IRremoteInt.h index 3ff620b59..d4cc63f63 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -61,9 +61,6 @@ #elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) #define IR_USE_TIMER1 // tx = pin 9 -#elif defined( __AVR_ATtinyX4__ ) - #define IR_USE_TIMER1 // tx = pin 6 - // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc #else //#define IR_USE_TIMER1 // tx = pin 9 @@ -93,24 +90,24 @@ // Pulse parms are *50-100 for the Mark and *50+100 for the space // First MARK is the one after the long gap // pulse parameters in usec -#define NEC_HDR_MARK 9000 -#define NEC_HDR_SPACE 4500 -#define NEC_BIT_MARK 560 -#define NEC_ONE_SPACE 1600 -#define NEC_ZERO_SPACE 560 -#define NEC_RPT_SPACE 2250 - -#define SONY_HDR_MARK 2400 -#define SONY_HDR_SPACE 600 -#define SONY_ONE_MARK 1200 -#define SONY_ZERO_MARK 600 +#define NEC_HDR_MARK 9000 +#define NEC_HDR_SPACE 4500 +#define NEC_BIT_MARK 560 +#define NEC_ONE_SPACE 1600 +#define NEC_ZERO_SPACE 560 +#define NEC_RPT_SPACE 2250 + +#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 // SA 8650B -#define SANYO_HDR_MARK 3500 // seen range 3500 -#define SANYO_HDR_SPACE 950 // seen 950 -#define SANYO_ONE_MARK 2400 // seen 2400 +#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 @@ -118,21 +115,21 @@ // 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_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 -#define RC5_T1 889 -#define RC5_RPT_LENGTH 46000 +#define RC5_T1 889 +#define RC5_RPT_LENGTH 46000 -#define RC6_HDR_MARK 2666 -#define RC6_HDR_SPACE 889 -#define RC6_T1 444 -#define RC6_RPT_LENGTH 46000 +#define RC6_HDR_MARK 2666 +#define RC6_HDR_SPACE 889 +#define RC6_T1 444 +#define RC6_RPT_LENGTH 46000 #define SHARP_BIT_MARK 245 #define SHARP_ONE_SPACE 1805 @@ -162,6 +159,14 @@ #define JVC_ZERO_SPACE 550 #define JVC_RPT_LENGTH 60000 +#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 + + #define SHARP_BITS 15 #define DISH_BITS 16 @@ -175,13 +180,6 @@ #define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK)) #define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1)) -#ifndef DEBUG -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 - // receiver states #define STATE_IDLE 2 #define STATE_MARK 3 @@ -216,6 +214,7 @@ extern volatile irparams_t irparams; #define MIN_RC6_SAMPLES 1 #define PANASONIC_BITS 48 #define JVC_BITS 16 +#define SAMSUNG_BITS 32 @@ -274,13 +273,7 @@ extern volatile irparams_t irparams; #define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) #define TIMER_DISABLE_INTR (TIMSK1 = 0) #endif - -#if defined(__AVR_ATtinyX4__) - #define TIMER_INTR_NAME TIM1_COMPA_vect -#else - #define TIMER_INTR_NAME TIMER1_COMPA_vect -#endif - +#define TIMER_INTR_NAME TIMER1_COMPA_vect #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR1A = _BV(WGM11); \ @@ -300,8 +293,6 @@ extern volatile irparams_t irparams; #define TIMER_PWM_PIN 11 /* Arduino Mega */ #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) #define TIMER_PWM_PIN 13 /* Sanguino */ -#elif defined(__AVR_ATtinyX4__) -#define TIMER_PWM_PIN 6 /* ATTiny84 */ #else #define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */ #endif From 0af9c5a9e901faeac8c54377464bc35c0dad8deb Mon Sep 17 00:00:00 2001 From: vk2tds Date: Mon, 7 Jul 2014 08:27:15 +1000 Subject: [PATCH 007/768] Update IRremoteInt.h --- IRremoteInt.h | 1 + 1 file changed, 1 insertion(+) diff --git a/IRremoteInt.h b/IRremoteInt.h index d4cc63f63..8c4316315 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -214,6 +214,7 @@ extern volatile irparams_t irparams; #define MIN_RC6_SAMPLES 1 #define PANASONIC_BITS 48 #define JVC_BITS 16 +#define LG_BITS 28 #define SAMSUNG_BITS 32 From 66c3b1f47cda899f44f1c1cb4879adb47725d6f5 Mon Sep 17 00:00:00 2001 From: Darryl Smith Date: Thu, 10 Jul 2014 08:27:36 +1000 Subject: [PATCH 008/768] Updates for LG Air Conditioner Remote --- IRremote.cpp | 53 ++++++++++++++++++++++++++++++ IRremote.h | 3 ++ IRremoteInt.h | 7 ++++ examples/IRrecvDump/IRrecvDump.ino | 4 +++ 4 files changed, 67 insertions(+) diff --git a/IRremote.cpp b/IRremote.cpp index 5f394cce4..deb23073e 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -14,6 +14,7 @@ * 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) + * LG added by Darryl Smith (based on the JVC protocol) */ #include "IRremote.h" @@ -459,6 +460,12 @@ int IRrecv::decode(decode_results *results) { if (decodePanasonic(results)) { return DECODED; } +#ifdef DEBUG + Serial.println("Attempting LG decode"); +#endif + if (decodeLG(results)) { + return DECODED; + } #ifdef DEBUG Serial.println("Attempting JVC decode"); #endif @@ -876,6 +883,52 @@ long IRrecv::decodePanasonic(decode_results *results) { results->bits = PANASONIC_BITS; return DECODED; } + +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 ERR; + } + offset++; + if (irparams.rawlen < 2 * LG_BITS + 1 ) { + return ERR; + } + // Initial space + if (!MATCH_SPACE(results->rawbuf[offset], LG_HDR_SPACE)) { + return ERR; + } + offset++; + for (int i = 0; i < LG_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) { + return ERR; + } + 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 ERR; + } + offset++; + } + //Stop bit + if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)){ + return ERR; + } + // Success + results->bits = LG_BITS; + results->value = data; + results->decode_type = LG; + return DECODED; +} + + long IRrecv::decodeJVC(decode_results *results) { long data = 0; int offset = 1; // Skip first space diff --git a/IRremote.h b/IRremote.h index b6267112d..e4463e891 100644 --- a/IRremote.h +++ b/IRremote.h @@ -10,6 +10,7 @@ * 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) +* LG added by Darryl Smith (based on the JVC protocol) */ #ifndef IRremote_h @@ -46,6 +47,7 @@ class decode_results { #define SANYO 9 #define MITSUBISHI 10 #define SAMSUNG 11 +#define LG 12 #define UNKNOWN -1 // Decoded value for NEC when a repeat code is received @@ -70,6 +72,7 @@ class IRrecv long decodeRC5(decode_results *results); long decodeRC6(decode_results *results); long decodePanasonic(decode_results *results); + long decodeLG(decode_results *results); long decodeJVC(decode_results *results); long decodeSAMSUNG(decode_results *results); long decodeHash(decode_results *results); diff --git a/IRremoteInt.h b/IRremoteInt.h index 8c4316315..418904e41 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -159,6 +159,13 @@ #define JVC_ZERO_SPACE 550 #define JVC_RPT_LENGTH 60000 +#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 + #define SAMSUNG_HDR_MARK 5000 #define SAMSUNG_HDR_SPACE 5000 #define SAMSUNG_BIT_MARK 560 diff --git a/examples/IRrecvDump/IRrecvDump.ino b/examples/IRrecvDump/IRrecvDump.ino index 6afcb0fbb..d66aee2c6 100644 --- a/examples/IRrecvDump/IRrecvDump.ino +++ b/examples/IRrecvDump/IRrecvDump.ino @@ -5,6 +5,7 @@ * 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) + * LG added by Darryl Smith (based on the JVC protocol) */ #include @@ -48,6 +49,9 @@ void dump(decode_results *results) { Serial.print(results->panasonicAddress,HEX); Serial.print(" Value: "); } + else if (results->decode_type == LG) { + Serial.print("Decoded LG: "); + } else if (results->decode_type == JVC) { Serial.print("Decoded JVC: "); } From 18591b037c638c1c611c8ae4b8c2a0caefe9c977 Mon Sep 17 00:00:00 2001 From: P THE AWESOME Date: Mon, 4 Aug 2014 16:19:07 -0500 Subject: [PATCH 009/768] Add delay to IRrecvDemo Loop preventing duplicates Prevents duplicates in serial when button was only pressed once. --- examples/IRrecvDemo/IRrecvDemo.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/IRrecvDemo/IRrecvDemo.ino b/examples/IRrecvDemo/IRrecvDemo.ino index f7b45b893..3a498328d 100644 --- a/examples/IRrecvDemo/IRrecvDemo.ino +++ b/examples/IRrecvDemo/IRrecvDemo.ino @@ -25,4 +25,5 @@ void loop() { Serial.println(results.value, HEX); irrecv.resume(); // Receive the next value } + delay(100); } From 95f93e639eba2fa111a4d45b2c277003d2730790 Mon Sep 17 00:00:00 2001 From: Piotr Dobrowolski Date: Wed, 17 Sep 2014 21:30:36 +0200 Subject: [PATCH 010/768] Cleanup sendSharp and fix reliability --- IRremote.cpp | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index deb23073e..2c0f90dab 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -1109,35 +1109,27 @@ linked LIRC file. void IRsend::sendSharp(unsigned long data, int nbits) { unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; enableIROut(38); - for (int i = 0; i < nbits; i++) { - if (data & 0x4000) { - mark(SHARP_BIT_MARK); - space(SHARP_ONE_SPACE); - } - else { - mark(SHARP_BIT_MARK); - space(SHARP_ZERO_SPACE); - } - data <<= 1; - } - - mark(SHARP_BIT_MARK); - space(SHARP_ZERO_SPACE); - delay(46); - for (int i = 0; i < nbits; i++) { - if (invertdata & 0x4000) { - mark(SHARP_BIT_MARK); - space(SHARP_ONE_SPACE); - } - else { - mark(SHARP_BIT_MARK); - space(SHARP_ZERO_SPACE); + + // 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 (int i = 1 << (nbits-1); i > 0; i>>=1) { + if (data & i) { + mark(SHARP_BIT_MARK); + space(SHARP_ONE_SPACE); + } + else { + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + } } - invertdata <<= 1; + + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + delay(40); + + data = data ^ SHARP_TOGGLE_MASK; } - mark(SHARP_BIT_MARK); - space(SHARP_ZERO_SPACE); - delay(46); } void IRsend::sendDISH(unsigned long data, int nbits) From 5719e7c00fc71997f5ca4b366280ff9b26770904 Mon Sep 17 00:00:00 2001 From: Piotr Dobrowolski Date: Wed, 17 Sep 2014 21:31:53 +0200 Subject: [PATCH 011/768] sendSharp API change to make it compatible with decodeSharp --- IRremote.cpp | 11 +++++++---- IRremote.h | 8 ++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 2c0f90dab..f8ccedb09 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -1106,8 +1106,7 @@ i.e. use 0x1C10 instead of 0x0000000000001C10 which is listed in the linked LIRC file. */ -void IRsend::sendSharp(unsigned long data, int nbits) { - unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; +void IRsend::sendSharpRaw(unsigned long data, int nbits) { enableIROut(38); // Sending codes in bursts of 3 (normal, inverted, normal) makes transmission @@ -1132,8 +1131,12 @@ void IRsend::sendSharp(unsigned long data, int nbits) { } } -void IRsend::sendDISH(unsigned long data, int nbits) -{ +// Sharp send compatible with data obtained through decodeSharp +void IRsend::sendSharp(unsigned int address, unsigned int command) { + sendSharpRaw((address << 10) | (command << 2) | 2, 15); +} + +void IRsend::sendDISH(unsigned long data, int nbits) { enableIROut(56); mark(DISH_HDR_MARK); space(DISH_HDR_SPACE); diff --git a/IRremote.h b/IRremote.h index e4463e891..17d5e81b1 100644 --- a/IRremote.h +++ b/IRremote.h @@ -28,7 +28,10 @@ class decode_results { public: int decode_type; // NEC, SONY, RC5, UNKNOWN - unsigned int panasonicAddress; // This is only used for decoding Panasonic data + union { // This is used for decoding Panasonic and Sharp data + unsigned int panasonicAddress; + unsigned int sharpAddress; + }; unsigned long value; // Decoded value int bits; // Number of bits in decoded value volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks @@ -101,7 +104,8 @@ class IRsend void sendRC5(unsigned long data, int nbits); void sendRC6(unsigned long data, int nbits); void sendDISH(unsigned long data, int nbits); - void sendSharp(unsigned long data, int nbits); + void sendSharp(unsigned int address, unsigned int command); + void sendSharpRaw(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: From b04b31232feb10ddbb466e224dc471ff49bc0a9f Mon Sep 17 00:00:00 2001 From: Piotr Dobrowolski Date: Wed, 17 Sep 2014 23:21:54 +0200 Subject: [PATCH 012/768] Update keywords.txt --- keywords.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/keywords.txt b/keywords.txt index 74010c419..6e77362ef 100644 --- a/keywords.txt +++ b/keywords.txt @@ -28,6 +28,7 @@ sendRC5 KEYWORD2 sendRC6 KEYWORD2 sendDISH KEYWORD2 sendSharp KEYWORD2 +sendSharpRaw KEYWORD2 sendPanasonic KEYWORD2 sendJVC KEYWORD2 @@ -47,4 +48,4 @@ SHARP LITERAL1 PANASONIC LITERAL1 JVC LITERAL1 UNKNOWN LITERAL1 -REPEAT LITERAL1 \ No newline at end of file +REPEAT LITERAL1 From e947f0924e28e75fced86949db6d1babb2fcb198 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 25 Sep 2014 14:18:56 +0300 Subject: [PATCH 013/768] PlatformIO-based manifest file Web: http://platformio.ikravets.com/#!/lib/show/Arduino-IRremote Docs: http://docs.platformio.ikravets.com/en/latest/librarymanager/index.html --- library.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 library.json diff --git a/library.json b/library.json new file mode 100644 index 000000000..2edf145a9 --- /dev/null +++ b/library.json @@ -0,0 +1,10 @@ +{ + "name": "Arduino-IRremote", + "keywords": "infrared, ir, remote", + "description": "Send and receive infrared signals with multiple protocols", + "repository": + { + "type": "git", + "url": "https://github.com/shirriff/Arduino-IRremote.git" + } +} From a3cdf402d7acea346f9010ce431d7ff301d2b469 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 20 Oct 2014 11:41:09 +0300 Subject: [PATCH 014/768] Avoid trademark issues with library name Added frameworks and platforms fields --- library.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 2edf145a9..3a29ecde4 100644 --- a/library.json +++ b/library.json @@ -1,10 +1,12 @@ { - "name": "Arduino-IRremote", + "name": "IRremote", "keywords": "infrared, ir, remote", "description": "Send and receive infrared signals with multiple protocols", "repository": { "type": "git", "url": "https://github.com/shirriff/Arduino-IRremote.git" - } + }, + "frameworks": "arduino", + "platforms": "atmelavr" } From 02f206e19c9152c7efb68e0f8d67a3807dd99318 Mon Sep 17 00:00:00 2001 From: Colton Schlosser Date: Sat, 10 Jan 2015 14:17:43 -0600 Subject: [PATCH 015/768] Add LG keyword --- keywords.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/keywords.txt b/keywords.txt index 6e77362ef..8eab9d17d 100644 --- a/keywords.txt +++ b/keywords.txt @@ -47,5 +47,6 @@ DISH LITERAL1 SHARP LITERAL1 PANASONIC LITERAL1 JVC LITERAL1 +LG LITERAL1 UNKNOWN LITERAL1 REPEAT LITERAL1 From 0fce321c9487d4a55ca8f93a89a4beeeb6890765 Mon Sep 17 00:00:00 2001 From: Francesco Meschia Date: Fri, 6 Feb 2015 21:29:56 -0800 Subject: [PATCH 016/768] Added Whynter A/C remote protocol Tested with Whynter ARC-110WD --- IRremote.cpp | 87 ++++++++++++++++++++++++++++++ IRremote.h | 14 ++--- IRremoteInt.h | 10 ++++ examples/IRrecvDump/IRrecvDump.ino | 3 ++ 4 files changed, 108 insertions(+), 6 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 888f5e2e3..af5a3c8a0 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -15,6 +15,7 @@ * * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) * LG added by Darryl Smith (based on the JVC protocol) + * Whynter A/C ARC-110WD added by Francesco Meschia */ #include "IRremote.h" @@ -93,6 +94,27 @@ void IRsend::sendNEC(unsigned long data, int nbits) space(0); } +void IRsend::sendWhynter(unsigned long data, int nbits) { + enableIROut(38); + mark(WHYNTER_ZERO_MARK); + space(WHYNTER_ZERO_SPACE); + mark(WHYNTER_HDR_MARK); + space(WHYNTER_HDR_SPACE); + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + mark(WHYNTER_ONE_MARK); + space(WHYNTER_ONE_SPACE); + } + else { + mark(WHYNTER_ZERO_MARK); + space(WHYNTER_ZERO_SPACE); + } + data <<= 1; + } + mark(WHYNTER_ZERO_MARK); + space(WHYNTER_ZERO_SPACE); +} + void IRsend::sendSony(unsigned long data, int nbits) { enableIROut(40); mark(SONY_HDR_MARK); @@ -478,6 +500,12 @@ int IRrecv::decode(decode_results *results) { if (decodeSAMSUNG(results)) { return DECODED; } +#ifdef DEBUG + Serial.println("Attempting Whynter decode"); +#endif + if (decodeWhynter(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. @@ -590,6 +618,65 @@ long IRrecv::decodeSony(decode_results *results) { return DECODED; } +long IRrecv::decodeWhynter(decode_results *results) { + long data = 0; + + if (irparams.rawlen < 2 * WHYNTER_BITS + 6) { + return ERR; + } + + 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 ERR; + } + offset++; + if (!MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE)) { + return ERR; + } + offset++; + + // header mark and space + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_HDR_MARK)) { + return ERR; + } + offset++; + if (!MATCH_SPACE(results->rawbuf[offset], WHYNTER_HDR_SPACE)) { + return ERR; + } + offset++; + + // data bits + for (int i = 0; i < WHYNTER_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) { + return ERR; + } + 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 ERR; + } + offset++; + } + + // trailing mark + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) { + return ERR; + } + // Success + results->bits = WHYNTER_BITS; + results->value = data; + results->decode_type = WHYNTER; + return DECODED; +} + + // I think this is a Sanyo decoder - serial = SA 8650B // Looks like Sony except for timings, 48 chars of data and time/space different long IRrecv::decodeSanyo(decode_results *results) { diff --git a/IRremote.h b/IRremote.h index 17d5e81b1..e4b274eef 100644 --- a/IRremote.h +++ b/IRremote.h @@ -10,7 +10,8 @@ * 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) -* LG added by Darryl Smith (based on the JVC protocol) + * LG added by Darryl Smith (based on the JVC protocol) + * Whynter A/C ARC-110WD added by Francesco Meschia */ #ifndef IRremote_h @@ -21,7 +22,7 @@ // If DEBUG is defined, a lot of debugging output will be printed during decoding. // TEST must be defined for the IRtest unittests to work. It will make some // methods virtual, which will be slightly slower, which is why it is optional. -// #define DEBUG +//#define DEBUG // #define TEST // Results returned from the decoder @@ -51,6 +52,7 @@ class decode_results { #define MITSUBISHI 10 #define SAMSUNG 11 #define LG 12 +#define WHYNTER 13 #define UNKNOWN -1 // Decoded value for NEC when a repeat code is received @@ -78,11 +80,11 @@ class IRrecv long decodeLG(decode_results *results); long decodeJVC(decode_results *results); long decodeSAMSUNG(decode_results *results); + long decodeWhynter(decode_results *results); long decodeHash(decode_results *results); int compare(unsigned int oldval, unsigned int newval); -} -; +} ; // Only used for testing; can remove virtual for shorter code #ifdef TEST @@ -95,6 +97,7 @@ class IRsend { public: IRsend() {} + void sendWhynter(unsigned long data, int nbits); void sendNEC(unsigned long data, int nbits); void sendSony(unsigned long data, int nbits); // Neither Sanyo nor Mitsubishi send is implemented yet @@ -113,8 +116,7 @@ class IRsend void enableIROut(int khz); VIRTUAL void mark(int usec); VIRTUAL void space(int usec); -} -; +} ; // Some useful constants diff --git a/IRremoteInt.h b/IRremoteInt.h index e5653277f..fa6c73911 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -11,6 +11,7 @@ * 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) + * Whynter A/C ARC-110WD added by Francesco Meschia */ #ifndef IRremoteint_h @@ -94,6 +95,14 @@ // Pulse parms are *50-100 for the Mark and *50+100 for the space // First MARK is the one after the long gap // pulse parameters in usec +#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 + #define NEC_HDR_MARK 9000 #define NEC_HDR_SPACE 4500 #define NEC_BIT_MARK 560 @@ -227,6 +236,7 @@ extern volatile irparams_t irparams; #define JVC_BITS 16 #define LG_BITS 28 #define SAMSUNG_BITS 32 +#define WHYNTER_BITS 32 diff --git a/examples/IRrecvDump/IRrecvDump.ino b/examples/IRrecvDump/IRrecvDump.ino index d66aee2c6..0f8e4f13b 100644 --- a/examples/IRrecvDump/IRrecvDump.ino +++ b/examples/IRrecvDump/IRrecvDump.ino @@ -55,6 +55,9 @@ void dump(decode_results *results) { else if (results->decode_type == JVC) { Serial.print("Decoded JVC: "); } + else if (results->decode_type == WHYNTER) { + Serial.print("Decoded Whynter: "); + } Serial.print(results->value, HEX); Serial.print(" ("); Serial.print(results->bits, DEC); From b3e3ced302e6c3c108675a735960c0f919e6c3e5 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 7 Mar 2015 16:53:43 -0600 Subject: [PATCH 017/768] Fix #41 Fixes #41 by implementing the solution by @canondale --- IRremoteInt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index e5653277f..cdcdefa72 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -97,7 +97,7 @@ #define NEC_HDR_MARK 9000 #define NEC_HDR_SPACE 4500 #define NEC_BIT_MARK 560 -#define NEC_ONE_SPACE 1600 +#define NEC_ONE_SPACE 1692 #define NEC_ZERO_SPACE 560 #define NEC_RPT_SPACE 2250 From 9d94115974291314fc211b9ea613a42540eddff4 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 7 Mar 2015 17:22:29 -0600 Subject: [PATCH 018/768] Revamped README --- README.md | 21 +++++++++++++++++++++ readme | 14 -------------- 2 files changed, 21 insertions(+), 14 deletions(-) create mode 100644 README.md delete mode 100644 readme diff --git a/README.md b/README.md new file mode 100644 index 000000000..bc507a2c4 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# IRremote Arduino Library +This library enables you to send and receive using infra red signals on an arduino + +## Version - 1.00 +This is the master branch and includes the most stable version. For the latest-mostly stable version please try teh beta branch. + +## Installation +1. Click "Download ZIP" +2. Extract the downloaded zip file +3. Rename the extracted folder from "Arduino-IRremote" to "IRremote" +4. Move this folder to your libraries directory + +## Contributing +If you want to contribute to this project: +- Report bugs and errors +- Ask for enhancements +- Create issues and pull requests +- Tell other people about this library + +## Copyright +Copyright 2009-2012 Ken Shirriff diff --git a/readme b/readme deleted file mode 100644 index 3de652611..000000000 --- a/readme +++ /dev/null @@ -1,14 +0,0 @@ -This is the IRremote library for the Arduino. - -To download from github (http://github.com/shirriff/Arduino-IRremote), click on the "Downloads" link in the upper right, click "Download as zip", and get a zip file. Unzip it and rename the directory shirriff-Arduino-IRremote-nnn to IRremote - -To install, move the downloaded IRremote directory to: -arduino-1.x/libraries/IRremote -where arduino-1.x is your Arduino installation directory - -After installation you should have files such as: -arduino-1.x/libraries/IRremote/IRremote.cpp - -For details on the library see the Wiki on github or the blog post http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html - -Copyright 2009-2012 Ken Shirriff From 4fed49fca61bc7adf2cec630ae671ccb00bef307 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 7 Mar 2015 17:24:50 -0600 Subject: [PATCH 019/768] Fixed typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bc507a2c4..121d8452c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # IRremote Arduino Library -This library enables you to send and receive using infra red signals on an arduino +This library enables you to send and receive using infra-red signals on an arduino ## Version - 1.00 -This is the master branch and includes the most stable version. For the latest-mostly stable version please try teh beta branch. +This is the master branch and includes the most stable version. For the latest-mostly stable version please try the beta branch. ## Installation 1. Click "Download ZIP" From 4610e7eb0e9371fcd6756c93489370a110cd06cb Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 7 Mar 2015 18:10:22 -0600 Subject: [PATCH 020/768] NEC_ONE_SPACE should actually be 1690 --- IRremoteInt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index 8ea516f1f..53167c299 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -106,7 +106,7 @@ #define NEC_HDR_MARK 9000 #define NEC_HDR_SPACE 4500 #define NEC_BIT_MARK 560 -#define NEC_ONE_SPACE 1692 +#define NEC_ONE_SPACE 1690 #define NEC_ZERO_SPACE 560 #define NEC_RPT_SPACE 2250 From 9235051c6a3e98f26857053cde860c59f38866da Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 7 Mar 2015 23:33:59 -0600 Subject: [PATCH 021/768] Readme is branch independent --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 121d8452c..952b7aa53 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ This library enables you to send and receive using infra-red signals on an arduino ## Version - 1.00 -This is the master branch and includes the most stable version. For the latest-mostly stable version please try the beta branch. ## Installation 1. Click "Download ZIP" From 12f7ef1d28507fd9c71575981420b312f4df4359 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 8 Mar 2015 16:03:41 -0600 Subject: [PATCH 022/768] Add contributors to readme --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 952b7aa53..cf97a7c90 100644 --- a/README.md +++ b/README.md @@ -16,5 +16,18 @@ If you want to contribute to this project: - Create issues and pull requests - Tell other people about this library +## Contributors +These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions. + +- [z3t0](github.com/z3t0) : Active Contributor and currently also the main contributor. + * Email: zetoslab@gmail.com + * Skype: polarised16 +- [shirriff](github.com/shirriff) : Owner of repository and creator of library. +- [Informatic](github.com/Informatic) : Active contributor +- [fmeschia](github.com/fmeschia) : Active contributor +- [PaullStoffregen](github.com/paullstroffregen) : Active contributor + +Note: This list is being updated constantly so please let @z3t0 know if you have been missed. + ## Copyright Copyright 2009-2012 Ken Shirriff From c0446fd6593fa612fdab0837edf4148f09430667 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 8 Mar 2015 16:07:40 -0600 Subject: [PATCH 023/768] Fixed broken links --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cf97a7c90..388f379c8 100644 --- a/README.md +++ b/README.md @@ -19,15 +19,15 @@ If you want to contribute to this project: ## Contributors These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions. -- [z3t0](github.com/z3t0) : Active Contributor and currently also the main contributor. +- [z3t0](https://github.com/z3t0) : Active Contributor and currently also the main contributor. * Email: zetoslab@gmail.com * Skype: polarised16 -- [shirriff](github.com/shirriff) : Owner of repository and creator of library. -- [Informatic](github.com/Informatic) : Active contributor -- [fmeschia](github.com/fmeschia) : Active contributor -- [PaullStoffregen](github.com/paullstroffregen) : Active contributor +- [shirriff](https://github.com/shirriff) : Owner of repository and creator of library. +- [Informatic](https://github.com/Informatic) : Active contributor +- [fmeschia](https://github.com/fmeschia) : Active contributor +- [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor -Note: This list is being updated constantly so please let @z3t0 know if you have been missed. +Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. ## Copyright Copyright 2009-2012 Ken Shirriff From bed4cc5c97b2d5ad440b5523bc9c28ca99354b54 Mon Sep 17 00:00:00 2001 From: Christian Musa Date: Wed, 30 Apr 2014 16:28:31 -0300 Subject: [PATCH 024/768] Added Aiwa protocol (remote control RC-T501). Added Aiwa protocol (remote control RC-T501) based on lirc file. Updated IRrecvDump example, added SendDemo example (AiwaRCT501SendDemo). --- IRremote.cpp | 116 ++++++++++++++++++ IRremote.h | 3 + IRremoteInt.h | 14 +++ .../AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino | 25 ++++ examples/IRrecvDump/IRrecvDump.ino | 4 + 5 files changed, 162 insertions(+) create mode 100644 examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino diff --git a/IRremote.cpp b/IRremote.cpp index af5a3c8a0..b617559b1 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -506,6 +506,13 @@ int IRrecv::decode(decode_results *results) { if (decodeWhynter(results)) { return DECODED; } +// Aiwa RC-T501 +#ifdef DEBUG + Serial.println("Attempting Aiwa RC-T501 decode"); +#endif + if (decodeAiwaRCT501(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. @@ -1117,6 +1124,65 @@ long IRrecv::decodeSAMSUNG(decode_results *results) { return DECODED; } +/** + * Aiwa system + * Remote control RC-T501 + * Lirc file http://lirc.sourceforge.net/remotes/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 ERR; + } + + // Check HDR + if(!MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_HDR_MARK)) { + return ERR; + } + offset++; + + // Check HDR space + if(!MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_HDR_SPACE)) { + return ERR; + } + 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 ERR; + } + + // 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 { + // End of one & zero detected + break; + } + offset++; + } + + results->bits = (offset - 1) / 2; + if(results->bits < 42) { + return ERR; + } + results->value = data; + results->decode_type = AIWA_RC_T501; + return DECODED; +} + /* ----------------------------------------------------------------------- * hashdecode - decode an arbitrary IR code. * Instead of decoding using a standard encoding scheme @@ -1239,3 +1305,53 @@ void IRsend::sendDISH(unsigned long data, int nbits) { data <<= 1; } } + +/** + * Aiwa system + * Remote control RC-T501 + * Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 + * + */ +void IRsend::sendAiwaRCT501(int code) { + // PRE-DATA, 26 bits, 0x227EEC0 + long int pre = 0x227EEC0; + int i; + + enableIROut(AIWA_RC_T501_HZ); + + // HDR mark + HDR space + mark(AIWA_RC_T501_HDR_MARK); + space(AIWA_RC_T501_HDR_SPACE); + + // Skip leading zero's + pre <<= 6; + // Send pre-data + for(i=0; i < 26; i++) { + mark(AIWA_RC_T501_BIT_MARK); + if(pre & TOPBIT) { + space(AIWA_RC_T501_ONE_SPACE); + } else { + space(AIWA_RC_T501_ZERO_SPACE); + } + pre <<= 1; + } + + // Skip firts code bit + code <<= 1; + // Send code + for(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; + } + // 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); +} \ No newline at end of file diff --git a/IRremote.h b/IRremote.h index e4b274eef..271f17e7e 100644 --- a/IRremote.h +++ b/IRremote.h @@ -53,6 +53,7 @@ class decode_results { #define SAMSUNG 11 #define LG 12 #define WHYNTER 13 +#define AIWA_RC_T501 14 #define UNKNOWN -1 // Decoded value for NEC when a repeat code is received @@ -81,6 +82,7 @@ class IRrecv long decodeJVC(decode_results *results); long decodeSAMSUNG(decode_results *results); long decodeWhynter(decode_results *results); + long decodeAiwaRCT501(decode_results *results); long decodeHash(decode_results *results); int compare(unsigned int oldval, unsigned int newval); @@ -111,6 +113,7 @@ class IRsend void sendSharpRaw(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. + void sendAiwaRCT501(int code); // private: void sendSAMSUNG(unsigned long data, int nbits); void enableIROut(int khz); diff --git a/IRremoteInt.h b/IRremoteInt.h index 53167c299..674ee8dfb 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -190,6 +190,20 @@ #define SHARP_BITS 15 #define DISH_BITS 16 +// AIWA RC T501 +// 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 + + #define TOLERANCE 25 // percent tolerance in measurements #define LTOL (1.0 - TOLERANCE/100.) #define UTOL (1.0 + TOLERANCE/100.) diff --git a/examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino b/examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino new file mode 100644 index 000000000..694bacce0 --- /dev/null +++ b/examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino @@ -0,0 +1,25 @@ +/* + * 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 + */ + +#include "IRremote.h" + +#define POWER 0x7F80 + +IRsend irsend; + +void setup() { + Serial.begin(9600); + Serial.println("Arduino Ready"); +} + +void loop() { + if (Serial.read() != -1) { + irsend.sendAiwaRCT501(POWER); + delay(60); // Optional + } +} diff --git a/examples/IRrecvDump/IRrecvDump.ino b/examples/IRrecvDump/IRrecvDump.ino index 0f8e4f13b..a1ba3b2e4 100644 --- a/examples/IRrecvDump/IRrecvDump.ino +++ b/examples/IRrecvDump/IRrecvDump.ino @@ -54,6 +54,10 @@ void dump(decode_results *results) { } else if (results->decode_type == JVC) { Serial.print("Decoded JVC: "); + + } + else if (results->decode_type == AIWA_RC_T501) { + Serial.print("Decoded AIWA RC T501: "); } else if (results->decode_type == WHYNTER) { Serial.print("Decoded Whynter: "); From 18f5aa639b7c2048e03cfde9b7935e0c12094591 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 8 Mar 2015 17:30:36 -0600 Subject: [PATCH 025/768] Added GitHub Page --- index.html | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 index.html diff --git a/index.html b/index.html new file mode 100644 index 000000000..126a8007d --- /dev/null +++ b/index.html @@ -0,0 +1,7 @@ + + + +

Hello World

+

I'm hosted with GitHub Pages.

+ + From c35f7219dd10665b483ecd799eddbefd5fb27d2a Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 8 Mar 2015 17:35:21 -0600 Subject: [PATCH 026/768] removed index --- index.html | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 index.html diff --git a/index.html b/index.html new file mode 100644 index 000000000..126a8007d --- /dev/null +++ b/index.html @@ -0,0 +1,7 @@ + + + +

Hello World

+

I'm hosted with GitHub Pages.

+ + From 3256c847b23d5237bfb631966c533ad3182e3c7e Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 8 Mar 2015 17:37:06 -0600 Subject: [PATCH 027/768] remove index (for real) --- index.html | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 index.html diff --git a/index.html b/index.html deleted file mode 100644 index 126a8007d..000000000 --- a/index.html +++ /dev/null @@ -1,7 +0,0 @@ - - - -

Hello World

-

I'm hosted with GitHub Pages.

- - From 9c2064c5b4027f6d5c406e0fb90f52a731c88ae2 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 8 Mar 2015 17:38:20 -0600 Subject: [PATCH 028/768] add crash7 to contributors list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 388f379c8..a333ce3ee 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ These are the active contributors of this project that you may contact if there - [Informatic](https://github.com/Informatic) : Active contributor - [fmeschia](https://github.com/fmeschia) : Active contributor - [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor +- [crash7](https://github.com/crash7) : Active contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. From 3b16c12b59cdfa7ef8687f0f43bf7ba761b34787 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 8 Mar 2015 19:40:16 -0600 Subject: [PATCH 029/768] Added Neco777 to contributors --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a333ce3ee..4f3fc2aa5 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ These are the active contributors of this project that you may contact if there - [fmeschia](https://github.com/fmeschia) : Active contributor - [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor - [crash7](https://github.com/crash7) : Active contributor +- [Neco777](https://github.com/neco777) : Active contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. From 7b08532e47cbd117aea110eabb99e411d85f1a3f Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 8 Mar 2015 19:42:47 -0600 Subject: [PATCH 030/768] Moved contributors to a different file --- Contributors.md | 16 ++++++++++++++++ README.md | 14 +------------- 2 files changed, 17 insertions(+), 13 deletions(-) create mode 100644 Contributors.md diff --git a/Contributors.md b/Contributors.md new file mode 100644 index 000000000..2af31262e --- /dev/null +++ b/Contributors.md @@ -0,0 +1,16 @@ +## Contributors +These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions. + +- [z3t0](https://github.com/z3t0) : Active Contributor and currently also the main contributor. + * Email: zetoslab@gmail.com + * Skype: polarised16 +- [shirriff](https://github.com/shirriff) : Owner of repository and creator of library. +- [Informatic](https://github.com/Informatic) : Active contributor +- [fmeschia](https://github.com/fmeschia) : Active contributor +- [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor +- [crash7](https://github.com/crash7) : Active contributor +- [Neco777](https://github.com/neco777) : Active contributor + +Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. + + diff --git a/README.md b/README.md index 4f3fc2aa5..086736c7c 100644 --- a/README.md +++ b/README.md @@ -17,19 +17,7 @@ If you want to contribute to this project: - Tell other people about this library ## Contributors -These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions. - -- [z3t0](https://github.com/z3t0) : Active Contributor and currently also the main contributor. - * Email: zetoslab@gmail.com - * Skype: polarised16 -- [shirriff](https://github.com/shirriff) : Owner of repository and creator of library. -- [Informatic](https://github.com/Informatic) : Active contributor -- [fmeschia](https://github.com/fmeschia) : Active contributor -- [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor -- [crash7](https://github.com/crash7) : Active contributor -- [Neco777](https://github.com/neco777) : Active contributor - -Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. +Check [here](Contributors.md) ## Copyright Copyright 2009-2012 Ken Shirriff From 2768ddc676eecb52b24e5d4c8b79ed79e3de732d Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 9 Mar 2015 13:01:25 -0600 Subject: [PATCH 031/768] Releases can be found on the releases page. --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 086736c7c..00e77e658 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,10 @@ This library enables you to send and receive using infra-red signals on an ardui ## Version - 1.00 ## Installation -1. Click "Download ZIP" -2. Extract the downloaded zip file -3. Rename the extracted folder from "Arduino-IRremote" to "IRremote" -4. Move this folder to your libraries directory +1. Navigate to the [Releases](https://github.com/shirriff/Arduino-IRremote/releases) page. +2. Download the latest release. +3. Extract the zip file +4. Move the "IRremote" folder that has been extracted to your libraries directory. ## Contributing If you want to contribute to this project: From c1c6bd4199ec33ccf29d00d7d192b85700bb8d0f Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 9 Mar 2015 18:54:25 -0600 Subject: [PATCH 032/768] Added reference to GitHub page --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 00e77e658..8e4b1499c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # IRremote Arduino Library -This library enables you to send and receive using infra-red signals on an arduino +This library enables you to send and receive using infra-red signals on an arduino. + +Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more information. ## Version - 1.00 From 2ad1487c8d01033b59df2a48dcc06b6d9b018305 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 10 Mar 2015 15:43:13 -0600 Subject: [PATCH 033/768] Added Lauszus to contrib. --- Contributors.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Contributors.md b/Contributors.md index 2af31262e..e374e7cc4 100644 --- a/Contributors.md +++ b/Contributors.md @@ -10,6 +10,7 @@ These are the active contributors of this project that you may contact if there - [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor - [crash7](https://github.com/crash7) : Active contributor - [Neco777](https://github.com/neco777) : Active contributor +- [Lauszus](htps://github.com/lauszus) : Active contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. From c2bf981fe7a309b39e2fc30ce0d4edfed1dbdccb Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 10 Mar 2015 15:43:28 -0600 Subject: [PATCH 034/768] Update Contributors.md --- Contributors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Contributors.md b/Contributors.md index e374e7cc4..2bb8d9db9 100644 --- a/Contributors.md +++ b/Contributors.md @@ -10,7 +10,7 @@ These are the active contributors of this project that you may contact if there - [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor - [crash7](https://github.com/crash7) : Active contributor - [Neco777](https://github.com/neco777) : Active contributor -- [Lauszus](htps://github.com/lauszus) : Active contributor +- [Lauszus](https://github.com/lauszus) : Active contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. From 549d92d2f5dbecff9d78b1dac1cc30f1a1df06d1 Mon Sep 17 00:00:00 2001 From: sstefanov Date: Thu, 12 Mar 2015 14:49:48 +0200 Subject: [PATCH 035/768] Added possibility to exclude non-necessary libraries by comment lines in IRremote.h --- IRremote.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++-- IRremote.h | 52 +++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 2 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 5f394cce4..cb130fc06 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -72,6 +72,7 @@ int MATCH_SPACE(int measured_ticks, int desired_us) {return MATCH(measured_ticks // Debugging versions are in IRremote.cpp #endif +#ifdef IRsendNEC void IRsend::sendNEC(unsigned long data, int nbits) { enableIROut(38); @@ -91,7 +92,9 @@ void IRsend::sendNEC(unsigned long data, int nbits) mark(NEC_BIT_MARK); space(0); } +#endif +#ifdef IRsendSONY void IRsend::sendSony(unsigned long data, int nbits) { enableIROut(40); mark(SONY_HDR_MARK); @@ -109,7 +112,9 @@ void IRsend::sendSony(unsigned long data, int nbits) { data <<= 1; } } +#endif +#ifdef IRsendRAW void IRsend::sendRaw(unsigned int buf[], int len, int hz) { enableIROut(hz); @@ -123,7 +128,9 @@ void IRsend::sendRaw(unsigned int buf[], int len, int hz) } space(0); // Just to be sure } +#endif +#ifdef IRsendRC5 // Note: first bit must be a one (start bit) void IRsend::sendRC5(unsigned long data, int nbits) { @@ -145,7 +152,9 @@ void IRsend::sendRC5(unsigned long data, int nbits) } space(0); // Turn off at end } +#endif +#ifdef IRsendRC6 // Caller needs to take care of flipping the toggle bit void IRsend::sendRC6(unsigned long data, int nbits) { @@ -177,6 +186,9 @@ void IRsend::sendRC6(unsigned long data, int nbits) } space(0); // Turn off at end } +#endif + +#ifdef IRsendPANASONIC void IRsend::sendPanasonic(unsigned int address, unsigned long data) { enableIROut(35); mark(PANASONIC_HDR_MARK); @@ -204,6 +216,9 @@ void IRsend::sendPanasonic(unsigned int address, unsigned long data) { mark(PANASONIC_BIT_MARK); space(0); } +#endif + +#ifdef IRsendJVC void IRsend::sendJVC(unsigned long data, int nbits, int repeat) { enableIROut(38); @@ -226,7 +241,9 @@ void IRsend::sendJVC(unsigned long data, int nbits, int repeat) mark(JVC_BIT_MARK); space(0); } +#endif +#ifdef IRsendSAMSUNG void IRsend::sendSAMSUNG(unsigned long data, int nbits) { enableIROut(38); @@ -246,6 +263,7 @@ void IRsend::sendSAMSUNG(unsigned long data, int nbits) mark(SAMSUNG_BIT_MARK); space(0); } +#endif void IRsend::mark(int time) { // Sends an IR mark for the specified number of microseconds. @@ -417,60 +435,87 @@ int IRrecv::decode(decode_results *results) { if (irparams.rcvstate != STATE_STOP) { return ERR; } +#ifdef NEC #ifdef DEBUG Serial.println("Attempting NEC decode"); #endif if (decodeNEC(results)) { return DECODED; } +#endif + +#ifdef SONY #ifdef DEBUG Serial.println("Attempting Sony decode"); #endif if (decodeSony(results)) { return DECODED; } +#endif + +#ifdef SANYO #ifdef DEBUG Serial.println("Attempting Sanyo decode"); #endif if (decodeSanyo(results)) { return DECODED; } +#endif + +#ifdef MITSUBISHI #ifdef DEBUG Serial.println("Attempting Mitsubishi decode"); #endif if (decodeMitsubishi(results)) { return DECODED; } +#endif + +#ifdef RC5 #ifdef DEBUG Serial.println("Attempting RC5 decode"); #endif if (decodeRC5(results)) { return DECODED; } +#endif + +#ifdef RC6 #ifdef DEBUG Serial.println("Attempting RC6 decode"); #endif if (decodeRC6(results)) { return DECODED; } +#endif + +#ifdef PANASONIC #ifdef DEBUG Serial.println("Attempting Panasonic decode"); #endif if (decodePanasonic(results)) { return DECODED; } +#endif + +#ifdef JVC #ifdef DEBUG Serial.println("Attempting JVC decode"); #endif if (decodeJVC(results)) { return DECODED; } +#endif + +#ifdef SAMSUNG #ifdef DEBUG Serial.println("Attempting SAMSUNG decode"); #endif if (decodeSAMSUNG(results)) { return DECODED; } +#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. @@ -482,6 +527,7 @@ int IRrecv::decode(decode_results *results) { return ERR; } +#ifdef NEC // NECs have a repeat only 4 items long long IRrecv::decodeNEC(decode_results *results) { long data = 0; @@ -530,7 +576,9 @@ long IRrecv::decodeNEC(decode_results *results) { results->decode_type = NEC; return DECODED; } +#endif +#ifdef SONY long IRrecv::decodeSony(decode_results *results) { long data = 0; if (irparams.rawlen < 2 * SONY_BITS + 2) { @@ -544,7 +592,11 @@ long IRrecv::decodeSony(decode_results *results) { // Serial.print("IR Gap found: "); results->bits = 0; results->value = REPEAT; +#ifdef SANYO results->decode_type = SANYO; +#else + results->decode_type = UNKNOWN; +#endif return DECODED; } offset++; @@ -582,7 +634,9 @@ long IRrecv::decodeSony(decode_results *results) { results->decode_type = SONY; return DECODED; } +#endif +#ifdef SANYO // I think this is a Sanyo decoder - serial = SA 8650B // Looks like Sony except for timings, 48 chars of data and time/space different long IRrecv::decodeSanyo(decode_results *results) { @@ -646,7 +700,9 @@ long IRrecv::decodeSanyo(decode_results *results) { results->decode_type = SANYO; return DECODED; } +#endif +#ifdef MITSUBISHI // Looks like Sony except for timings, 48 chars of data and time/space different long IRrecv::decodeMitsubishi(decode_results *results) { // Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2); @@ -710,8 +766,9 @@ long IRrecv::decodeMitsubishi(decode_results *results) { results->decode_type = MITSUBISHI; return DECODED; } +#endif - +#if defined(RC5) || defined(RC6) // 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, @@ -757,7 +814,9 @@ int IRrecv::getRClevel(decode_results *results, int *offset, int *used, int t1) #endif return val; } +#endif +#ifdef RC5 long IRrecv::decodeRC5(decode_results *results) { if (irparams.rawlen < MIN_RC5_SAMPLES + 2) { return ERR; @@ -792,7 +851,9 @@ long IRrecv::decodeRC5(decode_results *results) { results->decode_type = RC5; return DECODED; } +#endif +#ifdef RC6 long IRrecv::decodeRC6(decode_results *results) { if (results->rawlen < MIN_RC6_SAMPLES) { return ERR; @@ -843,6 +904,9 @@ long IRrecv::decodeRC6(decode_results *results) { results->decode_type = RC6; return DECODED; } +#endif + +#ifdef PANASONIC long IRrecv::decodePanasonic(decode_results *results) { unsigned long long data = 0; int offset = 1; @@ -876,6 +940,9 @@ long IRrecv::decodePanasonic(decode_results *results) { results->bits = PANASONIC_BITS; return DECODED; } +#endif + +#ifdef JVC long IRrecv::decodeJVC(decode_results *results) { long data = 0; int offset = 1; // Skip first space @@ -927,7 +994,9 @@ long IRrecv::decodeJVC(decode_results *results) { results->decode_type = JVC; return DECODED; } +#endif +#ifdef SAMSUNG // SAMSUNGs have a repeat only 4 items long long IRrecv::decodeSAMSUNG(decode_results *results) { long data = 0; @@ -976,6 +1045,7 @@ long IRrecv::decodeSAMSUNG(decode_results *results) { results->decode_type = SAMSUNG; return DECODED; } +#endif /* ----------------------------------------------------------------------- * hashdecode - decode an arbitrary IR code. @@ -1052,7 +1122,7 @@ For the DISH codes, only send the last for characters of the hex. i.e. use 0x1C10 instead of 0x0000000000001C10 which is listed in the linked LIRC file. */ - +#ifdef IRsendSHARP void IRsend::sendSharp(unsigned long data, int nbits) { unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; enableIROut(38); @@ -1086,7 +1156,9 @@ void IRsend::sendSharp(unsigned long data, int nbits) { space(SHARP_ZERO_SPACE); delay(46); } +#endif +#ifdef IRsendDISH void IRsend::sendDISH(unsigned long data, int nbits) { enableIROut(56); @@ -1104,3 +1176,4 @@ void IRsend::sendDISH(unsigned long data, int nbits) data <<= 1; } } +#endif diff --git a/IRremote.h b/IRremote.h index b6267112d..2e7f71e90 100644 --- a/IRremote.h +++ b/IRremote.h @@ -34,6 +34,20 @@ class decode_results { int rawlen; // Number of records in rawbuf. }; +// Send types +#define IRsendNEC +#define IRsendSONY +#define IRsendRC5 +#define IRsendRC6 +#define IRsendDISH +#define IRsendSHARP +#define IRsendPANASONIC +#define IRsendJVC +#define IRsendSANYO +#define IRsendMITSUBISHI +#define IRsendSAMSUNG +#define IRsendRAW + // Values for decode_type #define NEC 1 #define SONY 2 @@ -63,15 +77,33 @@ class IRrecv private: // These are called by decode int getRClevel(decode_results *results, int *offset, int *used, int t1); +#ifdef NEC long decodeNEC(decode_results *results); +#endif +#ifdef SONY long decodeSony(decode_results *results); +#endif +#ifdef SANYO long decodeSanyo(decode_results *results); +#endif +#ifdef MITSUBISHI long decodeMitsubishi(decode_results *results); +#endif +#ifdef RC5 long decodeRC5(decode_results *results); +#endif +#ifdef RC6 long decodeRC6(decode_results *results); +#endif +#ifdef PANASONIC long decodePanasonic(decode_results *results); +#endif +#ifdef JVC long decodeJVC(decode_results *results); +#endif +#ifdef SAMSUNG long decodeSAMSUNG(decode_results *results); +#endif long decodeHash(decode_results *results); int compare(unsigned int oldval, unsigned int newval); @@ -89,20 +121,40 @@ class IRsend { public: IRsend() {} +#ifdef IRsendNEC void sendNEC(unsigned long data, int nbits); +#endif +#ifdef IRsendSONY void sendSony(unsigned long data, int nbits); // Neither Sanyo nor Mitsubishi send is implemented yet // void sendSanyo(unsigned long data, int nbits); // void sendMitsubishi(unsigned long data, int nbits); +#endif +#ifdef IRsendRAW void sendRaw(unsigned int buf[], int len, int hz); +#endif +#ifdef IRsendRC5 void sendRC5(unsigned long data, int nbits); +#endif +#ifdef IRsendRC6 void sendRC6(unsigned long data, int nbits); +#endif +#ifdef IRsendDISH void sendDISH(unsigned long data, int nbits); +#endif +#ifdef IRsendSHARP void sendSharp(unsigned long data, int nbits); +#endif +#ifdef IRsendPANASONIC void sendPanasonic(unsigned int address, unsigned long data); +#endif +#ifdef IRsendJVC 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: +#endif +#ifdef IRsendSAMSUNG void sendSAMSUNG(unsigned long data, int nbits); +#endif void enableIROut(int khz); VIRTUAL void mark(int usec); VIRTUAL void space(int usec); From 66d82da532041c5f4a3d06bfd43e6cbb50ddad72 Mon Sep 17 00:00:00 2001 From: joshua noble Date: Sun, 15 Mar 2015 19:41:46 -0700 Subject: [PATCH 036/768] Updating for device usage --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 8e4b1499c..4f59361ef 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,14 @@ Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more 3. Extract the zip file 4. Move the "IRremote" folder that has been extracted to your libraries directory. +## Usage + +We get a lot of support for different device types. To keep the size of the library manageable we're moving to a model where different device types use a #define statement, for instance: + +```#define SHARP``` + +You'd put this at the top of your sketch to include the sendSharp() and decodeSharp() methods in your code. This way your sketch only uses the Sharp functions but not the LG, JVC, Sony, etc functions, thus saving you program space that you might want to use for other things. This allows us to support lots of devices without making the library too big. + ## Contributing If you want to contribute to this project: - Report bugs and errors From 04420c9f5c69a2d84b13ef3ded64af17ca98fd84 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 16 Mar 2015 12:07:21 -0600 Subject: [PATCH 037/768] Add Aiwa protocol to keywords --- keywords.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/keywords.txt b/keywords.txt index 8eab9d17d..5bf5d1dcd 100644 --- a/keywords.txt +++ b/keywords.txt @@ -48,5 +48,6 @@ SHARP LITERAL1 PANASONIC LITERAL1 JVC LITERAL1 LG LITERAL1 +AIWA_RC_T501 UNKNOWN LITERAL1 REPEAT LITERAL1 From 96fa0f557acb1f54416f56778f092634c11c0931 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 16 Mar 2015 12:07:55 -0600 Subject: [PATCH 038/768] Quick fix for previous commit --- keywords.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keywords.txt b/keywords.txt index 5bf5d1dcd..808c7ea3f 100644 --- a/keywords.txt +++ b/keywords.txt @@ -48,6 +48,6 @@ SHARP LITERAL1 PANASONIC LITERAL1 JVC LITERAL1 LG LITERAL1 -AIWA_RC_T501 +AIWA_RC_T501 LITERAL1 UNKNOWN LITERAL1 REPEAT LITERAL1 From 4caca675ff2d3763273c238a11d16496155d415e Mon Sep 17 00:00:00 2001 From: jan-r Date: Sat, 4 Apr 2015 11:02:53 +0200 Subject: [PATCH 039/768] Fixed problem with interrupt enable/disable on ATmega8 Previously, when enabling or disabling interrupts on the ATmega8, the whole TIMSK register was overwritten. This disables all other timer interrupts (for Timer0 and Timer2). The fix takes care of that by selectively enabling/disabling the required OCIE1A flag. --- IRremoteInt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index 674ee8dfb..32281f8d7 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -303,8 +303,8 @@ extern volatile irparams_t irparams; #define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) #define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) #if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) - #define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE1A)) - #define TIMER_DISABLE_INTR (TIMSK = 0) + #define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) + #define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) #else #define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) #define TIMER_DISABLE_INTR (TIMSK1 = 0) From 675f9fe04225e63c9394a5752f6630764572c81c Mon Sep 17 00:00:00 2001 From: Levon Saldamli Date: Mon, 6 Apr 2015 17:16:27 +0200 Subject: [PATCH 040/768] Library properties for arduino 1.0.5 to recognize as library. --- library.properties | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 library.properties diff --git a/library.properties b/library.properties new file mode 100644 index 000000000..816a7f9ec --- /dev/null +++ b/library.properties @@ -0,0 +1,9 @@ +name=IRremote +version=1.0 +author=shirriff +maintainer=shirriff +sentence=Send and receive infrared signals with multiple protocols +paragraph=Send and receive infrared signals with multiple protocols +category=infrared +url=https://github.com/shirriff/Arduino-IRremote.git +architectures=* From d336bc541a239fdd43a4451fede9ad1b80f324e4 Mon Sep 17 00:00:00 2001 From: Levon Saldamli Date: Mon, 6 Apr 2015 18:17:53 +0200 Subject: [PATCH 041/768] Changed ifdefs for SEND and DECODE, created enum for decode_type_t. Corrected ifdef errors, issues #121, #122, #123). --- IRremote.cpp | 77 +++++++++++++++++++++++++++------------------ IRremote.h | 89 +++++++++++++++++++++++++++------------------------- 2 files changed, 93 insertions(+), 73 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 0ea262ed6..9389267e3 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -74,7 +74,7 @@ int MATCH_SPACE(int measured_ticks, int desired_us) {return MATCH(measured_ticks // Debugging versions are in IRremote.cpp #endif -#ifdef NEC +#ifdef SEND_NEC void IRsend::sendNEC(unsigned long data, int nbits) { enableIROut(38); @@ -96,7 +96,7 @@ void IRsend::sendNEC(unsigned long data, int nbits) } #endif -#ifdef WHYNTER +#ifdef SEND_WHYNTER void IRsend::sendWhynter(unsigned long data, int nbits) { enableIROut(38); mark(WHYNTER_ZERO_MARK); @@ -119,7 +119,7 @@ void IRsend::sendWhynter(unsigned long data, int nbits) { } #endif -#ifdef SONY +#ifdef SEND_SONY void IRsend::sendSony(unsigned long data, int nbits) { enableIROut(40); mark(SONY_HDR_MARK); @@ -153,6 +153,7 @@ void IRsend::sendRaw(unsigned int buf[], int len, int hz) space(0); // Just to be sure } +#ifdef SEND_RC5 // Note: first bit must be a one (start bit) void IRsend::sendRC5(unsigned long data, int nbits) { @@ -174,7 +175,9 @@ void IRsend::sendRC5(unsigned long data, int nbits) } space(0); // Turn off at end } +#endif +#ifdef SEND_RC6 // Caller needs to take care of flipping the toggle bit void IRsend::sendRC6(unsigned long data, int nbits) { @@ -206,8 +209,9 @@ void IRsend::sendRC6(unsigned long data, int nbits) } space(0); // Turn off at end } +#endif -#ifdef PANASONIC +#ifdef SEND_PANASONIC void IRsend::sendPanasonic(unsigned int address, unsigned long data) { enableIROut(35); mark(PANASONIC_HDR_MARK); @@ -237,7 +241,7 @@ void IRsend::sendPanasonic(unsigned int address, unsigned long data) { } #endif -#ifdef JVC +#ifdef SEND_JVC void IRsend::sendJVC(unsigned long data, int nbits, int repeat) { enableIROut(38); @@ -262,7 +266,7 @@ void IRsend::sendJVC(unsigned long data, int nbits, int repeat) } #endif -#ifdef SAMSUNG +#ifdef SEND_SAMSUNG void IRsend::sendSAMSUNG(unsigned long data, int nbits) { enableIROut(38); @@ -454,7 +458,7 @@ int IRrecv::decode(decode_results *results) { if (irparams.rcvstate != STATE_STOP) { return ERR; } -#ifdef NEC +#ifdef DECODE_NEC #ifdef DEBUG Serial.println("Attempting NEC decode"); #endif @@ -463,7 +467,7 @@ int IRrecv::decode(decode_results *results) { } #endif -#ifdef SONY +#ifdef DECODE_SONY #ifdef DEBUG Serial.println("Attempting Sony decode"); #endif @@ -472,7 +476,7 @@ int IRrecv::decode(decode_results *results) { } #endif -#ifdef SANYO +#ifdef DECODE_SANYO #ifdef DEBUG Serial.println("Attempting Sanyo decode"); #endif @@ -481,7 +485,7 @@ int IRrecv::decode(decode_results *results) { } #endif -#ifdef MITSUBISHI +#ifdef DECODE_MITSUBISHI #ifdef DEBUG Serial.println("Attempting Mitsubishi decode"); #endif @@ -490,7 +494,7 @@ int IRrecv::decode(decode_results *results) { } #endif -#ifdef RC5 +#ifdef DECODE_RC5 #ifdef DEBUG Serial.println("Attempting RC5 decode"); #endif @@ -499,7 +503,7 @@ int IRrecv::decode(decode_results *results) { } #endif -#ifdef RC6 +#ifdef DECODE_RC6 #ifdef DEBUG Serial.println("Attempting RC6 decode"); #endif @@ -508,7 +512,7 @@ int IRrecv::decode(decode_results *results) { } #endif -#ifdef PANASONIC +#ifdef DECODE_PANASONIC #ifdef DEBUG Serial.println("Attempting Panasonic decode"); #endif @@ -517,13 +521,16 @@ int IRrecv::decode(decode_results *results) { } #endif -#ifdef JVC +#ifdef DECODE_LG #ifdef DEBUG Serial.println("Attempting LG decode"); #endif if (decodeLG(results)) { return DECODED; } +#endif + +#ifdef DECODE_JVC #ifdef DEBUG Serial.println("Attempting JVC decode"); #endif @@ -532,20 +539,24 @@ int IRrecv::decode(decode_results *results) { } #endif -#ifdef SAMSUNG +#ifdef DECODE_SAMSUNG #ifdef DEBUG Serial.println("Attempting SAMSUNG decode"); #endif if (decodeSAMSUNG(results)) { return DECODED; } +#endif + +#ifdef DECODE_WHYNTER #ifdef DEBUG Serial.println("Attempting Whynter decode"); #endif if (decodeWhynter(results)) { return DECODED; } -// Aiwa RC-T501 +#endif + #ifdef AIWA_RC_T501 #ifdef DEBUG Serial.println("Attempting Aiwa RC-T501 decode"); @@ -566,7 +577,7 @@ int IRrecv::decode(decode_results *results) { return ERR; } -#ifdef NEC +#ifdef DECODE_NEC // NECs have a repeat only 4 items long long IRrecv::decodeNEC(decode_results *results) { long data = 0; @@ -617,7 +628,7 @@ long IRrecv::decodeNEC(decode_results *results) { } #endif -#ifdef SONY +#ifdef DECODE_SONY long IRrecv::decodeSony(decode_results *results) { long data = 0; if (irparams.rawlen < 2 * SONY_BITS + 2) { @@ -631,7 +642,7 @@ long IRrecv::decodeSony(decode_results *results) { // Serial.print("IR Gap found: "); results->bits = 0; results->value = REPEAT; -#ifdef SANYO +#ifdef DECODE_SANYO results->decode_type = SANYO; #else results->decode_type = UNKNOWN; @@ -675,6 +686,7 @@ long IRrecv::decodeSony(decode_results *results) { } #endif +#ifdef DECODE_WHYNTER long IRrecv::decodeWhynter(decode_results *results) { long data = 0; @@ -732,9 +744,9 @@ long IRrecv::decodeWhynter(decode_results *results) { results->decode_type = WHYNTER; return DECODED; } +#endif - -#ifdef SANYO +#ifdef DECODE_SANYO // I think this is a Sanyo decoder - serial = SA 8650B // Looks like Sony except for timings, 48 chars of data and time/space different long IRrecv::decodeSanyo(decode_results *results) { @@ -800,7 +812,7 @@ long IRrecv::decodeSanyo(decode_results *results) { } #endif -#ifdef MITSUBISHI +#ifdef DECODE_MITSUBISHI // Looks like Sony except for timings, 48 chars of data and time/space different long IRrecv::decodeMitsubishi(decode_results *results) { // Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2); @@ -911,8 +923,8 @@ int IRrecv::getRClevel(decode_results *results, int *offset, int *used, int t1) #endif return val; } -#endif +#ifdef DECODE_RC5 long IRrecv::decodeRC5(decode_results *results) { if (irparams.rawlen < MIN_RC5_SAMPLES + 2) { return ERR; @@ -947,7 +959,9 @@ long IRrecv::decodeRC5(decode_results *results) { results->decode_type = RC5; return DECODED; } +#endif +#ifdef DECODE_RC6 long IRrecv::decodeRC6(decode_results *results) { if (results->rawlen < MIN_RC6_SAMPLES) { return ERR; @@ -998,8 +1012,9 @@ long IRrecv::decodeRC6(decode_results *results) { results->decode_type = RC6; return DECODED; } +#endif -#ifdef PANASONIC +#ifdef DECODE_PANASONIC long IRrecv::decodePanasonic(decode_results *results) { unsigned long long data = 0; int offset = 1; @@ -1035,7 +1050,7 @@ long IRrecv::decodePanasonic(decode_results *results) { } #endif -#ifdef LG +#ifdef DECODE_LG long IRrecv::decodeLG(decode_results *results) { long data = 0; int offset = 1; // Skip first space @@ -1083,7 +1098,7 @@ long IRrecv::decodeLG(decode_results *results) { #endif -#ifdef JVC +#ifdef DECODE_JVC long IRrecv::decodeJVC(decode_results *results) { long data = 0; int offset = 1; // Skip first space @@ -1137,7 +1152,7 @@ long IRrecv::decodeJVC(decode_results *results) { } #endif -#ifdef SAMSUNG +#ifdef DECODE_SAMSUNG // SAMSUNGs have a repeat only 4 items long long IRrecv::decodeSAMSUNG(decode_results *results) { long data = 0; @@ -1194,7 +1209,7 @@ long IRrecv::decodeSAMSUNG(decode_results *results) { * Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 * */ - #ifdef AIWA_RC_T501 + #ifdef DECODE_AIWA_RC_T501 long IRrecv::decodeAiwaRCT501(decode_results *results) { int data = 0; int offset = 1; // skip first garbage read @@ -1326,7 +1341,7 @@ i.e. use 0x1C10 instead of 0x0000000000001C10 which is listed in the linked LIRC file. */ -#ifdef IRsendSHARP +#ifdef SEND_SHARP void IRsend::sendSharp(unsigned long data, int nbits) { unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; enableIROut(38); @@ -1360,7 +1375,7 @@ void IRsend::sendSharp(unsigned int address, unsigned int command) { #endif -#ifdef IRsendDISH +#ifdef SEND_DISH void IRsend::sendDISH(unsigned long data, int nbits) { enableIROut(56); @@ -1386,7 +1401,7 @@ void IRsend::sendDISH(unsigned long data, int nbits) * */ - #ifdef AIWA_RC_T501 + #ifdef SEND_AIWA_RC_T501 void IRsend::sendAiwaRCT501(int code) { // PRE-DATA, 26 bits, 0x227EEC0 long int pre = 0x227EEC0; diff --git a/IRremote.h b/IRremote.h index a86be454e..654fc7ff6 100644 --- a/IRremote.h +++ b/IRremote.h @@ -25,10 +25,29 @@ //#define DEBUG // #define TEST +enum decode_type_t { + NEC = 1, + SONY = 2, + RC5 = 3, + RC6 = 4, + DISH = 5, + SHARP = 6, + PANASONIC = 7, + JVC = 8, + SANYO = 9, + MITSUBISHI = 10, + SAMSUNG = 11, + LG = 12, + WHYNTER = 13, + AIWA_RC_T501 = 14, + + UNKNOWN = -1 +}; + // Results returned from the decoder class decode_results { public: - int decode_type; // NEC, SONY, RC5, UNKNOWN + decode_type_t decode_type; // NEC, SONY, RC5, UNKNOWN union { // This is used for decoding Panasonic and Sharp data unsigned int panasonicAddress; unsigned int sharpAddress; @@ -53,23 +72,6 @@ class decode_results { #define IRsendSAMSUNG #define IRsendRAW -// Values for decode_type -#define NEC 1 -#define SONY 2 -#define RC5 3 -#define RC6 4 -#define DISH 5 -#define SHARP 6 -#define PANASONIC 7 -#define JVC 8 -#define SANYO 9 -#define MITSUBISHI 10 -#define SAMSUNG 11 -#define LG 12 -#define WHYNTER 13 -#define AIWA_RC_T501 14 -#define UNKNOWN -1 - // Decoded value for NEC when a repeat code is received #define REPEAT 0xffffffff @@ -85,42 +87,42 @@ class IRrecv private: // These are called by decode int getRClevel(decode_results *results, int *offset, int *used, int t1); -#ifdef NEC +#ifdef DECODE_NEC long decodeNEC(decode_results *results); #endif -#ifdef SONY +#ifdef DECODE_SONY long decodeSony(decode_results *results); #endif -#ifdef SANYO +#ifdef DECODE_SANYO long decodeSanyo(decode_results *results); #endif -#ifdef MITSUBISHI +#ifdef DECODE_MITSUBISHI long decodeMitsubishi(decode_results *results); #endif -#ifdef RC5 +#ifdef DECODE_RC5 long decodeRC5(decode_results *results); #endif -#ifdef RC6 +#ifdef DECODE_RC6 long decodeRC6(decode_results *results); #endif -#ifdef PANASONIC +#ifdef DECODE_PANASONIC long decodePanasonic(decode_results *results); #endif -#ifdef LG +#ifdef DECODE_LG long decodeLG(decode_results *results); #endif -#ifdef JVC +#ifdef DECODE_JVC long decodeJVC(decode_results *results); #endif -#ifdef SAMSUNG +#ifdef DECODE_SAMSUNG long decodeSAMSUNG(decode_results *results); #endif -#ifdef WHYNTER +#ifdef DECODE_WHYNTER long decodeWhynter(decode_results *results); #endif -#ifdef AIWA_RC_T501 +#ifdef DECODE_AIWA_RC_T501 long decodeAiwaRCT501(decode_results *results); #endif @@ -141,41 +143,44 @@ class IRsend public: IRsend() {} void sendRaw(unsigned int buf[], int len, int hz); +#ifdef SEND_RC5 void sendRC5(unsigned long data, int nbits); +#endif +#ifdef SEND_RC6 void sendRC6(unsigned long data, int nbits); - -#ifdef WHYNTER +#endif +#ifdef SEND_WHYNTER void sendWhynter(unsigned long data, int nbits); #endif -#ifdef NEC +#ifdef SEND_NEC void sendNEC(unsigned long data, int nbits); #endif -#ifdef SONY +#ifdef SEND_SONY void sendSony(unsigned long data, int nbits); // Neither Sanyo nor Mitsubishi send is implemented yet // void sendSanyo(unsigned long data, int nbits); // void sendMitsubishi(unsigned long data, int nbits); #endif - -#ifdef DISH +#ifdef SEND_DISH void sendDISH(unsigned long data, int nbits); #endif -#ifdef SHARP +#ifdef SEND_SHARP void sendSharp(unsigned int address, unsigned int command); void sendSharpRaw(unsigned long data, int nbits); #endif -#ifdef IRsendSHARP +#ifdef SEND_IRsendSHARP void sendSharp(unsigned long data, int nbits); #endif -#ifdef PANASONIC +#ifdef SEND_PANASONIC void sendPanasonic(unsigned int address, unsigned long data); #endif -#ifdef JVC +#ifdef SEND_JVC 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. +#endif +#ifdef SEND_AIWA_RC_T501 void sendAiwaRCT501(int code); - // private: #endif -#ifdef SAMSUNG +#ifdef SEND_SAMSUNG void sendSAMSUNG(unsigned long data, int nbits); #endif void enableIROut(int khz); From f9faf9804863b38452196dbe8d43ae62b9e858a3 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 26 Apr 2015 17:06:52 -0600 Subject: [PATCH 042/768] #133 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 816a7f9ec..094b283f6 100644 --- a/library.properties +++ b/library.properties @@ -4,6 +4,6 @@ author=shirriff maintainer=shirriff sentence=Send and receive infrared signals with multiple protocols paragraph=Send and receive infrared signals with multiple protocols -category=infrared +category=Signal Input/Output url=https://github.com/shirriff/Arduino-IRremote.git architectures=* From 9170c0b4a12219b5e83b56d638a7c82c0309b211 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 14 May 2015 16:32:48 -0600 Subject: [PATCH 043/768] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f59361ef..3fee47349 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +NOTE: THIS NEEDS TO BE FIXED.... PLEASE JUST USE THE LATEST RELEASE AND NOT THE MASTER BRANCH!!!! # IRremote Arduino Library This library enables you to send and receive using infra-red signals on an arduino. @@ -12,7 +13,6 @@ Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more 4. Move the "IRremote" folder that has been extracted to your libraries directory. ## Usage - We get a lot of support for different device types. To keep the size of the library manageable we're moving to a model where different device types use a #define statement, for instance: ```#define SHARP``` From 8e043b5bb45425fc8f9bf5f31130e4c612f80a0c Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 23 May 2015 19:35:45 +0300 Subject: [PATCH 044/768] Continuous Integration with @travis-ci + @PlatformIO --- .travis.yml | 24 ++++++++++++++++++++++++ README.md | 2 ++ 2 files changed, 26 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..63d901f17 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: python +python: + - "2.7" + +env: + - PLATFORMIO_CI_SRC=examples/AiwaRCT501SendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_AIWA_RC_T501" + - PLATFORMIO_CI_SRC=examples/IRrecord PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" + - PLATFORMIO_CI_SRC=examples/IRrecvDemo + - PLATFORMIO_CI_SRC=examples/IRrecvDump + - PLATFORMIO_CI_SRC=examples/IRrelay + - PLATFORMIO_CI_SRC=examples/IRsendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_SONY" + - PLATFORMIO_CI_SRC=examples/IRtest PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" + - PLATFORMIO_CI_SRC=examples/IRtest2 PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" + - PLATFORMIO_CI_SRC=examples/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC" + +install: + - python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)" + + # Temporary using PlatformIO from development branch + # @TODO remove this line after 2.0.1 release + - pip install https://github.com/platformio/platformio/archive/develop.zip + +script: + - platformio ci --lib="." --board=uno --board=leonardo --board=pro16MHzatmega168 diff --git a/README.md b/README.md index 3fee47349..4ea51fd30 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Build Status](https://travis-ci.org/shirriff/Arduino-IRremote.svg)](https://travis-ci.org/shirriff/Arduino-IRremote) +__________ NOTE: THIS NEEDS TO BE FIXED.... PLEASE JUST USE THE LATEST RELEASE AND NOT THE MASTER BRANCH!!!! # IRremote Arduino Library This library enables you to send and receive using infra-red signals on an arduino. From 66395a5daa712c52bcf3319db849fb8e99e0ff6c Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 27 May 2015 17:18:01 +0300 Subject: [PATCH 045/768] Switch to stable release of @PlatformIO --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 63d901f17..51640b156 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,9 +16,5 @@ env: install: - python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)" - # Temporary using PlatformIO from development branch - # @TODO remove this line after 2.0.1 release - - pip install https://github.com/platformio/platformio/archive/develop.zip - script: - platformio ci --lib="." --board=uno --board=leonardo --board=pro16MHzatmega168 From 942dcf40511c9ec642d3d932a6d1d2046f3fd255 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Wed, 17 Jun 2015 21:59:04 +0100 Subject: [PATCH 046/768] Clearly mark the start of every function to aid is source navigation & code maintainability --- IRremote.cpp | 221 +++++++++++++++++++++++++++++---------------------- 1 file changed, 128 insertions(+), 93 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 9389267e3..bbcac02b5 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -5,7 +5,7 @@ * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html * * Modified by Paul Stoffregen to support other boards and timers - * Modified by Mitra Ardron + * Modified by Mitra Ardron * Added Sanyo and Mitsubishi controllers * Modified Sony to spot the repeat codes that some Sony's send * @@ -74,6 +74,7 @@ int MATCH_SPACE(int measured_ticks, int desired_us) {return MATCH(measured_ticks // Debugging versions are in IRremote.cpp #endif +//+============================================================================= #ifdef SEND_NEC void IRsend::sendNEC(unsigned long data, int nbits) { @@ -84,7 +85,7 @@ void IRsend::sendNEC(unsigned long data, int nbits) if (data & TOPBIT) { mark(NEC_BIT_MARK); space(NEC_ONE_SPACE); - } + } else { mark(NEC_BIT_MARK); space(NEC_ZERO_SPACE); @@ -96,6 +97,7 @@ void IRsend::sendNEC(unsigned long data, int nbits) } #endif +//+============================================================================= #ifdef SEND_WHYNTER void IRsend::sendWhynter(unsigned long data, int nbits) { enableIROut(38); @@ -107,7 +109,7 @@ void IRsend::sendWhynter(unsigned long data, int nbits) { if (data & TOPBIT) { mark(WHYNTER_ONE_MARK); space(WHYNTER_ONE_SPACE); - } + } else { mark(WHYNTER_ZERO_MARK); space(WHYNTER_ZERO_SPACE); @@ -119,6 +121,7 @@ void IRsend::sendWhynter(unsigned long data, int nbits) { } #endif +//+============================================================================= #ifdef SEND_SONY void IRsend::sendSony(unsigned long data, int nbits) { enableIROut(40); @@ -129,7 +132,7 @@ void IRsend::sendSony(unsigned long data, int nbits) { if (data & TOPBIT) { mark(SONY_ONE_MARK); space(SONY_HDR_SPACE); - } + } else { mark(SONY_ZERO_MARK); space(SONY_HDR_SPACE); @@ -139,13 +142,14 @@ void IRsend::sendSony(unsigned long data, int nbits) { } #endif +//+============================================================================= void IRsend::sendRaw(unsigned int buf[], int len, int hz) { enableIROut(hz); for (int i = 0; i < len; i++) { if (i & 1) { space(buf[i]); - } + } else { mark(buf[i]); } @@ -153,6 +157,7 @@ void IRsend::sendRaw(unsigned int buf[], int len, int hz) space(0); // Just to be sure } +//+============================================================================= #ifdef SEND_RC5 // Note: first bit must be a one (start bit) void IRsend::sendRC5(unsigned long data, int nbits) @@ -166,7 +171,7 @@ void IRsend::sendRC5(unsigned long data, int nbits) if (data & TOPBIT) { space(RC5_T1); // 1 is space, then mark mark(RC5_T1); - } + } else { mark(RC5_T1); space(RC5_T1); @@ -177,6 +182,7 @@ void IRsend::sendRC5(unsigned long data, int nbits) } #endif +//+============================================================================= #ifdef SEND_RC6 // Caller needs to take care of flipping the toggle bit void IRsend::sendRC6(unsigned long data, int nbits) @@ -192,14 +198,14 @@ void IRsend::sendRC6(unsigned long data, int nbits) if (i == 3) { // double-wide trailer bit t = 2 * RC6_T1; - } + } else { t = RC6_T1; } if (data & TOPBIT) { mark(t); space(t); - } + } else { space(t); mark(t); @@ -211,12 +217,13 @@ void IRsend::sendRC6(unsigned long data, int nbits) } #endif +//+============================================================================= #ifdef SEND_PANASONIC 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); @@ -225,8 +232,8 @@ void IRsend::sendPanasonic(unsigned int address, unsigned long data) { } else { space(PANASONIC_ZERO_SPACE); } - address <<= 1; - } + address <<= 1; + } for (int i=0; i < 32; i++) { mark(PANASONIC_BIT_MARK); if (data & TOPBIT) { @@ -241,6 +248,7 @@ void IRsend::sendPanasonic(unsigned int address, unsigned long data) { } #endif +//+============================================================================= #ifdef SEND_JVC void IRsend::sendJVC(unsigned long data, int nbits, int repeat) { @@ -248,16 +256,16 @@ void IRsend::sendJVC(unsigned long data, int nbits, int repeat) data = data << (32 - nbits); if (!repeat){ mark(JVC_HDR_MARK); - space(JVC_HDR_SPACE); + space(JVC_HDR_SPACE); } for (int i = 0; i < nbits; i++) { if (data & TOPBIT) { mark(JVC_BIT_MARK); - space(JVC_ONE_SPACE); - } + space(JVC_ONE_SPACE); + } else { mark(JVC_BIT_MARK); - space(JVC_ZERO_SPACE); + space(JVC_ZERO_SPACE); } data <<= 1; } @@ -266,6 +274,7 @@ void IRsend::sendJVC(unsigned long data, int nbits, int repeat) } #endif +//+============================================================================= #ifdef SEND_SAMSUNG void IRsend::sendSAMSUNG(unsigned long data, int nbits) { @@ -276,7 +285,7 @@ void IRsend::sendSAMSUNG(unsigned long data, int nbits) if (data & TOPBIT) { mark(SAMSUNG_BIT_MARK); space(SAMSUNG_ONE_SPACE); - } + } else { mark(SAMSUNG_BIT_MARK); space(SAMSUNG_ZERO_SPACE); @@ -288,6 +297,7 @@ void IRsend::sendSAMSUNG(unsigned long data, int nbits) } #endif +//+============================================================================= void IRsend::mark(int time) { // Sends an IR mark for the specified number of microseconds. // The mark output is modulated at the PWM frequency. @@ -295,6 +305,7 @@ void IRsend::mark(int time) { if (time > 0) delayMicroseconds(time); } +//+============================================================================= /* Leave pin off for time (given in microseconds) */ void IRsend::space(int time) { // Sends an IR space for the specified number of microseconds. @@ -303,6 +314,7 @@ void IRsend::space(int time) { if (time > 0) delayMicroseconds(time); } +//+============================================================================= void IRsend::enableIROut(int khz) { // Enables IR output. The khz value controls the modulation frequency in kilohertz. // The IR output will be on pin 3 (OC2B). @@ -315,13 +327,13 @@ void IRsend::enableIROut(int khz) { // 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. - + // 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 @@ -330,12 +342,14 @@ void IRsend::enableIROut(int khz) { TIMER_CONFIG_KHZ(khz); } +//+============================================================================= IRrecv::IRrecv(int recvpin) { irparams.recvpin = recvpin; irparams.blinkflag = 0; } +//+============================================================================= // initialization void IRrecv::enableIRIn() { cli(); @@ -360,6 +374,7 @@ void IRrecv::enableIRIn() { pinMode(irparams.recvpin, INPUT); } +//+============================================================================= // enable/disable blinking of pin 13 on IR processing void IRrecv::blink13(int blinkflag) { @@ -368,6 +383,7 @@ void IRrecv::blink13(int blinkflag) pinMode(BLINKLED, OUTPUT); } +//+============================================================================= // TIMER2 interrupt code to collect raw data. // Widths of alternating SPACE, MARK are recorded in rawbuf. // Recorded in ticks of 50 microseconds. @@ -392,7 +408,7 @@ ISR(TIMER_INTR_NAME) 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; @@ -414,7 +430,7 @@ ISR(TIMER_INTR_NAME) 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 @@ -422,7 +438,7 @@ ISR(TIMER_INTR_NAME) // Switch to STOP // Don't reset timer; keep counting space width irparams.rcvstate = STATE_STOP; - } + } } break; case STATE_STOP: // waiting, measuring gap @@ -435,20 +451,20 @@ ISR(TIMER_INTR_NAME) if (irparams.blinkflag) { if (irdata == MARK) { BLINKLED_ON(); // turn pin 13 LED on - } + } else { BLINKLED_OFF(); // turn pin 13 LED off } } } +//+============================================================================= 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 @@ -497,7 +513,7 @@ int IRrecv::decode(decode_results *results) { #ifdef DECODE_RC5 #ifdef DEBUG Serial.println("Attempting RC5 decode"); -#endif +#endif if (decodeRC5(results)) { return DECODED; } @@ -506,7 +522,7 @@ int IRrecv::decode(decode_results *results) { #ifdef DECODE_RC6 #ifdef DEBUG Serial.println("Attempting RC6 decode"); -#endif +#endif if (decodeRC6(results)) { return DECODED; } @@ -515,7 +531,7 @@ int IRrecv::decode(decode_results *results) { #ifdef DECODE_PANASONIC #ifdef DEBUG Serial.println("Attempting Panasonic decode"); -#endif +#endif if (decodePanasonic(results)) { return DECODED; } @@ -524,7 +540,7 @@ int IRrecv::decode(decode_results *results) { #ifdef DECODE_LG #ifdef DEBUG Serial.println("Attempting LG decode"); -#endif +#endif if (decodeLG(results)) { return DECODED; } @@ -533,7 +549,7 @@ int IRrecv::decode(decode_results *results) { #ifdef DECODE_JVC #ifdef DEBUG Serial.println("Attempting JVC decode"); -#endif +#endif if (decodeJVC(results)) { return DECODED; } @@ -560,7 +576,7 @@ int IRrecv::decode(decode_results *results) { #ifdef AIWA_RC_T501 #ifdef DEBUG Serial.println("Attempting Aiwa RC-T501 decode"); -#endif +#endif if (decodeAiwaRCT501(results)) { return DECODED; } @@ -577,6 +593,7 @@ int IRrecv::decode(decode_results *results) { return ERR; } +//+============================================================================= #ifdef DECODE_NEC // NECs have a repeat only 4 items long long IRrecv::decodeNEC(decode_results *results) { @@ -599,7 +616,7 @@ long IRrecv::decodeNEC(decode_results *results) { if (irparams.rawlen < 2 * NEC_BITS + 4) { return ERR; } - // Initial space + // Initial space if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) { return ERR; } @@ -611,10 +628,10 @@ long IRrecv::decodeNEC(decode_results *results) { offset++; if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE)) { data = (data << 1) | 1; - } + } else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) { data <<= 1; - } + } else { return ERR; } @@ -628,6 +645,7 @@ long IRrecv::decodeNEC(decode_results *results) { } #endif +//+============================================================================= #ifdef DECODE_SONY long IRrecv::decodeSony(decode_results *results) { long data = 0; @@ -664,10 +682,10 @@ long IRrecv::decodeSony(decode_results *results) { 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 ERR; } @@ -686,14 +704,15 @@ long IRrecv::decodeSony(decode_results *results) { } #endif +//+============================================================================= #ifdef DECODE_WHYNTER long IRrecv::decodeWhynter(decode_results *results) { long data = 0; - + if (irparams.rawlen < 2 * WHYNTER_BITS + 6) { return ERR; } - + int offset = 1; // skip initial space // sequence begins with a bit mark and a zero space @@ -724,16 +743,16 @@ long IRrecv::decodeWhynter(decode_results *results) { 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 ERR; } offset++; } - + // trailing mark if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) { return ERR; @@ -746,6 +765,7 @@ long IRrecv::decodeWhynter(decode_results *results) { } #endif +//+============================================================================= #ifdef DECODE_SANYO // I think this is a Sanyo decoder - serial = SA 8650B // Looks like Sony except for timings, 48 chars of data and time/space different @@ -755,7 +775,7 @@ long IRrecv::decodeSanyo(decode_results *results) { return ERR; } int offset = 0; // Skip first space - // Initial space + // Initial space /* 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]); @@ -790,10 +810,10 @@ long IRrecv::decodeSanyo(decode_results *results) { 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 ERR; } @@ -812,6 +832,7 @@ long IRrecv::decodeSanyo(decode_results *results) { } #endif +//+============================================================================= #ifdef DECODE_MITSUBISHI // Looks like Sony except for timings, 48 chars of data and time/space different long IRrecv::decodeMitsubishi(decode_results *results) { @@ -821,7 +842,7 @@ long IRrecv::decodeMitsubishi(decode_results *results) { return ERR; } int offset = 0; // Skip first space - // Initial space + // Initial space /* 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]); @@ -840,7 +861,7 @@ long IRrecv::decodeMitsubishi(decode_results *results) { 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 + // 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)) { @@ -850,10 +871,10 @@ long IRrecv::decodeMitsubishi(decode_results *results) { 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 { // Serial.println("A"); Serial.println(offset); Serial.println(results->rawbuf[offset]); return ERR; @@ -878,6 +899,7 @@ long IRrecv::decodeMitsubishi(decode_results *results) { } #endif +//+============================================================================= // 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, @@ -897,13 +919,13 @@ int IRrecv::getRClevel(decode_results *results, int *offset, int *used, int t1) 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; } @@ -916,14 +938,15 @@ int IRrecv::getRClevel(decode_results *results, int *offset, int *used, int t1) #ifdef DEBUG if (val == MARK) { Serial.println("MARK"); - } + } else { Serial.println("SPACE"); } #endif - return val; + return val; } +//+============================================================================= #ifdef DECODE_RC5 long IRrecv::decodeRC5(decode_results *results) { if (irparams.rawlen < MIN_RC5_SAMPLES + 2) { @@ -938,19 +961,19 @@ long IRrecv::decodeRC5(decode_results *results) { if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR; int nbits; for (nbits = 0; offset < irparams.rawlen; nbits++) { - int levelA = getRClevel(results, &offset, &used, RC5_T1); + int levelA = getRClevel(results, &offset, &used, RC5_T1); int levelB = getRClevel(results, &offset, &used, RC5_T1); if (levelA == SPACE && levelB == MARK) { // 1 bit data = (data << 1) | 1; - } + } else if (levelA == MARK && levelB == SPACE) { // zero bit data <<= 1; - } + } else { return ERR; - } + } } // Success @@ -961,6 +984,7 @@ long IRrecv::decodeRC5(decode_results *results) { } #endif +//+============================================================================= #ifdef DECODE_RC6 long IRrecv::decodeRC6(decode_results *results) { if (results->rawlen < MIN_RC6_SAMPLES) { @@ -984,27 +1008,27 @@ long IRrecv::decodeRC6(decode_results *results) { int nbits; for (nbits = 0; offset < results->rawlen; nbits++) { int levelA, levelB; // Next two levels - levelA = getRClevel(results, &offset, &used, RC6_T1); + 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 ERR; - } + } 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 ERR; - } + } if (levelA == MARK && levelB == SPACE) { // reversed compared to RC5 // 1 bit data = (data << 1) | 1; - } + } else if (levelA == SPACE && levelB == MARK) { // zero bit data <<= 1; - } + } else { return ERR; // Error - } + } } // Success results->bits = nbits; @@ -1012,13 +1036,14 @@ long IRrecv::decodeRC6(decode_results *results) { results->decode_type = RC6; return DECODED; } -#endif +#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 ERR; } @@ -1027,7 +1052,7 @@ long IRrecv::decodePanasonic(decode_results *results) { return ERR; } offset++; - + // decode address for (int i = 0; i < PANASONIC_BITS; i++) { if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK)) { @@ -1050,20 +1075,21 @@ long IRrecv::decodePanasonic(decode_results *results) { } #endif +//+============================================================================= #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 ERR; } - offset++; + offset++; if (irparams.rawlen < 2 * LG_BITS + 1 ) { return ERR; } - // Initial space + // Initial space if (!MATCH_SPACE(results->rawbuf[offset], LG_HDR_SPACE)) { return ERR; } @@ -1075,10 +1101,10 @@ long IRrecv::decodeLG(decode_results *results) { 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 ERR; } @@ -1098,6 +1124,7 @@ long IRrecv::decodeLG(decode_results *results) { #endif +//+============================================================================= #ifdef DECODE_JVC long IRrecv::decodeJVC(decode_results *results) { long data = 0; @@ -1110,16 +1137,16 @@ long IRrecv::decodeJVC(decode_results *results) { results->value = REPEAT; results->decode_type = JVC; return DECODED; - } + } // Initial mark if (!MATCH_MARK(results->rawbuf[offset], JVC_HDR_MARK)) { return ERR; } - offset++; + offset++; if (irparams.rawlen < 2 * JVC_BITS + 1 ) { return ERR; } - // Initial space + // Initial space if (!MATCH_SPACE(results->rawbuf[offset], JVC_HDR_SPACE)) { return ERR; } @@ -1131,10 +1158,10 @@ long IRrecv::decodeJVC(decode_results *results) { 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; } @@ -1152,6 +1179,7 @@ long IRrecv::decodeJVC(decode_results *results) { } #endif +//+============================================================================= #ifdef DECODE_SAMSUNG // SAMSUNGs have a repeat only 4 items long long IRrecv::decodeSAMSUNG(decode_results *results) { @@ -1174,7 +1202,7 @@ long IRrecv::decodeSAMSUNG(decode_results *results) { if (irparams.rawlen < 2 * SAMSUNG_BITS + 4) { return ERR; } - // Initial space + // Initial space if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) { return ERR; } @@ -1186,10 +1214,10 @@ long IRrecv::decodeSAMSUNG(decode_results *results) { 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 ERR; } @@ -1203,10 +1231,11 @@ long IRrecv::decodeSAMSUNG(decode_results *results) { } #endif +//+============================================================================= /** * Aiwa system * Remote control RC-T501 - * Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 + * Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 * */ #ifdef DECODE_AIWA_RC_T501 @@ -1218,7 +1247,7 @@ long IRrecv::decodeAiwaRCT501(decode_results *results) { if(irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) { return ERR; } - + // Check HDR if(!MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_HDR_MARK)) { return ERR; @@ -1235,25 +1264,25 @@ long IRrecv::decodeAiwaRCT501(decode_results *results) { while(offset < irparams.rawlen - 4) { if(MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_BIT_MARK)) { offset++; - } + } else { return ERR; } - + // 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 { // End of one & zero detected break; } offset++; } - + results->bits = (offset - 1) / 2; if(results->bits < 42) { return ERR; @@ -1265,6 +1294,7 @@ long IRrecv::decodeAiwaRCT501(decode_results *results) { #endif +//+============================================================================= /* ----------------------------------------------------------------------- * hashdecode - decode an arbitrary IR code. * Instead of decoding using a standard encoding scheme @@ -1285,15 +1315,16 @@ long IRrecv::decodeAiwaRCT501(decode_results *results) { 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 #define FNV_PRIME_32 16777619 #define FNV_BASIS_32 2166136261 @@ -1319,6 +1350,7 @@ long IRrecv::decodeHash(decode_results *results) { return DECODED; } +//+============================================================================= /* Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand ) The Dish send function needs to be repeated 4 times, and the Sharp function @@ -1359,7 +1391,7 @@ void IRsend::sendSharp(unsigned long data, int nbits) { space(SHARP_ZERO_SPACE); } } - + mark(SHARP_BIT_MARK); space(SHARP_ZERO_SPACE); delay(40); @@ -1368,6 +1400,7 @@ void IRsend::sendSharp(unsigned long data, int nbits) { } } +//+============================================================================= // Sharp send compatible with data obtained through decodeSharp void IRsend::sendSharp(unsigned int address, unsigned int command) { sendSharpRaw((address << 10) | (command << 2) | 2, 15); @@ -1375,6 +1408,7 @@ void IRsend::sendSharp(unsigned int address, unsigned int command) { #endif +//+============================================================================= #ifdef SEND_DISH void IRsend::sendDISH(unsigned long data, int nbits) { @@ -1394,21 +1428,22 @@ void IRsend::sendDISH(unsigned long data, int nbits) } } #endif + +//+============================================================================= /** * Aiwa system * Remote control RC-T501 - * Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 + * Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 * */ - #ifdef SEND_AIWA_RC_T501 void IRsend::sendAiwaRCT501(int code) { // PRE-DATA, 26 bits, 0x227EEC0 long int pre = 0x227EEC0; int i; - + enableIROut(AIWA_RC_T501_HZ); - + // HDR mark + HDR space mark(AIWA_RC_T501_HDR_MARK); space(AIWA_RC_T501_HDR_SPACE); From 64698fd24b6e4ea891547ed588d2ba89d23d603e Mon Sep 17 00:00:00 2001 From: Bluechip Date: Wed, 17 Jun 2015 22:16:43 +0100 Subject: [PATCH 047/768] Standardise commenting as C++ style throughout --- IRremote.cpp | 213 +++++++++++++++++++++++++++------------------------ 1 file changed, 113 insertions(+), 100 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index bbcac02b5..a7b34cf24 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -1,22 +1,22 @@ -/* - * IRremote - * Version 0.11 August, 2009 - * Copyright 2009 Ken Shirriff - * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html - * - * Modified by Paul Stoffregen to support other boards and timers - * Modified by Mitra Ardron - * Added Sanyo and Mitsubishi controllers - * Modified Sony to spot the repeat codes that some Sony's send - * - * 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) - * LG added by Darryl Smith (based on the JVC protocol) - * Whynter A/C ARC-110WD added by Francesco Meschia - */ +//****************************************************************************** +// IRremote +// Version 0.11 August, 2009 +// Copyright 2009 Ken Shirriff +// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html +// +// Modified by Paul Stoffregen to support other boards and timers +// Modified by Mitra Ardron +// Added Sanyo and Mitsubishi controllers +// Modified Sony to spot the repeat codes that some Sony's send +// +// 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) +// LG added by Darryl Smith (based on the JVC protocol) +// Whynter A/C ARC-110WD added by Francesco Meschia +//****************************************************************************** #include "IRremote.h" #include "IRremoteInt.h" @@ -158,8 +158,9 @@ void IRsend::sendRaw(unsigned int buf[], int len, int hz) } //+============================================================================= -#ifdef SEND_RC5 // Note: first bit must be a one (start bit) +// +#ifdef SEND_RC5 void IRsend::sendRC5(unsigned long data, int nbits) { enableIROut(36); @@ -183,8 +184,9 @@ void IRsend::sendRC5(unsigned long data, int nbits) #endif //+============================================================================= -#ifdef SEND_RC6 // Caller needs to take care of flipping the toggle bit +// +#ifdef SEND_RC6 void IRsend::sendRC6(unsigned long data, int nbits) { enableIROut(36); @@ -298,36 +300,37 @@ void IRsend::sendSAMSUNG(unsigned long data, int nbits) #endif //+============================================================================= +// Sends an IR mark for the specified number of microseconds. +// The mark output is modulated at the PWM frequency. +// void IRsend::mark(int time) { - // Sends an IR mark for the specified number of microseconds. - // The mark output is modulated at the PWM frequency. TIMER_ENABLE_PWM; // Enable pin 3 PWM output if (time > 0) delayMicroseconds(time); } //+============================================================================= -/* Leave pin off for time (given in microseconds) */ +// 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) { - // Sends an IR space for the specified number of microseconds. - // A space is no output, so the PWM output is disabled. 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) { - // 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. - - // Disable the Timer2 Interrupt (which is used for receiving IR) TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt @@ -351,6 +354,7 @@ IRrecv::IRrecv(int recvpin) //+============================================================================= // initialization +// void IRrecv::enableIRIn() { cli(); // setup pulse clock timer interrupt @@ -376,6 +380,7 @@ void IRrecv::enableIRIn() { //+============================================================================= // enable/disable blinking of pin 13 on IR processing +// void IRrecv::blink13(int blinkflag) { irparams.blinkflag = blinkflag; @@ -391,6 +396,7 @@ void IRrecv::blink13(int blinkflag) // 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; @@ -766,9 +772,10 @@ long IRrecv::decodeWhynter(decode_results *results) { #endif //+============================================================================= -#ifdef DECODE_SANYO // I think this is a Sanyo decoder - serial = SA 8650B // Looks like Sony except for timings, 48 chars of data and time/space different +// +#ifdef DECODE_SANYO long IRrecv::decodeSanyo(decode_results *results) { long data = 0; if (irparams.rawlen < 2 * SANYO_BITS + 2) { @@ -776,12 +783,15 @@ long IRrecv::decodeSanyo(decode_results *results) { } int offset = 0; // Skip first space // Initial space - /* 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 + +#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; @@ -833,8 +843,9 @@ long IRrecv::decodeSanyo(decode_results *results) { #endif //+============================================================================= -#ifdef DECODE_MITSUBISHI // Looks like Sony except for timings, 48 chars of data and time/space different +// +#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; @@ -843,13 +854,17 @@ long IRrecv::decodeMitsubishi(decode_results *results) { } int offset = 0; // Skip first space // Initial space - /* 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 + +#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]); - */ - /* Not seeing double keys from Mitsubishi +#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; @@ -857,7 +872,9 @@ long IRrecv::decodeMitsubishi(decode_results *results) { results->decode_type = MITSUBISHI; return DECODED; } - */ +#endif + + offset++; // Typical @@ -907,6 +924,7 @@ long IRrecv::decodeMitsubishi(decode_results *results) { // 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) { // After end of recorded buffer, assume SPACE. @@ -1232,13 +1250,11 @@ long IRrecv::decodeSAMSUNG(decode_results *results) { #endif //+============================================================================= -/** - * Aiwa system - * Remote control RC-T501 - * Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 - * - */ - #ifdef DECODE_AIWA_RC_T501 +// Aiwa system +// Remote control RC-T501 +// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 +// +#ifdef DECODE_AIWA_RC_T501 long IRrecv::decodeAiwaRCT501(decode_results *results) { int data = 0; int offset = 1; // skip first garbage read @@ -1295,23 +1311,22 @@ long IRrecv::decodeAiwaRCT501(decode_results *results) { #endif //+============================================================================= -/* ----------------------------------------------------------------------- - * 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 - */ - +// 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; @@ -1326,13 +1341,13 @@ int IRrecv::compare(unsigned int oldval, unsigned int newval) { //+============================================================================= // 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 -/* 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. - */ long IRrecv::decodeHash(decode_results *results) { // Require at least 6 samples to prevent triggering on noise if (results->rawlen < 6) { @@ -1351,28 +1366,27 @@ long IRrecv::decodeHash(decode_results *results) { } //+============================================================================= -/* Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand ) - -The Dish send function needs to be repeated 4 times, and the Sharp 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 are the LIRC files that I found that seem to match the remote codes -from the oscilloscope: - -Sharp LCD TV: -http://lirc.sourceforge.net/remotes/sharp/GA538WJSA - -DISH NETWORK (echostar 301): -http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx - -For the DISH codes, only send the last for characters of the hex. -i.e. use 0x1C10 instead of 0x0000000000001C10 which is listed in the -linked LIRC file. -*/ - +// Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand ) +// +// The Dish send function needs to be repeated 4 times, and the Sharp 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 are the LIRC files that I found that seem to match the remote codes +// from the oscilloscope: +// +// Sharp LCD TV: +// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA +// +// DISH NETWORK (echostar 301): +// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx +// +// For the DISH codes, only send the last for characters of the hex. +// i.e. use 0x1C10 instead of 0x0000000000001C10 which is listed in the +// linked LIRC file. +// #ifdef SEND_SHARP void IRsend::sendSharp(unsigned long data, int nbits) { unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; @@ -1402,6 +1416,7 @@ void IRsend::sendSharp(unsigned long data, int nbits) { //+============================================================================= // Sharp send compatible with data obtained through decodeSharp +// void IRsend::sendSharp(unsigned int address, unsigned int command) { sendSharpRaw((address << 10) | (command << 2) | 2, 15); } @@ -1430,13 +1445,11 @@ void IRsend::sendDISH(unsigned long data, int nbits) #endif //+============================================================================= -/** - * Aiwa system - * Remote control RC-T501 - * Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 - * - */ - #ifdef SEND_AIWA_RC_T501 +// Aiwa system +// Remote control RC-T501 +// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 +// +#ifdef SEND_AIWA_RC_T501 void IRsend::sendAiwaRCT501(int code) { // PRE-DATA, 26 bits, 0x227EEC0 long int pre = 0x227EEC0; From c45b84f65cb1fa61b1a23bd9a550e4cfabdca1cd Mon Sep 17 00:00:00 2001 From: Bluechip Date: Wed, 17 Jun 2015 22:25:34 +0100 Subject: [PATCH 048/768] Standardise function headers for consistent coding style --- IRremote.cpp | 133 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 89 insertions(+), 44 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index a7b34cf24..3a807d703 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -30,7 +30,8 @@ volatile irparams_t irparams; // To use them, set DEBUG in IRremoteInt.h // Normally macros are used for efficiency #ifdef DEBUG -int MATCH(int measured, int desired) { +int MATCH (int measured, int desired) +{ Serial.print("Testing: "); Serial.print(TICKS_LOW(desired), DEC); Serial.print(" <= "); @@ -40,7 +41,8 @@ int MATCH(int measured, int desired) { return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired); } -int MATCH_MARK(int measured_ticks, int desired_us) { +int MATCH_MARK (int measured_ticks, int desired_us) +{ Serial.print("Testing mark "); Serial.print(measured_ticks * USECPERTICK, DEC); Serial.print(" vs "); @@ -54,7 +56,8 @@ int MATCH_MARK(int measured_ticks, int desired_us) { return measured_ticks >= TICKS_LOW(desired_us + MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS); } -int MATCH_SPACE(int measured_ticks, int desired_us) { +int MATCH_SPACE (int measured_ticks, int desired_us) +{ Serial.print("Testing space "); Serial.print(measured_ticks * USECPERTICK, DEC); Serial.print(" vs "); @@ -67,16 +70,30 @@ int MATCH_SPACE(int measured_ticks, int desired_us) { Serial.println(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); return measured_ticks >= TICKS_LOW(desired_us - MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS); } + #else -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));} + +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 //+============================================================================= #ifdef SEND_NEC -void IRsend::sendNEC(unsigned long data, int nbits) +void IRsend::sendNEC (unsigned long data, int nbits) { enableIROut(38); mark(NEC_HDR_MARK); @@ -99,7 +116,8 @@ void IRsend::sendNEC(unsigned long data, int nbits) //+============================================================================= #ifdef SEND_WHYNTER -void IRsend::sendWhynter(unsigned long data, int nbits) { +void IRsend::sendWhynter (unsigned long data, int nbits) +{ enableIROut(38); mark(WHYNTER_ZERO_MARK); space(WHYNTER_ZERO_SPACE); @@ -123,7 +141,8 @@ void IRsend::sendWhynter(unsigned long data, int nbits) { //+============================================================================= #ifdef SEND_SONY -void IRsend::sendSony(unsigned long data, int nbits) { +void IRsend::sendSony (unsigned long data, int nbits) +{ enableIROut(40); mark(SONY_HDR_MARK); space(SONY_HDR_SPACE); @@ -143,7 +162,7 @@ void IRsend::sendSony(unsigned long data, int nbits) { #endif //+============================================================================= -void IRsend::sendRaw(unsigned int buf[], int len, int hz) +void IRsend::sendRaw (unsigned int buf[], int len, int hz) { enableIROut(hz); for (int i = 0; i < len; i++) { @@ -161,7 +180,7 @@ void IRsend::sendRaw(unsigned int buf[], int len, int hz) // Note: first bit must be a one (start bit) // #ifdef SEND_RC5 -void IRsend::sendRC5(unsigned long data, int nbits) +void IRsend::sendRC5 (unsigned long data, int nbits) { enableIROut(36); data = data << (32 - nbits); @@ -187,7 +206,7 @@ void IRsend::sendRC5(unsigned long data, int nbits) // Caller needs to take care of flipping the toggle bit // #ifdef SEND_RC6 -void IRsend::sendRC6(unsigned long data, int nbits) +void IRsend::sendRC6 (unsigned long data, int nbits) { enableIROut(36); data = data << (32 - nbits); @@ -221,7 +240,8 @@ void IRsend::sendRC6(unsigned long data, int nbits) //+============================================================================= #ifdef SEND_PANASONIC -void IRsend::sendPanasonic(unsigned int address, unsigned long data) { +void IRsend::sendPanasonic (unsigned int address, unsigned long data) +{ enableIROut(35); mark(PANASONIC_HDR_MARK); space(PANASONIC_HDR_SPACE); @@ -252,7 +272,7 @@ void IRsend::sendPanasonic(unsigned int address, unsigned long data) { //+============================================================================= #ifdef SEND_JVC -void IRsend::sendJVC(unsigned long data, int nbits, int repeat) +void IRsend::sendJVC (unsigned long data, int nbits, int repeat) { enableIROut(38); data = data << (32 - nbits); @@ -278,7 +298,7 @@ void IRsend::sendJVC(unsigned long data, int nbits, int repeat) //+============================================================================= #ifdef SEND_SAMSUNG -void IRsend::sendSAMSUNG(unsigned long data, int nbits) +void IRsend::sendSAMSUNG (unsigned long data, int nbits) { enableIROut(38); mark(SAMSUNG_HDR_MARK); @@ -303,7 +323,8 @@ void IRsend::sendSAMSUNG(unsigned long data, int nbits) // Sends an IR mark for the specified number of microseconds. // The mark output is modulated at the PWM frequency. // -void IRsend::mark(int time) { +void IRsend::mark (int time) +{ TIMER_ENABLE_PWM; // Enable pin 3 PWM output if (time > 0) delayMicroseconds(time); } @@ -313,7 +334,8 @@ void IRsend::mark(int time) { // 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) { +void IRsend::space (int time) +{ TIMER_DISABLE_PWM; // Disable pin 3 PWM output if (time > 0) delayMicroseconds(time); } @@ -330,7 +352,8 @@ void IRsend::space(int time) { // 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) { +void IRsend::enableIROut (int khz) +{ // Disable the Timer2 Interrupt (which is used for receiving IR) TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt @@ -346,7 +369,7 @@ void IRsend::enableIROut(int khz) { } //+============================================================================= -IRrecv::IRrecv(int recvpin) +IRrecv::IRrecv (int recvpin) { irparams.recvpin = recvpin; irparams.blinkflag = 0; @@ -355,7 +378,8 @@ IRrecv::IRrecv(int recvpin) //+============================================================================= // initialization // -void IRrecv::enableIRIn() { +void IRrecv::enableIRIn ( ) +{ cli(); // setup pulse clock timer interrupt //Prescale /8 (16M/8 = 0.5 microseconds per tick) @@ -381,7 +405,7 @@ void IRrecv::enableIRIn() { //+============================================================================= // enable/disable blinking of pin 13 on IR processing // -void IRrecv::blink13(int blinkflag) +void IRrecv::blink13 (int blinkflag) { irparams.blinkflag = blinkflag; if (blinkflag) @@ -397,7 +421,7 @@ void IRrecv::blink13(int blinkflag) // 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) +ISR (TIMER_INTR_NAME) { TIMER_RESET; @@ -465,7 +489,8 @@ ISR(TIMER_INTR_NAME) } //+============================================================================= -void IRrecv::resume() { +void IRrecv::resume ( ) +{ irparams.rcvstate = STATE_IDLE; irparams.rawlen = 0; } @@ -474,7 +499,8 @@ void IRrecv::resume() { // 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) { +int IRrecv::decode (decode_results *results) +{ results->rawbuf = irparams.rawbuf; results->rawlen = irparams.rawlen; if (irparams.rcvstate != STATE_STOP) { @@ -602,7 +628,8 @@ int IRrecv::decode(decode_results *results) { //+============================================================================= #ifdef DECODE_NEC // NECs have a repeat only 4 items long -long IRrecv::decodeNEC(decode_results *results) { +long IRrecv::decodeNEC (decode_results *results) +{ long data = 0; int offset = 1; // Skip first space // Initial mark @@ -653,7 +680,8 @@ long IRrecv::decodeNEC(decode_results *results) { //+============================================================================= #ifdef DECODE_SONY -long IRrecv::decodeSony(decode_results *results) { +long IRrecv::decodeSony (decode_results *results) +{ long data = 0; if (irparams.rawlen < 2 * SONY_BITS + 2) { return ERR; @@ -712,7 +740,8 @@ long IRrecv::decodeSony(decode_results *results) { //+============================================================================= #ifdef DECODE_WHYNTER -long IRrecv::decodeWhynter(decode_results *results) { +long IRrecv::decodeWhynter (decode_results *results) +{ long data = 0; if (irparams.rawlen < 2 * WHYNTER_BITS + 6) { @@ -776,7 +805,8 @@ long IRrecv::decodeWhynter(decode_results *results) { // Looks like Sony except for timings, 48 chars of data and time/space different // #ifdef DECODE_SANYO -long IRrecv::decodeSanyo(decode_results *results) { +long IRrecv::decodeSanyo (decode_results *results) +{ long data = 0; if (irparams.rawlen < 2 * SANYO_BITS + 2) { return ERR; @@ -846,7 +876,8 @@ long IRrecv::decodeSanyo(decode_results *results) { // Looks like Sony except for timings, 48 chars of data and time/space different // #ifdef DECODE_MITSUBISHI -long IRrecv::decodeMitsubishi(decode_results *results) { +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) { @@ -925,7 +956,8 @@ long IRrecv::decodeMitsubishi(decode_results *results) { // 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) { +int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int t1) +{ if (*offset >= results->rawlen) { // After end of recorded buffer, assume SPACE. return SPACE; @@ -966,7 +998,8 @@ int IRrecv::getRClevel(decode_results *results, int *offset, int *used, int t1) //+============================================================================= #ifdef DECODE_RC5 -long IRrecv::decodeRC5(decode_results *results) { +long IRrecv::decodeRC5 (decode_results *results) +{ if (irparams.rawlen < MIN_RC5_SAMPLES + 2) { return ERR; } @@ -1004,7 +1037,8 @@ long IRrecv::decodeRC5(decode_results *results) { //+============================================================================= #ifdef DECODE_RC6 -long IRrecv::decodeRC6(decode_results *results) { +long IRrecv::decodeRC6 (decode_results *results) +{ if (results->rawlen < MIN_RC6_SAMPLES) { return ERR; } @@ -1058,7 +1092,8 @@ long IRrecv::decodeRC6(decode_results *results) { //+============================================================================= #ifdef DECODE_PANASONIC -long IRrecv::decodePanasonic(decode_results *results) { +long IRrecv::decodePanasonic (decode_results *results) +{ unsigned long long data = 0; int offset = 1; @@ -1095,7 +1130,8 @@ long IRrecv::decodePanasonic(decode_results *results) { //+============================================================================= #ifdef DECODE_LG -long IRrecv::decodeLG(decode_results *results) { +long IRrecv::decodeLG (decode_results *results) +{ long data = 0; int offset = 1; // Skip first space @@ -1144,7 +1180,8 @@ long IRrecv::decodeLG(decode_results *results) { //+============================================================================= #ifdef DECODE_JVC -long IRrecv::decodeJVC(decode_results *results) { +long IRrecv::decodeJVC (decode_results *results) +{ long data = 0; int offset = 1; // Skip first space // Check for repeat @@ -1198,9 +1235,11 @@ long IRrecv::decodeJVC(decode_results *results) { #endif //+============================================================================= -#ifdef DECODE_SAMSUNG // SAMSUNGs have a repeat only 4 items long -long IRrecv::decodeSAMSUNG(decode_results *results) { +// +#ifdef DECODE_SAMSUNG +long IRrecv::decodeSAMSUNG (decode_results *results) +{ long data = 0; int offset = 1; // Skip first space // Initial mark @@ -1255,7 +1294,8 @@ long IRrecv::decodeSAMSUNG(decode_results *results) { // Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 // #ifdef DECODE_AIWA_RC_T501 -long IRrecv::decodeAiwaRCT501(decode_results *results) { +long IRrecv::decodeAiwaRCT501 (decode_results *results) +{ int data = 0; int offset = 1; // skip first garbage read @@ -1327,7 +1367,8 @@ long IRrecv::decodeAiwaRCT501(decode_results *results) { // 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) { +int IRrecv::compare (unsigned int oldval, unsigned int newval) +{ if (newval < oldval * .8) { return 0; } @@ -1348,7 +1389,8 @@ int IRrecv::compare(unsigned int oldval, unsigned int newval) { #define FNV_PRIME_32 16777619 #define FNV_BASIS_32 2166136261 -long IRrecv::decodeHash(decode_results *results) { +long IRrecv::decodeHash (decode_results *results) +{ // Require at least 6 samples to prevent triggering on noise if (results->rawlen < 6) { return ERR; @@ -1388,7 +1430,8 @@ long IRrecv::decodeHash(decode_results *results) { // linked LIRC file. // #ifdef SEND_SHARP -void IRsend::sendSharp(unsigned long data, int nbits) { +void IRsend::sendSharp (unsigned long data, int nbits) +{ unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; enableIROut(38); @@ -1417,7 +1460,8 @@ void IRsend::sendSharp(unsigned long data, int nbits) { //+============================================================================= // Sharp send compatible with data obtained through decodeSharp // -void IRsend::sendSharp(unsigned int address, unsigned int command) { +void IRsend::sendSharp (unsigned int address, unsigned int command) +{ sendSharpRaw((address << 10) | (command << 2) | 2, 15); } @@ -1425,7 +1469,7 @@ void IRsend::sendSharp(unsigned int address, unsigned int command) { //+============================================================================= #ifdef SEND_DISH -void IRsend::sendDISH(unsigned long data, int nbits) +void IRsend::sendDISH (unsigned long data, int nbits) { enableIROut(56); mark(DISH_HDR_MARK); @@ -1450,7 +1494,8 @@ void IRsend::sendDISH(unsigned long data, int nbits) // Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 // #ifdef SEND_AIWA_RC_T501 -void IRsend::sendAiwaRCT501(int code) { +void IRsend::sendAiwaRCT501 (int code) +{ // PRE-DATA, 26 bits, 0x227EEC0 long int pre = 0x227EEC0; int i; From 7f1387278fdb50a3fd22b9a5f90b4eeb2a07d4ed Mon Sep 17 00:00:00 2001 From: Bluechip Date: Wed, 17 Jun 2015 22:54:43 +0100 Subject: [PATCH 049/768] Reduce one-line-if's down to one line --- IRremote.cpp | 508 +++++++++++++-------------------------------------- 1 file changed, 129 insertions(+), 379 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 3a807d703..e5d44e02a 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -166,12 +166,8 @@ void IRsend::sendRaw (unsigned int buf[], int len, int hz) { enableIROut(hz); for (int i = 0; i < len; i++) { - if (i & 1) { - space(buf[i]); - } - else { - mark(buf[i]); - } + if (i & 1) space(buf[i]) ; + else mark (buf[i]) ; } space(0); // Just to be sure } @@ -216,13 +212,8 @@ void IRsend::sendRC6 (unsigned long data, int nbits) space(RC6_T1); int t; for (int i = 0; i < nbits; i++) { - if (i == 3) { - // double-wide trailer bit - t = 2 * RC6_T1; - } - else { - t = RC6_T1; - } + if (i == 3) t = RC6_T1 * 2 ; // double-wide trailer bit + else t = RC6_T1 ; if (data & TOPBIT) { mark(t); space(t); @@ -249,20 +240,14 @@ void IRsend::sendPanasonic (unsigned int address, unsigned long data) for(int i=0;i<16;i++) { mark(PANASONIC_BIT_MARK); - if (address & 0x8000) { - space(PANASONIC_ONE_SPACE); - } else { - space(PANASONIC_ZERO_SPACE); - } + 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); - } + if (data & TOPBIT) space(PANASONIC_ONE_SPACE) ; + else space(PANASONIC_ZERO_SPACE) ; data <<= 1; } mark(PANASONIC_BIT_MARK); @@ -408,8 +393,7 @@ void IRrecv::enableIRIn ( ) void IRrecv::blink13 (int blinkflag) { irparams.blinkflag = blinkflag; - if (blinkflag) - pinMode(BLINKLED, OUTPUT); + if (blinkflag) pinMode(BLINKLED, OUTPUT) ; } //+============================================================================= @@ -428,10 +412,7 @@ ISR (TIMER_INTR_NAME) uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); irparams.timer++; // One more 50us tick - if (irparams.rawlen >= RAWBUF) { - // Buffer overflow - irparams.rcvstate = STATE_STOP; - } + 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) { @@ -472,18 +453,13 @@ ISR (TIMER_INTR_NAME) } break; case STATE_STOP: // waiting, measuring gap - if (irdata == MARK) { // reset gap timer - irparams.timer = 0; - } + 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 + if (irdata == MARK) BLINKLED_ON() ; // turn pin 13 LED on + else BLINKLED_OFF() ; // turn pin 13 LED off } } } @@ -503,123 +479,95 @@ int IRrecv::decode (decode_results *results) { results->rawbuf = irparams.rawbuf; results->rawlen = irparams.rawlen; - if (irparams.rcvstate != STATE_STOP) { - return ERR; - } + if (irparams.rcvstate != STATE_STOP) return ERR ; #ifdef DECODE_NEC #ifdef DEBUG Serial.println("Attempting NEC decode"); #endif - if (decodeNEC(results)) { - return DECODED; - } + if (decodeNEC(results)) return DECODED ; #endif #ifdef DECODE_SONY #ifdef DEBUG Serial.println("Attempting Sony decode"); #endif - if (decodeSony(results)) { - return DECODED; - } + if (decodeSony(results)) return DECODED ; #endif #ifdef DECODE_SANYO #ifdef DEBUG Serial.println("Attempting Sanyo decode"); #endif - if (decodeSanyo(results)) { - return DECODED; - } + if (decodeSanyo(results)) return DECODED ; #endif #ifdef DECODE_MITSUBISHI #ifdef DEBUG Serial.println("Attempting Mitsubishi decode"); #endif - if (decodeMitsubishi(results)) { - return DECODED; - } + if (decodeMitsubishi(results)) return DECODED ; #endif #ifdef DECODE_RC5 #ifdef DEBUG Serial.println("Attempting RC5 decode"); #endif - if (decodeRC5(results)) { - return DECODED; - } + if (decodeRC5(results)) return DECODED ; #endif #ifdef DECODE_RC6 #ifdef DEBUG Serial.println("Attempting RC6 decode"); #endif - if (decodeRC6(results)) { - return DECODED; - } + if (decodeRC6(results)) return DECODED ; #endif #ifdef DECODE_PANASONIC #ifdef DEBUG Serial.println("Attempting Panasonic decode"); #endif - if (decodePanasonic(results)) { - return DECODED; - } + if (decodePanasonic(results)) return DECODED ; #endif #ifdef DECODE_LG #ifdef DEBUG Serial.println("Attempting LG decode"); #endif - if (decodeLG(results)) { - return DECODED; - } + if (decodeLG(results)) return DECODED ; #endif #ifdef DECODE_JVC #ifdef DEBUG Serial.println("Attempting JVC decode"); #endif - if (decodeJVC(results)) { - return DECODED; - } + if (decodeJVC(results)) return DECODED ; #endif #ifdef DECODE_SAMSUNG #ifdef DEBUG Serial.println("Attempting SAMSUNG decode"); #endif - if (decodeSAMSUNG(results)) { - return DECODED; - } + if (decodeSAMSUNG(results)) return DECODED ; #endif #ifdef DECODE_WHYNTER #ifdef DEBUG Serial.println("Attempting Whynter decode"); #endif - if (decodeWhynter(results)) { - return DECODED; - } + if (decodeWhynter(results)) return DECODED ; #endif #ifdef AIWA_RC_T501 #ifdef DEBUG Serial.println("Attempting Aiwa RC-T501 decode"); #endif - if (decodeAiwaRCT501(results)) { - return DECODED; - } + if (decodeAiwaRCT501(results)) return DECODED ; #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 DECODED; - } + if (decodeHash(results)) return DECODED ; // Throw away and start over resume(); return ERR; @@ -633,9 +581,7 @@ long IRrecv::decodeNEC (decode_results *results) long data = 0; int offset = 1; // Skip first space // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) return ERR ; offset++; // Check for repeat if (irparams.rawlen == 4 && @@ -646,28 +592,16 @@ long IRrecv::decodeNEC (decode_results *results) results->decode_type = NEC; return DECODED; } - if (irparams.rawlen < 2 * NEC_BITS + 4) { - return ERR; - } + if (irparams.rawlen < 2 * NEC_BITS + 4) return ERR ; // Initial space - if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) { - return ERR; - } + if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) return ERR ; offset++; for (int i = 0; i < NEC_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) return ERR ; offset++; - if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE)) { - data = (data << 1) | 1; - } - else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) { - data <<= 1; - } - else { - return ERR; - } + if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE)) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) data <<= 1 ; + else return ERR ; offset++; } // Success @@ -683,9 +617,7 @@ long IRrecv::decodeNEC (decode_results *results) long IRrecv::decodeSony (decode_results *results) { long data = 0; - if (irparams.rawlen < 2 * SONY_BITS + 2) { - return ERR; - } + if (irparams.rawlen < 2 * SONY_BITS + 2) return ERR ; int offset = 0; // Dont skip first space, check its size // Some Sony's deliver repeats fast after first @@ -704,25 +636,15 @@ long IRrecv::decodeSony (decode_results *results) offset++; // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], SONY_HDR_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], SONY_HDR_MARK)) return ERR ; offset++; while (offset + 1 < irparams.rawlen) { - if (!MATCH_SPACE(results->rawbuf[offset], SONY_HDR_SPACE)) { - break; - } + 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 ERR; - } + 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 ERR ; offset++; } @@ -744,54 +666,34 @@ long IRrecv::decodeWhynter (decode_results *results) { long data = 0; - if (irparams.rawlen < 2 * WHYNTER_BITS + 6) { - return ERR; - } + if (irparams.rawlen < 2 * WHYNTER_BITS + 6) return ERR ; 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 ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return ERR ; offset++; - if (!MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE)) { - return ERR; - } + if (!MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE)) return ERR ; offset++; // header mark and space - if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_HDR_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_HDR_MARK)) return ERR ; offset++; - if (!MATCH_SPACE(results->rawbuf[offset], WHYNTER_HDR_SPACE)) { - return ERR; - } + if (!MATCH_SPACE(results->rawbuf[offset], WHYNTER_HDR_SPACE)) return ERR ; offset++; // data bits for (int i = 0; i < WHYNTER_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return ERR ; 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 ERR; - } + 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 ERR ; offset++; } // trailing mark - if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return ERR ; // Success results->bits = WHYNTER_BITS; results->value = data; @@ -808,9 +710,7 @@ long IRrecv::decodeWhynter (decode_results *results) long IRrecv::decodeSanyo (decode_results *results) { long data = 0; - if (irparams.rawlen < 2 * SANYO_BITS + 2) { - return ERR; - } + if (irparams.rawlen < 2 * SANYO_BITS + 2) return ERR ; int offset = 0; // Skip first space // Initial space @@ -832,31 +732,19 @@ long IRrecv::decodeSanyo (decode_results *results) offset++; // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) return ERR ; offset++; // Skip Second Mark - if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) return ERR ; offset++; while (offset + 1 < irparams.rawlen) { - if (!MATCH_SPACE(results->rawbuf[offset], SANYO_HDR_SPACE)) { - break; - } + 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 ERR; - } + 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 ERR ; offset++; } @@ -880,9 +768,7 @@ 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 ERR; - } + if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2) return ERR ; int offset = 0; // Skip first space // Initial space @@ -912,26 +798,14 @@ long IRrecv::decodeMitsubishi (decode_results *results) // 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 ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) return ERR ; 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 { - // Serial.println("A"); Serial.println(offset); Serial.println(results->rawbuf[offset]); - return ERR; - } + 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 ERR ; offset++; - if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) { - // Serial.println("B"); Serial.println(offset); Serial.println(results->rawbuf[offset]); - break; - } + if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) break ; offset++; } @@ -958,27 +832,16 @@ long IRrecv::decodeMitsubishi (decode_results *results) // int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int t1) { - if (*offset >= results->rawlen) { - // After end of recorded buffer, assume SPACE. - return SPACE; - } + 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; - } + 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) { @@ -1000,31 +863,21 @@ int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int #ifdef DECODE_RC5 long IRrecv::decodeRC5 (decode_results *results) { - if (irparams.rawlen < MIN_RC5_SAMPLES + 2) { - return ERR; - } + if (irparams.rawlen < MIN_RC5_SAMPLES + 2) return ERR ; int offset = 1; // Skip gap space long data = 0; int used = 0; // Get start bits - if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR; - if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return ERR; - if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR; + if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR ; + if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return ERR ; + if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR ; 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) { - // 1 bit - data = (data << 1) | 1; - } - else if (levelA == MARK && levelB == SPACE) { - // zero bit - data <<= 1; - } - else { - return ERR; - } + if (levelA == SPACE && levelB == MARK) data = (data << 1) | 1 ; // 1 bit + else if (levelA == MARK && levelB == SPACE) data <<= 1 ; // zero bit + else return ERR ; } // Success @@ -1039,24 +892,18 @@ long IRrecv::decodeRC5 (decode_results *results) #ifdef DECODE_RC6 long IRrecv::decodeRC6 (decode_results *results) { - if (results->rawlen < MIN_RC6_SAMPLES) { - return ERR; - } + if (results->rawlen < MIN_RC6_SAMPLES) return ERR ; int offset = 1; // Skip first space // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], RC6_HDR_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], RC6_HDR_MARK)) return ERR ; offset++; - if (!MATCH_SPACE(results->rawbuf[offset], RC6_HDR_SPACE)) { - return ERR; - } + if (!MATCH_SPACE(results->rawbuf[offset], RC6_HDR_SPACE)) return ERR ; offset++; long data = 0; int used = 0; // Get start bit (1) - if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return ERR; - if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return ERR; + if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return ERR ; + if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return ERR ; int nbits; for (nbits = 0; offset < results->rawlen; nbits++) { int levelA, levelB; // Next two levels @@ -1070,17 +917,9 @@ long IRrecv::decodeRC6 (decode_results *results) // T bit is double wide; make sure second half matches if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return ERR; } - if (levelA == MARK && levelB == SPACE) { // reversed compared to RC5 - // 1 bit - data = (data << 1) | 1; - } - else if (levelA == SPACE && levelB == MARK) { - // zero bit - data <<= 1; - } - else { - return ERR; // Error - } + 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 ERR ; // Error } // Success results->bits = nbits; @@ -1097,27 +936,17 @@ 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; - } + if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_MARK)) return ERR ; offset++; - if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_SPACE)) { - return ERR; - } + 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; - } + 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; @@ -1136,38 +965,22 @@ long IRrecv::decodeLG (decode_results *results) int offset = 1; // Skip first space // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], LG_HDR_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], LG_HDR_MARK)) return ERR ; offset++; - if (irparams.rawlen < 2 * LG_BITS + 1 ) { - return ERR; - } + if (irparams.rawlen < 2 * LG_BITS + 1 ) return ERR ; // Initial space - if (!MATCH_SPACE(results->rawbuf[offset], LG_HDR_SPACE)) { - return ERR; - } + if (!MATCH_SPACE(results->rawbuf[offset], LG_HDR_SPACE)) return ERR ; offset++; for (int i = 0; i < LG_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return ERR ; 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 ERR; - } + 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 ERR ; offset++; } //Stop bit - if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)){ - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return ERR ; // Success results->bits = LG_BITS; results->value = data; @@ -1194,38 +1007,22 @@ long IRrecv::decodeJVC (decode_results *results) return DECODED; } // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], JVC_HDR_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], JVC_HDR_MARK)) return ERR ; offset++; - if (irparams.rawlen < 2 * JVC_BITS + 1 ) { - return ERR; - } + if (irparams.rawlen < 2 * JVC_BITS + 1 ) return ERR ; // Initial space - if (!MATCH_SPACE(results->rawbuf[offset], JVC_HDR_SPACE)) { - return ERR; - } + 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; - } + 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; - } + 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; - } + if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return ERR ; // Success results->bits = JVC_BITS; results->value = data; @@ -1243,9 +1040,7 @@ 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 ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return ERR ; offset++; // Check for repeat if (irparams.rawlen == 4 && @@ -1256,28 +1051,16 @@ long IRrecv::decodeSAMSUNG (decode_results *results) results->decode_type = SAMSUNG; return DECODED; } - if (irparams.rawlen < 2 * SAMSUNG_BITS + 4) { - return ERR; - } + if (irparams.rawlen < 2 * SAMSUNG_BITS + 4) return ERR ; // Initial space - if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) { - return ERR; - } + if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) return ERR ; offset++; for (int i = 0; i < SAMSUNG_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_BIT_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_BIT_MARK)) return ERR ; 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 ERR; - } + 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 ERR ; offset++; } // Success @@ -1300,49 +1083,30 @@ long IRrecv::decodeAiwaRCT501 (decode_results *results) int offset = 1; // skip first garbage read // Check SIZE - if(irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) { - return ERR; - } + if (irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) return ERR ; // Check HDR - if(!MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_HDR_MARK)) { - return ERR; - } + if (!MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_HDR_MARK)) return ERR ; offset++; // Check HDR space - if(!MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_HDR_SPACE)) { - return ERR; - } + if (!MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_HDR_SPACE)) return ERR ; 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 ERR; - } + if (MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_BIT_MARK)) offset++ ; + else return ERR ; // 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 { - // End of one & zero detected - break; - } + 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 ERR; - } + if (results->bits < 42) return ERR ; results->value = data; results->decode_type = AIWA_RC_T501; return DECODED; @@ -1369,15 +1133,9 @@ long IRrecv::decodeAiwaRCT501 (decode_results *results) // 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; - } + if (newval < oldval * .8) return 0 ; + else if (oldval < newval * .8) return 2 ; + else return 1 ; } //+============================================================================= @@ -1392,9 +1150,7 @@ int IRrecv::compare (unsigned int oldval, unsigned int newval) long IRrecv::decodeHash (decode_results *results) { // Require at least 6 samples to prevent triggering on noise - if (results->rawlen < 6) { - return ERR; - } + if (results->rawlen < 6) return ERR ; long hash = FNV_BASIS_32; for (int i = 1; i+2 < results->rawlen; i++) { int value = compare(results->rawbuf[i], results->rawbuf[i+2]); @@ -1511,11 +1267,8 @@ void IRsend::sendAiwaRCT501 (int code) // Send pre-data for(i=0; i < 26; i++) { mark(AIWA_RC_T501_BIT_MARK); - if(pre & TOPBIT) { - space(AIWA_RC_T501_ONE_SPACE); - } else { - space(AIWA_RC_T501_ZERO_SPACE); - } + if (pre & TOPBIT) space(AIWA_RC_T501_ONE_SPACE) ; + else space(AIWA_RC_T501_ZERO_SPACE) ; pre <<= 1; } @@ -1524,11 +1277,8 @@ void IRsend::sendAiwaRCT501 (int code) // Send code for(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); - } + if (code & TOPBIT) space(AIWA_RC_T501_ONE_SPACE) ; + else space(AIWA_RC_T501_ZERO_SPACE) ; code <<= 1; } // POST-DATA, 1 bit, 0x0 From 7d926499b433422e59ed6a9246de60df03d103e7 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Wed, 17 Jun 2015 23:04:47 +0100 Subject: [PATCH 050/768] Cleaned up the DEBUG output --- IRremote.cpp | 73 ++++++++++++++++++---------------------------------- 1 file changed, 25 insertions(+), 48 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index e5d44e02a..40255c087 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -24,6 +24,15 @@ // Provides ISR #include +//------------------------------------------------------------------------------ +// Debug directives +#ifdef DEBUG +# define DBG_PRINTLN(s) Serial.println(s); +#else +# define DBG_PRINTLN(s) +#endif + +//------------------------------------------------------------------------------ volatile irparams_t irparams; // These versions of MATCH, MATCH_MARK, and MATCH_SPACE are only for debugging. @@ -87,7 +96,6 @@ int MATCH_SPACE (int measured_ticks, int desired_us) { return MATCH(measured_ticks, (desired_us - MARK_EXCESS)); } -// Debugging versions are in IRremote.cpp #endif @@ -481,86 +489,62 @@ int IRrecv::decode (decode_results *results) results->rawlen = irparams.rawlen; if (irparams.rcvstate != STATE_STOP) return ERR ; #ifdef DECODE_NEC -#ifdef DEBUG - Serial.println("Attempting NEC decode"); -#endif + DBG_PRINTLN("Attempting NEC decode"); if (decodeNEC(results)) return DECODED ; #endif #ifdef DECODE_SONY -#ifdef DEBUG - Serial.println("Attempting Sony decode"); -#endif + DBG_PRINTLN("Attempting Sony decode"); if (decodeSony(results)) return DECODED ; #endif #ifdef DECODE_SANYO -#ifdef DEBUG - Serial.println("Attempting Sanyo decode"); -#endif + DBG_PRINTLN("Attempting Sanyo decode"); if (decodeSanyo(results)) return DECODED ; #endif #ifdef DECODE_MITSUBISHI -#ifdef DEBUG - Serial.println("Attempting Mitsubishi decode"); -#endif + DBG_PRINTLN("Attempting Mitsubishi decode"); if (decodeMitsubishi(results)) return DECODED ; #endif #ifdef DECODE_RC5 -#ifdef DEBUG - Serial.println("Attempting RC5 decode"); -#endif + DBG_PRINTLN("Attempting RC5 decode"); if (decodeRC5(results)) return DECODED ; #endif #ifdef DECODE_RC6 -#ifdef DEBUG - Serial.println("Attempting RC6 decode"); -#endif + DBG_PRINTLN("Attempting RC6 decode"); if (decodeRC6(results)) return DECODED ; #endif #ifdef DECODE_PANASONIC -#ifdef DEBUG - Serial.println("Attempting Panasonic decode"); -#endif - if (decodePanasonic(results)) return DECODED ; + DBG_PRINTLN("Attempting Panasonic decode"); + if (decodePanasonic(results)) return DECODED ; #endif #ifdef DECODE_LG -#ifdef DEBUG - Serial.println("Attempting LG decode"); -#endif - if (decodeLG(results)) return DECODED ; + DBG_PRINTLN("Attempting LG decode"); + if (decodeLG(results)) return DECODED ; #endif #ifdef DECODE_JVC -#ifdef DEBUG - Serial.println("Attempting JVC decode"); -#endif - if (decodeJVC(results)) return DECODED ; + DBG_PRINTLN("Attempting JVC decode"); + if (decodeJVC(results)) return DECODED ; #endif #ifdef DECODE_SAMSUNG -#ifdef DEBUG - Serial.println("Attempting SAMSUNG decode"); -#endif + DBG_PRINTLN("Attempting SAMSUNG decode"); if (decodeSAMSUNG(results)) return DECODED ; #endif #ifdef DECODE_WHYNTER -#ifdef DEBUG - Serial.println("Attempting Whynter decode"); -#endif + DBG_PRINTLN("Attempting Whynter decode"); if (decodeWhynter(results)) return DECODED ; #endif #ifdef AIWA_RC_T501 -#ifdef DEBUG - Serial.println("Attempting Aiwa RC-T501 decode"); -#endif + DBG_PRINTLN("Attempting Aiwa RC-T501 decode"); if (decodeAiwaRCT501(results)) return DECODED ; #endif @@ -848,14 +832,7 @@ int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int *used = 0; (*offset)++; } -#ifdef DEBUG - if (val == MARK) { - Serial.println("MARK"); - } - else { - Serial.println("SPACE"); - } -#endif + DBG_PRINTLN( (val == MARK) ? "MARK" : "SPACE" ); return val; } From 6af9a1b4853b994e9012ef13bcd6b70052319202 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Wed, 17 Jun 2015 23:12:32 +0100 Subject: [PATCH 051/768] Whitespace cleanup on for() loops --- IRremote.cpp | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 40255c087..3377ae845 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -106,7 +106,7 @@ void IRsend::sendNEC (unsigned long data, int nbits) enableIROut(38); mark(NEC_HDR_MARK); space(NEC_HDR_SPACE); - for (int i = 0; i < nbits; i++) { + for (int i = 0; i < nbits; i++) { if (data & TOPBIT) { mark(NEC_BIT_MARK); space(NEC_ONE_SPACE); @@ -131,7 +131,7 @@ void IRsend::sendWhynter (unsigned long data, int nbits) space(WHYNTER_ZERO_SPACE); mark(WHYNTER_HDR_MARK); space(WHYNTER_HDR_SPACE); - for (int i = 0; i < nbits; i++) { + for (int i = 0; i < nbits; i++) { if (data & TOPBIT) { mark(WHYNTER_ONE_MARK); space(WHYNTER_ONE_SPACE); @@ -155,7 +155,7 @@ void IRsend::sendSony (unsigned long data, int nbits) mark(SONY_HDR_MARK); space(SONY_HDR_SPACE); data = data << (32 - nbits); - for (int i = 0; i < nbits; i++) { + for (int i = 0; i < nbits; i++) { if (data & TOPBIT) { mark(SONY_ONE_MARK); space(SONY_HDR_SPACE); @@ -173,7 +173,7 @@ void IRsend::sendSony (unsigned long data, int nbits) void IRsend::sendRaw (unsigned int buf[], int len, int hz) { enableIROut(hz); - for (int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { if (i & 1) space(buf[i]) ; else mark (buf[i]) ; } @@ -191,7 +191,7 @@ void IRsend::sendRC5 (unsigned long data, int nbits) mark(RC5_T1); // First start bit space(RC5_T1); // Second start bit mark(RC5_T1); // Second start bit - for (int i = 0; i < nbits; i++) { + for (int i = 0; i < nbits; i++) { if (data & TOPBIT) { space(RC5_T1); // 1 is space, then mark mark(RC5_T1); @@ -219,7 +219,7 @@ void IRsend::sendRC6 (unsigned long data, int nbits) mark(RC6_T1); // start bit space(RC6_T1); int t; - for (int i = 0; i < nbits; i++) { + for (int i = 0; i < nbits; i++) { if (i == 3) t = RC6_T1 * 2 ; // double-wide trailer bit else t = RC6_T1 ; if (data & TOPBIT) { @@ -245,14 +245,14 @@ void IRsend::sendPanasonic (unsigned int address, unsigned long data) mark(PANASONIC_HDR_MARK); space(PANASONIC_HDR_SPACE); - for(int i=0;i<16;i++) + 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++) { + for (int i = 0; i < 32; i++) { mark(PANASONIC_BIT_MARK); if (data & TOPBIT) space(PANASONIC_ONE_SPACE) ; else space(PANASONIC_ZERO_SPACE) ; @@ -273,7 +273,7 @@ void IRsend::sendJVC (unsigned long data, int nbits, int repeat) mark(JVC_HDR_MARK); space(JVC_HDR_SPACE); } - for (int i = 0; i < nbits; i++) { + for (int i = 0; i < nbits; i++) { if (data & TOPBIT) { mark(JVC_BIT_MARK); space(JVC_ONE_SPACE); @@ -296,7 +296,7 @@ void IRsend::sendSAMSUNG (unsigned long data, int nbits) enableIROut(38); mark(SAMSUNG_HDR_MARK); space(SAMSUNG_HDR_SPACE); - for (int i = 0; i < nbits; i++) { + for (int i = 0; i < nbits; i++) { if (data & TOPBIT) { mark(SAMSUNG_BIT_MARK); space(SAMSUNG_ONE_SPACE); @@ -580,7 +580,7 @@ long IRrecv::decodeNEC (decode_results *results) // Initial space if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) return ERR ; offset++; - for (int i = 0; i < NEC_BITS; i++) { + for (int i = 0; i < NEC_BITS; i++) { if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) return ERR ; offset++; if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE)) data = (data << 1) | 1 ; @@ -667,7 +667,7 @@ long IRrecv::decodeWhynter (decode_results *results) offset++; // data bits - for (int i = 0; i < WHYNTER_BITS; i++) { + for (int i = 0; i < WHYNTER_BITS; i++) { if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return ERR ; offset++; if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ONE_SPACE)) data = (data << 1) | 1 ; @@ -849,7 +849,7 @@ long IRrecv::decodeRC5 (decode_results *results) if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return ERR ; if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR ; int nbits; - for (nbits = 0; offset < irparams.rawlen; 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 @@ -882,7 +882,7 @@ long IRrecv::decodeRC6 (decode_results *results) if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return ERR ; if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return ERR ; int nbits; - for (nbits = 0; offset < results->rawlen; nbits++) { + for (nbits = 0; offset < results->rawlen; nbits++) { int levelA, levelB; // Next two levels levelA = getRClevel(results, &offset, &used, RC6_T1); if (nbits == 3) { @@ -919,7 +919,7 @@ long IRrecv::decodePanasonic (decode_results *results) offset++; // decode address - for (int i = 0; i < PANASONIC_BITS; i++) { + 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 ; @@ -948,7 +948,7 @@ long IRrecv::decodeLG (decode_results *results) // Initial space if (!MATCH_SPACE(results->rawbuf[offset], LG_HDR_SPACE)) return ERR ; offset++; - for (int i = 0; i < LG_BITS; i++) { + for (int i = 0; i < LG_BITS; i++) { if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return ERR ; offset++; if (MATCH_SPACE(results->rawbuf[offset], LG_ONE_SPACE)) data = (data << 1) | 1 ; @@ -990,7 +990,7 @@ long IRrecv::decodeJVC (decode_results *results) // Initial space if (!MATCH_SPACE(results->rawbuf[offset], JVC_HDR_SPACE)) return ERR ; offset++; - for (int i = 0; i < JVC_BITS; i++) { + 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 ; @@ -1032,7 +1032,7 @@ long IRrecv::decodeSAMSUNG (decode_results *results) // Initial space if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) return ERR ; offset++; - for (int i = 0; i < SAMSUNG_BITS; i++) { + for (int i = 0; i < SAMSUNG_BITS; i++) { if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_BIT_MARK)) return ERR ; offset++; if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ONE_SPACE)) data = (data << 1) | 1 ; @@ -1129,7 +1129,7 @@ long IRrecv::decodeHash (decode_results *results) // Require at least 6 samples to prevent triggering on noise if (results->rawlen < 6) return ERR ; long hash = FNV_BASIS_32; - for (int i = 1; i+2 < results->rawlen; i++) { + 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; @@ -1170,8 +1170,8 @@ void IRsend::sendSharp (unsigned long data, int nbits) // 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 (int i = 1 << (nbits-1); i > 0; i>>=1) { + for (int n = 0; n < 3; n++) { + for (int i = 1 << (nbits - 1); i > 0; i >>= 1) { if (data & i) { mark(SHARP_BIT_MARK); space(SHARP_ONE_SPACE); @@ -1207,7 +1207,7 @@ void IRsend::sendDISH (unsigned long data, int nbits) enableIROut(56); mark(DISH_HDR_MARK); space(DISH_HDR_SPACE); - for (int i = 0; i < nbits; i++) { + for (int i = 0; i < nbits; i++) { if (data & DISH_TOP_BIT) { mark(DISH_BIT_MARK); space(DISH_ONE_SPACE); @@ -1242,7 +1242,7 @@ void IRsend::sendAiwaRCT501 (int code) // Skip leading zero's pre <<= 6; // Send pre-data - for(i=0; i < 26; i++) { + for (i = 0; i < 26; i++) { mark(AIWA_RC_T501_BIT_MARK); if (pre & TOPBIT) space(AIWA_RC_T501_ONE_SPACE) ; else space(AIWA_RC_T501_ZERO_SPACE) ; @@ -1252,7 +1252,7 @@ void IRsend::sendAiwaRCT501 (int code) // Skip firts code bit code <<= 1; // Send code - for(i=0; i < 15; i++) { + for (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) ; From 001ccf94257c9e3d15d981c561d8b99ac492f79b Mon Sep 17 00:00:00 2001 From: Bluechip Date: Thu, 18 Jun 2015 19:24:21 +0100 Subject: [PATCH 052/768] Optimise send() loops Query accuracy of sendAiwaRCT501() [see inline comment] --- IRremote.cpp | 65 ++++++++++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 3377ae845..7102d8b90 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -106,8 +106,8 @@ void IRsend::sendNEC (unsigned long data, int nbits) enableIROut(38); mark(NEC_HDR_MARK); space(NEC_HDR_SPACE); - for (int i = 0; i < nbits; i++) { - if (data & TOPBIT) { + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { mark(NEC_BIT_MARK); space(NEC_ONE_SPACE); } @@ -115,7 +115,6 @@ void IRsend::sendNEC (unsigned long data, int nbits) mark(NEC_BIT_MARK); space(NEC_ZERO_SPACE); } - data <<= 1; } mark(NEC_BIT_MARK); space(0); @@ -131,8 +130,8 @@ void IRsend::sendWhynter (unsigned long data, int nbits) space(WHYNTER_ZERO_SPACE); mark(WHYNTER_HDR_MARK); space(WHYNTER_HDR_SPACE); - for (int i = 0; i < nbits; i++) { - if (data & TOPBIT) { + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { mark(WHYNTER_ONE_MARK); space(WHYNTER_ONE_SPACE); } @@ -140,7 +139,6 @@ void IRsend::sendWhynter (unsigned long data, int nbits) mark(WHYNTER_ZERO_MARK); space(WHYNTER_ZERO_SPACE); } - data <<= 1; } mark(WHYNTER_ZERO_MARK); space(WHYNTER_ZERO_SPACE); @@ -154,9 +152,8 @@ void IRsend::sendSony (unsigned long data, int nbits) enableIROut(40); mark(SONY_HDR_MARK); space(SONY_HDR_SPACE); - data = data << (32 - nbits); - for (int i = 0; i < nbits; i++) { - if (data & TOPBIT) { + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { mark(SONY_ONE_MARK); space(SONY_HDR_SPACE); } @@ -164,7 +161,6 @@ void IRsend::sendSony (unsigned long data, int nbits) mark(SONY_ZERO_MARK); space(SONY_HDR_SPACE); } - data <<= 1; } } #endif @@ -187,12 +183,11 @@ void IRsend::sendRaw (unsigned int buf[], int len, int hz) void IRsend::sendRC5 (unsigned long data, int nbits) { enableIROut(36); - data = data << (32 - nbits); mark(RC5_T1); // First start bit space(RC5_T1); // Second start bit mark(RC5_T1); // Second start bit - for (int i = 0; i < nbits; i++) { - if (data & TOPBIT) { + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { space(RC5_T1); // 1 is space, then mark mark(RC5_T1); } @@ -200,7 +195,6 @@ void IRsend::sendRC5 (unsigned long data, int nbits) mark(RC5_T1); space(RC5_T1); } - data <<= 1; } space(0); // Turn off at end } @@ -213,16 +207,15 @@ void IRsend::sendRC5 (unsigned long data, int nbits) void IRsend::sendRC6 (unsigned long data, int nbits) { enableIROut(36); - data = data << (32 - nbits); mark(RC6_HDR_MARK); space(RC6_HDR_SPACE); mark(RC6_T1); // start bit space(RC6_T1); - int t; - for (int i = 0; i < nbits; i++) { + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + int t; if (i == 3) t = RC6_T1 * 2 ; // double-wide trailer bit else t = RC6_T1 ; - if (data & TOPBIT) { + if (data & mask) { mark(t); space(t); } @@ -230,8 +223,6 @@ void IRsend::sendRC6 (unsigned long data, int nbits) space(t); mark(t); } - - data <<= 1; } space(0); // Turn off at end } @@ -245,18 +236,16 @@ void IRsend::sendPanasonic (unsigned int address, unsigned long data) mark(PANASONIC_HDR_MARK); space(PANASONIC_HDR_SPACE); - for (int i = 0; i < 16; i++) + for (unsigned long mask = 1 << (16 - 1); mask; mask >>= 1) { { mark(PANASONIC_BIT_MARK); - if (address & 0x8000) space(PANASONIC_ONE_SPACE) ; - else space(PANASONIC_ZERO_SPACE) ; - address <<= 1; + if (address & mask) space(PANASONIC_ONE_SPACE) ; + else space(PANASONIC_ZERO_SPACE) ; } - for (int i = 0; i < 32; i++) { + for (unsigned long mask = 1 << (32 - 1); mask; mask >>= 1) { mark(PANASONIC_BIT_MARK); - if (data & TOPBIT) space(PANASONIC_ONE_SPACE) ; - else space(PANASONIC_ZERO_SPACE) ; - data <<= 1; + if (data & mask) space(PANASONIC_ONE_SPACE) ; + else space(PANASONIC_ZERO_SPACE) ; } mark(PANASONIC_BIT_MARK); space(0); @@ -268,13 +257,12 @@ void IRsend::sendPanasonic (unsigned int address, unsigned long data) 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) { + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { mark(JVC_BIT_MARK); space(JVC_ONE_SPACE); } @@ -282,7 +270,6 @@ void IRsend::sendJVC (unsigned long data, int nbits, int repeat) mark(JVC_BIT_MARK); space(JVC_ZERO_SPACE); } - data <<= 1; } mark(JVC_BIT_MARK); space(0); @@ -296,8 +283,8 @@ void IRsend::sendSAMSUNG (unsigned long data, int nbits) enableIROut(38); mark(SAMSUNG_HDR_MARK); space(SAMSUNG_HDR_SPACE); - for (int i = 0; i < nbits; i++) { - if (data & TOPBIT) { + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { mark(SAMSUNG_BIT_MARK); space(SAMSUNG_ONE_SPACE); } @@ -305,7 +292,6 @@ void IRsend::sendSAMSUNG (unsigned long data, int nbits) mark(SAMSUNG_BIT_MARK); space(SAMSUNG_ZERO_SPACE); } - data <<= 1; } mark(SAMSUNG_BIT_MARK); space(0); @@ -1171,8 +1157,8 @@ void IRsend::sendSharp (unsigned long data, int nbits) // 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 (int i = 1 << (nbits - 1); i > 0; i >>= 1) { - if (data & i) { + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { mark(SHARP_BIT_MARK); space(SHARP_ONE_SPACE); } @@ -1207,8 +1193,8 @@ void IRsend::sendDISH (unsigned long data, int nbits) enableIROut(56); mark(DISH_HDR_MARK); space(DISH_HDR_SPACE); - for (int i = 0; i < nbits; i++) { - if (data & DISH_TOP_BIT) { + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + if (data & mark) { mark(DISH_BIT_MARK); space(DISH_ONE_SPACE); } @@ -1216,7 +1202,6 @@ void IRsend::sendDISH (unsigned long data, int nbits) mark(DISH_BIT_MARK); space(DISH_ZERO_SPACE); } - data <<= 1; } } #endif From a338d5525a1e44e33fa552dfd2705e9f635a4e24 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Thu, 18 Jun 2015 19:52:22 +0100 Subject: [PATCH 053/768] Bit more cleanup Guests have arrived - sanity checkin --- IRremote.cpp | 288 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 182 insertions(+), 106 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 7102d8b90..b32c6368a 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -103,19 +103,22 @@ int MATCH_SPACE (int measured_ticks, int desired_us) #ifdef SEND_NEC void IRsend::sendNEC (unsigned long data, int nbits) { + // Set IR carrier frequency enableIROut(38); + mark(NEC_HDR_MARK); space(NEC_HDR_SPACE); + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(NEC_BIT_MARK); space(NEC_ONE_SPACE); - } - else { + } else { mark(NEC_BIT_MARK); space(NEC_ZERO_SPACE); } } + mark(NEC_BIT_MARK); space(0); } @@ -125,21 +128,24 @@ void IRsend::sendNEC (unsigned long data, int nbits) #ifdef SEND_WHYNTER void IRsend::sendWhynter (unsigned long data, int nbits) { + // Set IR carrier frequency enableIROut(38); + mark(WHYNTER_ZERO_MARK); space(WHYNTER_ZERO_SPACE); mark(WHYNTER_HDR_MARK); space(WHYNTER_HDR_SPACE); + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(WHYNTER_ONE_MARK); space(WHYNTER_ONE_SPACE); - } - else { + } else { mark(WHYNTER_ZERO_MARK); space(WHYNTER_ZERO_SPACE); } } + mark(WHYNTER_ZERO_MARK); space(WHYNTER_ZERO_SPACE); } @@ -149,15 +155,17 @@ void IRsend::sendWhynter (unsigned long data, int nbits) #ifdef SEND_SONY void IRsend::sendSony (unsigned long data, int nbits) { + // Set IR carrier frequency enableIROut(40); + mark(SONY_HDR_MARK); space(SONY_HDR_SPACE); + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(SONY_ONE_MARK); space(SONY_HDR_SPACE); - } - else { + } else { mark(SONY_ZERO_MARK); space(SONY_HDR_SPACE); } @@ -168,11 +176,14 @@ void IRsend::sendSony (unsigned long data, int nbits) //+============================================================================= 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); // Just to be sure } @@ -182,20 +193,23 @@ void IRsend::sendRaw (unsigned int buf[], int len, int hz) #ifdef SEND_RC5 void IRsend::sendRC5 (unsigned long data, int nbits) { + // Set IR carrier frequency enableIROut(36); + mark(RC5_T1); // First start bit space(RC5_T1); // Second start bit mark(RC5_T1); // Second start bit + 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 { + } else { mark(RC5_T1); space(RC5_T1); } } + space(0); // Turn off at end } #endif @@ -206,24 +220,25 @@ void IRsend::sendRC5 (unsigned long data, int nbits) #ifdef SEND_RC6 void IRsend::sendRC6 (unsigned long data, int nbits) { + // Set IR carrier frequency enableIROut(36); + mark(RC6_HDR_MARK); space(RC6_HDR_SPACE); mark(RC6_T1); // start bit space(RC6_T1); + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { - int t; - if (i == 3) t = RC6_T1 * 2 ; // double-wide trailer bit - else t = RC6_T1 ; + int t = (i == 3) ? (RC6_T1 * 2) : (RC6_T1) ; if (data & mask) { mark(t); space(t); - } - else { + } else { space(t); mark(t); } } + space(0); // Turn off at end } #endif @@ -232,7 +247,9 @@ void IRsend::sendRC6 (unsigned long data, int nbits) #ifdef SEND_PANASONIC void IRsend::sendPanasonic (unsigned int address, unsigned long data) { + // Set IR carrier frequency enableIROut(35); + mark(PANASONIC_HDR_MARK); space(PANASONIC_HDR_SPACE); @@ -242,11 +259,13 @@ void IRsend::sendPanasonic (unsigned int address, unsigned long data) if (address & mask) space(PANASONIC_ONE_SPACE) ; else space(PANASONIC_ZERO_SPACE) ; } + 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) ; } + mark(PANASONIC_BIT_MARK); space(0); } @@ -256,11 +275,14 @@ void IRsend::sendPanasonic (unsigned int address, unsigned long data) #ifdef SEND_JVC void IRsend::sendJVC (unsigned long data, int nbits, int repeat) { + // Set IR carrier frequency enableIROut(38); + if (!repeat){ mark(JVC_HDR_MARK); space(JVC_HDR_SPACE); } + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(JVC_BIT_MARK); @@ -271,6 +293,7 @@ void IRsend::sendJVC (unsigned long data, int nbits, int repeat) space(JVC_ZERO_SPACE); } } + mark(JVC_BIT_MARK); space(0); } @@ -280,19 +303,22 @@ void IRsend::sendJVC (unsigned long data, int nbits, int repeat) #ifdef SEND_SAMSUNG void IRsend::sendSAMSUNG (unsigned long data, int nbits) { + // Set IR carrier frequency enableIROut(38); + mark(SAMSUNG_HDR_MARK); space(SAMSUNG_HDR_SPACE); + 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); - } + if (data & mask) { + mark(SAMSUNG_BIT_MARK); + space(SAMSUNG_ONE_SPACE); + } else { + mark(SAMSUNG_BIT_MARK); + space(SAMSUNG_ZERO_SPACE); + } } + mark(SAMSUNG_BIT_MARK); space(0); } @@ -407,48 +433,52 @@ ISR (TIMER_INTR_NAME) 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. + 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; } - else { - // gap just ended, record duration and start recording transmission - irparams.rawlen = 0; + 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; } - } - 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; + 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; + break; + + case STATE_STOP: // waiting, measuring gap + if (irdata == MARK) irparams.timer = 0 ; // reset gap timer + break; } if (irparams.blinkflag) { @@ -473,7 +503,9 @@ int IRrecv::decode (decode_results *results) { results->rawbuf = irparams.rawbuf; results->rawlen = irparams.rawlen; + if (irparams.rcvstate != STATE_STOP) return ERR ; + #ifdef DECODE_NEC DBG_PRINTLN("Attempting NEC decode"); if (decodeNEC(results)) return DECODED ; @@ -550,9 +582,11 @@ long IRrecv::decodeNEC (decode_results *results) { long data = 0; int offset = 1; // Skip first space + // Initial mark if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) return ERR ; offset++; + // Check for repeat if (irparams.rawlen == 4 && MATCH_SPACE(results->rawbuf[offset], NEC_RPT_SPACE) && @@ -563,9 +597,11 @@ long IRrecv::decodeNEC (decode_results *results) return DECODED; } if (irparams.rawlen < 2 * NEC_BITS + 4) return ERR ; + // Initial space if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) return ERR ; offset++; + for (int i = 0; i < NEC_BITS; i++) { if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) return ERR ; offset++; @@ -574,10 +610,12 @@ long IRrecv::decodeNEC (decode_results *results) else return ERR ; offset++; } + // Success - results->bits = NEC_BITS; - results->value = data; + results->bits = NEC_BITS; + results->value = data; results->decode_type = NEC; + return DECODED; } #endif @@ -596,11 +634,13 @@ long IRrecv::decodeSony (decode_results *results) // Serial.print("IR Gap found: "); results->bits = 0; results->value = REPEAT; -#ifdef DECODE_SANYO - results->decode_type = SANYO; -#else - results->decode_type = UNKNOWN; -#endif + +# ifdef DECODE_SANYO + results->decode_type = SANYO; +# else + results->decode_type = UNKNOWN; +# endif + return DECODED; } offset++; @@ -624,7 +664,7 @@ long IRrecv::decodeSony (decode_results *results) results->bits = 0; return ERR; } - results->value = data; + results->value = data; results->decode_type = SONY; return DECODED; } @@ -656,6 +696,7 @@ long IRrecv::decodeWhynter (decode_results *results) for (int i = 0; i < WHYNTER_BITS; i++) { if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return ERR ; 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 ERR ; @@ -664,6 +705,7 @@ long IRrecv::decodeWhynter (decode_results *results) // trailing mark if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return ERR ; + // Success results->bits = WHYNTER_BITS; results->value = data; @@ -724,7 +766,8 @@ long IRrecv::decodeSanyo (decode_results *results) results->bits = 0; return ERR; } - results->value = data; + + results->value = data; results->decode_type = SANYO; return DECODED; } @@ -761,7 +804,6 @@ long IRrecv::decodeMitsubishi (decode_results *results) } #endif - offset++; // Typical @@ -770,11 +812,13 @@ long IRrecv::decodeMitsubishi (decode_results *results) // Initial Space if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) return ERR ; 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 ERR ; offset++; + if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) break ; offset++; } @@ -785,7 +829,8 @@ long IRrecv::decodeMitsubishi (decode_results *results) results->bits = 0; return ERR; } - results->value = data; + + results->value = data; results->decode_type = MITSUBISHI; return DECODED; } @@ -818,6 +863,7 @@ int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int *used = 0; (*offset)++; } + DBG_PRINTLN( (val == MARK) ? "MARK" : "SPACE" ); return val; } @@ -838,14 +884,15 @@ long IRrecv::decodeRC5 (decode_results *results) 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 ERR ; } // Success - results->bits = nbits; - results->value = data; + results->bits = nbits; + results->value = data; results->decode_type = RC5; return DECODED; } @@ -857,13 +904,17 @@ long IRrecv::decodeRC6 (decode_results *results) { if (results->rawlen < MIN_RC6_SAMPLES) return ERR ; int offset = 1; // Skip first space + // Initial mark if (!MATCH_MARK(results->rawbuf[offset], RC6_HDR_MARK)) return ERR ; offset++; + if (!MATCH_SPACE(results->rawbuf[offset], RC6_HDR_SPACE)) return ERR ; offset++; - long data = 0; - int used = 0; + + long data = 0; + int used = 0; + // Get start bit (1) if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return ERR ; if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return ERR ; @@ -884,6 +935,7 @@ long IRrecv::decodeRC6 (decode_results *results) else if (levelA == SPACE && levelB == MARK) data <<= 1 ; // zero bit else return ERR ; // Error } + // Success results->bits = nbits; results->value = data; @@ -907,15 +959,18 @@ long IRrecv::decodePanasonic (decode_results *results) // 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->value = (unsigned long)data; results->panasonicAddress = (unsigned int)(data >> 32); - results->decode_type = PANASONIC; - results->bits = PANASONIC_BITS; + results->decode_type = PANASONIC; + results->bits = PANASONIC_BITS; + return DECODED; } #endif @@ -924,8 +979,8 @@ long IRrecv::decodePanasonic (decode_results *results) #ifdef DECODE_LG long IRrecv::decodeLG (decode_results *results) { - long data = 0; - int offset = 1; // Skip first space + long data = 0; + int offset = 1; // Skip first space // Initial mark if (!MATCH_MARK(results->rawbuf[offset], LG_HDR_MARK)) return ERR ; @@ -942,24 +997,25 @@ long IRrecv::decodeLG (decode_results *results) else return ERR ; offset++; } - //Stop bit + + // Stop bit if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return ERR ; + // Success results->bits = LG_BITS; results->value = data; results->decode_type = LG; return DECODED; } - - #endif //+============================================================================= #ifdef DECODE_JVC long IRrecv::decodeJVC (decode_results *results) { - long data = 0; - int offset = 1; // Skip first space + 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) && @@ -969,13 +1025,17 @@ long IRrecv::decodeJVC (decode_results *results) 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++; @@ -984,12 +1044,15 @@ long IRrecv::decodeJVC (decode_results *results) else return ERR ; offset++; } - //Stop bit + + // Stop bit if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return ERR ; + // Success - results->bits = JVC_BITS; - results->value = data; + results->bits = JVC_BITS; + results->value = data; results->decode_type = JVC; + return DECODED; } #endif @@ -1000,11 +1063,13 @@ long IRrecv::decodeJVC (decode_results *results) #ifdef DECODE_SAMSUNG long IRrecv::decodeSAMSUNG (decode_results *results) { - long data = 0; - int offset = 1; // Skip first space + long data = 0; + int offset = 1; // Skip first space + // Initial mark if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return ERR ; offset++; + // Check for repeat if (irparams.rawlen == 4 && MATCH_SPACE(results->rawbuf[offset], SAMSUNG_RPT_SPACE) && @@ -1015,20 +1080,25 @@ long IRrecv::decodeSAMSUNG (decode_results *results) return DECODED; } if (irparams.rawlen < 2 * SAMSUNG_BITS + 4) return ERR ; + // Initial space if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) return ERR ; offset++; + for (int i = 0; i < SAMSUNG_BITS; i++) { if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_BIT_MARK)) return ERR ; + 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 ERR ; offset++; } + // Success - results->bits = SAMSUNG_BITS; - results->value = data; + results->bits = SAMSUNG_BITS; + results->value = data; results->decode_type = SAMSUNG; return DECODED; } @@ -1042,8 +1112,8 @@ long IRrecv::decodeSAMSUNG (decode_results *results) #ifdef DECODE_AIWA_RC_T501 long IRrecv::decodeAiwaRCT501 (decode_results *results) { - int data = 0; - int offset = 1; // skip first garbage read + int data = 0; + int offset = 1; // skip first garbage read // Check SIZE if (irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) return ERR ; @@ -1070,11 +1140,10 @@ long IRrecv::decodeAiwaRCT501 (decode_results *results) results->bits = (offset - 1) / 2; if (results->bits < 42) return ERR ; - results->value = data; + results->value = data; results->decode_type = AIWA_RC_T501; return DECODED; } - #endif //+============================================================================= @@ -1120,9 +1189,11 @@ long IRrecv::decodeHash (decode_results *results) // Add value into the hash hash = (hash * FNV_PRIME_32) ^ value; } - results->value = hash; - results->bits = 32; + + results->value = hash; + results->bits = 32; results->decode_type = UNKNOWN; + return DECODED; } @@ -1151,7 +1222,7 @@ long IRrecv::decodeHash (decode_results *results) #ifdef SEND_SHARP void IRsend::sendSharp (unsigned long data, int nbits) { - unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; + unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; enableIROut(38); // Sending codes in bursts of 3 (normal, inverted, normal) makes transmission @@ -1161,8 +1232,7 @@ void IRsend::sendSharp (unsigned long data, int nbits) if (data & mask) { mark(SHARP_BIT_MARK); space(SHARP_ONE_SPACE); - } - else { + } else { mark(SHARP_BIT_MARK); space(SHARP_ZERO_SPACE); } @@ -1190,15 +1260,17 @@ void IRsend::sendSharp (unsigned int address, unsigned int command) #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 & mark) { mark(DISH_BIT_MARK); space(DISH_ONE_SPACE); - } - else { + } else { mark(DISH_BIT_MARK); space(DISH_ZERO_SPACE); } @@ -1215,25 +1287,27 @@ void IRsend::sendDISH (unsigned long data, int nbits) void IRsend::sendAiwaRCT501 (int code) { // PRE-DATA, 26 bits, 0x227EEC0 - long int pre = 0x227EEC0; - int i; + unsigned long pre = 0x227EEC0; + int mask; + // Set IR carrier frequency enableIROut(AIWA_RC_T501_HZ); // HDR mark + HDR space mark(AIWA_RC_T501_HDR_MARK); space(AIWA_RC_T501_HDR_SPACE); - // Skip leading zero's - pre <<= 6; // Send pre-data - for (i = 0; i < 26; i++) { + for (unsigned long mask = 1 << (26 - 1); mask; mask >>= 1) { mark(AIWA_RC_T501_BIT_MARK); - if (pre & TOPBIT) space(AIWA_RC_T501_ONE_SPACE) ; - else space(AIWA_RC_T501_ZERO_SPACE) ; - pre <<= 1; + 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 @@ -1243,6 +1317,8 @@ void IRsend::sendAiwaRCT501 (int code) 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); From 5f92834a12488bd92c2189da212e531556883a59 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Fri, 19 Jun 2015 00:12:29 +0100 Subject: [PATCH 054/768] Finish sendXXX() cleanup Move NEC decode to be with NEC send --- IRremote.cpp | 617 +++++++++++++++++++++++++++++---------------------- 1 file changed, 353 insertions(+), 264 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index b32c6368a..df9b069f9 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -100,227 +100,361 @@ int MATCH_SPACE (int measured_ticks, int desired_us) #endif //+============================================================================= +// RRRR AAA W W +// R R A A W W +// RRRR AAAAA W W W +// R R A A W W W +// R R A A WWW +// +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); // Just to be sure +} + +//+============================================================================= +// N N EEEEE CCCC +// NN N E C +// N N N EEE C +// N NN E C +// N N EEEEE CCCC +// #ifdef SEND_NEC void IRsend::sendNEC (unsigned long data, int nbits) { - // Set IR carrier frequency - enableIROut(38); + // Set IR carrier frequency + enableIROut(38); - mark(NEC_HDR_MARK); - space(NEC_HDR_SPACE); + // Header + mark(NEC_HDR_MARK); + space(NEC_HDR_SPACE); - 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); - } - } + // 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); // Alwasy end with the LED off +} +#endif - mark(NEC_BIT_MARK); - space(0); +//+============================================================================= +// 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 //+============================================================================= +// 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 +// #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); - } - } - + 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); + space(WHYNTER_ZERO_SPACE); // Always end with the LED off } #endif //+============================================================================= +// 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 +// #ifdef SEND_SONY void IRsend::sendSony (unsigned long data, int nbits) { - // Set IR carrier frequency - enableIROut(40); + // Set IR carrier frequency + enableIROut(40); - mark(SONY_HDR_MARK); - space(SONY_HDR_SPACE); + // Header + mark(SONY_HDR_MARK); + space(SONY_HDR_SPACE); - 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); - } - } + // 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 //+============================================================================= -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); // Just to be sure -} - -//+============================================================================= +// RRRR CCCC 55555 +// R R C 5 +// R R C 5555 +// RRRR C 5 +// R R C 5 5 +// R R CCCC 555 +// // Note: first bit must be a one (start bit) // #ifdef SEND_RC5 void IRsend::sendRC5 (unsigned long data, int nbits) { - // Set IR carrier frequency - enableIROut(36); - - mark(RC5_T1); // First start bit - space(RC5_T1); // Second start bit - mark(RC5_T1); // Second start bit + // Set IR carrier frequency + enableIROut(36); - 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); - } - } + // Start + mark(RC5_T1); + space(RC5_T1); + mark(RC5_T1); - space(0); // Turn off at end + // 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 //+============================================================================= -// Caller needs to take care of flipping the toggle bit +// RRRR CCCC 666 +// R R C 6 +// R R C 6 66 +// RRRR C 66 6 +// R R C 6 6 +// R R CCCC 666 +// +// NB : Caller needs to take care of flipping the toggle bit // #ifdef SEND_RC6 void IRsend::sendRC6 (unsigned long data, int nbits) { - // Set IR carrier frequency - enableIROut(36); + // Set IR carrier frequency + enableIROut(36); - mark(RC6_HDR_MARK); - space(RC6_HDR_SPACE); - mark(RC6_T1); // start bit - space(RC6_T1); + // Header + mark(RC6_HDR_MARK); + space(RC6_HDR_SPACE); - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { - int t = (i == 3) ? (RC6_T1 * 2) : (RC6_T1) ; - if (data & mask) { - mark(t); - space(t); - } else { - space(t); - mark(t); - } - } + // Start bit + mark(RC6_T1); + space(RC6_T1); - space(0); // Turn off at end + // Data + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + int t = (i == 3) ? (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 //+============================================================================= +// 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 +// #ifdef SEND_PANASONIC void IRsend::sendPanasonic (unsigned int address, unsigned long data) { // Set IR carrier frequency - enableIROut(35); + enableIROut(35); - mark(PANASONIC_HDR_MARK); - space(PANASONIC_HDR_SPACE); + // 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) ; + 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); + space(0); // Always end with the LED off } #endif //+============================================================================= +// JJJJJ V V CCCC +// J V V C +// J V V C +// J J V V C +// J V CCCC +// #ifdef SEND_JVC void IRsend::sendJVC (unsigned long data, int nbits, int repeat) { // Set IR carrier frequency - enableIROut(38); + enableIROut(38); - if (!repeat){ - mark(JVC_HDR_MARK); - space(JVC_HDR_SPACE); - } + // 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); - } - } - + 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); + space(0); // Always end with the LED off } #endif //+============================================================================= +// 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 +// #ifdef SEND_SAMSUNG void IRsend::sendSAMSUNG (unsigned long data, int nbits) { - // Set IR carrier frequency - enableIROut(38); - - mark(SAMSUNG_HDR_MARK); - space(SAMSUNG_HDR_SPACE); + // Set IR carrier frequency + enableIROut(38); - 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); - } - } + // Header + mark(SAMSUNG_HDR_MARK); + space(SAMSUNG_HDR_SPACE); - mark(SAMSUNG_BIT_MARK); - space(0); + // 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 @@ -504,128 +638,83 @@ int IRrecv::decode (decode_results *results) results->rawbuf = irparams.rawbuf; results->rawlen = irparams.rawlen; - if (irparams.rcvstate != STATE_STOP) return ERR ; + if (irparams.rcvstate != STATE_STOP) return false ; #ifdef DECODE_NEC DBG_PRINTLN("Attempting NEC decode"); - if (decodeNEC(results)) return DECODED ; + if (decodeNEC(results)) return true ; #endif #ifdef DECODE_SONY DBG_PRINTLN("Attempting Sony decode"); - if (decodeSony(results)) return DECODED ; + if (decodeSony(results)) return true ; #endif #ifdef DECODE_SANYO DBG_PRINTLN("Attempting Sanyo decode"); - if (decodeSanyo(results)) return DECODED ; + if (decodeSanyo(results)) return true ; #endif #ifdef DECODE_MITSUBISHI DBG_PRINTLN("Attempting Mitsubishi decode"); - if (decodeMitsubishi(results)) return DECODED ; + if (decodeMitsubishi(results)) return true ; #endif #ifdef DECODE_RC5 DBG_PRINTLN("Attempting RC5 decode"); - if (decodeRC5(results)) return DECODED ; + if (decodeRC5(results)) return true ; #endif #ifdef DECODE_RC6 DBG_PRINTLN("Attempting RC6 decode"); - if (decodeRC6(results)) return DECODED ; + if (decodeRC6(results)) return true ; #endif #ifdef DECODE_PANASONIC DBG_PRINTLN("Attempting Panasonic decode"); - if (decodePanasonic(results)) return DECODED ; + if (decodePanasonic(results)) return true ; #endif #ifdef DECODE_LG DBG_PRINTLN("Attempting LG decode"); - if (decodeLG(results)) return DECODED ; + if (decodeLG(results)) return true ; #endif #ifdef DECODE_JVC DBG_PRINTLN("Attempting JVC decode"); - if (decodeJVC(results)) return DECODED ; + if (decodeJVC(results)) return true ; #endif #ifdef DECODE_SAMSUNG DBG_PRINTLN("Attempting SAMSUNG decode"); - if (decodeSAMSUNG(results)) return DECODED ; + if (decodeSAMSUNG(results)) return true ; #endif #ifdef DECODE_WHYNTER DBG_PRINTLN("Attempting Whynter decode"); - if (decodeWhynter(results)) return DECODED ; + if (decodeWhynter(results)) return true ; #endif #ifdef AIWA_RC_T501 DBG_PRINTLN("Attempting Aiwa RC-T501 decode"); - if (decodeAiwaRCT501(results)) return DECODED ; + 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 DECODED ; + if (decodeHash(results)) return true ; // Throw away and start over resume(); - return ERR; + return false; } -//+============================================================================= -#ifdef DECODE_NEC -// NECs have a repeat only 4 items long -long IRrecv::decodeNEC (decode_results *results) -{ - long data = 0; - int offset = 1; // Skip first space - - // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) return ERR ; - 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 DECODED; - } - if (irparams.rawlen < 2 * NEC_BITS + 4) return ERR ; - - // Initial space - if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) return ERR ; - offset++; - - for (int i = 0; i < NEC_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) return ERR ; - offset++; - if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE)) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) data <<= 1 ; - else return ERR ; - offset++; - } - - // Success - results->bits = NEC_BITS; - results->value = data; - results->decode_type = NEC; - - return DECODED; -} -#endif - //+============================================================================= #ifdef DECODE_SONY long IRrecv::decodeSony (decode_results *results) { long data = 0; - if (irparams.rawlen < 2 * SONY_BITS + 2) return ERR ; + 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 @@ -641,12 +730,12 @@ long IRrecv::decodeSony (decode_results *results) results->decode_type = UNKNOWN; # endif - return DECODED; + return true; } offset++; // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], SONY_HDR_MARK)) return ERR ; + if (!MATCH_MARK(results->rawbuf[offset], SONY_HDR_MARK)) return false ; offset++; while (offset + 1 < irparams.rawlen) { @@ -654,7 +743,7 @@ long IRrecv::decodeSony (decode_results *results) 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 ERR ; + else return false ; offset++; } @@ -662,11 +751,11 @@ long IRrecv::decodeSony (decode_results *results) results->bits = (offset - 1) / 2; if (results->bits < 12) { results->bits = 0; - return ERR; + return false; } results->value = data; results->decode_type = SONY; - return DECODED; + return true; } #endif @@ -676,41 +765,41 @@ long IRrecv::decodeWhynter (decode_results *results) { long data = 0; - if (irparams.rawlen < 2 * WHYNTER_BITS + 6) return ERR ; + 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 ERR ; + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return false ; offset++; - if (!MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE)) return ERR ; + 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 ERR ; + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_HDR_MARK)) return false ; offset++; - if (!MATCH_SPACE(results->rawbuf[offset], WHYNTER_HDR_SPACE)) return ERR ; + 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 ERR ; + 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 ERR ; + else return false ; offset++; } // trailing mark - if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return ERR ; + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return false ; // Success results->bits = WHYNTER_BITS; results->value = data; results->decode_type = WHYNTER; - return DECODED; + return true; } #endif @@ -722,7 +811,7 @@ long IRrecv::decodeWhynter (decode_results *results) long IRrecv::decodeSanyo (decode_results *results) { long data = 0; - if (irparams.rawlen < 2 * SANYO_BITS + 2) return ERR ; + if (irparams.rawlen < 2 * SANYO_BITS + 2) return false ; int offset = 0; // Skip first space // Initial space @@ -739,16 +828,16 @@ long IRrecv::decodeSanyo (decode_results *results) results->bits = 0; results->value = REPEAT; results->decode_type = SANYO; - return DECODED; + return true; } offset++; // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) return ERR ; + 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 ERR ; + if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) return false ; offset++; while (offset + 1 < irparams.rawlen) { @@ -756,7 +845,7 @@ long IRrecv::decodeSanyo (decode_results *results) 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 ERR ; + else return false ; offset++; } @@ -764,12 +853,12 @@ long IRrecv::decodeSanyo (decode_results *results) results->bits = (offset - 1) / 2; if (results->bits < 12) { results->bits = 0; - return ERR; + return false; } results->value = data; results->decode_type = SANYO; - return DECODED; + return true; } #endif @@ -781,7 +870,7 @@ 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 ERR ; + if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2) return false ; int offset = 0; // Skip first space // Initial space @@ -800,7 +889,7 @@ long IRrecv::decodeMitsubishi (decode_results *results) results->bits = 0; results->value = REPEAT; results->decode_type = MITSUBISHI; - return DECODED; + return true; } #endif @@ -810,13 +899,13 @@ long IRrecv::decodeMitsubishi (decode_results *results) // 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 ERR ; + 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 ERR ; + else return false ; offset++; if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) break ; @@ -827,12 +916,12 @@ long IRrecv::decodeMitsubishi (decode_results *results) results->bits = (offset - 1) / 2; if (results->bits < MITSUBISHI_BITS) { results->bits = 0; - return ERR; + return false; } results->value = data; results->decode_type = MITSUBISHI; - return DECODED; + return true; } #endif @@ -872,14 +961,14 @@ int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int #ifdef DECODE_RC5 long IRrecv::decodeRC5 (decode_results *results) { - if (irparams.rawlen < MIN_RC5_SAMPLES + 2) return ERR ; + 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 ERR ; - if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return ERR ; - if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR ; + 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); @@ -887,14 +976,14 @@ long IRrecv::decodeRC5 (decode_results *results) if (levelA == SPACE && levelB == MARK) data = (data << 1) | 1 ; // 1 bit else if (levelA == MARK && levelB == SPACE) data <<= 1 ; // zero bit - else return ERR ; + else return false ; } // Success results->bits = nbits; results->value = data; results->decode_type = RC5; - return DECODED; + return true; } #endif @@ -902,45 +991,45 @@ long IRrecv::decodeRC5 (decode_results *results) #ifdef DECODE_RC6 long IRrecv::decodeRC6 (decode_results *results) { - if (results->rawlen < MIN_RC6_SAMPLES) return ERR ; + 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 ERR ; + if (!MATCH_MARK(results->rawbuf[offset], RC6_HDR_MARK)) return false ; offset++; - if (!MATCH_SPACE(results->rawbuf[offset], RC6_HDR_SPACE)) return ERR ; + 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 ERR ; - if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return ERR ; + 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 ERR; + 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 ERR; + 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 ERR ; // Error + else return false ; // Error } // Success results->bits = nbits; results->value = data; results->decode_type = RC6; - return DECODED; + return true; } #endif @@ -951,18 +1040,18 @@ 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 ; + if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_MARK)) return false ; offset++; - if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_SPACE)) return ERR ; + 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 ERR ; + 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 <<= 1 ; - else return ERR ; + else return false ; offset++; } @@ -971,7 +1060,7 @@ long IRrecv::decodePanasonic (decode_results *results) results->decode_type = PANASONIC; results->bits = PANASONIC_BITS; - return DECODED; + return true; } #endif @@ -983,29 +1072,29 @@ long IRrecv::decodeLG (decode_results *results) int offset = 1; // Skip first space // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], LG_HDR_MARK)) return ERR ; + if (!MATCH_MARK(results->rawbuf[offset], LG_HDR_MARK)) return false ; offset++; - if (irparams.rawlen < 2 * LG_BITS + 1 ) return ERR ; + if (irparams.rawlen < 2 * LG_BITS + 1 ) return false ; // Initial space - if (!MATCH_SPACE(results->rawbuf[offset], LG_HDR_SPACE)) return ERR ; + 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 ERR ; + 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 ERR ; + else return false ; offset++; } // Stop bit - if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return ERR ; + if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return false ; // Success results->bits = LG_BITS; results->value = data; results->decode_type = LG; - return DECODED; + return true; } #endif @@ -1023,37 +1112,37 @@ long IRrecv::decodeJVC (decode_results *results) results->bits = 0; results->value = REPEAT; results->decode_type = JVC; - return DECODED; + return true; } // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], JVC_HDR_MARK)) return ERR ; + if (!MATCH_MARK(results->rawbuf[offset], JVC_HDR_MARK)) return false ; offset++; - if (irparams.rawlen < 2 * JVC_BITS + 1 ) return ERR ; + if (irparams.rawlen < 2 * JVC_BITS + 1 ) return false ; // Initial space - if (!MATCH_SPACE(results->rawbuf[offset], JVC_HDR_SPACE)) return ERR ; + 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 ERR ; + 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 ERR ; + else return false ; offset++; } // Stop bit - if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return ERR ; + if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return false ; // Success results->bits = JVC_BITS; results->value = data; results->decode_type = JVC; - return DECODED; + return true; } #endif @@ -1067,7 +1156,7 @@ long IRrecv::decodeSAMSUNG (decode_results *results) int offset = 1; // Skip first space // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return ERR ; + if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return false ; offset++; // Check for repeat @@ -1077,22 +1166,22 @@ long IRrecv::decodeSAMSUNG (decode_results *results) results->bits = 0; results->value = REPEAT; results->decode_type = SAMSUNG; - return DECODED; + return true; } - if (irparams.rawlen < 2 * SAMSUNG_BITS + 4) return ERR ; + if (irparams.rawlen < 2 * SAMSUNG_BITS + 4) return false ; // Initial space - if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) return ERR ; + 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 ERR ; + 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 ERR ; + else return false ; offset++; } @@ -1100,7 +1189,7 @@ long IRrecv::decodeSAMSUNG (decode_results *results) results->bits = SAMSUNG_BITS; results->value = data; results->decode_type = SAMSUNG; - return DECODED; + return true; } #endif @@ -1116,20 +1205,20 @@ long IRrecv::decodeAiwaRCT501 (decode_results *results) int offset = 1; // skip first garbage read // Check SIZE - if (irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) return ERR ; + 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 ERR ; + 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 ERR ; + 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 ERR ; + else return false ; // ONE & ZERO if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ONE_SPACE)) data = (data << 1) | 1 ; @@ -1139,10 +1228,10 @@ long IRrecv::decodeAiwaRCT501 (decode_results *results) } results->bits = (offset - 1) / 2; - if (results->bits < 42) return ERR ; + if (results->bits < 42) return false ; results->value = data; results->decode_type = AIWA_RC_T501; - return DECODED; + return true; } #endif @@ -1182,7 +1271,7 @@ int IRrecv::compare (unsigned int oldval, unsigned int newval) long IRrecv::decodeHash (decode_results *results) { // Require at least 6 samples to prevent triggering on noise - if (results->rawlen < 6) return ERR ; + 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]); @@ -1194,7 +1283,7 @@ long IRrecv::decodeHash (decode_results *results) results->bits = 32; results->decode_type = UNKNOWN; - return DECODED; + return true; } //+============================================================================= From 04e2cfbdadc2c0177a89abaa9f034127675c289e Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 01:20:25 +0100 Subject: [PATCH 055/768] Compiling, all functionality enabled, tested with Panasonic --- IRremote.cpp | 1316 ++++++++++++++++++++++++++++--------------------- IRremote.h | 60 +-- IRremoteInt.h | 144 +----- 3 files changed, 802 insertions(+), 718 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index df9b069f9..bce7b37d3 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -1,3 +1,29 @@ +#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 SEND_AIWA_RC_T501 +#define DECODE_MITSUBISHI +#define DECODE_AIWA_RC_T501 +#define SEND_SHARP +#define SEND_DISH + + + //****************************************************************************** // IRremote // Version 0.11 August, 2009 @@ -108,15 +134,15 @@ int MATCH_SPACE (int measured_ticks, int desired_us) // void IRsend::sendRaw (unsigned int buf[], int len, int hz) { - // Set IR carrier frequency - enableIROut(hz); + // Set IR carrier frequency + enableIROut(hz); - for (int i = 0; i < len; i++) { - if (i & 1) space(buf[i]) ; - else mark (buf[i]) ; - } + for (int i = 0; i < len; i++) { + if (i & 1) space(buf[i]) ; + else mark (buf[i]) ; + } - space(0); // Just to be sure + space(0); // Always end with the LED off } //+============================================================================= @@ -126,6 +152,14 @@ void IRsend::sendRaw (unsigned int buf[], int len, int hz) // 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) { @@ -149,11 +183,11 @@ void IRsend::sendNEC (unsigned long data, int nbits) // Footer mark(NEC_BIT_MARK); - space(0); // Alwasy end with the LED off + space(0); // Always end with the LED off } #endif -//+============================================================================= +//+======================================================== // NECs have a repeat only 4 items long // #ifdef DECODE_NEC @@ -212,6 +246,15 @@ long IRrecv::decodeNEC (decode_results *results) // 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) { @@ -243,6 +286,50 @@ void IRsend::sendWhynter (unsigned long data, int nbits) } #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 + //+============================================================================= // SSSS OOO N N Y Y // S O O NN N Y Y @@ -250,6 +337,14 @@ void IRsend::sendWhynter (unsigned long data, int nbits) // 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) { @@ -275,16 +370,145 @@ void IRsend::sendSony (unsigned long data, int nbits) } #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 + +//+============================================================================= +// 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 +// +// SA 8650B +#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 + //+============================================================================= // RRRR CCCC 55555 // R R C 5 -// R R C 5555 -// RRRR C 5 -// R R C 5 5 -// R R CCCC 555 +// RRRR C 5555 +// R R C 5 +// R R CCCC 5555 // -// Note: first bit must be a one (start bit) +// 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) { @@ -311,16 +535,51 @@ void IRsend::sendRC5 (unsigned long data, int nbits) } #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 666 -// R R C 6 -// R R C 6 66 -// RRRR C 66 6 +// 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) { @@ -336,8 +595,9 @@ void IRsend::sendRC6 (unsigned long data, int nbits) space(RC6_T1); // Data - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { - int t = (i == 3) ? (RC6_T1 * 2) : (RC6_T1) ; + 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); @@ -351,6 +611,52 @@ void IRsend::sendRC6 (unsigned long data, int nbits) } #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 + //+============================================================================= // 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 @@ -358,6 +664,13 @@ void IRsend::sendRC6 (unsigned long data, int nbits) // 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) { @@ -388,6 +701,37 @@ void IRsend::sendPanasonic (unsigned int address, unsigned long data) } #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 <<= 1 ; + 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 + //+============================================================================= // JJJJJ V V CCCC // J V V C @@ -395,6 +739,14 @@ void IRsend::sendPanasonic (unsigned int address, unsigned long data) // 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) { @@ -424,6 +776,54 @@ void IRsend::sendJVC (unsigned long data, int nbits, int repeat) } #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 + //+============================================================================= // SSSS AAA MMM SSSS U U N N GGGG // S A A M M M S U U NN N G @@ -431,6 +831,14 @@ void IRsend::sendJVC (unsigned long data, int nbits, int repeat) // 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) { @@ -458,87 +866,268 @@ void IRsend::sendSAMSUNG (unsigned long data, int nbits) } #endif -//+============================================================================= -// 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. +//+======================================================== +// SAMSUNGs have a repeat only 4 items long // -void IRsend::space (int time) +#ifdef DECODE_SAMSUNG +long IRrecv::decodeSAMSUNG (decode_results *results) { - TIMER_DISABLE_PWM; // Disable pin 3 PWM output - if (time > 0) delayMicroseconds(time); -} + long data = 0; + int offset = 1; // Skip first space -//+============================================================================= -// 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); -} + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return false ; + offset++; -//+============================================================================= -IRrecv::IRrecv (int recvpin) -{ - irparams.recvpin = recvpin; - irparams.blinkflag = 0; -} + // 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 ; -//+============================================================================= -// 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(); + // Initial space + if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) return false ; + offset++; - //Timer2 Overflow Interrupt Enable - TIMER_ENABLE_INTR; + for (int i = 0; i < SAMSUNG_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_BIT_MARK)) return false ; - TIMER_RESET; + offset++; - sei(); // enable interrupts + 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 + +//+============================================================================= +// 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 + +//+============================================================================= +// 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! - // initialize state machine variables - irparams.rcvstate = STATE_IDLE; - irparams.rawlen = 0; + // POST-DATA, 1 bit, 0x0 + mark(AIWA_RC_T501_BIT_MARK); + space(AIWA_RC_T501_ZERO_SPACE); - // set pin modes - pinMode(irparams.recvpin, INPUT); + mark(AIWA_RC_T501_BIT_MARK); + space(0); +} +#endif + + + + + + + + + + + + + + + + + + + + + +//+============================================================================= +// 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); +} + +//+============================================================================= +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); } //+============================================================================= @@ -546,8 +1135,8 @@ void IRrecv::enableIRIn ( ) // void IRrecv::blink13 (int blinkflag) { - irparams.blinkflag = blinkflag; - if (blinkflag) pinMode(BLINKLED, OUTPUT) ; + irparams.blinkflag = blinkflag; + if (blinkflag) pinMode(BLINKLED, OUTPUT) ; } //+============================================================================= @@ -618,253 +1207,134 @@ ISR (TIMER_INTR_NAME) if (irparams.blinkflag) { if (irdata == MARK) BLINKLED_ON() ; // turn pin 13 LED on else BLINKLED_OFF() ; // turn pin 13 LED off - } } } //+============================================================================= void IRrecv::resume ( ) { - irparams.rcvstate = STATE_IDLE; - irparams.rawlen = 0; + 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; + results->rawbuf = irparams.rawbuf; + results->rawlen = irparams.rawlen; - if (irparams.rcvstate != STATE_STOP) return false ; + if (irparams.rcvstate != STATE_STOP) return false ; #ifdef DECODE_NEC - DBG_PRINTLN("Attempting NEC decode"); - if (decodeNEC(results)) return true ; + DBG_PRINTLN("Attempting NEC decode"); + if (decodeNEC(results)) return true ; #endif #ifdef DECODE_SONY - DBG_PRINTLN("Attempting Sony decode"); - if (decodeSony(results)) return true ; + DBG_PRINTLN("Attempting Sony decode"); + if (decodeSony(results)) return true ; #endif #ifdef DECODE_SANYO - DBG_PRINTLN("Attempting Sanyo decode"); - if (decodeSanyo(results)) return true ; + DBG_PRINTLN("Attempting Sanyo decode"); + if (decodeSanyo(results)) return true ; #endif #ifdef DECODE_MITSUBISHI - DBG_PRINTLN("Attempting Mitsubishi decode"); - if (decodeMitsubishi(results)) return true ; + DBG_PRINTLN("Attempting Mitsubishi decode"); + if (decodeMitsubishi(results)) return true ; #endif #ifdef DECODE_RC5 - DBG_PRINTLN("Attempting RC5 decode"); - if (decodeRC5(results)) return true ; + DBG_PRINTLN("Attempting RC5 decode"); + if (decodeRC5(results)) return true ; #endif #ifdef DECODE_RC6 - DBG_PRINTLN("Attempting RC6 decode"); - if (decodeRC6(results)) return true ; + DBG_PRINTLN("Attempting RC6 decode"); + if (decodeRC6(results)) return true ; #endif #ifdef DECODE_PANASONIC - DBG_PRINTLN("Attempting Panasonic decode"); - if (decodePanasonic(results)) return true ; + DBG_PRINTLN("Attempting Panasonic decode"); + if (decodePanasonic(results)) return true ; #endif #ifdef DECODE_LG - DBG_PRINTLN("Attempting LG decode"); - if (decodeLG(results)) return true ; + DBG_PRINTLN("Attempting LG decode"); + if (decodeLG(results)) return true ; #endif #ifdef DECODE_JVC - DBG_PRINTLN("Attempting JVC decode"); - if (decodeJVC(results)) return true ; + DBG_PRINTLN("Attempting JVC decode"); + if (decodeJVC(results)) return true ; #endif #ifdef DECODE_SAMSUNG - DBG_PRINTLN("Attempting SAMSUNG decode"); - if (decodeSAMSUNG(results)) return true ; + DBG_PRINTLN("Attempting SAMSUNG decode"); + if (decodeSAMSUNG(results)) return true ; #endif #ifdef DECODE_WHYNTER - DBG_PRINTLN("Attempting Whynter decode"); - if (decodeWhynter(results)) return true ; + 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 ; + 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; + // 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; } -//+============================================================================= -#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 -//+============================================================================= -#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 //+============================================================================= -// I think this is a Sanyo decoder - serial = SA 8650B // Looks like Sony except for timings, 48 chars of data and time/space different // -#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 +#define MITSUBISHI_BITS 16 - 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; - } +// 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 - results->value = data; - results->decode_type = SANYO; - return true; -} -#endif - -//+============================================================================= -// Looks like Sony except for timings, 48 chars of data and time/space different -// #ifdef DECODE_MITSUBISHI long IRrecv::decodeMitsubishi (decode_results *results) { @@ -957,241 +1427,6 @@ int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int return val; } -//+============================================================================= -#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 - -//+============================================================================= -#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 - -//+============================================================================= -#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 <<= 1 ; - 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 - -//+============================================================================= -#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 - -//+============================================================================= -#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 - -//+============================================================================= -// 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 //+============================================================================= // Aiwa system @@ -1308,8 +1543,18 @@ long IRrecv::decodeHash (decode_results *results) // i.e. use 0x1C10 instead of 0x0000000000001C10 which is listed in the // linked LIRC file. // + +#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::sendSharp (unsigned long data, int nbits) +void IRsend::sendSharpRaw (unsigned long data, int nbits) { unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; enableIROut(38); @@ -1346,6 +1591,16 @@ void IRsend::sendSharp (unsigned int address, unsigned int command) #endif //+============================================================================= +#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) { @@ -1356,7 +1611,7 @@ void IRsend::sendDISH (unsigned long data, int nbits) space(DISH_HDR_SPACE); for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { - if (data & mark) { + if (data & mask) { mark(DISH_BIT_MARK); space(DISH_ONE_SPACE); } else { @@ -1367,52 +1622,3 @@ void IRsend::sendDISH (unsigned long data, int nbits) } #endif -//+============================================================================= -// Aiwa system -// Remote control RC-T501 -// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 -// -#ifdef SEND_AIWA_RC_T501 -void IRsend::sendAiwaRCT501 (int code) -{ - // PRE-DATA, 26 bits, 0x227EEC0 - unsigned long pre = 0x227EEC0; - int mask; - - // Set IR carrier frequency - enableIROut(AIWA_RC_T501_HZ); - - // HDR mark + HDR space - 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 (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 diff --git a/IRremote.h b/IRremote.h index 654fc7ff6..13b0d9b66 100644 --- a/IRremote.h +++ b/IRremote.h @@ -26,22 +26,23 @@ // #define TEST enum decode_type_t { - NEC = 1, - SONY = 2, - RC5 = 3, - RC6 = 4, - DISH = 5, - SHARP = 6, - PANASONIC = 7, - JVC = 8, - SANYO = 9, - MITSUBISHI = 10, - SAMSUNG = 11, - LG = 12, - WHYNTER = 13, - AIWA_RC_T501 = 14, - - UNKNOWN = -1 + UNKNOWN = -1, + UNUSED = 0, + NEC = 1, + SONY = 2, + RC5 = 3, + RC6 = 4, + DISH = 5, + SHARP = 6, + PANASONIC = 7, + JVC = 8, + SANYO = 9, + MITSUBISHI = 10, + SAMSUNG = 11, + LG = 12, + WHYNTER = 13, + AIWA_RC_T501 = 14, + }; // Results returned from the decoder @@ -58,20 +59,6 @@ class decode_results { int rawlen; // Number of records in rawbuf. }; -// Send types -#define IRsendNEC -#define IRsendSONY -#define IRsendRC5 -#define IRsendRC6 -#define IRsendDISH -#define IRsendSHARP -#define IRsendPANASONIC -#define IRsendJVC -#define IRsendSANYO -#define IRsendMITSUBISHI -#define IRsendSAMSUNG -#define IRsendRAW - // Decoded value for NEC when a repeat code is received #define REPEAT 0xffffffff @@ -152,24 +139,21 @@ class IRsend #ifdef SEND_WHYNTER void sendWhynter(unsigned long data, int nbits); #endif -#ifdef SEND_NEC +#ifdef SEND_NEC void sendNEC(unsigned long data, int nbits); #endif -#ifdef SEND_SONY +#ifdef SEND_SONY void sendSony(unsigned long data, int nbits); // Neither Sanyo nor Mitsubishi send is implemented yet // void sendSanyo(unsigned long data, int nbits); // void sendMitsubishi(unsigned long data, int nbits); #endif -#ifdef SEND_DISH +#ifdef SEND_DISH void sendDISH(unsigned long data, int nbits); #endif #ifdef SEND_SHARP - void sendSharp(unsigned int address, unsigned int command); void sendSharpRaw(unsigned long data, int nbits); -#endif -#ifdef SEND_IRsendSHARP - void sendSharp(unsigned long data, int nbits); + void sendSharp(unsigned int address, unsigned int command); #endif #ifdef SEND_PANASONIC void sendPanasonic(unsigned int address, unsigned long data); @@ -180,7 +164,7 @@ class IRsend #ifdef SEND_AIWA_RC_T501 void sendAiwaRCT501(int code); #endif -#ifdef SEND_SAMSUNG +#ifdef SEND_SAMSUNG void sendSAMSUNG(unsigned long data, int nbits); #endif void enableIROut(int khz); diff --git a/IRremoteInt.h b/IRremoteInt.h index 32281f8d7..fa5e31ac4 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -95,118 +95,27 @@ // Pulse parms are *50-100 for the Mark and *50+100 for the space // First MARK is the one after the long gap // pulse parameters in usec -#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 - -#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 - -#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 - -// SA 8650B -#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 - -// 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 - - -#define RC5_T1 889 -#define RC5_RPT_LENGTH 46000 - -#define RC6_HDR_MARK 2666 -#define RC6_HDR_SPACE 889 -#define RC6_T1 444 -#define RC6_RPT_LENGTH 46000 - -#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 - -#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 - -#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 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 - -#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 - - -#define SHARP_BITS 15 -#define DISH_BITS 16 - -// AIWA RC T501 -// 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 + + + + + + + + + + + + + + + + #define TOLERANCE 25 // percent tolerance in measurements -#define LTOL (1.0 - TOLERANCE/100.) -#define UTOL (1.0 + TOLERANCE/100.) +#define LTOL (1.0 - TOLERANCE/100.) +#define UTOL (1.0 + TOLERANCE/100.) #define _GAP 5000 // Minimum map between transmissions #define GAP_TICKS (_GAP/USECPERTICK) @@ -228,7 +137,7 @@ typedef struct { unsigned int timer; // state timer, counts 50uS ticks. unsigned int rawbuf[RAWBUF]; // raw data uint8_t rawlen; // counter of entries in rawbuf -} +} irparams_t; // Defined in IRremote.cpp @@ -240,21 +149,6 @@ extern volatile irparams_t irparams; #define TOPBIT 0x80000000 -#define NEC_BITS 32 -#define SONY_BITS 12 -#define SANYO_BITS 12 -#define MITSUBISHI_BITS 16 -#define MIN_RC5_SAMPLES 11 -#define MIN_RC6_SAMPLES 1 -#define PANASONIC_BITS 48 -#define JVC_BITS 16 -#define LG_BITS 28 -#define SAMSUNG_BITS 32 -#define WHYNTER_BITS 32 - - - - // defines for timer2 (8 bits) #if defined(IR_USE_TIMER2) #define TIMER_RESET From 88e243fe068e06d2ed602fefe6bd5effd07006e1 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 04:29:28 +0100 Subject: [PATCH 056/768] 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. --- IRremote.cpp | 1628 ++------------------------------------------- IRremote.h | 47 +- IRremoteInt.h | 8 +- irISR.cpp | 76 +++ irRecv.cpp | 195 ++++++ irSend.cpp | 66 ++ ir_Aiwa.cpp | 108 +++ ir_Dish.cpp | 55 ++ ir_JVC.cpp | 97 +++ ir_LG.cpp | 54 ++ ir_Mitsubishi.cpp | 85 +++ ir_NEC.cpp | 98 +++ ir_Panasonic.cpp | 80 +++ ir_RC5_RC6.cpp | 196 ++++++ ir_Samsung.cpp | 94 +++ ir_Sanyo.cpp | 79 +++ ir_Sharp.cpp | 71 ++ ir_Sony.cpp | 95 +++ ir_Whynter.cpp | 96 +++ 19 files changed, 1640 insertions(+), 1588 deletions(-) create mode 100644 irISR.cpp create mode 100644 irRecv.cpp create mode 100644 irSend.cpp create mode 100644 ir_Aiwa.cpp create mode 100644 ir_Dish.cpp create mode 100644 ir_JVC.cpp create mode 100644 ir_LG.cpp create mode 100644 ir_Mitsubishi.cpp create mode 100644 ir_NEC.cpp create mode 100644 ir_Panasonic.cpp create mode 100644 ir_RC5_RC6.cpp create mode 100644 ir_Samsung.cpp create mode 100644 ir_Sanyo.cpp create mode 100644 ir_Sharp.cpp create mode 100644 ir_Sony.cpp create mode 100644 ir_Whynter.cpp diff --git a/IRremote.cpp b/IRremote.cpp index bce7b37d3..534ae66a1 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -1,29 +1,3 @@ -#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 SEND_AIWA_RC_T501 -#define DECODE_MITSUBISHI -#define DECODE_AIWA_RC_T501 -#define SEND_SHARP -#define SEND_DISH - - - //****************************************************************************** // IRremote // Version 0.11 August, 2009 @@ -44,1581 +18,63 @@ // Whynter A/C ARC-110WD added by Francesco Meschia //****************************************************************************** -#include "IRremote.h" -#include "IRremoteInt.h" - -// Provides ISR -#include +// Defining IR_GLOBAL here allows us to declare the instantiation of global variables +#define IR_GLOBAL +# include "IRremote.h" +# include "IRremoteInt.h" +#undef IR_GLOBAL //------------------------------------------------------------------------------ -// Debug directives -#ifdef DEBUG -# define DBG_PRINTLN(s) Serial.println(s); -#else -# define DBG_PRINTLN(s) -#endif - -//------------------------------------------------------------------------------ -volatile irparams_t irparams; - // These versions of MATCH, MATCH_MARK, and MATCH_SPACE are only for debugging. -// To use them, set DEBUG in IRremoteInt.h -// Normally macros are used for efficiency -#ifdef DEBUG -int MATCH (int measured, int desired) -{ - Serial.print("Testing: "); - Serial.print(TICKS_LOW(desired), DEC); - Serial.print(" <= "); - Serial.print(measured, DEC); - Serial.print(" <= "); - Serial.println(TICKS_HIGH(desired), DEC); - return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired); -} - -int MATCH_MARK (int measured_ticks, int desired_us) -{ - Serial.print("Testing mark "); - Serial.print(measured_ticks * USECPERTICK, DEC); - Serial.print(" vs "); - Serial.print(desired_us, DEC); - Serial.print(": "); - Serial.print(TICKS_LOW(desired_us + MARK_EXCESS), DEC); - Serial.print(" <= "); - Serial.print(measured_ticks, DEC); - Serial.print(" <= "); - Serial.println(TICKS_HIGH(desired_us + MARK_EXCESS), DEC); - return measured_ticks >= TICKS_LOW(desired_us + MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS); -} - -int MATCH_SPACE (int measured_ticks, int desired_us) -{ - Serial.print("Testing space "); - Serial.print(measured_ticks * USECPERTICK, DEC); - Serial.print(" vs "); - Serial.print(desired_us, DEC); - Serial.print(": "); - Serial.print(TICKS_LOW(desired_us - MARK_EXCESS), DEC); - Serial.print(" <= "); - Serial.print(measured_ticks, DEC); - Serial.print(" <= "); - Serial.println(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); - return measured_ticks >= TICKS_LOW(desired_us - MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS); -} - -#else - -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)); -} - -#endif - -//+============================================================================= -// RRRR AAA W W -// R R A A W W -// RRRR AAAAA W W W -// R R A A W W W -// R R A A WWW -// -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 -} - -//+============================================================================= -// 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 - -//+============================================================================= -// 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 - -//+============================================================================= -// 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 - -//+============================================================================= -// 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 -// -// SA 8650B -#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 - -//+============================================================================= -// 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 - -//+============================================================================= -// 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 <<= 1 ; - 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 - -//+============================================================================= -// 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 - -//+============================================================================= -// 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 +// To use them, set DEBUG to 1 in IRremoteInt.h +// (Normally macros are used for efficiency) +// ...but every time i reduce these functions down to macros, the decoders stop working!!?? //+============================================================================= -// 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 - -//+============================================================================= -// 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 - - - - - - - - - - - - - - - - - - - - - -//+============================================================================= -// 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); -} - -//+============================================================================= -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) ; -} - -//+============================================================================= -// 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 - } -} - -//+============================================================================= -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; -} - - - - - - - - - - - - -//+============================================================================= -// 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 - -//+============================================================================= -// 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; -} - - -//+============================================================================= -// Aiwa system -// Remote control RC-T501 -// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 -// -#ifdef DECODE_AIWA_RC_T501 -long IRrecv::decodeAiwaRCT501 (decode_results *results) +int MATCH (int measured, int desired) { - 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 + DBG_PRINT("Testing: "); + DBG_PRINT(TICKS_LOW(desired), DEC); + DBG_PRINT(" <= "); + DBG_PRINT(measured, DEC); + DBG_PRINT(" <= "); + DBG_PRINTLN(TICKS_HIGH(desired), DEC); -//+============================================================================= -// 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 ; + return ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); } //+============================================================================= -// 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; -} - -//+============================================================================= -// Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand ) -// -// The Dish send function needs to be repeated 4 times, and the Sharp 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 are the LIRC files that I found that seem to match the remote codes -// from the oscilloscope: -// -// Sharp LCD TV: -// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA -// -// DISH NETWORK (echostar 301): -// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx -// -// For the DISH codes, only send the last for characters of the hex. -// i.e. use 0x1C10 instead of 0x0000000000001C10 which is listed in the -// linked LIRC file. -// - -#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) +int MATCH_MARK (int measured_ticks, int desired_us) { - 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); - } - } + DBG_PRINT("Testing mark "); + DBG_PRINT(measured_ticks * USECPERTICK, DEC); + DBG_PRINT(" vs "); + DBG_PRINT(desired_us, DEC); + DBG_PRINT(": "); + DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS), DEC); + DBG_PRINT(" <= "); + DBG_PRINT(measured_ticks, DEC); + DBG_PRINT(" <= "); + DBG_PRINTLN(TICKS_HIGH(desired_us + MARK_EXCESS), DEC); - mark(SHARP_BIT_MARK); - space(SHARP_ZERO_SPACE); - delay(40); - - data = data ^ SHARP_TOGGLE_MASK; - } -} - -//+============================================================================= -// Sharp send compatible with data obtained through decodeSharp -// -void IRsend::sendSharp (unsigned int address, unsigned int command) -{ - sendSharpRaw((address << 10) | (command << 2) | 2, 15); + return ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) + && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); } -#endif - //+============================================================================= -#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) +int MATCH_SPACE (int measured_ticks, int desired_us) { - // Set IR carrier frequency - enableIROut(56); - - mark(DISH_HDR_MARK); - space(DISH_HDR_SPACE); + DBG_PRINT("Testing space "); + DBG_PRINT(measured_ticks * USECPERTICK, DEC); + DBG_PRINT(" vs "); + DBG_PRINT(desired_us, DEC); + DBG_PRINT(": "); + DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS), DEC); + DBG_PRINT(" <= "); + DBG_PRINT(measured_ticks, DEC); + DBG_PRINT(" <= "); + DBG_PRINTLN(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); - 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); - } - } + return ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) + && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); } -#endif - diff --git a/IRremote.h b/IRremote.h index 13b0d9b66..ed9a448ec 100644 --- a/IRremote.h +++ b/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 diff --git a/IRremoteInt.h b/IRremoteInt.h index fa5e31ac4..af0015be4 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -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 #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 diff --git a/irISR.cpp b/irISR.cpp new file mode 100644 index 000000000..8a23c9e0e --- /dev/null +++ b/irISR.cpp @@ -0,0 +1,76 @@ +#include + +#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 + } +} + diff --git a/irRecv.cpp b/irRecv.cpp new file mode 100644 index 000000000..4c4e30b42 --- /dev/null +++ b/irRecv.cpp @@ -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; +} diff --git a/irSend.cpp b/irSend.cpp new file mode 100644 index 000000000..df3b1d9ff --- /dev/null +++ b/irSend.cpp @@ -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); +} + diff --git a/ir_Aiwa.cpp b/ir_Aiwa.cpp new file mode 100644 index 000000000..b34d6f40f --- /dev/null +++ b/ir_Aiwa.cpp @@ -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 + diff --git a/ir_Dish.cpp b/ir_Dish.cpp new file mode 100644 index 000000000..22e10d025 --- /dev/null +++ b/ir_Dish.cpp @@ -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 + diff --git a/ir_JVC.cpp b/ir_JVC.cpp new file mode 100644 index 000000000..151820a26 --- /dev/null +++ b/ir_JVC.cpp @@ -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 + diff --git a/ir_LG.cpp b/ir_LG.cpp new file mode 100644 index 000000000..44b1a778b --- /dev/null +++ b/ir_LG.cpp @@ -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 + diff --git a/ir_Mitsubishi.cpp b/ir_Mitsubishi.cpp new file mode 100644 index 000000000..e02b64aa5 --- /dev/null +++ b/ir_Mitsubishi.cpp @@ -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 + diff --git a/ir_NEC.cpp b/ir_NEC.cpp new file mode 100644 index 000000000..cb3b248f4 --- /dev/null +++ b/ir_NEC.cpp @@ -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 diff --git a/ir_Panasonic.cpp b/ir_Panasonic.cpp new file mode 100644 index 000000000..494c28ddb --- /dev/null +++ b/ir_Panasonic.cpp @@ -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 + diff --git a/ir_RC5_RC6.cpp b/ir_RC5_RC6.cpp new file mode 100644 index 000000000..16c2badae --- /dev/null +++ b/ir_RC5_RC6.cpp @@ -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 diff --git a/ir_Samsung.cpp b/ir_Samsung.cpp new file mode 100644 index 000000000..0773eddc2 --- /dev/null +++ b/ir_Samsung.cpp @@ -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 + diff --git a/ir_Sanyo.cpp b/ir_Sanyo.cpp new file mode 100644 index 000000000..ad0e76f82 --- /dev/null +++ b/ir_Sanyo.cpp @@ -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 + diff --git a/ir_Sharp.cpp b/ir_Sharp.cpp new file mode 100644 index 000000000..ffd77ed0c --- /dev/null +++ b/ir_Sharp.cpp @@ -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 diff --git a/ir_Sony.cpp b/ir_Sony.cpp new file mode 100644 index 000000000..4446f834e --- /dev/null +++ b/ir_Sony.cpp @@ -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 + diff --git a/ir_Whynter.cpp b/ir_Whynter.cpp new file mode 100644 index 000000000..c97732abf --- /dev/null +++ b/ir_Whynter.cpp @@ -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 + From a1cf782c44f62e4774bfc7852111bed2a1687e44 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 14:42:59 +0100 Subject: [PATCH 057/768] Bit more code cleanup --- IRremote.cpp | 82 ++++++++++++++++++++++++----------------- IRremote.h | 18 +++++---- IRremoteInt.h | 10 +++-- irISR.cpp | 100 +++++++++++++++++++++++++------------------------- irRecv.cpp | 46 +++++++++-------------- 5 files changed, 133 insertions(+), 123 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 534ae66a1..ad01643e2 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -31,50 +31,66 @@ // ...but every time i reduce these functions down to macros, the decoders stop working!!?? //+============================================================================= +// The match functions were (apparently) originally MACROs to improve code speed +// (although this would have bloated the code size) hence the names being CAPS +// A later release implemented debug output and so they needed to be converted +// to functions. +// I tried to implement a dual-compile mode (DEBUG/non-DEBUG) but for some +// reason, no matter what I did I could not get them to function as macros again. +// I have found a *lot* of bugs in the Arduino compiler over the last few weeks, +// and I am currently assuming that one of these bugs is my problem. +// I may revisit this code at a later date and look at the assembler produced +// in a hope of finding out what is going on, but for now they will remain as +// functions even in non-DEBUG mode +// int MATCH (int measured, int desired) { - DBG_PRINT("Testing: "); - DBG_PRINT(TICKS_LOW(desired), DEC); - DBG_PRINT(" <= "); - DBG_PRINT(measured, DEC); - DBG_PRINT(" <= "); - DBG_PRINTLN(TICKS_HIGH(desired), DEC); + DBG_PRINT("Testing: "); + DBG_PRINT(TICKS_LOW(desired), DEC); + DBG_PRINT(" <= "); + DBG_PRINT(measured, DEC); + DBG_PRINT(" <= "); + DBG_PRINTLN(TICKS_HIGH(desired), DEC); - return ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); + return ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); } -//+============================================================================= +//+======================================================== +// Marks tend to be 100us too long when received due to sensor lag. +// int MATCH_MARK (int measured_ticks, int desired_us) { - DBG_PRINT("Testing mark "); - DBG_PRINT(measured_ticks * USECPERTICK, DEC); - DBG_PRINT(" vs "); - DBG_PRINT(desired_us, DEC); - DBG_PRINT(": "); - DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS), DEC); - DBG_PRINT(" <= "); - DBG_PRINT(measured_ticks, DEC); - DBG_PRINT(" <= "); - DBG_PRINTLN(TICKS_HIGH(desired_us + MARK_EXCESS), DEC); + DBG_PRINT("Testing mark "); + DBG_PRINT(measured_ticks * USECPERTICK, DEC); + DBG_PRINT(" vs "); + DBG_PRINT(desired_us, DEC); + DBG_PRINT(": "); + DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS), DEC); + DBG_PRINT(" <= "); + DBG_PRINT(measured_ticks, DEC); + DBG_PRINT(" <= "); + DBG_PRINTLN(TICKS_HIGH(desired_us + MARK_EXCESS), DEC); - return ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) - && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); + return ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) + && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); } -//+============================================================================= +//+======================================================== +// Spaces tend to be 100us too short when received due to sensor lag. +// int MATCH_SPACE (int measured_ticks, int desired_us) { - DBG_PRINT("Testing space "); - DBG_PRINT(measured_ticks * USECPERTICK, DEC); - DBG_PRINT(" vs "); - DBG_PRINT(desired_us, DEC); - DBG_PRINT(": "); - DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS), DEC); - DBG_PRINT(" <= "); - DBG_PRINT(measured_ticks, DEC); - DBG_PRINT(" <= "); - DBG_PRINTLN(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); + DBG_PRINT("Testing space "); + DBG_PRINT(measured_ticks * USECPERTICK, DEC); + DBG_PRINT(" vs "); + DBG_PRINT(desired_us, DEC); + DBG_PRINT(": "); + DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS), DEC); + DBG_PRINT(" <= "); + DBG_PRINT(measured_ticks, DEC); + DBG_PRINT(" <= "); + DBG_PRINTLN(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); - return ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) - && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); + return ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) + && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); } diff --git a/IRremote.h b/IRremote.h index ed9a448ec..2bb3388b0 100644 --- a/IRremote.h +++ b/IRremote.h @@ -1,3 +1,6 @@ +#ifndef IRremote_h +#define IRremote_h + #define DEBUG #undef DEBUG @@ -16,10 +19,7 @@ int MATCH (int measured, int desired) ; # 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 @@ -60,9 +60,6 @@ int MATCH (int measured, int desired) ; * Whynter A/C ARC-110WD added by Francesco Meschia */ -#ifndef IRremote_h -#define IRremote_h - // The following are compile-time library options. // If you change them, recompile the library. // If DEBUG is defined, a lot of debugging output will be printed during decoding. @@ -71,6 +68,7 @@ int MATCH (int measured, int desired) ; //#define DEBUG // #define TEST +//------------------------------------------------------------------------------ enum decode_type_t { UNKNOWN = -1, UNUSED = 0, @@ -90,6 +88,7 @@ enum decode_type_t { AIWA_RC_T501 = 14, }; +//------------------------------------------------------------------------------ // Results returned from the decoder class decode_results { public: @@ -104,9 +103,11 @@ class decode_results { int rawlen; // Number of records in rawbuf. }; +//------------------------------------------------------------------------------ // Decoded value for NEC when a repeat code is received #define REPEAT 0xffffffff +//------------------------------------------------------------------------------ // main class for receiving IR class IRrecv { @@ -163,6 +164,7 @@ class IRrecv } ; +//------------------------------------------------------------------------------ // Only used for testing; can remove virtual for shorter code #ifdef TEST #define VIRTUAL virtual @@ -170,6 +172,7 @@ class IRrecv #define VIRTUAL #endif +//------------------------------------------------------------------------------ class IRsend { public: @@ -217,6 +220,7 @@ class IRsend VIRTUAL void space(int usec); } ; +//------------------------------------------------------------------------------ // Some useful constants #define USECPERTICK 50 // microseconds per clock interrupt tick diff --git a/IRremoteInt.h b/IRremoteInt.h index af0015be4..21a0c8d34 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -17,18 +17,21 @@ #ifndef IRremoteint_h #define IRremoteint_h +//------------------------------------------------------------------------------ #ifdef IR_GLOBAL # define EXTERN #else # define EXTERN extern #endif +//------------------------------------------------------------------------------ #if defined(ARDUINO) && ARDUINO >= 100 #include #else #include #endif +//------------------------------------------------------------------------------ // define which timer to use // // Uncomment the timer you wish to use on your board. If you @@ -78,18 +81,18 @@ #define IR_USE_TIMER2 // tx = pin 3 #endif - - +//------------------------------------------------------------------------------ #ifdef F_CPU #define SYSCLOCK F_CPU // main Arduino clock #else #define SYSCLOCK 16000000 // main Arduino clock #endif +//------------------------------------------------------------------------------ #define ERR 0 #define DECODED 1 - +//------------------------------------------------------------------------------ // defines for setting and clearing register bits #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) @@ -98,6 +101,7 @@ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif +//------------------------------------------------------------------------------ // Pulse parms are *50-100 for the Mark and *50+100 for the space // First MARK is the one after the long gap // pulse parameters in usec diff --git a/irISR.cpp b/irISR.cpp index 8a23c9e0e..5e1d98d8b 100644 --- a/irISR.cpp +++ b/irISR.cpp @@ -14,63 +14,61 @@ // ISR (TIMER_INTR_NAME) { - TIMER_RESET; + TIMER_RESET; - uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); + uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); - irparams.timer++; // One more 50us tick - if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_STOP ; // Buffer overflow + 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; + 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; - 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; + } 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_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_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_STOP: // waiting, measuring gap - if (irdata == MARK) irparams.timer = 0 ; // reset gap timer - 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; - if (irparams.blinkflag) { - if (irdata == MARK) BLINKLED_ON() ; // turn pin 13 LED on - else BLINKLED_OFF() ; // turn pin 13 LED off - } + } else if (irparams.timer > GAP_TICKS) { // SPACE + // 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 + } } diff --git a/irRecv.cpp b/irRecv.cpp index 4c4e30b42..8328319a4 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -51,18 +51,6 @@ void IRrecv::resume ( ) irparams.rawlen = 0; } - - - - - - - - - - - - //+============================================================================= // Decodes the received IR message // Returns 0 if no data ready, 1 if data ready. @@ -162,9 +150,9 @@ int IRrecv::decode (decode_results *results) // 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 ; + if (newval < oldval * .8) return 0 ; + else if (oldval < newval * .8) return 2 ; + else return 1 ; } //+============================================================================= @@ -178,18 +166,18 @@ int IRrecv::compare (unsigned int oldval, unsigned int newval) 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; + // 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; } From 813a3038ab2e56bf72bfd797ccde0219509684fc Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 17:51:10 +0100 Subject: [PATCH 058/768] Commenting --- IRremote.cpp | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index ad01643e2..e4fb94ba1 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -24,24 +24,18 @@ # include "IRremoteInt.h" #undef IR_GLOBAL -//------------------------------------------------------------------------------ -// These versions of MATCH, MATCH_MARK, and MATCH_SPACE are only for debugging. -// To use them, set DEBUG to 1 in IRremoteInt.h -// (Normally macros are used for efficiency) -// ...but every time i reduce these functions down to macros, the decoders stop working!!?? - //+============================================================================= // The match functions were (apparently) originally MACROs to improve code speed -// (although this would have bloated the code size) hence the names being CAPS +// (although this would have bloated the code) hence the names being CAPS // A later release implemented debug output and so they needed to be converted -// to functions. +// to functions. // I tried to implement a dual-compile mode (DEBUG/non-DEBUG) but for some -// reason, no matter what I did I could not get them to function as macros again. +// reason, no matter what I did I could not get them to function as macros again. // I have found a *lot* of bugs in the Arduino compiler over the last few weeks, -// and I am currently assuming that one of these bugs is my problem. +// and I am currently assuming that one of these bugs is my problem. // I may revisit this code at a later date and look at the assembler produced -// in a hope of finding out what is going on, but for now they will remain as -// functions even in non-DEBUG mode +// in a hope of finding out what is going on, but for now they will remain as +// functions even in non-DEBUG mode // int MATCH (int measured, int desired) { @@ -56,7 +50,7 @@ int MATCH (int measured, int desired) } //+======================================================== -// Marks tend to be 100us too long when received due to sensor lag. +// Due to sensor lag, when received, Marks tend to be 100us too long // int MATCH_MARK (int measured_ticks, int desired_us) { @@ -76,7 +70,7 @@ int MATCH_MARK (int measured_ticks, int desired_us) } //+======================================================== -// Spaces tend to be 100us too short when received due to sensor lag. +// Due to sensor lag, when received, Spaces tend to be 100us too short // int MATCH_SPACE (int measured_ticks, int desired_us) { From 7b8444a30579790c94816868bcb3d0f4d33a5d5f Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 17:51:40 +0100 Subject: [PATCH 059/768] Remove use of macro TOPBIT --- ir_Aiwa.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ir_Aiwa.cpp b/ir_Aiwa.cpp index b34d6f40f..b4049ca67 100644 --- a/ir_Aiwa.cpp +++ b/ir_Aiwa.cpp @@ -46,15 +46,15 @@ void IRsend::sendAiwaRCT501 (int code) //-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 +// then uses TOPBIT which is 0x80000000 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) ; + if (code & 0x80000000) space(AIWA_RC_T501_ONE_SPACE) ; + else space(AIWA_RC_T501_ZERO_SPACE) ; code <<= 1; } //-^- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK! From 5d994880b90c2b1f3ecab79f317512fe895226e4 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 17:54:18 +0100 Subject: [PATCH 060/768] Commenting formatting move ISR macros to ISR header --- IRremote.h | 10 - IRremoteInt.h | 620 ++++++++++++++++++++++++++++---------------------- 2 files changed, 349 insertions(+), 281 deletions(-) diff --git a/IRremote.h b/IRremote.h index 2bb3388b0..a45605c71 100644 --- a/IRremote.h +++ b/IRremote.h @@ -220,14 +220,4 @@ class IRsend VIRTUAL void space(int usec); } ; -//------------------------------------------------------------------------------ -// Some useful constants - -#define USECPERTICK 50 // microseconds per clock interrupt tick -#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. -#define MARK_EXCESS 100 - #endif diff --git a/IRremoteInt.h b/IRremoteInt.h index 21a0c8d34..393b5024a 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -1,251 +1,309 @@ -/* - * IRremote - * Version 0.1 July, 2009 - * Copyright 2009 Ken Shirriff - * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html - * - * Modified by Paul Stoffregen to support other boards and timers - * - * 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) - * Whynter A/C ARC-110WD added by Francesco Meschia - */ +//****************************************************************************** +// IRremote +// Version 0.1 July, 2009 +// Copyright 2009 Ken Shirriff +// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html +// +// Modified by Paul Stoffregen to support other boards and timers +// +// 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) +// Whynter A/C ARC-110WD added by Francesco Meschia +//****************************************************************************** #ifndef IRremoteint_h #define IRremoteint_h //------------------------------------------------------------------------------ -#ifdef IR_GLOBAL -# define EXTERN +// Include the right Arduino header +// +#if defined(ARDUINO) && (ARDUINO >= 100) +# include #else -# define EXTERN extern +# include #endif //------------------------------------------------------------------------------ -#if defined(ARDUINO) && ARDUINO >= 100 -#include +// This handles definition and access to global variables +// +#ifdef IR_GLOBAL +# define EXTERN #else -#include +# define EXTERN extern #endif //------------------------------------------------------------------------------ -// define which timer to use +// Information for the Interrupt Service Routine // -// Uncomment the timer you wish to use on your board. If you -// are using another library which uses timer2, you have options -// to switch IRremote to use a different timer. - -// Arduino Mega -#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 - //#define IR_USE_TIMER4 // tx = pin 6 - //#define IR_USE_TIMER5 // tx = pin 46 +#define RAWBUF 100 // Maximum length of raw duration buffer + +typedef + struct { + // The fields are ordered to reduce memory over caused by struct-padding + uint8_t rcvstate; // State Machine state + uint8_t recvpin; // Pin connected to IR data from detector + uint8_t blinkflag; // true -> enable blinking of pin 13 on IR processing + uint8_t rawlen; // counter of entries in rawbuf + unsigned int timer; // State timer, counts 50uS ticks. + unsigned int rawbuf[RAWBUF]; // raw data + uint8_t overflow; // Raw buffer overflow occurred + } +irparams_t; -// Teensy 1.0 -#elif defined(__AVR_AT90USB162__) - #define IR_USE_TIMER1 // tx = pin 17 +// ISR State-Machine : Receiver States +#define STATE_IDLE 2 +#define STATE_MARK 3 +#define STATE_SPACE 4 +#define STATE_STOP 5 +#define STATE_OVERFLOW 6 -// Teensy 2.0 -#elif defined(__AVR_ATmega32U4__) - //#define IR_USE_TIMER1 // tx = pin 14 - //#define IR_USE_TIMER3 // tx = pin 9 - #define IR_USE_TIMER4_HS // tx = pin 10 +// Allow all parts of the code access to the ISR data +// NB. The data can be changed by the ISR at any time, even mid-function +// Therefore we declare it as "volatile" to stop the compiler/CPU caching it +EXTERN volatile irparams_t irparams; -// Teensy 3.0 -#elif defined(__MK20DX128__) - #define IR_USE_TIMER_CMT // tx = pin 5 +//------------------------------------------------------------------------------ +// Defines for blinking the LED +// +#if defined(CORE_LED0_PIN) +# define BLINKLED CORE_LED0_PIN +# define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH)) +# define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW)) -// Teensy++ 1.0 & 2.0 -#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) - //#define IR_USE_TIMER1 // tx = pin 25 - #define IR_USE_TIMER2 // tx = pin 1 - //#define IR_USE_TIMER3 // tx = pin 16 +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define BLINKLED 13 +# define BLINKLED_ON() (PORTB |= B10000000) +# define BLINKLED_OFF() (PORTB &= B01111111) -// Sanguino #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) - //#define IR_USE_TIMER1 // tx = pin 13 - #define IR_USE_TIMER2 // tx = pin 14 - -// Atmega8 -#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) - #define IR_USE_TIMER1 // tx = pin 9 +# define BLINKLED 0 +# define BLINKLED_ON() (PORTD |= B00000001) +# define BLINKLED_OFF() (PORTD &= B11111110) -// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc #else - //#define IR_USE_TIMER1 // tx = pin 9 - #define IR_USE_TIMER2 // tx = pin 3 +# define BLINKLED 13 + #define BLINKLED_ON() (PORTB |= B00100000) +# define BLINKLED_OFF() (PORTB &= B11011111) #endif //------------------------------------------------------------------------------ +// CPU Frequency +// #ifdef F_CPU -#define SYSCLOCK F_CPU // main Arduino clock +# define SYSCLOCK F_CPU // main Arduino clock #else -#define SYSCLOCK 16000000 // main Arduino clock +# define SYSCLOCK 16000000 // main Arduino clock #endif //------------------------------------------------------------------------------ -#define ERR 0 -#define DECODED 1 - -//------------------------------------------------------------------------------ -// defines for setting and clearing register bits +// Defines for setting and clearing register bits +// #ifndef cbi -#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +# define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif + #ifndef sbi -#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +# define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif //------------------------------------------------------------------------------ -// Pulse parms are *50-100 for the Mark and *50+100 for the space +// Pulse parms are ((X*50)-100) for the Mark and ((X*50)+100) for the Space. // First MARK is the one after the long gap -// pulse parameters in usec - - - - - - - - +// Pulse parameters in uSec +// +// Due to sensor lag, when received, Marks tend to be 100us too long and +// Spaces tend to be 100us too short +#define MARK_EXCESS 100 +// microseconds per clock interrupt tick +#define USECPERTICK 50 +// Upper and Lower percentage tolerances in measurements +#define TOLERANCE 25 +#define LTOL (1.0 - (TOLERANCE/100.)) +#define UTOL (1.0 + (TOLERANCE/100.)) +// Minimum gap between IR transmissions +#define _GAP 5000 +#define GAP_TICKS (_GAP/USECPERTICK) +#define TICKS_LOW(us) ((int)(((us)*LTOL/USECPERTICK))) +#define TICKS_HIGH(us) ((int)(((us)*UTOL/USECPERTICK + 1))) +//------------------------------------------------------------------------------ +// IR detector output is active low +// +#define MARK 0 +#define SPACE 1 +//------------------------------------------------------------------------------ +// Define which timer to use +// +// Uncomment the timer you wish to use on your board. +// If you are using another library which uses timer2, you have options to +// switch IRremote to use a different timer. +// +// Arduino Mega +#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 + //#define IR_USE_TIMER4 // tx = pin 6 + //#define IR_USE_TIMER5 // tx = pin 46 +// Teensy 1.0 +#elif defined(__AVR_AT90USB162__) + #define IR_USE_TIMER1 // tx = pin 17 -#define TOLERANCE 25 // percent tolerance in measurements -#define LTOL (1.0 - TOLERANCE/100.) -#define UTOL (1.0 + TOLERANCE/100.) +// Teensy 2.0 +#elif defined(__AVR_ATmega32U4__) + //#define IR_USE_TIMER1 // tx = pin 14 + //#define IR_USE_TIMER3 // tx = pin 9 + #define IR_USE_TIMER4_HS // tx = pin 10 -#define _GAP 5000 // Minimum map between transmissions -#define GAP_TICKS (_GAP/USECPERTICK) +// Teensy 3.0 +#elif defined(__MK20DX128__) + #define IR_USE_TIMER_CMT // tx = pin 5 -#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK)) -#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1)) +// Teensy++ 1.0 & 2.0 +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) + //#define IR_USE_TIMER1 // tx = pin 25 + #define IR_USE_TIMER2 // tx = pin 1 + //#define IR_USE_TIMER3 // tx = pin 16 -// receiver states -#define STATE_IDLE 2 -#define STATE_MARK 3 -#define STATE_SPACE 4 -#define STATE_STOP 5 +// Sanguino +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) + //#define IR_USE_TIMER1 // tx = pin 13 + #define IR_USE_TIMER2 // tx = pin 14 -// information for the interrupt handler -typedef struct { - uint8_t recvpin; // pin for IR data from detector - uint8_t rcvstate; // state machine - uint8_t blinkflag; // TRUE to enable blinking of pin 13 on IR processing - unsigned int timer; // state timer, counts 50uS ticks. - unsigned int rawbuf[RAWBUF]; // raw data - uint8_t rawlen; // counter of entries in rawbuf -} -irparams_t; +// Atmega8 +#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) + #define IR_USE_TIMER1 // tx = pin 9 -// Defined in IRremote.cpp -EXTERN volatile irparams_t irparams; +// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc +#else + //#define IR_USE_TIMER1 // tx = pin 9 + #define IR_USE_TIMER2 // tx = pin 3 -// IR detector output is active low -#define MARK 0 -#define SPACE 1 +#endif -#define TOPBIT 0x80000000 +//------------------------------------------------------------------------------ +// Defines for Timer -// defines for timer2 (8 bits) +//--------------------------------------------------------- +// Timer2 (8 bits) +// #if defined(IR_USE_TIMER2) + #define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) -#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) -#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) -#define TIMER_DISABLE_INTR (TIMSK2 = 0) -#define TIMER_INTR_NAME TIMER2_COMPA_vect +#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) +#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) +#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) +#define TIMER_DISABLE_INTR (TIMSK2 = 0) +#define TIMER_INTR_NAME TIMER2_COMPA_vect + #define TIMER_CONFIG_KHZ(val) ({ \ - const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR2A = _BV(WGM20); \ - TCCR2B = _BV(WGM22) | _BV(CS20); \ - OCR2A = pwmval; \ - OCR2B = pwmval / 3; \ + const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR2A = _BV(WGM20); \ + TCCR2B = _BV(WGM22) | _BV(CS20); \ + OCR2A = pwmval; \ + OCR2B = pwmval / 3; \ }) -#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) + +#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) + +//----------------- #if (TIMER_COUNT_TOP < 256) -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR2A = _BV(WGM21); \ - TCCR2B = _BV(CS20); \ - OCR2A = TIMER_COUNT_TOP; \ - TCNT2 = 0; \ -}) +# define TIMER_CONFIG_NORMAL() ({ \ + TCCR2A = _BV(WGM21); \ + TCCR2B = _BV(CS20); \ + OCR2A = TIMER_COUNT_TOP; \ + TCNT2 = 0; \ + }) #else -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR2A = _BV(WGM21); \ - TCCR2B = _BV(CS21); \ - OCR2A = TIMER_COUNT_TOP / 8; \ - TCNT2 = 0; \ -}) +# define TIMER_CONFIG_NORMAL() ({ \ + TCCR2A = _BV(WGM21); \ + TCCR2B = _BV(CS21); \ + OCR2A = TIMER_COUNT_TOP / 8; \ + TCNT2 = 0; \ + }) #endif + +//----------------- #if defined(CORE_OC2B_PIN) -#define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */ +# define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define TIMER_PWM_PIN 9 /* Arduino Mega */ +# define TIMER_PWM_PIN 9 // Arduino Mega #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) -#define TIMER_PWM_PIN 14 /* Sanguino */ +# define TIMER_PWM_PIN 14 // Sanguino #else -#define TIMER_PWM_PIN 3 /* Arduino Duemilanove, Diecimila, LilyPad, etc */ +# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc #endif - -// defines for timer1 (16 bits) +//--------------------------------------------------------- +// Timer1 (16 bits) +// #elif defined(IR_USE_TIMER1) + #define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) -#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) +#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) +#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) + +//----------------- #if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) - #define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) - #define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) +# define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) +# define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) #else - #define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) - #define TIMER_DISABLE_INTR (TIMSK1 = 0) +# define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) +# define TIMER_DISABLE_INTR (TIMSK1 = 0) #endif -#define TIMER_INTR_NAME TIMER1_COMPA_vect + +//----------------- +#define TIMER_INTR_NAME TIMER1_COMPA_vect + #define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR1A = _BV(WGM11); \ - TCCR1B = _BV(WGM13) | _BV(CS10); \ - ICR1 = pwmval; \ - OCR1A = pwmval / 3; \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR1A = _BV(WGM11); \ + TCCR1B = _BV(WGM13) | _BV(CS10); \ + ICR1 = pwmval; \ + OCR1A = pwmval / 3; \ }) + #define TIMER_CONFIG_NORMAL() ({ \ - TCCR1A = 0; \ - TCCR1B = _BV(WGM12) | _BV(CS10); \ - OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT1 = 0; \ + TCCR1A = 0; \ + TCCR1B = _BV(WGM12) | _BV(CS10); \ + OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT1 = 0; \ }) + +//----------------- #if defined(CORE_OC1A_PIN) -#define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */ +# define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define TIMER_PWM_PIN 11 /* Arduino Mega */ +# define TIMER_PWM_PIN 11 // Arduino Mega #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) -#define TIMER_PWM_PIN 13 /* Sanguino */ +# define TIMER_PWM_PIN 13 // Sanguino #else -#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */ +# define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc #endif - -// defines for timer3 (16 bits) +//--------------------------------------------------------- +// Timer3 (16 bits) +// #elif defined(IR_USE_TIMER3) + #define TIMER_RESET #define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1)) #define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1))) #define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A)) #define TIMER_DISABLE_INTR (TIMSK3 = 0) #define TIMER_INTR_NAME TIMER3_COMPA_vect + #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR3A = _BV(WGM31); \ @@ -253,69 +311,81 @@ EXTERN volatile irparams_t irparams; ICR3 = pwmval; \ OCR3A = pwmval / 3; \ }) + #define TIMER_CONFIG_NORMAL() ({ \ TCCR3A = 0; \ TCCR3B = _BV(WGM32) | _BV(CS30); \ OCR3A = SYSCLOCK * USECPERTICK / 1000000; \ TCNT3 = 0; \ }) + +//----------------- #if defined(CORE_OC3A_PIN) -#define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */ +# define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define TIMER_PWM_PIN 5 /* Arduino Mega */ +# define TIMER_PWM_PIN 5 // Arduino Mega #else -#error "Please add OC3A pin number here\n" +# error "Please add OC3A pin number here\n" #endif - -// defines for timer4 (10 bits, high speed option) +//--------------------------------------------------------- +// Timer4 (10 bits, high speed option) +// #elif defined(IR_USE_TIMER4_HS) + #define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) -#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) -#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) -#define TIMER_DISABLE_INTR (TIMSK4 = 0) -#define TIMER_INTR_NAME TIMER4_OVF_vect +#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) +#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) +#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) +#define TIMER_DISABLE_INTR (TIMSK4 = 0) +#define TIMER_INTR_NAME TIMER4_OVF_vect + #define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR4A = (1<> 8; \ - OCR4C = pwmval; \ - TC4H = (pwmval / 3) >> 8; \ - OCR4A = (pwmval / 3) & 255; \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR4A = (1<> 8; \ + OCR4C = pwmval; \ + TC4H = (pwmval / 3) >> 8; \ + OCR4A = (pwmval / 3) & 255; \ }) + #define TIMER_CONFIG_NORMAL() ({ \ - TCCR4A = 0; \ - TCCR4B = _BV(CS40); \ - TCCR4C = 0; \ - TCCR4D = 0; \ - TCCR4E = 0; \ - TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ - OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ - TC4H = 0; \ - TCNT4 = 0; \ + TCCR4A = 0; \ + TCCR4B = _BV(CS40); \ + TCCR4C = 0; \ + TCCR4D = 0; \ + TCCR4E = 0; \ + TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ + OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ + TC4H = 0; \ + TCNT4 = 0; \ }) + +//----------------- #if defined(CORE_OC4A_PIN) -#define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */ +# define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy #elif defined(__AVR_ATmega32U4__) -#define TIMER_PWM_PIN 13 /* Leonardo */ +# define TIMER_PWM_PIN 13 // Leonardo #else -#error "Please add OC4A pin number here\n" +# error "Please add OC4A pin number here\n" #endif - -// defines for timer4 (16 bits) +//--------------------------------------------------------- +// Timer4 (16 bits) +// #elif defined(IR_USE_TIMER4) + #define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) -#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) -#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) -#define TIMER_DISABLE_INTR (TIMSK4 = 0) -#define TIMER_INTR_NAME TIMER4_COMPA_vect +#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) +#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) +#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) +#define TIMER_DISABLE_INTR (TIMSK4 = 0) +#define TIMER_INTR_NAME TIMER4_COMPA_vect + #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR4A = _BV(WGM41); \ @@ -323,29 +393,35 @@ EXTERN volatile irparams_t irparams; ICR4 = pwmval; \ OCR4A = pwmval / 3; \ }) + #define TIMER_CONFIG_NORMAL() ({ \ TCCR4A = 0; \ TCCR4B = _BV(WGM42) | _BV(CS40); \ OCR4A = SYSCLOCK * USECPERTICK / 1000000; \ TCNT4 = 0; \ }) + +//----------------- #if defined(CORE_OC4A_PIN) -#define TIMER_PWM_PIN CORE_OC4A_PIN +# define TIMER_PWM_PIN CORE_OC4A_PIN #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define TIMER_PWM_PIN 6 /* Arduino Mega */ +# define TIMER_PWM_PIN 6 // Arduino Mega #else -#error "Please add OC4A pin number here\n" +# error "Please add OC4A pin number here\n" #endif - -// defines for timer5 (16 bits) +//--------------------------------------------------------- +// Timer5 (16 bits) +// #elif defined(IR_USE_TIMER5) + #define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) -#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) -#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) -#define TIMER_DISABLE_INTR (TIMSK5 = 0) -#define TIMER_INTR_NAME TIMER5_COMPA_vect +#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) +#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) +#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) +#define TIMER_DISABLE_INTR (TIMSK5 = 0) +#define TIMER_INTR_NAME TIMER5_COMPA_vect + #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR5A = _BV(WGM51); \ @@ -353,91 +429,93 @@ EXTERN volatile irparams_t irparams; ICR5 = pwmval; \ OCR5A = pwmval / 3; \ }) + #define TIMER_CONFIG_NORMAL() ({ \ TCCR5A = 0; \ TCCR5B = _BV(WGM52) | _BV(CS50); \ OCR5A = SYSCLOCK * USECPERTICK / 1000000; \ TCNT5 = 0; \ }) + +//----------------- #if defined(CORE_OC5A_PIN) -#define TIMER_PWM_PIN CORE_OC5A_PIN +# define TIMER_PWM_PIN CORE_OC5A_PIN #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define TIMER_PWM_PIN 46 /* Arduino Mega */ +# define TIMER_PWM_PIN 46 // Arduino Mega #else -#error "Please add OC5A pin number here\n" +# error "Please add OC5A pin number here\n" #endif - -// defines for special carrier modulator timer +//--------------------------------------------------------- +// Special carrier modulator timer +// #elif defined(IR_USE_TIMER_CMT) -#define TIMER_RESET ({ \ - uint8_t tmp = CMT_MSC; \ - CMT_CMD2 = 30; \ + +#define TIMER_RESET ({ \ + uint8_t tmp = CMT_MSC; \ + CMT_CMD2 = 30; \ }) -#define TIMER_ENABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_DSE|PORT_PCR_SRE -#define TIMER_DISABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE -#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) -#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) -#define TIMER_INTR_NAME cmt_isr + +#define TIMER_ENABLE_PWM do { \ + CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \ +} while(0) + +#define TIMER_DISABLE_PWM do { \ + CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \ +} while(0) + +#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) +#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) +#define TIMER_INTR_NAME cmt_isr + +//----------------- #ifdef ISR -#undef ISR +# undef ISR #endif -#define ISR(f) void f(void) -#if F_BUS == 48000000 -#define CMT_PPS_VAL 5 +#define ISR(f) void f(void) + +//----------------- +#if (F_BUS == 48000000) +# define CMT_PPS_VAL 5 #else -#define CMT_PPS_VAL 2 +# define CMT_PPS_VAL 2 #endif -#define TIMER_CONFIG_KHZ(val) ({ \ - SIM_SCGC4 |= SIM_SCGC4_CMT; \ - SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ - CMT_PPS = CMT_PPS_VAL; \ - CMT_CGH1 = 2667 / val; \ - CMT_CGL1 = 5333 / val; \ - CMT_CMD1 = 0; \ - CMT_CMD2 = 30; \ - CMT_CMD3 = 0; \ - CMT_CMD4 = 0; \ - CMT_OC = 0x60; \ - CMT_MSC = 0x01; \ -}) -#define TIMER_CONFIG_NORMAL() ({ \ - SIM_SCGC4 |= SIM_SCGC4_CMT; \ - CMT_PPS = CMT_PPS_VAL; \ - CMT_CGH1 = 1; \ - CMT_CGL1 = 1; \ - CMT_CMD1 = 0; \ - CMT_CMD2 = 30; \ - CMT_CMD3 = 0; \ - CMT_CMD4 = 19; \ - CMT_OC = 0; \ - CMT_MSC = 0x03; \ -}) -#define TIMER_PWM_PIN 5 +//----------------- +#define TIMER_CONFIG_KHZ(val) ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ + CMT_PPS = CMT_PPS_VAL; \ + CMT_CGH1 = 2667 / val; \ + CMT_CGL1 = 5333 / val; \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = 0; \ + CMT_OC = 0x60; \ + CMT_MSC = 0x01; \ +}) -#else // unknown timer -#error "Internal code configuration error, no known IR_USE_TIMER# defined\n" -#endif +#define TIMER_CONFIG_NORMAL() ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + CMT_PPS = CMT_PPS_VAL; \ + CMT_CGH1 = 1; \ + CMT_CGL1 = 1; \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30 \ + CMT_CMD3 = 0; \ + CMT_CMD4 = 19; \ + CMT_OC = 0; \ + CMT_MSC = 0x03; \ +}) +#define TIMER_PWM_PIN 5 -// defines for blinking the LED -#if defined(CORE_LED0_PIN) -#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__) || defined(__AVR_ATmega2560__) -#define BLINKLED 13 -#define BLINKLED_ON() (PORTB |= B10000000) -#define BLINKLED_OFF() (PORTB &= B01111111) -#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) -#define BLINKLED 0 -#define BLINKLED_ON() (PORTD |= B00000001) -#define BLINKLED_OFF() (PORTD &= B11111110) +//--------------------------------------------------------- +// Unknown Timer +// #else -#define BLINKLED 13 -#define BLINKLED_ON() (PORTB |= B00100000) -#define BLINKLED_OFF() (PORTB &= B11011111) +# error "Internal code configuration error, no known IR_USE_TIMER# defined\n" #endif -#endif +#endif // IRremoteint_h From dfd14d437cf23d65b6d97fb0611f879cee9a63b5 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 18:24:50 +0100 Subject: [PATCH 061/768] Increased RAWLEN to 101 to stop Panasonic codes overflowing --- IRremoteInt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index 393b5024a..486e0cf8a 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -38,7 +38,7 @@ //------------------------------------------------------------------------------ // Information for the Interrupt Service Routine // -#define RAWBUF 100 // Maximum length of raw duration buffer +#define RAWBUF 101 // Maximum length of raw duration buffer typedef struct { From 8afb3e73a6196b4a7b1f4d9631e83500b58aeedb Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 18:26:23 +0100 Subject: [PATCH 062/768] Introduced overflow detection code to the ISR State Machine --- irISR.cpp | 25 ++++++++++++++++++------- irRecv.cpp | 6 ++++-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/irISR.cpp b/irISR.cpp index 5e1d98d8b..479e98477 100644 --- a/irISR.cpp +++ b/irISR.cpp @@ -4,22 +4,27 @@ #include "IRremoteInt.h" //+============================================================================= +// Interrupt Service Routine - Fires every 50uS // 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. +// Recorded in ticks of 50uS [microseconds, 0.000050 seconds] +// '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 +// As soon as a the first [SPACE] entry 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; New logging starts // ISR (TIMER_INTR_NAME) { TIMER_RESET; - uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); + // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on] + // digitalRead() is very slow. Optimisation is possible, but makes the code unportable + uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); - irparams.timer++; // One more 50us tick - if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_STOP ; // Buffer overflow + irparams.timer++; // One more 50uS tick + if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_OVERFLOW ; // Buffer overflow switch(irparams.rcvstate) { case STATE_IDLE: // In the middle of a gap @@ -30,6 +35,7 @@ ISR (TIMER_INTR_NAME) } else { // gap just ended, record duration and start recording transmission + irparams.overflow = false; irparams.rawlen = 0; irparams.rawbuf[irparams.rawlen++] = irparams.timer; irparams.timer = 0; @@ -64,6 +70,11 @@ ISR (TIMER_INTR_NAME) case STATE_STOP: // waiting, measuring gap if (irdata == MARK) irparams.timer = 0 ; // reset gap timer break; + + case STATE_OVERFLOW: // Flag up a read overflow + irparams.overflow = true; + irparams.rcvstate = STATE_STOP; + break; } if (irparams.blinkflag) { diff --git a/irRecv.cpp b/irRecv.cpp index 8328319a4..8bcb0bf0d 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -57,8 +57,10 @@ void IRrecv::resume ( ) // Results of decoding are stored in results int IRrecv::decode (decode_results *results) { - results->rawbuf = irparams.rawbuf; - results->rawlen = irparams.rawlen; + results->rawbuf = irparams.rawbuf; + results->rawlen = irparams.rawlen; + + results->overflow = irparams.overflow; if (irparams.rcvstate != STATE_STOP) return false ; From 5e7a1c1f12560f8dc745ce717ea955b154f3475a Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 18:27:10 +0100 Subject: [PATCH 063/768] Abbreviated (Panasonic) address handling --- IRremote.h | 63 ++++++++++++++++++++++++++---------------------- ir_Panasonic.cpp | 8 +++--- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/IRremote.h b/IRremote.h index a45605c71..6507f9d76 100644 --- a/IRremote.h +++ b/IRremote.h @@ -69,42 +69,47 @@ int MATCH (int measured, int desired) ; // #define TEST //------------------------------------------------------------------------------ -enum decode_type_t { - UNKNOWN = -1, - UNUSED = 0, - NEC = 1, - SONY = 2, - RC5 = 3, - RC6 = 4, - DISH = 5, - SHARP = 6, - PANASONIC = 7, - JVC = 8, - SANYO = 9, - MITSUBISHI = 10, - SAMSUNG = 11, - LG = 12, - WHYNTER = 13, - AIWA_RC_T501 = 14, -}; +// An enumerated list of all supported formats +// +typedef + enum { + UNKNOWN = -1, + UNUSED = 0, + NEC = 1, + SONY = 2, + RC5 = 3, + RC6 = 4, + DISH = 5, + SHARP = 6, + PANASONIC = 7, + JVC = 8, + SANYO = 9, + MITSUBISHI = 10, + SAMSUNG = 11, + LG = 12, + WHYNTER = 13, + AIWA_RC_T501 = 14, + } +decode_type_t; //------------------------------------------------------------------------------ // Results returned from the decoder -class decode_results { -public: - decode_type_t decode_type; // NEC, SONY, RC5, UNKNOWN - union { // This is used for decoding Panasonic and Sharp data - unsigned int panasonicAddress; - unsigned int sharpAddress; - }; - unsigned long value; // Decoded value - int bits; // Number of bits in decoded value - volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks - int rawlen; // Number of records in rawbuf. +// +class decode_results +{ + public: + decode_type_t decode_type; // UNKNOWN, NEC, SONY, RC5, ... + unsigned int address; // Used by Panasonic & Sharp + unsigned long value; // Decoded value + int bits; // Number of bits in decoded value + volatile unsigned int *rawbuf; // Raw intervals in 50uS ticks + int rawlen; // Number of records in rawbuf. + int overflow; // true iff IR raw code too long }; //------------------------------------------------------------------------------ // Decoded value for NEC when a repeat code is received +// #define REPEAT 0xffffffff //------------------------------------------------------------------------------ diff --git a/ir_Panasonic.cpp b/ir_Panasonic.cpp index 494c28ddb..8d88ade9c 100644 --- a/ir_Panasonic.cpp +++ b/ir_Panasonic.cpp @@ -69,10 +69,10 @@ long IRrecv::decodePanasonic (decode_results *results) offset++; } - results->value = (unsigned long)data; - results->panasonicAddress = (unsigned int)(data >> 32); - results->decode_type = PANASONIC; - results->bits = PANASONIC_BITS; + results->value = (unsigned long)data; + results->address = (unsigned int)(data >> 32); + results->decode_type = PANASONIC; + results->bits = PANASONIC_BITS; return true; } From 66dee2fa169968e1a7be0ea1b7300d17177140e8 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 18:33:00 +0100 Subject: [PATCH 064/768] ISR Commenting --- irISR.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/irISR.cpp b/irISR.cpp index 479e98477..acafafb45 100644 --- a/irISR.cpp +++ b/irISR.cpp @@ -27,14 +27,14 @@ ISR (TIMER_INTR_NAME) if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_OVERFLOW ; // 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. + 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 + // Gap just ended; Record duration; Start recording transmission irparams.overflow = false; irparams.rawlen = 0; irparams.rawbuf[irparams.rawlen++] = irparams.timer; @@ -43,43 +43,43 @@ ISR (TIMER_INTR_NAME) } } break; - - case STATE_MARK: // timing MARK - if (irdata == SPACE) { // MARK ended, record time + //...................................................................... + 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 + //...................................................................... + case STATE_SPACE: // Timing Space + if (irdata == MARK) { // Space just ended; Record time irparams.rawbuf[irparams.rawlen++] = irparams.timer; irparams.timer = 0; irparams.rcvstate = STATE_MARK; - } else if (irparams.timer > GAP_TICKS) { // SPACE - // big SPACE, indicates gap between codes - // Mark current code as ready for processing + } else if (irparams.timer > GAP_TICKS) { // Space + // A long Space, indicates gap between codes + // Flag the current code as ready for processing // Switch to STOP - // Don't reset timer; keep counting space width + // 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 + //...................................................................... + case STATE_STOP: // Waiting; Measuring Gap + if (irdata == MARK) irparams.timer = 0 ; // Reset gap timer break; - - case STATE_OVERFLOW: // Flag up a read overflow + //...................................................................... + case STATE_OVERFLOW: // Flag up a read overflow; Stop the State Machine irparams.overflow = true; irparams.rcvstate = STATE_STOP; break; } + // If requested, flash LED L (D13) while receiving IR data if (irparams.blinkflag) { if (irdata == MARK) BLINKLED_ON() ; // turn pin 13 LED on else BLINKLED_OFF() ; // turn pin 13 LED off } } - From eb0360e75888b8491bb2e0a6883fca8ea360135a Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 20:27:59 +0100 Subject: [PATCH 065/768] More cleanup and a few minor optimisations --- IRremote.h | 419 ++++++++++++++++++++++++++-------------------- ir_Aiwa.cpp | 70 ++++---- ir_Dish.cpp | 48 +++--- ir_JVC.cpp | 38 +++-- ir_LG.cpp | 28 ++-- ir_Mitsubishi.cpp | 4 +- ir_NEC.cpp | 6 +- ir_Panasonic.cpp | 28 ++-- ir_RC5_RC6.cpp | 125 +++++++------- ir_Samsung.cpp | 30 ++-- ir_Sanyo.cpp | 99 ++++++----- ir_Sharp.cpp | 62 +++---- ir_Sony.cpp | 22 +-- ir_Whynter.cpp | 37 ++-- 14 files changed, 536 insertions(+), 480 deletions(-) diff --git a/IRremote.h b/IRremote.h index 6507f9d76..8882fa8c6 100644 --- a/IRremote.h +++ b/IRremote.h @@ -1,17 +1,104 @@ + +//****************************************************************************** +// IRremote +// Version 0.1 July, 2009 +// Copyright 2009 Ken Shirriff +// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm http://arcfn.com +// Edited by Mitra to add new controller SANYO +// +// 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) +// LG added by Darryl Smith (based on the JVC protocol) +// Whynter A/C ARC-110WD added by Francesco Meschia +//****************************************************************************** + #ifndef IRremote_h #define IRremote_h -#define DEBUG -#undef DEBUG +//------------------------------------------------------------------------------ +// Supported IR protocols +// Each protocol you include costs memory and, during decode, costs time +// Disable (set to 0) all the protocols you do not need/want! +// +#define DECODE_RC5 1 +#define SEND_RC5 1 + +#define DECODE_RC6 1 +#define SEND_RC6 1 + +#define DECODE_NEC 1 +#define SEND_NEC 1 + +#define DECODE_SONY 1 +#define SEND_SONY 1 + +#define DECODE_PANASONIC 1 +#define SEND_PANASONIC 1 + +#define DECODE_JVC 1 +#define SEND_JVC 1 + +#define DECODE_SAMSUNG 1 +#define SEND_SAMSUNG 1 + +#define DECODE_WHYNTER 1 +#define SEND_WHYNTER 1 + +#define DECODE_AIWA_RC_T501 1 +#define SEND_AIWA_RC_T501 1 + +#define DECODE_LG 1 +#define SEND_LG 0 // NOT WRITTEN + +#define DECODE_SANYO 1 +#define SEND_SANYO 0 // NOT WRITTEN + +#define DECODE_MITSUBISHI 1 +#define SEND_MITSUBISHI 0 // NOT WRITTEN + +#define DECODE_DISH 0 // NOT WRITTEN +#define SEND_DISH 1 + +#define DECODE_SHARP 0 // NOT WRITTEN +#define SEND_SHARP 1 //------------------------------------------------------------------------------ -int MATCH_SPACE (int measured_ticks, int desired_us) ; -int MATCH_MARK (int measured_ticks, int desired_us) ; -int MATCH (int measured, int desired) ; +// An enumerated list of all supported formats +// You do NOT need to remove entries from this list when disabling protocols! +// +typedef + enum { + UNKNOWN = -1, + UNUSED = 0, + RC5 = 1, + RC6 = 2, + NEC = 3, + SONY = 4, + PANASONIC = 5, + JVC = 6, + SAMSUNG = 7, + WHYNTER = 8, + AIWA_RC_T501 = 9, + LG = 10, + SANYO = 11, + MITSUBISHI = 12, + DISH = 13, + SHARP = 14, + } +decode_type_t; + +//------------------------------------------------------------------------------ +// Set DEBUG to 1 for lots of lovely debug output +// +#define DEBUG 0 //------------------------------------------------------------------------------ // Debug directives -#ifdef DEBUG +// +#if DEBUG # define DBG_PRINT(...) Serial.print(__VA_ARGS__) # define DBG_PRINTLN(...) Serial.println(__VA_ARGS__) #else @@ -20,77 +107,11 @@ int MATCH (int measured, int desired) ; #endif //------------------------------------------------------------------------------ -#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 - * Copyright 2009 Ken Shirriff - * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm http://arcfn.com - * Edited by Mitra to add new controller SANYO - * - * 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) - * LG added by Darryl Smith (based on the JVC protocol) - * Whynter A/C ARC-110WD added by Francesco Meschia - */ - -// The following are compile-time library options. -// If you change them, recompile the library. -// If DEBUG is defined, a lot of debugging output will be printed during decoding. -// TEST must be defined for the IRtest unittests to work. It will make some -// methods virtual, which will be slightly slower, which is why it is optional. -//#define DEBUG -// #define TEST - -//------------------------------------------------------------------------------ -// An enumerated list of all supported formats +// Mark & Space matching functions // -typedef - enum { - UNKNOWN = -1, - UNUSED = 0, - NEC = 1, - SONY = 2, - RC5 = 3, - RC6 = 4, - DISH = 5, - SHARP = 6, - PANASONIC = 7, - JVC = 8, - SANYO = 9, - MITSUBISHI = 10, - SAMSUNG = 11, - LG = 12, - WHYNTER = 13, - AIWA_RC_T501 = 14, - } -decode_type_t; +int MATCH (int measured, int desired) ; +int MATCH_MARK (int measured_ticks, int desired_us) ; +int MATCH_SPACE (int measured_ticks, int desired_us) ; //------------------------------------------------------------------------------ // Results returned from the decoder @@ -99,130 +120,168 @@ class decode_results { public: decode_type_t decode_type; // UNKNOWN, NEC, SONY, RC5, ... - unsigned int address; // Used by Panasonic & Sharp - unsigned long value; // Decoded value + unsigned int address; // Used by Panasonic & Sharp [16-bits] + unsigned long value; // Decoded value [max 32-bits] int bits; // Number of bits in decoded value volatile unsigned int *rawbuf; // Raw intervals in 50uS ticks - int rawlen; // Number of records in rawbuf. + int rawlen; // Number of records in rawbuf int overflow; // true iff IR raw code too long }; //------------------------------------------------------------------------------ // Decoded value for NEC when a repeat code is received // -#define REPEAT 0xffffffff +#define REPEAT 0xFFFFFFFF //------------------------------------------------------------------------------ -// main class for receiving IR +// Main class for receiving IR +// class IRrecv { -public: - IRrecv(int recvpin); - void blink13(int blinkflag); - int decode(decode_results *results); - void enableIRIn(); - void resume(); -private: - // These are called by decode - int getRClevel(decode_results *results, int *offset, int *used, int t1); -#ifdef DECODE_NEC - long decodeNEC(decode_results *results); -#endif -#ifdef DECODE_SONY - long decodeSony(decode_results *results); -#endif -#ifdef DECODE_SANYO - long decodeSanyo(decode_results *results); -#endif -#ifdef DECODE_MITSUBISHI - long decodeMitsubishi(decode_results *results); -#endif -#ifdef DECODE_RC5 - long decodeRC5(decode_results *results); -#endif -#ifdef DECODE_RC6 - long decodeRC6(decode_results *results); -#endif -#ifdef DECODE_PANASONIC - long decodePanasonic(decode_results *results); -#endif -#ifdef DECODE_LG - long decodeLG(decode_results *results); -#endif -#ifdef DECODE_JVC - long decodeJVC(decode_results *results); -#endif -#ifdef DECODE_SAMSUNG - long decodeSAMSUNG(decode_results *results); -#endif + public: + IRrecv (int recvpin) ; -#ifdef DECODE_WHYNTER - long decodeWhynter(decode_results *results); -#endif + void blink13 (int blinkflag) ; + int decode (decode_results *results) ; + void enableIRIn ( ) ; + void resume ( ) ; -#ifdef DECODE_AIWA_RC_T501 - long decodeAiwaRCT501(decode_results *results); -#endif - - long decodeHash(decode_results *results); - int compare(unsigned int oldval, unsigned int newval); + private: + long decodeHash (decode_results *results) ; + int compare (unsigned int oldval, unsigned int newval) ; + //...................................................................... +# if (DECODE_RC5 || DECODE_RC6) + // This helper function is shared by RC5 and RC6 + int getRClevel (decode_results *results, int *offset, int *used, int t1) ; +# endif +# if DECODE_RC5 + bool decodeRC5 (decode_results *results) ; +# endif +# if DECODE_RC6 + bool decodeRC6 (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_NEC + bool decodeNEC (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_SONY + bool decodeSony (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_PANASONIC + bool decodePanasonic (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_JVC + bool decodeJVC (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_SAMSUNG + bool decodeSAMSUNG (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_WHYNTER + bool decodeWhynter (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_AIWA_RC_T501 + bool decodeAiwaRCT501 (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_LG + bool decodeLG (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_SANYO + bool decodeSanyo (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_MITSUBISHI + bool decodeMitsubishi (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_DISH + bool decodeDish (decode_results *results) ; // NOT WRITTEN +# endif + //...................................................................... +# if DECODE_SHARP + bool decodeSharp (decode_results *results) ; // NOT WRITTEN +# endif } ; -//------------------------------------------------------------------------------ -// Only used for testing; can remove virtual for shorter code -#ifdef TEST -#define VIRTUAL virtual -#else -#define VIRTUAL -#endif - //------------------------------------------------------------------------------ class IRsend { -public: - IRsend() {} - void sendRaw(unsigned int buf[], int len, int hz); -#ifdef SEND_RC5 - void sendRC5(unsigned long data, int nbits); -#endif -#ifdef SEND_RC6 - void sendRC6(unsigned long data, int nbits); -#endif -#ifdef SEND_WHYNTER - void sendWhynter(unsigned long data, int nbits); -#endif -#ifdef SEND_NEC - void sendNEC(unsigned long data, int nbits); -#endif -#ifdef SEND_SONY - void sendSony(unsigned long data, int nbits); - // Neither Sanyo nor Mitsubishi send is implemented yet - // void sendSanyo(unsigned long data, int nbits); - // void sendMitsubishi(unsigned long data, int nbits); -#endif -#ifdef SEND_DISH - void sendDISH(unsigned long data, int nbits); -#endif -#ifdef SEND_SHARP - void sendSharpRaw(unsigned long data, int nbits); - void sendSharp(unsigned int address, unsigned int command); -#endif -#ifdef SEND_PANASONIC - void sendPanasonic(unsigned int address, unsigned long data); -#endif -#ifdef SEND_JVC - 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. -#endif -#ifdef SEND_AIWA_RC_T501 - void sendAiwaRCT501(int code); -#endif -#ifdef SEND_SAMSUNG - void sendSAMSUNG(unsigned long data, int nbits); -#endif - void enableIROut(int khz); - VIRTUAL void mark(int usec); - VIRTUAL void space(int usec); + public: + IRsend () { } + + void enableIROut (int khz) ; + void mark (int usec) ; + void space (int usec) ; + void sendRaw (unsigned int buf[], int len, int hz) ; + + //...................................................................... +# if SEND_RC5 + void sendRC5 (unsigned long data, int nbits) ; +# endif +# if SEND_RC6 + void sendRC6 (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_NEC + void sendNEC (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_SONY + void sendSony (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_PANASONIC + void sendPanasonic (unsigned int address, unsigned long data) ; +# endif + //...................................................................... +# if SEND_JVC + // JVC does NOT repeat by sending a separate code (like NEC does). + // The JVC protocol repeats by skipping the header. + // To send a JVC repeat signal, send the original code value + // and set 'repeat' to true + void sendJVC (unsigned long data, int nbits, bool repeat) ; +# endif + //...................................................................... +# if SEND_SAMSUNG + void sendSAMSUNG (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_WHYNTER + void sendWhynter (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_AIWA_RC_T501 + void sendAiwaRCT501 (int code) ; +# endif + //...................................................................... +# if SEND_LG + void sendLG ( ) ; // NOT WRITTEN +# endif + //...................................................................... +# if SEND_SANYO + void sendSanyo ( ) ; // NOT WRITTEN +# endif + //...................................................................... +# if SEND_MISUBISHI + void sendMitsubishi ( ) ; // NOT WRITTEN +# endif + //...................................................................... +# if SEND_DISH + void sendDISH (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_SHARP + void sendSharpRaw (unsigned long data, int nbits) ; + void sendSharp (unsigned int address, unsigned int command) ; +# endif } ; #endif diff --git a/ir_Aiwa.cpp b/ir_Aiwa.cpp index b4049ca67..f56aa9981 100644 --- a/ir_Aiwa.cpp +++ b/ir_Aiwa.cpp @@ -24,7 +24,7 @@ #define AIWA_RC_T501_ZERO_SPACE 1700 //+============================================================================= -#ifdef SEND_AIWA_RC_T501 +#if SEND_AIWA_RC_T501 void IRsend::sendAiwaRCT501 (int code) { unsigned long pre = 0x0227EEC0; // 26-bits @@ -48,7 +48,8 @@ void IRsend::sendAiwaRCT501 (int code) // it only send 15bits and ignores the top bit // then uses TOPBIT which is 0x80000000 to check the bit code // I suspect TOPBIT should be changed to 0x00008000 - // Skip firts code bit + + // Skip first code bit code <<= 1; // Send code for (int i = 0; i < 15; i++) { @@ -57,6 +58,7 @@ void IRsend::sendAiwaRCT501 (int code) else space(AIWA_RC_T501_ZERO_SPACE) ; code <<= 1; } + //-^- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK! // POST-DATA, 1 bit, 0x0 @@ -69,40 +71,36 @@ void IRsend::sendAiwaRCT501 (int code) #endif //+============================================================================= -#ifdef DECODE_AIWA_RC_T501 -long IRrecv::decodeAiwaRCT501 (decode_results *results) +#if DECODE_AIWA_RC_T501 +bool 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; + int data = 0; + int offset = 1; + + // Check SIZE + if (irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) return false ; + + // Check HDR Mark/Space + if (!MATCH_MARK (results->rawbuf[offset++], AIWA_RC_T501_HDR_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], AIWA_RC_T501_HDR_SPACE)) return false ; + + 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 = (data << 1) | 0 ; + 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 - diff --git a/ir_Dish.cpp b/ir_Dish.cpp index 22e10d025..387b163db 100644 --- a/ir_Dish.cpp +++ b/ir_Dish.cpp @@ -21,35 +21,33 @@ // 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 +#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 //+============================================================================= -#ifdef SEND_DISH +#if 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); - } - } + // 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 diff --git a/ir_JVC.cpp b/ir_JVC.cpp index 151820a26..123c20e1f 100644 --- a/ir_JVC.cpp +++ b/ir_JVC.cpp @@ -18,8 +18,13 @@ #define JVC_RPT_LENGTH 60000 //+============================================================================= -#ifdef SEND_JVC -void IRsend::sendJVC (unsigned long data, int nbits, int repeat) +// JVC does NOT repeat by sending a separate code (like NEC does). +// The JVC protocol repeats by skipping the header. +// To send a JVC repeat signal, send the original code value +// and set 'repeat' to true +// +#if SEND_JVC +void IRsend::sendJVC (unsigned long data, int nbits, bool repeat) { // Set IR carrier frequency enableIROut(38); @@ -48,37 +53,36 @@ void IRsend::sendJVC (unsigned long data, int nbits, int repeat) #endif //+============================================================================= -#ifdef DECODE_JVC -long IRrecv::decodeJVC (decode_results *results) +#if DECODE_JVC +bool 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; + 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 (!MATCH_MARK(results->rawbuf[offset++], JVC_HDR_MARK)) return false ; - if (irparams.rawlen < 2 * JVC_BITS + 1 ) return false ; + if (irparams.rawlen < (2 * JVC_BITS) + 1 ) return false ; // Initial space - if (!MATCH_SPACE(results->rawbuf[offset], JVC_HDR_SPACE)) return false ; - offset++; + if (!MATCH_SPACE(results->rawbuf[offset++], JVC_HDR_SPACE)) return false ; for (int i = 0; i < JVC_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return false ; - offset++; + if (!MATCH_MARK(results->rawbuf[offset++], JVC_BIT_MARK)) return false ; + 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 if (MATCH_SPACE(results->rawbuf[offset], JVC_ZERO_SPACE)) data = (data << 1) | 0 ; else return false ; offset++; } diff --git a/ir_LG.cpp b/ir_LG.cpp index 44b1a778b..4e8dd82b6 100644 --- a/ir_LG.cpp +++ b/ir_LG.cpp @@ -19,24 +19,24 @@ #define LG_RPT_LENGTH 60000 //+============================================================================= -#ifdef DECODE_LG -long IRrecv::decodeLG (decode_results *results) +#if DECODE_LG +bool 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++; + // Check we have the right amount of data + if (irparams.rawlen < (2 * LG_BITS) + 1 ) return false ; + + // Initial mark/space + if (!MATCH_MARK(results->rawbuf[offset++], LG_HDR_MARK)) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], LG_HDR_SPACE)) return false ; + for (int i = 0; i < LG_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return false ; - offset++; + if (!MATCH_MARK(results->rawbuf[offset++], LG_BIT_MARK)) return false ; + 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 if (MATCH_SPACE(results->rawbuf[offset], LG_ZERO_SPACE)) data = (data << 1) | 0 ; else return false ; offset++; } @@ -45,8 +45,8 @@ long IRrecv::decodeLG (decode_results *results) if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return false ; // Success - results->bits = LG_BITS; - results->value = data; + results->bits = LG_BITS; + results->value = data; results->decode_type = LG; return true; } diff --git a/ir_Mitsubishi.cpp b/ir_Mitsubishi.cpp index e02b64aa5..7f83e530f 100644 --- a/ir_Mitsubishi.cpp +++ b/ir_Mitsubishi.cpp @@ -23,8 +23,8 @@ // #define MITSUBISHI_RPT_LENGTH 45000 //+============================================================================= -#ifdef DECODE_MITSUBISHI -long IRrecv::decodeMitsubishi (decode_results *results) +#if DECODE_MITSUBISHI +bool 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; diff --git a/ir_NEC.cpp b/ir_NEC.cpp index cb3b248f4..8da46e876 100644 --- a/ir_NEC.cpp +++ b/ir_NEC.cpp @@ -18,7 +18,7 @@ #define NEC_RPT_SPACE 2250 //+============================================================================= -#ifdef SEND_NEC +#if SEND_NEC void IRsend::sendNEC (unsigned long data, int nbits) { // Set IR carrier frequency @@ -48,8 +48,8 @@ void IRsend::sendNEC (unsigned long data, int nbits) //+============================================================================= // NECs have a repeat only 4 items long // -#ifdef DECODE_NEC -long IRrecv::decodeNEC (decode_results *results) +#if DECODE_NEC +bool 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!? diff --git a/ir_Panasonic.cpp b/ir_Panasonic.cpp index 8d88ade9c..d3b471a6d 100644 --- a/ir_Panasonic.cpp +++ b/ir_Panasonic.cpp @@ -9,15 +9,15 @@ // 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 +#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 +#if SEND_PANASONIC void IRsend::sendPanasonic (unsigned int address, unsigned long data) { // Set IR carrier frequency @@ -48,16 +48,14 @@ void IRsend::sendPanasonic (unsigned int address, unsigned long data) #endif //+============================================================================= -#ifdef DECODE_PANASONIC -long IRrecv::decodePanasonic (decode_results *results) +#if DECODE_PANASONIC +bool IRrecv::decodePanasonic (decode_results *results) { - unsigned long long data = 0; - int offset = 1; + 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++; + if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_MARK )) return false ; + if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_SPACE)) return false ; // decode address for (int i = 0; i < PANASONIC_BITS; i++) { diff --git a/ir_RC5_RC6.cpp b/ir_RC5_RC6.cpp index 16c2badae..1a9576d2e 100644 --- a/ir_RC5_RC6.cpp +++ b/ir_RC5_RC6.cpp @@ -12,25 +12,30 @@ // 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; + int width; + int val; + int correction; + int avail; + + if (*offset >= results->rawlen) return SPACE ; // After end of recorded buffer, assume SPACE. + width = results->rawbuf[*offset]; + val = ((*offset) % 2) ? MARK : SPACE; + correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS; + + 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; } //============================================================================== @@ -42,12 +47,12 @@ int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int // // NB: First bit must be a one (start bit) // -#define MIN_RC5_SAMPLES 11 -#define RC5_T1 889 -#define RC5_RPT_LENGTH 46000 +#define MIN_RC5_SAMPLES 11 +#define RC5_T1 889 +#define RC5_RPT_LENGTH 46000 //+============================================================================= -#ifdef SEND_RC5 +#if SEND_RC5 void IRsend::sendRC5 (unsigned long data, int nbits) { // Set IR carrier frequency @@ -74,25 +79,28 @@ void IRsend::sendRC5 (unsigned long data, int nbits) #endif //+============================================================================= -#ifdef DECODE_RC5 -long IRrecv::decodeRC5 (decode_results *results) +#if DECODE_RC5 +bool IRrecv::decodeRC5 (decode_results *results) { + int nbits; + long data = 0; + int used = 0; + int offset = 1; // Skip gap space + 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); + 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 ; + if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 1 ; + else if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 0 ; + else return false ; } // Success @@ -112,13 +120,13 @@ long IRrecv::decodeRC5 (decode_results *results) // // 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 +#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 +#if SEND_RC6 void IRsend::sendRC6 (unsigned long data, int nbits) { // Set IR carrier frequency @@ -150,46 +158,47 @@ void IRsend::sendRC6 (unsigned long data, int nbits) #endif //+============================================================================= -#ifdef DECODE_RC6 -long IRrecv::decodeRC6 (decode_results *results) +#if DECODE_RC6 +bool IRrecv::decodeRC6 (decode_results *results) { + int nbits; + long data = 0; + int used = 0; + int offset = 1; // Skip first space + 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; + if (!MATCH_MARK(results->rawbuf[offset++], RC6_HDR_MARK)) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], RC6_HDR_SPACE)) return false ; // 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 + 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 + + if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 1 ; // inverted compared to RC5 + else if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 0 ; // ... + else return false ; // Error } // Success - results->bits = nbits; - results->value = data; + results->bits = nbits; + results->value = data; results->decode_type = RC6; return true; } diff --git a/ir_Samsung.cpp b/ir_Samsung.cpp index 0773eddc2..65452f262 100644 --- a/ir_Samsung.cpp +++ b/ir_Samsung.cpp @@ -18,7 +18,7 @@ #define SAMSUNG_RPT_SPACE 2250 //+============================================================================= -#ifdef SEND_SAMSUNG +#if SEND_SAMSUNG void IRsend::sendSAMSUNG (unsigned long data, int nbits) { // Set IR carrier frequency @@ -48,38 +48,36 @@ void IRsend::sendSAMSUNG (unsigned long data, int nbits) //+============================================================================= // SAMSUNGs have a repeat only 4 items long // -#ifdef DECODE_SAMSUNG -long IRrecv::decodeSAMSUNG (decode_results *results) +#if DECODE_SAMSUNG +bool IRrecv::decodeSAMSUNG (decode_results *results) { long data = 0; - int offset = 1; // Skip first space + 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; + 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 ; + if (irparams.rawlen < (2 * SAMSUNG_BITS) + 4) return false ; // Initial space - if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) return false ; - offset++; + if (!MATCH_SPACE(results->rawbuf[offset++], SAMSUNG_HDR_SPACE)) return false ; for (int i = 0; i < SAMSUNG_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_BIT_MARK)) return false ; - - offset++; + if (!MATCH_MARK(results->rawbuf[offset++], SAMSUNG_BIT_MARK)) return false ; 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 if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ZERO_SPACE)) data = (data << 1) | 0 ; else return false ; offset++; } diff --git a/ir_Sanyo.cpp b/ir_Sanyo.cpp index ad0e76f82..c775d6118 100644 --- a/ir_Sanyo.cpp +++ b/ir_Sanyo.cpp @@ -12,68 +12,65 @@ // 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 +#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) +#if DECODE_SANYO +bool 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 + long data = 0; + int offset = 0; // Skip first space <-- CHECK THIS! + + if (irparams.rawlen < (2 * SANYO_BITS) + 2) return false ; #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]); + // 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 space + 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++; + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK)) return false ; - // Skip Second 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 ; - 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++; - } + while (offset + 1 < irparams.rawlen) { + if (!MATCH_SPACE(results->rawbuf[offset++], SANYO_HDR_SPACE)) break ; - // Success - results->bits = (offset - 1) / 2; - if (results->bits < 12) { - results->bits = 0; - return false; - } + if (MATCH_MARK(results->rawbuf[offset], SANYO_ONE_MARK)) data = (data << 1) | 1 ; + else if (MATCH_MARK(results->rawbuf[offset], SANYO_ZERO_MARK)) data = (data << 1) | 0 ; + else return false ; + offset++; + } - results->value = data; - results->decode_type = SANYO; - return true; + // 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 - diff --git a/ir_Sharp.cpp b/ir_Sharp.cpp index ffd77ed0c..13f8a53e4 100644 --- a/ir_Sharp.cpp +++ b/ir_Sharp.cpp @@ -9,63 +9,63 @@ // SSSS H H A A R R P //============================================================================== -// Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand ) +// 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 +// 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_BITS 15 +#define SHARP_BIT_MARK 245 +#define SHARP_ONE_SPACE 1805 +#define SHARP_ZERO_SPACE 795 +#define SHARP_GAP 600000 +#define SHARP_RPT_SPACE 3000 -#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 +#define SHARP_TOGGLE_MASK 0x3FF //+============================================================================= -#ifdef SEND_SHARP +#if SEND_SHARP void IRsend::sendSharpRaw (unsigned long data, int nbits) { - unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; - enableIROut(38); + 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); - } - } + // 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); + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + delay(40); - data = data ^ SHARP_TOGGLE_MASK; - } + data = data ^ SHARP_TOGGLE_MASK; + } } +#endif //+============================================================================= // Sharp send compatible with data obtained through decodeSharp() // ^^^^^^^^^^^^^ FUNCTION MISSING! // +#if SEND_SHARP void IRsend::sendSharp (unsigned int address, unsigned int command) { - sendSharpRaw((address << 10) | (command << 2) | 2, 15); + sendSharpRaw((address << 10) | (command << 2) | 2, SHARP_BITS); } - #endif diff --git a/ir_Sony.cpp b/ir_Sony.cpp index 4446f834e..e01df550c 100644 --- a/ir_Sony.cpp +++ b/ir_Sony.cpp @@ -18,7 +18,7 @@ #define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround //+============================================================================= -#ifdef SEND_SONY +#if SEND_SONY void IRsend::sendSony (unsigned long data, int nbits) { // Set IR carrier frequency @@ -44,12 +44,13 @@ void IRsend::sendSony (unsigned long data, int nbits) #endif //+============================================================================= -#ifdef DECODE_SONY -long IRrecv::decodeSony (decode_results *results) +#if DECODE_SONY +bool 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 + long data = 0; + int offset = 0; // Dont skip first space, check its size + + if (irparams.rawlen < (2 * SONY_BITS) + 2) return false ; // Some Sony's deliver repeats fast after first // unfortunately can't spot difference from of repeat from two fast clicks @@ -69,14 +70,13 @@ long IRrecv::decodeSony (decode_results *results) offset++; // Initial mark - if (!MATCH_MARK(results->rawbuf[offset], SONY_HDR_MARK)) return false ; - offset++; + if (!MATCH_MARK(results->rawbuf[offset++], SONY_HDR_MARK)) return false ; while (offset + 1 < irparams.rawlen) { - if (!MATCH_SPACE(results->rawbuf[offset], SONY_HDR_SPACE)) break ; - offset++; + if (!MATCH_SPACE(results->rawbuf[offset++], SONY_HDR_SPACE)) break ; + 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 if (MATCH_MARK(results->rawbuf[offset], SONY_ZERO_MARK)) data = (data << 1) | 0 ; else return false ; offset++; } diff --git a/ir_Whynter.cpp b/ir_Whynter.cpp index c97732abf..2165cb706 100644 --- a/ir_Whynter.cpp +++ b/ir_Whynter.cpp @@ -19,7 +19,7 @@ #define WHYNTER_ZERO_SPACE 750 //+============================================================================= -#ifdef SEND_WHYNTER +#if SEND_WHYNTER void IRsend::sendWhynter (unsigned long data, int nbits) { // Set IR carrier frequency @@ -51,35 +51,30 @@ void IRsend::sendWhynter (unsigned long data, int nbits) #endif //+============================================================================= -#ifdef DECODE_WHYNTER -long IRrecv::decodeWhynter (decode_results *results) +#if DECODE_WHYNTER +bool IRrecv::decodeWhynter (decode_results *results) { - long data = 0; + long data = 0; + int offset = 1; // skip initial space - if (irparams.rawlen < 2 * WHYNTER_BITS + 6) return false ; + // Check we have the right amount of data + 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++; + // Sequence begins with a bit mark and a zero space + if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_BIT_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_ZERO_SPACE)) return false ; // 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++; + if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_HDR_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_HDR_SPACE)) return false ; // data bits for (int i = 0; i < WHYNTER_BITS; i++) { - if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return false ; - offset++; + if (!MATCH_MARK(results->rawbuf[offset++], WHYNTER_BIT_MARK)) return false ; - 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 ; + if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ONE_SPACE )) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; offset++; } From aa32e8f048459620484c1fdd68a945bfe9df6815 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 21:07:40 +0100 Subject: [PATCH 066/768] Removed explicit values in enumeration --- IRremote.h | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/IRremote.h b/IRremote.h index 8882fa8c6..086da756f 100644 --- a/IRremote.h +++ b/IRremote.h @@ -73,20 +73,20 @@ typedef enum { UNKNOWN = -1, UNUSED = 0, - RC5 = 1, - RC6 = 2, - NEC = 3, - SONY = 4, - PANASONIC = 5, - JVC = 6, - SAMSUNG = 7, - WHYNTER = 8, - AIWA_RC_T501 = 9, - LG = 10, - SANYO = 11, - MITSUBISHI = 12, - DISH = 13, - SHARP = 14, + RC5, + RC6 + NEC, + SONY, + PANASONIC, + JVC, + SAMSUNG, + WHYNTER, + AIWA_RC_T501, + LG, + SANYO, + MITSUBISHI, + DISH, + SHARP, } decode_type_t; @@ -212,6 +212,8 @@ class IRrecv } ; //------------------------------------------------------------------------------ +// Main class for sending IR +// class IRsend { public: From 05e688a9617239a9cbbf840ab34a0145fb345c69 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 21:08:21 +0100 Subject: [PATCH 067/768] Added a template for new protocols with full instructions in a big comment at the top --- ir_Template.cpp | 172 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 ir_Template.cpp diff --git a/ir_Template.cpp b/ir_Template.cpp new file mode 100644 index 000000000..9aa33ae93 --- /dev/null +++ b/ir_Template.cpp @@ -0,0 +1,172 @@ +/* +Assuming the protocol we are adding is for the (imaginary) manufacturer: Shuzu + +Our fantasy protocol is a standard protocol, so we can use this standard +template without too much work. Some protocols are quite unique and will require +considerably more work in this file! It is way beyond the scope of this text to +explain how to reverse engineer "unusual" IR protocols. But, unless you own an +oscilloscope, the starting point is probably to use the rawDump.ino sketch and +try to spot the pattern! + +Before you start, make sure the IR library is working OK: + # Open up the Arduino IDE + # Load up the rawDump.ino example sketch + # Run it + +Now we can start to add our new protocol... + +1. Copy this file to : ir_Shuzu.cpp + +2. Replace all occurrences of "Shuzu" with the name of your protocol. + +3. Tweak the #defines to suit your protocol. + +4. If you're lucky, tweaking the #defines will make the default send() function + work. + +5. Again, if you're lucky, tweaking the #defines will have made the default + decode() function work. + +You have written the code to support your new protocol! + +Now you must do a few things to add it to the IRremote system: + +1. Open IRremote.h and make the following changes: + REMEMEBER to change occurences of "SHUZU" with the name of your protocol + + A. At the top, in the section "Supported Protocols", add: + #define DECODE_SHUZU 1 + #define SEND_SHUZU 1 + + B. In the section "enumerated list of all supported formats", add: + SHUZU, + to the end of the list (notice there is a comma after the protocol name) + + C. Further down in "Main class for receiving IR", add: + //...................................................................... + #if DECODE_SHUZU + bool decodeShuzu (decode_results *results) ; + #endif + + D. Further down in "Main class for sending IR", add: + //...................................................................... + #if SEND_SHUZU + void sendShuzu (unsigned long data, int nbits) ; + #endif + + E. Save your changes and close the file + +2. Now open irRecv.cpp and make the following change: + + A. In the function IRrecv::decode(), add: + #ifdef DECODE_NEC + DBG_PRINTLN("Attempting Shuzu decode"); + if (decodeShuzu(results)) return true ; + #endif + + B. Save your changes and close the file + +Now open the Arduino IDE, load up the rawDump.ino sketch, and run it. +Hopefully it will compile and upload. +If it doesn't, you've done something wrong. Check your work. +If you can't get it to work - seek help from somewhere. + +If you get this far, I will assume you have successfully added your new protocol +There is one last thing to do. + +1. Delete this giant instructional comment. + +2. Send a copy of your work to us so we can include it in the library and + others may benefit from your hard work and maybe even write a song about how + great you are for helping them! :) + +Regards, + BlueChip +*/ + +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// +// +// S H U Z U +// +// +//============================================================================== + +#define SHUZU_BITS 32 // The number of bits in the command + +#define SHUZU_HDR_MARK 1000 // The length of the Header:Mark +#define SHUZU_HDR_SPACE 2000 // The lenght of the Header:Space + +#define SHUZU_BIT_MARK 3000 // The length of a Bit:Mark +#define SHUZU_ONE_SPACE 4000 // The length of a Bit:Space for 1's +#define SHUZU_ZERO_SPACE 5000 // The length of a Bit:Space for 0's + +#define SHUZU_OTHER 1234 // Other things you may need to define + +//+============================================================================= +// +#if SEND_SHUZU +void IRsend::sendShuzu (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(38); + + // Header + mark (SHUZU_HDR_MARK); + space(SHUZU_HDR_SPACE); + + // Data + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark (SHUZU_BIT_MARK); + space(SHUZU_ONE_SPACE); + } else { + mark (SHUZU_BIT_MARK); + space(SHUZU_ZERO_SPACE); + } + } + + // Footer + mark(SHUZU_BIT_MARK); + space(0); // Always end with the LED off +} +#endif + +//+============================================================================= +// +#if DECODE_SHUZU +bool IRrecv::decodeShuzu (decode_results *results) +{ + unsigned long data = 0; // Somewhere to build our code + int offset = 1; // Skip the Gap reading + + // Check we have the right amount of data + if (irparams.rawlen != 1 + 2 + (2 * SHUZU_BITS) + 1) return false ; + + // Check initial Mark+Space match + if (!MATCH_MARK (results->rawbuf[offset++], SHUZU_HDR_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], SHUZU_HDR_SPACE)) return false ; + + // Read the bits in + for (int i = 0; i < SHUZU_BITS; i++) { + // Each bit looks like: MARK + SPACE_1 -> 1 + // or : MARK + SPACE_0 -> 0 + if (!MATCH_MARK(results->rawbuf[offset++], SAMSUNG_BIT_MARK)) return false ; + + // IR data is big-endian, so we shuffle it in from the right: + if (MATCH_SPACE(results->rawbuf[offset], SHUZU_ONE_SPACE)) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], SHUZU_ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // Success + results->bits = SHUZU_BITS; + results->value = data; + results->decode_type = SHUZU; + return true; +} +#endif From 07df68af9d7964748b6627c62d59b7529e0aa884 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 21:09:44 +0100 Subject: [PATCH 068/768] correct typo --- IRremote.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRremote.h b/IRremote.h index 086da756f..f5f433a74 100644 --- a/IRremote.h +++ b/IRremote.h @@ -74,7 +74,7 @@ typedef UNKNOWN = -1, UNUSED = 0, RC5, - RC6 + RC6, NEC, SONY, PANASONIC, From ae477413dea8e99325bdea616a9227a388a9d30c Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 22:03:00 +0100 Subject: [PATCH 069/768] Fixup old examples Add new example --- IRremote.h | 5 + examples/IRrecvDump/IRrecvDump.ino | 16 +-- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 162 +++++++++++++++++++++++++ 3 files changed, 175 insertions(+), 8 deletions(-) create mode 100644 examples/IRrecvDumpV2/IRrecvDumpV2.ino diff --git a/IRremote.h b/IRremote.h index f5f433a74..47a0e06b5 100644 --- a/IRremote.h +++ b/IRremote.h @@ -18,6 +18,11 @@ #ifndef IRremote_h #define IRremote_h +//------------------------------------------------------------------------------ +// The ISR header contains several useful macros the user may wish to use +// +#include "IRremoteInt.h" + //------------------------------------------------------------------------------ // Supported IR protocols // Each protocol you include costs memory and, during decode, costs time diff --git a/examples/IRrecvDump/IRrecvDump.ino b/examples/IRrecvDump/IRrecvDump.ino index a1ba3b2e4..abfef5488 100644 --- a/examples/IRrecvDump/IRrecvDump.ino +++ b/examples/IRrecvDump/IRrecvDump.ino @@ -31,22 +31,22 @@ void dump(decode_results *results) { int count = results->rawlen; if (results->decode_type == UNKNOWN) { Serial.print("Unknown encoding: "); - } + } else if (results->decode_type == NEC) { Serial.print("Decoded NEC: "); - } + } else if (results->decode_type == SONY) { Serial.print("Decoded SONY: "); - } + } else if (results->decode_type == RC5) { Serial.print("Decoded RC5: "); - } + } else if (results->decode_type == RC6) { Serial.print("Decoded RC6: "); } - else if (results->decode_type == PANASONIC) { + else if (results->decode_type == PANASONIC) { Serial.print("Decoded PANASONIC - Address: "); - Serial.print(results->panasonicAddress,HEX); + Serial.print(results->address,HEX); Serial.print(" Value: "); } else if (results->decode_type == LG) { @@ -54,7 +54,7 @@ void dump(decode_results *results) { } else if (results->decode_type == JVC) { Serial.print("Decoded JVC: "); - + } else if (results->decode_type == AIWA_RC_T501) { Serial.print("Decoded AIWA RC T501: "); @@ -73,7 +73,7 @@ void dump(decode_results *results) { for (int i = 0; i < count; i++) { if ((i % 2) == 1) { Serial.print(results->rawbuf[i]*USECPERTICK, DEC); - } + } else { Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); } diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino new file mode 100644 index 000000000..c6f070c45 --- /dev/null +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -0,0 +1,162 @@ +//------------------------------------------------------------------------------ +// Include the IRremote library headers +// +#include +#include + +//------------------------------------------------------------------------------ +// Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838) +// +IRrecv irrecv(6); + +//+============================================================================= +// Configure the Arduino +// +void setup ( ) +{ + Serial.begin(9600); // Status message will be sent to PC at 9600 baud + irrecv.enableIRIn(); // Start the receiver +} + +//+============================================================================= +// Display IR code +// +void ircode (decode_results *results) +{ + // Panasonic has an Address + if (results->decode_type == PANASONIC) { + Serial.print(results->address, HEX); + Serial.print(":"); + } + + // Print Code + Serial.print(results->value, HEX); +} + +//+============================================================================= +// Display encoding type +// +void encoding (decode_results *results) +{ + switch (results->decode_type) { + default: + case UNKNOWN: Serial.print("UNKNOWN"); break ; + case NEC: Serial.print("NEC"); break ; + case SONY: Serial.print("SONY"); break ; + case RC5: Serial.print("RC5"); break ; + case RC6: Serial.print("RC6"); break ; + case DISH: Serial.print("DISH"); break ; + case SHARP: Serial.print("SHARP"); break ; + case JVC: Serial.print("JVC"); break ; + case SANYO: Serial.print("SANYO"); break ; + case MITSUBISHI: Serial.print("MITSUBISHI"); break ; + case SAMSUNG: Serial.print("SAMSUNG"); break ; + case LG: Serial.print("LG"); break ; + case WHYNTER: Serial.print("WHYNTER"); break ; + case AIWA_RC_T501: Serial.print("AIWA_RC_T501"); break ; + case PANASONIC: Serial.print("PANASONIC"); break ; + } +} + +//+============================================================================= +// Dump out the decode_results structure. +// +void dumpInfo (decode_results *results) +{ + // Check if the buffer overflowed + if (results->overflow) { + Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWLEN"); + return; + } + + // Show Encoding standard + Serial.print("Encoding : "); + encoding(results); + Serial.println(""); + + // Show Code & length + Serial.print("Code : "); + ircode(results); + Serial.print(" ("); + Serial.print(results->bits, DEC); + Serial.println(" bits)"); +} + +//+============================================================================= +// Dump out the decode_results structure. +// +void dumpRaw (decode_results *results) +{ + // Print Raw data + Serial.print("Timing["); + Serial.print(results->rawlen, DEC); + Serial.println("]: "); + Serial.print(" -"); + Serial.println(results->rawbuf[0] * USECPERTICK, DEC); + for (int i = 1; i < results->rawlen; i++) { + int x = results->rawbuf[i] * USECPERTICK; + if (!(i & 1)) { // even + Serial.print("-"); + if (x < 1000) Serial.print(" ") ; + if (x < 100) Serial.print(" ") ; + Serial.print(x, DEC); + } else { // odd + Serial.print(" "); + Serial.print("+"); + if (x < 1000) Serial.print(" ") ; + if (x < 100) Serial.print(" ") ; + Serial.print(x, DEC); + Serial.print(", "); + } + if (!(i%8)) Serial.println(""); + } + Serial.println(""); // Newline +} + +//+============================================================================= +// Dump out the decode_results structure. +// +void dumpCode (decode_results *results) +{ + // Start declaration + Serial.print("unsigned int "); // variable type + Serial.print("rawData["); // array name + Serial.print(results->rawlen + 1, DEC); // array size + Serial.print("] = {"); // Start declaration + + // Dump data + for (int i = 0; i < results->rawlen; i++) { + Serial.print(results->rawbuf[i], DEC); + Serial.print(","); + if (!(i&1)) Serial.print(" "); + } + + // End declaration + Serial.print("0};"); // Turn LED off at the end + + // Comment + Serial.print(" // "); + encoding(results); + Serial.print(" "); + ircode(results); + + // Newline + Serial.println(""); +} + +//+============================================================================= +// The repeating section of the code +// +void loop ( ) +{ + decode_results results; // Somewhere to store the results + + if (irrecv.decode(&results)) { // Grab an IR code + dumpInfo(&results); // Output the results + dumpRaw(&results); // Output the results in RAW format + dumpCode(&results); // Output the results as source code + Serial.println(""); // Blank line between entries + irrecv.resume(); // Prepare for the next value + } +} + From 593e0a3ee3c5c2e2b7c17be590b794f4002f8dd2 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sat, 20 Jun 2015 22:08:13 +0100 Subject: [PATCH 070/768] Improve documentation and fixup IRrecvDumpV2.ino --- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 23 +++++++++++------------ ir_Template.cpp | 7 +++++++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index c6f070c45..c9b7ff495 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -1,8 +1,7 @@ //------------------------------------------------------------------------------ -// Include the IRremote library headers +// Include the IRremote library header // #include -#include //------------------------------------------------------------------------------ // Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838) @@ -28,7 +27,7 @@ void ircode (decode_results *results) Serial.print(results->address, HEX); Serial.print(":"); } - + // Print Code Serial.print(results->value, HEX); } @@ -68,12 +67,12 @@ void dumpInfo (decode_results *results) Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWLEN"); return; } - + // Show Encoding standard Serial.print("Encoding : "); encoding(results); Serial.println(""); - + // Show Code & length Serial.print("Code : "); ircode(results); @@ -123,25 +122,25 @@ void dumpCode (decode_results *results) Serial.print("rawData["); // array name Serial.print(results->rawlen + 1, DEC); // array size Serial.print("] = {"); // Start declaration - + // Dump data for (int i = 0; i < results->rawlen; i++) { Serial.print(results->rawbuf[i], DEC); Serial.print(","); if (!(i&1)) Serial.print(" "); } - + // End declaration Serial.print("0};"); // Turn LED off at the end - + // Comment - Serial.print(" // "); + Serial.print(" // "); encoding(results); Serial.print(" "); ircode(results); - + // Newline - Serial.println(""); + Serial.println(""); } //+============================================================================= @@ -159,4 +158,4 @@ void loop ( ) irrecv.resume(); // Prepare for the next value } } - + diff --git a/ir_Template.cpp b/ir_Template.cpp index 9aa33ae93..c0f960662 100644 --- a/ir_Template.cpp +++ b/ir_Template.cpp @@ -66,6 +66,13 @@ Now you must do a few things to add it to the IRremote system: B. Save your changes and close the file +You will probably want to add your new protocol to the example sketch + +3. Open MyDocuments\Arduino\libraries\IRremote\examples\IRrecvDumpV2.ino + + A. In the encoding() function, add: + case SHUZU: Serial.print("SHUZU"); break ; + Now open the Arduino IDE, load up the rawDump.ino sketch, and run it. Hopefully it will compile and upload. If it doesn't, you've done something wrong. Check your work. From 78e9b87a3425815552e73c29133ce5296196d1cd Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sun, 21 Jun 2015 01:20:44 +0100 Subject: [PATCH 071/768] Add Denon support Improve comments Fixup DECODE_AIWA_RC_T50 Simplify template --- IRremote.h | 12 ++++ examples/IRrecvDumpV2/IRrecvDumpV2.ino | 1 + irRecv.cpp | 17 ++++- ir_Denon.cpp | 86 ++++++++++++++++++++++++++ ir_Template.cpp | 44 ++++++------- 5 files changed, 135 insertions(+), 25 deletions(-) create mode 100644 ir_Denon.cpp diff --git a/IRremote.h b/IRremote.h index 47a0e06b5..cb8d95835 100644 --- a/IRremote.h +++ b/IRremote.h @@ -70,6 +70,9 @@ #define DECODE_SHARP 0 // NOT WRITTEN #define SEND_SHARP 1 +#define DECODE_DENON 1 +#define SEND_DENON 1 + //------------------------------------------------------------------------------ // An enumerated list of all supported formats // You do NOT need to remove entries from this list when disabling protocols! @@ -92,6 +95,7 @@ typedef MITSUBISHI, DISH, SHARP, + DENON, } decode_type_t; @@ -213,6 +217,10 @@ class IRrecv //...................................................................... # if DECODE_SHARP bool decodeSharp (decode_results *results) ; // NOT WRITTEN +# endif + //...................................................................... +# if DECODE_DENON + bool decodeDenon (decode_results *results) ; # endif } ; @@ -288,6 +296,10 @@ class IRsend # if SEND_SHARP void sendSharpRaw (unsigned long data, int nbits) ; void sendSharp (unsigned int address, unsigned int command) ; +# endif + //...................................................................... +# if SEND_DENON + void sendDenon (unsigned long data, int nbits) ; # endif } ; diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index c9b7ff495..a610bff17 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -54,6 +54,7 @@ void encoding (decode_results *results) case WHYNTER: Serial.print("WHYNTER"); break ; case AIWA_RC_T501: Serial.print("AIWA_RC_T501"); break ; case PANASONIC: Serial.print("PANASONIC"); break ; + case DENON: Serial.print("Denon"); break ; } } diff --git a/irRecv.cpp b/irRecv.cpp index 8bcb0bf0d..d3a7060c8 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -45,6 +45,8 @@ void IRrecv::blink13 (int blinkflag) } //+============================================================================= +// Restart the ISR state machine +// void IRrecv::resume ( ) { irparams.rcvstate = STATE_IDLE; @@ -55,6 +57,7 @@ void IRrecv::resume ( ) // 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; @@ -119,15 +122,21 @@ int IRrecv::decode (decode_results *results) if (decodeWhynter(results)) return true ; #endif -#ifdef AIWA_RC_T501 +#ifdef DECODE_AIWA_RC_T501 DBG_PRINTLN("Attempting Aiwa RC-T501 decode"); if (decodeAiwaRCT501(results)) return true ; #endif +#ifdef DECODE_DENON + DBG_PRINTLN("Attempting Denon decode"); + if (decodeDenon(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; @@ -140,7 +149,7 @@ int IRrecv::decode (decode_results *results) // // 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, +// Do the same with the SPACE signals. Hash 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. // @@ -168,9 +177,11 @@ int IRrecv::compare (unsigned int oldval, unsigned int newval) long IRrecv::decodeHash (decode_results *results) { + long hash = FNV_BASIS_32; + // 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 diff --git a/ir_Denon.cpp b/ir_Denon.cpp new file mode 100644 index 000000000..4ce6862f1 --- /dev/null +++ b/ir_Denon.cpp @@ -0,0 +1,86 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +// Reverse Engineerd by looking at RAW dumps generated by IRremote + +//============================================================================== +// DDDD EEEEE N N OOO N N +// D D E NN N O O NN N +// D D EEE N N N O O N N N +// D D E N NN O O N NN +// DDDD EEEEE N N OOO N N +//============================================================================== + +#define BITS 14 // The number of bits in the command + +#define HDR_MARK 300 // The length of the Header:Mark +#define HDR_SPACE 750 // The lenght of the Header:Space + +#define BIT_MARK 300 // The length of a Bit:Mark +#define ONE_SPACE 1800 // The length of a Bit:Space for 1's +#define ZERO_SPACE 750 // The length of a Bit:Space for 0's + +//+============================================================================= +// +#if SEND_DENON +void IRsend::sendDenon (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(38); + + // Header + mark (HDR_MARK); + space(HDR_SPACE); + + // Data + for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark (BIT_MARK); + space(ONE_SPACE); + } else { + mark (BIT_MARK); + space(ZERO_SPACE); + } + } + + // Footer + mark(BIT_MARK); + space(0); // Always end with the LED off +} +#endif + +//+============================================================================= +// +#if DECODE_DENON +bool IRrecv::decodeDenon (decode_results *results) +{ + unsigned long data = 0; // Somewhere to build our code + int offset = 1; // Skip the Gap reading + + // Check we have the right amount of data + if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1) return false ; + + // Check initial Mark+Space match + if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE)) return false ; + + // Read the bits in + for (int i = 0; i < BITS; i++) { + // Each bit looks like: MARK + SPACE_1 -> 1 + // or : MARK + SPACE_0 -> 0 + if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK)) return false ; + + // IR data is big-endian, so we shuffle it in from the right: + if (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE)) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // Success + results->bits = BITS; + results->value = data; + results->decode_type = DENON; + return true; +} +#endif diff --git a/ir_Template.cpp b/ir_Template.cpp index c0f960662..474d77763 100644 --- a/ir_Template.cpp +++ b/ir_Template.cpp @@ -102,16 +102,16 @@ Regards, // //============================================================================== -#define SHUZU_BITS 32 // The number of bits in the command +#define BITS 32 // The number of bits in the command -#define SHUZU_HDR_MARK 1000 // The length of the Header:Mark -#define SHUZU_HDR_SPACE 2000 // The lenght of the Header:Space +#define HDR_MARK 1000 // The length of the Header:Mark +#define HDR_SPACE 2000 // The lenght of the Header:Space -#define SHUZU_BIT_MARK 3000 // The length of a Bit:Mark -#define SHUZU_ONE_SPACE 4000 // The length of a Bit:Space for 1's -#define SHUZU_ZERO_SPACE 5000 // The length of a Bit:Space for 0's +#define BIT_MARK 3000 // The length of a Bit:Mark +#define ONE_SPACE 4000 // The length of a Bit:Space for 1's +#define ZERO_SPACE 5000 // The length of a Bit:Space for 0's -#define SHUZU_OTHER 1234 // Other things you may need to define +#define OTHER 1234 // Other things you may need to define //+============================================================================= // @@ -122,22 +122,22 @@ void IRsend::sendShuzu (unsigned long data, int nbits) enableIROut(38); // Header - mark (SHUZU_HDR_MARK); - space(SHUZU_HDR_SPACE); + mark (HDR_MARK); + space(HDR_SPACE); // Data for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { if (data & mask) { - mark (SHUZU_BIT_MARK); - space(SHUZU_ONE_SPACE); + mark (BIT_MARK); + space(ONE_SPACE); } else { - mark (SHUZU_BIT_MARK); - space(SHUZU_ZERO_SPACE); + mark (BIT_MARK); + space(ZERO_SPACE); } } // Footer - mark(SHUZU_BIT_MARK); + mark(BIT_MARK); space(0); // Always end with the LED off } #endif @@ -151,27 +151,27 @@ bool IRrecv::decodeShuzu (decode_results *results) int offset = 1; // Skip the Gap reading // Check we have the right amount of data - if (irparams.rawlen != 1 + 2 + (2 * SHUZU_BITS) + 1) return false ; + if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1) return false ; // Check initial Mark+Space match - if (!MATCH_MARK (results->rawbuf[offset++], SHUZU_HDR_MARK )) return false ; - if (!MATCH_SPACE(results->rawbuf[offset++], SHUZU_HDR_SPACE)) return false ; + if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE)) return false ; // Read the bits in for (int i = 0; i < SHUZU_BITS; i++) { // Each bit looks like: MARK + SPACE_1 -> 1 // or : MARK + SPACE_0 -> 0 - if (!MATCH_MARK(results->rawbuf[offset++], SAMSUNG_BIT_MARK)) return false ; + if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK)) return false ; // IR data is big-endian, so we shuffle it in from the right: - if (MATCH_SPACE(results->rawbuf[offset], SHUZU_ONE_SPACE)) data = (data << 1) | 1 ; - else if (MATCH_SPACE(results->rawbuf[offset], SHUZU_ZERO_SPACE)) data = (data << 1) | 0 ; - else return false ; + if (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE)) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; offset++; } // Success - results->bits = SHUZU_BITS; + results->bits = BITS; results->value = data; results->decode_type = SHUZU; return true; From 6a1222d180afb9386b917c111f3a816388ddfb43 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sun, 21 Jun 2015 03:11:24 +0100 Subject: [PATCH 072/768] Started work on supporting Pronto Codes --- irPronto.cpp | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 irPronto.cpp diff --git a/irPronto.cpp b/irPronto.cpp new file mode 100644 index 000000000..dacb66ceb --- /dev/null +++ b/irPronto.cpp @@ -0,0 +1,171 @@ +#if 0 +/* +http://www.remotecentral.com/features/irdisp2.htm + +http://www.hifi-remote.com/wiki/index.php?title=Working_With_Pronto_Hex + +The first 4 digits of the Pronto code indicate the form it is stored in. + 0000 - raw oscillated code + 0100 - raw unmodulated code + +*/ + +char code[] = +"0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 +"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 +"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 +"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 +"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 +"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 +"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 +"0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 +"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 +"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 +"0010 0030 0010 0aa6" // 104 + +#define DEBUGF(...) printf(__VA_ARGS__) + +//+============================================================================= +// Check for a valid hex digit +// +bool ishex (char ch) +{ + return ( ((ch >= '0') && (ch <= '9')) || + ((ch >= 'A') && (ch <= 'F')) || + ((ch >= 'a') && (ch <= 'f')) ) ? true : false ; +} + +//+============================================================================= +// Check for a valid "blank" ... '\0' is a valid "blank" +// +bool isblank (char ch) +{ + return ((ch == ' ') || (ch == '\t') || (ch == '\0')) ? true : false ; +} + +//+============================================================================= +// Bypass spaces +// +bool byp (char** pcp) +{ + while (isblank(**pcp)) *pcp++ ; +} + +//+============================================================================= +// String must be block of 4 hex digits separated with blanks +// +bool validate (char* cp, int* len) +{ + for (*len = 0; *cp; *len++, cp += 4) + byp(*cp); + if ( !ishex(cp[0]) || !ishex(cp[1]) || + !ishex(cp[2]) || !ishex(cp[3]) || !isspace(cp[4]) ) return false ; + } + + return true; +} + +//+============================================================================= +// Hex-to-Byte : Decode a hex digit +// We assume the character has already been validated +// +uint8_t htob (char cp) +{ + if ((ch >= '0') && (ch <= '9')) return ch - '0' ; + if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' ; + if ((ch >= 'a') && (ch <= 'f')) return ch - 'f' ; +} + +//+============================================================================= +// Hex-to-Word : Decode a block of 4 hex digits +// We assume the string has already been validated +// and the pointer being passed points at the start of a block of 4 hex digits +// +uint16_t htow (char* cp) +{ + return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | + (htob(cp[2]) << 4) | (htob(cp[3]) ) ) +} + +//+============================================================================= +// +typedef + struct { + int len; + uint16_t* code; + + int freq; + int usec; + + int onceLen; + int onceSt; + + int rptLen; + int rptSt; + } +pronto_t; + +bool decodePronto (char* s, pronto_t* p) +{ + int i; + char* cp; + + // Validate the Pronto string + if (!validate(s, &p->len)) { + DEBUGF("Invalid pronto string\n"); + return false ; + } + DEBUGF("Found %d hex codes\n", p->len); + + // Allocate memory to store the decoded string + if (!(p->code = malloc(p->len))) { + DEBUGF("Memory allocation failed\n"); + return false ; + } + + // Decode the string + cp = s; + for (i = 0; i < p->len; i++) { + byp(*cp); + p->code[i] = htow(cp); + } + + // Annound our findings + DEBUGF("Input: |%s|", s); + DEBUGF("Found: |"); + for (i = 0; i < p->len; i++) DEBUGF("%04x ", p->code[i]) ; + DEBUGF("|\n"); + + DEBUGF("Form : "); + if (p->code[0] = 0x0000) DEBUGF("Oscillated (Learned)\n"); + else if (p->code[0] = 0x0100) DEBUGF("Unmodulated\n"); + else DEBUGF("Unknown\n"); + if (p->code[0] != 0x0000) return false ; // Can only handle Oscillated + + // Calculate the carrier frequency (+/i 10%) & uSecs per pulse + // Pronto uses a crystal which generates a timeabse of 0.241246 + p->freq = 1000000 / (p->code[1] * 0.241246); + p->usec = (int)(((1.0 / p->freq) * 1000000) + 0.5); + DEBUGF("Freq : %d (%suS/pluse)\n", freq, usec); + + // Get the start+length of the "once" code + p->onceSt = 4; + p->onceLen = p->code[2]; + DEBUGF("Once : %d\n", p->onceLen); + + // Get the start+length of the "repeat" code + p->rptLen = code[3]; + p->rptSt = 4 + p->onceLen; + DEBUGF("Rpt : %d\n", p->rptLen); + + // Check everything tallies + if (1 + 1 + 1 + 1 + p->onceLen + p->rptLen != p->len) { + DEBUGF("Bad code length\n"); + return false; + } + + return true; +} + + +#endif //0 \ No newline at end of file From 3dec9973919d5a55bb15c20763d80ac7db9d129a Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sun, 21 Jun 2015 18:13:21 +0100 Subject: [PATCH 073/768] Added sendPronto() --- IRremote.h | 25 ++- IRremoteInt.h | 4 +- irPronto.cpp | 490 ++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 439 insertions(+), 80 deletions(-) diff --git a/IRremote.h b/IRremote.h index cb8d95835..3a64fedfd 100644 --- a/IRremote.h +++ b/IRremote.h @@ -3,7 +3,7 @@ // IRremote // Version 0.1 July, 2009 // Copyright 2009 Ken Shirriff -// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm http://arcfn.com +// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html // Edited by Mitra to add new controller SANYO // // Interrupt code based on NECIRrcv by Joe Knapp @@ -73,6 +73,24 @@ #define DECODE_DENON 1 #define SEND_DENON 1 +#define DECODE_PRONTO 0 // This function doe not logically make sense +#define SEND_PRONTO 1 + +//------------------------------------------------------------------------------ +// When sending a Pronto code we request to send either the "once" code +// or the "repeat" code +// If the code requested does not exist we can request to fallback on the +// other code (the one we did not explicitly request) +// +// I would suggest that "fallback" will be the standard calling method +// The last paragraph on this page discusses the rationale of this idea: +// http://www.remotecentral.com/features/irdisp2.htm +// +#define PRONTO_ONCE false +#define PRONTO_REPEAT true +#define PRONTO_FALLBACK true +#define PRONTO_NOFALLBACK false + //------------------------------------------------------------------------------ // An enumerated list of all supported formats // You do NOT need to remove entries from this list when disabling protocols! @@ -96,6 +114,7 @@ typedef DISH, SHARP, DENON, + PRONTO, } decode_type_t; @@ -300,6 +319,10 @@ class IRsend //...................................................................... # if SEND_DENON void sendDenon (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_Pronto + void sendPronto (char* code, bool repeat, bool fallback) ; # endif } ; diff --git a/IRremoteInt.h b/IRremoteInt.h index 486e0cf8a..83d0dffae 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -23,7 +23,9 @@ #if defined(ARDUINO) && (ARDUINO >= 100) # include #else -# include +# if !defined(IRPRONTO) +# include +# endif #endif //------------------------------------------------------------------------------ diff --git a/irPronto.cpp b/irPronto.cpp index dacb66ceb..2411038d4 100644 --- a/irPronto.cpp +++ b/irPronto.cpp @@ -1,29 +1,16 @@ -#if 0 -/* -http://www.remotecentral.com/features/irdisp2.htm - -http://www.hifi-remote.com/wiki/index.php?title=Working_With_Pronto_Hex - -The first 4 digits of the Pronto code indicate the form it is stored in. - 0000 - raw oscillated code - 0100 - raw unmodulated code - -*/ - -char code[] = -"0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 -"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 -"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 -"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 -"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 -"0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 -"0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 -"0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 -"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 -"0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 -"0010 0030 0010 0aa6" // 104 +#if SEND_PRONTO -#define DEBUGF(...) printf(__VA_ARGS__) +#define TEST 0 + +//****************************************************************************** +#if TEST +# include + void enableIROut (int freq) { printf("\nFreq = %d KHz\n", freq); } + void mark (int t) { printf("+%d," , t); } + void space (int t) { printf("-%d, ", t); } +#else +# include "IRremote.h" +#endif // TEST //+============================================================================= // Check for a valid hex digit @@ -48,18 +35,316 @@ bool isblank (char ch) // bool byp (char** pcp) { - while (isblank(**pcp)) *pcp++ ; + while (isblank(**pcp)) (*pcp)++ ; +} + +//+============================================================================= +// Hex-to-Byte : Decode a hex digit +// We assume the character has already been validated +// +uint8_t htob (char ch) +{ + if ((ch >= '0') && (ch <= '9')) return ch - '0' ; + if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ; + if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ; +} + +//+============================================================================= +// Hex-to-Word : Decode a block of 4 hex digits +// We assume the string has already been validated +// and the pointer being passed points at the start of a block of 4 hex digits +// +uint16_t htow (char* cp) +{ + return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | + (htob(cp[2]) << 4) | (htob(cp[3]) ) ) ; +} + +//+============================================================================= +// +bool sendPronto (char* s, bool repeat, bool fallback) +{ + int i; + int len; + int skip; + char* cp; + uint8_t freq; // Frequency in KHz + uint8_t usec; // pronto uSec/tick + uint8_t once; + uint8_t rpt; + + // Validate the string + for (cp = s; *cp; cp += 4) { + byp(&cp); + if ( !ishex(cp[0]) || !ishex(cp[1]) || + !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ; + } + + // We will use cp to traverse the string + cp = s; + + // Check mode = Oscillated/Learned + byp(&cp); + if (htow(cp) != 0000) return false; + cp += 4; + + // Extract & set frequency + byp(&cp); + freq = (int)((1000000 / (htow(cp) * 0.241246)) / 1000); + usec = (int)(((1.0 / freq) * 1000000) + 0.5); + cp += 4; + + // Get length of "once" code + byp(&cp); + once = htow(cp); + cp += 4; + + // Get length of "repeat" code + byp(&cp); + rpt = htow(cp); + cp += 4; + + // Which code are we sending? + if (fallback) { + if (!repeat) { // requested 'once' + if (once) len = once * 2, skip = 0 ; // if once exists send it + else len = rpt * 2, skip = 0 ; // else send repeat code + } else { // requested 'repeat' + if (rpt) len = rpt * 2, skip = 0 ; // if rpt exists send it + else len = once * 2, skip = 0 ; // else send once code + } + } else { // Send what we asked for, do not fallback if the code is empty! + if (!repeat) len = once * 2, skip = 0 ; // 'once' starts at 0 + else len = rpt * 2, skip = once ; // 'repeat' starts where 'once' ends + } + + // Skip to start of code + for (i = 0; i < skip; i++, cp += 4) byp(&cp) ; + + // Send code + enableIROut(freq); + + for (i = 0; i < len; i++) { + byp(&cp); + if (i & 1) space(htow(cp) * usec); + else mark (htow(cp) * usec); + cp += 4; + } } +//+============================================================================= +#if TEST + +int main ( ) +{ + char prontoTest[] = + "0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 + "0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 + "0010 0030 0010 0aa6"; // 104 + + sendPronto(prontoTest, PRONTO_ONCE, PRONTO_FALLBACK); // once code + sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_FALLBACK); // repeat code + sendPronto(prontoTest, PRONTO_ONCE, PRONTO_NOFALLBACK); // once code + sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_NOFALLBACK); // repeat code + + return 0; +} + +#endif // TEST + +#endif SEND_PRONTO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#if 0 +//****************************************************************************** +// Sources: +// http://www.remotecentral.com/features/irdisp2.htm +// http://www.hifi-remote.com/wiki/index.php?title=Working_With_Pronto_Hex +//****************************************************************************** + +#include +#include + +#define IRPRONTO +#include "IRremoteInt.h" // The Arduino IRremote library defines USECPERTICK + +//------------------------------------------------------------------------------ +// Source: https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet +// -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls +// +char prontoTest[] = + "0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 + "0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 + "0010 0030 0010 0aa6"; // 104 + +//------------------------------------------------------------------------------ +// This is the longest code we can support +#define CODEMAX 200 + +//------------------------------------------------------------------------------ +// This is the data we pull out of the pronto code +typedef + struct { + int freq; // Carrier frequency (in Hz) + int usec; // uSec per tick (based on freq) + + int codeLen; // Length of code + uint16_t code[CODEMAX]; // Code in hex + + int onceLen; // Length of "once" transmit + uint16_t* once; // Pointer to start within 'code' + + int rptLen; // Length of "repeat" transmit + uint16_t* rpt; // Pointer to start within 'code' + } +pronto_t; + +//------------------------------------------------------------------------------ +// From what I have seen, the only time we go over 8-bits is the 'space' +// on the end which creates the lead-out/inter-code gap. Assuming I'm right, +// we can code this up as a special case and otherwise halve the size of our +// data! +// Ignoring the first four values (the config data) and the last value +// (the lead-out), if you find a protocol that uses values greater than 00fe +// we are going to have to revisit this code! +// +// +// So, the 0th byte will be the carrier frequency in Khz (NOT Hz) +// " 1st " " " " length of the "once" code +// " 2nd " " " " length of the "repeat" code +// +// Thereafter, odd bytes will be Mark lengths as a multiple of USECPERTICK uS +// even " " " Space " " " " " " " +// +// Any occurence of "FF" in either a Mark or a Space will indicate +// "Use the 16-bit FF value" which will also be a multiple of USECPERTICK uS +// +// +// As a point of comparison, the test code (prontoTest[]) is 520 bytes +// (yes, more than 0.5KB of our Arduino's precious 32KB) ... after conversion +// to pronto hex that goes down to ((520/5)*2) = 208 bytes ... once converted to +// our format we are down to ((208/2) -1 -1 +2) = 104 bytes +// +// In fariness this is still very memory-hungry +// ...As a rough guide: +// 10 codes cost 1K of memory (this will vary depending on the protocol). +// +// So if you're building a complex remote control, you will probably need to +// keep the codes on an external memory device (not in the Arduino sketch) and +// load them as you need them. Hmmm. +// +// This dictates that "Oscillated Pronto Codes" are probably NOT the way forward +// +// For example, prontoTest[] happens to be: A 48-bit IR code in Denon format +// So we know it starts with 80/40 (Denon header) +// and ends with 10/aa6 (Denon leadout) +// and all (48) bits in between are either 10/10 (Denon 0) +// or 10/30 (Denon 1) +// So we could easily store this data in 1-byte ("Denon") +// + 1-byte (Length=48) +// + 6-bytes (IR code) +// At 8-bytes per code, we can store 128 codes in 1KB or memory - that's a lot +// better than the 2 (two) we started off with! +// +// And serendipitously, by reducing the amount of data, our program will run +// a LOT faster! +// +// Again, I repeat, even after you have spent time converting the "Oscillated +// Pronto Codes" in to IRremote format, it will be a LOT more memory-hungry +// than using sendDenon() (or whichever) ...BUT these codes are easily +// available on the internet, so we'll support them! +// +typedef + struct { + uint16_t FF; + uint8_t code[CODEMAX]; + } +irCode_t; + +//------------------------------------------------------------------------------ +#define DEBUGF(...) printf(__VA_ARGS__) + //+============================================================================= // String must be block of 4 hex digits separated with blanks // bool validate (char* cp, int* len) { - for (*len = 0; *cp; *len++, cp += 4) - byp(*cp); + for (*len = 0; *cp; (*len)++, cp += 4) { + byp(&cp); if ( !ishex(cp[0]) || !ishex(cp[1]) || - !ishex(cp[2]) || !ishex(cp[3]) || !isspace(cp[4]) ) return false ; + !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ; } return true; @@ -69,11 +354,11 @@ bool validate (char* cp, int* len) // Hex-to-Byte : Decode a hex digit // We assume the character has already been validated // -uint8_t htob (char cp) +uint8_t htob (char ch) { if ((ch >= '0') && (ch <= '9')) return ch - '0' ; - if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' ; - if ((ch >= 'a') && (ch <= 'f')) return ch - 'f' ; + if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ; + if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ; } //+============================================================================= @@ -84,88 +369,137 @@ uint8_t htob (char cp) uint16_t htow (char* cp) { return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | - (htob(cp[2]) << 4) | (htob(cp[3]) ) ) + (htob(cp[2]) << 4) | (htob(cp[3]) ) ) ; } //+============================================================================= +// Convert the pronto string in to data // -typedef - struct { - int len; - uint16_t* code; - - int freq; - int usec; - - int onceLen; - int onceSt; - - int rptLen; - int rptSt; - } -pronto_t; - -bool decodePronto (char* s, pronto_t* p) +bool decode (char* s, pronto_t* p, irCode_t* ir) { - int i; + int i, len; char* cp; // Validate the Pronto string - if (!validate(s, &p->len)) { + if (!validate(s, &p->codeLen)) { DEBUGF("Invalid pronto string\n"); return false ; } - DEBUGF("Found %d hex codes\n", p->len); + DEBUGF("Found %d hex codes\n", p->codeLen); // Allocate memory to store the decoded string - if (!(p->code = malloc(p->len))) { - DEBUGF("Memory allocation failed\n"); + //if (!(p->code = malloc(p->len))) { + // DEBUGF("Memory allocation failed\n"); + // return false ; + //} + + // Check in case our code is too long + if (p->codeLen > CODEMAX) { + DEBUGF("Code too long, edit CODEMAX and recompile\n"); return false ; } // Decode the string cp = s; - for (i = 0; i < p->len; i++) { - byp(*cp); + for (i = 0; i < p->codeLen; i++, cp += 4) { + byp(&cp); p->code[i] = htow(cp); } - // Annound our findings - DEBUGF("Input: |%s|", s); + // Announce our findings + DEBUGF("Input: |%s|\n", s); DEBUGF("Found: |"); - for (i = 0; i < p->len; i++) DEBUGF("%04x ", p->code[i]) ; + for (i = 0; i < p->codeLen; i++) DEBUGF("%04x ", p->code[i]) ; DEBUGF("|\n"); - DEBUGF("Form : "); - if (p->code[0] = 0x0000) DEBUGF("Oscillated (Learned)\n"); - else if (p->code[0] = 0x0100) DEBUGF("Unmodulated\n"); - else DEBUGF("Unknown\n"); + DEBUGF("Form [%04X] : ", p->code[0]); + if (p->code[0] == 0x0000) DEBUGF("Oscillated (Learned)\n"); + else if (p->code[0] == 0x0100) DEBUGF("Unmodulated\n"); + else DEBUGF("Unknown\n"); if (p->code[0] != 0x0000) return false ; // Can only handle Oscillated - // Calculate the carrier frequency (+/i 10%) & uSecs per pulse + // Calculate the carrier frequency (+/- 10%) & uSecs per pulse // Pronto uses a crystal which generates a timeabse of 0.241246 - p->freq = 1000000 / (p->code[1] * 0.241246); - p->usec = (int)(((1.0 / p->freq) * 1000000) + 0.5); - DEBUGF("Freq : %d (%suS/pluse)\n", freq, usec); + p->freq = (int)(1000000 / (p->code[1] * 0.241246)); + p->usec = (int)(((1.0 / p->freq) * 1000000) + 0.5); + ir->code[0] = p->freq / 1000; + DEBUGF("Freq [%04X] : %d Hz (%d uS/pluse) -> %d KHz\n", + p->code[1], p->freq, p->usec, ir->code[0]); - // Get the start+length of the "once" code - p->onceSt = 4; - p->onceLen = p->code[2]; - DEBUGF("Once : %d\n", p->onceLen); + // Set the length & start pointer for the "once" code + p->onceLen = p->code[2]; + p->once = &p->code[4]; + ir->code[1] = p->onceLen; + DEBUGF("Once [%04X] : %d\n", p->code[2], p->onceLen); - // Get the start+length of the "repeat" code - p->rptLen = code[3]; - p->rptSt = 4 + p->onceLen; - DEBUGF("Rpt : %d\n", p->rptLen); + // Set the length & start pointer for the "repeat" code + p->rptLen = p->code[3]; + p->rpt = &p->code[4 + p->onceLen]; + ir->code[2] = p->rptLen; + DEBUGF("Rpt [%04X] : %d\n", p->code[3], p->rptLen); // Check everything tallies - if (1 + 1 + 1 + 1 + p->onceLen + p->rptLen != p->len) { + if (1 + 1 + 1 + 1 + (p->onceLen * 2) + (p->rptLen * 2) != p->codeLen) { DEBUGF("Bad code length\n"); return false; } + // Convert the IR data to our new format + ir->FF = p->code[p->codeLen - 1]; + + len = (p->onceLen * 2) + (p->rptLen * 2); + DEBUGF("Encoded: |"); + for (i = 0; i < len; i++) { + if (p->code[i+4] == ir->FF) { + ir->code[i+3] = 0xFF; + } else if (p->code[i+4] > 0xFE) { + DEBUGF("\n%04X : Mark/Space overflow\n", p->code[i+4]); + return false; + } else { + ir->code[i+3] = (p->code[i+4] * p->usec) / USECPERTICK; + } + DEBUGF("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]); + } + DEBUGF("|\n"); + + ir->FF = (ir->FF * p->usec) / USECPERTICK; + DEBUGF("FF -> %d\n", ir->FF); + return true; } +//+============================================================================= +// +void irDump (irCode_t* ir) +{ + int i, len; + + printf("uint8_t buttonName[%d] = {", len); + + printf("%d,%d, ", (ir->FF >> 8), ir->FF & 0xFF); + printf("%d,%d,%d, ", ir->code[0], ir->code[1], ir->code[2]); + + len = (ir->code[1] * 2) + (ir->code[2] * 2); + for (i = 0; i < len; i++) { + printf("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]); + } + + printf("};\n"); + +} + +//+============================================================================= +// +int main ( ) +{ + pronto_t pCode; + irCode_t irCode; + + decode(prontoTest, &pCode, &irCode); + + irDump(&irCode); + + return 0; +} -#endif //0 \ No newline at end of file +#endif //0 From 2e163ae3f453aadd1c5e12b960b0e4478e5209c0 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sun, 21 Jun 2015 18:33:47 +0100 Subject: [PATCH 074/768] Additional comments in Denon code --- ir_Denon.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ir_Denon.cpp b/ir_Denon.cpp index 4ce6862f1..7c9b07545 100644 --- a/ir_Denon.cpp +++ b/ir_Denon.cpp @@ -1,7 +1,15 @@ #include "IRremote.h" #include "IRremoteInt.h" -// Reverse Engineerd by looking at RAW dumps generated by IRremote +// Reverse Engineered by looking at RAW dumps generated by IRremote + +// I have since discovered that Denon publish all their IR codes: +// https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet +// -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls + +// Having looked at the official Denon Pronto sheet and reverse engineered +// the timing values from it, it is obvious that Denon have a range of +// different timings and protocols ...the values here work for my AVR-3801 Amp! //============================================================================== // DDDD EEEEE N N OOO N N From 845e912e9f291dbbdfbafe0dba63154bdae931df Mon Sep 17 00:00:00 2001 From: Bluechip Date: Sun, 21 Jun 2015 18:34:40 +0100 Subject: [PATCH 075/768] Fixup test harness & frequency calculator in Pronto code --- irPronto.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/irPronto.cpp b/irPronto.cpp index 2411038d4..0f530a900 100644 --- a/irPronto.cpp +++ b/irPronto.cpp @@ -1,7 +1,15 @@ -#if SEND_PRONTO - #define TEST 0 +#if TEST +# define SEND_PRONTO 1 +# define PRONTO_ONCE false +# define PRONTO_REPEAT true +# define PRONTO_FALLBACK true +# define PRONTO_NOFALLBACK false +#endif + +#if SEND_PRONTO + //****************************************************************************** #if TEST # include @@ -68,7 +76,7 @@ bool sendPronto (char* s, bool repeat, bool fallback) int len; int skip; char* cp; - uint8_t freq; // Frequency in KHz + uint16_t freq; // Frequency in KHz uint8_t usec; // pronto uSec/tick uint8_t once; uint8_t rpt; @@ -90,8 +98,9 @@ bool sendPronto (char* s, bool repeat, bool fallback) // Extract & set frequency byp(&cp); - freq = (int)((1000000 / (htow(cp) * 0.241246)) / 1000); - usec = (int)(((1.0 / freq) * 1000000) + 0.5); + freq = (int)(1000000 / (htow(cp) * 0.241246)); // Rounding errors will occur, tolerance is +/- 10% + usec = (int)(((1.0 / freq) * 1000000) + 0.5); // Another rounding error, thank Cod for analogue electronics + freq /= 1000; // This will introduce a(nother) rounding error which we do not want in the usec calcualtion cp += 4; // Get length of "once" code @@ -105,7 +114,7 @@ bool sendPronto (char* s, bool repeat, bool fallback) cp += 4; // Which code are we sending? - if (fallback) { + if (fallback) { // fallback on the "other" code if "this" code is not present if (!repeat) { // requested 'once' if (once) len = once * 2, skip = 0 ; // if once exists send it else len = rpt * 2, skip = 0 ; // else send repeat code @@ -123,7 +132,6 @@ bool sendPronto (char* s, bool repeat, bool fallback) // Send code enableIROut(freq); - for (i = 0; i < len; i++) { byp(&cp); if (i & 1) space(htow(cp) * usec); @@ -160,7 +168,7 @@ int main ( ) #endif // TEST -#endif SEND_PRONTO +#endif // SEND_PRONTO From 4e5608f25f03f069847281feb1b3cf25e4ddb87b Mon Sep 17 00:00:00 2001 From: Bluechip Date: Mon, 22 Jun 2015 21:23:53 +0100 Subject: [PATCH 076/768] https://github.com/shirriff/Arduino-IRremote/issues/156 Improve output for recvDumpV2 Added my name to the contributors list (not 'cos I really care for the credit but so people know who to "blame" [non-pejorative]) Moved the decode() function to the top of the source as it is likely to be edited the most --- Contributors.md | 1 + examples/IRrecvDumpV2/IRrecvDumpV2.ino | 16 ++++ irRecv.cpp | 104 ++++++++++++------------- irSend.cpp | 2 +- 4 files changed, 70 insertions(+), 53 deletions(-) diff --git a/Contributors.md b/Contributors.md index 2bb8d9db9..4a9b88da3 100644 --- a/Contributors.md +++ b/Contributors.md @@ -11,6 +11,7 @@ These are the active contributors of this project that you may contact if there - [crash7](https://github.com/crash7) : Active contributor - [Neco777](https://github.com/neco777) : Active contributor - [Lauszus](https://github.com/lauszus) : Active contributor +- [csBlueChip](https://github.com/csbluechip) : Active contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index a610bff17..a2add9fff 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -142,6 +142,22 @@ void dumpCode (decode_results *results) // Newline Serial.println(""); + + // Now dump "known" codes + if (results->decode_type != UNKNOWN) { + + // Some protocols have an address + if (results->decode_type == PANASONIC) { + Serial.print("unsigned int addr = 0x"); + Serial.print(results->address, HEX); + Serial.println(";"); + } + + // All protocols have data + Serial.print("unsigned int data = 0x"); + Serial.print(results->value, HEX); + Serial.println(";"); + } } //+============================================================================= diff --git a/irRecv.cpp b/irRecv.cpp index d3a7060c8..461402090 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -1,58 +1,6 @@ #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) ; -} - -//+============================================================================= -// Restart the ISR state machine -// -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. @@ -142,6 +90,58 @@ int IRrecv::decode (decode_results *results) return false; } +//+============================================================================= +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) ; +} + +//+============================================================================= +// Restart the ISR state machine +// +void IRrecv::resume ( ) +{ + irparams.rcvstate = STATE_IDLE; + irparams.rawlen = 0; +} + //+============================================================================= // hashdecode - decode an arbitrary IR code. // Instead of decoding using a standard encoding scheme diff --git a/irSend.cpp b/irSend.cpp index df3b1d9ff..1ec97a5b1 100644 --- a/irSend.cpp +++ b/irSend.cpp @@ -59,7 +59,7 @@ void IRsend::enableIROut (int khz) // 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 + // CS2 = 000: no prescaling // The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A. TIMER_CONFIG_KHZ(khz); } From 5d5479adbdfb05fa7106df4b3aecd8f5088ba136 Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Thu, 25 Jun 2015 22:59:19 +0000 Subject: [PATCH 077/768] Added Gitter badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 3fee47349..5b333f1ff 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ NOTE: THIS NEEDS TO BE FIXED.... PLEASE JUST USE THE LATEST RELEASE AND NOT THE MASTER BRANCH!!!! # IRremote Arduino Library + +[![Join the chat at https://gitter.im/shirriff/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/shirriff/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) This library enables you to send and receive using infra-red signals on an arduino. Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more information. From 0cacdf1ccb065348a977c356b77aae8ea90409a6 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Fri, 26 Jun 2015 12:25:39 -0600 Subject: [PATCH 078/768] added changelog --- changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changelog.txt diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 000000000..ca8bab287 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,6 @@ +## 1.1.0 - 2015/06/26 +- Separated protocols into individual files +- Lots of code clean up +- Possible bug fixes + + From ec5e1bd5f97bbf691c3dd7de33a73da4ea03e7f5 Mon Sep 17 00:00:00 2001 From: Bluechip Date: Wed, 1 Jul 2015 20:06:51 +0100 Subject: [PATCH 079/768] Fix coding error in send loops (specify bit size of literal) --- ir_Aiwa.cpp | 2 +- ir_Denon.cpp | 2 +- ir_Dish.cpp | 2 +- ir_JVC.cpp | 2 +- ir_NEC.cpp | 2 +- ir_Panasonic.cpp | 4 ++-- ir_RC5_RC6.cpp | 4 ++-- ir_Samsung.cpp | 2 +- ir_Sharp.cpp | 2 +- ir_Sony.cpp | 2 +- ir_Template.cpp | 2 +- ir_Whynter.cpp | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/ir_Aiwa.cpp b/ir_Aiwa.cpp index f56aa9981..bd5ba8966 100644 --- a/ir_Aiwa.cpp +++ b/ir_Aiwa.cpp @@ -38,7 +38,7 @@ void IRsend::sendAiwaRCT501 (int code) space(AIWA_RC_T501_HDR_SPACE); // Send "pre" data - for (unsigned long mask = 1 << (26 - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (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) ; diff --git a/ir_Denon.cpp b/ir_Denon.cpp index 7c9b07545..c54e28654 100644 --- a/ir_Denon.cpp +++ b/ir_Denon.cpp @@ -41,7 +41,7 @@ void IRsend::sendDenon (unsigned long data, int nbits) space(HDR_SPACE); // Data - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark (BIT_MARK); space(ONE_SPACE); diff --git a/ir_Dish.cpp b/ir_Dish.cpp index 387b163db..3dad8130d 100644 --- a/ir_Dish.cpp +++ b/ir_Dish.cpp @@ -39,7 +39,7 @@ void IRsend::sendDISH (unsigned long data, int nbits) mark(DISH_HDR_MARK); space(DISH_HDR_SPACE); - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(DISH_BIT_MARK); space(DISH_ONE_SPACE); diff --git a/ir_JVC.cpp b/ir_JVC.cpp index 123c20e1f..eeec20fe9 100644 --- a/ir_JVC.cpp +++ b/ir_JVC.cpp @@ -36,7 +36,7 @@ void IRsend::sendJVC (unsigned long data, int nbits, bool repeat) } // Data - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(JVC_BIT_MARK); space(JVC_ONE_SPACE); diff --git a/ir_NEC.cpp b/ir_NEC.cpp index 8da46e876..3b4932100 100644 --- a/ir_NEC.cpp +++ b/ir_NEC.cpp @@ -29,7 +29,7 @@ void IRsend::sendNEC (unsigned long data, int nbits) space(NEC_HDR_SPACE); // Data - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(NEC_BIT_MARK); space(NEC_ONE_SPACE); diff --git a/ir_Panasonic.cpp b/ir_Panasonic.cpp index d3b471a6d..dc0dd7317 100644 --- a/ir_Panasonic.cpp +++ b/ir_Panasonic.cpp @@ -28,14 +28,14 @@ void IRsend::sendPanasonic (unsigned int address, unsigned long data) space(PANASONIC_HDR_SPACE); // Address - for (unsigned long mask = 1 << (16 - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (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) { + for (unsigned long mask = 1UL << (32 - 1); mask; mask >>= 1) { mark(PANASONIC_BIT_MARK); if (data & mask) space(PANASONIC_ONE_SPACE) ; else space(PANASONIC_ZERO_SPACE) ; diff --git a/ir_RC5_RC6.cpp b/ir_RC5_RC6.cpp index 1a9576d2e..e59e3c0a9 100644 --- a/ir_RC5_RC6.cpp +++ b/ir_RC5_RC6.cpp @@ -64,7 +64,7 @@ void IRsend::sendRC5 (unsigned long data, int nbits) mark(RC5_T1); // Data - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { if (data & mask) { space(RC5_T1); // 1 is space, then mark mark(RC5_T1); @@ -141,7 +141,7 @@ void IRsend::sendRC6 (unsigned long data, int nbits) space(RC6_T1); // Data - for (unsigned long i = 1, mask = 1 << (nbits - 1); mask; i++, mask >>= 1) { + for (unsigned long i = 1, mask = 1UL << (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) { diff --git a/ir_Samsung.cpp b/ir_Samsung.cpp index 65452f262..224487dbc 100644 --- a/ir_Samsung.cpp +++ b/ir_Samsung.cpp @@ -29,7 +29,7 @@ void IRsend::sendSAMSUNG (unsigned long data, int nbits) space(SAMSUNG_HDR_SPACE); // Data - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(SAMSUNG_BIT_MARK); space(SAMSUNG_ONE_SPACE); diff --git a/ir_Sharp.cpp b/ir_Sharp.cpp index 13f8a53e4..73462c5bc 100644 --- a/ir_Sharp.cpp +++ b/ir_Sharp.cpp @@ -40,7 +40,7 @@ void IRsend::sendSharpRaw (unsigned long data, int nbits) // 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) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(SHARP_BIT_MARK); space(SHARP_ONE_SPACE); diff --git a/ir_Sony.cpp b/ir_Sony.cpp index e01df550c..31e67cf78 100644 --- a/ir_Sony.cpp +++ b/ir_Sony.cpp @@ -29,7 +29,7 @@ void IRsend::sendSony (unsigned long data, int nbits) space(SONY_HDR_SPACE); // Data - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(SONY_ONE_MARK); space(SONY_HDR_SPACE); diff --git a/ir_Template.cpp b/ir_Template.cpp index 474d77763..eee2b0bb2 100644 --- a/ir_Template.cpp +++ b/ir_Template.cpp @@ -126,7 +126,7 @@ void IRsend::sendShuzu (unsigned long data, int nbits) space(HDR_SPACE); // Data - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark (BIT_MARK); space(ONE_SPACE); diff --git a/ir_Whynter.cpp b/ir_Whynter.cpp index 2165cb706..a830562c6 100644 --- a/ir_Whynter.cpp +++ b/ir_Whynter.cpp @@ -34,7 +34,7 @@ void IRsend::sendWhynter (unsigned long data, int nbits) space(WHYNTER_HDR_SPACE); // Data - for (unsigned long mask = 1 << (nbits - 1); mask; mask >>= 1) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { if (data & mask) { mark(WHYNTER_ONE_MARK); space(WHYNTER_ONE_SPACE); From 360ca6ffb936f5df972a57be94818eda3c0e9b73 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Wed, 8 Jul 2015 16:22:50 -0600 Subject: [PATCH 080/768] Add Teensy LC Support, confirmed working @48Mhz with RecvDemo --- .gitignore | 1 + IRremoteInt.h | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..c5d99cb2a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.un~ diff --git a/IRremoteInt.h b/IRremoteInt.h index 83d0dffae..6fcaa1149 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -172,6 +172,10 @@ EXTERN volatile irparams_t irparams; #elif defined(__MK20DX128__) #define IR_USE_TIMER_CMT // tx = pin 5 +// Teensy-LC +#elif defined(__MKL26Z64__) + #define IR_USE_TIMER_TPM1 // tx = pin 16 + // Teensy++ 1.0 & 2.0 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) //#define IR_USE_TIMER1 // tx = pin 25 @@ -513,11 +517,42 @@ EXTERN volatile irparams_t irparams; #define TIMER_PWM_PIN 5 +// defines for TPM1 timer on Teensy-LC +#elif defined(IR_USE_TIMER_TPM1) +#define TIMER_RESET FTM1_SC |= FTM_SC_TOF; +#define TIMER_ENABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE +#define TIMER_DISABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE +#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1) +#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1) +#define TIMER_INTR_NAME ftm1_isr +#ifdef ISR +#undef ISR +#endif +#define ISR(f) void f(void) +#define TIMER_CONFIG_KHZ(val) ({ \ + SIM_SCGC6 |= SIM_SCGC6_TPM1; \ + FTM1_SC = 0; \ + FTM1_CNT = 0; \ + FTM1_MOD = (F_PLL/2000) / val - 1; \ + FTM1_C0V = (F_PLL/6000) / val - 1; \ + FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + SIM_SCGC6 |= SIM_SCGC6_TPM1; \ + FTM1_SC = 0; \ + FTM1_CNT = 0; \ + FTM1_MOD = (F_PLL/40000) - 1; \ + FTM1_C0V = 0; \ + FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \ +}) +#define TIMER_PWM_PIN 16 + + + //--------------------------------------------------------- // Unknown Timer // #else # error "Internal code configuration error, no known IR_USE_TIMER# defined\n" #endif - -#endif // IRremoteint_h +#endif From 2e4538bac8d48eb395be7f6c055c3d089c25aaee Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 11 Jul 2015 00:35:30 -0600 Subject: [PATCH 081/768] Added option for Teensy 3.1's processor. This is NOT a fix to #171 --- IRremoteInt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index 6fcaa1149..dbbbd281f 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -169,7 +169,7 @@ EXTERN volatile irparams_t irparams; #define IR_USE_TIMER4_HS // tx = pin 10 // Teensy 3.0 -#elif defined(__MK20DX128__) +#elif defined(__MK20DX128__) || defined(__MK20DX256__) #define IR_USE_TIMER_CMT // tx = pin 5 // Teensy-LC From 555a600acc3d7278ec9c1592ff70d22de06d3937 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 11 Jul 2015 15:22:18 -0600 Subject: [PATCH 082/768] Added pin variable in IRrecvDumpV2 --- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index a2add9fff..6dfa8109e 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -6,7 +6,8 @@ //------------------------------------------------------------------------------ // Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838) // -IRrecv irrecv(6); +int recvPin = 6; +IRrecv irrecv(recvPin); //+============================================================================= // Configure the Arduino From 1e85b4a0584c98b030fa41c3ff837d376338841f Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 11 Jul 2015 15:43:18 -0600 Subject: [PATCH 083/768] Experimental Release --- README.md | 10 +++------- changelog.md | 5 +++++ changelog.txt | 6 ------ 3 files changed, 8 insertions(+), 13 deletions(-) create mode 100644 changelog.md delete mode 100644 changelog.txt diff --git a/README.md b/README.md index 5b333f1ff..29233d0f7 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -NOTE: THIS NEEDS TO BE FIXED.... PLEASE JUST USE THE LATEST RELEASE AND NOT THE MASTER BRANCH!!!! # IRremote Arduino Library [![Join the chat at https://gitter.im/shirriff/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/shirriff/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + This library enables you to send and receive using infra-red signals on an arduino. Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more information. -## Version - 1.00 +## Version - 22.00 ## Installation 1. Navigate to the [Releases](https://github.com/shirriff/Arduino-IRremote/releases) page. @@ -15,11 +15,7 @@ Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more 4. Move the "IRremote" folder that has been extracted to your libraries directory. ## Usage -We get a lot of support for different device types. To keep the size of the library manageable we're moving to a model where different device types use a #define statement, for instance: - -```#define SHARP``` - -You'd put this at the top of your sketch to include the sendSharp() and decodeSharp() methods in your code. This way your sketch only uses the Sharp functions but not the LG, JVC, Sony, etc functions, thus saving you program space that you might want to use for other things. This allows us to support lots of devices without making the library too big. +- TODO (Check examples for now) ## Contributing If you want to contribute to this project: diff --git a/changelog.md b/changelog.md new file mode 100644 index 000000000..af4724478 --- /dev/null +++ b/changelog.md @@ -0,0 +1,5 @@ +## 2.0.1 - 2015/06/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA) +- Separated protocols into individual files +- Lots of code clean up +- Possible bug fixes + diff --git a/changelog.txt b/changelog.txt deleted file mode 100644 index ca8bab287..000000000 --- a/changelog.txt +++ /dev/null @@ -1,6 +0,0 @@ -## 1.1.0 - 2015/06/26 -- Separated protocols into individual files -- Lots of code clean up -- Possible bug fixes - - From 2280c963a7a296e1ddd5880fb78b7cedaa00f48b Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 16 Jul 2015 19:47:11 -0600 Subject: [PATCH 084/768] testing travis --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 61ec1b11c..4e380c1a3 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ If you want to contribute to this project: - Ask for enhancements - Create issues and pull requests - Tell other people about this library +- Contribute new protocols ## Contributors Check [here](Contributors.md) From ee1b44de3f8d022ff1e333b5c87312d8094fd5ef Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 23 Jul 2015 19:04:22 -0600 Subject: [PATCH 085/768] Add support for ATtiny84 --- IRremoteInt.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index dbbbd281f..60f744aa4 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -168,7 +168,7 @@ EXTERN volatile irparams_t irparams; //#define IR_USE_TIMER3 // tx = pin 9 #define IR_USE_TIMER4_HS // tx = pin 10 -// Teensy 3.0 +// Teensy 3.0 / Teensy 3.1 #elif defined(__MK20DX128__) || defined(__MK20DX256__) #define IR_USE_TIMER_CMT // tx = pin 5 @@ -191,6 +191,10 @@ EXTERN volatile irparams_t irparams; #elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) #define IR_USE_TIMER1 // tx = pin 9 +// ATtiny84 +#elif defined(__AVR_ATtiny84__) + #define IR_USE_TIMER1 + // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc #else //#define IR_USE_TIMER1 // tx = pin 9 From dcd06fa0ef17f15d09ee2837a02e0bfcdbea3e5e Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 23 Jul 2015 19:12:23 -0600 Subject: [PATCH 086/768] Add support for ATtiny85 --- IRremoteInt.h | 36 ++++++++++++++++++++++++++++++ examples/IRsendDemo/IRsendDemo.ino | 3 --- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index 60f744aa4..47c612328 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -195,6 +195,10 @@ EXTERN volatile irparams_t irparams; #elif defined(__AVR_ATtiny84__) #define IR_USE_TIMER1 +//ATtiny85 +#elif defined(__AVR_ATtiny85__) + #define IR_USE_TIMER_TINY0 // tx = pin 1 + // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc #else //#define IR_USE_TIMER1 // tx = pin 9 @@ -551,7 +555,39 @@ EXTERN volatile irparams_t irparams; }) #define TIMER_PWM_PIN 16 +// defines for timer_tiny0 (8 bits) +#elif defined(IR_USE_TIMER_TINY0) +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR0A |= _BV(COM0B1)) +#define TIMER_DISABLE_PWM (TCCR0A &= ~(_BV(COM0B1))) +#define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE0A)) +#define TIMER_DISABLE_INTR (TIMSK &= ~(_BV(OCIE0A))) +#define TIMER_INTR_NAME TIMER0_COMPA_vect +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR0A = _BV(WGM00); \ + TCCR0B = _BV(WGM02) | _BV(CS00); \ + OCR0A = pwmval; \ + OCR0B = pwmval / 3; \ +}) +#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) +#if (TIMER_COUNT_TOP < 256) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR0A = _BV(WGM01); \ + TCCR0B = _BV(CS00); \ + OCR0A = TIMER_COUNT_TOP; \ + TCNT0 = 0; \ +}) +#else +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR0A = _BV(WGM01); \ + TCCR0B = _BV(CS01); \ + OCR0A = TIMER_COUNT_TOP / 8; \ + TCNT0 = 0; \ +}) +#endif +#define TIMER_PWM_PIN 1 /* ATtiny85 */ //--------------------------------------------------------- // Unknown Timer diff --git a/examples/IRsendDemo/IRsendDemo.ino b/examples/IRsendDemo/IRsendDemo.ino index a21af315b..e3772ed73 100644 --- a/examples/IRsendDemo/IRsendDemo.ino +++ b/examples/IRsendDemo/IRsendDemo.ino @@ -12,14 +12,11 @@ IRsend irsend; void setup() { - Serial.begin(9600); } void loop() { - if (Serial.read() != -1) { for (int i = 0; i < 3; i++) { irsend.sendSony(0xa90, 12); // Sony TV power code delay(40); } - } } From 1e519b1bf31135a93044418bc12bf0f03b0542cd Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 23 Jul 2015 19:39:46 -0600 Subject: [PATCH 087/768] added isIdle Method for receiving, #48 --- IRremote.h | 1 + examples/IRsendDemo/IRsendDemo.ino | 9 ++++----- irRecv.cpp | 7 +++++++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/IRremote.h b/IRremote.h index 3a64fedfd..da9364880 100644 --- a/IRremote.h +++ b/IRremote.h @@ -172,6 +172,7 @@ class IRrecv void blink13 (int blinkflag) ; int decode (decode_results *results) ; void enableIRIn ( ) ; + bool isIdle ( ) ; void resume ( ) ; private: diff --git a/examples/IRsendDemo/IRsendDemo.ino b/examples/IRsendDemo/IRsendDemo.ino index e3772ed73..80e37f2e2 100644 --- a/examples/IRsendDemo/IRsendDemo.ino +++ b/examples/IRsendDemo/IRsendDemo.ino @@ -8,15 +8,14 @@ #include -IRsend irsend; +IRrecv irrecv; void setup() { + Serial.begin(115200); } void loop() { - for (int i = 0; i < 3; i++) { - irsend.sendSony(0xa90, 12); // Sony TV power code - delay(40); - } + if (irrecv.isIdle()) + Serial.println("Idling"); } diff --git a/irRecv.cpp b/irRecv.cpp index 461402090..a6fafe2a6 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -133,6 +133,13 @@ void IRrecv::blink13 (int blinkflag) if (blinkflag) pinMode(BLINKLED, OUTPUT) ; } +//+============================================================================= +// Return if receiving new IR signals +// +bool IRrecv::isIdle ( ) +{ + return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false; +} //+============================================================================= // Restart the ISR state machine // From 107b8c249c800e122022d3c9ac17b6ef5eb434e6 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Fri, 24 Jul 2015 16:35:28 -0600 Subject: [PATCH 088/768] 1e519b1bf --- irRecv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irRecv.cpp b/irRecv.cpp index a6fafe2a6..6cafb58e8 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -138,7 +138,7 @@ void IRrecv::blink13 (int blinkflag) // bool IRrecv::isIdle ( ) { - return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false; + return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false; } //+============================================================================= // Restart the ISR state machine From 3cc9956f97b4aff5b3e8c1da3acd3e597c43c599 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Fri, 24 Jul 2015 16:36:09 -0600 Subject: [PATCH 089/768] #176 --- IRremoteInt.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/IRremoteInt.h b/IRremoteInt.h index 47c612328..6f5d660f5 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -302,6 +302,8 @@ EXTERN volatile irparams_t irparams; # define TIMER_PWM_PIN 11 // Arduino Mega #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) # define TIMER_PWM_PIN 13 // Sanguino +#elif defined(__AVR_ATtiny84__) +# define TIMER_PWM_PIN 6 #else # define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc #endif From e23aa5eb328e0781ce7e024591af0796841fff6c Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 26 Jul 2015 22:13:24 -0600 Subject: [PATCH 090/768] Updating Changelog - test 1 --- changelog.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index af4724478..ce457afad 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,14 @@ -## 2.0.1 - 2015/06/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA) -- Separated protocols into individual files -- Lots of code clean up -- Possible bug fixes +## 2.0.1 - 2015/07/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA) +### Changes +- Updated README +- Updated Contributors +- Fixed #110 Mess +### Additions +- [Added Aiwa RC-T501 Protocol] (c2bf981) +- [Added Library Properties] (675f9fe04225e63c9394a5752f6630764572c81c) +- + + + +### Deletions From 29826d01f4cf9a881fe3c0b3f80c3605c5a76481 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 26 Jul 2015 22:37:56 -0600 Subject: [PATCH 091/768] Added pin comment for ATtiny84 --- IRremoteInt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index 6f5d660f5..38a4a2c27 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -193,7 +193,7 @@ EXTERN volatile irparams_t irparams; // ATtiny84 #elif defined(__AVR_ATtiny84__) - #define IR_USE_TIMER1 + #define IR_USE_TIMER1 // tx = pin 6 //ATtiny85 #elif defined(__AVR_ATtiny85__) From 0c298aaf3991a5980321d75e8fc362d54bd5a1b2 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 26 Jul 2015 22:38:20 -0600 Subject: [PATCH 092/768] Updated changelog --- changelog.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index ce457afad..81e95d87b 100644 --- a/changelog.md +++ b/changelog.md @@ -3,12 +3,34 @@ - Updated README - Updated Contributors - Fixed #110 Mess +- Created Gitter Room +- Added Gitter Badge +- Standardised Code Base +- Clean Debug Output +- Optimized Send Loops +- Modularized Design +- Optimized and Updated Examples +- Improved Documentation +- Fixed and Improved many coding errors +- Fixed Aiwa RC-T501 Decoding +- Fixed Interrupt on ATmega8 +- Switched to Stable Release of @PlatformIO ### Additions -- [Added Aiwa RC-T501 Protocol] (c2bf981) -- [Added Library Properties] (675f9fe04225e63c9394a5752f6630764572c81c) -- - - +- Added Aiwa RC-T501 Protocol +- Added Denon Protocol +- Added Pronto Support +- Added Library Properties +- Added Template For New Protocols +- Added this changelog +- Added Teensy LC Support +- Added ATtiny84 Support +- Added ATtiny85 Support +- Added isIdle method ### Deletions +- Removed (Fixed) #110 +- Broke Teensy 3 / 3.1 Support + +### Not Working +- Teensy 3 / 3.1 Support is in Development From 9fe9551705262abc93882f455e7ee89cb394b3e6 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 26 Jul 2015 23:03:39 -0600 Subject: [PATCH 093/768] Removed Travis Badge, will add when Travis is working --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 4e380c1a3..cec345a64 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -![Build Status](https://travis-ci.org/shirriff/Arduino-IRremote.svg)](https://travis-ci.org/shirriff/Arduino-IRremote) - # IRremote Arduino Library [![Join the chat at https://gitter.im/shirriff/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/shirriff/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From 86a1e93b231cf6a5738316d72f8db044ceabe128 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 30 Jul 2015 00:01:37 -0600 Subject: [PATCH 094/768] dummy commit to test travis ci --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cec345a64..adb0f8cf3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Join the chat at https://gitter.im/shirriff/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/shirriff/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -This library enables you to send and receive using infra-red signals on an arduino. +This library enables you to send and receive using infra-red signals on an Arduino. Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more information. From e794c747dbafd5d98019174e049f2b2a8b59cac5 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 30 Jul 2015 00:03:15 -0600 Subject: [PATCH 095/768] Travis CI workingvim README.md ! added the badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index adb0f8cf3..bfb77edb4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # IRremote Arduino Library +[![Build Status](https://travis-ci.org/shirriff/Arduino-IRremote.svg?branch=master)](https://travis-ci.org/shirriff/Arduino-IRremote) + [![Join the chat at https://gitter.im/shirriff/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/shirriff/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) This library enables you to send and receive using infra-red signals on an Arduino. From 197ff26f68b746412ab979c8280de822251ff107 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 30 Jul 2015 00:14:55 -0600 Subject: [PATCH 096/768] Update Contributors.md --- Contributors.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Contributors.md b/Contributors.md index 4a9b88da3..e56b29c6d 100644 --- a/Contributors.md +++ b/Contributors.md @@ -4,14 +4,14 @@ These are the active contributors of this project that you may contact if there - [z3t0](https://github.com/z3t0) : Active Contributor and currently also the main contributor. * Email: zetoslab@gmail.com * Skype: polarised16 -- [shirriff](https://github.com/shirriff) : Owner of repository and creator of library. +- [shirriff](https://github.com/shirriff) : An amazing person who worked to create this awesome library and provide unending support - [Informatic](https://github.com/Informatic) : Active contributor - [fmeschia](https://github.com/fmeschia) : Active contributor - [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor - [crash7](https://github.com/crash7) : Active contributor - [Neco777](https://github.com/neco777) : Active contributor - [Lauszus](https://github.com/lauszus) : Active contributor -- [csBlueChip](https://github.com/csbluechip) : Active contributor +- [csBlueChip](https://github.com/csbluechip) : Active contributor, who contributed major and vital changes to the code base. Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. From b6c04cde1a2f2b0092877eec44e2b388bec51efb Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 30 Jul 2015 19:24:12 +0300 Subject: [PATCH 097/768] Update Travis CI badge with @z3t0 account --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bfb77edb4..b352ca80d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # IRremote Arduino Library -[![Build Status](https://travis-ci.org/shirriff/Arduino-IRremote.svg?branch=master)](https://travis-ci.org/shirriff/Arduino-IRremote) +[![Build Status](https://travis-ci.org/z3t0/Arduino-IRremote.svg?branch=master)](https://travis-ci.org/z3t0/Arduino-IRremote) [![Join the chat at https://gitter.im/shirriff/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/shirriff/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From 6a10861a44e82b422fdd2d3fad22c5ba4f265175 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 30 Jul 2015 11:43:59 -0600 Subject: [PATCH 098/768] Update IRsendDemo.ino --- examples/IRsendDemo/IRsendDemo.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/IRsendDemo/IRsendDemo.ino b/examples/IRsendDemo/IRsendDemo.ino index 80e37f2e2..fa1c56afd 100644 --- a/examples/IRsendDemo/IRsendDemo.ino +++ b/examples/IRsendDemo/IRsendDemo.ino @@ -8,7 +8,8 @@ #include -IRrecv irrecv; +int RECV_PIN = 11; +IRrecv irrecv (RECV_PIN); void setup() { From 114fe2ccd64e8c2af5fc50a24c8400602682e15e Mon Sep 17 00:00:00 2001 From: madmalkav Date: Fri, 31 Jul 2015 20:58:04 +0200 Subject: [PATCH 099/768] Added suport for user defined IR reception feedback LED --- IRremote.h | 3 ++- IRremoteInt.h | 4 +++- irISR.cpp | 9 ++++++--- irRecv.cpp | 10 ++++++++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/IRremote.h b/IRremote.h index da9364880..097a217c5 100644 --- a/IRremote.h +++ b/IRremote.h @@ -168,11 +168,12 @@ class IRrecv { public: IRrecv (int recvpin) ; + IRrecv (int recvpin, int blinkpin); void blink13 (int blinkflag) ; int decode (decode_results *results) ; void enableIRIn ( ) ; - bool isIdle ( ) ; + bool isIdle ( ) ; void resume ( ) ; private: diff --git a/IRremoteInt.h b/IRremoteInt.h index 38a4a2c27..32515c3c8 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -47,7 +47,8 @@ typedef // The fields are ordered to reduce memory over caused by struct-padding uint8_t rcvstate; // State Machine state uint8_t recvpin; // Pin connected to IR data from detector - uint8_t blinkflag; // true -> enable blinking of pin 13 on IR processing + uint8_t blinkpin; + uint8_t blinkflag; // true -> enable blinking of pin on IR processing uint8_t rawlen; // counter of entries in rawbuf unsigned int timer; // State timer, counts 50uS ticks. unsigned int rawbuf[RAWBUF]; // raw data @@ -70,6 +71,7 @@ EXTERN volatile irparams_t irparams; //------------------------------------------------------------------------------ // Defines for blinking the LED // + #if defined(CORE_LED0_PIN) # define BLINKLED CORE_LED0_PIN # define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH)) diff --git a/irISR.cpp b/irISR.cpp index acafafb45..b124e9ca6 100644 --- a/irISR.cpp +++ b/irISR.cpp @@ -77,9 +77,12 @@ ISR (TIMER_INTR_NAME) break; } - // If requested, flash LED L (D13) while receiving IR data + // If requested, flash LED while receiving IR data if (irparams.blinkflag) { - if (irdata == MARK) BLINKLED_ON() ; // turn pin 13 LED on - else BLINKLED_OFF() ; // turn pin 13 LED off + if (irdata == MARK) + if (irparams.blinkpin) digitalWrite(irparams.blinkpin, HIGH); // Turn user defined pin LED on + else BLINKLED_ON() ; // if no user defined LED pin, turn default LED pin for the hardware on + else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on + else BLINKLED_OFF() ; // if no user defined LED pin, turn default LED pin for the hardware on } } diff --git a/irRecv.cpp b/irRecv.cpp index 6cafb58e8..40bd78222 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -97,6 +97,16 @@ IRrecv::IRrecv (int recvpin) irparams.blinkflag = 0; } +IRrecv::IRrecv (int recvpin, int blinkpin) +{ + irparams.recvpin = recvpin; + irparams.blinkpin = blinkpin; + pinMode(blinkpin, OUTPUT); + irparams.blinkflag = 0; +} + + + //+============================================================================= // initialization // From 2efeef446e732cc1f63082d24a22ec3ba4977699 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 10 Aug 2015 13:53:56 -0600 Subject: [PATCH 100/768] Working on sendRaw Bug --- irSend.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/irSend.cpp b/irSend.cpp index 1ec97a5b1..f1365711d 100644 --- a/irSend.cpp +++ b/irSend.cpp @@ -2,12 +2,12 @@ #include "IRremoteInt.h" //+============================================================================= -void IRsend::sendRaw (unsigned int buf[], int len, int hz) +void IRsend::sendRaw (unsigned int buf[], unsigned char len, unsigned char hz) { // Set IR carrier frequency enableIROut(hz); - for (int i = 0; i < len; i++) { + for (unsigned char i = 0; i < len; i++) { if (i & 1) space(buf[i]) ; else mark (buf[i]) ; } From a1a45382006781c88bc0b5a2e3f0dc11db7db6e3 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 10 Aug 2015 14:12:03 -0600 Subject: [PATCH 101/768] fixed previous commit --- IRremote.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRremote.h b/IRremote.h index 097a217c5..9321d1779 100644 --- a/IRremote.h +++ b/IRremote.h @@ -256,7 +256,7 @@ class IRsend void enableIROut (int khz) ; void mark (int usec) ; void space (int usec) ; - void sendRaw (unsigned int buf[], int len, int hz) ; + void sendRaw (unsigned int buf[], unsigned char len, unsigned char hz) ; //...................................................................... # if SEND_RC5 From c9e8ab555e659f42697428d0bacf184a4238143b Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 10 Aug 2015 14:31:27 -0600 Subject: [PATCH 102/768] changed ifdef to if in IRRecv --- irRecv.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/irRecv.cpp b/irRecv.cpp index 40bd78222..a3ff452e0 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -15,67 +15,67 @@ int IRrecv::decode (decode_results *results) if (irparams.rcvstate != STATE_STOP) return false ; -#ifdef DECODE_NEC +#if DECODE_NEC DBG_PRINTLN("Attempting NEC decode"); if (decodeNEC(results)) return true ; #endif -#ifdef DECODE_SONY +#if DECODE_SONY DBG_PRINTLN("Attempting Sony decode"); if (decodeSony(results)) return true ; #endif -#ifdef DECODE_SANYO +#if DECODE_SANYO DBG_PRINTLN("Attempting Sanyo decode"); if (decodeSanyo(results)) return true ; #endif -#ifdef DECODE_MITSUBISHI +#if DECODE_MITSUBISHI DBG_PRINTLN("Attempting Mitsubishi decode"); if (decodeMitsubishi(results)) return true ; #endif -#ifdef DECODE_RC5 +#if DECODE_RC5 DBG_PRINTLN("Attempting RC5 decode"); if (decodeRC5(results)) return true ; #endif -#ifdef DECODE_RC6 +#if DECODE_RC6 DBG_PRINTLN("Attempting RC6 decode"); if (decodeRC6(results)) return true ; #endif -#ifdef DECODE_PANASONIC +#if DECODE_PANASONIC DBG_PRINTLN("Attempting Panasonic decode"); if (decodePanasonic(results)) return true ; #endif -#ifdef DECODE_LG +#if DECODE_LG DBG_PRINTLN("Attempting LG decode"); if (decodeLG(results)) return true ; #endif -#ifdef DECODE_JVC +#if DECODE_JVC DBG_PRINTLN("Attempting JVC decode"); if (decodeJVC(results)) return true ; #endif -#ifdef DECODE_SAMSUNG +#if DECODE_SAMSUNG DBG_PRINTLN("Attempting SAMSUNG decode"); if (decodeSAMSUNG(results)) return true ; #endif -#ifdef DECODE_WHYNTER +#if DECODE_WHYNTER DBG_PRINTLN("Attempting Whynter decode"); if (decodeWhynter(results)) return true ; #endif -#ifdef DECODE_AIWA_RC_T501 +#if DECODE_AIWA_RC_T501 DBG_PRINTLN("Attempting Aiwa RC-T501 decode"); if (decodeAiwaRCT501(results)) return true ; #endif -#ifdef DECODE_DENON +#if DECODE_DENON DBG_PRINTLN("Attempting Denon decode"); if (decodeDenon(results)) return true ; #endif From 5c920bd31dead97ce9acfc6429b9c3e0162faf47 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 10 Aug 2015 14:33:35 -0600 Subject: [PATCH 103/768] wrapped getRCLevel function with #if DECODE_RC5/6 --- ir_RC5_RC6.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ir_RC5_RC6.cpp b/ir_RC5_RC6.cpp index e59e3c0a9..10e79278e 100644 --- a/ir_RC5_RC6.cpp +++ b/ir_RC5_RC6.cpp @@ -10,6 +10,7 @@ // t1 is the time interval for a single bit in microseconds. // Returns -1 for error (measured time interval is not a multiple of t1). // +#if (DECODE_RC5 || DECODE_RC6) int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int t1) { int width; @@ -37,6 +38,7 @@ int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int return val; } +#endif //============================================================================== // RRRR CCCC 55555 From cd9fb53520390799c294a1cd9778ae518acd3e48 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 10 Aug 2015 14:41:13 -0600 Subject: [PATCH 104/768] Fixed README links. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b352ca80d..ec1aecc0c 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,16 @@ [![Build Status](https://travis-ci.org/z3t0/Arduino-IRremote.svg?branch=master)](https://travis-ci.org/z3t0/Arduino-IRremote) -[![Join the chat at https://gitter.im/shirriff/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/shirriff/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Join the chat at https://gitter.im/z3t0/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/z3t0/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) This library enables you to send and receive using infra-red signals on an Arduino. -Check [here](http://shirriff.github.io/Arduino-IRremote/) for tutorials and more information. +Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more information. ## Version - 2.01 ## Installation -1. Navigate to the [Releases](https://github.com/shirriff/Arduino-IRremote/releases) page. +1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. 2. Download the latest release. 3. Extract the zip file 4. Move the "IRremote" folder that has been extracted to your libraries directory. From 879b06b1c4262bdbd8d0df4110edf4f5fa4c88d4 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 11 Aug 2015 00:17:55 -0600 Subject: [PATCH 105/768] Removed a windows encoding line in irISR.cpp, #192 --- irISR.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irISR.cpp b/irISR.cpp index b124e9ca6..e3bc1c370 100644 --- a/irISR.cpp +++ b/irISR.cpp @@ -15,7 +15,7 @@ // As soon as first MARK arrives: // Gap width is recorded; Ready is cleared; New logging starts // -ISR (TIMER_INTR_NAME) +ISR (TIMER_INTR_NAME) { TIMER_RESET; From c058f3f336e1c1116240ff70065a38e5c7536ca1 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Wed, 12 Aug 2015 14:16:51 -0600 Subject: [PATCH 106/768] solves #195 --- examples/IRsendDemo/IRsendDemo.ino | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/IRsendDemo/IRsendDemo.ino b/examples/IRsendDemo/IRsendDemo.ino index fa1c56afd..4f51a578c 100644 --- a/examples/IRsendDemo/IRsendDemo.ino +++ b/examples/IRsendDemo/IRsendDemo.ino @@ -6,17 +6,18 @@ * http://arcfn.com */ + #include -int RECV_PIN = 11; -IRrecv irrecv (RECV_PIN); +IRsend irsend; void setup() { - Serial.begin(115200); } void loop() { - if (irrecv.isIdle()) - Serial.println("Idling"); + for (int i = 0; i < 3; i++) { + irsend.sendSony(0xa90, 12); + delay(40); + } } From 11cb3fe442b2084600ab4bf278d5c727573aced3 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 13 Aug 2015 16:54:59 -0600 Subject: [PATCH 107/768] Fixed delay method by replacing delayMicroseconds call with a loop if it is too long. --- IRremote.h | 9 ++-- irSend.cpp | 150 ++++++++++++++++++++++++++++++----------------------- 2 files changed, 89 insertions(+), 70 deletions(-) diff --git a/IRremote.h b/IRremote.h index 9321d1779..42be5ed38 100644 --- a/IRremote.h +++ b/IRremote.h @@ -253,10 +253,11 @@ class IRsend public: IRsend () { } - void enableIROut (int khz) ; - void mark (int usec) ; - void space (int usec) ; - void sendRaw (unsigned int buf[], unsigned char len, unsigned char hz) ; + void custom_delay_ms (unsigned int time); + void enableIROut (int khz) ; + void mark (int usec) ; + void space (int usec) ; + void sendRaw (unsigned int buf[], unsigned char len, unsigned char hz) ; //...................................................................... # if SEND_RC5 diff --git a/irSend.cpp b/irSend.cpp index f1365711d..e7b9d86e5 100644 --- a/irSend.cpp +++ b/irSend.cpp @@ -1,66 +1,84 @@ -#include "IRremote.h" -#include "IRremoteInt.h" - -//+============================================================================= -void IRsend::sendRaw (unsigned int buf[], unsigned char len, unsigned char hz) -{ - // Set IR carrier frequency - enableIROut(hz); - - for (unsigned char 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); -} - +#include "IRremote.h" +#include "IRremoteInt.h" + +//+============================================================================= +void IRsend::sendRaw (unsigned int buf[], unsigned char len, unsigned char hz) +{ + // Set IR carrier frequency + enableIROut(hz); + + for (unsigned char 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) custom_delay_ms(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) IRsend::custom_delay_ms(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); +} + +//+============================================================================= +// Custom delay function that circumvents Arduino's delayMicroseconds limit + +void IRsend::custom_delay_ms(unsigned int time) { + if (time) + { + if (time > 16000) + { + delayMicroseconds(time % 1000); + delay(time / 1000); + } + else delayMicroseconds(time); + } +} From 7aee7fcf8976463df519f5cf76d879e1005c2bb3 Mon Sep 17 00:00:00 2001 From: Paul Coughlin Date: Fri, 14 Aug 2015 20:22:34 -0600 Subject: [PATCH 108/768] update custom_delay function Use micros() to delay based on "real-time" instead of approximation with delay() or delayMicroseconds() Changed name to _usec to correspond to MicroSeconds. _ms is MilliSeconds. --- IRremote.h | 2 +- irSend.cpp | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/IRremote.h b/IRremote.h index 42be5ed38..fcfb0b83c 100644 --- a/IRremote.h +++ b/IRremote.h @@ -253,7 +253,7 @@ class IRsend public: IRsend () { } - void custom_delay_ms (unsigned int time); + void custom_delay_usec (unsigned long uSecs); void enableIROut (int khz) ; void mark (int usec) ; void space (int usec) ; diff --git a/irSend.cpp b/irSend.cpp index e7b9d86e5..0b2e11984 100644 --- a/irSend.cpp +++ b/irSend.cpp @@ -22,7 +22,7 @@ void IRsend::sendRaw (unsigned int buf[], unsigned char len, unsigned char hz void IRsend::mark (int time) { TIMER_ENABLE_PWM; // Enable pin 3 PWM output - if (time > 0) custom_delay_ms(time); + if (time > 0) custom_delay_usec(time); } //+============================================================================= @@ -33,7 +33,7 @@ void IRsend::mark (int time) void IRsend::space (int time) { TIMER_DISABLE_PWM; // Disable pin 3 PWM output - if (time > 0) IRsend::custom_delay_ms(time); + if (time > 0) IRsend::custom_delay_usec(time); } @@ -71,14 +71,16 @@ void IRsend::enableIROut (int khz) //+============================================================================= // Custom delay function that circumvents Arduino's delayMicroseconds limit -void IRsend::custom_delay_ms(unsigned int time) { - if (time) - { - if (time > 16000) - { - delayMicroseconds(time % 1000); - delay(time / 1000); - } - else delayMicroseconds(time); - } +void IRsend::custom_delay_usec(unsigned long uSecs) { + if (uSecs > 4) { + unsigned long start = micros(); + unsigned long endMicros = start + uSecs - 4; + if (endMicros < start) { // Check if overflow + while ( micros() > start ) {} // wait until overflow + } + while ( micros() < endMicros ) {} // normal wait + } else { + __asm__("nop\n\t"); // must have or compiler optimizes out + } } + From 1e72064557cd7a69fce8f2ac300457f139a047b4 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Wed, 19 Aug 2015 23:17:03 +0100 Subject: [PATCH 109/768] changes to senRAW, mark,space,custom_delay_usec parameters changed from int to unsigned int to allow longer mark/space durations and signal length.hz changed to allow for potential future use of 455kHz carrier frequency. (Ther may be existing modes to the library, using this frequency) removed "asm" workaround for compiler, because it was not need ed on my system. Original autor should verify this again. It could be alternatice compiler optimization settings? Alternatively, place the volatile keyword before the variables in the function to avoid the "optimization out" --- irSend.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/irSend.cpp b/irSend.cpp index 0b2e11984..1340e6390 100644 --- a/irSend.cpp +++ b/irSend.cpp @@ -2,12 +2,12 @@ #include "IRremoteInt.h" //+============================================================================= -void IRsend::sendRaw (unsigned int buf[], unsigned char len, unsigned char hz) +void IRsend::sendRaw (unsigned int buf[], unsigned int len, unsigned int hz) { // Set IR carrier frequency enableIROut(hz); - for (unsigned char i = 0; i < len; i++) { + for (unsigned int i = 0; i < len; i++) { if (i & 1) space(buf[i]) ; else mark (buf[i]) ; } @@ -19,7 +19,7 @@ void IRsend::sendRaw (unsigned int buf[], unsigned char len, unsigned char hz // Sends an IR mark for the specified number of microseconds. // The mark output is modulated at the PWM frequency. // -void IRsend::mark (int time) +void IRsend::mark (unsigned int time) { TIMER_ENABLE_PWM; // Enable pin 3 PWM output if (time > 0) custom_delay_usec(time); @@ -30,7 +30,7 @@ void IRsend::mark (int time) // 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) +void IRsend::space (unsigned int time) { TIMER_DISABLE_PWM; // Disable pin 3 PWM output if (time > 0) IRsend::custom_delay_usec(time); @@ -79,8 +79,9 @@ void IRsend::custom_delay_usec(unsigned long uSecs) { while ( micros() > start ) {} // wait until overflow } while ( micros() < endMicros ) {} // normal wait - } else { - __asm__("nop\n\t"); // must have or compiler optimizes out - } + } + //else { + // __asm__("nop\n\t"); // must have or compiler optimizes out + //} } From 9b21a7fdbdcafcaf0db26ef041737375122c6919 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Wed, 19 Aug 2015 23:24:59 +0100 Subject: [PATCH 110/768] Update parameters for mark,space and sendraw parameters changed from int to unsigned int to allow longer mark/space durations and signal length. hz changed to allow for potential future use of 455kHz carrier frequency. (Ther may be existing modes to the library, using this frequency) --- IRremote.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IRremote.h b/IRremote.h index fcfb0b83c..898bd155b 100644 --- a/IRremote.h +++ b/IRremote.h @@ -255,9 +255,9 @@ class IRsend void custom_delay_usec (unsigned long uSecs); void enableIROut (int khz) ; - void mark (int usec) ; - void space (int usec) ; - void sendRaw (unsigned int buf[], unsigned char len, unsigned char hz) ; + void mark (unsigned int usec) ; + void space (unsigned int usec) ; + void sendRaw (unsigned int buf[], unsigned int len, unsigned int hz) ; //...................................................................... # if SEND_RC5 From 1fd88cd308f41de975af2b8d08202eb38a23e61a Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Thu, 20 Aug 2015 15:46:23 +0100 Subject: [PATCH 111/768] change int to unsigned int in IRrecvDumpV2 some larger values could overflow to negative numbers, with unsigned int (vs int) --- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index 6dfa8109e..bbfb6749c 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -95,7 +95,7 @@ void dumpRaw (decode_results *results) Serial.print(" -"); Serial.println(results->rawbuf[0] * USECPERTICK, DEC); for (int i = 1; i < results->rawlen; i++) { - int x = results->rawbuf[i] * USECPERTICK; + unsigned int x = results->rawbuf[i] * USECPERTICK; if (!(i & 1)) { // even Serial.print("-"); if (x < 1000) Serial.print(" ") ; From f83fe2b70faf826b354e9d35fe8937a9884d6783 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Thu, 20 Aug 2015 15:53:50 +0100 Subject: [PATCH 112/768] Update IRrecvDumpV2.ino looks like this multiplier was omitted and needs to be include to make the output meaningful/useful??? Would also explain some weird output I have seen posted. --- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index bbfb6749c..f29e74af6 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -127,7 +127,7 @@ void dumpCode (decode_results *results) // Dump data for (int i = 0; i < results->rawlen; i++) { - Serial.print(results->rawbuf[i], DEC); + Serial.print(results->rawbuf[i] * USECPERTICK, DEC); Serial.print(","); if (!(i&1)) Serial.print(" "); } From ec371483acceeadfbdb650bced7d672a4402a2d3 Mon Sep 17 00:00:00 2001 From: chaeplin Date: Sat, 22 Aug 2015 19:06:22 +0900 Subject: [PATCH 113/768] adding SEND_LG --- IRremote.h | 4 +- examples/LGACSendDemo/LGACSendDemo.ino | 249 +++++++++++++++++++++++++ examples/LGACSendDemo/LGACSendDemo.md | 35 ++++ ir_LG.cpp | 26 +++ 4 files changed, 312 insertions(+), 2 deletions(-) create mode 100644 examples/LGACSendDemo/LGACSendDemo.ino create mode 100644 examples/LGACSendDemo/LGACSendDemo.md diff --git a/IRremote.h b/IRremote.h index 898bd155b..ce404a686 100644 --- a/IRremote.h +++ b/IRremote.h @@ -56,7 +56,7 @@ #define SEND_AIWA_RC_T501 1 #define DECODE_LG 1 -#define SEND_LG 0 // NOT WRITTEN +#define SEND_LG 1 #define DECODE_SANYO 1 #define SEND_SANYO 0 // NOT WRITTEN @@ -300,7 +300,7 @@ class IRsend # endif //...................................................................... # if SEND_LG - void sendLG ( ) ; // NOT WRITTEN + void sendLG (unsigned long data, int nbits) ; # endif //...................................................................... # if SEND_SANYO diff --git a/examples/LGACSendDemo/LGACSendDemo.ino b/examples/LGACSendDemo/LGACSendDemo.ino new file mode 100644 index 000000000..66d5025d8 --- /dev/null +++ b/examples/LGACSendDemo/LGACSendDemo.ino @@ -0,0 +1,249 @@ +#include +#include + + +IRsend irsend; +// not used +int RECV_PIN = 11; +IRrecv irrecv (RECV_PIN); + +const int AC_TYPE = 0; +// 0 : TOWER +// 1 : WALL + +int AC_POWER_ON = 0; +// 0 : off +// 1 : on + +int AC_AIR_ACLEAN = 0; +// 0 : off +// 1 : on --> power on + +int AC_TEMPERATURE = 27; +// temperature : 18 ~ 30 + +int AC_FLOW = 1; +// 0 : low +// 1 : mid +// 2 : high +// if AC_TYPE =1, 3 : change + +const int AC_FLOW_TOWER[3] = {0, 4, 6}; +const int AC_FLOW_WALL[4] = {0, 2, 4, 5}; + +unsigned long AC_CODE_TO_SEND; + +int r = LOW; +int o_r = LOW; + +byte a, b; + +void ac_send_code(unsigned long code) +{ + Serial.print("code to send : "); + Serial.print(code, BIN); + Serial.print(" : "); + Serial.println(code, HEX); + + irsend.sendLG(code, 28); +} + +void ac_activate(int temperature, int air_flow) +{ + + int AC_MSBITS1 = 8; + int AC_MSBITS2 = 8; + int AC_MSBITS3 = 0; + int AC_MSBITS4 = 0; + int AC_MSBITS5 = temperature - 15; + int AC_MSBITS6 ; + + if ( AC_TYPE == 0) { + AC_MSBITS6 = AC_FLOW_TOWER[air_flow]; + } else { + AC_MSBITS6 = AC_FLOW_WALL[air_flow]; + } + + int AC_MSBITS7 = (AC_MSBITS3 + AC_MSBITS4 + AC_MSBITS5 + AC_MSBITS6) & B00001111; + + AC_CODE_TO_SEND = AC_MSBITS1 << 4 ; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS2) << 4; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS3) << 4; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS4) << 4; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS5) << 4; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS6) << 4; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS7); + + ac_send_code(AC_CODE_TO_SEND); + + AC_POWER_ON = 1; + AC_TEMPERATURE = temperature; + AC_FLOW = air_flow; +} + +void ac_change_air_swing(int air_swing) +{ + if ( AC_TYPE == 0) { + if ( air_swing == 1) { + AC_CODE_TO_SEND = 0x881316B; + } else { + AC_CODE_TO_SEND = 0x881317C; + } + } else { + if ( air_swing == 1) { + AC_CODE_TO_SEND = 0x8813149; + } else { + AC_CODE_TO_SEND = 0x881315A; + } + } + + ac_send_code(AC_CODE_TO_SEND); +} + +void ac_power_down() +{ + AC_CODE_TO_SEND = 0x88C0051; + + ac_send_code(AC_CODE_TO_SEND); + + AC_POWER_ON = 0; +} + +void ac_air_clean(int air_clean) +{ + if ( air_clean == 1) { + AC_CODE_TO_SEND = 0x88C000C; + } else { + AC_CODE_TO_SEND = 0x88C0084; + } + + ac_send_code(AC_CODE_TO_SEND); + + AC_AIR_ACLEAN = air_clean; +} + +void setup() +{ + Serial.begin(38400); + delay(1000); + Wire.begin(7); + Wire.onReceive(receiveEvent); + + Serial.println(" - - - T E S T - - - "); + +/* test + ac_activate(25, 1); + delay(5000); + ac_activate(27, 2); + delay(5000); + +*/ +} + +void loop() +{ + + + ac_activate(25, 1); + delay(5000); + ac_activate(27, 0); + delay(5000); + + + if ( r != o_r) { + + /* + # a : mode or temp b : air_flow, temp, swing, clean + # 18 ~ 30 : temp 0 ~ 2 : flow // on + # 0 : off 0 + # 1 : on 0 + # 2 : air_swing 0 or 1 + # 3 : air_clean 0 or 1 + # 4 : air_flow 0 ~ 2 : flow + # 5 : temp 18 ~ 30 + # + : temp + 1 + # - : temp - 1 + # m : change cooling to air clean, air clean to cooling + */ + Serial.print("a : "); + Serial.print(a); + Serial.print(" b : "); + Serial.println(b); + + switch (a) { + case 0: // off + ac_power_down(); + break; + case 1: // on + ac_activate(AC_TEMPERATURE, AC_FLOW); + break; + case 2: + if ( b == 0 | b == 1 ) { + ac_change_air_swing(b); + } + break; + case 3: // 1 : clean on, power on + if ( b == 0 | b == 1 ) { + ac_air_clean(b); + } + break; + case 4: + if ( 0 <= b && b <= 2 ) { + ac_activate(AC_TEMPERATURE, b); + } + break; + case 5: + if (18 <= b && b <= 30 ) { + ac_activate(b, AC_FLOW); + } + break; + case '+': + if ( 18 <= AC_TEMPERATURE && AC_TEMPERATURE <= 29 ) { + ac_activate((AC_TEMPERATURE + 1), AC_FLOW); + } + break; + case '-': + if ( 19 <= AC_TEMPERATURE && AC_TEMPERATURE <= 30 ) { + ac_activate((AC_TEMPERATURE - 1), AC_FLOW); + } + break; + case 'm': + /* + if ac is on, 1) turn off, 2) turn on ac_air_clean(1) + if ac is off, 1) turn on, 2) turn off ac_air_clean(0) + */ + if ( AC_POWER_ON == 1 ) { + ac_power_down(); + delay(100); + ac_air_clean(1); + } else { + if ( AC_AIR_ACLEAN == 1) { + ac_air_clean(0); + delay(100); + } + ac_activate(AC_TEMPERATURE, AC_FLOW); + } + break; + default: + if ( 18 <= a && a <= 30 ) { + if ( 0 <= b && b <= 2 ) { + ac_activate(a, b); + } + } + } + + o_r = r ; + } + delay(100); +} + + + +void receiveEvent(int howMany) +{ + a = Wire.read(); + b = Wire.read(); + r = !r ; +} + + diff --git a/examples/LGACSendDemo/LGACSendDemo.md b/examples/LGACSendDemo/LGACSendDemo.md new file mode 100644 index 000000000..1bff51f22 --- /dev/null +++ b/examples/LGACSendDemo/LGACSendDemo.md @@ -0,0 +1,35 @@ +1) Sample raw code : https://gist.github.com/chaeplin/ab2a7ad1533c41260f0d +2) send raw code : https://gist.github.com/chaeplin/7c800d3166463bb51be4 + + +=== *** === +- (1) : fixed +- (2) : fixed +- (3) : special(power, swing, air clean) +- (4) : change air flow, temperature +- (5) : temperature ( 15 + (5) = ) +- (6) : air flow +- (7) : crc ( 3 + 4 + 5 + 6 ) & B00001111 + +=== *** === + +| status | (1)| (2)| (3)| (4)| (5)| (6)| (7) +|----------------|----|----|----|----|----|----|---- +| on / 25 / mid |1000|1000|0000|0000|1010|0010|1100 +| on / 26 / mid |1000|1000|0000|0000|1011|0010|1101 +| on / 27 / mid |1000|1000|0000|0000|1100|0010|1110 +| on / 28 / mid |1000|1000|0000|0000|1101|0010|1111 +| on / 25 / high |1000|1000|0000|0000|1010|0100|1110 +| on / 26 / high |1000|1000|0000|0000|1011|0100|1111 +| on / 27 / high |1000|1000|0000|0000|1100|0100|0000 +| on / 28 / high |1000|1000|0000|0000|1101|0100|0001 +| 1 up |1000|1000|0000|1000|1101|0100|1001 +| Cool power |1000|1000|0001|0000|0000|1100|1101 +| energy saving |1000|1000|0001|0000|0000|0100|0101 +| power |1000|1000|0001|0000|0000|1000|1001 +| flow/up/down |1000|1000|0001|0011|0001|0100|1001 +| up/down off |1000|1000|0001|0011|0001|0101|1010 +| flow/left/right|1000|1000|0001|0011|0001|0110|1011 +| left/right off |1000|1000|0001|0011|0001|0111|1100 +| Air clean |1000|1000|1100|0000|0000|0000|1100 +| off |1000|1000|1100|0000|0000|0101|0001 \ No newline at end of file diff --git a/ir_LG.cpp b/ir_LG.cpp index 4e8dd82b6..ba532cb60 100644 --- a/ir_LG.cpp +++ b/ir_LG.cpp @@ -52,3 +52,29 @@ bool IRrecv::decodeLG (decode_results *results) } #endif +//+============================================================================= +#if SEND_LG +void IRsend::sendLG (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(38); + + // Header + mark(LG_HDR_MARK); + space(LG_HDR_SPACE); + mark(LG_BIT_MARK); + + // Data + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + space(LG_ONE_SPACE); + mark(LG_BIT_MARK); + } else { + space(LG_ZERO_SPACE); + mark(LG_BIT_MARK); + } + } + space(0); // Always end with the LED off +} +#endif + From d433744ec753d526bd10df30469fdc8594594423 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Mon, 24 Aug 2015 20:37:41 +0100 Subject: [PATCH 114/768] Update IRsendDemo.ino As written this example will cause issues with some IR receivers. On the face of it it sends teh sony signal burst 3 times with a 40ms gap. However, it really continues to send the sony signal forever with a 40ms gap. There needs to be a reasonable gap between signals sent & I have added in a 5 sec gap as a reasonable figure. Without a gap, many IR receivers will treat this signal as noise as it send continuous sony bursts with a 40 ms gap. --- examples/IRsendDemo/IRsendDemo.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/IRsendDemo/IRsendDemo.ino b/examples/IRsendDemo/IRsendDemo.ino index 4f51a578c..4f23af6cf 100644 --- a/examples/IRsendDemo/IRsendDemo.ino +++ b/examples/IRsendDemo/IRsendDemo.ino @@ -20,4 +20,5 @@ void loop() { irsend.sendSony(0xa90, 12); delay(40); } + delay(5000); //5 second delay between each signal burst } From e9d43f77514a548a969c932edfaeab6ab36674d8 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Mon, 24 Aug 2015 21:17:23 +0100 Subject: [PATCH 115/768] Create IRsendRawDemo As sendRaw is a very popular methos of sending unknown or AC signals, I though it would be very useful to include and example of same with the library. The code in this new example is tested and verified as working with the latest Master. --- examples/IRsendRawDemo | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 examples/IRsendRawDemo diff --git a/examples/IRsendRawDemo b/examples/IRsendRawDemo new file mode 100644 index 000000000..e83d6e6df --- /dev/null +++ b/examples/IRsendRawDemo @@ -0,0 +1,37 @@ +/* + * IRremote: IRsendRawDemo - demonstrates sending IR codes with sendRaw + * An IR LED must be connected to Arduino PWM pin 3. + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + * + * IRsendRawDemo - added by AnalysIR (via www.AnalysIR.com), 24 August 2015 + * + * This example shows how to send a RAW signal using the IRremote library. + * The example signal is actually a 32 bit NEC signal. + * Remote Control button: LGTV Power On/Off. + * Hex Value: 0x20DF10EF, 32 bits + * + * It is more efficient to use the sendNEC function to send NEC signals. + * Use of sendRaw here, serves only as an example of using the function. + * + */ + + +#include + +IRsend irsend; + +void setup() +{ + +} + +void loop() { + int khz = 38; // 38kHz carrier frequency for the NEC protocol + unsigned int irSignal[] = {9000, 4500, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 39416, 9000, 2210, 560}; //AnalysIR Batch Export (IRremote) - RAW + + irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); //Note the approach used to automatically calculate the size of the array. + + delay(5000); //In this example, the signal will be repeated every 5 seconds, approximately. +} From 61d0263c5b3bc176f59fbc29a9c2db437872a6f1 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Mon, 24 Aug 2015 21:21:46 +0100 Subject: [PATCH 116/768] Rename IRsendRawDemo to IRsendRawDemo.ino forgot to put .ino extension on file. now corrected --- examples/{IRsendRawDemo => IRsendRawDemo.ino} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{IRsendRawDemo => IRsendRawDemo.ino} (100%) diff --git a/examples/IRsendRawDemo b/examples/IRsendRawDemo.ino similarity index 100% rename from examples/IRsendRawDemo rename to examples/IRsendRawDemo.ino From 0abc9f090879595c43cba27e454b4859894d3cf1 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Mon, 24 Aug 2015 21:25:22 +0100 Subject: [PATCH 117/768] Create IRsendRawDemo.ino New example should go into new fordel of same name...sorry --- examples/IRsendRawDemo/IRsendRawDemo.ino | 37 ++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 examples/IRsendRawDemo/IRsendRawDemo.ino diff --git a/examples/IRsendRawDemo/IRsendRawDemo.ino b/examples/IRsendRawDemo/IRsendRawDemo.ino new file mode 100644 index 000000000..e83d6e6df --- /dev/null +++ b/examples/IRsendRawDemo/IRsendRawDemo.ino @@ -0,0 +1,37 @@ +/* + * IRremote: IRsendRawDemo - demonstrates sending IR codes with sendRaw + * An IR LED must be connected to Arduino PWM pin 3. + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + * + * IRsendRawDemo - added by AnalysIR (via www.AnalysIR.com), 24 August 2015 + * + * This example shows how to send a RAW signal using the IRremote library. + * The example signal is actually a 32 bit NEC signal. + * Remote Control button: LGTV Power On/Off. + * Hex Value: 0x20DF10EF, 32 bits + * + * It is more efficient to use the sendNEC function to send NEC signals. + * Use of sendRaw here, serves only as an example of using the function. + * + */ + + +#include + +IRsend irsend; + +void setup() +{ + +} + +void loop() { + int khz = 38; // 38kHz carrier frequency for the NEC protocol + unsigned int irSignal[] = {9000, 4500, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 39416, 9000, 2210, 560}; //AnalysIR Batch Export (IRremote) - RAW + + irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); //Note the approach used to automatically calculate the size of the array. + + delay(5000); //In this example, the signal will be repeated every 5 seconds, approximately. +} From 339a7969c9a900262b40812cf8a8ebb4d131de46 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Mon, 24 Aug 2015 21:26:08 +0100 Subject: [PATCH 118/768] Delete IRsendRawDemo.ino moved to own folder to maintain consistency with other examples --- examples/IRsendRawDemo.ino | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 examples/IRsendRawDemo.ino diff --git a/examples/IRsendRawDemo.ino b/examples/IRsendRawDemo.ino deleted file mode 100644 index e83d6e6df..000000000 --- a/examples/IRsendRawDemo.ino +++ /dev/null @@ -1,37 +0,0 @@ -/* - * IRremote: IRsendRawDemo - demonstrates sending IR codes with sendRaw - * An IR LED must be connected to Arduino PWM pin 3. - * Version 0.1 July, 2009 - * Copyright 2009 Ken Shirriff - * http://arcfn.com - * - * IRsendRawDemo - added by AnalysIR (via www.AnalysIR.com), 24 August 2015 - * - * This example shows how to send a RAW signal using the IRremote library. - * The example signal is actually a 32 bit NEC signal. - * Remote Control button: LGTV Power On/Off. - * Hex Value: 0x20DF10EF, 32 bits - * - * It is more efficient to use the sendNEC function to send NEC signals. - * Use of sendRaw here, serves only as an example of using the function. - * - */ - - -#include - -IRsend irsend; - -void setup() -{ - -} - -void loop() { - int khz = 38; // 38kHz carrier frequency for the NEC protocol - unsigned int irSignal[] = {9000, 4500, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 39416, 9000, 2210, 560}; //AnalysIR Batch Export (IRremote) - RAW - - irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); //Note the approach used to automatically calculate the size of the array. - - delay(5000); //In this example, the signal will be repeated every 5 seconds, approximately. -} From bd72084b7f2efc893f5364425a8eb110a6dd0e4e Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Tue, 25 Aug 2015 00:34:54 +0100 Subject: [PATCH 119/768] Bug fixes as per Issue #167 Have updated IRrecvDdump to fix bugs described in Issue: #167 In summary, removed bug where large space values were displayed incorrectly & confusing users. The output now always starts with a mark, instead of a space, which makes it easier to interpret and less confusing for users. refer to #167 for more detials. The update has been tested with several protocols (but not all) and verified as working. --- examples/IRrecvDump/IRrecvDump.ino | 35 ++++++++++++++++-------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/examples/IRrecvDump/IRrecvDump.ino b/examples/IRrecvDump/IRrecvDump.ino index abfef5488..90b47ba69 100644 --- a/examples/IRrecvDump/IRrecvDump.ino +++ b/examples/IRrecvDump/IRrecvDump.ino @@ -10,7 +10,12 @@ #include -int RECV_PIN = 11; +/* +* Default is Arduino pin D11. +* You can change this to another available Arduino Pin. +* Your IR receiver should be connected to the pin defined here +*/ +int RECV_PIN = 11; IRrecv irrecv(RECV_PIN); @@ -22,18 +27,17 @@ void setup() irrecv.enableIRIn(); // Start the receiver } -// Dumps out the decode_results structure. -// Call this after IRrecv::decode() -// void * to work around compiler issue -//void dump(void *v) { -// decode_results *results = (decode_results *)v + void dump(decode_results *results) { + // Dumps out the decode_results structure. + // Call this after IRrecv::decode() int count = results->rawlen; if (results->decode_type == UNKNOWN) { Serial.print("Unknown encoding: "); } else if (results->decode_type == NEC) { Serial.print("Decoded NEC: "); + } else if (results->decode_type == SONY) { Serial.print("Decoded SONY: "); @@ -46,21 +50,20 @@ void dump(decode_results *results) { } else if (results->decode_type == PANASONIC) { Serial.print("Decoded PANASONIC - Address: "); - Serial.print(results->address,HEX); + Serial.print(results->address, HEX); Serial.print(" Value: "); } else if (results->decode_type == LG) { - Serial.print("Decoded LG: "); + Serial.print("Decoded LG: "); } else if (results->decode_type == JVC) { - Serial.print("Decoded JVC: "); - + Serial.print("Decoded JVC: "); } else if (results->decode_type == AIWA_RC_T501) { Serial.print("Decoded AIWA RC T501: "); } else if (results->decode_type == WHYNTER) { - Serial.print("Decoded Whynter: "); + Serial.print("Decoded Whynter: "); } Serial.print(results->value, HEX); Serial.print(" ("); @@ -70,19 +73,19 @@ void dump(decode_results *results) { Serial.print(count, DEC); Serial.print("): "); - for (int i = 0; i < count; i++) { - if ((i % 2) == 1) { + for (int i = 1; i < count; i++) { + if (i & 1) { Serial.print(results->rawbuf[i]*USECPERTICK, DEC); } else { - Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); + Serial.write('-'); + Serial.print((unsigned long) results->rawbuf[i]*USECPERTICK, DEC); } Serial.print(" "); } - Serial.println(""); + Serial.println(); } - void loop() { if (irrecv.decode(&results)) { Serial.println(results.value, HEX); From 61f00b8dc5733698e9ebce60fc1a49a0f5a673d2 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Tue, 25 Aug 2015 01:00:56 +0100 Subject: [PATCH 120/768] Update IRrecvDumpV2.ino Fixed presentation & 2 bugs. Presentation: No longer display leading space in timings, as is confusing to users & essentially irrelevant. Bug Fix 1: rawData was starting with a space & would not work with sendRaw Bug Fix 2: chaned x from unsigned int to nsigend long to avoid potential overflow on integer multiplication. very similar to recent changes to IRrecDump #167 #207 --- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 38 ++++++++++++-------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index f29e74af6..3bea2f4a9 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -6,7 +6,7 @@ //------------------------------------------------------------------------------ // Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838) // -int recvPin = 6; +int recvPin = 11; IRrecv irrecv(recvPin); //+============================================================================= @@ -92,10 +92,9 @@ void dumpRaw (decode_results *results) Serial.print("Timing["); Serial.print(results->rawlen, DEC); Serial.println("]: "); - Serial.print(" -"); - Serial.println(results->rawbuf[0] * USECPERTICK, DEC); + for (int i = 1; i < results->rawlen; i++) { - unsigned int x = results->rawbuf[i] * USECPERTICK; + unsigned long x = results->rawbuf[i] * USECPERTICK; if (!(i & 1)) { // even Serial.print("-"); if (x < 1000) Serial.print(" ") ; @@ -109,7 +108,7 @@ void dumpRaw (decode_results *results) Serial.print(x, DEC); Serial.print(", "); } - if (!(i%8)) Serial.println(""); + if (!(i % 8)) Serial.println(""); } Serial.println(""); // Newline } @@ -126,10 +125,10 @@ void dumpCode (decode_results *results) Serial.print("] = {"); // Start declaration // Dump data - for (int i = 0; i < results->rawlen; i++) { + for (int i = 1; i < results->rawlen; i++) { Serial.print(results->rawbuf[i] * USECPERTICK, DEC); Serial.print(","); - if (!(i&1)) Serial.print(" "); + if (!(i & 1)) Serial.print(" "); } // End declaration @@ -143,17 +142,17 @@ void dumpCode (decode_results *results) // Newline Serial.println(""); - + // Now dump "known" codes if (results->decode_type != UNKNOWN) { - + // Some protocols have an address if (results->decode_type == PANASONIC) { Serial.print("unsigned int addr = 0x"); Serial.print(results->address, HEX); Serial.println(";"); } - + // All protocols have data Serial.print("unsigned int data = 0x"); Serial.print(results->value, HEX); @@ -166,14 +165,13 @@ void dumpCode (decode_results *results) // void loop ( ) { - decode_results results; // Somewhere to store the results - - if (irrecv.decode(&results)) { // Grab an IR code - dumpInfo(&results); // Output the results - dumpRaw(&results); // Output the results in RAW format - dumpCode(&results); // Output the results as source code - Serial.println(""); // Blank line between entries - irrecv.resume(); // Prepare for the next value - } + decode_results results; // Somewhere to store the results + + if (irrecv.decode(&results)) { // Grab an IR code + dumpInfo(&results); // Output the results + dumpRaw(&results); // Output the results in RAW format + dumpCode(&results); // Output the results as source code + Serial.println(""); // Blank line between entries + irrecv.resume(); // Prepare for the next value + } } - From 0bf5993a5b33e2f4edae6f492d115a248fbd6bfe Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Wed, 26 Aug 2015 16:14:26 -0600 Subject: [PATCH 121/768] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ec1aecc0c..9dee657a1 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more inf 2. Download the latest release. 3. Extract the zip file 4. Move the "IRremote" folder that has been extracted to your libraries directory. +5. Make sure to delete Arduino_Root/libraries/RobotIRRemote. Where Arduino_Root refers to the install directory of Arduino. The library RobotIRRemote has similar definitions to IRremote and causes errors. ## Usage - TODO (Check examples for now) From bce86bf8ed629487e44526cadde42d9cedec3542 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Wed, 26 Aug 2015 16:16:26 -0600 Subject: [PATCH 122/768] corrected a typo --- IRremote.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRremote.h b/IRremote.h index ce404a686..4af944a44 100644 --- a/IRremote.h +++ b/IRremote.h @@ -324,7 +324,7 @@ class IRsend void sendDenon (unsigned long data, int nbits) ; # endif //...................................................................... -# if SEND_Pronto +# if SEND_PRONTO void sendPronto (char* code, bool repeat, bool fallback) ; # endif } ; From df3439696938ecc8b5ba69f35c15b47e205568f2 Mon Sep 17 00:00:00 2001 From: chaeplin Date: Thu, 27 Aug 2015 20:55:40 +0900 Subject: [PATCH 123/768] heating --- examples/LGACSendDemo/LGACSendDemo.md | 84 ++++++++++++++++++++------- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/examples/LGACSendDemo/LGACSendDemo.md b/examples/LGACSendDemo/LGACSendDemo.md index 1bff51f22..3fe73c606 100644 --- a/examples/LGACSendDemo/LGACSendDemo.md +++ b/examples/LGACSendDemo/LGACSendDemo.md @@ -3,33 +3,75 @@ === *** === +- (0) : Cooling or Heating - (1) : fixed - (2) : fixed - (3) : special(power, swing, air clean) -- (4) : change air flow, temperature +- (4) : change air flow, temperature, coolingi(0)/heating(4) - (5) : temperature ( 15 + (5) = ) - (6) : air flow - (7) : crc ( 3 + 4 + 5 + 6 ) & B00001111 + +°F = °C × 1.8 + 32 +°C = (°F − 32) / 1.8 + + === *** === +* remote / Korea / without heating +| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) +|----------------|---|----|----|----|----|----|----|---- +| on / 25 / mid | C |1000|1000|0000|0000|1010|0010|1100 +| on / 26 / mid | C |1000|1000|0000|0000|1011|0010|1101 +| on / 27 / mid | C |1000|1000|0000|0000|1100|0010|1110 +| on / 28 / mid | C |1000|1000|0000|0000|1101|0010|1111 +| on / 25 / high | C |1000|1000|0000|0000|1010|0100|1110 +| on / 26 / high | C |1000|1000|0000|0000|1011|0100|1111 +| on / 27 / high | C |1000|1000|0000|0000|1100|0100|0000 +| on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001 +| 1 up | C |1000|1000|0000|1000|1101|0100|1001 +| Cool power | C |1000|1000|0001|0000|0000|1100|1101 +| energy saving | C |1000|1000|0001|0000|0000|0100|0101 +| power | C |1000|1000|0001|0000|0000|1000|1001 +| flow/up/down | C |1000|1000|0001|0011|0001|0100|1001 +| up/down off | C |1000|1000|0001|0011|0001|0101|1010 +| flow/left/right| C |1000|1000|0001|0011|0001|0110|1011 +| left/right off | C |1000|1000|0001|0011|0001|0111|1100 +| Air clean | C |1000|1000|1100|0000|0000|0000|1100 +| off | C |1000|1000|1100|0000|0000|0101|0001 + + + +* remote / with heating +* converted from raw code at https://github.com/chaeplin/RaspAC/blob/master/lircd.conf + +| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) +|----------------|---|----|----|----|----|----|----|---- +| on | C |1000|1000|0000|0000|1011|0010|1101 +| of | C |1000|1000|1100|0000|0000|0101|0001 +|----------------|---|----|----|----|----|----|----|---- +| 64 | C |1000|1000|0000|0000|0011|0100|0111 +| 66 | C |1000|1000|0000|0000|0100|0100|1000 +| 68 | C |1000|1000|0000|0000|0101|0100|1001 +| 70 | C |1000|1000|0000|0000|0110|0100|1010 +| 72 | C |1000|1000|0000|0000|0111|0100|1011 +| 74 | C |1000|1000|0000|0000|1000|0100|1100 +| 76 | C |1000|1000|0000|0000|1010|0100|1110 +| 78 | C |1000|1000|0000|0000|1011|0100|1111 +| 80 | C |1000|1000|0000|0000|1100|0100|0000 +| 82 | C |1000|1000|0000|0000|1101|0100|0001 +| 84 | C |1000|1000|0000|0000|1110|0100|0010 +| 86 | C |1000|1000|0000|0000|1111|0100|0011 +| heat64 | H |1000|1000|0000|0100|0011|0100|1011 +| heat66 | H |1000|1000|0000|0100|0100|0100|1100 +| heat68 | H |1000|1000|0000|0100|0101|0100|1101 +| heat70 | H |1000|1000|0000|0100|0110|0100|1110 +| heat72 | H |1000|1000|0000|0100|0111|0100|1111 +| heat74 | H |1000|1000|0000|0100|1000|0100|0000 +| heat76 | H |1000|1000|0000|0100|1001|0100|0001 +| heat78 | H |1000|1000|0000|0100|1011|0100|0011 +| heat80 | H |1000|1000|0000|0100|1100|0100|0100 +| heat82 | H |1000|1000|0000|0100|1101|0100|0101 +| heat84 | H |1000|1000|0000|0100|1110|0100|0110 +| heat86 | H |1000|1000|0000|0100|1111|0100|0111 -| status | (1)| (2)| (3)| (4)| (5)| (6)| (7) -|----------------|----|----|----|----|----|----|---- -| on / 25 / mid |1000|1000|0000|0000|1010|0010|1100 -| on / 26 / mid |1000|1000|0000|0000|1011|0010|1101 -| on / 27 / mid |1000|1000|0000|0000|1100|0010|1110 -| on / 28 / mid |1000|1000|0000|0000|1101|0010|1111 -| on / 25 / high |1000|1000|0000|0000|1010|0100|1110 -| on / 26 / high |1000|1000|0000|0000|1011|0100|1111 -| on / 27 / high |1000|1000|0000|0000|1100|0100|0000 -| on / 28 / high |1000|1000|0000|0000|1101|0100|0001 -| 1 up |1000|1000|0000|1000|1101|0100|1001 -| Cool power |1000|1000|0001|0000|0000|1100|1101 -| energy saving |1000|1000|0001|0000|0000|0100|0101 -| power |1000|1000|0001|0000|0000|1000|1001 -| flow/up/down |1000|1000|0001|0011|0001|0100|1001 -| up/down off |1000|1000|0001|0011|0001|0101|1010 -| flow/left/right|1000|1000|0001|0011|0001|0110|1011 -| left/right off |1000|1000|0001|0011|0001|0111|1100 -| Air clean |1000|1000|1100|0000|0000|0000|1100 -| off |1000|1000|1100|0000|0000|0101|0001 \ No newline at end of file From e6bcf89664bcb7d6eb15c01232165fa01558eacc Mon Sep 17 00:00:00 2001 From: chaeplin Date: Thu, 27 Aug 2015 20:58:00 +0900 Subject: [PATCH 124/768] Revert "heating" This reverts commit df3439696938ecc8b5ba69f35c15b47e205568f2. --- examples/LGACSendDemo/LGACSendDemo.md | 84 +++++++-------------------- 1 file changed, 21 insertions(+), 63 deletions(-) diff --git a/examples/LGACSendDemo/LGACSendDemo.md b/examples/LGACSendDemo/LGACSendDemo.md index 3fe73c606..1bff51f22 100644 --- a/examples/LGACSendDemo/LGACSendDemo.md +++ b/examples/LGACSendDemo/LGACSendDemo.md @@ -3,75 +3,33 @@ === *** === -- (0) : Cooling or Heating - (1) : fixed - (2) : fixed - (3) : special(power, swing, air clean) -- (4) : change air flow, temperature, coolingi(0)/heating(4) +- (4) : change air flow, temperature - (5) : temperature ( 15 + (5) = ) - (6) : air flow - (7) : crc ( 3 + 4 + 5 + 6 ) & B00001111 - -°F = °C × 1.8 + 32 -°C = (°F − 32) / 1.8 - - === *** === -* remote / Korea / without heating -| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) -|----------------|---|----|----|----|----|----|----|---- -| on / 25 / mid | C |1000|1000|0000|0000|1010|0010|1100 -| on / 26 / mid | C |1000|1000|0000|0000|1011|0010|1101 -| on / 27 / mid | C |1000|1000|0000|0000|1100|0010|1110 -| on / 28 / mid | C |1000|1000|0000|0000|1101|0010|1111 -| on / 25 / high | C |1000|1000|0000|0000|1010|0100|1110 -| on / 26 / high | C |1000|1000|0000|0000|1011|0100|1111 -| on / 27 / high | C |1000|1000|0000|0000|1100|0100|0000 -| on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001 -| 1 up | C |1000|1000|0000|1000|1101|0100|1001 -| Cool power | C |1000|1000|0001|0000|0000|1100|1101 -| energy saving | C |1000|1000|0001|0000|0000|0100|0101 -| power | C |1000|1000|0001|0000|0000|1000|1001 -| flow/up/down | C |1000|1000|0001|0011|0001|0100|1001 -| up/down off | C |1000|1000|0001|0011|0001|0101|1010 -| flow/left/right| C |1000|1000|0001|0011|0001|0110|1011 -| left/right off | C |1000|1000|0001|0011|0001|0111|1100 -| Air clean | C |1000|1000|1100|0000|0000|0000|1100 -| off | C |1000|1000|1100|0000|0000|0101|0001 - - - -* remote / with heating -* converted from raw code at https://github.com/chaeplin/RaspAC/blob/master/lircd.conf - -| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) -|----------------|---|----|----|----|----|----|----|---- -| on | C |1000|1000|0000|0000|1011|0010|1101 -| of | C |1000|1000|1100|0000|0000|0101|0001 -|----------------|---|----|----|----|----|----|----|---- -| 64 | C |1000|1000|0000|0000|0011|0100|0111 -| 66 | C |1000|1000|0000|0000|0100|0100|1000 -| 68 | C |1000|1000|0000|0000|0101|0100|1001 -| 70 | C |1000|1000|0000|0000|0110|0100|1010 -| 72 | C |1000|1000|0000|0000|0111|0100|1011 -| 74 | C |1000|1000|0000|0000|1000|0100|1100 -| 76 | C |1000|1000|0000|0000|1010|0100|1110 -| 78 | C |1000|1000|0000|0000|1011|0100|1111 -| 80 | C |1000|1000|0000|0000|1100|0100|0000 -| 82 | C |1000|1000|0000|0000|1101|0100|0001 -| 84 | C |1000|1000|0000|0000|1110|0100|0010 -| 86 | C |1000|1000|0000|0000|1111|0100|0011 -| heat64 | H |1000|1000|0000|0100|0011|0100|1011 -| heat66 | H |1000|1000|0000|0100|0100|0100|1100 -| heat68 | H |1000|1000|0000|0100|0101|0100|1101 -| heat70 | H |1000|1000|0000|0100|0110|0100|1110 -| heat72 | H |1000|1000|0000|0100|0111|0100|1111 -| heat74 | H |1000|1000|0000|0100|1000|0100|0000 -| heat76 | H |1000|1000|0000|0100|1001|0100|0001 -| heat78 | H |1000|1000|0000|0100|1011|0100|0011 -| heat80 | H |1000|1000|0000|0100|1100|0100|0100 -| heat82 | H |1000|1000|0000|0100|1101|0100|0101 -| heat84 | H |1000|1000|0000|0100|1110|0100|0110 -| heat86 | H |1000|1000|0000|0100|1111|0100|0111 +| status | (1)| (2)| (3)| (4)| (5)| (6)| (7) +|----------------|----|----|----|----|----|----|---- +| on / 25 / mid |1000|1000|0000|0000|1010|0010|1100 +| on / 26 / mid |1000|1000|0000|0000|1011|0010|1101 +| on / 27 / mid |1000|1000|0000|0000|1100|0010|1110 +| on / 28 / mid |1000|1000|0000|0000|1101|0010|1111 +| on / 25 / high |1000|1000|0000|0000|1010|0100|1110 +| on / 26 / high |1000|1000|0000|0000|1011|0100|1111 +| on / 27 / high |1000|1000|0000|0000|1100|0100|0000 +| on / 28 / high |1000|1000|0000|0000|1101|0100|0001 +| 1 up |1000|1000|0000|1000|1101|0100|1001 +| Cool power |1000|1000|0001|0000|0000|1100|1101 +| energy saving |1000|1000|0001|0000|0000|0100|0101 +| power |1000|1000|0001|0000|0000|1000|1001 +| flow/up/down |1000|1000|0001|0011|0001|0100|1001 +| up/down off |1000|1000|0001|0011|0001|0101|1010 +| flow/left/right|1000|1000|0001|0011|0001|0110|1011 +| left/right off |1000|1000|0001|0011|0001|0111|1100 +| Air clean |1000|1000|1100|0000|0000|0000|1100 +| off |1000|1000|1100|0000|0000|0101|0001 \ No newline at end of file From b4c8e6b22c155a4e8b1bd10d36ea841f3d205161 Mon Sep 17 00:00:00 2001 From: chaeplin Date: Thu, 27 Aug 2015 20:58:38 +0900 Subject: [PATCH 125/768] Revert "Revert "heating"" This reverts commit e6bcf89664bcb7d6eb15c01232165fa01558eacc. --- examples/LGACSendDemo/LGACSendDemo.md | 84 ++++++++++++++++++++------- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/examples/LGACSendDemo/LGACSendDemo.md b/examples/LGACSendDemo/LGACSendDemo.md index 1bff51f22..3fe73c606 100644 --- a/examples/LGACSendDemo/LGACSendDemo.md +++ b/examples/LGACSendDemo/LGACSendDemo.md @@ -3,33 +3,75 @@ === *** === +- (0) : Cooling or Heating - (1) : fixed - (2) : fixed - (3) : special(power, swing, air clean) -- (4) : change air flow, temperature +- (4) : change air flow, temperature, coolingi(0)/heating(4) - (5) : temperature ( 15 + (5) = ) - (6) : air flow - (7) : crc ( 3 + 4 + 5 + 6 ) & B00001111 + +°F = °C × 1.8 + 32 +°C = (°F − 32) / 1.8 + + === *** === +* remote / Korea / without heating +| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) +|----------------|---|----|----|----|----|----|----|---- +| on / 25 / mid | C |1000|1000|0000|0000|1010|0010|1100 +| on / 26 / mid | C |1000|1000|0000|0000|1011|0010|1101 +| on / 27 / mid | C |1000|1000|0000|0000|1100|0010|1110 +| on / 28 / mid | C |1000|1000|0000|0000|1101|0010|1111 +| on / 25 / high | C |1000|1000|0000|0000|1010|0100|1110 +| on / 26 / high | C |1000|1000|0000|0000|1011|0100|1111 +| on / 27 / high | C |1000|1000|0000|0000|1100|0100|0000 +| on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001 +| 1 up | C |1000|1000|0000|1000|1101|0100|1001 +| Cool power | C |1000|1000|0001|0000|0000|1100|1101 +| energy saving | C |1000|1000|0001|0000|0000|0100|0101 +| power | C |1000|1000|0001|0000|0000|1000|1001 +| flow/up/down | C |1000|1000|0001|0011|0001|0100|1001 +| up/down off | C |1000|1000|0001|0011|0001|0101|1010 +| flow/left/right| C |1000|1000|0001|0011|0001|0110|1011 +| left/right off | C |1000|1000|0001|0011|0001|0111|1100 +| Air clean | C |1000|1000|1100|0000|0000|0000|1100 +| off | C |1000|1000|1100|0000|0000|0101|0001 + + + +* remote / with heating +* converted from raw code at https://github.com/chaeplin/RaspAC/blob/master/lircd.conf + +| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) +|----------------|---|----|----|----|----|----|----|---- +| on | C |1000|1000|0000|0000|1011|0010|1101 +| of | C |1000|1000|1100|0000|0000|0101|0001 +|----------------|---|----|----|----|----|----|----|---- +| 64 | C |1000|1000|0000|0000|0011|0100|0111 +| 66 | C |1000|1000|0000|0000|0100|0100|1000 +| 68 | C |1000|1000|0000|0000|0101|0100|1001 +| 70 | C |1000|1000|0000|0000|0110|0100|1010 +| 72 | C |1000|1000|0000|0000|0111|0100|1011 +| 74 | C |1000|1000|0000|0000|1000|0100|1100 +| 76 | C |1000|1000|0000|0000|1010|0100|1110 +| 78 | C |1000|1000|0000|0000|1011|0100|1111 +| 80 | C |1000|1000|0000|0000|1100|0100|0000 +| 82 | C |1000|1000|0000|0000|1101|0100|0001 +| 84 | C |1000|1000|0000|0000|1110|0100|0010 +| 86 | C |1000|1000|0000|0000|1111|0100|0011 +| heat64 | H |1000|1000|0000|0100|0011|0100|1011 +| heat66 | H |1000|1000|0000|0100|0100|0100|1100 +| heat68 | H |1000|1000|0000|0100|0101|0100|1101 +| heat70 | H |1000|1000|0000|0100|0110|0100|1110 +| heat72 | H |1000|1000|0000|0100|0111|0100|1111 +| heat74 | H |1000|1000|0000|0100|1000|0100|0000 +| heat76 | H |1000|1000|0000|0100|1001|0100|0001 +| heat78 | H |1000|1000|0000|0100|1011|0100|0011 +| heat80 | H |1000|1000|0000|0100|1100|0100|0100 +| heat82 | H |1000|1000|0000|0100|1101|0100|0101 +| heat84 | H |1000|1000|0000|0100|1110|0100|0110 +| heat86 | H |1000|1000|0000|0100|1111|0100|0111 -| status | (1)| (2)| (3)| (4)| (5)| (6)| (7) -|----------------|----|----|----|----|----|----|---- -| on / 25 / mid |1000|1000|0000|0000|1010|0010|1100 -| on / 26 / mid |1000|1000|0000|0000|1011|0010|1101 -| on / 27 / mid |1000|1000|0000|0000|1100|0010|1110 -| on / 28 / mid |1000|1000|0000|0000|1101|0010|1111 -| on / 25 / high |1000|1000|0000|0000|1010|0100|1110 -| on / 26 / high |1000|1000|0000|0000|1011|0100|1111 -| on / 27 / high |1000|1000|0000|0000|1100|0100|0000 -| on / 28 / high |1000|1000|0000|0000|1101|0100|0001 -| 1 up |1000|1000|0000|1000|1101|0100|1001 -| Cool power |1000|1000|0001|0000|0000|1100|1101 -| energy saving |1000|1000|0001|0000|0000|0100|0101 -| power |1000|1000|0001|0000|0000|1000|1001 -| flow/up/down |1000|1000|0001|0011|0001|0100|1001 -| up/down off |1000|1000|0001|0011|0001|0101|1010 -| flow/left/right|1000|1000|0001|0011|0001|0110|1011 -| left/right off |1000|1000|0001|0011|0001|0111|1100 -| Air clean |1000|1000|1100|0000|0000|0000|1100 -| off |1000|1000|1100|0000|0000|0101|0001 \ No newline at end of file From 3fcb071d36eacb6d31d6ff6868e179a26a25adf6 Mon Sep 17 00:00:00 2001 From: chaeplin Date: Thu, 27 Aug 2015 21:01:26 +0900 Subject: [PATCH 126/768] heating --- examples/LGACSendDemo/LGACSendDemo.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/LGACSendDemo/LGACSendDemo.md b/examples/LGACSendDemo/LGACSendDemo.md index 3fe73c606..4ed3042a9 100644 --- a/examples/LGACSendDemo/LGACSendDemo.md +++ b/examples/LGACSendDemo/LGACSendDemo.md @@ -1,5 +1,6 @@ -1) Sample raw code : https://gist.github.com/chaeplin/ab2a7ad1533c41260f0d -2) send raw code : https://gist.github.com/chaeplin/7c800d3166463bb51be4 +=== *** === +- 1) Sample raw code : https://gist.github.com/chaeplin/ab2a7ad1533c41260f0d +- 2) send raw code : https://gist.github.com/chaeplin/7c800d3166463bb51be4 === *** === @@ -19,6 +20,7 @@ === *** === * remote / Korea / without heating + | status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) |----------------|---|----|----|----|----|----|----|---- | on / 25 / mid | C |1000|1000|0000|0000|1010|0010|1100 @@ -28,7 +30,8 @@ | on / 25 / high | C |1000|1000|0000|0000|1010|0100|1110 | on / 26 / high | C |1000|1000|0000|0000|1011|0100|1111 | on / 27 / high | C |1000|1000|0000|0000|1100|0100|0000 -| on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001 +| on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001 +|----------------|---|----|----|----|----|----|----|---- | 1 up | C |1000|1000|0000|1000|1101|0100|1001 | Cool power | C |1000|1000|0001|0000|0000|1100|1101 | energy saving | C |1000|1000|0001|0000|0000|0100|0101 @@ -74,4 +77,3 @@ | heat82 | H |1000|1000|0000|0100|1101|0100|0101 | heat84 | H |1000|1000|0000|0100|1110|0100|0110 | heat86 | H |1000|1000|0000|0100|1111|0100|0111 - From d8bdbb1a4417aab210ac23b76f4bbcf769674f92 Mon Sep 17 00:00:00 2001 From: chaeplin Date: Thu, 27 Aug 2015 21:04:34 +0900 Subject: [PATCH 127/768] typo --- examples/LGACSendDemo/LGACSendDemo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/LGACSendDemo/LGACSendDemo.md b/examples/LGACSendDemo/LGACSendDemo.md index 4ed3042a9..230701ad5 100644 --- a/examples/LGACSendDemo/LGACSendDemo.md +++ b/examples/LGACSendDemo/LGACSendDemo.md @@ -8,7 +8,7 @@ - (1) : fixed - (2) : fixed - (3) : special(power, swing, air clean) -- (4) : change air flow, temperature, coolingi(0)/heating(4) +- (4) : change air flow, temperature, cooling(0)/heating(4) - (5) : temperature ( 15 + (5) = ) - (6) : air flow - (7) : crc ( 3 + 4 + 5 + 6 ) & B00001111 From d87707d0ec9a4f22b1c1021880a6b853a9dfcad3 Mon Sep 17 00:00:00 2001 From: chaeplin Date: Thu, 27 Aug 2015 21:09:30 +0900 Subject: [PATCH 128/768] add heating --- examples/LGACSendDemo/LGACSendDemo.ino | 28 ++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/examples/LGACSendDemo/LGACSendDemo.ino b/examples/LGACSendDemo/LGACSendDemo.ino index 66d5025d8..8dfb804b0 100644 --- a/examples/LGACSendDemo/LGACSendDemo.ino +++ b/examples/LGACSendDemo/LGACSendDemo.ino @@ -10,6 +10,11 @@ IRrecv irrecv (RECV_PIN); const int AC_TYPE = 0; // 0 : TOWER // 1 : WALL +// + +const int AC_HEAT = 0; +// 0 : cooling +// 1 : heating int AC_POWER_ON = 0; // 0 : off @@ -27,6 +32,8 @@ int AC_FLOW = 1; // 1 : mid // 2 : high // if AC_TYPE =1, 3 : change +// + const int AC_FLOW_TOWER[3] = {0, 4, 6}; const int AC_FLOW_WALL[4] = {0, 2, 4, 5}; @@ -54,7 +61,12 @@ void ac_activate(int temperature, int air_flow) int AC_MSBITS1 = 8; int AC_MSBITS2 = 8; int AC_MSBITS3 = 0; - int AC_MSBITS4 = 0; + int AC_MSBITS4 ; + if ( AC_HEAT == 1 ) { + AC_MSBITS4 = 4; + } else { + AC_MSBITS4 = 0; + } int AC_MSBITS5 = temperature - 15; int AC_MSBITS6 ; @@ -131,13 +143,13 @@ void setup() Serial.println(" - - - T E S T - - - "); -/* test - ac_activate(25, 1); - delay(5000); - ac_activate(27, 2); - delay(5000); + /* test + ac_activate(25, 1); + delay(5000); + ac_activate(27, 2); + delay(5000); -*/ + */ } void loop() @@ -149,7 +161,7 @@ void loop() ac_activate(27, 0); delay(5000); - + if ( r != o_r) { /* From 0ef30ed2275ff623c5502a3331adca9ad832976c Mon Sep 17 00:00:00 2001 From: chaeplin Date: Fri, 28 Aug 2015 03:36:26 +0900 Subject: [PATCH 129/768] Fahrenheit --- examples/LGACSendDemo/LGACSendDemo.ino | 6 ++-- examples/LGACSendDemo/LGACSendDemo.md | 39 +++++++++++++++----------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/examples/LGACSendDemo/LGACSendDemo.ino b/examples/LGACSendDemo/LGACSendDemo.ino index 8dfb804b0..da5db37eb 100644 --- a/examples/LGACSendDemo/LGACSendDemo.ino +++ b/examples/LGACSendDemo/LGACSendDemo.ino @@ -12,7 +12,7 @@ const int AC_TYPE = 0; // 1 : WALL // -const int AC_HEAT = 0; +int AC_HEAT = 0; // 0 : cooling // 1 : heating @@ -63,8 +63,10 @@ void ac_activate(int temperature, int air_flow) int AC_MSBITS3 = 0; int AC_MSBITS4 ; if ( AC_HEAT == 1 ) { + // heating AC_MSBITS4 = 4; } else { + // cooling AC_MSBITS4 = 0; } int AC_MSBITS5 = temperature - 15; @@ -165,7 +167,7 @@ void loop() if ( r != o_r) { /* - # a : mode or temp b : air_flow, temp, swing, clean + # a : mode or temp b : air_flow, temp, swing, clean, cooling/heating # 18 ~ 30 : temp 0 ~ 2 : flow // on # 0 : off 0 # 1 : on 0 diff --git a/examples/LGACSendDemo/LGACSendDemo.md b/examples/LGACSendDemo/LGACSendDemo.md index 230701ad5..7f859d149 100644 --- a/examples/LGACSendDemo/LGACSendDemo.md +++ b/examples/LGACSendDemo/LGACSendDemo.md @@ -32,39 +32,44 @@ | on / 27 / high | C |1000|1000|0000|0000|1100|0100|0000 | on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001 |----------------|---|----|----|----|----|----|----|---- -| 1 up | C |1000|1000|0000|1000|1101|0100|1001 +| 1 up | C |1000|1000|0000|1000|1101|0100|1001 +|----------------|---|----|----|----|----|----|----|---- | Cool power | C |1000|1000|0001|0000|0000|1100|1101 | energy saving | C |1000|1000|0001|0000|0000|0100|0101 | power | C |1000|1000|0001|0000|0000|1000|1001 | flow/up/down | C |1000|1000|0001|0011|0001|0100|1001 | up/down off | C |1000|1000|0001|0011|0001|0101|1010 | flow/left/right| C |1000|1000|0001|0011|0001|0110|1011 -| left/right off | C |1000|1000|0001|0011|0001|0111|1100 -| Air clean | C |1000|1000|1100|0000|0000|0000|1100 +| left/right off | C |1000|1000|0001|0011|0001|0111|1100 +|----------------|---|----|----|----|----|----|----|---- +| Air clean | C |1000|1000|1100|0000|0000|0000|1100 +|----------------|---|----|----|----|----|----|----|---- | off | C |1000|1000|1100|0000|0000|0101|0001 * remote / with heating -* converted from raw code at https://github.com/chaeplin/RaspAC/blob/master/lircd.conf +* converted using raw code at https://github.com/chaeplin/RaspAC/blob/master/lircd.conf | status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) |----------------|---|----|----|----|----|----|----|---- | on | C |1000|1000|0000|0000|1011|0010|1101 -| of | C |1000|1000|1100|0000|0000|0101|0001 |----------------|---|----|----|----|----|----|----|---- -| 64 | C |1000|1000|0000|0000|0011|0100|0111 -| 66 | C |1000|1000|0000|0000|0100|0100|1000 -| 68 | C |1000|1000|0000|0000|0101|0100|1001 -| 70 | C |1000|1000|0000|0000|0110|0100|1010 -| 72 | C |1000|1000|0000|0000|0111|0100|1011 -| 74 | C |1000|1000|0000|0000|1000|0100|1100 -| 76 | C |1000|1000|0000|0000|1010|0100|1110 -| 78 | C |1000|1000|0000|0000|1011|0100|1111 -| 80 | C |1000|1000|0000|0000|1100|0100|0000 -| 82 | C |1000|1000|0000|0000|1101|0100|0001 -| 84 | C |1000|1000|0000|0000|1110|0100|0010 -| 86 | C |1000|1000|0000|0000|1111|0100|0011 +| off | C |1000|1000|1100|0000|0000|0101|0001 +|----------------|---|----|----|----|----|----|----|---- +| 64 / 18 | C |1000|1000|0000|0000|0011|0100|0111 +| 66 / 19 | C |1000|1000|0000|0000|0100|0100|1000 +| 68 / 20 | C |1000|1000|0000|0000|0101|0100|1001 +| 70 / 21 | C |1000|1000|0000|0000|0110|0100|1010 +| 72 / 22 | C |1000|1000|0000|0000|0111|0100|1011 +| 74 / 23 | C |1000|1000|0000|0000|1000|0100|1100 +| 76 / 25 | C |1000|1000|0000|0000|1010|0100|1110 +| 78 / 26 | C |1000|1000|0000|0000|1011|0100|1111 +| 80 / 27 | C |1000|1000|0000|0000|1100|0100|0000 +| 82 / 28 | C |1000|1000|0000|0000|1101|0100|0001 +| 84 / 29 | C |1000|1000|0000|0000|1110|0100|0010 +| 86 / 20 | C |1000|1000|0000|0000|1111|0100|0011 +|----------------|---|----|----|----|----|----|----|---- | heat64 | H |1000|1000|0000|0100|0011|0100|1011 | heat66 | H |1000|1000|0000|0100|0100|0100|1100 | heat68 | H |1000|1000|0000|0100|0101|0100|1101 From 27777e89b2d50c58a1d1aea15ae609a8d53acc6e Mon Sep 17 00:00:00 2001 From: chaeplin Date: Fri, 28 Aug 2015 04:02:47 +0900 Subject: [PATCH 130/768] decoding for LG A/C --- examples/LGACSendDemo/LGACSendDemo.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/LGACSendDemo/LGACSendDemo.md b/examples/LGACSendDemo/LGACSendDemo.md index 7f859d149..c82a22b53 100644 --- a/examples/LGACSendDemo/LGACSendDemo.md +++ b/examples/LGACSendDemo/LGACSendDemo.md @@ -1,3 +1,12 @@ +=== decoding for LG A/C ==== +- 1) remote of LG AC has two type of HDR mark/space, 8000/4000 and 3100/10000 +- 2) HDR 8000/4000 is decoded using decodeLG(IRrecvDumpV2) without problem +- 3) for HDR 3100/10000, use AnalysIR's code : http://www.analysir.com/blog/2014/03/19/air-conditioners-problems-recording-long-infrared-remote-control-signals-arduino/ +- 4) for bin output based on AnalysIR's code : https://gist.github.com/chaeplin/a3a4b4b6b887c663bfe8 +- 5) remove first two byte(11) +- 6) sample rawcode with bin output : https://gist.github.com/chaeplin/134d232e0b8cfb898860 + + === *** === - 1) Sample raw code : https://gist.github.com/chaeplin/ab2a7ad1533c41260f0d - 2) send raw code : https://gist.github.com/chaeplin/7c800d3166463bb51be4 From a237a0e393ef5846c47d26a6138fa0590e446ec8 Mon Sep 17 00:00:00 2001 From: chaeplin Date: Fri, 28 Aug 2015 04:15:04 +0900 Subject: [PATCH 131/768] typo 86 / 30 --- examples/LGACSendDemo/LGACSendDemo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/LGACSendDemo/LGACSendDemo.md b/examples/LGACSendDemo/LGACSendDemo.md index c82a22b53..62c707316 100644 --- a/examples/LGACSendDemo/LGACSendDemo.md +++ b/examples/LGACSendDemo/LGACSendDemo.md @@ -77,7 +77,7 @@ | 80 / 27 | C |1000|1000|0000|0000|1100|0100|0000 | 82 / 28 | C |1000|1000|0000|0000|1101|0100|0001 | 84 / 29 | C |1000|1000|0000|0000|1110|0100|0010 -| 86 / 20 | C |1000|1000|0000|0000|1111|0100|0011 +| 86 / 30 | C |1000|1000|0000|0000|1111|0100|0011 |----------------|---|----|----|----|----|----|----|---- | heat64 | H |1000|1000|0000|0100|0011|0100|1011 | heat66 | H |1000|1000|0000|0100|0100|0100|1100 From f985c4b318b0742310b83ad72204896d971b03c6 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Fri, 28 Aug 2015 15:56:18 +0100 Subject: [PATCH 132/768] Update IRrecvDumpV2.ino - Cleaned up layout of output, removed trailing commas - buffer sizes are now correct - no need to add 0 for space at end, as sendRAW takes care of this --- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index 3bea2f4a9..cbfadccec 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -90,7 +90,7 @@ void dumpRaw (decode_results *results) { // Print Raw data Serial.print("Timing["); - Serial.print(results->rawlen, DEC); + Serial.print(results->rawlen-1, DEC); Serial.println("]: "); for (int i = 1; i < results->rawlen; i++) { @@ -106,7 +106,7 @@ void dumpRaw (decode_results *results) if (x < 1000) Serial.print(" ") ; if (x < 100) Serial.print(" ") ; Serial.print(x, DEC); - Serial.print(", "); + if (i < results->rawlen-1) Serial.print(", "); //',' not needed for last one } if (!(i % 8)) Serial.println(""); } @@ -121,18 +121,18 @@ void dumpCode (decode_results *results) // Start declaration Serial.print("unsigned int "); // variable type Serial.print("rawData["); // array name - Serial.print(results->rawlen + 1, DEC); // array size + Serial.print(results->rawlen - 1, DEC); // array size Serial.print("] = {"); // Start declaration // Dump data for (int i = 1; i < results->rawlen; i++) { Serial.print(results->rawbuf[i] * USECPERTICK, DEC); - Serial.print(","); + if ( i < results->rawlen-1 ) Serial.print(","); // ',' not needed on last one if (!(i & 1)) Serial.print(" "); } // End declaration - Serial.print("0};"); // Turn LED off at the end + Serial.print("};"); // // Comment Serial.print(" // "); From 5b82539954a6b2299130dee86e1939446fb32ea4 Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Wed, 2 Sep 2015 20:19:03 +0100 Subject: [PATCH 133/768] Merge back irISR.cpp into irRemote.cpp to avoid an issue due to the absence of exported symbols from irISR.cpp see https://github.com/z3t0/Arduino-IRremote/issues/214 https://github.com/sudar/Arduino-Makefile/issues/376 In some circumstances the linker skips irISR.cpp irRemote.cpp is always included (by the linker). Andrea --- IRremote.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++ irISR.cpp | 88 ---------------------------------------------------- 2 files changed, 86 insertions(+), 88 deletions(-) delete mode 100644 irISR.cpp diff --git a/IRremote.cpp b/IRremote.cpp index e4fb94ba1..e079ece8a 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -18,6 +18,8 @@ // Whynter A/C ARC-110WD added by Francesco Meschia //****************************************************************************** +#include + // Defining IR_GLOBAL here allows us to declare the instantiation of global variables #define IR_GLOBAL # include "IRremote.h" @@ -88,3 +90,87 @@ int MATCH_SPACE (int measured_ticks, int desired_us) return ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); } + +//+============================================================================= +// Interrupt Service Routine - Fires every 50uS +// TIMER2 interrupt code to collect raw data. +// Widths of alternating SPACE, MARK are recorded in rawbuf. +// Recorded in ticks of 50uS [microseconds, 0.000050 seconds] +// 'rawlen' counts the number of entries recorded so far. +// First entry is the SPACE between transmissions. +// As soon as a the first [SPACE] entry 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; New logging starts +// +ISR (TIMER_INTR_NAME) +{ + TIMER_RESET; + + // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on] + // digitalRead() is very slow. Optimisation is possible, but makes the code unportable + uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); + + irparams.timer++; // One more 50uS tick + if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_OVERFLOW ; // 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; Start recording transmission + irparams.overflow = false; + 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 time + irparams.rawbuf[irparams.rawlen++] = irparams.timer; + irparams.timer = 0; + irparams.rcvstate = STATE_MARK; + + } else if (irparams.timer > GAP_TICKS) { // Space + // A long Space, indicates gap between codes + // Flag the 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; + //...................................................................... + case STATE_OVERFLOW: // Flag up a read overflow; Stop the State Machine + irparams.overflow = true; + irparams.rcvstate = STATE_STOP; + break; + } + + // If requested, flash LED while receiving IR data + if (irparams.blinkflag) { + if (irdata == MARK) + if (irparams.blinkpin) digitalWrite(irparams.blinkpin, HIGH); // Turn user defined pin LED on + else BLINKLED_ON() ; // if no user defined LED pin, turn default LED pin for the hardware on + else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on + else BLINKLED_OFF() ; // if no user defined LED pin, turn default LED pin for the hardware on + } +} diff --git a/irISR.cpp b/irISR.cpp deleted file mode 100644 index e3bc1c370..000000000 --- a/irISR.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include - -#include "IRremote.h" -#include "IRremoteInt.h" - -//+============================================================================= -// Interrupt Service Routine - Fires every 50uS -// TIMER2 interrupt code to collect raw data. -// Widths of alternating SPACE, MARK are recorded in rawbuf. -// Recorded in ticks of 50uS [microseconds, 0.000050 seconds] -// 'rawlen' counts the number of entries recorded so far. -// First entry is the SPACE between transmissions. -// As soon as a the first [SPACE] entry 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; New logging starts -// -ISR (TIMER_INTR_NAME) -{ - TIMER_RESET; - - // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on] - // digitalRead() is very slow. Optimisation is possible, but makes the code unportable - uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); - - irparams.timer++; // One more 50uS tick - if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_OVERFLOW ; // 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; Start recording transmission - irparams.overflow = false; - 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 time - irparams.rawbuf[irparams.rawlen++] = irparams.timer; - irparams.timer = 0; - irparams.rcvstate = STATE_MARK; - - } else if (irparams.timer > GAP_TICKS) { // Space - // A long Space, indicates gap between codes - // Flag the 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; - //...................................................................... - case STATE_OVERFLOW: // Flag up a read overflow; Stop the State Machine - irparams.overflow = true; - irparams.rcvstate = STATE_STOP; - break; - } - - // If requested, flash LED while receiving IR data - if (irparams.blinkflag) { - if (irdata == MARK) - if (irparams.blinkpin) digitalWrite(irparams.blinkpin, HIGH); // Turn user defined pin LED on - else BLINKLED_ON() ; // if no user defined LED pin, turn default LED pin for the hardware on - else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on - else BLINKLED_OFF() ; // if no user defined LED pin, turn default LED pin for the hardware on - } -} From f5071daac8c6886f76e40f101140843dd4d1b9aa Mon Sep 17 00:00:00 2001 From: Bernhard Essl Date: Wed, 9 Sep 2015 10:47:28 +0200 Subject: [PATCH 134/768] Changed library name "RobotIRremote" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9dee657a1..a64eef4fe 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more inf 2. Download the latest release. 3. Extract the zip file 4. Move the "IRremote" folder that has been extracted to your libraries directory. -5. Make sure to delete Arduino_Root/libraries/RobotIRRemote. Where Arduino_Root refers to the install directory of Arduino. The library RobotIRRemote has similar definitions to IRremote and causes errors. +5. Make sure to delete Arduino_Root/libraries/RobotIRremote. Where Arduino_Root refers to the install directory of Arduino. The library RobotIRremote has similar definitions to IRremote and causes errors. ## Usage - TODO (Check examples for now) From c90d6788a13f59effcc2f29d952d7000fe558f7b Mon Sep 17 00:00:00 2001 From: Paolo P Date: Thu, 24 Sep 2015 11:43:33 +0200 Subject: [PATCH 135/768] Update version to 2.0.1 Update to version 2.0.1 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 094b283f6..3553dc1fc 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=IRremote -version=1.0 +version=2.0.1 author=shirriff maintainer=shirriff sentence=Send and receive infrared signals with multiple protocols From 9a57b2aead79cd5bbb32776b19d96141d5348534 Mon Sep 17 00:00:00 2001 From: Paolo Paolucci Date: Fri, 25 Sep 2015 09:22:25 +0200 Subject: [PATCH 136/768] Errata corrige keyword file --- keywords.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/keywords.txt b/keywords.txt index 808c7ea3f..6fd016fc3 100644 --- a/keywords.txt +++ b/keywords.txt @@ -32,7 +32,6 @@ sendSharpRaw KEYWORD2 sendPanasonic KEYWORD2 sendJVC KEYWORD2 -# ####################################### # Constants (LITERAL1) ####################################### From d7a4c4e0c8bbb57cc5e514a6765e4557b7ddb4d4 Mon Sep 17 00:00:00 2001 From: Paolo Paolucci Date: Fri, 25 Sep 2015 09:23:22 +0200 Subject: [PATCH 137/768] Update version to 2.0.1 --- IRremote.cpp | 2 +- IRremote.h | 2 +- IRremoteInt.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index e079ece8a..466a4fb80 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -1,6 +1,6 @@ //****************************************************************************** // IRremote -// Version 0.11 August, 2009 +// Version 2.0.1 June, 2015 // Copyright 2009 Ken Shirriff // For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html // diff --git a/IRremote.h b/IRremote.h index 4af944a44..86815b4fb 100644 --- a/IRremote.h +++ b/IRremote.h @@ -1,7 +1,7 @@ //****************************************************************************** // IRremote -// Version 0.1 July, 2009 +// Version 2.0.1 June, 2015 // Copyright 2009 Ken Shirriff // For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html // Edited by Mitra to add new controller SANYO diff --git a/IRremoteInt.h b/IRremoteInt.h index 32515c3c8..125eb7205 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -1,6 +1,6 @@ //****************************************************************************** // IRremote -// Version 0.1 July, 2009 +// Version 2.0.1 June, 2015 // Copyright 2009 Ken Shirriff // For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html // From 26560e5755c68e0607b848102564ef5e3a59a311 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 28 Sep 2015 20:45:55 -0600 Subject: [PATCH 138/768] Contact info @readme.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index a64eef4fe..fe7fa25f4 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,11 @@ If you want to contribute to this project: - Create issues and pull requests - Tell other people about this library - Contribute new protocols +- + +## Contact +The only way to contact me at the moment is by email: zetoslab@gmail.com +I am not currently monitoring any PRs or Issues due to other issues but will respond to all emails. If anyone wants contributor access, feel free to email me. Or if you find any Issues/PRs to be of importance that my attention is needed please email me. ## Contributors Check [here](Contributors.md) From c41f506cc12daf265c182324e4f95bcf988553a9 Mon Sep 17 00:00:00 2001 From: ram-0000 Date: Sun, 8 Nov 2015 19:38:54 +0100 Subject: [PATCH 139/768] Update ir_Aiwa.cpp Remove unused mask variable line 31 --- ir_Aiwa.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/ir_Aiwa.cpp b/ir_Aiwa.cpp index bd5ba8966..9cc5656ce 100644 --- a/ir_Aiwa.cpp +++ b/ir_Aiwa.cpp @@ -28,7 +28,6 @@ void IRsend::sendAiwaRCT501 (int code) { unsigned long pre = 0x0227EEC0; // 26-bits - int mask; // Set IR carrier frequency enableIROut(AIWA_RC_T501_HZ); From e1957629d37aae720b3de64687a2b11663ffb4f9 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 10 Nov 2015 15:02:32 -0600 Subject: [PATCH 140/768] Update ir_Aiwa.cpp fixed typo in line 12 --- ir_Aiwa.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir_Aiwa.cpp b/ir_Aiwa.cpp index 9cc5656ce..50ec58d8c 100644 --- a/ir_Aiwa.cpp +++ b/ir_Aiwa.cpp @@ -9,7 +9,7 @@ // A A IIIII WWW A A //============================================================================== -// Baszed off the RC-T501 RCU +// Based off the RC-T501 RCU // Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 #define AIWA_RC_T501_HZ 38 From 711ebd7d92a3e8b20bd53099add45b9d69cfc3b3 Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Sat, 28 Nov 2015 21:11:08 +0000 Subject: [PATCH 141/768] Create IRremoteInfo.ino A helper tool to assist in supporting troubleshooting with IRremote. Prints all of the current settings applied within the users IRremote set-up. A description og the utility is available here: http://www.analysir.com/blog/2015/11/28/helper-utility-for-troubleshooting-irremote/ --- examples/IRremoteInfo/IRremoteInfo.ino | 210 +++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 examples/IRremoteInfo/IRremoteInfo.ino diff --git a/examples/IRremoteInfo/IRremoteInfo.ino b/examples/IRremoteInfo/IRremoteInfo.ino new file mode 100644 index 000000000..bc13c5d12 --- /dev/null +++ b/examples/IRremoteInfo/IRremoteInfo.ino @@ -0,0 +1,210 @@ +/* + * IRremote: IRremoteInfo - prints relevant config info & settings for IRremote over serial + * Intended to help identify & troubleshoot the various settings of IRremote + * For example, sometimes users are unsure of which pin is used for Tx or the RAWBUF values + * This example can be used to assist the user directly or with support. + * Intended to help identify & troubleshoot the various settings of IRremote + * Hopefully this utility will be a useful tool for support & troubleshooting for IRremote + * Check out the blog post describing the sketch via http://www.analysir.com/blog/2015/11/28/helper-utility-for-troubleshooting-irremote/ + * Version 1.0 November 2015 + * Original Author: AnalysIR - IR software & modules for Makers & Pros, visit http://www.AnalysIR.com + */ + + +#include + +void setup() +{ + Serial.begin(115200); //You may alter the BAUD rate here as needed + while (!Serial); //wait until Serial is established - required on some Platforms + + //Runs only once per restart of the Arduino. + dumpHeader(); + dumpRAWBUF(); + dumpTIMER(); + dumpTimerPin(); + dumpClock(); + dumpPlatform(); + dumpPulseParams(); + dumpSignalParams(); + dumpArduinoIDE(); + dumpDebugMode(); + dumpProtocols(); + dumpFooter(); +} + +void loop() { + //nothing to do! +} + +void dumpRAWBUF() { + Serial.print(F("RAWBUF: ")); + Serial.println(RAWBUF); +} + +void dumpTIMER() { + boolean flag = false; +#ifdef IR_USE_TIMER1 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer1")); flag = true; +#endif +#ifdef IR_USE_TIMER2 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer2")); flag = true; +#endif +#ifdef IR_USE_TIMER3 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer3")); flag = true; +#endif +#ifdef IR_USE_TIMER4 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer4")); flag = true; +#endif +#ifdef IR_USE_TIMER5 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer5")); flag = true; +#endif +#ifdef IR_USE_TIMER4_HS + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer4_HS")); flag = true; +#endif +#ifdef IR_USE_TIMER_CMT + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_CMT")); flag = true; +#endif +#ifdef IR_USE_TIMER_TPM1 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_TPM1")); flag = true; +#endif +#ifdef IR_USE_TIMER_TINY0 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_TINY0")); flag = true; +#endif + + if (!flag) { + Serial.print(F("Timer Error: ")); Serial.println(F("not defined")); + } +} + +void dumpTimerPin() { + Serial.print(F("IR Tx Pin: ")); + Serial.println(TIMER_PWM_PIN); +} + +void dumpClock() { + Serial.print(F("MCU Clock: ")); + Serial.println(F_CPU); +} + +void dumpPlatform() { + Serial.print(F("MCU Platform: ")); + +#if defined(__AVR_ATmega1280__) + Serial.println(F("Arduino Mega1280")); +#elif defined(__AVR_ATmega2560__) + Serial.println(F("Arduino Mega2560")); +#elif defined(__AVR_AT90USB162__) + Serial.println(F("Teensy 1.0 / AT90USB162")); + // Teensy 2.0 +#elif defined(__AVR_ATmega32U4__) + Serial.println(F("Arduino Leonardo / Yun / Teensy 1.0 / ATmega32U4")); +#elif defined(__MK20DX128__) || defined(__MK20DX256__) + Serial.println(F("Teensy 3.0 / Teensy 3.1 / MK20DX128 / MK20DX256")); +#elif defined(__MKL26Z64__) + Serial.println(F("Teensy-LC / MKL26Z64")); +#elif defined(__AVR_AT90USB646__) + Serial.println(F("Teensy++ 1.0 / AT90USB646")); +#elif defined(__AVR_AT90USB1286__) + Serial.println(F("Teensy++ 2.0 / AT90USB1286")); +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) + Serial.println(F("Sanguino / ATmega644(P)")); +#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) + Serial.println(F("Atmega8 / ATmega8(P)")); +#elif defined(__AVR_ATtiny84__) + Serial.println(F("ATtiny84")); +#elif defined(__AVR_ATtiny85__) + Serial.println(F("ATtiny85")); +#else + Serial.println(F("ATmega328(P) / (Duemilanove, Diecimila, LilyPad, Mini, Micro, Fio, Nano, etc)")); +#endif +} + +void dumpPulseParams() { + Serial.print(F("Mark Excess: ")); Serial.print(MARK_EXCESS);; Serial.println(F(" uSecs")); + Serial.print(F("Microseconds per tick: ")); Serial.print(USECPERTICK);; Serial.println(F(" uSecs")); + Serial.print(F("Measurement tolerance: ")); Serial.print(TOLERANCE); Serial.println(F("%")); +} + +void dumpSignalParams() { + Serial.print(F("Minimum Gap between IR Signals: ")); Serial.print(_GAP); Serial.println(F(" uSecs")); +} + +void dumpDebugMode() { + Serial.print(F("Debug Mode: ")); +#if DEBUG + Serial.println(F("ON")); +#else + Serial.println(F("OFF (Normal)")); +#endif + +} + +void dumpArduinoIDE() { + Serial.print(F("Arduino IDE version: ")); + Serial.print(ARDUINO / 10000); + Serial.write('.'); + Serial.print((ARDUINO % 10000) / 100); + Serial.write('.'); + Serial.println(ARDUINO % 100); +} + +void dumpProtocols() { + + Serial.println(); Serial.print(F("IR PROTOCOLS ")); Serial.print(F("SEND ")); Serial.println(F("DECODE")); + Serial.print(F("============= ")); Serial.print(F("======== ")); Serial.println(F("========")); + Serial.print(F("RC5: ")); printSendEnabled(SEND_RC5); printDecodeEnabled(DECODE_RC6); + Serial.print(F("RC6: ")); printSendEnabled(SEND_RC6); printDecodeEnabled(DECODE_RC5); + Serial.print(F("NEC: ")); printSendEnabled(SEND_NEC); printDecodeEnabled(DECODE_NEC); + Serial.print(F("SONY: ")); printSendEnabled(SEND_SONY); printDecodeEnabled(DECODE_SONY); + Serial.print(F("PANASONIC: ")); printSendEnabled(SEND_PANASONIC); printDecodeEnabled(DECODE_PANASONIC); + Serial.print(F("JVC: ")); printSendEnabled(SEND_JVC); printDecodeEnabled(DECODE_JVC); + Serial.print(F("SAMSUNG: ")); printSendEnabled(SEND_SAMSUNG); printDecodeEnabled(DECODE_SAMSUNG); + Serial.print(F("WHYNTER: ")); printSendEnabled(SEND_WHYNTER); printDecodeEnabled(DECODE_WHYNTER); + Serial.print(F("AIWA_RC_T501: ")); printSendEnabled(SEND_AIWA_RC_T501); printDecodeEnabled(DECODE_AIWA_RC_T501); + Serial.print(F("LG: ")); printSendEnabled(SEND_LG); printDecodeEnabled(DECODE_LG); + Serial.print(F("SANYO: ")); printSendEnabled(SEND_SANYO); printDecodeEnabled(DECODE_SANYO); + Serial.print(F("MITSUBISHI: ")); printSendEnabled(SEND_MITSUBISHI); printDecodeEnabled(DECODE_MITSUBISHI); + Serial.print(F("DISH: ")); printSendEnabled(SEND_DISH); printDecodeEnabled(DECODE_DISH); + Serial.print(F("SHARP: ")); printSendEnabled(SEND_SHARP); printDecodeEnabled(DECODE_SHARP); + Serial.print(F("DENON: ")); printSendEnabled(SEND_DENON); printDecodeEnabled(DECODE_DENON); + Serial.print(F("PRONTO: ")); printSendEnabled(SEND_PRONTO); Serial.println(F("(Not Applicable)")); +} + +void printSendEnabled(int flag) { + if (flag) { + Serial.print(F("Enabled ")); + } + else { + Serial.print(F("Disabled ")); + } +} + +void printDecodeEnabled(int flag) { + if (flag) { + Serial.println(F("Enabled")); + } + else { + Serial.println(F("Disabled")); + } +} + +void dumpHeader() { + Serial.println(F("IRremoteInfo - by AnalysIR (http://www.AnalysIR.com/)")); + Serial.println(F(" - A helper sketch to assist in troubleshooting issues with the library by reviewing the settings within the IRremote library")); + Serial.println(F(" - Prints out the important settings within the library, which can be configured to suit the many supported platforms")); + Serial.println(F(" - When seeking on-line support, please post or upload the output of this sketch, where appropriate")); + Serial.println(); + Serial.println(F("IRremote Library Settings")); + Serial.println(F("=========================")); +} + +void dumpFooter() { + Serial.println(); + Serial.println(F("Notes: ")); + Serial.println(F(" - Most of the seetings above can be configured in the following files included as part of the library")); + Serial.println(F(" - IRremteInt.h")); + Serial.println(F(" - IRremote.h")); + Serial.println(F(" - You can save SRAM by disabling the Decode or Send features for any protocol (Near the top of IRremoteInt.h)")); + Serial.println(F(" - Some Timer conflicts, with other libraries, can be easily resolved by configuring a differnt Timer for your platform")); +} From 8bde9ee628fef443cbd26628ad65386332f69b78 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Wed, 2 Dec 2015 23:57:00 +0000 Subject: [PATCH 142/768] merging #241 --- .travis.yml | 1 + changelog.md | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 43666bd08..f4b1ba001 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ env: - PLATFORMIO_CI_SRC=examples/IRtest PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" - PLATFORMIO_CI_SRC=examples/IRtest2 PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" - PLATFORMIO_CI_SRC=examples/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC" + - PLATFORMIO_CI_SRC=examples/IRremoteInfo install: - python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)" diff --git a/changelog.md b/changelog.md index 81e95d87b..d5f4cffa5 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,8 @@ + +## 2.0.2 - 2015/12/02 +- Added IRremoteInfo Sketch - [PR](https://github.com/z3t0/Arduino-IRremote/pull/241) +- Enforcing changelog.md + ## 2.0.1 - 2015/07/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA) ### Changes - Updated README From ed1a2a21539b6f38e8141a1eec8c4f866f5b4ca1 Mon Sep 17 00:00:00 2001 From: Gabriel Staples Date: Sat, 23 Jan 2016 20:18:25 -0500 Subject: [PATCH 143/768] Update IRremote.cpp to improve debugging This is a small change, and definitely an improvement. I simply improved the debugging by stating whether a check passed or failed, for easier identification in debug mode. --- IRremote.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 466a4fb80..5885d2697 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -46,9 +46,14 @@ int MATCH (int measured, int desired) DBG_PRINT(" <= "); DBG_PRINT(measured, DEC); DBG_PRINT(" <= "); - DBG_PRINTLN(TICKS_HIGH(desired), DEC); + DBG_PRINT(TICKS_HIGH(desired), DEC); - return ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); + bool passed = ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); + if (passed) + DBG_PRINTLN("; passed"); + else + DBG_PRINTLN("; FAILED"); + return passed; } //+======================================================== @@ -65,10 +70,15 @@ int MATCH_MARK (int measured_ticks, int desired_us) DBG_PRINT(" <= "); DBG_PRINT(measured_ticks, DEC); DBG_PRINT(" <= "); - DBG_PRINTLN(TICKS_HIGH(desired_us + MARK_EXCESS), DEC); + DBG_PRINT(TICKS_HIGH(desired_us + MARK_EXCESS), DEC); - return ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) - && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); + bool passed = ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) + && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); + if (passed) + DBG_PRINTLN("; passed"); + else + DBG_PRINTLN("; FAILED"); + return passed; } //+======================================================== @@ -85,10 +95,15 @@ int MATCH_SPACE (int measured_ticks, int desired_us) DBG_PRINT(" <= "); DBG_PRINT(measured_ticks, DEC); DBG_PRINT(" <= "); - DBG_PRINTLN(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); + DBG_PRINT(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); - return ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) - && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); + bool passed = ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) + && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); + if (passed) + DBG_PRINTLN("; passed"); + else + DBG_PRINTLN("; FAILED"); + return passed; } //+============================================================================= From 92092df7a0f48152032e539949a867577de7c896 Mon Sep 17 00:00:00 2001 From: Gabriel Staples Date: Sat, 23 Jan 2016 21:06:41 -0500 Subject: [PATCH 144/768] Update IRremote.cpp Further improved debug formatting, & added F macro to reduce RAM usage during prints. --- IRremote.cpp | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 5885d2697..a5513d60f 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -41,18 +41,18 @@ // int MATCH (int measured, int desired) { - DBG_PRINT("Testing: "); + DBG_PRINT(F("Testing: ")); DBG_PRINT(TICKS_LOW(desired), DEC); - DBG_PRINT(" <= "); + DBG_PRINT(F(" <= ")); DBG_PRINT(measured, DEC); - DBG_PRINT(" <= "); + DBG_PRINT(F(" <= ")); DBG_PRINT(TICKS_HIGH(desired), DEC); bool passed = ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); if (passed) - DBG_PRINTLN("; passed"); + DBG_PRINTLN(F("; passed")); else - DBG_PRINTLN("; FAILED"); + DBG_PRINTLN(F("; FAILED")); return passed; } @@ -61,23 +61,24 @@ int MATCH (int measured, int desired) // int MATCH_MARK (int measured_ticks, int desired_us) { - DBG_PRINT("Testing mark "); + DBG_PRINT(F("Testing mark (actual vs desired): ")); DBG_PRINT(measured_ticks * USECPERTICK, DEC); - DBG_PRINT(" vs "); + DBG_PRINT(F("us vs ")); DBG_PRINT(desired_us, DEC); + DBG_PRINT("us"); DBG_PRINT(": "); - DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS), DEC); - DBG_PRINT(" <= "); - DBG_PRINT(measured_ticks, DEC); - DBG_PRINT(" <= "); - DBG_PRINT(TICKS_HIGH(desired_us + MARK_EXCESS), DEC); + DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS) * USECPERTICK, DEC); + DBG_PRINT(F(" <= ")); + DBG_PRINT(measured_ticks * USECPERTICK, DEC); + DBG_PRINT(F(" <= ")); + DBG_PRINT(TICKS_HIGH(desired_us + MARK_EXCESS) * USECPERTICK, DEC); bool passed = ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); if (passed) - DBG_PRINTLN("; passed"); + DBG_PRINTLN(F("; passed")); else - DBG_PRINTLN("; FAILED"); + DBG_PRINTLN(F("; FAILED")); return passed; } @@ -86,23 +87,24 @@ int MATCH_MARK (int measured_ticks, int desired_us) // int MATCH_SPACE (int measured_ticks, int desired_us) { - DBG_PRINT("Testing space "); + DBG_PRINT(F("Testing space (actual vs desired): ")); DBG_PRINT(measured_ticks * USECPERTICK, DEC); - DBG_PRINT(" vs "); + DBG_PRINT(F("us vs ")); DBG_PRINT(desired_us, DEC); + DBG_PRINT("us"); DBG_PRINT(": "); - DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS), DEC); - DBG_PRINT(" <= "); - DBG_PRINT(measured_ticks, DEC); - DBG_PRINT(" <= "); - DBG_PRINT(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); + DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS) * USECPERTICK, DEC); + DBG_PRINT(F(" <= ")); + DBG_PRINT(measured_ticks * USECPERTICK, DEC); + DBG_PRINT(F(" <= ")); + DBG_PRINT(TICKS_HIGH(desired_us - MARK_EXCESS) * USECPERTICK, DEC); bool passed = ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); if (passed) - DBG_PRINTLN("; passed"); + DBG_PRINTLN(F("; passed")); else - DBG_PRINTLN("; FAILED"); + DBG_PRINTLN(F("; FAILED")); return passed; } From e4933e809e38b939363ade03d4f7d61a42fb61bd Mon Sep 17 00:00:00 2001 From: Gabriel Staples Date: Sat, 23 Jan 2016 21:12:34 -0500 Subject: [PATCH 145/768] Update IRremote.cpp very minor changes --- IRremote.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index a5513d60f..c9907ebe7 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -50,9 +50,9 @@ int MATCH (int measured, int desired) bool passed = ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); if (passed) - DBG_PRINTLN(F("; passed")); + DBG_PRINTLN(F("?; passed")); else - DBG_PRINTLN(F("; FAILED")); + DBG_PRINTLN(F("?; FAILED")); return passed; } @@ -65,7 +65,7 @@ int MATCH_MARK (int measured_ticks, int desired_us) DBG_PRINT(measured_ticks * USECPERTICK, DEC); DBG_PRINT(F("us vs ")); DBG_PRINT(desired_us, DEC); - DBG_PRINT("us"); + DBG_PRINT("us"); DBG_PRINT(": "); DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS) * USECPERTICK, DEC); DBG_PRINT(F(" <= ")); @@ -76,9 +76,9 @@ int MATCH_MARK (int measured_ticks, int desired_us) bool passed = ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); if (passed) - DBG_PRINTLN(F("; passed")); + DBG_PRINTLN(F("?; passed")); else - DBG_PRINTLN(F("; FAILED")); + DBG_PRINTLN(F("?; FAILED")); return passed; } @@ -91,7 +91,7 @@ int MATCH_SPACE (int measured_ticks, int desired_us) DBG_PRINT(measured_ticks * USECPERTICK, DEC); DBG_PRINT(F("us vs ")); DBG_PRINT(desired_us, DEC); - DBG_PRINT("us"); + DBG_PRINT("us"); DBG_PRINT(": "); DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS) * USECPERTICK, DEC); DBG_PRINT(F(" <= ")); @@ -102,9 +102,9 @@ int MATCH_SPACE (int measured_ticks, int desired_us) bool passed = ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); if (passed) - DBG_PRINTLN(F("; passed")); + DBG_PRINTLN(F("?; passed")); else - DBG_PRINTLN(F("; FAILED")); + DBG_PRINTLN(F("?; FAILED")); return passed; } From 86e20db36cf651445ddba7c0f6e8cc912b6948be Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 20 Feb 2016 23:02:55 -0600 Subject: [PATCH 146/768] added sublime project file to gitignore --- .gitignore | 1 + arduino-irremote.sublime-workspace | 240 +++++++++++++++++++++++++++++ 2 files changed, 241 insertions(+) create mode 100644 arduino-irremote.sublime-workspace diff --git a/.gitignore b/.gitignore index c5d99cb2a..a78f1f532 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.un~ +*.sublime-project \ No newline at end of file diff --git a/arduino-irremote.sublime-workspace b/arduino-irremote.sublime-workspace new file mode 100644 index 000000000..f536803d0 --- /dev/null +++ b/arduino-irremote.sublime-workspace @@ -0,0 +1,240 @@ +{ + "auto_complete": + { + "selected_items": + [ + [ + "vb", + "vboMatrix" + ] + ] + }, + "buffers": + [ + ], + "build_system": "", + "build_system_choices": + [ + ], + "build_varint": "", + "command_palette": + { + "height": 275.0, + "last_filter": "blame", + "selected_items": + [ + [ + "blame", + "Git: Blame" + ], + [ + "install", + "Package Control: Install Package" + ], + [ + "diff", + "Git: Diff Current File" + ], + [ + "js", + "Set Syntax: JavaScript" + ], + [ + "i", + "Package Control: Install Package" + ], + [ + "instal", + "Package Control: Install Package" + ] + ], + "width": 510.0 + }, + "console": + { + "height": 126.0, + "history": + [ + "import urllib.request,os,hashlib; h = '2915d1851351e5ee549c20394736b442' + '8bc59f460fa1548d1514676163dafc88'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)" + ] + }, + "distraction_free": + { + "menu_visible": true, + "show_minimap": false, + "show_open_files": false, + "show_tabs": false, + "side_bar_visible": false, + "status_bar_visible": false + }, + "expanded_folders": + [ + "/C/Users/Rafi Khan/Documents/Arduino/libraries/Arduino-IRremote" + ], + "file_history": + [ + "/C/Users/Rafi Khan/Documents/Arduino/libraries/Arduino-IRremote/changelog.md", + "/C/Users/Rafi Khan/Documents/Development/Arduino-IRremote/arduino-irremote.sublime-project", + "/C/Users/Rafi Khan/Documents/Development/Arduino-IRremote/.gitignore", + "/C/Users/Rafi Khan/Documents/Development/magic/README.md", + "/C/Users/Rafi Khan/Documents/Development/magic/shader.frag", + "/C/Users/Rafi Khan/Documents/Development/magic/package.json", + "/C/Users/Rafi Khan/Documents/Development/magic/block.js", + "/C/Users/Rafi Khan/Documents/Development/magic/chunker.js", + "/C/Users/Rafi Khan/Documents/Development/magic/index.js", + "/C/Users/Rafi Khan/Documents/Development/magic/blocks", + "/C/Users/Rafi Khan/AppData/Roaming/Sublime Text 3/Packages/User/Preferences.sublime-settings", + "/C/Users/Rafi Khan/Documents/Development/magic/shader.vert", + "/C/Users/Rafi Khan/Documents/Development/magic/magic.sublime-project", + "/C/Users/Rafi Khan/Documents/Development/magic/node_modules/browserify/node_modules/syntax-error/node_modules/acorn/.tern-project", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/supermarket.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/takingavacation.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/TipCalculator.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/battleship.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/exam.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/pyglatin.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/student.py" + ], + "find": + { + "height": 28.0 + }, + "find_in_files": + { + "height": 0.0, + "where_history": + [ + ] + }, + "find_state": + { + "case_sensitive": false, + "find_history": + [ + "i", + "Direction", + ";", + ";\n", + "north", + "cubeMatrix", + ")\n", + "vec3.set", + "f", + ";", + "();\n", + "render", + "this", + "y" + ], + "highlight": true, + "in_selection": false, + "preserve_case": false, + "regex": false, + "replace_history": + [ + ], + "reverse": false, + "show_context": true, + "use_buffer2": true, + "whole_word": false, + "wrap": true + }, + "groups": + [ + { + "sheets": + [ + ] + } + ], + "incremental_find": + { + "height": 28.0 + }, + "input": + { + "height": 66.0 + }, + "layout": + { + "cells": + [ + [ + 0, + 0, + 1, + 1 + ] + ], + "cols": + [ + 0.0, + 1.0 + ], + "rows": + [ + 0.0, + 1.0 + ] + }, + "menu_visible": true, + "output.find_results": + { + "height": 0.0 + }, + "pinned_build_system": "", + "project": "arduino-irremote.sublime-project", + "replace": + { + "height": 52.0 + }, + "save_all_on_build": true, + "select_file": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + [ + "json", + "package.json" + ], + [ + "inde", + "index.js" + ] + ], + "width": 0.0 + }, + "select_project": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "select_symbol": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "selected_group": 0, + "settings": + { + }, + "show_minimap": true, + "show_open_files": false, + "show_tabs": true, + "side_bar_visible": true, + "side_bar_width": 150.0, + "status_bar_visible": true, + "template_settings": + { + } +} From 96c40f63f0ff0a24b618aa8c996d1d96b1e8ac83 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 20 Feb 2016 23:17:07 -0600 Subject: [PATCH 147/768] added sublime workspace to gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a78f1f532..e24b84cda 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.un~ -*.sublime-project \ No newline at end of file +*.sublime-project +*.sublime-workspace \ No newline at end of file From 376301228aeabf18442edbe6392cec6977b1893d Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 20 Feb 2016 23:17:45 -0600 Subject: [PATCH 148/768] changed irsendraw parameter to const, #227 --- Contributors.md | 1 + IRremote.h | 2 +- README.md | 2 +- changelog.md | 2 ++ irSend.cpp | 2 +- 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Contributors.md b/Contributors.md index e56b29c6d..2cfa98140 100644 --- a/Contributors.md +++ b/Contributors.md @@ -12,6 +12,7 @@ These are the active contributors of this project that you may contact if there - [Neco777](https://github.com/neco777) : Active contributor - [Lauszus](https://github.com/lauszus) : Active contributor - [csBlueChip](https://github.com/csbluechip) : Active contributor, who contributed major and vital changes to the code base. +- [Sebazzz](https://github.com/sebazz): Contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. diff --git a/IRremote.h b/IRremote.h index 86815b4fb..96d82ca71 100644 --- a/IRremote.h +++ b/IRremote.h @@ -257,7 +257,7 @@ class IRsend void enableIROut (int khz) ; void mark (unsigned int usec) ; void space (unsigned int usec) ; - void sendRaw (unsigned int buf[], unsigned int len, unsigned int hz) ; + void sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz) ; //...................................................................... # if SEND_RC5 diff --git a/README.md b/README.md index fe7fa25f4..40e5c454a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This library enables you to send and receive using infra-red signals on an Ardui Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more information. -## Version - 2.01 +## Version - 2.03 ## Installation 1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. diff --git a/changelog.md b/changelog.md index d5f4cffa5..0ec8afe60 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,5 @@ +## 2.0.3 - 2016/02/20 +- Change IRSend Raw parameter to const [PR](https://github.com/z3t0/Arduino-IRremote/pull/227) ## 2.0.2 - 2015/12/02 - Added IRremoteInfo Sketch - [PR](https://github.com/z3t0/Arduino-IRremote/pull/241) diff --git a/irSend.cpp b/irSend.cpp index 1340e6390..253c941a9 100644 --- a/irSend.cpp +++ b/irSend.cpp @@ -2,7 +2,7 @@ #include "IRremoteInt.h" //+============================================================================= -void IRsend::sendRaw (unsigned int buf[], unsigned int len, unsigned int hz) +void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz) { // Set IR carrier frequency enableIROut(hz); From c471e2816de59558a489a145b3c52d7a0e673b17 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 20 Feb 2016 23:37:11 -0600 Subject: [PATCH 149/768] @2.0.4 #54 (added changelog info) --- Contributors.md | 1 + README.md | 2 +- changelog.md | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Contributors.md b/Contributors.md index 2cfa98140..6a0c9e101 100644 --- a/Contributors.md +++ b/Contributors.md @@ -13,6 +13,7 @@ These are the active contributors of this project that you may contact if there - [Lauszus](https://github.com/lauszus) : Active contributor - [csBlueChip](https://github.com/csbluechip) : Active contributor, who contributed major and vital changes to the code base. - [Sebazzz](https://github.com/sebazz): Contributor +- [lumbric](https://github.com/lumbric): Contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. diff --git a/README.md b/README.md index 40e5c454a..21e6b2127 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This library enables you to send and receive using infra-red signals on an Ardui Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more information. -## Version - 2.03 +## Version - 2.04 ## Installation 1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. diff --git a/changelog.md b/changelog.md index 0ec8afe60..e0d9fd217 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +## 2.0.4 - 2016/02/20 +- Add Panasonic and JVC to IRrecord example [PR](https://github.com/z3t0/Arduino-IRremote/pull/54) + ## 2.0.3 - 2016/02/20 - Change IRSend Raw parameter to const [PR](https://github.com/z3t0/Arduino-IRremote/pull/227) From bd1a2e05a03ab3a29b8c6533bfe19166ce43be18 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 20 Feb 2016 23:46:02 -0600 Subject: [PATCH 150/768] @2.1.0 #258 (updated changelog) --- Contributors.md | 1 + README.md | 2 +- changelog.md | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Contributors.md b/Contributors.md index 6a0c9e101..6988f52d0 100644 --- a/Contributors.md +++ b/Contributors.md @@ -14,6 +14,7 @@ These are the active contributors of this project that you may contact if there - [csBlueChip](https://github.com/csbluechip) : Active contributor, who contributed major and vital changes to the code base. - [Sebazzz](https://github.com/sebazz): Contributor - [lumbric](https://github.com/lumbric): Contributor +- [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. diff --git a/README.md b/README.md index 21e6b2127..d0a1163c6 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This library enables you to send and receive using infra-red signals on an Ardui Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more information. -## Version - 2.04 +## Version - 2.1.0 ## Installation 1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. diff --git a/changelog.md b/changelog.md index e0d9fd217..2901dd167 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,7 @@ +## 2.1.0 - 2016/02/20 +- Improved Debugging [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258) +- Display TIME instead of TICKS [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258) + ## 2.0.4 - 2016/02/20 - Add Panasonic and JVC to IRrecord example [PR](https://github.com/z3t0/Arduino-IRremote/pull/54) From 841e77a642120f47e0b71e8c6e39a9054aa6fd3c Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 20 Feb 2016 23:47:27 -0600 Subject: [PATCH 151/768] changed travis link for dev branch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d0a1163c6..a17b92702 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # IRremote Arduino Library -[![Build Status](https://travis-ci.org/z3t0/Arduino-IRremote.svg?branch=master)](https://travis-ci.org/z3t0/Arduino-IRremote) +[![Build Status](https://travis-ci.org/z3t0/Arduino-IRremote.svg?branch=dev)](https://travis-ci.org/z3t0/Arduino-IRremote) [![Join the chat at https://gitter.im/z3t0/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/z3t0/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From 3bdc6a65a65bdcc02f1b8b5a4a132d9ca8eaa5a5 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 21 Feb 2016 00:03:44 -0600 Subject: [PATCH 152/768] added support boards section in the readme --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a17b92702..94068a987 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,15 @@ Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more inf 4. Move the "IRremote" folder that has been extracted to your libraries directory. 5. Make sure to delete Arduino_Root/libraries/RobotIRremote. Where Arduino_Root refers to the install directory of Arduino. The library RobotIRremote has similar definitions to IRremote and causes errors. +## Supported Boards +- Arduino Uno / Mega / Leonardo / Duemilanove / Diecimila / LilyPad / Mini / Fio / Nano etc. +- Teensy 1.0 / 1.0++ / 2.0 / 2++ / 3.0 / 3.1 / Teensy-LC; Credits: @PaulStoffregen (Teensy Team) +- Sanguino +- Atmega8 +- ATtiny 84 / 85 + +We are open to suggestions for adding support to new boards, however we highly recommend you contact your supplier first and ask them to provide support from their side. + ## Usage - TODO (Check examples for now) @@ -27,7 +36,6 @@ If you want to contribute to this project: - Create issues and pull requests - Tell other people about this library - Contribute new protocols -- ## Contact The only way to contact me at the moment is by email: zetoslab@gmail.com From 9e2c41230c3b962fc324d294de944e3f0ede81b9 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 21 Feb 2016 00:13:00 -0600 Subject: [PATCH 153/768] added contribution guidelines --- Contributing.md | 11 +++++++++++ README.md | 2 ++ 2 files changed, 13 insertions(+) create mode 100644 Contributing.md diff --git a/Contributing.md b/Contributing.md new file mode 100644 index 000000000..81df23428 --- /dev/null +++ b/Contributing.md @@ -0,0 +1,11 @@ +# Contribution Guidlines + +This library is the culmination of the expertise of many members of the open source community who have dedicated their time and hard work. The best way to ask for help or propose a new idea is to [create a new issue](https://github.com/z3t0/Arduino-IRremote/issues/new) while creating a Pull Request with your code changes allows you to share your own innovations with the rest of the community. + +The following are some guidelines to observe when creating issues or PRs: +- Be friendly; it is important that we can all enjoy a safe space as we are all working on the same project and it is okay for people to have different ideas +- [Use code blocks](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code); it helps us help you when we can read your code! On that note also refrain from pasting more than 30 lines of code in a post, instead [create a gist](https://gist.github.com/) if you need to share large snippets +- Use reasonable titles; refrain from using overly long or capitalized titles as they are usually annoying and do little to encourage others to help :smile: +- Be detailed; refrain from mentioning code problems without sharing your source code and always give information regarding your board and version of the library + +If there is any need to contact me then you can find my email on the README, I do not mind responding to emails but it would be in your own interests to create issues if you need help with the library as responses would be from a larger community with greater knowledge! \ No newline at end of file diff --git a/README.md b/README.md index 94068a987..03fb6d2d5 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ If you want to contribute to this project: - Tell other people about this library - Contribute new protocols +Check [here](Contributing.md) for some guidelines. + ## Contact The only way to contact me at the moment is by email: zetoslab@gmail.com I am not currently monitoring any PRs or Issues due to other issues but will respond to all emails. If anyone wants contributor access, feel free to email me. Or if you find any Issues/PRs to be of importance that my attention is needed please email me. From cb01593db0d0591218e0b77c3fba8658a3ae0b93 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 21 Feb 2016 00:41:34 -0600 Subject: [PATCH 154/768] Contributing.md added hardware specs table --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 03fb6d2d5..826a04072 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,24 @@ Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more inf We are open to suggestions for adding support to new boards, however we highly recommend you contact your supplier first and ask them to provide support from their side. +### Hardware specifications + +| Board/CPU | Send Pin | Timers | +|------------------------------------------|--------------------|-------------------| +| Arduino Mega / ATmega 1280 / ATmega 2560 | 5, 6 **9**, 11, 46 | 1, **2**, 3, 4, 5 | +| Teensy 1.0 | **17** | **1** | +| Teensy 2.0 | 9, **10**, 14 | 1, 3, **4_HS** | +| Teensy++ 1.0 / 2.0 | **1**, 16, 25 | 1, **2**, 3 | +| Teensy 3.0 / 3.1 | **5** | **CMT** | +| Teensy-LC | **16** | **TPM1** | +| Sanguino | 13, **14** | 1, **2** | +| Atmega8 | **9** | **1** | +| ATtiny84 | **6** | **1** | +| ATtiny85 | **1** | **TINY0** | +| Arduino Duemilanove, UNO etc. | **3**, 9 | 1, **2** | + +The table above lists the currently supported timers and corresponding send pins, many of these can have additional pins opened up and we are open to requests if a need arises for other pins. + ## Usage - TODO (Check examples for now) From 17628525af20119c66fb963fe61b9c2697b7069d Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 21 Feb 2016 00:48:41 -0600 Subject: [PATCH 155/768] added ISSUE_TEMPLATE --- Contributing.md | 2 +- ISSUE_TEMPLATE.md | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 ISSUE_TEMPLATE.md diff --git a/Contributing.md b/Contributing.md index 81df23428..56409a9d2 100644 --- a/Contributing.md +++ b/Contributing.md @@ -6,6 +6,6 @@ The following are some guidelines to observe when creating issues or PRs: - Be friendly; it is important that we can all enjoy a safe space as we are all working on the same project and it is okay for people to have different ideas - [Use code blocks](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code); it helps us help you when we can read your code! On that note also refrain from pasting more than 30 lines of code in a post, instead [create a gist](https://gist.github.com/) if you need to share large snippets - Use reasonable titles; refrain from using overly long or capitalized titles as they are usually annoying and do little to encourage others to help :smile: -- Be detailed; refrain from mentioning code problems without sharing your source code and always give information regarding your board and version of the library +- Be detailed; refrain from mentioning code problems without sharing your source code and always give information regarding your board and version of the library If there is any need to contact me then you can find my email on the README, I do not mind responding to emails but it would be in your own interests to create issues if you need help with the library as responses would be from a larger community with greater knowledge! \ No newline at end of file diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..bb9232ea3 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,21 @@ +**Board:** ARDUINO UNO +**Library Version:** 2.1.0 +**Protocol:** Sony (if any) + +**Code Block:** +```c + +#include + +..... + +``` + +Use [a gist](gist.github.com) if the code exceeds 30 lines + +**checklist:** +- [] The latest [release](https://github.com/z3t0/Arduino-IRremote/releases/latest) is used +- [] Any code referenced is provided +- [] The title of the issue is helpful and relevant + +The above is a short template allowing you to make detailed issues! \ No newline at end of file From 0486c4f25a5ddaae30cabc7c8b5f1f1ad839ec7f Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 21 Feb 2016 00:50:49 -0600 Subject: [PATCH 156/768] change travis link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 826a04072..5ba7a6552 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # IRremote Arduino Library -[![Build Status](https://travis-ci.org/z3t0/Arduino-IRremote.svg?branch=dev)](https://travis-ci.org/z3t0/Arduino-IRremote) +[![Build Status](https://travis-ci.org/z3t0/Arduino-IRremote.svg?branch=master)](https://travis-ci.org/z3t0/Arduino-IRremote) [![Join the chat at https://gitter.im/z3t0/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/z3t0/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From 3aebf42ca8daa865ce8ae572245328e7443e438e Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 21 Feb 2016 01:03:15 -0600 Subject: [PATCH 157/768] typo --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 5ba7a6552..33c1d1158 100644 --- a/README.md +++ b/README.md @@ -28,19 +28,19 @@ We are open to suggestions for adding support to new boards, however we highly r ### Hardware specifications -| Board/CPU | Send Pin | Timers | -|------------------------------------------|--------------------|-------------------| -| Arduino Mega / ATmega 1280 / ATmega 2560 | 5, 6 **9**, 11, 46 | 1, **2**, 3, 4, 5 | -| Teensy 1.0 | **17** | **1** | -| Teensy 2.0 | 9, **10**, 14 | 1, 3, **4_HS** | -| Teensy++ 1.0 / 2.0 | **1**, 16, 25 | 1, **2**, 3 | -| Teensy 3.0 / 3.1 | **5** | **CMT** | -| Teensy-LC | **16** | **TPM1** | -| Sanguino | 13, **14** | 1, **2** | -| Atmega8 | **9** | **1** | -| ATtiny84 | **6** | **1** | -| ATtiny85 | **1** | **TINY0** | -| Arduino Duemilanove, UNO etc. | **3**, 9 | 1, **2** | +| Board/CPU | Send Pin | Timers | +|------------------------------------------|---------------------|-------------------| +| Arduino Mega / ATmega 1280 / ATmega 2560 | 5, 6, **9**, 11, 46 | 1, **2**, 3, 4, 5 | +| Teensy 1.0 | **17** | **1** | +| Teensy 2.0 | 9, **10**, 14 | 1, 3, **4_HS** | +| Teensy++ 1.0 / 2.0 | **1**, 16, 25 | 1, **2**, 3 | +| Teensy 3.0 / 3.1 | **5** | **CMT** | +| Teensy-LC | **16** | **TPM1** | +| Sanguino | 13, **14** | 1, **2** | +| Atmega8 | **9** | **1** | +| ATtiny84 | **6** | **1** | +| ATtiny85 | **1** | **TINY0** | +| Arduino Duemilanove, UNO etc. | **3**, 9 | 1, **2** | The table above lists the currently supported timers and corresponding send pins, many of these can have additional pins opened up and we are open to requests if a need arises for other pins. From cf7b49389c599d3d654e6f0105efe8c3f575d4ae Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 22 Mar 2016 23:09:07 -0600 Subject: [PATCH 158/768] added authors feel free to add your self --- library.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/library.json b/library.json index 3a29ecde4..8cd6ce057 100644 --- a/library.json +++ b/library.json @@ -8,5 +8,17 @@ "url": "https://github.com/shirriff/Arduino-IRremote.git" }, "frameworks": "arduino", - "platforms": "atmelavr" + "platforms": "atmelavr", + "authors" : + [ + { + name:"Rafi Khan", + email:"zetoslab@gmail.com" + } + + { + name:"Ken Shirriff", + email:"ken.shirriff@gmail.com" + } + ] } From fba0ee0ae5fe0d77034d0b4bde5c2021ace1620e Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Wed, 23 Mar 2016 01:06:24 -0600 Subject: [PATCH 159/768] fix syntax --- library.json | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/library.json b/library.json index 8cd6ce057..b08559f76 100644 --- a/library.json +++ b/library.json @@ -11,14 +11,13 @@ "platforms": "atmelavr", "authors" : [ - { - name:"Rafi Khan", - email:"zetoslab@gmail.com" - } - - { - name:"Ken Shirriff", - email:"ken.shirriff@gmail.com" - } - ] + { + "name":"Rafi Khan", + "email":"zetoslab@gmail.com" + }, + { + "name":"Ken Shirriff", + "email":"ken.shirriff@gmail.com" + } +] } From fc96667673f2ae3d0bd6f1bf380b0a26b03e4c4e Mon Sep 17 00:00:00 2001 From: AnalysIR Date: Sat, 26 Mar 2016 14:22:06 +0000 Subject: [PATCH 160/768] Fixed bug in ir_Dish.cpp for sending One of our users of AnalysIR, reported issues with sending DIsh signals. After some investigation we realised that this file was neglecting to send the trailing mark after the bits. Fix is included in this update & has been tested on a live Dish device by our own user. AnalysIR - 26th March 2016 ---------------------------------------- https://www.AnalysIR.com/ --- ir_Dish.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ir_Dish.cpp b/ir_Dish.cpp index 3dad8130d..fa8e06516 100644 --- a/ir_Dish.cpp +++ b/ir_Dish.cpp @@ -48,6 +48,7 @@ void IRsend::sendDISH (unsigned long data, int nbits) space(DISH_ZERO_SPACE); } } + mark(DISH_HDR_MARK); //added 26th March 2016, by AnalysIR ( https://www.AnalysIR.com ) } #endif From fa2f5f93523bd7f9c196717c07b626230646b81b Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sun, 27 Mar 2016 18:40:13 +0300 Subject: [PATCH 161/768] Use tagged/versioned source code from repo --- library.json | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/library.json b/library.json index b08559f76..b62b0de37 100644 --- a/library.json +++ b/library.json @@ -5,19 +5,20 @@ "repository": { "type": "git", - "url": "https://github.com/shirriff/Arduino-IRremote.git" + "url": "https://github.com/z3t0/Arduino-IRremote.git" }, + "version": "2.1.0", "frameworks": "arduino", "platforms": "atmelavr", "authors" : [ { - "name":"Rafi Khan", - "email":"zetoslab@gmail.com" + "name":"Rafi Khan", + "email":"zetoslab@gmail.com" }, { - "name":"Ken Shirriff", - "email":"ken.shirriff@gmail.com" + "name":"Ken Shirriff", + "email":"ken.shirriff@gmail.com" } -] + ] } From f04b014da5f2e6c2bb36582edda1cd50cdd6fee2 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sun, 27 Mar 2016 18:43:02 +0300 Subject: [PATCH 162/768] Cache PlatformIO packages using Travis CI container-based infrastructure --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f4b1ba001..72fb6659b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,12 @@ language: python python: - "2.7" + +# Cache PlatformIO packages using Travis CI container-based infrastructure +sudo: false +cache: + directories: + - "~/.platformio" env: - PLATFORMIO_CI_SRC=examples/AiwaRCT501SendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_AIWA_RC_T501" @@ -16,7 +22,7 @@ env: - PLATFORMIO_CI_SRC=examples/IRremoteInfo install: - - python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)" + - pip install -U platformio script: - platformio ci --lib="." --board=uno --board=leonardo --board=pro16MHzatmega168 From 34e5cd87ca553bcdfbfcb62a69bbe3f2bafa2bc5 Mon Sep 17 00:00:00 2001 From: Philipp Henkel Date: Wed, 27 Apr 2016 21:57:57 +0200 Subject: [PATCH 163/768] Add Lego Power Functions send protocol --- .travis.yml | 1 + IRremote.h | 14 +- .../LegoPowerFunctionsSendDemo.ino | 22 +++ irRecv.cpp | 9 +- ir_Lego_PF.cpp | 130 ++++++++++++++++++ 5 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino create mode 100644 ir_Lego_PF.cpp diff --git a/.travis.yml b/.travis.yml index 72fb6659b..d62004f8f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ env: - PLATFORMIO_CI_SRC=examples/IRtest PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" - PLATFORMIO_CI_SRC=examples/IRtest2 PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" - PLATFORMIO_CI_SRC=examples/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC" + - PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF" - PLATFORMIO_CI_SRC=examples/IRremoteInfo install: diff --git a/IRremote.h b/IRremote.h index 96d82ca71..fe1a87029 100644 --- a/IRremote.h +++ b/IRremote.h @@ -56,7 +56,7 @@ #define SEND_AIWA_RC_T501 1 #define DECODE_LG 1 -#define SEND_LG 1 +#define SEND_LG 1 #define DECODE_SANYO 1 #define SEND_SANYO 0 // NOT WRITTEN @@ -76,6 +76,9 @@ #define DECODE_PRONTO 0 // This function doe not logically make sense #define SEND_PRONTO 1 +#define DECODE_LEGO_PF 0 // NOT WRITTEN +#define SEND_LEGO_PF 1 + //------------------------------------------------------------------------------ // When sending a Pronto code we request to send either the "once" code // or the "repeat" code @@ -115,6 +118,7 @@ typedef SHARP, DENON, PRONTO, + LEGO_PF, } decode_type_t; @@ -243,6 +247,10 @@ class IRrecv # if DECODE_DENON bool decodeDenon (decode_results *results) ; # endif +//...................................................................... +# if DECODE_LEGO_PF + bool decodeLegoPowerFunctions (decode_results *results) ; +# endif } ; //------------------------------------------------------------------------------ @@ -327,6 +335,10 @@ class IRsend # if SEND_PRONTO void sendPronto (char* code, bool repeat, bool fallback) ; # endif +//...................................................................... +# if SEND_LEGO_PF + void sendLegoPowerFunctions (uint16_t data, bool repeat = true) ; +# endif } ; #endif diff --git a/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino b/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino new file mode 100644 index 000000000..e43d06c2e --- /dev/null +++ b/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino @@ -0,0 +1,22 @@ +/* + * LegoPowerFunctionsSendDemo: LEGO Power Functions + * Copyright (c) 2016 Philipp Henkel + */ + +#include +#include + +IRsend irsend; + +void setup() { +} + +void loop() { + // Send repeated command "channel 1, blue forward, red backward" + irsend.sendLegoPowerFunctions(0x197); + delay(2000); + + // Send single command "channel 1, blue forward, red backward" + irsend.sendLegoPowerFunctions(0x197, false); + delay(2000); +} diff --git a/irRecv.cpp b/irRecv.cpp index a3ff452e0..63438566a 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -80,6 +80,11 @@ int IRrecv::decode (decode_results *results) if (decodeDenon(results)) return true ; #endif +#if DECODE_LEGO_PF + DBG_PRINTLN("Attempting Lego Power Functions"); + if (decodeLegoPowerFunctions(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. @@ -145,8 +150,8 @@ void IRrecv::blink13 (int blinkflag) //+============================================================================= // Return if receiving new IR signals -// -bool IRrecv::isIdle ( ) +// +bool IRrecv::isIdle ( ) { return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false; } diff --git a/ir_Lego_PF.cpp b/ir_Lego_PF.cpp new file mode 100644 index 000000000..dc94243ec --- /dev/null +++ b/ir_Lego_PF.cpp @@ -0,0 +1,130 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// L EEEEEE EEEE OOOO +// L E E O O +// L EEEE E EEE O O +// L E E E O O LEGO Power Functions +// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016 Philipp Henkel +//============================================================================== + +//+============================================================================= +// +#if SEND_LEGO_PF + +class BitStreamEncoder { + private: + uint16_t data; + bool repeatMessage; + int messageBitIdx; + int repeatCount; + int messageLength; + + // HIGH data bit = IR mark + high pause + // LOW data bit = IR mark + low pause + static const int LOW_BIT_DURATION = 421; + static const int HIGH_BIT_DURATION = 711; + static const int START_BIT_DURATION = 1184; + static const int STOP_BIT_DURATION = 1184; + static const int IR_MARK_DURATION = 158; + static const int HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; + static const int LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; + static const int START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; + static const int STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; + static const int MESSAGE_BITS = 18; + static const int MAX_MESSAGE_LENGTH = 16000; + + public: + void reset(uint16_t data, bool repeatMessage) { + this->data = data; + this->repeatMessage = repeatMessage; + messageBitIdx = 0; + repeatCount = 0; + messageLength = getMessageLength(); + } + + int getChannelId() const { return 1 + ((data >> 12) & 0x3); } + + int getMessageLength() const { + // Sum up all marks + int length = MESSAGE_BITS * IR_MARK_DURATION; + + // Sum up all pauses + length += START_PAUSE_DURATION; + for (unsigned long mask = 1UL << 15; mask; mask >>= 1) { + if (data & mask) { + length += HIGH_PAUSE_DURATION; + } else { + length += LOW_PAUSE_DURATION; + } + } + length += STOP_PAUSE_DURATION; + return length; + } + + boolean next() { + messageBitIdx++; + if (messageBitIdx >= MESSAGE_BITS) { + repeatCount++; + messageBitIdx = 0; + } + if (repeatCount >= 1 && !repeatMessage) { + return false; + } else if (repeatCount >= 5) { + return false; + } else { + return true; + } + } + + int getMarkDuration() const { return IR_MARK_DURATION; } + + int getPauseDuration() const { + if (messageBitIdx == 0) + return START_PAUSE_DURATION; + else if (messageBitIdx < MESSAGE_BITS - 1) { + return getDataBitPause(); + } else { + return getStopPause(); + } + } + + private: + int getDataBitPause() const { + const int pos = MESSAGE_BITS - 2 - messageBitIdx; + const bool isHigh = data & (1 << pos); + return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION; + } + + int getStopPause() const { + if (repeatMessage) { + return getRepeatStopPause(); + } else { + return STOP_PAUSE_DURATION; + } + } + + int getRepeatStopPause() const { + if (repeatCount == 0 || repeatCount == 1) { + return STOP_PAUSE_DURATION + 5 * MAX_MESSAGE_LENGTH - messageLength; + } else if (repeatCount == 2 || repeatCount == 3) { + return STOP_PAUSE_DURATION + + (6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; + } else { + return STOP_PAUSE_DURATION; + } + } +}; + +void IRsend::sendLegoPowerFunctions(uint16_t data, bool repeat) +{ + enableIROut(38); + static BitStreamEncoder bitStreamEncoder; + bitStreamEncoder.reset(data, repeat); + do { + mark(bitStreamEncoder.getMarkDuration()); + space(bitStreamEncoder.getPauseDuration()); + } while (bitStreamEncoder.next()); +} +#endif From d0f1d0d33d18b9aa8dd2eddb3ed096a730f660de Mon Sep 17 00:00:00 2001 From: Philipp Henkel Date: Wed, 27 Apr 2016 23:51:56 +0200 Subject: [PATCH 164/768] =?UTF-8?q?Add=20supported=20device=20LEGO=C2=AE?= =?UTF-8?q?=20Power=20Functions=20IR=20Receiver=208884?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ir_Lego_PF.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ir_Lego_PF.cpp b/ir_Lego_PF.cpp index dc94243ec..2196bed6f 100644 --- a/ir_Lego_PF.cpp +++ b/ir_Lego_PF.cpp @@ -9,6 +9,9 @@ // LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016 Philipp Henkel //============================================================================== +// Supported Devices +// LEGO® Power Functions IR Receiver 8884 + //+============================================================================= // #if SEND_LEGO_PF From 92c7f0013869fd1289eebb1391861557783e8e68 Mon Sep 17 00:00:00 2001 From: Philipp Henkel Date: Wed, 4 May 2016 22:08:52 +0200 Subject: [PATCH 165/768] Update changelog and contributors --- Contributors.md | 5 ++--- changelog.md | 9 ++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Contributors.md b/Contributors.md index 6988f52d0..1b559fea8 100644 --- a/Contributors.md +++ b/Contributors.md @@ -1,5 +1,5 @@ ## Contributors -These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions. +These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions. - [z3t0](https://github.com/z3t0) : Active Contributor and currently also the main contributor. * Email: zetoslab@gmail.com @@ -15,7 +15,6 @@ These are the active contributors of this project that you may contact if there - [Sebazzz](https://github.com/sebazz): Contributor - [lumbric](https://github.com/lumbric): Contributor - [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor +- [henkel](https://github.com/henkel): Contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. - - diff --git a/changelog.md b/changelog.md index 2901dd167..41a214f18 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +## 2.1.1 - 2016/05/04 +- Added Lego Power Functions Protocol [PR #309](https://github.com/z3t0/Arduino-IRremote/pull/309) + ## 2.1.0 - 2016/02/20 - Improved Debugging [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258) - Display TIME instead of TICKS [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258) @@ -15,7 +18,7 @@ ## 2.0.1 - 2015/07/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA) ### Changes - Updated README -- Updated Contributors +- Updated Contributors - Fixed #110 Mess - Created Gitter Room - Added Gitter Badge @@ -35,7 +38,7 @@ - Added Denon Protocol - Added Pronto Support - Added Library Properties -- Added Template For New Protocols +- Added Template For New Protocols - Added this changelog - Added Teensy LC Support - Added ATtiny84 Support @@ -44,7 +47,7 @@ ### Deletions - Removed (Fixed) #110 -- Broke Teensy 3 / 3.1 Support +- Broke Teensy 3 / 3.1 Support ### Not Working - Teensy 3 / 3.1 Support is in Development From e7e5465b74abb1170f53799be472beae342db723 Mon Sep 17 00:00:00 2001 From: Hans Date: Sun, 26 Jun 2016 11:10:26 +0200 Subject: [PATCH 166/768] Added support for more ATmegas! Support for ATmega8535, ATmega16, ATmega32, ATmega64, ATmega128, ATmega164, ATmega324, ATmega644 and ATmega1284 --- IRremoteInt.h | 51 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index 125eb7205..b6f54526d 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -184,13 +184,31 @@ EXTERN volatile irparams_t irparams; #define IR_USE_TIMER2 // tx = pin 1 //#define IR_USE_TIMER3 // tx = pin 16 -// Sanguino -#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) +// MightyCore - ATmega1284 +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) + //#define IR_USE_TIMER1 // tx = pin 13 + #define IR_USE_TIMER2 // tx = pin 14 + //#define IR_USE_TIMER3 // tx = pin 6 + +// MightyCore - ATmega164, ATmega324, ATmega644 +#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) //#define IR_USE_TIMER1 // tx = pin 13 #define IR_USE_TIMER2 // tx = pin 14 + +//MegaCore - ATmega64, ATmega128 +#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) + #define IR_USE_TIMER1 // tx = pin 13 + +// MightyCore - ATmega8535, ATmega16, ATmega32 +#elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) + #define IR_USE_TIMER1 // tx = pin 13 + // Atmega8 -#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) +#elif defined(__AVR_ATmega8__) #define IR_USE_TIMER1 // tx = pin 9 // ATtiny84 @@ -255,8 +273,12 @@ EXTERN volatile irparams_t irparams; # define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy #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 +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ +|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) +# define TIMER_PWM_PIN 14 // MightyCore #else # define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc #endif @@ -271,7 +293,9 @@ EXTERN volatile irparams_t irparams; #define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) //----------------- -#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) +#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8535__) \ +|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ +|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) # define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) # define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) #else @@ -302,10 +326,17 @@ EXTERN volatile irparams_t irparams; # define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy #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 +#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) +# define TIMER_PWM_PIN 13 // MegaCore +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ +|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ +|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) +# define TIMER_PWM_PIN 13 // MightyCore #elif defined(__AVR_ATtiny84__) -# define TIMER_PWM_PIN 6 +# define TIMER_PWM_PIN 6 #else # define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc #endif @@ -342,6 +373,8 @@ EXTERN volatile irparams_t irparams; # define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) # define TIMER_PWM_PIN 5 // Arduino Mega +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) +# define TIMER_PWM_PIN 6 // MightyCore #else # error "Please add OC3A pin number here\n" #endif From d5658f4488e70eb52e81649cd8f8fe6958347f04 Mon Sep 17 00:00:00 2001 From: Hans Date: Sun, 26 Jun 2016 11:33:46 +0200 Subject: [PATCH 167/768] Update IRremoteInt.h --- IRremoteInt.h | 1 - 1 file changed, 1 deletion(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index b6f54526d..ca18bcd97 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -205,7 +205,6 @@ EXTERN volatile irparams_t irparams; // MightyCore - ATmega8535, ATmega16, ATmega32 #elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) #define IR_USE_TIMER1 // tx = pin 13 - // Atmega8 #elif defined(__AVR_ATmega8__) From 38c1e017a291e91721aa04871df486c10ca79cf6 Mon Sep 17 00:00:00 2001 From: Hans Date: Sun, 26 Jun 2016 11:43:22 +0200 Subject: [PATCH 168/768] Added more microcontrollers --- README.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 33c1d1158..929757af7 100644 --- a/README.md +++ b/README.md @@ -28,19 +28,22 @@ We are open to suggestions for adding support to new boards, however we highly r ### Hardware specifications -| Board/CPU | Send Pin | Timers | -|------------------------------------------|---------------------|-------------------| -| Arduino Mega / ATmega 1280 / ATmega 2560 | 5, 6, **9**, 11, 46 | 1, **2**, 3, 4, 5 | -| Teensy 1.0 | **17** | **1** | -| Teensy 2.0 | 9, **10**, 14 | 1, 3, **4_HS** | -| Teensy++ 1.0 / 2.0 | **1**, 16, 25 | 1, **2**, 3 | -| Teensy 3.0 / 3.1 | **5** | **CMT** | -| Teensy-LC | **16** | **TPM1** | -| Sanguino | 13, **14** | 1, **2** | -| Atmega8 | **9** | **1** | -| ATtiny84 | **6** | **1** | -| ATtiny85 | **1** | **TINY0** | -| Arduino Duemilanove, UNO etc. | **3**, 9 | 1, **2** | +| Board/CPU | Send Pin | Timers | +|--------------------------------------------------------------------------|---------------------|-------------------| +| [ATtiny84](https://github.com/SpenceKonde/ATTinyCore) | **6** | **1** | +| [ATtiny85](https://github.com/SpenceKonde/ATTinyCore) | **1** | **TINY0** | +| ATmega8 | **9** | **1** | +| ATmega168, ATmega328 | **3**, 9 | 1, **2** | +| [ATmega1284](https://github.com/MCUdude/MightyCore) | 13, 14, 6 | 1, **2**, 3 | +| [ATmega164, ATmega324, ATmega644](https://github.com/MCUdude/MightyCore) | 13, **14** | 1, **2** | +| [ATmega8535 ATmega16, ATmega32](https://github.com/MCUdude/MightyCore) | **13** | **1** | +| [ATmega64, ATmega128](https://github.com/MCUdude/MegaCore) | **13** | **1** | +| ATmega1280, ATmega2560 | 5, 6, **9**, 11, 46 | 1, **2**, 3, 4, 5 | +| [Teensy 1.0](https://www.pjrc.com/teensy/) | **17** | **1** | +| [Teensy 2.0](https://www.pjrc.com/teensy/) | 9, **10**, 14 | 1, 3, **4_HS** | +| [Teensy++ 1.0 / 2.0](https://www.pjrc.com/teensy/) | **1**, 16, 25 | 1, **2**, 3 | +| [Teensy 3.0 / 3.1](https://www.pjrc.com/teensy/) | **5** | **CMT** | +| [Teensy-LC](https://www.pjrc.com/teensy/) | **16** | **TPM1** | The table above lists the currently supported timers and corresponding send pins, many of these can have additional pins opened up and we are open to requests if a need arises for other pins. From bc15ded405dad94ccb4be6e09fd5c7ff75c5a646 Mon Sep 17 00:00:00 2001 From: Hans Date: Sun, 26 Jun 2016 12:02:25 +0200 Subject: [PATCH 169/768] Added more microcontrollers to the list --- examples/IRremoteInfo/IRremoteInfo.ino | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/examples/IRremoteInfo/IRremoteInfo.ino b/examples/IRremoteInfo/IRremoteInfo.ino index bc13c5d12..55db6608f 100644 --- a/examples/IRremoteInfo/IRremoteInfo.ino +++ b/examples/IRremoteInfo/IRremoteInfo.ino @@ -107,8 +107,24 @@ void dumpPlatform() { Serial.println(F("Teensy++ 1.0 / AT90USB646")); #elif defined(__AVR_AT90USB1286__) Serial.println(F("Teensy++ 2.0 / AT90USB1286")); -#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) - Serial.println(F("Sanguino / ATmega644(P)")); +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) + Serial.println(F("ATmega1284")); +#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) + Serial.println(F("ATmega644")); +#elif defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) || defined(__AVR_ATmega324PA__) + Serial.println(F("ATmega324")); +#elif defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164P__) + Serial.println(F("ATmega164")); +#elif defined(__AVR_ATmega128__) + Serial.println(F("ATmega128")); +#elif defined(__AVR_ATmega64__) + Serial.println(F("ATmega64")); +#elif defined(__AVR_ATmega32__) + Serial.println(F("ATmega32")); +#elif defined(__AVR_ATmega16__) + Serial.println(F("ATmega16")); +#elif defined(__AVR_ATmega8535__) + Serial.println(F("ATmega8535")); #elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) Serial.println(F("Atmega8 / ATmega8(P)")); #elif defined(__AVR_ATtiny84__) From f9a41c99c801a6a1d2ce6d8252dbcf6b0375c3a5 Mon Sep 17 00:00:00 2001 From: Hans Date: Sun, 26 Jun 2016 12:04:52 +0200 Subject: [PATCH 170/768] There's no such thing as an ATmega8P --- examples/IRremoteInfo/IRremoteInfo.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/IRremoteInfo/IRremoteInfo.ino b/examples/IRremoteInfo/IRremoteInfo.ino index 55db6608f..b44097767 100644 --- a/examples/IRremoteInfo/IRremoteInfo.ino +++ b/examples/IRremoteInfo/IRremoteInfo.ino @@ -125,8 +125,8 @@ void dumpPlatform() { Serial.println(F("ATmega16")); #elif defined(__AVR_ATmega8535__) Serial.println(F("ATmega8535")); -#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) - Serial.println(F("Atmega8 / ATmega8(P)")); +#elif defined(__AVR_ATmega8__) + Serial.println(F("Atmega8")); #elif defined(__AVR_ATtiny84__) Serial.println(F("ATtiny84")); #elif defined(__AVR_ATtiny85__) From bb1470a029e6dd891d71375f3a50de9f0cb14d2c Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 28 Jun 2016 00:59:20 -0600 Subject: [PATCH 171/768] added changelog --- README.md | 4 ++-- changelog.md | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 929757af7..1312ef222 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This library enables you to send and receive using infra-red signals on an Ardui Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more information. -## Version - 2.1.0 +## Version - 2.2.0 ## Installation 1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. @@ -21,7 +21,7 @@ Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more inf - Arduino Uno / Mega / Leonardo / Duemilanove / Diecimila / LilyPad / Mini / Fio / Nano etc. - Teensy 1.0 / 1.0++ / 2.0 / 2++ / 3.0 / 3.1 / Teensy-LC; Credits: @PaulStoffregen (Teensy Team) - Sanguino -- Atmega8 +- Atmega8535, 8, 16, 32, 164, 324, 644, 1284, 64, 128 - ATtiny 84 / 85 We are open to suggestions for adding support to new boards, however we highly recommend you contact your supplier first and ask them to provide support from their side. diff --git a/changelog.md b/changelog.md index 41a214f18..297ffd479 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,16 @@ +## 2.2.0 - 2016/06/28 +- Added support for ATmega8535 +- Added support for ATmega16 +- Added support for ATmega32 +- Added support for ATmega164 +- Added support for ATmega324 +- Added support for ATmega644 +- Added support for ATmega1284 +- Added support for ATmega64 +- Added support for ATmega128 + +[PR](https://github.com/z3t0/Arduino-IRremote/pull/324) + ## 2.1.1 - 2016/05/04 - Added Lego Power Functions Protocol [PR #309](https://github.com/z3t0/Arduino-IRremote/pull/309) From 978284d55fda59220e8add85eecafe520625f1f6 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 28 Jun 2016 01:10:24 -0600 Subject: [PATCH 172/768] slightly modified travis - TODO support more boards --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d62004f8f..ce01e805f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,4 +26,4 @@ install: - pip install -U platformio script: - - platformio ci --lib="." --board=uno --board=leonardo --board=pro16MHzatmega168 + - platformio ci --lib="." --board=uno --board=leonardo --board=pro16MHzatmega168 --board=btatmega328 From e5dc3e108ed3181ae93f181c5f253e80ded0dcf0 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 10 Jul 2016 23:42:23 -0500 Subject: [PATCH 173/768] Added Leonardo to hardware table #224 #281 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1312ef222..d89580692 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ We are open to suggestions for adding support to new boards, however we highly r | [ATtiny84](https://github.com/SpenceKonde/ATTinyCore) | **6** | **1** | | [ATtiny85](https://github.com/SpenceKonde/ATTinyCore) | **1** | **TINY0** | | ATmega8 | **9** | **1** | +| Atmega32u4 | 5, 9, **13** | 1, 3, **4** | | ATmega168, ATmega328 | **3**, 9 | 1, **2** | | [ATmega1284](https://github.com/MCUdude/MightyCore) | 13, 14, 6 | 1, **2**, 3 | | [ATmega164, ATmega324, ATmega644](https://github.com/MCUdude/MightyCore) | 13, **14** | 1, **2** | From d28b6f985c45d3958441034d4f5f89fe8b3395ec Mon Sep 17 00:00:00 2001 From: Philipp Henkel Date: Tue, 12 Jul 2016 23:14:47 +0200 Subject: [PATCH 174/768] Add Lego Power Functions tests --- .travis.yml | 1 + .../LegoPowerFunctionsTests.ino | 197 ++++++++++++++++++ ir_Lego_PF.cpp | 123 ++--------- ir_Lego_PF_BitStreamEncoder.h | 115 ++++++++++ 4 files changed, 331 insertions(+), 105 deletions(-) create mode 100644 examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino create mode 100644 ir_Lego_PF_BitStreamEncoder.h diff --git a/.travis.yml b/.travis.yml index ce01e805f..543a0a74b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ env: - PLATFORMIO_CI_SRC=examples/IRtest2 PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" - PLATFORMIO_CI_SRC=examples/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC" - PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF" + - PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsTests PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF" - PLATFORMIO_CI_SRC=examples/IRremoteInfo install: diff --git a/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino b/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino new file mode 100644 index 000000000..6a2bda57d --- /dev/null +++ b/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino @@ -0,0 +1,197 @@ +/* + * LegoPowerFunctionsTest: LEGO Power Functions Tests + * Copyright (c) 2016 Philipp Henkel + */ + +#include + +void setup() { + Serial.begin(9600); + delay(1000); // wait for reset triggered by serial connection + runBitStreamEncoderTests(); +} + +void loop() { +} + +void runBitStreamEncoderTests() { + Serial.println(); + Serial.println("BitStreamEncoder Tests"); + static LegoPfBitStreamEncoder bitStreamEncoder; + testStartBit(bitStreamEncoder); + testLowBit(bitStreamEncoder); + testHighBit(bitStreamEncoder); + testMessageBitCount(bitStreamEncoder); + testMessageBitCountRepeat(bitStreamEncoder); + testMessage407(bitStreamEncoder); + testMessage407Repeated(bitStreamEncoder); + testGetChannelId1(bitStreamEncoder); + testGetChannelId2(bitStreamEncoder); + testGetChannelId3(bitStreamEncoder); + testGetChannelId4(bitStreamEncoder); + testGetMessageLengthAllHigh(bitStreamEncoder); + testGetMessageLengthAllLow(bitStreamEncoder); +} + +void logTestResult(bool testPassed) { + if (testPassed) { + Serial.println("OK"); + } + else { + Serial.println("FAIL ############"); + } +} + +void testStartBit(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testStartBit "); + bitStreamEncoder.reset(0, false); + int startMark = bitStreamEncoder.getMarkDuration(); + int startPause = bitStreamEncoder.getPauseDuration(); + logTestResult(startMark == 158 && startPause == 1184-158); +} + +void testLowBit(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testLowBit "); + bitStreamEncoder.reset(0, false); + bitStreamEncoder.next(); + int lowMark = bitStreamEncoder.getMarkDuration(); + int lowPause = bitStreamEncoder.getPauseDuration(); + logTestResult(lowMark == 158 && lowPause == 421-158); +} + +void testHighBit(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testHighBit "); + bitStreamEncoder.reset(0xFFFF, false); + bitStreamEncoder.next(); + int highMark = bitStreamEncoder.getMarkDuration(); + int highPause = bitStreamEncoder.getPauseDuration(); + logTestResult(highMark == 158 && highPause == 711-158); +} + +void testMessageBitCount(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessageBitCount "); + bitStreamEncoder.reset(0xFFFF, false); + int bitCount = 1; + while (bitStreamEncoder.next()) { + bitCount++; + } + logTestResult(bitCount == 18); +} + +boolean check(LegoPfBitStreamEncoder& bitStreamEncoder, int markDuration, int pauseDuration) { + bool result = true; + result = result && bitStreamEncoder.getMarkDuration() == markDuration; + result = result && bitStreamEncoder.getPauseDuration() == pauseDuration; + return result; +} + +boolean checkNext(LegoPfBitStreamEncoder& bitStreamEncoder, int markDuration, int pauseDuration) { + bool result = bitStreamEncoder.next(); + result = result && check(bitStreamEncoder, markDuration, pauseDuration); + return result; +} + +boolean checkDataBitsOfMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) { + bool result = true; + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 553); + return result; +} + +void testMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessage407 "); + bitStreamEncoder.reset(407, false); + bool result = true; + result = result && check(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && !bitStreamEncoder.next(); + logTestResult(result); +} + +void testMessage407Repeated(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessage407Repeated "); + bitStreamEncoder.reset(407, true); + bool result = true; + result = result && check(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026 + 5 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026 + 5 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026 + 8 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026 + 8 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && !bitStreamEncoder.next(); + logTestResult(result); +} + +void testMessageBitCountRepeat(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessageBitCountRepeat "); + bitStreamEncoder.reset(0xFFFF, true); + int bitCount = 1; + while (bitStreamEncoder.next()) { + bitCount++; + } + logTestResult(bitCount == 5*18); +} + +void testGetChannelId1(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId1 "); + bitStreamEncoder.reset(407, false); + logTestResult(bitStreamEncoder.getChannelId() == 1); +} + +void testGetChannelId2(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId2 "); + bitStreamEncoder.reset(4502, false); + logTestResult(bitStreamEncoder.getChannelId() == 2); +} + +void testGetChannelId3(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId3 "); + bitStreamEncoder.reset(8597, false); + logTestResult(bitStreamEncoder.getChannelId() == 3); +} + +void testGetChannelId4(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId4 "); + bitStreamEncoder.reset(12692, false); + logTestResult(bitStreamEncoder.getChannelId() == 4); +} + +void testGetMessageLengthAllHigh(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetMessageLengthAllHigh "); + bitStreamEncoder.reset(0xFFFF, false); + logTestResult(bitStreamEncoder.getMessageLength() == 13744); +} + +void testGetMessageLengthAllLow(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetMessageLengthAllLow "); + bitStreamEncoder.reset(0x0, false); + logTestResult(bitStreamEncoder.getMessageLength() == 9104); +} + + + + diff --git a/ir_Lego_PF.cpp b/ir_Lego_PF.cpp index 2196bed6f..37d507ceb 100644 --- a/ir_Lego_PF.cpp +++ b/ir_Lego_PF.cpp @@ -1,5 +1,6 @@ #include "IRremote.h" #include "IRremoteInt.h" +#include "ir_Lego_PF_BitStreamEncoder.h" //============================================================================== // L EEEEEE EEEE OOOO @@ -16,118 +17,30 @@ // #if SEND_LEGO_PF -class BitStreamEncoder { - private: - uint16_t data; - bool repeatMessage; - int messageBitIdx; - int repeatCount; - int messageLength; - - // HIGH data bit = IR mark + high pause - // LOW data bit = IR mark + low pause - static const int LOW_BIT_DURATION = 421; - static const int HIGH_BIT_DURATION = 711; - static const int START_BIT_DURATION = 1184; - static const int STOP_BIT_DURATION = 1184; - static const int IR_MARK_DURATION = 158; - static const int HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; - static const int LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; - static const int START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; - static const int STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; - static const int MESSAGE_BITS = 18; - static const int MAX_MESSAGE_LENGTH = 16000; - - public: - void reset(uint16_t data, bool repeatMessage) { - this->data = data; - this->repeatMessage = repeatMessage; - messageBitIdx = 0; - repeatCount = 0; - messageLength = getMessageLength(); - } - - int getChannelId() const { return 1 + ((data >> 12) & 0x3); } - - int getMessageLength() const { - // Sum up all marks - int length = MESSAGE_BITS * IR_MARK_DURATION; - - // Sum up all pauses - length += START_PAUSE_DURATION; - for (unsigned long mask = 1UL << 15; mask; mask >>= 1) { - if (data & mask) { - length += HIGH_PAUSE_DURATION; - } else { - length += LOW_PAUSE_DURATION; - } - } - length += STOP_PAUSE_DURATION; - return length; - } - - boolean next() { - messageBitIdx++; - if (messageBitIdx >= MESSAGE_BITS) { - repeatCount++; - messageBitIdx = 0; - } - if (repeatCount >= 1 && !repeatMessage) { - return false; - } else if (repeatCount >= 5) { - return false; - } else { - return true; - } - } - - int getMarkDuration() const { return IR_MARK_DURATION; } - - int getPauseDuration() const { - if (messageBitIdx == 0) - return START_PAUSE_DURATION; - else if (messageBitIdx < MESSAGE_BITS - 1) { - return getDataBitPause(); - } else { - return getStopPause(); - } - } - - private: - int getDataBitPause() const { - const int pos = MESSAGE_BITS - 2 - messageBitIdx; - const bool isHigh = data & (1 << pos); - return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION; - } - - int getStopPause() const { - if (repeatMessage) { - return getRepeatStopPause(); - } else { - return STOP_PAUSE_DURATION; - } - } - - int getRepeatStopPause() const { - if (repeatCount == 0 || repeatCount == 1) { - return STOP_PAUSE_DURATION + 5 * MAX_MESSAGE_LENGTH - messageLength; - } else if (repeatCount == 2 || repeatCount == 3) { - return STOP_PAUSE_DURATION - + (6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; - } else { - return STOP_PAUSE_DURATION; - } - } -}; +#if DEBUG +namespace { +void logFunctionParameters(uint16_t data, bool repeat) { + DBG_PRINT("sendLegoPowerFunctions(data="); + DBG_PRINT(data); + DBG_PRINT(", repeat="); + DBG_PRINTLN(repeat?"true)" : "false)"); +} +} // anonymous namespace +#endif // DEBUG void IRsend::sendLegoPowerFunctions(uint16_t data, bool repeat) { +#if DEBUG + ::logFunctionParameters(data, repeat); +#endif // DEBUG + enableIROut(38); - static BitStreamEncoder bitStreamEncoder; + static LegoPfBitStreamEncoder bitStreamEncoder; bitStreamEncoder.reset(data, repeat); do { mark(bitStreamEncoder.getMarkDuration()); space(bitStreamEncoder.getPauseDuration()); } while (bitStreamEncoder.next()); } -#endif + +#endif // SEND_LEGO_PF diff --git a/ir_Lego_PF_BitStreamEncoder.h b/ir_Lego_PF_BitStreamEncoder.h new file mode 100644 index 000000000..7689cde28 --- /dev/null +++ b/ir_Lego_PF_BitStreamEncoder.h @@ -0,0 +1,115 @@ + +//============================================================================== +// L EEEEEE EEEE OOOO +// L E E O O +// L EEEE E EEE O O +// L E E E O O LEGO Power Functions +// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016 Philipp Henkel +//============================================================================== + +//+============================================================================= +// + +class LegoPfBitStreamEncoder { + private: + uint16_t data; + bool repeatMessage; + int messageBitIdx; + int repeatCount; + int messageLength; + + // HIGH data bit = IR mark + high pause + // LOW data bit = IR mark + low pause + static const int LOW_BIT_DURATION = 421; + static const int HIGH_BIT_DURATION = 711; + static const int START_BIT_DURATION = 1184; + static const int STOP_BIT_DURATION = 1184; + static const int IR_MARK_DURATION = 158; + static const int HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; + static const int LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; + static const int START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; + static const int STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; + static const int MESSAGE_BITS = 18; + static const int MAX_MESSAGE_LENGTH = 16000; + + public: + void reset(uint16_t data, bool repeatMessage) { + this->data = data; + this->repeatMessage = repeatMessage; + messageBitIdx = 0; + repeatCount = 0; + messageLength = getMessageLength(); + } + + int getChannelId() const { return 1 + ((data >> 12) & 0x3); } + + int getMessageLength() const { + // Sum up all marks + int length = MESSAGE_BITS * IR_MARK_DURATION; + + // Sum up all pauses + length += START_PAUSE_DURATION; + for (unsigned long mask = 1UL << 15; mask; mask >>= 1) { + if (data & mask) { + length += HIGH_PAUSE_DURATION; + } else { + length += LOW_PAUSE_DURATION; + } + } + length += STOP_PAUSE_DURATION; + return length; + } + + boolean next() { + messageBitIdx++; + if (messageBitIdx >= MESSAGE_BITS) { + repeatCount++; + messageBitIdx = 0; + } + if (repeatCount >= 1 && !repeatMessage) { + return false; + } else if (repeatCount >= 5) { + return false; + } else { + return true; + } + } + + int getMarkDuration() const { return IR_MARK_DURATION; } + + int getPauseDuration() const { + if (messageBitIdx == 0) + return START_PAUSE_DURATION; + else if (messageBitIdx < MESSAGE_BITS - 1) { + return getDataBitPause(); + } else { + return getStopPause(); + } + } + + private: + int getDataBitPause() const { + const int pos = MESSAGE_BITS - 2 - messageBitIdx; + const bool isHigh = data & (1 << pos); + return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION; + } + + int getStopPause() const { + if (repeatMessage) { + return getRepeatStopPause(); + } else { + return STOP_PAUSE_DURATION; + } + } + + int getRepeatStopPause() const { + if (repeatCount == 0 || repeatCount == 1) { + return STOP_PAUSE_DURATION + 5 * MAX_MESSAGE_LENGTH - messageLength; + } else if (repeatCount == 2 || repeatCount == 3) { + return STOP_PAUSE_DURATION + + (6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; + } else { + return STOP_PAUSE_DURATION; + } + } +}; From ec5a82bd934079f6186e687a5b4bff17ef955125 Mon Sep 17 00:00:00 2001 From: Hans Date: Fri, 15 Jul 2016 22:20:53 +0200 Subject: [PATCH 175/768] Added ATmega48 and ATmega88 --- IRremoteInt.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index ca18bcd97..8cd6052c2 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -219,6 +219,7 @@ EXTERN volatile irparams_t irparams; #define IR_USE_TIMER_TINY0 // tx = pin 1 // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc +// ATmega48, ATmega88, ATmega168, ATmega328 #else //#define IR_USE_TIMER1 // tx = pin 9 #define IR_USE_TIMER2 // tx = pin 3 @@ -280,7 +281,7 @@ EXTERN volatile irparams_t irparams; # define TIMER_PWM_PIN 14 // MightyCore #else # define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc -#endif +#endif // ATmega48, ATmega88, ATmega168, ATmega328 //--------------------------------------------------------- // Timer1 (16 bits) @@ -338,7 +339,7 @@ EXTERN volatile irparams_t irparams; # define TIMER_PWM_PIN 6 #else # define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc -#endif +#endif // ATmega48, ATmega88, ATmega168, ATmega328 //--------------------------------------------------------- // Timer3 (16 bits) From 9bf00849b3ea99ad7ec8987e60e24bf316cef282 Mon Sep 17 00:00:00 2001 From: Hans Date: Fri, 15 Jul 2016 22:25:01 +0200 Subject: [PATCH 176/768] Added ATmega48 and ATmega88 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d89580692..af2f6f7a3 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,9 @@ We are open to suggestions for adding support to new boards, however we highly r |--------------------------------------------------------------------------|---------------------|-------------------| | [ATtiny84](https://github.com/SpenceKonde/ATTinyCore) | **6** | **1** | | [ATtiny85](https://github.com/SpenceKonde/ATTinyCore) | **1** | **TINY0** | -| ATmega8 | **9** | **1** | +| [ATmega8](https://github.com/MCUdude/MiniCore) | **9** | **1** | | Atmega32u4 | 5, 9, **13** | 1, 3, **4** | -| ATmega168, ATmega328 | **3**, 9 | 1, **2** | +| [ATmega48, ATmega88, ATmega168, ATmega328](https://github.com/MCUdude/MiniCore) | **3**, 9 | 1, **2** | | [ATmega1284](https://github.com/MCUdude/MightyCore) | 13, 14, 6 | 1, **2**, 3 | | [ATmega164, ATmega324, ATmega644](https://github.com/MCUdude/MightyCore) | 13, **14** | 1, **2** | | [ATmega8535 ATmega16, ATmega32](https://github.com/MCUdude/MightyCore) | **13** | **1** | From 75960b95f6bb6de243a89d4b57efb1b2d459f812 Mon Sep 17 00:00:00 2001 From: Hans Date: Fri, 15 Jul 2016 22:27:57 +0200 Subject: [PATCH 177/768] Added ATmega48 and ATmega88 --- examples/IRremoteInfo/IRremoteInfo.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/IRremoteInfo/IRremoteInfo.ino b/examples/IRremoteInfo/IRremoteInfo.ino index b44097767..2a269d948 100644 --- a/examples/IRremoteInfo/IRremoteInfo.ino +++ b/examples/IRremoteInfo/IRremoteInfo.ino @@ -117,8 +117,12 @@ void dumpPlatform() { Serial.println(F("ATmega164")); #elif defined(__AVR_ATmega128__) Serial.println(F("ATmega128")); +#elif defined(__AVR_ATmega88__) || defined(__AVR_ATmega88P__) + Serial.println(F("ATmega88")); #elif defined(__AVR_ATmega64__) Serial.println(F("ATmega64")); +#elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__) + Serial.println(F("ATmega48")); #elif defined(__AVR_ATmega32__) Serial.println(F("ATmega32")); #elif defined(__AVR_ATmega16__) From 76e23159f2edb74580a67aaf66e983f8d3f63422 Mon Sep 17 00:00:00 2001 From: Hans Date: Fri, 15 Jul 2016 22:30:02 +0200 Subject: [PATCH 178/768] Added myself! --- Contributors.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Contributors.md b/Contributors.md index 1b559fea8..cabd0654e 100644 --- a/Contributors.md +++ b/Contributors.md @@ -16,5 +16,6 @@ These are the active contributors of this project that you may contact if there - [lumbric](https://github.com/lumbric): Contributor - [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor - [henkel](https://github.com/henkel): Contributor +- [MCUdude](https://github.com/MCUdude): Contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. From b27398de74f798a7f1d200f31ddbadcdb3acd329 Mon Sep 17 00:00:00 2001 From: Hans Date: Fri, 22 Jul 2016 19:31:14 +0200 Subject: [PATCH 179/768] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index af2f6f7a3..7c473528c 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,9 @@ Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more inf - Arduino Uno / Mega / Leonardo / Duemilanove / Diecimila / LilyPad / Mini / Fio / Nano etc. - Teensy 1.0 / 1.0++ / 2.0 / 2++ / 3.0 / 3.1 / Teensy-LC; Credits: @PaulStoffregen (Teensy Team) - Sanguino -- Atmega8535, 8, 16, 32, 164, 324, 644, 1284, 64, 128 +- ATmega8, 48, 88, 168, 328 +- ATmega8535, 16, 32, 164, 324, 644, 1284, +- ATmega64, 128 - ATtiny 84 / 85 We are open to suggestions for adding support to new boards, however we highly recommend you contact your supplier first and ask them to provide support from their side. From 8a767328dfdbab035e76c3001d93f36913b0a1fc Mon Sep 17 00:00:00 2001 From: Hans Meine Date: Mon, 25 Jul 2016 12:42:48 +0200 Subject: [PATCH 180/768] rephrase sentence linking to (to-do) tutorials --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7c473528c..77ccf7d1e 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This library enables you to send and receive using infra-red signals on an Arduino. -Check [here](http://z3t0.github.io/Arduino-IRremote/) for tutorials and more information. +Tutorials and more information will be made available on [the official homepage](http://z3t0.github.io/Arduino-IRremote/). ## Version - 2.2.0 From a9385b92d8a566780eed8e4c93c89130edb4ed3f Mon Sep 17 00:00:00 2001 From: Philipp Henkel Date: Tue, 12 Jul 2016 23:14:47 +0200 Subject: [PATCH 181/768] Add Lego Power Functions tests --- .travis.yml | 1 + .../LegoPowerFunctionsTests.ino | 197 ++++++++++++++++++ ir_Lego_PF.cpp | 123 ++--------- ir_Lego_PF_BitStreamEncoder.h | 115 ++++++++++ 4 files changed, 331 insertions(+), 105 deletions(-) create mode 100644 examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino create mode 100644 ir_Lego_PF_BitStreamEncoder.h diff --git a/.travis.yml b/.travis.yml index ce01e805f..543a0a74b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ env: - PLATFORMIO_CI_SRC=examples/IRtest2 PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" - PLATFORMIO_CI_SRC=examples/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC" - PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF" + - PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsTests PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF" - PLATFORMIO_CI_SRC=examples/IRremoteInfo install: diff --git a/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino b/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino new file mode 100644 index 000000000..6a2bda57d --- /dev/null +++ b/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino @@ -0,0 +1,197 @@ +/* + * LegoPowerFunctionsTest: LEGO Power Functions Tests + * Copyright (c) 2016 Philipp Henkel + */ + +#include + +void setup() { + Serial.begin(9600); + delay(1000); // wait for reset triggered by serial connection + runBitStreamEncoderTests(); +} + +void loop() { +} + +void runBitStreamEncoderTests() { + Serial.println(); + Serial.println("BitStreamEncoder Tests"); + static LegoPfBitStreamEncoder bitStreamEncoder; + testStartBit(bitStreamEncoder); + testLowBit(bitStreamEncoder); + testHighBit(bitStreamEncoder); + testMessageBitCount(bitStreamEncoder); + testMessageBitCountRepeat(bitStreamEncoder); + testMessage407(bitStreamEncoder); + testMessage407Repeated(bitStreamEncoder); + testGetChannelId1(bitStreamEncoder); + testGetChannelId2(bitStreamEncoder); + testGetChannelId3(bitStreamEncoder); + testGetChannelId4(bitStreamEncoder); + testGetMessageLengthAllHigh(bitStreamEncoder); + testGetMessageLengthAllLow(bitStreamEncoder); +} + +void logTestResult(bool testPassed) { + if (testPassed) { + Serial.println("OK"); + } + else { + Serial.println("FAIL ############"); + } +} + +void testStartBit(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testStartBit "); + bitStreamEncoder.reset(0, false); + int startMark = bitStreamEncoder.getMarkDuration(); + int startPause = bitStreamEncoder.getPauseDuration(); + logTestResult(startMark == 158 && startPause == 1184-158); +} + +void testLowBit(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testLowBit "); + bitStreamEncoder.reset(0, false); + bitStreamEncoder.next(); + int lowMark = bitStreamEncoder.getMarkDuration(); + int lowPause = bitStreamEncoder.getPauseDuration(); + logTestResult(lowMark == 158 && lowPause == 421-158); +} + +void testHighBit(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testHighBit "); + bitStreamEncoder.reset(0xFFFF, false); + bitStreamEncoder.next(); + int highMark = bitStreamEncoder.getMarkDuration(); + int highPause = bitStreamEncoder.getPauseDuration(); + logTestResult(highMark == 158 && highPause == 711-158); +} + +void testMessageBitCount(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessageBitCount "); + bitStreamEncoder.reset(0xFFFF, false); + int bitCount = 1; + while (bitStreamEncoder.next()) { + bitCount++; + } + logTestResult(bitCount == 18); +} + +boolean check(LegoPfBitStreamEncoder& bitStreamEncoder, int markDuration, int pauseDuration) { + bool result = true; + result = result && bitStreamEncoder.getMarkDuration() == markDuration; + result = result && bitStreamEncoder.getPauseDuration() == pauseDuration; + return result; +} + +boolean checkNext(LegoPfBitStreamEncoder& bitStreamEncoder, int markDuration, int pauseDuration) { + bool result = bitStreamEncoder.next(); + result = result && check(bitStreamEncoder, markDuration, pauseDuration); + return result; +} + +boolean checkDataBitsOfMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) { + bool result = true; + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 553); + return result; +} + +void testMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessage407 "); + bitStreamEncoder.reset(407, false); + bool result = true; + result = result && check(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && !bitStreamEncoder.next(); + logTestResult(result); +} + +void testMessage407Repeated(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessage407Repeated "); + bitStreamEncoder.reset(407, true); + bool result = true; + result = result && check(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026 + 5 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026 + 5 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026 + 8 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026 + 8 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && !bitStreamEncoder.next(); + logTestResult(result); +} + +void testMessageBitCountRepeat(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessageBitCountRepeat "); + bitStreamEncoder.reset(0xFFFF, true); + int bitCount = 1; + while (bitStreamEncoder.next()) { + bitCount++; + } + logTestResult(bitCount == 5*18); +} + +void testGetChannelId1(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId1 "); + bitStreamEncoder.reset(407, false); + logTestResult(bitStreamEncoder.getChannelId() == 1); +} + +void testGetChannelId2(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId2 "); + bitStreamEncoder.reset(4502, false); + logTestResult(bitStreamEncoder.getChannelId() == 2); +} + +void testGetChannelId3(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId3 "); + bitStreamEncoder.reset(8597, false); + logTestResult(bitStreamEncoder.getChannelId() == 3); +} + +void testGetChannelId4(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId4 "); + bitStreamEncoder.reset(12692, false); + logTestResult(bitStreamEncoder.getChannelId() == 4); +} + +void testGetMessageLengthAllHigh(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetMessageLengthAllHigh "); + bitStreamEncoder.reset(0xFFFF, false); + logTestResult(bitStreamEncoder.getMessageLength() == 13744); +} + +void testGetMessageLengthAllLow(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetMessageLengthAllLow "); + bitStreamEncoder.reset(0x0, false); + logTestResult(bitStreamEncoder.getMessageLength() == 9104); +} + + + + diff --git a/ir_Lego_PF.cpp b/ir_Lego_PF.cpp index 2196bed6f..37d507ceb 100644 --- a/ir_Lego_PF.cpp +++ b/ir_Lego_PF.cpp @@ -1,5 +1,6 @@ #include "IRremote.h" #include "IRremoteInt.h" +#include "ir_Lego_PF_BitStreamEncoder.h" //============================================================================== // L EEEEEE EEEE OOOO @@ -16,118 +17,30 @@ // #if SEND_LEGO_PF -class BitStreamEncoder { - private: - uint16_t data; - bool repeatMessage; - int messageBitIdx; - int repeatCount; - int messageLength; - - // HIGH data bit = IR mark + high pause - // LOW data bit = IR mark + low pause - static const int LOW_BIT_DURATION = 421; - static const int HIGH_BIT_DURATION = 711; - static const int START_BIT_DURATION = 1184; - static const int STOP_BIT_DURATION = 1184; - static const int IR_MARK_DURATION = 158; - static const int HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; - static const int LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; - static const int START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; - static const int STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; - static const int MESSAGE_BITS = 18; - static const int MAX_MESSAGE_LENGTH = 16000; - - public: - void reset(uint16_t data, bool repeatMessage) { - this->data = data; - this->repeatMessage = repeatMessage; - messageBitIdx = 0; - repeatCount = 0; - messageLength = getMessageLength(); - } - - int getChannelId() const { return 1 + ((data >> 12) & 0x3); } - - int getMessageLength() const { - // Sum up all marks - int length = MESSAGE_BITS * IR_MARK_DURATION; - - // Sum up all pauses - length += START_PAUSE_DURATION; - for (unsigned long mask = 1UL << 15; mask; mask >>= 1) { - if (data & mask) { - length += HIGH_PAUSE_DURATION; - } else { - length += LOW_PAUSE_DURATION; - } - } - length += STOP_PAUSE_DURATION; - return length; - } - - boolean next() { - messageBitIdx++; - if (messageBitIdx >= MESSAGE_BITS) { - repeatCount++; - messageBitIdx = 0; - } - if (repeatCount >= 1 && !repeatMessage) { - return false; - } else if (repeatCount >= 5) { - return false; - } else { - return true; - } - } - - int getMarkDuration() const { return IR_MARK_DURATION; } - - int getPauseDuration() const { - if (messageBitIdx == 0) - return START_PAUSE_DURATION; - else if (messageBitIdx < MESSAGE_BITS - 1) { - return getDataBitPause(); - } else { - return getStopPause(); - } - } - - private: - int getDataBitPause() const { - const int pos = MESSAGE_BITS - 2 - messageBitIdx; - const bool isHigh = data & (1 << pos); - return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION; - } - - int getStopPause() const { - if (repeatMessage) { - return getRepeatStopPause(); - } else { - return STOP_PAUSE_DURATION; - } - } - - int getRepeatStopPause() const { - if (repeatCount == 0 || repeatCount == 1) { - return STOP_PAUSE_DURATION + 5 * MAX_MESSAGE_LENGTH - messageLength; - } else if (repeatCount == 2 || repeatCount == 3) { - return STOP_PAUSE_DURATION - + (6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; - } else { - return STOP_PAUSE_DURATION; - } - } -}; +#if DEBUG +namespace { +void logFunctionParameters(uint16_t data, bool repeat) { + DBG_PRINT("sendLegoPowerFunctions(data="); + DBG_PRINT(data); + DBG_PRINT(", repeat="); + DBG_PRINTLN(repeat?"true)" : "false)"); +} +} // anonymous namespace +#endif // DEBUG void IRsend::sendLegoPowerFunctions(uint16_t data, bool repeat) { +#if DEBUG + ::logFunctionParameters(data, repeat); +#endif // DEBUG + enableIROut(38); - static BitStreamEncoder bitStreamEncoder; + static LegoPfBitStreamEncoder bitStreamEncoder; bitStreamEncoder.reset(data, repeat); do { mark(bitStreamEncoder.getMarkDuration()); space(bitStreamEncoder.getPauseDuration()); } while (bitStreamEncoder.next()); } -#endif + +#endif // SEND_LEGO_PF diff --git a/ir_Lego_PF_BitStreamEncoder.h b/ir_Lego_PF_BitStreamEncoder.h new file mode 100644 index 000000000..7689cde28 --- /dev/null +++ b/ir_Lego_PF_BitStreamEncoder.h @@ -0,0 +1,115 @@ + +//============================================================================== +// L EEEEEE EEEE OOOO +// L E E O O +// L EEEE E EEE O O +// L E E E O O LEGO Power Functions +// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016 Philipp Henkel +//============================================================================== + +//+============================================================================= +// + +class LegoPfBitStreamEncoder { + private: + uint16_t data; + bool repeatMessage; + int messageBitIdx; + int repeatCount; + int messageLength; + + // HIGH data bit = IR mark + high pause + // LOW data bit = IR mark + low pause + static const int LOW_BIT_DURATION = 421; + static const int HIGH_BIT_DURATION = 711; + static const int START_BIT_DURATION = 1184; + static const int STOP_BIT_DURATION = 1184; + static const int IR_MARK_DURATION = 158; + static const int HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; + static const int LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; + static const int START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; + static const int STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; + static const int MESSAGE_BITS = 18; + static const int MAX_MESSAGE_LENGTH = 16000; + + public: + void reset(uint16_t data, bool repeatMessage) { + this->data = data; + this->repeatMessage = repeatMessage; + messageBitIdx = 0; + repeatCount = 0; + messageLength = getMessageLength(); + } + + int getChannelId() const { return 1 + ((data >> 12) & 0x3); } + + int getMessageLength() const { + // Sum up all marks + int length = MESSAGE_BITS * IR_MARK_DURATION; + + // Sum up all pauses + length += START_PAUSE_DURATION; + for (unsigned long mask = 1UL << 15; mask; mask >>= 1) { + if (data & mask) { + length += HIGH_PAUSE_DURATION; + } else { + length += LOW_PAUSE_DURATION; + } + } + length += STOP_PAUSE_DURATION; + return length; + } + + boolean next() { + messageBitIdx++; + if (messageBitIdx >= MESSAGE_BITS) { + repeatCount++; + messageBitIdx = 0; + } + if (repeatCount >= 1 && !repeatMessage) { + return false; + } else if (repeatCount >= 5) { + return false; + } else { + return true; + } + } + + int getMarkDuration() const { return IR_MARK_DURATION; } + + int getPauseDuration() const { + if (messageBitIdx == 0) + return START_PAUSE_DURATION; + else if (messageBitIdx < MESSAGE_BITS - 1) { + return getDataBitPause(); + } else { + return getStopPause(); + } + } + + private: + int getDataBitPause() const { + const int pos = MESSAGE_BITS - 2 - messageBitIdx; + const bool isHigh = data & (1 << pos); + return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION; + } + + int getStopPause() const { + if (repeatMessage) { + return getRepeatStopPause(); + } else { + return STOP_PAUSE_DURATION; + } + } + + int getRepeatStopPause() const { + if (repeatCount == 0 || repeatCount == 1) { + return STOP_PAUSE_DURATION + 5 * MAX_MESSAGE_LENGTH - messageLength; + } else if (repeatCount == 2 || repeatCount == 3) { + return STOP_PAUSE_DURATION + + (6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; + } else { + return STOP_PAUSE_DURATION; + } + } +}; From b26b64f87126afd573b12d7bd5a2ec3008182659 Mon Sep 17 00:00:00 2001 From: Philipp Henkel Date: Wed, 27 Jul 2016 07:25:52 +0200 Subject: [PATCH 182/768] Update changelog and version info --- README.md | 2 +- changelog.md | 3 +++ library.json | 2 +- library.properties | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 77ccf7d1e..48ddfc986 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This library enables you to send and receive using infra-red signals on an Ardui Tutorials and more information will be made available on [the official homepage](http://z3t0.github.io/Arduino-IRremote/). -## Version - 2.2.0 +## Version - 2.2.1 ## Installation 1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. diff --git a/changelog.md b/changelog.md index 297ffd479..fbe70b457 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +## 2.2.1 - 2016/07/27 +- Added tests for Lego Power Functions Protocol [PR #336](https://github.com/z3t0/Arduino-IRremote/pull/336) + ## 2.2.0 - 2016/06/28 - Added support for ATmega8535 - Added support for ATmega16 diff --git a/library.json b/library.json index b62b0de37..090578d10 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/z3t0/Arduino-IRremote.git" }, - "version": "2.1.0", + "version": "2.2.1", "frameworks": "arduino", "platforms": "atmelavr", "authors" : diff --git a/library.properties b/library.properties index 3553dc1fc..15aabee44 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=IRremote -version=2.0.1 +version=2.2.1 author=shirriff maintainer=shirriff sentence=Send and receive infrared signals with multiple protocols From 2d1b0f47371b2e449b8ef7740e6defc0335dba32 Mon Sep 17 00:00:00 2001 From: PaulStoffregen Date: Mon, 1 Aug 2016 06:55:56 -0700 Subject: [PATCH 183/768] Fix errors on Teensy 3.x --- IRremoteInt.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index 8cd6052c2..0199836e5 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -171,7 +171,7 @@ EXTERN volatile irparams_t irparams; #define IR_USE_TIMER4_HS // tx = pin 10 // Teensy 3.0 / Teensy 3.1 -#elif defined(__MK20DX128__) || defined(__MK20DX256__) +#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) #define IR_USE_TIMER_CMT // tx = pin 5 // Teensy-LC @@ -503,7 +503,7 @@ EXTERN volatile irparams_t irparams; #elif defined(IR_USE_TIMER_CMT) #define TIMER_RESET ({ \ - uint8_t tmp = CMT_MSC; \ + uint8_t tmp __attribute__((unused)) = CMT_MSC; \ CMT_CMD2 = 30; \ }) @@ -553,7 +553,7 @@ EXTERN volatile irparams_t irparams; CMT_CGH1 = 1; \ CMT_CGL1 = 1; \ CMT_CMD1 = 0; \ - CMT_CMD2 = 30 \ + CMT_CMD2 = 30; \ CMT_CMD3 = 0; \ CMT_CMD4 = 19; \ CMT_OC = 0; \ From e72008adf67a0f09f6dede132c1f54c8fc9c2598 Mon Sep 17 00:00:00 2001 From: PaulStoffregen Date: Mon, 1 Aug 2016 07:08:17 -0700 Subject: [PATCH 184/768] Allow any clock >= 8 MHz on Teensy 3.x --- IRremoteInt.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/IRremoteInt.h b/IRremoteInt.h index 0199836e5..9a9c3c2f3 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -526,19 +526,18 @@ EXTERN volatile irparams_t irparams; #define ISR(f) void f(void) //----------------- -#if (F_BUS == 48000000) -# define CMT_PPS_VAL 5 -#else -# define CMT_PPS_VAL 2 +#define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000) +#if F_BUS < 8000000 +#error IRremote requires at least 8 MHz on Teensy 3.x #endif //----------------- #define TIMER_CONFIG_KHZ(val) ({ \ SIM_SCGC4 |= SIM_SCGC4_CMT; \ SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ - CMT_PPS = CMT_PPS_VAL; \ - CMT_CGH1 = 2667 / val; \ - CMT_CGL1 = 5333 / val; \ + CMT_PPS = CMT_PPS_DIV - 1; \ + CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((val)/2)) / (val); \ + CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((val)/2)) / (val); \ CMT_CMD1 = 0; \ CMT_CMD2 = 30; \ CMT_CMD3 = 0; \ @@ -549,13 +548,13 @@ EXTERN volatile irparams_t irparams; #define TIMER_CONFIG_NORMAL() ({ \ SIM_SCGC4 |= SIM_SCGC4_CMT; \ - CMT_PPS = CMT_PPS_VAL; \ + CMT_PPS = CMT_PPS_DIV - 1; \ CMT_CGH1 = 1; \ CMT_CGL1 = 1; \ CMT_CMD1 = 0; \ CMT_CMD2 = 30; \ CMT_CMD3 = 0; \ - CMT_CMD4 = 19; \ + CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \ CMT_OC = 0; \ CMT_MSC = 0x03; \ }) From c0dda82685524e1e7365889b1bf1e1db8f15daee Mon Sep 17 00:00:00 2001 From: safaorhan Date: Thu, 18 Aug 2016 12:20:43 +0300 Subject: [PATCH 185/768] Update keywords.txt Add sendLG as KEYWORD2 --- keywords.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/keywords.txt b/keywords.txt index 6fd016fc3..f2b9a4957 100644 --- a/keywords.txt +++ b/keywords.txt @@ -31,6 +31,7 @@ sendSharp KEYWORD2 sendSharpRaw KEYWORD2 sendPanasonic KEYWORD2 sendJVC KEYWORD2 +sendLG KEYWORD2 ####################################### # Constants (LITERAL1) From 0d69a1a9ed19a8c887110094173574f8f192cd01 Mon Sep 17 00:00:00 2001 From: Bengt Martensson Date: Tue, 23 Aug 2016 15:23:51 +0200 Subject: [PATCH 186/768] Move board specific configuration info to new file boarddefs.h. --- IRremoteInt.h | 525 +---------------------------------------------- boarddefs.h | 548 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 550 insertions(+), 523 deletions(-) create mode 100644 boarddefs.h diff --git a/IRremoteInt.h b/IRremoteInt.h index 9a9c3c2f3..1c319acbf 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -68,40 +68,6 @@ irparams_t; // Therefore we declare it as "volatile" to stop the compiler/CPU caching it EXTERN volatile irparams_t irparams; -//------------------------------------------------------------------------------ -// Defines for blinking the LED -// - -#if defined(CORE_LED0_PIN) -# 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__) || defined(__AVR_ATmega2560__) -# define BLINKLED 13 -# define BLINKLED_ON() (PORTB |= B10000000) -# define BLINKLED_OFF() (PORTB &= B01111111) - -#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) -# define BLINKLED 0 -# define BLINKLED_ON() (PORTD |= B00000001) -# define BLINKLED_OFF() (PORTD &= B11111110) - -#else -# define BLINKLED 13 - #define BLINKLED_ON() (PORTB |= B00100000) -# define BLINKLED_OFF() (PORTB &= B11011111) -#endif - -//------------------------------------------------------------------------------ -// CPU Frequency -// -#ifdef F_CPU -# define SYSCLOCK F_CPU // main Arduino clock -#else -# define SYSCLOCK 16000000 // main Arduino clock -#endif - //------------------------------------------------------------------------------ // Defines for setting and clearing register bits // @@ -123,9 +89,6 @@ EXTERN volatile irparams_t irparams; // Spaces tend to be 100us too short #define MARK_EXCESS 100 -// microseconds per clock interrupt tick -#define USECPERTICK 50 - // Upper and Lower percentage tolerances in measurements #define TOLERANCE 25 #define LTOL (1.0 - (TOLERANCE/100.)) @@ -144,491 +107,7 @@ EXTERN volatile irparams_t irparams; #define MARK 0 #define SPACE 1 -//------------------------------------------------------------------------------ -// Define which timer to use -// -// Uncomment the timer you wish to use on your board. -// If you are using another library which uses timer2, you have options to -// switch IRremote to use a different timer. -// - -// Arduino Mega -#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 - //#define IR_USE_TIMER4 // tx = pin 6 - //#define IR_USE_TIMER5 // tx = pin 46 - -// Teensy 1.0 -#elif defined(__AVR_AT90USB162__) - #define IR_USE_TIMER1 // tx = pin 17 - -// Teensy 2.0 -#elif defined(__AVR_ATmega32U4__) - //#define IR_USE_TIMER1 // tx = pin 14 - //#define IR_USE_TIMER3 // tx = pin 9 - #define IR_USE_TIMER4_HS // tx = pin 10 - -// Teensy 3.0 / Teensy 3.1 -#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) - #define IR_USE_TIMER_CMT // tx = pin 5 - -// Teensy-LC -#elif defined(__MKL26Z64__) - #define IR_USE_TIMER_TPM1 // tx = pin 16 - -// Teensy++ 1.0 & 2.0 -#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) - //#define IR_USE_TIMER1 // tx = pin 25 - #define IR_USE_TIMER2 // tx = pin 1 - //#define IR_USE_TIMER3 // tx = pin 16 - -// MightyCore - ATmega1284 -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) - //#define IR_USE_TIMER1 // tx = pin 13 - #define IR_USE_TIMER2 // tx = pin 14 - //#define IR_USE_TIMER3 // tx = pin 6 - -// MightyCore - ATmega164, ATmega324, ATmega644 -#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) - //#define IR_USE_TIMER1 // tx = pin 13 - #define IR_USE_TIMER2 // tx = pin 14 - -//MegaCore - ATmega64, ATmega128 -#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) - #define IR_USE_TIMER1 // tx = pin 13 - -// MightyCore - ATmega8535, ATmega16, ATmega32 -#elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) - #define IR_USE_TIMER1 // tx = pin 13 - -// Atmega8 -#elif defined(__AVR_ATmega8__) - #define IR_USE_TIMER1 // tx = pin 9 +// All board specific stuff has been moved to its own file, included here. +#include "boarddefs.h" -// ATtiny84 -#elif defined(__AVR_ATtiny84__) - #define IR_USE_TIMER1 // tx = pin 6 - -//ATtiny85 -#elif defined(__AVR_ATtiny85__) - #define IR_USE_TIMER_TINY0 // tx = pin 1 - -// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc -// ATmega48, ATmega88, ATmega168, ATmega328 -#else - //#define IR_USE_TIMER1 // tx = pin 9 - #define IR_USE_TIMER2 // tx = pin 3 - -#endif - -//------------------------------------------------------------------------------ -// Defines for Timer - -//--------------------------------------------------------- -// Timer2 (8 bits) -// -#if defined(IR_USE_TIMER2) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) -#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) -#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) -#define TIMER_DISABLE_INTR (TIMSK2 = 0) -#define TIMER_INTR_NAME TIMER2_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR2A = _BV(WGM20); \ - TCCR2B = _BV(WGM22) | _BV(CS20); \ - OCR2A = pwmval; \ - OCR2B = pwmval / 3; \ -}) - -#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) - -//----------------- -#if (TIMER_COUNT_TOP < 256) -# define TIMER_CONFIG_NORMAL() ({ \ - TCCR2A = _BV(WGM21); \ - TCCR2B = _BV(CS20); \ - OCR2A = TIMER_COUNT_TOP; \ - TCNT2 = 0; \ - }) -#else -# define TIMER_CONFIG_NORMAL() ({ \ - TCCR2A = _BV(WGM21); \ - TCCR2B = _BV(CS21); \ - OCR2A = TIMER_COUNT_TOP / 8; \ - TCNT2 = 0; \ - }) -#endif - -//----------------- -#if defined(CORE_OC2B_PIN) -# define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 9 // Arduino Mega -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) -# define TIMER_PWM_PIN 14 // MightyCore -#else -# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc -#endif // ATmega48, ATmega88, ATmega168, ATmega328 - -//--------------------------------------------------------- -// Timer1 (16 bits) -// -#elif defined(IR_USE_TIMER1) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) -#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) - -//----------------- -#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) -# define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) -# define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) -#else -# define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) -# define TIMER_DISABLE_INTR (TIMSK1 = 0) -#endif - -//----------------- -#define TIMER_INTR_NAME TIMER1_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR1A = _BV(WGM11); \ - TCCR1B = _BV(WGM13) | _BV(CS10); \ - ICR1 = pwmval; \ - OCR1A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR1A = 0; \ - TCCR1B = _BV(WGM12) | _BV(CS10); \ - OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT1 = 0; \ -}) - -//----------------- -#if defined(CORE_OC1A_PIN) -# define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 11 // Arduino Mega -#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) -# define TIMER_PWM_PIN 13 // MegaCore -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) -# define TIMER_PWM_PIN 13 // MightyCore -#elif defined(__AVR_ATtiny84__) -# define TIMER_PWM_PIN 6 -#else -# define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc -#endif // ATmega48, ATmega88, ATmega168, ATmega328 - -//--------------------------------------------------------- -// Timer3 (16 bits) -// -#elif defined(IR_USE_TIMER3) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1)) -#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1))) -#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A)) -#define TIMER_DISABLE_INTR (TIMSK3 = 0) -#define TIMER_INTR_NAME TIMER3_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR3A = _BV(WGM31); \ - TCCR3B = _BV(WGM33) | _BV(CS30); \ - ICR3 = pwmval; \ - OCR3A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR3A = 0; \ - TCCR3B = _BV(WGM32) | _BV(CS30); \ - OCR3A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT3 = 0; \ -}) - -//----------------- -#if defined(CORE_OC3A_PIN) -# define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 5 // Arduino Mega -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) -# define TIMER_PWM_PIN 6 // MightyCore -#else -# error "Please add OC3A pin number here\n" -#endif - -//--------------------------------------------------------- -// Timer4 (10 bits, high speed option) -// -#elif defined(IR_USE_TIMER4_HS) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) -#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) -#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) -#define TIMER_DISABLE_INTR (TIMSK4 = 0) -#define TIMER_INTR_NAME TIMER4_OVF_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR4A = (1<> 8; \ - OCR4C = pwmval; \ - TC4H = (pwmval / 3) >> 8; \ - OCR4A = (pwmval / 3) & 255; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR4A = 0; \ - TCCR4B = _BV(CS40); \ - TCCR4C = 0; \ - TCCR4D = 0; \ - TCCR4E = 0; \ - TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ - OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ - TC4H = 0; \ - TCNT4 = 0; \ -}) - -//----------------- -#if defined(CORE_OC4A_PIN) -# define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy -#elif defined(__AVR_ATmega32U4__) -# define TIMER_PWM_PIN 13 // Leonardo -#else -# error "Please add OC4A pin number here\n" -#endif - -//--------------------------------------------------------- -// Timer4 (16 bits) -// -#elif defined(IR_USE_TIMER4) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) -#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) -#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) -#define TIMER_DISABLE_INTR (TIMSK4 = 0) -#define TIMER_INTR_NAME TIMER4_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR4A = _BV(WGM41); \ - TCCR4B = _BV(WGM43) | _BV(CS40); \ - ICR4 = pwmval; \ - OCR4A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR4A = 0; \ - TCCR4B = _BV(WGM42) | _BV(CS40); \ - OCR4A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT4 = 0; \ -}) - -//----------------- -#if defined(CORE_OC4A_PIN) -# define TIMER_PWM_PIN CORE_OC4A_PIN -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 6 // Arduino Mega -#else -# error "Please add OC4A pin number here\n" -#endif - -//--------------------------------------------------------- -// Timer5 (16 bits) -// -#elif defined(IR_USE_TIMER5) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) -#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) -#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) -#define TIMER_DISABLE_INTR (TIMSK5 = 0) -#define TIMER_INTR_NAME TIMER5_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR5A = _BV(WGM51); \ - TCCR5B = _BV(WGM53) | _BV(CS50); \ - ICR5 = pwmval; \ - OCR5A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR5A = 0; \ - TCCR5B = _BV(WGM52) | _BV(CS50); \ - OCR5A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT5 = 0; \ -}) - -//----------------- -#if defined(CORE_OC5A_PIN) -# define TIMER_PWM_PIN CORE_OC5A_PIN -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 46 // Arduino Mega -#else -# error "Please add OC5A pin number here\n" -#endif - -//--------------------------------------------------------- -// Special carrier modulator timer -// -#elif defined(IR_USE_TIMER_CMT) - -#define TIMER_RESET ({ \ - uint8_t tmp __attribute__((unused)) = CMT_MSC; \ - CMT_CMD2 = 30; \ -}) - -#define TIMER_ENABLE_PWM do { \ - CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \ -} while(0) - -#define TIMER_DISABLE_PWM do { \ - CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \ -} while(0) - -#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) -#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) -#define TIMER_INTR_NAME cmt_isr - -//----------------- -#ifdef ISR -# undef ISR -#endif -#define ISR(f) void f(void) - -//----------------- -#define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000) -#if F_BUS < 8000000 -#error IRremote requires at least 8 MHz on Teensy 3.x -#endif - -//----------------- -#define TIMER_CONFIG_KHZ(val) ({ \ - SIM_SCGC4 |= SIM_SCGC4_CMT; \ - SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ - CMT_PPS = CMT_PPS_DIV - 1; \ - CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((val)/2)) / (val); \ - CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((val)/2)) / (val); \ - CMT_CMD1 = 0; \ - CMT_CMD2 = 30; \ - CMT_CMD3 = 0; \ - CMT_CMD4 = 0; \ - CMT_OC = 0x60; \ - CMT_MSC = 0x01; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - SIM_SCGC4 |= SIM_SCGC4_CMT; \ - CMT_PPS = CMT_PPS_DIV - 1; \ - CMT_CGH1 = 1; \ - CMT_CGL1 = 1; \ - CMT_CMD1 = 0; \ - CMT_CMD2 = 30; \ - CMT_CMD3 = 0; \ - CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \ - CMT_OC = 0; \ - CMT_MSC = 0x03; \ -}) - -#define TIMER_PWM_PIN 5 - -// defines for TPM1 timer on Teensy-LC -#elif defined(IR_USE_TIMER_TPM1) -#define TIMER_RESET FTM1_SC |= FTM_SC_TOF; -#define TIMER_ENABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE -#define TIMER_DISABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE -#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1) -#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1) -#define TIMER_INTR_NAME ftm1_isr -#ifdef ISR -#undef ISR -#endif -#define ISR(f) void f(void) -#define TIMER_CONFIG_KHZ(val) ({ \ - SIM_SCGC6 |= SIM_SCGC6_TPM1; \ - FTM1_SC = 0; \ - FTM1_CNT = 0; \ - FTM1_MOD = (F_PLL/2000) / val - 1; \ - FTM1_C0V = (F_PLL/6000) / val - 1; \ - FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \ -}) -#define TIMER_CONFIG_NORMAL() ({ \ - SIM_SCGC6 |= SIM_SCGC6_TPM1; \ - FTM1_SC = 0; \ - FTM1_CNT = 0; \ - FTM1_MOD = (F_PLL/40000) - 1; \ - FTM1_C0V = 0; \ - FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \ -}) -#define TIMER_PWM_PIN 16 - -// defines for timer_tiny0 (8 bits) -#elif defined(IR_USE_TIMER_TINY0) -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR0A |= _BV(COM0B1)) -#define TIMER_DISABLE_PWM (TCCR0A &= ~(_BV(COM0B1))) -#define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE0A)) -#define TIMER_DISABLE_INTR (TIMSK &= ~(_BV(OCIE0A))) -#define TIMER_INTR_NAME TIMER0_COMPA_vect -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR0A = _BV(WGM00); \ - TCCR0B = _BV(WGM02) | _BV(CS00); \ - OCR0A = pwmval; \ - OCR0B = pwmval / 3; \ -}) -#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) -#if (TIMER_COUNT_TOP < 256) -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR0A = _BV(WGM01); \ - TCCR0B = _BV(CS00); \ - OCR0A = TIMER_COUNT_TOP; \ - TCNT0 = 0; \ -}) -#else -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR0A = _BV(WGM01); \ - TCCR0B = _BV(CS01); \ - OCR0A = TIMER_COUNT_TOP / 8; \ - TCNT0 = 0; \ -}) -#endif - -#define TIMER_PWM_PIN 1 /* ATtiny85 */ - -//--------------------------------------------------------- -// Unknown Timer -// -#else -# error "Internal code configuration error, no known IR_USE_TIMER# defined\n" -#endif #endif diff --git a/boarddefs.h b/boarddefs.h new file mode 100644 index 000000000..62b6be4fb --- /dev/null +++ b/boarddefs.h @@ -0,0 +1,548 @@ +//****************************************************************************** +// IRremote +// Version 2.0.1 June, 2015 +// Copyright 2009 Ken Shirriff +// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html + +// This file contains all board specific information. It was previously contained within +// IRremoteInt.h + +// Modified by Paul Stoffregen to support other boards and timers +// +// 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) +// Whynter A/C ARC-110WD added by Francesco Meschia +//****************************************************************************** + +#ifndef boarddefs_h +#define boarddefs_h + +//------------------------------------------------------------------------------ +// Defines for blinking the LED +// + +#if defined(CORE_LED0_PIN) +# 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__) || defined(__AVR_ATmega2560__) +# define BLINKLED 13 +# define BLINKLED_ON() (PORTB |= B10000000) +# define BLINKLED_OFF() (PORTB &= B01111111) + +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) +# define BLINKLED 0 +# define BLINKLED_ON() (PORTD |= B00000001) +# define BLINKLED_OFF() (PORTD &= B11111110) + +#else +# define BLINKLED 13 + #define BLINKLED_ON() (PORTB |= B00100000) +# define BLINKLED_OFF() (PORTB &= B11011111) +#endif + +//------------------------------------------------------------------------------ +// CPU Frequency +// +#ifdef F_CPU +# define SYSCLOCK F_CPU // main Arduino clock +#else +# define SYSCLOCK 16000000 // main Arduino clock +#endif + +// microseconds per clock interrupt tick +#define USECPERTICK 50 + +//------------------------------------------------------------------------------ +// Define which timer to use +// +// Uncomment the timer you wish to use on your board. +// If you are using another library which uses timer2, you have options to +// switch IRremote to use a different timer. +// + +// Arduino Mega +#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 + //#define IR_USE_TIMER4 // tx = pin 6 + //#define IR_USE_TIMER5 // tx = pin 46 + +// Teensy 1.0 +#elif defined(__AVR_AT90USB162__) + #define IR_USE_TIMER1 // tx = pin 17 + +// Teensy 2.0 +#elif defined(__AVR_ATmega32U4__) + //#define IR_USE_TIMER1 // tx = pin 14 + //#define IR_USE_TIMER3 // tx = pin 9 + #define IR_USE_TIMER4_HS // tx = pin 10 + +// Teensy 3.0 / Teensy 3.1 +#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) + #define IR_USE_TIMER_CMT // tx = pin 5 + +// Teensy-LC +#elif defined(__MKL26Z64__) + #define IR_USE_TIMER_TPM1 // tx = pin 16 + +// Teensy++ 1.0 & 2.0 +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) + //#define IR_USE_TIMER1 // tx = pin 25 + #define IR_USE_TIMER2 // tx = pin 1 + //#define IR_USE_TIMER3 // tx = pin 16 + +// MightyCore - ATmega1284 +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) + //#define IR_USE_TIMER1 // tx = pin 13 + #define IR_USE_TIMER2 // tx = pin 14 + //#define IR_USE_TIMER3 // tx = pin 6 + +// MightyCore - ATmega164, ATmega324, ATmega644 +#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) + //#define IR_USE_TIMER1 // tx = pin 13 + #define IR_USE_TIMER2 // tx = pin 14 + +//MegaCore - ATmega64, ATmega128 +#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) + #define IR_USE_TIMER1 // tx = pin 13 + +// MightyCore - ATmega8535, ATmega16, ATmega32 +#elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) + #define IR_USE_TIMER1 // tx = pin 13 + +// Atmega8 +#elif defined(__AVR_ATmega8__) + #define IR_USE_TIMER1 // tx = pin 9 + +// ATtiny84 +#elif defined(__AVR_ATtiny84__) + #define IR_USE_TIMER1 // tx = pin 6 + +//ATtiny85 +#elif defined(__AVR_ATtiny85__) + #define IR_USE_TIMER_TINY0 // tx = pin 1 + +// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc +// ATmega48, ATmega88, ATmega168, ATmega328 +#else + //#define IR_USE_TIMER1 // tx = pin 9 + #define IR_USE_TIMER2 // tx = pin 3 + +#endif + +//------------------------------------------------------------------------------ +// Defines for Timer + +//--------------------------------------------------------- +// Timer2 (8 bits) +// +#if defined(IR_USE_TIMER2) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) +#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) +#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) +#define TIMER_DISABLE_INTR (TIMSK2 = 0) +#define TIMER_INTR_NAME TIMER2_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR2A = _BV(WGM20); \ + TCCR2B = _BV(WGM22) | _BV(CS20); \ + OCR2A = pwmval; \ + OCR2B = pwmval / 3; \ +}) + +#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) + +//----------------- +#if (TIMER_COUNT_TOP < 256) +# define TIMER_CONFIG_NORMAL() ({ \ + TCCR2A = _BV(WGM21); \ + TCCR2B = _BV(CS20); \ + OCR2A = TIMER_COUNT_TOP; \ + TCNT2 = 0; \ + }) +#else +# define TIMER_CONFIG_NORMAL() ({ \ + TCCR2A = _BV(WGM21); \ + TCCR2B = _BV(CS21); \ + OCR2A = TIMER_COUNT_TOP / 8; \ + TCNT2 = 0; \ + }) +#endif + +//----------------- +#if defined(CORE_OC2B_PIN) +# define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 9 // Arduino Mega +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ +|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) +# define TIMER_PWM_PIN 14 // MightyCore +#else +# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc +#endif // ATmega48, ATmega88, ATmega168, ATmega328 + +//--------------------------------------------------------- +// Timer1 (16 bits) +// +#elif defined(IR_USE_TIMER1) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) +#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) + +//----------------- +#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8535__) \ +|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ +|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) +# define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) +# define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) +#else +# define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) +# define TIMER_DISABLE_INTR (TIMSK1 = 0) +#endif + +//----------------- +#define TIMER_INTR_NAME TIMER1_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR1A = _BV(WGM11); \ + TCCR1B = _BV(WGM13) | _BV(CS10); \ + ICR1 = pwmval; \ + OCR1A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR1A = 0; \ + TCCR1B = _BV(WGM12) | _BV(CS10); \ + OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT1 = 0; \ +}) + +//----------------- +#if defined(CORE_OC1A_PIN) +# define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 11 // Arduino Mega +#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) +# define TIMER_PWM_PIN 13 // MegaCore +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ +|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ +|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) +# define TIMER_PWM_PIN 13 // MightyCore +#elif defined(__AVR_ATtiny84__) +# define TIMER_PWM_PIN 6 +#else +# define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc +#endif // ATmega48, ATmega88, ATmega168, ATmega328 + +//--------------------------------------------------------- +// Timer3 (16 bits) +// +#elif defined(IR_USE_TIMER3) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1)) +#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1))) +#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A)) +#define TIMER_DISABLE_INTR (TIMSK3 = 0) +#define TIMER_INTR_NAME TIMER3_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR3A = _BV(WGM31); \ + TCCR3B = _BV(WGM33) | _BV(CS30); \ + ICR3 = pwmval; \ + OCR3A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR3A = 0; \ + TCCR3B = _BV(WGM32) | _BV(CS30); \ + OCR3A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT3 = 0; \ +}) + +//----------------- +#if defined(CORE_OC3A_PIN) +# define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 5 // Arduino Mega +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) +# define TIMER_PWM_PIN 6 // MightyCore +#else +# error "Please add OC3A pin number here\n" +#endif + +//--------------------------------------------------------- +// Timer4 (10 bits, high speed option) +// +#elif defined(IR_USE_TIMER4_HS) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) +#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) +#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) +#define TIMER_DISABLE_INTR (TIMSK4 = 0) +#define TIMER_INTR_NAME TIMER4_OVF_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR4A = (1<> 8; \ + OCR4C = pwmval; \ + TC4H = (pwmval / 3) >> 8; \ + OCR4A = (pwmval / 3) & 255; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR4A = 0; \ + TCCR4B = _BV(CS40); \ + TCCR4C = 0; \ + TCCR4D = 0; \ + TCCR4E = 0; \ + TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ + OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ + TC4H = 0; \ + TCNT4 = 0; \ +}) + +//----------------- +#if defined(CORE_OC4A_PIN) +# define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy +#elif defined(__AVR_ATmega32U4__) +# define TIMER_PWM_PIN 13 // Leonardo +#else +# error "Please add OC4A pin number here\n" +#endif + +//--------------------------------------------------------- +// Timer4 (16 bits) +// +#elif defined(IR_USE_TIMER4) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) +#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) +#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) +#define TIMER_DISABLE_INTR (TIMSK4 = 0) +#define TIMER_INTR_NAME TIMER4_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR4A = _BV(WGM41); \ + TCCR4B = _BV(WGM43) | _BV(CS40); \ + ICR4 = pwmval; \ + OCR4A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR4A = 0; \ + TCCR4B = _BV(WGM42) | _BV(CS40); \ + OCR4A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT4 = 0; \ +}) + +//----------------- +#if defined(CORE_OC4A_PIN) +# define TIMER_PWM_PIN CORE_OC4A_PIN +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 6 // Arduino Mega +#else +# error "Please add OC4A pin number here\n" +#endif + +//--------------------------------------------------------- +// Timer5 (16 bits) +// +#elif defined(IR_USE_TIMER5) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) +#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) +#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) +#define TIMER_DISABLE_INTR (TIMSK5 = 0) +#define TIMER_INTR_NAME TIMER5_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR5A = _BV(WGM51); \ + TCCR5B = _BV(WGM53) | _BV(CS50); \ + ICR5 = pwmval; \ + OCR5A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR5A = 0; \ + TCCR5B = _BV(WGM52) | _BV(CS50); \ + OCR5A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT5 = 0; \ +}) + +//----------------- +#if defined(CORE_OC5A_PIN) +# define TIMER_PWM_PIN CORE_OC5A_PIN +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 46 // Arduino Mega +#else +# error "Please add OC5A pin number here\n" +#endif + +//--------------------------------------------------------- +// Special carrier modulator timer +// +#elif defined(IR_USE_TIMER_CMT) + +#define TIMER_RESET ({ \ + uint8_t tmp __attribute__((unused)) = CMT_MSC; \ + CMT_CMD2 = 30; \ +}) + +#define TIMER_ENABLE_PWM do { \ + CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \ +} while(0) + +#define TIMER_DISABLE_PWM do { \ + CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \ +} while(0) + +#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) +#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) +#define TIMER_INTR_NAME cmt_isr + +//----------------- +#ifdef ISR +# undef ISR +#endif +#define ISR(f) void f(void) + +//----------------- +#define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000) +#if F_BUS < 8000000 +#error IRremote requires at least 8 MHz on Teensy 3.x +#endif + +//----------------- +#define TIMER_CONFIG_KHZ(val) ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ + CMT_PPS = CMT_PPS_DIV - 1; \ + CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((val)/2)) / (val); \ + CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((val)/2)) / (val); \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = 0; \ + CMT_OC = 0x60; \ + CMT_MSC = 0x01; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + CMT_PPS = CMT_PPS_DIV - 1; \ + CMT_CGH1 = 1; \ + CMT_CGL1 = 1; \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \ + CMT_OC = 0; \ + CMT_MSC = 0x03; \ +}) + +#define TIMER_PWM_PIN 5 + +// defines for TPM1 timer on Teensy-LC +#elif defined(IR_USE_TIMER_TPM1) +#define TIMER_RESET FTM1_SC |= FTM_SC_TOF; +#define TIMER_ENABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE +#define TIMER_DISABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE +#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1) +#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1) +#define TIMER_INTR_NAME ftm1_isr +#ifdef ISR +#undef ISR +#endif +#define ISR(f) void f(void) +#define TIMER_CONFIG_KHZ(val) ({ \ + SIM_SCGC6 |= SIM_SCGC6_TPM1; \ + FTM1_SC = 0; \ + FTM1_CNT = 0; \ + FTM1_MOD = (F_PLL/2000) / val - 1; \ + FTM1_C0V = (F_PLL/6000) / val - 1; \ + FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + SIM_SCGC6 |= SIM_SCGC6_TPM1; \ + FTM1_SC = 0; \ + FTM1_CNT = 0; \ + FTM1_MOD = (F_PLL/40000) - 1; \ + FTM1_C0V = 0; \ + FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \ +}) +#define TIMER_PWM_PIN 16 + +// defines for timer_tiny0 (8 bits) +#elif defined(IR_USE_TIMER_TINY0) +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR0A |= _BV(COM0B1)) +#define TIMER_DISABLE_PWM (TCCR0A &= ~(_BV(COM0B1))) +#define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE0A)) +#define TIMER_DISABLE_INTR (TIMSK &= ~(_BV(OCIE0A))) +#define TIMER_INTR_NAME TIMER0_COMPA_vect +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR0A = _BV(WGM00); \ + TCCR0B = _BV(WGM02) | _BV(CS00); \ + OCR0A = pwmval; \ + OCR0B = pwmval / 3; \ +}) +#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) +#if (TIMER_COUNT_TOP < 256) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR0A = _BV(WGM01); \ + TCCR0B = _BV(CS00); \ + OCR0A = TIMER_COUNT_TOP; \ + TCNT0 = 0; \ +}) +#else +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR0A = _BV(WGM01); \ + TCCR0B = _BV(CS01); \ + OCR0A = TIMER_COUNT_TOP / 8; \ + TCNT0 = 0; \ +}) +#endif + +#define TIMER_PWM_PIN 1 /* ATtiny85 */ + +//--------------------------------------------------------- +// Unknown Timer +// +#else +# error "Internal code configuration error, no known IR_USE_TIMER# defined\n" +#endif + +#endif // ! boarddefs_h From 9ae0239fb71a52a633c378c1d8a63aaf43904623 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 8 Oct 2016 02:03:14 -0600 Subject: [PATCH 187/768] updated readme email notice far too many emails for things that should be an issue or PR --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 48ddfc986..c8e074cf9 100644 --- a/README.md +++ b/README.md @@ -64,8 +64,8 @@ If you want to contribute to this project: Check [here](Contributing.md) for some guidelines. ## Contact -The only way to contact me at the moment is by email: zetoslab@gmail.com -I am not currently monitoring any PRs or Issues due to other issues but will respond to all emails. If anyone wants contributor access, feel free to email me. Or if you find any Issues/PRs to be of importance that my attention is needed please email me. +Email: zetoslab@gmail.com +Please only email me if it is more appropriate than creating an Issue / PR. I **will** not respond to requests for adding support for particular boards, unless of course you are the creator of the board and would like to cooperate on the project. I will also **ignore** any emails asking me to tell you how to implement your ideas. However, if you have a private inquiry that you would only apply to you and you would prefer it to be via email, by all means. ## Contributors Check [here](Contributors.md) From 74594847b7707f8d0d0654119fcc895230d5c41c Mon Sep 17 00:00:00 2001 From: Bengt Martensson Date: Tue, 23 Aug 2016 15:23:51 +0200 Subject: [PATCH 188/768] Move board specific configuration info to new file boarddefs.h. --- IRremoteInt.h | 525 +---------------------------------------------- boarddefs.h | 548 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 550 insertions(+), 523 deletions(-) create mode 100644 boarddefs.h diff --git a/IRremoteInt.h b/IRremoteInt.h index 9a9c3c2f3..1c319acbf 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -68,40 +68,6 @@ irparams_t; // Therefore we declare it as "volatile" to stop the compiler/CPU caching it EXTERN volatile irparams_t irparams; -//------------------------------------------------------------------------------ -// Defines for blinking the LED -// - -#if defined(CORE_LED0_PIN) -# 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__) || defined(__AVR_ATmega2560__) -# define BLINKLED 13 -# define BLINKLED_ON() (PORTB |= B10000000) -# define BLINKLED_OFF() (PORTB &= B01111111) - -#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) -# define BLINKLED 0 -# define BLINKLED_ON() (PORTD |= B00000001) -# define BLINKLED_OFF() (PORTD &= B11111110) - -#else -# define BLINKLED 13 - #define BLINKLED_ON() (PORTB |= B00100000) -# define BLINKLED_OFF() (PORTB &= B11011111) -#endif - -//------------------------------------------------------------------------------ -// CPU Frequency -// -#ifdef F_CPU -# define SYSCLOCK F_CPU // main Arduino clock -#else -# define SYSCLOCK 16000000 // main Arduino clock -#endif - //------------------------------------------------------------------------------ // Defines for setting and clearing register bits // @@ -123,9 +89,6 @@ EXTERN volatile irparams_t irparams; // Spaces tend to be 100us too short #define MARK_EXCESS 100 -// microseconds per clock interrupt tick -#define USECPERTICK 50 - // Upper and Lower percentage tolerances in measurements #define TOLERANCE 25 #define LTOL (1.0 - (TOLERANCE/100.)) @@ -144,491 +107,7 @@ EXTERN volatile irparams_t irparams; #define MARK 0 #define SPACE 1 -//------------------------------------------------------------------------------ -// Define which timer to use -// -// Uncomment the timer you wish to use on your board. -// If you are using another library which uses timer2, you have options to -// switch IRremote to use a different timer. -// - -// Arduino Mega -#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 - //#define IR_USE_TIMER4 // tx = pin 6 - //#define IR_USE_TIMER5 // tx = pin 46 - -// Teensy 1.0 -#elif defined(__AVR_AT90USB162__) - #define IR_USE_TIMER1 // tx = pin 17 - -// Teensy 2.0 -#elif defined(__AVR_ATmega32U4__) - //#define IR_USE_TIMER1 // tx = pin 14 - //#define IR_USE_TIMER3 // tx = pin 9 - #define IR_USE_TIMER4_HS // tx = pin 10 - -// Teensy 3.0 / Teensy 3.1 -#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) - #define IR_USE_TIMER_CMT // tx = pin 5 - -// Teensy-LC -#elif defined(__MKL26Z64__) - #define IR_USE_TIMER_TPM1 // tx = pin 16 - -// Teensy++ 1.0 & 2.0 -#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) - //#define IR_USE_TIMER1 // tx = pin 25 - #define IR_USE_TIMER2 // tx = pin 1 - //#define IR_USE_TIMER3 // tx = pin 16 - -// MightyCore - ATmega1284 -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) - //#define IR_USE_TIMER1 // tx = pin 13 - #define IR_USE_TIMER2 // tx = pin 14 - //#define IR_USE_TIMER3 // tx = pin 6 - -// MightyCore - ATmega164, ATmega324, ATmega644 -#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) - //#define IR_USE_TIMER1 // tx = pin 13 - #define IR_USE_TIMER2 // tx = pin 14 - -//MegaCore - ATmega64, ATmega128 -#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) - #define IR_USE_TIMER1 // tx = pin 13 - -// MightyCore - ATmega8535, ATmega16, ATmega32 -#elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) - #define IR_USE_TIMER1 // tx = pin 13 - -// Atmega8 -#elif defined(__AVR_ATmega8__) - #define IR_USE_TIMER1 // tx = pin 9 +// All board specific stuff has been moved to its own file, included here. +#include "boarddefs.h" -// ATtiny84 -#elif defined(__AVR_ATtiny84__) - #define IR_USE_TIMER1 // tx = pin 6 - -//ATtiny85 -#elif defined(__AVR_ATtiny85__) - #define IR_USE_TIMER_TINY0 // tx = pin 1 - -// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc -// ATmega48, ATmega88, ATmega168, ATmega328 -#else - //#define IR_USE_TIMER1 // tx = pin 9 - #define IR_USE_TIMER2 // tx = pin 3 - -#endif - -//------------------------------------------------------------------------------ -// Defines for Timer - -//--------------------------------------------------------- -// Timer2 (8 bits) -// -#if defined(IR_USE_TIMER2) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) -#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) -#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) -#define TIMER_DISABLE_INTR (TIMSK2 = 0) -#define TIMER_INTR_NAME TIMER2_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR2A = _BV(WGM20); \ - TCCR2B = _BV(WGM22) | _BV(CS20); \ - OCR2A = pwmval; \ - OCR2B = pwmval / 3; \ -}) - -#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) - -//----------------- -#if (TIMER_COUNT_TOP < 256) -# define TIMER_CONFIG_NORMAL() ({ \ - TCCR2A = _BV(WGM21); \ - TCCR2B = _BV(CS20); \ - OCR2A = TIMER_COUNT_TOP; \ - TCNT2 = 0; \ - }) -#else -# define TIMER_CONFIG_NORMAL() ({ \ - TCCR2A = _BV(WGM21); \ - TCCR2B = _BV(CS21); \ - OCR2A = TIMER_COUNT_TOP / 8; \ - TCNT2 = 0; \ - }) -#endif - -//----------------- -#if defined(CORE_OC2B_PIN) -# define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 9 // Arduino Mega -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) -# define TIMER_PWM_PIN 14 // MightyCore -#else -# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc -#endif // ATmega48, ATmega88, ATmega168, ATmega328 - -//--------------------------------------------------------- -// Timer1 (16 bits) -// -#elif defined(IR_USE_TIMER1) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) -#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) - -//----------------- -#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8535__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) -# define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) -# define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) -#else -# define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) -# define TIMER_DISABLE_INTR (TIMSK1 = 0) -#endif - -//----------------- -#define TIMER_INTR_NAME TIMER1_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR1A = _BV(WGM11); \ - TCCR1B = _BV(WGM13) | _BV(CS10); \ - ICR1 = pwmval; \ - OCR1A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR1A = 0; \ - TCCR1B = _BV(WGM12) | _BV(CS10); \ - OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT1 = 0; \ -}) - -//----------------- -#if defined(CORE_OC1A_PIN) -# define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 11 // Arduino Mega -#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) -# define TIMER_PWM_PIN 13 // MegaCore -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ -|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ -|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ -|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ -|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ -|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) -# define TIMER_PWM_PIN 13 // MightyCore -#elif defined(__AVR_ATtiny84__) -# define TIMER_PWM_PIN 6 -#else -# define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc -#endif // ATmega48, ATmega88, ATmega168, ATmega328 - -//--------------------------------------------------------- -// Timer3 (16 bits) -// -#elif defined(IR_USE_TIMER3) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1)) -#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1))) -#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A)) -#define TIMER_DISABLE_INTR (TIMSK3 = 0) -#define TIMER_INTR_NAME TIMER3_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR3A = _BV(WGM31); \ - TCCR3B = _BV(WGM33) | _BV(CS30); \ - ICR3 = pwmval; \ - OCR3A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR3A = 0; \ - TCCR3B = _BV(WGM32) | _BV(CS30); \ - OCR3A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT3 = 0; \ -}) - -//----------------- -#if defined(CORE_OC3A_PIN) -# define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 5 // Arduino Mega -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) -# define TIMER_PWM_PIN 6 // MightyCore -#else -# error "Please add OC3A pin number here\n" -#endif - -//--------------------------------------------------------- -// Timer4 (10 bits, high speed option) -// -#elif defined(IR_USE_TIMER4_HS) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) -#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) -#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) -#define TIMER_DISABLE_INTR (TIMSK4 = 0) -#define TIMER_INTR_NAME TIMER4_OVF_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR4A = (1<> 8; \ - OCR4C = pwmval; \ - TC4H = (pwmval / 3) >> 8; \ - OCR4A = (pwmval / 3) & 255; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR4A = 0; \ - TCCR4B = _BV(CS40); \ - TCCR4C = 0; \ - TCCR4D = 0; \ - TCCR4E = 0; \ - TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ - OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ - TC4H = 0; \ - TCNT4 = 0; \ -}) - -//----------------- -#if defined(CORE_OC4A_PIN) -# define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy -#elif defined(__AVR_ATmega32U4__) -# define TIMER_PWM_PIN 13 // Leonardo -#else -# error "Please add OC4A pin number here\n" -#endif - -//--------------------------------------------------------- -// Timer4 (16 bits) -// -#elif defined(IR_USE_TIMER4) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) -#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) -#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) -#define TIMER_DISABLE_INTR (TIMSK4 = 0) -#define TIMER_INTR_NAME TIMER4_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR4A = _BV(WGM41); \ - TCCR4B = _BV(WGM43) | _BV(CS40); \ - ICR4 = pwmval; \ - OCR4A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR4A = 0; \ - TCCR4B = _BV(WGM42) | _BV(CS40); \ - OCR4A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT4 = 0; \ -}) - -//----------------- -#if defined(CORE_OC4A_PIN) -# define TIMER_PWM_PIN CORE_OC4A_PIN -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 6 // Arduino Mega -#else -# error "Please add OC4A pin number here\n" -#endif - -//--------------------------------------------------------- -// Timer5 (16 bits) -// -#elif defined(IR_USE_TIMER5) - -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) -#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) -#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) -#define TIMER_DISABLE_INTR (TIMSK5 = 0) -#define TIMER_INTR_NAME TIMER5_COMPA_vect - -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR5A = _BV(WGM51); \ - TCCR5B = _BV(WGM53) | _BV(CS50); \ - ICR5 = pwmval; \ - OCR5A = pwmval / 3; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR5A = 0; \ - TCCR5B = _BV(WGM52) | _BV(CS50); \ - OCR5A = SYSCLOCK * USECPERTICK / 1000000; \ - TCNT5 = 0; \ -}) - -//----------------- -#if defined(CORE_OC5A_PIN) -# define TIMER_PWM_PIN CORE_OC5A_PIN -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 46 // Arduino Mega -#else -# error "Please add OC5A pin number here\n" -#endif - -//--------------------------------------------------------- -// Special carrier modulator timer -// -#elif defined(IR_USE_TIMER_CMT) - -#define TIMER_RESET ({ \ - uint8_t tmp __attribute__((unused)) = CMT_MSC; \ - CMT_CMD2 = 30; \ -}) - -#define TIMER_ENABLE_PWM do { \ - CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \ -} while(0) - -#define TIMER_DISABLE_PWM do { \ - CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \ -} while(0) - -#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) -#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) -#define TIMER_INTR_NAME cmt_isr - -//----------------- -#ifdef ISR -# undef ISR -#endif -#define ISR(f) void f(void) - -//----------------- -#define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000) -#if F_BUS < 8000000 -#error IRremote requires at least 8 MHz on Teensy 3.x -#endif - -//----------------- -#define TIMER_CONFIG_KHZ(val) ({ \ - SIM_SCGC4 |= SIM_SCGC4_CMT; \ - SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ - CMT_PPS = CMT_PPS_DIV - 1; \ - CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((val)/2)) / (val); \ - CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((val)/2)) / (val); \ - CMT_CMD1 = 0; \ - CMT_CMD2 = 30; \ - CMT_CMD3 = 0; \ - CMT_CMD4 = 0; \ - CMT_OC = 0x60; \ - CMT_MSC = 0x01; \ -}) - -#define TIMER_CONFIG_NORMAL() ({ \ - SIM_SCGC4 |= SIM_SCGC4_CMT; \ - CMT_PPS = CMT_PPS_DIV - 1; \ - CMT_CGH1 = 1; \ - CMT_CGL1 = 1; \ - CMT_CMD1 = 0; \ - CMT_CMD2 = 30; \ - CMT_CMD3 = 0; \ - CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \ - CMT_OC = 0; \ - CMT_MSC = 0x03; \ -}) - -#define TIMER_PWM_PIN 5 - -// defines for TPM1 timer on Teensy-LC -#elif defined(IR_USE_TIMER_TPM1) -#define TIMER_RESET FTM1_SC |= FTM_SC_TOF; -#define TIMER_ENABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE -#define TIMER_DISABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE -#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1) -#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1) -#define TIMER_INTR_NAME ftm1_isr -#ifdef ISR -#undef ISR -#endif -#define ISR(f) void f(void) -#define TIMER_CONFIG_KHZ(val) ({ \ - SIM_SCGC6 |= SIM_SCGC6_TPM1; \ - FTM1_SC = 0; \ - FTM1_CNT = 0; \ - FTM1_MOD = (F_PLL/2000) / val - 1; \ - FTM1_C0V = (F_PLL/6000) / val - 1; \ - FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \ -}) -#define TIMER_CONFIG_NORMAL() ({ \ - SIM_SCGC6 |= SIM_SCGC6_TPM1; \ - FTM1_SC = 0; \ - FTM1_CNT = 0; \ - FTM1_MOD = (F_PLL/40000) - 1; \ - FTM1_C0V = 0; \ - FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \ -}) -#define TIMER_PWM_PIN 16 - -// defines for timer_tiny0 (8 bits) -#elif defined(IR_USE_TIMER_TINY0) -#define TIMER_RESET -#define TIMER_ENABLE_PWM (TCCR0A |= _BV(COM0B1)) -#define TIMER_DISABLE_PWM (TCCR0A &= ~(_BV(COM0B1))) -#define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE0A)) -#define TIMER_DISABLE_INTR (TIMSK &= ~(_BV(OCIE0A))) -#define TIMER_INTR_NAME TIMER0_COMPA_vect -#define TIMER_CONFIG_KHZ(val) ({ \ - const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ - TCCR0A = _BV(WGM00); \ - TCCR0B = _BV(WGM02) | _BV(CS00); \ - OCR0A = pwmval; \ - OCR0B = pwmval / 3; \ -}) -#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) -#if (TIMER_COUNT_TOP < 256) -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR0A = _BV(WGM01); \ - TCCR0B = _BV(CS00); \ - OCR0A = TIMER_COUNT_TOP; \ - TCNT0 = 0; \ -}) -#else -#define TIMER_CONFIG_NORMAL() ({ \ - TCCR0A = _BV(WGM01); \ - TCCR0B = _BV(CS01); \ - OCR0A = TIMER_COUNT_TOP / 8; \ - TCNT0 = 0; \ -}) -#endif - -#define TIMER_PWM_PIN 1 /* ATtiny85 */ - -//--------------------------------------------------------- -// Unknown Timer -// -#else -# error "Internal code configuration error, no known IR_USE_TIMER# defined\n" -#endif #endif diff --git a/boarddefs.h b/boarddefs.h new file mode 100644 index 000000000..62b6be4fb --- /dev/null +++ b/boarddefs.h @@ -0,0 +1,548 @@ +//****************************************************************************** +// IRremote +// Version 2.0.1 June, 2015 +// Copyright 2009 Ken Shirriff +// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html + +// This file contains all board specific information. It was previously contained within +// IRremoteInt.h + +// Modified by Paul Stoffregen to support other boards and timers +// +// 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) +// Whynter A/C ARC-110WD added by Francesco Meschia +//****************************************************************************** + +#ifndef boarddefs_h +#define boarddefs_h + +//------------------------------------------------------------------------------ +// Defines for blinking the LED +// + +#if defined(CORE_LED0_PIN) +# 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__) || defined(__AVR_ATmega2560__) +# define BLINKLED 13 +# define BLINKLED_ON() (PORTB |= B10000000) +# define BLINKLED_OFF() (PORTB &= B01111111) + +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) +# define BLINKLED 0 +# define BLINKLED_ON() (PORTD |= B00000001) +# define BLINKLED_OFF() (PORTD &= B11111110) + +#else +# define BLINKLED 13 + #define BLINKLED_ON() (PORTB |= B00100000) +# define BLINKLED_OFF() (PORTB &= B11011111) +#endif + +//------------------------------------------------------------------------------ +// CPU Frequency +// +#ifdef F_CPU +# define SYSCLOCK F_CPU // main Arduino clock +#else +# define SYSCLOCK 16000000 // main Arduino clock +#endif + +// microseconds per clock interrupt tick +#define USECPERTICK 50 + +//------------------------------------------------------------------------------ +// Define which timer to use +// +// Uncomment the timer you wish to use on your board. +// If you are using another library which uses timer2, you have options to +// switch IRremote to use a different timer. +// + +// Arduino Mega +#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 + //#define IR_USE_TIMER4 // tx = pin 6 + //#define IR_USE_TIMER5 // tx = pin 46 + +// Teensy 1.0 +#elif defined(__AVR_AT90USB162__) + #define IR_USE_TIMER1 // tx = pin 17 + +// Teensy 2.0 +#elif defined(__AVR_ATmega32U4__) + //#define IR_USE_TIMER1 // tx = pin 14 + //#define IR_USE_TIMER3 // tx = pin 9 + #define IR_USE_TIMER4_HS // tx = pin 10 + +// Teensy 3.0 / Teensy 3.1 +#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) + #define IR_USE_TIMER_CMT // tx = pin 5 + +// Teensy-LC +#elif defined(__MKL26Z64__) + #define IR_USE_TIMER_TPM1 // tx = pin 16 + +// Teensy++ 1.0 & 2.0 +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) + //#define IR_USE_TIMER1 // tx = pin 25 + #define IR_USE_TIMER2 // tx = pin 1 + //#define IR_USE_TIMER3 // tx = pin 16 + +// MightyCore - ATmega1284 +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) + //#define IR_USE_TIMER1 // tx = pin 13 + #define IR_USE_TIMER2 // tx = pin 14 + //#define IR_USE_TIMER3 // tx = pin 6 + +// MightyCore - ATmega164, ATmega324, ATmega644 +#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) + //#define IR_USE_TIMER1 // tx = pin 13 + #define IR_USE_TIMER2 // tx = pin 14 + +//MegaCore - ATmega64, ATmega128 +#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) + #define IR_USE_TIMER1 // tx = pin 13 + +// MightyCore - ATmega8535, ATmega16, ATmega32 +#elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) + #define IR_USE_TIMER1 // tx = pin 13 + +// Atmega8 +#elif defined(__AVR_ATmega8__) + #define IR_USE_TIMER1 // tx = pin 9 + +// ATtiny84 +#elif defined(__AVR_ATtiny84__) + #define IR_USE_TIMER1 // tx = pin 6 + +//ATtiny85 +#elif defined(__AVR_ATtiny85__) + #define IR_USE_TIMER_TINY0 // tx = pin 1 + +// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc +// ATmega48, ATmega88, ATmega168, ATmega328 +#else + //#define IR_USE_TIMER1 // tx = pin 9 + #define IR_USE_TIMER2 // tx = pin 3 + +#endif + +//------------------------------------------------------------------------------ +// Defines for Timer + +//--------------------------------------------------------- +// Timer2 (8 bits) +// +#if defined(IR_USE_TIMER2) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) +#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) +#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) +#define TIMER_DISABLE_INTR (TIMSK2 = 0) +#define TIMER_INTR_NAME TIMER2_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR2A = _BV(WGM20); \ + TCCR2B = _BV(WGM22) | _BV(CS20); \ + OCR2A = pwmval; \ + OCR2B = pwmval / 3; \ +}) + +#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) + +//----------------- +#if (TIMER_COUNT_TOP < 256) +# define TIMER_CONFIG_NORMAL() ({ \ + TCCR2A = _BV(WGM21); \ + TCCR2B = _BV(CS20); \ + OCR2A = TIMER_COUNT_TOP; \ + TCNT2 = 0; \ + }) +#else +# define TIMER_CONFIG_NORMAL() ({ \ + TCCR2A = _BV(WGM21); \ + TCCR2B = _BV(CS21); \ + OCR2A = TIMER_COUNT_TOP / 8; \ + TCNT2 = 0; \ + }) +#endif + +//----------------- +#if defined(CORE_OC2B_PIN) +# define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 9 // Arduino Mega +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ +|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) +# define TIMER_PWM_PIN 14 // MightyCore +#else +# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc +#endif // ATmega48, ATmega88, ATmega168, ATmega328 + +//--------------------------------------------------------- +// Timer1 (16 bits) +// +#elif defined(IR_USE_TIMER1) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) +#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) + +//----------------- +#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8535__) \ +|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ +|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) +# define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) +# define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) +#else +# define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) +# define TIMER_DISABLE_INTR (TIMSK1 = 0) +#endif + +//----------------- +#define TIMER_INTR_NAME TIMER1_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR1A = _BV(WGM11); \ + TCCR1B = _BV(WGM13) | _BV(CS10); \ + ICR1 = pwmval; \ + OCR1A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR1A = 0; \ + TCCR1B = _BV(WGM12) | _BV(CS10); \ + OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT1 = 0; \ +}) + +//----------------- +#if defined(CORE_OC1A_PIN) +# define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 11 // Arduino Mega +#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) +# define TIMER_PWM_PIN 13 // MegaCore +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ +|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ +|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) +# define TIMER_PWM_PIN 13 // MightyCore +#elif defined(__AVR_ATtiny84__) +# define TIMER_PWM_PIN 6 +#else +# define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc +#endif // ATmega48, ATmega88, ATmega168, ATmega328 + +//--------------------------------------------------------- +// Timer3 (16 bits) +// +#elif defined(IR_USE_TIMER3) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1)) +#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1))) +#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A)) +#define TIMER_DISABLE_INTR (TIMSK3 = 0) +#define TIMER_INTR_NAME TIMER3_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR3A = _BV(WGM31); \ + TCCR3B = _BV(WGM33) | _BV(CS30); \ + ICR3 = pwmval; \ + OCR3A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR3A = 0; \ + TCCR3B = _BV(WGM32) | _BV(CS30); \ + OCR3A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT3 = 0; \ +}) + +//----------------- +#if defined(CORE_OC3A_PIN) +# define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 5 // Arduino Mega +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) +# define TIMER_PWM_PIN 6 // MightyCore +#else +# error "Please add OC3A pin number here\n" +#endif + +//--------------------------------------------------------- +// Timer4 (10 bits, high speed option) +// +#elif defined(IR_USE_TIMER4_HS) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) +#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) +#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) +#define TIMER_DISABLE_INTR (TIMSK4 = 0) +#define TIMER_INTR_NAME TIMER4_OVF_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR4A = (1<> 8; \ + OCR4C = pwmval; \ + TC4H = (pwmval / 3) >> 8; \ + OCR4A = (pwmval / 3) & 255; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR4A = 0; \ + TCCR4B = _BV(CS40); \ + TCCR4C = 0; \ + TCCR4D = 0; \ + TCCR4E = 0; \ + TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ + OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ + TC4H = 0; \ + TCNT4 = 0; \ +}) + +//----------------- +#if defined(CORE_OC4A_PIN) +# define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy +#elif defined(__AVR_ATmega32U4__) +# define TIMER_PWM_PIN 13 // Leonardo +#else +# error "Please add OC4A pin number here\n" +#endif + +//--------------------------------------------------------- +// Timer4 (16 bits) +// +#elif defined(IR_USE_TIMER4) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) +#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) +#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) +#define TIMER_DISABLE_INTR (TIMSK4 = 0) +#define TIMER_INTR_NAME TIMER4_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR4A = _BV(WGM41); \ + TCCR4B = _BV(WGM43) | _BV(CS40); \ + ICR4 = pwmval; \ + OCR4A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR4A = 0; \ + TCCR4B = _BV(WGM42) | _BV(CS40); \ + OCR4A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT4 = 0; \ +}) + +//----------------- +#if defined(CORE_OC4A_PIN) +# define TIMER_PWM_PIN CORE_OC4A_PIN +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 6 // Arduino Mega +#else +# error "Please add OC4A pin number here\n" +#endif + +//--------------------------------------------------------- +// Timer5 (16 bits) +// +#elif defined(IR_USE_TIMER5) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) +#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) +#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) +#define TIMER_DISABLE_INTR (TIMSK5 = 0) +#define TIMER_INTR_NAME TIMER5_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR5A = _BV(WGM51); \ + TCCR5B = _BV(WGM53) | _BV(CS50); \ + ICR5 = pwmval; \ + OCR5A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR5A = 0; \ + TCCR5B = _BV(WGM52) | _BV(CS50); \ + OCR5A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT5 = 0; \ +}) + +//----------------- +#if defined(CORE_OC5A_PIN) +# define TIMER_PWM_PIN CORE_OC5A_PIN +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 46 // Arduino Mega +#else +# error "Please add OC5A pin number here\n" +#endif + +//--------------------------------------------------------- +// Special carrier modulator timer +// +#elif defined(IR_USE_TIMER_CMT) + +#define TIMER_RESET ({ \ + uint8_t tmp __attribute__((unused)) = CMT_MSC; \ + CMT_CMD2 = 30; \ +}) + +#define TIMER_ENABLE_PWM do { \ + CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \ +} while(0) + +#define TIMER_DISABLE_PWM do { \ + CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \ +} while(0) + +#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) +#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) +#define TIMER_INTR_NAME cmt_isr + +//----------------- +#ifdef ISR +# undef ISR +#endif +#define ISR(f) void f(void) + +//----------------- +#define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000) +#if F_BUS < 8000000 +#error IRremote requires at least 8 MHz on Teensy 3.x +#endif + +//----------------- +#define TIMER_CONFIG_KHZ(val) ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ + CMT_PPS = CMT_PPS_DIV - 1; \ + CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((val)/2)) / (val); \ + CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((val)/2)) / (val); \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = 0; \ + CMT_OC = 0x60; \ + CMT_MSC = 0x01; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + CMT_PPS = CMT_PPS_DIV - 1; \ + CMT_CGH1 = 1; \ + CMT_CGL1 = 1; \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \ + CMT_OC = 0; \ + CMT_MSC = 0x03; \ +}) + +#define TIMER_PWM_PIN 5 + +// defines for TPM1 timer on Teensy-LC +#elif defined(IR_USE_TIMER_TPM1) +#define TIMER_RESET FTM1_SC |= FTM_SC_TOF; +#define TIMER_ENABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE +#define TIMER_DISABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE +#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1) +#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1) +#define TIMER_INTR_NAME ftm1_isr +#ifdef ISR +#undef ISR +#endif +#define ISR(f) void f(void) +#define TIMER_CONFIG_KHZ(val) ({ \ + SIM_SCGC6 |= SIM_SCGC6_TPM1; \ + FTM1_SC = 0; \ + FTM1_CNT = 0; \ + FTM1_MOD = (F_PLL/2000) / val - 1; \ + FTM1_C0V = (F_PLL/6000) / val - 1; \ + FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + SIM_SCGC6 |= SIM_SCGC6_TPM1; \ + FTM1_SC = 0; \ + FTM1_CNT = 0; \ + FTM1_MOD = (F_PLL/40000) - 1; \ + FTM1_C0V = 0; \ + FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \ +}) +#define TIMER_PWM_PIN 16 + +// defines for timer_tiny0 (8 bits) +#elif defined(IR_USE_TIMER_TINY0) +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR0A |= _BV(COM0B1)) +#define TIMER_DISABLE_PWM (TCCR0A &= ~(_BV(COM0B1))) +#define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE0A)) +#define TIMER_DISABLE_INTR (TIMSK &= ~(_BV(OCIE0A))) +#define TIMER_INTR_NAME TIMER0_COMPA_vect +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR0A = _BV(WGM00); \ + TCCR0B = _BV(WGM02) | _BV(CS00); \ + OCR0A = pwmval; \ + OCR0B = pwmval / 3; \ +}) +#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) +#if (TIMER_COUNT_TOP < 256) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR0A = _BV(WGM01); \ + TCCR0B = _BV(CS00); \ + OCR0A = TIMER_COUNT_TOP; \ + TCNT0 = 0; \ +}) +#else +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR0A = _BV(WGM01); \ + TCCR0B = _BV(CS01); \ + OCR0A = TIMER_COUNT_TOP / 8; \ + TCNT0 = 0; \ +}) +#endif + +#define TIMER_PWM_PIN 1 /* ATtiny85 */ + +//--------------------------------------------------------- +// Unknown Timer +// +#else +# error "Internal code configuration error, no known IR_USE_TIMER# defined\n" +#endif + +#endif // ! boarddefs_h From 20b6e3b8a26f4898cb5f2f1f57a482f96044f260 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Fri, 11 Nov 2016 22:28:41 -0600 Subject: [PATCH 189/768] Just gonna put this in here.... --- Contributors.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Contributors.md b/Contributors.md index cabd0654e..36ec80630 100644 --- a/Contributors.md +++ b/Contributors.md @@ -5,6 +5,7 @@ These are the active contributors of this project that you may contact if there * Email: zetoslab@gmail.com * Skype: polarised16 - [shirriff](https://github.com/shirriff) : An amazing person who worked to create this awesome library and provide unending support +- [AnalysIR](https:/github.com/AnalysIR): Active contributor and is amazing with providing support! - [Informatic](https://github.com/Informatic) : Active contributor - [fmeschia](https://github.com/fmeschia) : Active contributor - [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor From 9a74475c8d88ff2d55742f7609ce3394fda3b653 Mon Sep 17 00:00:00 2001 From: Felipe Noronha Date: Fri, 13 Jan 2017 11:58:40 -0200 Subject: [PATCH 190/768] fix example error message --- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index cbfadccec..725612735 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -66,7 +66,7 @@ void dumpInfo (decode_results *results) { // Check if the buffer overflowed if (results->overflow) { - Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWLEN"); + Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWBUF"); return; } From 3b41130ff916f03e46e8e45d5c54a0f02124ae0f Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Fri, 20 Jan 2017 23:59:24 -0600 Subject: [PATCH 191/768] Manual merge of #398 --- changelog.md | 3 +++ examples/IRrecord/IRrecord.ino | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index fbe70b457..cb2b7e26f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +## 2.2.2 - 2017/01/20 +- Fixed naming bug [PR #398](https://github.com/z3t0/Arduino-IRremote/pull/398) + ## 2.2.1 - 2016/07/27 - Added tests for Lego Power Functions Protocol [PR #336](https://github.com/z3t0/Arduino-IRremote/pull/336) diff --git a/examples/IRrecord/IRrecord.ino b/examples/IRrecord/IRrecord.ino index bf290fa39..7fc5cfd39 100644 --- a/examples/IRrecord/IRrecord.ino +++ b/examples/IRrecord/IRrecord.ino @@ -126,7 +126,7 @@ void sendCode(int repeat) { Serial.println(codeValue, HEX); } else if (codeType == JVC) { - irsend.sendPanasonic(codeValue, codeLen); + irsend.sendJVC(codeValue, codeLen, false); Serial.print("Sent JVC"); Serial.println(codeValue, HEX); } From 4f24b696cf8ea2a7ec28c95c7216803fa3621ecd Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Fri, 3 Feb 2017 21:18:47 -0600 Subject: [PATCH 192/768] Update ISSUE_TEMPLATE.md --- ISSUE_TEMPLATE.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index bb9232ea3..98358d0e4 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -14,8 +14,12 @@ Use [a gist](gist.github.com) if the code exceeds 30 lines **checklist:** +- [] I have **read** the README.md file thoroughly +- [] I have searched existing issues to see if there is anything I have missed. - [] The latest [release](https://github.com/z3t0/Arduino-IRremote/releases/latest) is used -- [] Any code referenced is provided +- [] Any code referenced is provided and if over 30 lines a gist is linked INSTEAD of it being pasted in here - [] The title of the issue is helpful and relevant -The above is a short template allowing you to make detailed issues! \ No newline at end of file +** We will start to close issues that do not follow these guidelines as it doesn't help the contributors who spend time trying to solve issues if the community ignores guidelines!** + +The above is a short template allowing you to make detailed issues! From aa8f7b31fe16ccb8e26baa5e887126bfca4e24ed Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Sun, 19 Mar 2017 20:27:56 -0700 Subject: [PATCH 193/768] Added ESP32 IR receive support (IRsend not implemented yet). - disable a lot of defines not relevant to ESP32, set them to 1 (no-op) - change default IR pin to 35 from 11 - changed serial speed to 115200 (9600 is too slow to keep up with IR input) - irSend disables code that will not compile on ESP32. It won't work, but it won't break compilation either. --- IRremote.cpp | 6 ++++++ boarddefs.h | 13 +++++++++++++ examples/IRrecvDemo/IRrecvDemo.ino | 8 +++++++- examples/IRrecvDump/IRrecvDump.ino | 8 ++++++-- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 4 ++-- irRecv.cpp | 15 +++++++++++++++ irSend.cpp | 3 +++ 7 files changed, 52 insertions(+), 5 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index c9907ebe7..9613beaa1 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -18,7 +18,9 @@ // Whynter A/C ARC-110WD added by Francesco Meschia //****************************************************************************** +#ifndef ESP32 #include +#endif // Defining IR_GLOBAL here allows us to declare the instantiation of global variables #define IR_GLOBAL @@ -120,7 +122,11 @@ int MATCH_SPACE (int measured_ticks, int desired_us) // As soon as first MARK arrives: // Gap width is recorded; Ready is cleared; New logging starts // +#ifdef ESP32 +void onTimer() +#else ISR (TIMER_INTR_NAME) +#endif { TIMER_RESET; diff --git a/boarddefs.h b/boarddefs.h index 62b6be4fb..ce8a4f97d 100644 --- a/boarddefs.h +++ b/boarddefs.h @@ -39,6 +39,10 @@ # define BLINKLED_ON() (PORTD |= B00000001) # define BLINKLED_OFF() (PORTD &= B11111110) +#elif defined(ESP32) +# define BLINKLED 255 +# define BLINKLED_ON() 1 +# define BLINKLED_OFF() 1 #else # define BLINKLED 13 #define BLINKLED_ON() (PORTB |= B00100000) @@ -147,12 +151,21 @@ // #if defined(IR_USE_TIMER2) +#ifdef ESP32 // Used in irSend, not implemented yet (FIXME) +#define TIMER_RESET 1 +#define TIMER_ENABLE_PWM 1 +#define TIMER_DISABLE_PWM Serial.println("IRsend not implemented for ESP32 yet"); +#define TIMER_ENABLE_INTR 1 +#define TIMER_DISABLE_INTR 1 +#define TIMER_INTR_NAME 1 +#else #define TIMER_RESET #define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) #define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) #define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) #define TIMER_DISABLE_INTR (TIMSK2 = 0) #define TIMER_INTR_NAME TIMER2_COMPA_vect +#endif #define TIMER_CONFIG_KHZ(val) ({ \ const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ diff --git a/examples/IRrecvDemo/IRrecvDemo.ino b/examples/IRrecvDemo/IRrecvDemo.ino index 3a498328d..4635b2c79 100644 --- a/examples/IRrecvDemo/IRrecvDemo.ino +++ b/examples/IRrecvDemo/IRrecvDemo.ino @@ -8,7 +8,11 @@ #include +#ifdef ESP32 +int RECV_PIN = 35; +#else int RECV_PIN = 11; +#endif IRrecv irrecv(RECV_PIN); @@ -16,8 +20,10 @@ decode_results results; void setup() { - Serial.begin(9600); + Serial.begin(115200); + Serial.println("Enabling IRin"); irrecv.enableIRIn(); // Start the receiver + Serial.println("Enabled IRin"); } void loop() { diff --git a/examples/IRrecvDump/IRrecvDump.ino b/examples/IRrecvDump/IRrecvDump.ino index 90b47ba69..9a21b5698 100644 --- a/examples/IRrecvDump/IRrecvDump.ino +++ b/examples/IRrecvDump/IRrecvDump.ino @@ -15,7 +15,11 @@ * You can change this to another available Arduino Pin. * Your IR receiver should be connected to the pin defined here */ -int RECV_PIN = 11; +#ifdef ESP32 +int RECV_PIN = 35; +#else +int RECV_PIN = 11; +#endif IRrecv irrecv(RECV_PIN); @@ -23,7 +27,7 @@ decode_results results; void setup() { - Serial.begin(9600); + Serial.begin(115200); irrecv.enableIRIn(); // Start the receiver } diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index 725612735..570baba94 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -6,7 +6,7 @@ //------------------------------------------------------------------------------ // Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838) // -int recvPin = 11; +int recvPin = 35; IRrecv irrecv(recvPin); //+============================================================================= @@ -14,7 +14,7 @@ IRrecv irrecv(recvPin); // void setup ( ) { - Serial.begin(9600); // Status message will be sent to PC at 9600 baud + Serial.begin(115200); // Status message will be sent to PC at 9600 baud irrecv.enableIRIn(); // Start the receiver } diff --git a/irRecv.cpp b/irRecv.cpp index 63438566a..2f510c4a2 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -1,5 +1,10 @@ #include "IRremote.h" #include "IRremoteInt.h" + +#ifdef ESP32 +hw_timer_t *timer; +void onTimer(); // defined in IRremote.cpp +#endif //+============================================================================= // Decodes the received IR message @@ -117,6 +122,15 @@ IRrecv::IRrecv (int recvpin, int blinkpin) // void IRrecv::enableIRIn ( ) { +// Interrupt Service Routine - Fires every 50uS +#ifdef ESP32 + // 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up + timer = timerBegin(1, 80, 1); + timerAttachInterrupt(timer, &onTimer, 1); + // every 50ns, autoreload = true + timerAlarmWrite(timer, 50, true); + timerAlarmEnable(timer); +#else cli(); // Setup pulse clock timer interrupt // Prescale /8 (16M/8 = 0.5 microseconds per tick) @@ -130,6 +144,7 @@ void IRrecv::enableIRIn ( ) TIMER_RESET; sei(); // enable interrupts +#endif // Initialize state machine variables irparams.rcvstate = STATE_IDLE; diff --git a/irSend.cpp b/irSend.cpp index 253c941a9..6191aa6ad 100644 --- a/irSend.cpp +++ b/irSend.cpp @@ -54,6 +54,8 @@ void IRsend::space (unsigned int time) // void IRsend::enableIROut (int khz) { +// FIXME: implement ESP32 support +#ifndef ESP32 // Disable the Timer2 Interrupt (which is used for receiving IR) TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt @@ -66,6 +68,7 @@ void IRsend::enableIROut (int khz) // CS2 = 000: no prescaling // The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A. TIMER_CONFIG_KHZ(khz); +#endif } //+============================================================================= From 1b56da6cc73ec787e3d570e9906d80fad01933df Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Sun, 19 Mar 2017 21:28:14 -0700 Subject: [PATCH 194/768] Rename ESP32 timer name so that it doesn't conflict with other timers. --- IRremote.cpp | 2 +- irRecv.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index 9613beaa1..b438bc16f 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -123,7 +123,7 @@ int MATCH_SPACE (int measured_ticks, int desired_us) // Gap width is recorded; Ready is cleared; New logging starts // #ifdef ESP32 -void onTimer() +void IRTimer() #else ISR (TIMER_INTR_NAME) #endif diff --git a/irRecv.cpp b/irRecv.cpp index 2f510c4a2..a15ac0f57 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -3,7 +3,7 @@ #ifdef ESP32 hw_timer_t *timer; -void onTimer(); // defined in IRremote.cpp +void IRTimer(); // defined in IRremote.cpp #endif //+============================================================================= @@ -126,7 +126,7 @@ void IRrecv::enableIRIn ( ) #ifdef ESP32 // 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up timer = timerBegin(1, 80, 1); - timerAttachInterrupt(timer, &onTimer, 1); + timerAttachInterrupt(timer, &IRTimer, 1); // every 50ns, autoreload = true timerAlarmWrite(timer, 50, true); timerAlarmEnable(timer); From 257a15130ff2a3386984ea96405ca50707c23237 Mon Sep 17 00:00:00 2001 From: Philipp Henkel Date: Sun, 26 Mar 2017 22:32:55 +0200 Subject: [PATCH 195/768] Fix calculation of pause length in LEGO PF protocol Fix #384 Integer overflow in LEGO Power Functions affects pause between messages Is rebased version of PR #385 --- .../LegoPowerFunctionsTests.ino | 18 +++---- ir_Lego_PF_BitStreamEncoder.h | 50 +++++++++---------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino b/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino index 6a2bda57d..65760e2fd 100644 --- a/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino +++ b/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino @@ -1,6 +1,6 @@ /* * LegoPowerFunctionsTest: LEGO Power Functions Tests - * Copyright (c) 2016 Philipp Henkel + * Copyright (c) 2016, 2017 Philipp Henkel */ #include @@ -78,14 +78,14 @@ void testMessageBitCount(LegoPfBitStreamEncoder& bitStreamEncoder) { logTestResult(bitCount == 18); } -boolean check(LegoPfBitStreamEncoder& bitStreamEncoder, int markDuration, int pauseDuration) { +boolean check(LegoPfBitStreamEncoder& bitStreamEncoder, unsigned long markDuration, unsigned long pauseDuration) { bool result = true; result = result && bitStreamEncoder.getMarkDuration() == markDuration; result = result && bitStreamEncoder.getPauseDuration() == pauseDuration; return result; } -boolean checkNext(LegoPfBitStreamEncoder& bitStreamEncoder, int markDuration, int pauseDuration) { +boolean checkNext(LegoPfBitStreamEncoder& bitStreamEncoder, unsigned long markDuration, unsigned long pauseDuration) { bool result = bitStreamEncoder.next(); result = result && check(bitStreamEncoder, markDuration, pauseDuration); return result; @@ -129,16 +129,16 @@ void testMessage407Repeated(LegoPfBitStreamEncoder& bitStreamEncoder) { bool result = true; result = result && check(bitStreamEncoder, 158, 1026); result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026 + 5 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 5L * 16000L - 10844L); result = result && checkNext(bitStreamEncoder, 158, 1026); result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026 + 5 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 5L * 16000L - 10844L); result = result && checkNext(bitStreamEncoder, 158, 1026); result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026 + 8 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 8L * 16000L - 10844L); result = result && checkNext(bitStreamEncoder, 158, 1026); result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026 + 8 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 8L * 16000L - 10844L); result = result && checkNext(bitStreamEncoder, 158, 1026); result = result && checkDataBitsOfMessage407(bitStreamEncoder); result = result && checkNext(bitStreamEncoder, 158, 1026); @@ -191,7 +191,3 @@ void testGetMessageLengthAllLow(LegoPfBitStreamEncoder& bitStreamEncoder) { bitStreamEncoder.reset(0x0, false); logTestResult(bitStreamEncoder.getMessageLength() == 9104); } - - - - diff --git a/ir_Lego_PF_BitStreamEncoder.h b/ir_Lego_PF_BitStreamEncoder.h index 7689cde28..e5a3d66a9 100644 --- a/ir_Lego_PF_BitStreamEncoder.h +++ b/ir_Lego_PF_BitStreamEncoder.h @@ -4,7 +4,7 @@ // L E E O O // L EEEE E EEE O O // L E E E O O LEGO Power Functions -// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016 Philipp Henkel +// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016, 2017 Philipp Henkel //============================================================================== //+============================================================================= @@ -14,25 +14,25 @@ class LegoPfBitStreamEncoder { private: uint16_t data; bool repeatMessage; - int messageBitIdx; - int repeatCount; - int messageLength; + uint8_t messageBitIdx; + uint8_t repeatCount; + uint16_t messageLength; + public: // HIGH data bit = IR mark + high pause // LOW data bit = IR mark + low pause - static const int LOW_BIT_DURATION = 421; - static const int HIGH_BIT_DURATION = 711; - static const int START_BIT_DURATION = 1184; - static const int STOP_BIT_DURATION = 1184; - static const int IR_MARK_DURATION = 158; - static const int HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; - static const int LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; - static const int START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; - static const int STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; - static const int MESSAGE_BITS = 18; - static const int MAX_MESSAGE_LENGTH = 16000; + static const uint16_t LOW_BIT_DURATION = 421; + static const uint16_t HIGH_BIT_DURATION = 711; + static const uint16_t START_BIT_DURATION = 1184; + static const uint16_t STOP_BIT_DURATION = 1184; + static const uint8_t IR_MARK_DURATION = 158; + static const uint16_t HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; + static const uint16_t LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; + static const uint16_t START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; + static const uint16_t STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; + static const uint8_t MESSAGE_BITS = 18; + static const uint16_t MAX_MESSAGE_LENGTH = 16000; - public: void reset(uint16_t data, bool repeatMessage) { this->data = data; this->repeatMessage = repeatMessage; @@ -43,9 +43,9 @@ class LegoPfBitStreamEncoder { int getChannelId() const { return 1 + ((data >> 12) & 0x3); } - int getMessageLength() const { + uint16_t getMessageLength() const { // Sum up all marks - int length = MESSAGE_BITS * IR_MARK_DURATION; + uint16_t length = MESSAGE_BITS * IR_MARK_DURATION; // Sum up all pauses length += START_PAUSE_DURATION; @@ -75,9 +75,9 @@ class LegoPfBitStreamEncoder { } } - int getMarkDuration() const { return IR_MARK_DURATION; } + uint8_t getMarkDuration() const { return IR_MARK_DURATION; } - int getPauseDuration() const { + uint32_t getPauseDuration() const { if (messageBitIdx == 0) return START_PAUSE_DURATION; else if (messageBitIdx < MESSAGE_BITS - 1) { @@ -88,13 +88,13 @@ class LegoPfBitStreamEncoder { } private: - int getDataBitPause() const { + uint16_t getDataBitPause() const { const int pos = MESSAGE_BITS - 2 - messageBitIdx; const bool isHigh = data & (1 << pos); return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION; } - int getStopPause() const { + uint32_t getStopPause() const { if (repeatMessage) { return getRepeatStopPause(); } else { @@ -102,12 +102,12 @@ class LegoPfBitStreamEncoder { } } - int getRepeatStopPause() const { + uint32_t getRepeatStopPause() const { if (repeatCount == 0 || repeatCount == 1) { - return STOP_PAUSE_DURATION + 5 * MAX_MESSAGE_LENGTH - messageLength; + return STOP_PAUSE_DURATION + (uint32_t)5 * MAX_MESSAGE_LENGTH - messageLength; } else if (repeatCount == 2 || repeatCount == 3) { return STOP_PAUSE_DURATION - + (6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; + + (uint32_t)(6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; } else { return STOP_PAUSE_DURATION; } From ccc9d0135cd5d4786b5b1ccc8b2a5056a9900e4c Mon Sep 17 00:00:00 2001 From: Philipp Henkel Date: Mon, 27 Mar 2017 19:57:25 +0200 Subject: [PATCH 196/768] Add Lego fix to change and bump version up to 2.2.3 --- Contributors.md | 2 +- README.md | 4 ++-- changelog.md | 3 +++ library.json | 2 +- library.properties | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Contributors.md b/Contributors.md index 36ec80630..ae2489008 100644 --- a/Contributors.md +++ b/Contributors.md @@ -16,7 +16,7 @@ These are the active contributors of this project that you may contact if there - [Sebazzz](https://github.com/sebazz): Contributor - [lumbric](https://github.com/lumbric): Contributor - [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor -- [henkel](https://github.com/henkel): Contributor +- [philipphenkel](https://github.com/philipphenkel): Active Contributor - [MCUdude](https://github.com/MCUdude): Contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. diff --git a/README.md b/README.md index c8e074cf9..2ec302c58 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This library enables you to send and receive using infra-red signals on an Ardui Tutorials and more information will be made available on [the official homepage](http://z3t0.github.io/Arduino-IRremote/). -## Version - 2.2.1 +## Version - 2.2.3 ## Installation 1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. @@ -65,7 +65,7 @@ Check [here](Contributing.md) for some guidelines. ## Contact Email: zetoslab@gmail.com -Please only email me if it is more appropriate than creating an Issue / PR. I **will** not respond to requests for adding support for particular boards, unless of course you are the creator of the board and would like to cooperate on the project. I will also **ignore** any emails asking me to tell you how to implement your ideas. However, if you have a private inquiry that you would only apply to you and you would prefer it to be via email, by all means. +Please only email me if it is more appropriate than creating an Issue / PR. I **will** not respond to requests for adding support for particular boards, unless of course you are the creator of the board and would like to cooperate on the project. I will also **ignore** any emails asking me to tell you how to implement your ideas. However, if you have a private inquiry that you would only apply to you and you would prefer it to be via email, by all means. ## Contributors Check [here](Contributors.md) diff --git a/changelog.md b/changelog.md index cb2b7e26f..0702ddcf9 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +## 2.2.3 - 2017/03/27 +- Fix calculation of pause length in LEGO PF protocol [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/427) + ## 2.2.2 - 2017/01/20 - Fixed naming bug [PR #398](https://github.com/z3t0/Arduino-IRremote/pull/398) diff --git a/library.json b/library.json index 090578d10..de93d16e5 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/z3t0/Arduino-IRremote.git" }, - "version": "2.2.1", + "version": "2.2.3", "frameworks": "arduino", "platforms": "atmelavr", "authors" : diff --git a/library.properties b/library.properties index 15aabee44..39fd814eb 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=IRremote -version=2.2.1 +version=2.2.3 author=shirriff maintainer=shirriff sentence=Send and receive infrared signals with multiple protocols From eae9de43076fb839cad9c1371ceac7c0579f7b46 Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Fri, 31 Mar 2017 21:52:52 -0700 Subject: [PATCH 197/768] Cleaned up ESP32 integration, reverted ESP32 ifdefs on irreceive examples. - fixed indenting on existing code in a few places for consistency - introduced IR_TIMER_USE_ESP32 for ifdefs within the code as per request - added comments explaining what's missing for irsend support on ESP32 - IRrecvDemo.ino gets a warning before and after interrupt is enabled in case it causes a crash TESTED=IoTuz ESP32 board and original 328p arduino to make sure current code did not break. --- IRremote.cpp | 11 +++---- boarddefs.h | 40 ++++++++++++++++++-------- examples/IRrecvDemo/IRrecvDemo.ino | 8 ++---- examples/IRrecvDump/IRrecvDump.ino | 4 --- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 4 +-- irRecv.cpp | 2 ++ irSend.cpp | 2 +- 7 files changed, 42 insertions(+), 29 deletions(-) diff --git a/IRremote.cpp b/IRremote.cpp index b438bc16f..e811cfc7b 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -18,16 +18,17 @@ // Whynter A/C ARC-110WD added by Francesco Meschia //****************************************************************************** -#ifndef ESP32 -#include -#endif - // Defining IR_GLOBAL here allows us to declare the instantiation of global variables #define IR_GLOBAL # include "IRremote.h" # include "IRremoteInt.h" #undef IR_GLOBAL +#ifndef IR_TIMER_USE_ESP32 +#include +#endif + + //+============================================================================= // The match functions were (apparently) originally MACROs to improve code speed // (although this would have bloated the code) hence the names being CAPS @@ -122,7 +123,7 @@ int MATCH_SPACE (int measured_ticks, int desired_us) // As soon as first MARK arrives: // Gap width is recorded; Ready is cleared; New logging starts // -#ifdef ESP32 +#ifdef IR_TIMER_USE_ESP32 void IRTimer() #else ISR (TIMER_INTR_NAME) diff --git a/boarddefs.h b/boarddefs.h index ce8a4f97d..c126b546b 100644 --- a/boarddefs.h +++ b/boarddefs.h @@ -39,13 +39,14 @@ # define BLINKLED_ON() (PORTD |= B00000001) # define BLINKLED_OFF() (PORTD &= B11111110) +// No system LED on ESP32, disable blinking #elif defined(ESP32) # define BLINKLED 255 # define BLINKLED_ON() 1 # define BLINKLED_OFF() 1 #else # define BLINKLED 13 - #define BLINKLED_ON() (PORTB |= B00100000) +# define BLINKLED_ON() (PORTB |= B00100000) # define BLINKLED_OFF() (PORTB &= B11011111) #endif @@ -129,14 +130,16 @@ // ATtiny84 #elif defined(__AVR_ATtiny84__) - #define IR_USE_TIMER1 // tx = pin 6 + #define IR_USE_TIMER1 // tx = pin 6 //ATtiny85 #elif defined(__AVR_ATtiny85__) - #define IR_USE_TIMER_TINY0 // tx = pin 1 + #define IR_USE_TIMER_TINY0 // tx = pin 1 // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc // ATmega48, ATmega88, ATmega168, ATmega328 +#elif defined(ESP32) + #define IR_TIMER_USE_ESP32 #else //#define IR_USE_TIMER1 // tx = pin 9 #define IR_USE_TIMER2 // tx = pin 3 @@ -151,21 +154,12 @@ // #if defined(IR_USE_TIMER2) -#ifdef ESP32 // Used in irSend, not implemented yet (FIXME) -#define TIMER_RESET 1 -#define TIMER_ENABLE_PWM 1 -#define TIMER_DISABLE_PWM Serial.println("IRsend not implemented for ESP32 yet"); -#define TIMER_ENABLE_INTR 1 -#define TIMER_DISABLE_INTR 1 -#define TIMER_INTR_NAME 1 -#else #define TIMER_RESET #define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) #define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) #define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) #define TIMER_DISABLE_INTR (TIMSK2 = 0) #define TIMER_INTR_NAME TIMER2_COMPA_vect -#endif #define TIMER_CONFIG_KHZ(val) ({ \ const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ @@ -551,6 +545,28 @@ #define TIMER_PWM_PIN 1 /* ATtiny85 */ +//--------------------------------------------------------- +// ESP32 (ESP8266 should likely be added here too) +// + +// ESP32 has it own timer API and does not use these macros, but to avoid ifdef'ing +// them out in the common code, they are defined to no-op. This allows the code to compile +// (which it wouldn't otherwise) but irsend will not work until ESP32 specific code is written +// for that -- merlin +// As a warning, sending timing specific code from an ESP32 can be challenging if you need 100% +// reliability because the arduino code may be interrupted and cause your sent waveform to be the +// wrong length. This is specifically an issue for neopixels which require 800Khz resolution. +// IR may just work as is with the common code since it's lower frequency, but if not, the other +// way to do this on ESP32 is using the RMT built in driver like in this incomplete library below +// https://github.com/ExploreEmbedded/ESP32_RMT +#elif defined(IR_TIMER_USE_ESP32) +#define TIMER_RESET 1 +#define TIMER_ENABLE_PWM 1 +#define TIMER_DISABLE_PWM Serial.println("IRsend not implemented for ESP32 yet"); +#define TIMER_ENABLE_INTR 1 +#define TIMER_DISABLE_INTR 1 +#define TIMER_INTR_NAME 1 + //--------------------------------------------------------- // Unknown Timer // diff --git a/examples/IRrecvDemo/IRrecvDemo.ino b/examples/IRrecvDemo/IRrecvDemo.ino index 4635b2c79..3e2d280eb 100644 --- a/examples/IRrecvDemo/IRrecvDemo.ino +++ b/examples/IRrecvDemo/IRrecvDemo.ino @@ -8,11 +8,7 @@ #include -#ifdef ESP32 -int RECV_PIN = 35; -#else int RECV_PIN = 11; -#endif IRrecv irrecv(RECV_PIN); @@ -20,7 +16,9 @@ decode_results results; void setup() { - Serial.begin(115200); + Serial.begin(9600); + // In case the interrupt driver crashes on setup, give a clue + // to the user what's going on. Serial.println("Enabling IRin"); irrecv.enableIRIn(); // Start the receiver Serial.println("Enabled IRin"); diff --git a/examples/IRrecvDump/IRrecvDump.ino b/examples/IRrecvDump/IRrecvDump.ino index 9a21b5698..990c3f60c 100644 --- a/examples/IRrecvDump/IRrecvDump.ino +++ b/examples/IRrecvDump/IRrecvDump.ino @@ -15,11 +15,7 @@ * You can change this to another available Arduino Pin. * Your IR receiver should be connected to the pin defined here */ -#ifdef ESP32 -int RECV_PIN = 35; -#else int RECV_PIN = 11; -#endif IRrecv irrecv(RECV_PIN); diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index 570baba94..725612735 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -6,7 +6,7 @@ //------------------------------------------------------------------------------ // Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838) // -int recvPin = 35; +int recvPin = 11; IRrecv irrecv(recvPin); //+============================================================================= @@ -14,7 +14,7 @@ IRrecv irrecv(recvPin); // void setup ( ) { - Serial.begin(115200); // Status message will be sent to PC at 9600 baud + Serial.begin(9600); // Status message will be sent to PC at 9600 baud irrecv.enableIRIn(); // Start the receiver } diff --git a/irRecv.cpp b/irRecv.cpp index a15ac0f57..6631fb7ef 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -124,6 +124,8 @@ void IRrecv::enableIRIn ( ) { // Interrupt Service Routine - Fires every 50uS #ifdef ESP32 + // ESP32 has a proper API to setup timers, no weird chip macros needed + // simply call the readable API versions :) // 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up timer = timerBegin(1, 80, 1); timerAttachInterrupt(timer, &IRTimer, 1); diff --git a/irSend.cpp b/irSend.cpp index 6191aa6ad..c3ef3ffac 100644 --- a/irSend.cpp +++ b/irSend.cpp @@ -54,7 +54,7 @@ void IRsend::space (unsigned int time) // void IRsend::enableIROut (int khz) { -// FIXME: implement ESP32 support +// FIXME: implement ESP32 support, see IR_TIMER_USE_ESP32 in boarddefs.h #ifndef ESP32 // Disable the Timer2 Interrupt (which is used for receiving IR) TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt From 6b8f2bdbfcca1c8b9db38418312d7a621e6f606b Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Fri, 31 Mar 2017 22:01:31 -0700 Subject: [PATCH 198/768] move comment about 'or else' chips that use TIMER2. --- boarddefs.h | 4 ++-- examples/IRrecvDump/IRrecvDump.ino | 2 +- irRecv.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boarddefs.h b/boarddefs.h index c126b546b..925c92a98 100644 --- a/boarddefs.h +++ b/boarddefs.h @@ -136,11 +136,11 @@ #elif defined(__AVR_ATtiny85__) #define IR_USE_TIMER_TINY0 // tx = pin 1 -// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc -// ATmega48, ATmega88, ATmega168, ATmega328 #elif defined(ESP32) #define IR_TIMER_USE_ESP32 #else +// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc +// ATmega48, ATmega88, ATmega168, ATmega328 //#define IR_USE_TIMER1 // tx = pin 9 #define IR_USE_TIMER2 // tx = pin 3 diff --git a/examples/IRrecvDump/IRrecvDump.ino b/examples/IRrecvDump/IRrecvDump.ino index 990c3f60c..fa25cd8ea 100644 --- a/examples/IRrecvDump/IRrecvDump.ino +++ b/examples/IRrecvDump/IRrecvDump.ino @@ -23,7 +23,7 @@ decode_results results; void setup() { - Serial.begin(115200); + Serial.begin(9600); irrecv.enableIRIn(); // Start the receiver } diff --git a/irRecv.cpp b/irRecv.cpp index 6631fb7ef..12b0806b1 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -1,7 +1,7 @@ #include "IRremote.h" #include "IRremoteInt.h" -#ifdef ESP32 +#ifdef IR_TIMER_USE_ESP32 hw_timer_t *timer; void IRTimer(); // defined in IRremote.cpp #endif From 88b294a0cd898c20ab7026f55f612eab718370c1 Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Fri, 31 Mar 2017 22:32:48 -0700 Subject: [PATCH 199/768] change no-op defines from '1' to ''. --- boarddefs.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/boarddefs.h b/boarddefs.h index 925c92a98..17e25513e 100644 --- a/boarddefs.h +++ b/boarddefs.h @@ -560,12 +560,12 @@ // way to do this on ESP32 is using the RMT built in driver like in this incomplete library below // https://github.com/ExploreEmbedded/ESP32_RMT #elif defined(IR_TIMER_USE_ESP32) -#define TIMER_RESET 1 -#define TIMER_ENABLE_PWM 1 +#define TIMER_RESET +#define TIMER_ENABLE_PWM #define TIMER_DISABLE_PWM Serial.println("IRsend not implemented for ESP32 yet"); -#define TIMER_ENABLE_INTR 1 -#define TIMER_DISABLE_INTR 1 -#define TIMER_INTR_NAME 1 +#define TIMER_ENABLE_INTR +#define TIMER_DISABLE_INTR +#define TIMER_INTR_NAME //--------------------------------------------------------- // Unknown Timer From 9133814e60e905f2495e850a96c3fe768238d5aa Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Fri, 31 Mar 2017 23:10:07 -0700 Subject: [PATCH 200/768] Rev'ed to 2.2.4. --- Contributors.md | 1 + README.md | 1 + changelog.md | 3 +++ library.json | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Contributors.md b/Contributors.md index ae2489008..bf1e64dbd 100644 --- a/Contributors.md +++ b/Contributors.md @@ -18,5 +18,6 @@ These are the active contributors of this project that you may contact if there - [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor - [philipphenkel](https://github.com/philipphenkel): Active Contributor - [MCUdude](https://github.com/MCUdude): Contributor +- [marcmerlin](https://github.com/marcmerlin): Contributor (ESP32 port) Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. diff --git a/README.md b/README.md index 2ec302c58..8ecf11288 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Tutorials and more information will be made available on [the official homepage] - ATmega8535, 16, 32, 164, 324, 644, 1284, - ATmega64, 128 - ATtiny 84 / 85 +- ESP32 (receive only) We are open to suggestions for adding support to new boards, however we highly recommend you contact your supplier first and ask them to provide support from their side. diff --git a/changelog.md b/changelog.md index 0702ddcf9..dc01c9857 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +## 2.2.4 - 2017/03/31 +- Added ESP32 IR receive support [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/425) + ## 2.2.3 - 2017/03/27 - Fix calculation of pause length in LEGO PF protocol [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/427) diff --git a/library.json b/library.json index de93d16e5..4f29e7b53 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/z3t0/Arduino-IRremote.git" }, - "version": "2.2.3", + "version": "2.2.4", "frameworks": "arduino", "platforms": "atmelavr", "authors" : From 419c948c29ae8f6813071459b4940a20b747e8a0 Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Sat, 1 Apr 2017 08:32:37 -0700 Subject: [PATCH 201/768] Fixed rev to 2.3.3 and added info on timer used. --- README.md | 1 + changelog.md | 2 +- library.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8ecf11288..305c7bd9c 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ We are open to suggestions for adding support to new boards, however we highly r | [ATmega8535 ATmega16, ATmega32](https://github.com/MCUdude/MightyCore) | **13** | **1** | | [ATmega64, ATmega128](https://github.com/MCUdude/MegaCore) | **13** | **1** | | ATmega1280, ATmega2560 | 5, 6, **9**, 11, 46 | 1, **2**, 3, 4, 5 | +| [ESP32](http://esp32.net/) | N/A (not supported) | **1** | | [Teensy 1.0](https://www.pjrc.com/teensy/) | **17** | **1** | | [Teensy 2.0](https://www.pjrc.com/teensy/) | 9, **10**, 14 | 1, 3, **4_HS** | | [Teensy++ 1.0 / 2.0](https://www.pjrc.com/teensy/) | **1**, 16, 25 | 1, **2**, 3 | diff --git a/changelog.md b/changelog.md index dc01c9857..81339f2e6 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,4 @@ -## 2.2.4 - 2017/03/31 +## 2.3.3 - 2017/03/31 - Added ESP32 IR receive support [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/425) ## 2.2.3 - 2017/03/27 diff --git a/library.json b/library.json index 4f29e7b53..d8cd523a7 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/z3t0/Arduino-IRremote.git" }, - "version": "2.2.4", + "version": "2.3.3", "frameworks": "arduino", "platforms": "atmelavr", "authors" : From 691ea5bc536e91bbb9926234bc907ca4c38b3250 Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Sun, 9 Apr 2017 19:55:49 -0700 Subject: [PATCH 202/768] Added pointer for ESP8266 fork As requested in https://github.com/z3t0/Arduino-IRremote/issues/400 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 305c7bd9c..f2c7b92c9 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Tutorials and more information will be made available on [the official homepage] - ATmega64, 128 - ATtiny 84 / 85 - ESP32 (receive only) +- ESP8266 is supported in a fork based on an old codebase that isn't as recent, but it works reasonably well given that perfectly timed sub millisecond interrupts are different on that chip. See https://github.com/markszabo/IRremoteESP8266 We are open to suggestions for adding support to new boards, however we highly recommend you contact your supplier first and ask them to provide support from their side. From 18f12d3affb3491abbfe708d4859df12a6f84d5f Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Sat, 22 Apr 2017 19:44:19 -0700 Subject: [PATCH 203/768] Add FAQ on mixing IR and neopixels (#451) * Add FAQ on mixing IR and neopixels As requested in https://github.com/z3t0/Arduino-IRremote/issues/435 * Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index f2c7b92c9..c14b11bc4 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,12 @@ Tutorials and more information will be made available on [the official homepage] 4. Move the "IRremote" folder that has been extracted to your libraries directory. 5. Make sure to delete Arduino_Root/libraries/RobotIRremote. Where Arduino_Root refers to the install directory of Arduino. The library RobotIRremote has similar definitions to IRremote and causes errors. + +## FAQ +- IR does not work right when I use Neopixels (aka WS2811/WS2812/WS2812B) +Whether you use the Adafruit Neopixel lib, or FastLED, interrupts get disabled on many lower end CPUs like the basic arduinos. In turn, this stops the IR interrupt handler from running when it needs to. There are some solutions to this on some processors, [see this page from Marc MERLIN](http://marc.merlins.org/perso/arduino/post_2017-04-03_Arduino-328P-Uno-Teensy3_1-ESP8266-ESP32-IR-and-Neopixels.html) + + ## Supported Boards - Arduino Uno / Mega / Leonardo / Duemilanove / Diecimila / LilyPad / Mini / Fio / Nano etc. - Teensy 1.0 / 1.0++ / 2.0 / 2++ / 3.0 / 3.1 / Teensy-LC; Credits: @PaulStoffregen (Teensy Team) From 0913c94bdf75983b2a2e0ef1a711e1d56f5a41ae Mon Sep 17 00:00:00 2001 From: Bengt Martensson Date: Sun, 23 Apr 2017 13:12:34 +0200 Subject: [PATCH 204/768] New file MicroGirs.ino. --- examples/MicroGirs/MicroGirs.ino | 312 +++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 examples/MicroGirs/MicroGirs.ino diff --git a/examples/MicroGirs/MicroGirs.ino b/examples/MicroGirs/MicroGirs.ino new file mode 100644 index 000000000..c816bcab6 --- /dev/null +++ b/examples/MicroGirs/MicroGirs.ino @@ -0,0 +1,312 @@ +/* +This is a minimalistic Girs server (http://harctoolbox.org/Girs.html). +It only depends on (a subset of) IRremote +(https://github.com/z3t0/Arduino-IRremote), It can be used with +IrScrutinizer (Sending/Capturing hw = Girs Client) and Lirc 0.9.4 and +later (driver girs http://lirc.org/html/girs.html). (Authors of +similar software are encourage to implement support.) + +It consists of an interacive IR server, taking one-line commands from +the "user" (which is typically not a person but another program), and +responds with a one-line response. In the language of the Girs +specifications, the modules "base", receive, and transmit are +implemented. (The two latter can be disabled by not defining two +corresponding CPP symbols.) + +It understands the following commands: + +* The "version" command returns the program name and version, +* The "modules" command returns the modules implemented, normally base, receive and transmit. +* The "receve" command reads an IR signal using the deployed sensor. +* The "send" commands transmits a supplied raw signal the requested number of times. + +Only the first character of the command is evaluated in this implementation. + +The "receive" command returns the received IR sequence as a sequence +of durations, including a (dummy) trailing silence. On-periods +("marks", "flashes") are prefixed by "+", while off-periods ("spaces", +"gaps") are prefixed by "-". The present version never times out. + +The "send" command takes the following parameters: + + send noSends frequencyHz introLength repeatLength endingLength durations... + + where + +* frequencyHz denotes the modulation frequency in Hz + (NOT khz, as is commonly used in IRremote) +* introLength denotes the length of the intro sequence, must be even, +* repeatLength denotes the length of the repeat sequence, must be even, +* endingLength denotes the length of the ending sequence (normally 0), must be even. +* duration... denotes the microsecond durations to send, + starting with the first on-period, ending with a (possibly dummy) trailing silence + +Semantics: first the intro sequence will be sent once (i.e., the first +repeatLength durations) (if non-empty). Then the repeat sequence will +be sent (noSends-1) times, unless the intro sequence was empty, in +which case it will be send noSends times. Finally, the ending +sequence will be send once (if non-empty). + +Weaknesses of the IRremote implementation: +* Reception never times out. +* The IRrecv class does its own decoding which is irrelevant for us. It cannot be disabled. +* The timeout at the end on a signal reception is not configurable. + For example, a NEC1 type signal will cut after the intro sequence, + and the repeats will be considered independent signals. +* IR reception cannot be turned of. +* The size of the data is platform dependent (unsigned int). +*/ + +#include +#include + +// Define the ones that should be enabled +#define RECEIVE +#define TRANSMIT + +// Change the following if desired + +// Pin used by the receiver +#define INPUTPIN 11 + +// (The sending pin is in general not configurable, see the documentation of IRremote.) + +// Character that ends the command lines. Do not change unless you known what +// you are doing. IrScrutinizer and Lirc expects \r. +#define EOLCHAR '\r' + +// Baud rate for the serial/USB connection. +// 115200 is the default for IrScrutinizer and Lirc. +#define BAUDRATE 115200 + +////// End of user configurable variables //////////////////// + +#define modulesSupported "base transmit receive" +#ifndef PROGNAME +#define PROGNAME "MicroGirs" +#endif +#ifndef VERSION +#define VERSION "2017-04-23" +#endif +#define okString "OK" +#define errorString "ERROR" +#define timeoutString "." + +// For compatibility with IRremote, we deliberately use +// the platform dependent types. +typedef unsigned frequency_t; +typedef unsigned microseconds_t; + +static const microseconds_t DUMMYENDING = 40000U; +static const frequency_t FREQUENCY_T_MAX = UINT16_MAX; +static const frequency_t MICROSECONDS_T_MAX = UINT16_MAX; + +#ifdef RECEIVE +IRrecv irRecv(INPUTPIN); +#endif +#ifdef TRANSMIT +IRsend irSend; +#endif + +///////// Tokenizer class. Breaks the command line into tokens. ////// +class Tokenizer { +private: + static const int invalidIndex = -1; + + int index; // signed since invalidIndex is possible + const String& payload; + void trim(); + +public: + Tokenizer(const String &str); + virtual ~Tokenizer(); + + String getToken(); + String getRest(); + String getLine(); + long getInt(); + microseconds_t getMicroseconds(); + frequency_t getFrequency(); + + static const int invalid = INT_MAX; +}; + +Tokenizer::Tokenizer(const String& str) : index(0), payload(str) { +} + +Tokenizer::~Tokenizer() { +} + +String Tokenizer::getRest() { + String result = index == invalidIndex ? String("") : payload.substring(index); + index = invalidIndex; + return result; +} + +String Tokenizer::getLine() { + if (index == invalidIndex) + return String(""); + + int i = payload.indexOf('\n', index); + String s = (i > 0) ? payload.substring(index, i) : payload.substring(index); + index = (i > 0) ? i+1 : invalidIndex; + return s; +} + +String Tokenizer::getToken() { + if (index < 0) + return String(""); + + int i = payload.indexOf(' ', index); + String s = (i > 0) ? payload.substring(index, i) : payload.substring(index); + index = (i > 0) ? i : invalidIndex; + if (index != invalidIndex) + if (index != invalidIndex) + while (payload.charAt(index) == ' ') + index++; + return s; +} + +long Tokenizer::getInt() { + String token = getToken(); + return token == "" ? (long) invalid : token.toInt(); +} + +microseconds_t Tokenizer::getMicroseconds() { + long t = getToken().toInt(); + return (microseconds_t) ((t < MICROSECONDS_T_MAX) ? t : MICROSECONDS_T_MAX); +} + +frequency_t Tokenizer::getFrequency() { + long t = getToken().toInt(); + return (frequency_t) ((t < FREQUENCY_T_MAX) ? t : FREQUENCY_T_MAX); +} +///////////////// end Tokenizer ///////////////////////////////// + +#ifdef TRANSMIT +static inline unsigned hz2khz(frequency_t hz) { + return (hz + 500)/1000; +} + +static void sendRaw(const microseconds_t intro[], unsigned lengthIntro, + const microseconds_t repeat[], unsigned lengthRepeat, + const microseconds_t ending[], unsigned lengthEnding, + frequency_t frequency, unsigned times) { + if (lengthIntro > 0U) + irSend.sendRaw(intro, lengthIntro, hz2khz(frequency)); + if (lengthRepeat > 0U) + for (unsigned i = 0U; i < times - (lengthIntro > 0U); i++) + irSend.sendRaw(repeat, lengthRepeat, hz2khz(frequency)); + if (lengthEnding > 0U) + irSend.sendRaw(ending, lengthEnding, hz2khz(frequency)); +} +#endif // TRANSMIT + +#ifdef RECEIVE +static void receive(Stream& stream) { + irRecv.resume(); // Receive the next value + + decode_results results; + while (!irRecv.decode(&results)) { + } + + dump(stream, &results); +} + +static void dump(Stream& stream, decode_results* results) { + unsigned int count = results->rawlen; + for (unsigned int i = 1; i < count; i++) { + stream.write(i & 1 ? '+' : '-'); + stream.print(results->rawbuf[i] * USECPERTICK, DEC); + stream.print(" "); + } + stream.print('-'); + stream.println(DUMMYENDING); +} +#endif // RECEIVE + +void setup() { + Serial.begin(BAUDRATE); + while (!Serial) + ; // wait for serial port to connect. "Needed for Leonardo only" + + Serial.println(F(PROGNAME " " VERSION)); + //Serial.setTimeout(SERIALTIMEOUT); +#ifdef RECEIVE + // There is unfortunately no disableIRIn in IRremote. + // Therefore, turn it on, and leave it on. + // We _hope_ that it will not interfere with sending. + irRecv.enableIRIn(); +#endif +} + + +static String readCommand(Stream& stream) { + while (stream.available() == 0) { + } + + String line = stream.readStringUntil(EOLCHAR); + line.trim(); + return line; +} + +static void processCommand(const String& line, Stream& stream) { + Tokenizer tokenizer(line); + String cmd = tokenizer.getToken(); + + // Decode the command in cmd + if (cmd.length() == 0) { + // empty command, do nothing + stream.println(F(okString)); + return; + } + + switch (cmd[0]) { + case 'm': + stream.println(F(modulesSupported)); + break; + +#ifdef RECEIVE + case 'r': // receive + case 'a': + case 'c': + receive(stream); + break; +#endif // RECEIVE + +#ifdef TRANSMIT + case 's': // send + { + // TODO: handle unparsable data gracefully + unsigned noSends = (unsigned) tokenizer.getInt(); + frequency_t frequency = tokenizer.getFrequency(); + unsigned introLength = (unsigned) tokenizer.getInt(); + unsigned repeatLength = (unsigned) tokenizer.getInt(); + unsigned endingLength = (unsigned) tokenizer.getInt(); + microseconds_t intro[introLength]; + microseconds_t repeat[repeatLength]; + microseconds_t ending[endingLength]; + for (unsigned i = 0; i < introLength; i++) + intro[i] = tokenizer.getMicroseconds(); + for (unsigned i = 0; i < repeatLength; i++) + repeat[i] = tokenizer.getMicroseconds(); + for (unsigned i = 0; i < endingLength; i++) + ending[i] = tokenizer.getMicroseconds(); + sendRaw(intro, introLength, repeat, repeatLength, ending, endingLength, frequency, noSends); + stream.println(F(okString)); + } + break; +#endif // TRANSMIT + + case 'v': // version + stream.println(F(PROGNAME " " VERSION)); + break; + default: + stream.println(F(errorString)); + } +} + +void loop() { + String line = readCommand(Serial); + processCommand(line, Serial); +} From eb7a0bee7d3e3b5d8927dfc47138bb85bf486eb1 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sat, 1 Jul 2017 21:53:37 -0700 Subject: [PATCH 205/768] #481 note (#484) --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index c14b11bc4..00a4b03be 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,12 @@ We are open to suggestions for adding support to new boards, however we highly r | [Teensy 3.0 / 3.1](https://www.pjrc.com/teensy/) | **5** | **CMT** | | [Teensy-LC](https://www.pjrc.com/teensy/) | **16** | **TPM1** | + +### Experimental patches +The following are strictly community supported patches that have yet to make it into mainstream. If you have issues feel free to ask here. If it works well then let us know! + +[Arduino 101](https://github.com/z3t0/Arduino-IRremote/pull/481#issuecomment-311243146) + The table above lists the currently supported timers and corresponding send pins, many of these can have additional pins opened up and we are open to requests if a need arises for other pins. ## Usage From 47aadf559d359d7e270eb4b5451ee68cd6d1d464 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 24 Jul 2017 14:51:03 -0600 Subject: [PATCH 206/768] Update Contributors.md (#488) --- Contributors.md | 1 - 1 file changed, 1 deletion(-) diff --git a/Contributors.md b/Contributors.md index bf1e64dbd..1bed7b6d4 100644 --- a/Contributors.md +++ b/Contributors.md @@ -3,7 +3,6 @@ These are the active contributors of this project that you may contact if there - [z3t0](https://github.com/z3t0) : Active Contributor and currently also the main contributor. * Email: zetoslab@gmail.com - * Skype: polarised16 - [shirriff](https://github.com/shirriff) : An amazing person who worked to create this awesome library and provide unending support - [AnalysIR](https:/github.com/AnalysIR): Active contributor and is amazing with providing support! - [Informatic](https://github.com/Informatic) : Active contributor From 679348568da2b886e7ae50e8bfeed4a2b9c93056 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 10 Aug 2017 16:57:54 -0600 Subject: [PATCH 207/768] merge #437 --- Contributors.md | 2 + IRremote.cpp | 8 +- IRremote.h | 27 ++++- boarddefs.h | 140 +++++++++++++++++++------ esp32.cpp | 39 +++++++ examples/IRremoteInfo/IRremoteInfo.ino | 2 +- irRecv.cpp | 22 +--- irSend.cpp | 61 +++++++++-- sam.cpp | 102 ++++++++++++++++++ 9 files changed, 341 insertions(+), 62 deletions(-) create mode 100644 esp32.cpp create mode 100644 sam.cpp diff --git a/Contributors.md b/Contributors.md index 1bed7b6d4..821c8da45 100644 --- a/Contributors.md +++ b/Contributors.md @@ -18,5 +18,7 @@ These are the active contributors of this project that you may contact if there - [philipphenkel](https://github.com/philipphenkel): Active Contributor - [MCUdude](https://github.com/MCUdude): Contributor - [marcmerlin](https://github.com/marcmerlin): Contributor (ESP32 port) +- [bengtmartensson](https://github.com/bengtmartensson): Active Contributor +- [MrBryonMiller](https://github.com/MrBryonMiller): Contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. diff --git a/IRremote.cpp b/IRremote.cpp index e811cfc7b..f41f81878 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -24,7 +24,7 @@ # include "IRremoteInt.h" #undef IR_GLOBAL -#ifndef IR_TIMER_USE_ESP32 +#ifdef HAS_AVR_INTERRUPT_H #include #endif @@ -123,11 +123,7 @@ int MATCH_SPACE (int measured_ticks, int desired_us) // As soon as first MARK arrives: // Gap width is recorded; Ready is cleared; New logging starts // -#ifdef IR_TIMER_USE_ESP32 -void IRTimer() -#else ISR (TIMER_INTR_NAME) -#endif { TIMER_RESET; @@ -189,6 +185,7 @@ ISR (TIMER_INTR_NAME) break; } +#ifdef BLINKLED // If requested, flash LED while receiving IR data if (irparams.blinkflag) { if (irdata == MARK) @@ -197,4 +194,5 @@ ISR (TIMER_INTR_NAME) else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on else BLINKLED_OFF() ; // if no user defined LED pin, turn default LED pin for the hardware on } +#endif // BLINKLED } diff --git a/IRremote.h b/IRremote.h index fe1a87029..928284361 100644 --- a/IRremote.h +++ b/IRremote.h @@ -259,7 +259,18 @@ class IRrecv class IRsend { public: - IRsend () { } +#ifdef USE_SOFT_CARRIER + + IRsend(int pin = SEND_PIN) + { + sendPin = pin; + } +#else + + IRsend() + { + } +#endif void custom_delay_usec (unsigned long uSecs); void enableIROut (int khz) ; @@ -339,6 +350,20 @@ class IRsend # if SEND_LEGO_PF void sendLegoPowerFunctions (uint16_t data, bool repeat = true) ; # endif + +#ifdef USE_SOFT_CARRIER + private: + int sendPin; + + unsigned int periodTime; + unsigned int periodOnTime; + + void sleepMicros(unsigned long us); + void sleepUntilMicros(unsigned long targetTime); + +#else + const int sendPin = SEND_PIN; +#endif } ; #endif diff --git a/boarddefs.h b/boarddefs.h index 17e25513e..5c49465ef 100644 --- a/boarddefs.h +++ b/boarddefs.h @@ -20,6 +20,32 @@ #ifndef boarddefs_h #define boarddefs_h +// Define some defaults, that some boards may like to override +// (This is to avoid negative logic, ! DONT_... is just awkward.) + +// This board has/needs the avr/interrupt.h +#define HAS_AVR_INTERRUPT_H + +// Define if sending is supported +#define SENDING_SUPPORTED + +// If defined, a standard enableIRIn function will be define. +// Undefine for boards supplying their own. +#define USE_DEFAULT_ENABLE_IR_IN + +// Duty cycle in percent for sent signals. Presently takes effect only with USE_SOFT_CARRIER +#define DUTY_CYCLE 50 + +// If USE_SOFT_CARRIER, this amount (in micro seconds) is subtracted from the +// on-time of the pulses. +#define PULSE_CORRECTION 3 + +// digitalWrite is supposed to be slow. If this is an issue, define faster, +// board-dependent versions of these macros SENDPIN_ON(pin) and SENDPIN_OFF(pin). +// Portable, possibly slow, default definitions are given at the end of this file. +// If defining new versions, feel free to ignore the pin argument if it +// is not configurable on the current board. + //------------------------------------------------------------------------------ // Defines for blinking the LED // @@ -39,11 +65,31 @@ # define BLINKLED_ON() (PORTD |= B00000001) # define BLINKLED_OFF() (PORTD &= B11111110) -// No system LED on ESP32, disable blinking +#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) +# define BLINKLED LED_BUILTIN +# define BLINKLED_ON() (digitalWrite(LED_BUILTIN, HIGH)) +# define BLINKLED_OFF() (digitalWrite(LED_BUILTIN, LOW)) + +# define USE_SOFT_CARRIER + // Define to use spin wait instead of delayMicros() +//# define USE_SPIN_WAIT +# undef USE_DEFAULT_ENABLE_IR_IN + + // The default pin used used for sending. +# define SEND_PIN 9 + #elif defined(ESP32) -# define BLINKLED 255 -# define BLINKLED_ON() 1 -# define BLINKLED_OFF() 1 + // No system LED on ESP32, disable blinking by NOT defining BLINKLED + + // avr/interrupt.h is not present +# undef HAS_AVR_INTERRUPT_H + + // Sending not implemented +# undef SENDING_SUPPORTED# + + // Supply own enbleIRIn +# undef USE_DEFAULT_ENABLE_IR_IN + #else # define BLINKLED 13 # define BLINKLED_ON() (PORTB |= B00100000) @@ -138,6 +184,10 @@ #elif defined(ESP32) #define IR_TIMER_USE_ESP32 + +#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) + #define TIMER_PRESCALER_DIV 64 + #else // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc // ATmega48, ATmega88, ATmega168, ATmega328 @@ -190,17 +240,17 @@ //----------------- #if defined(CORE_OC2B_PIN) -# define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy +# define SEND_PIN CORE_OC2B_PIN // Teensy #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 9 // Arduino Mega +# define SEND_PIN 9 // Arduino Mega #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ || defined(__AVR_ATmega164P__) -# define TIMER_PWM_PIN 14 // MightyCore +# define SEND_PIN 14 // MightyCore #else -# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc +# define SEND_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc #endif // ATmega48, ATmega88, ATmega168, ATmega328 //--------------------------------------------------------- @@ -243,22 +293,22 @@ //----------------- #if defined(CORE_OC1A_PIN) -# define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy +# define SEND_PIN CORE_OC1A_PIN // Teensy #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 11 // Arduino Mega +# define SEND_PIN 11 // Arduino Mega #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) -# define TIMER_PWM_PIN 13 // MegaCore +# define SEND_PIN 13 // MegaCore #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ || defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ || defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) -# define TIMER_PWM_PIN 13 // MightyCore +# define SEND_PIN 13 // MightyCore #elif defined(__AVR_ATtiny84__) -# define TIMER_PWM_PIN 6 +# define SEND_PIN 6 #else -# define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc +# define SEND_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc #endif // ATmega48, ATmega88, ATmega168, ATmega328 //--------------------------------------------------------- @@ -290,11 +340,11 @@ //----------------- #if defined(CORE_OC3A_PIN) -# define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy +# define SEND_PIN CORE_OC3A_PIN // Teensy #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 5 // Arduino Mega +# define SEND_PIN 5 // Arduino Mega #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) -# define TIMER_PWM_PIN 6 // MightyCore +# define SEND_PIN 6 // MightyCore #else # error "Please add OC3A pin number here\n" #endif @@ -338,9 +388,9 @@ //----------------- #if defined(CORE_OC4A_PIN) -# define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy +# define SEND_PIN CORE_OC4A_PIN // Teensy #elif defined(__AVR_ATmega32U4__) -# define TIMER_PWM_PIN 13 // Leonardo +# define SEND_PIN 13 // Leonardo #else # error "Please add OC4A pin number here\n" #endif @@ -374,9 +424,9 @@ //----------------- #if defined(CORE_OC4A_PIN) -# define TIMER_PWM_PIN CORE_OC4A_PIN +# define SEND_PIN CORE_OC4A_PIN #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 6 // Arduino Mega +# define SEND_PIN 6 // Arduino Mega #else # error "Please add OC4A pin number here\n" #endif @@ -410,9 +460,9 @@ //----------------- #if defined(CORE_OC5A_PIN) -# define TIMER_PWM_PIN CORE_OC5A_PIN +# define SEND_PIN CORE_OC5A_PIN #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -# define TIMER_PWM_PIN 46 // Arduino Mega +# define SEND_PIN 46 // Arduino Mega #else # error "Please add OC5A pin number here\n" #endif @@ -479,7 +529,7 @@ CMT_MSC = 0x03; \ }) -#define TIMER_PWM_PIN 5 +#define SEND_PIN 5 // defines for TPM1 timer on Teensy-LC #elif defined(IR_USE_TIMER_TPM1) @@ -509,7 +559,7 @@ FTM1_C0V = 0; \ FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \ }) -#define TIMER_PWM_PIN 16 +#define SEND_PIN 16 // defines for timer_tiny0 (8 bits) #elif defined(IR_USE_TIMER_TINY0) @@ -543,7 +593,7 @@ }) #endif -#define TIMER_PWM_PIN 1 /* ATtiny85 */ +#define SEND_PIN 1 /* ATtiny85 */ //--------------------------------------------------------- // ESP32 (ESP8266 should likely be added here too) @@ -560,12 +610,29 @@ // way to do this on ESP32 is using the RMT built in driver like in this incomplete library below // https://github.com/ExploreEmbedded/ESP32_RMT #elif defined(IR_TIMER_USE_ESP32) -#define TIMER_RESET -#define TIMER_ENABLE_PWM -#define TIMER_DISABLE_PWM Serial.println("IRsend not implemented for ESP32 yet"); -#define TIMER_ENABLE_INTR -#define TIMER_DISABLE_INTR -#define TIMER_INTR_NAME + +#define TIMER_RESET + +#ifdef ISR +# undef ISR +#endif +#define ISR(f) void IRTimer() + +#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) +// use timer 3 hardcoded at this time + +#define TIMER_RESET +#define TIMER_ENABLE_PWM // Not presently used +#define TIMER_DISABLE_PWM +#define TIMER_ENABLE_INTR NVIC_EnableIRQ(TC3_IRQn) // Not presently used +#define TIMER_DISABLE_INTR NVIC_DisableIRQ(TC3_IRQn) +#define TIMER_INTR_NAME TC3_Handler // Not presently used +#define TIMER_CONFIG_KHZ(f) + +#ifdef ISR +# undef ISR +#endif +#define ISR(f) void irs() //--------------------------------------------------------- // Unknown Timer @@ -574,4 +641,13 @@ # error "Internal code configuration error, no known IR_USE_TIMER# defined\n" #endif +// Provide default definitions, portable but possibly slower than necessary. +#ifndef SENDPIN_ON +#define SENDPIN_ON(pin) digitalWrite(pin, HIGH) +#endif + +#ifndef SENDPIN_OFF +#define SENDPIN_OFF(pin) digitalWrite(pin, LOW) +#endif + #endif // ! boarddefs_h diff --git a/esp32.cpp b/esp32.cpp new file mode 100644 index 000000000..ef4d79476 --- /dev/null +++ b/esp32.cpp @@ -0,0 +1,39 @@ +#ifdef ESP32 + +// This file contains functions specific to the ESP32. + +#include "IRremote.h" +#include "IRremoteInt.h" + +// "Idiot check" +#ifdef USE_DEFAULT_ENABLE_IR_IN +#error Must undef USE_DEFAULT_ENABLE_IR_IN +#endif + +hw_timer_t *timer; +void IRTimer(); // defined in IRremote.cpp, masqueraded as ISR(TIMER_INTR_NAME) + +//+============================================================================= +// initialization +// +void IRrecv::enableIRIn ( ) +{ +// Interrupt Service Routine - Fires every 50uS + // ESP32 has a proper API to setup timers, no weird chip macros needed + // simply call the readable API versions :) + // 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up + timer = timerBegin(1, 80, 1); + timerAttachInterrupt(timer, &IRTimer, 1); + // every 50ns, autoreload = true + timerAlarmWrite(timer, 50, true); + timerAlarmEnable(timer); + + // Initialize state machine variables + irparams.rcvstate = STATE_IDLE; + irparams.rawlen = 0; + + // Set pin modes + pinMode(irparams.recvpin, INPUT); +} + +#endif // ESP32 diff --git a/examples/IRremoteInfo/IRremoteInfo.ino b/examples/IRremoteInfo/IRremoteInfo.ino index 2a269d948..c3f329754 100644 --- a/examples/IRremoteInfo/IRremoteInfo.ino +++ b/examples/IRremoteInfo/IRremoteInfo.ino @@ -79,7 +79,7 @@ void dumpTIMER() { void dumpTimerPin() { Serial.print(F("IR Tx Pin: ")); - Serial.println(TIMER_PWM_PIN); + Serial.println(SEND_PIN); } void dumpClock() { diff --git a/irRecv.cpp b/irRecv.cpp index 12b0806b1..b549dac1c 100644 --- a/irRecv.cpp +++ b/irRecv.cpp @@ -1,10 +1,5 @@ #include "IRremote.h" #include "IRremoteInt.h" - -#ifdef IR_TIMER_USE_ESP32 -hw_timer_t *timer; -void IRTimer(); // defined in IRremote.cpp -#endif //+============================================================================= // Decodes the received IR message @@ -120,19 +115,10 @@ IRrecv::IRrecv (int recvpin, int blinkpin) //+============================================================================= // initialization // +#ifdef USE_DEFAULT_ENABLE_IR_IN void IRrecv::enableIRIn ( ) { -// Interrupt Service Routine - Fires every 50uS -#ifdef ESP32 - // ESP32 has a proper API to setup timers, no weird chip macros needed - // simply call the readable API versions :) - // 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up - timer = timerBegin(1, 80, 1); - timerAttachInterrupt(timer, &IRTimer, 1); - // every 50ns, autoreload = true - timerAlarmWrite(timer, 50, true); - timerAlarmEnable(timer); -#else +// Interrupt Service Routine - Fires every 50uS cli(); // Setup pulse clock timer interrupt // Prescale /8 (16M/8 = 0.5 microseconds per tick) @@ -146,7 +132,6 @@ void IRrecv::enableIRIn ( ) TIMER_RESET; sei(); // enable interrupts -#endif // Initialize state machine variables irparams.rcvstate = STATE_IDLE; @@ -155,14 +140,17 @@ void IRrecv::enableIRIn ( ) // Set pin modes pinMode(irparams.recvpin, INPUT); } +#endif // USE_DEFAULT_ENABLE_IR_IN //+============================================================================= // Enable/disable blinking of pin 13 on IR processing // void IRrecv::blink13 (int blinkflag) { +#ifdef BLINKLED irparams.blinkflag = blinkflag; if (blinkflag) pinMode(BLINKLED, OUTPUT) ; +#endif } //+============================================================================= diff --git a/irSend.cpp b/irSend.cpp index c3ef3ffac..a01b5a012 100644 --- a/irSend.cpp +++ b/irSend.cpp @@ -1,6 +1,7 @@ #include "IRremote.h" #include "IRremoteInt.h" +#ifdef SENDING_SUPPORTED //+============================================================================= void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz) { @@ -15,14 +16,59 @@ void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned in space(0); // Always end with the LED off } +#ifdef USE_SOFT_CARRIER +void inline IRsend::sleepMicros(unsigned long us) +{ +#ifdef USE_SPIN_WAIT + sleepUntilMicros(micros() + us); +#else + if (us > 0U) // Is this necessary? (Official docu https://www.arduino.cc/en/Reference/DelayMicroseconds does not tell.) + delayMicroseconds((unsigned int) us); +#endif +} + +void inline IRsend::sleepUntilMicros(unsigned long targetTime) +{ +#ifdef USE_SPIN_WAIT + while (micros() < targetTime) + ; +#else + unsigned long now = micros(); + if (now < targetTime) + sleepMicros(targetTime - now); +#endif +} +#endif // USE_SOFT_CARRIER + //+============================================================================= // Sends an IR mark for the specified number of microseconds. // The mark output is modulated at the PWM frequency. // -void IRsend::mark (unsigned int time) + +void IRsend::mark(unsigned int time) { +#ifdef USE_SOFT_CARRIER + unsigned long start = micros(); + unsigned long stop = start + time; + if (stop + periodTime < start) + // Counter wrap-around, happens very seldomly, but CAN happen. + // Just give up instead of possibly damaging the hardware. + return; + + unsigned long nextPeriodEnding = start; + unsigned long now = micros(); + while (now < stop) { + SENDPIN_ON(sendPin); + sleepMicros(periodOnTime); + SENDPIN_OFF(sendPin); + nextPeriodEnding += periodTime; + sleepUntilMicros(nextPeriodEnding); + now = micros(); + } +#else TIMER_ENABLE_PWM; // Enable pin 3 PWM output if (time > 0) custom_delay_usec(time); +#endif } //+============================================================================= @@ -54,13 +100,16 @@ void IRsend::space (unsigned int time) // void IRsend::enableIROut (int khz) { -// FIXME: implement ESP32 support, see IR_TIMER_USE_ESP32 in boarddefs.h -#ifndef ESP32 +#ifdef USE_SOFT_CARRIER + periodTime = (1000U + khz/2) / khz; // = 1000/khz + 1/2 = round(1000.0/khz) + periodOnTime = periodTime * DUTY_CYCLE / 100U - PULSE_CORRECTION; +#endif + // 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 + pinMode(sendPin, OUTPUT); + SENDPIN_OFF(sendPin); // When not sending, we want it low // COM2A = 00: disconnect OC2A // COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted @@ -68,7 +117,6 @@ void IRsend::enableIROut (int khz) // CS2 = 000: no prescaling // The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A. TIMER_CONFIG_KHZ(khz); -#endif } //+============================================================================= @@ -88,3 +136,4 @@ void IRsend::custom_delay_usec(unsigned long uSecs) { //} } +#endif // SENDING_SUPPORTED \ No newline at end of file diff --git a/sam.cpp b/sam.cpp new file mode 100644 index 000000000..06575891c --- /dev/null +++ b/sam.cpp @@ -0,0 +1,102 @@ +// Support routines for SAM processor boards + +#include "IRremote.h" +#include "IRremoteInt.h" + +#if defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) + +// "Idiot check" +#ifdef USE_DEFAULT_ENABLE_IR_IN +#error Must undef USE_DEFAULT_ENABLE_IR_IN +#endif + +//+============================================================================= +// ATSAMD Timer setup & IRQ functions +// + +// following based on setup from GitHub jdneo/timerInterrupt.ino + +static void setTimerFrequency(int frequencyHz) +{ + int compareValue = (SYSCLOCK / (TIMER_PRESCALER_DIV * frequencyHz)) - 1; + //Serial.println(compareValue); + TcCount16* TC = (TcCount16*) TC3; + // Make sure the count is in a proportional position to where it was + // to prevent any jitter or disconnect when changing the compare value. + TC->COUNT.reg = map(TC->COUNT.reg, 0, TC->CC[0].reg, 0, compareValue); + TC->CC[0].reg = compareValue; + //Serial.print("COUNT.reg "); + //Serial.println(TC->COUNT.reg); + //Serial.print("CC[0].reg "); + //Serial.println(TC->CC[0].reg); + while (TC->STATUS.bit.SYNCBUSY == 1); +} + +static void startTimer() +{ + REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3); + while (GCLK->STATUS.bit.SYNCBUSY == 1); // wait for sync + + TcCount16* TC = (TcCount16*) TC3; + + TC->CTRLA.reg &= ~TC_CTRLA_ENABLE; + while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync + + // Use the 16-bit timer + TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16; + while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync + + // Use match mode so that the timer counter resets when the count matches the compare register + TC->CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ; + while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync + + // Set prescaler to 1024 + //TC->CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1024; + TC->CTRLA.reg |= TC_CTRLA_PRESCALER_DIV64; + while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync + + setTimerFrequency(1000000 / USECPERTICK); + + // Enable the compare interrupt + TC->INTENSET.reg = 0; + TC->INTENSET.bit.MC0 = 1; + + NVIC_EnableIRQ(TC3_IRQn); + + TC->CTRLA.reg |= TC_CTRLA_ENABLE; + while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync +} + +//+============================================================================= +// initialization +// + +void IRrecv::enableIRIn() +{ + // Interrupt Service Routine - Fires every 50uS + //Serial.println("Starting timer"); + startTimer(); + //Serial.println("Started timer"); + + // Initialize state machine variables + irparams.rcvstate = STATE_IDLE; + irparams.rawlen = 0; + + // Set pin modes + pinMode(irparams.recvpin, INPUT); +} + +void irs(); // Defined in IRRemote as ISR(TIMER_INTR_NAME) + +void TC3_Handler(void) +{ + TcCount16* TC = (TcCount16*) TC3; + // If this interrupt is due to the compare register matching the timer count + // we toggle the LED. + if (TC->INTFLAG.bit.MC0 == 1) { + TC->INTFLAG.bit.MC0 = 1; + irs(); + } +} + +#endif // defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) \ No newline at end of file From e1768b4debb03441e93a1f2d5f135111e98fdd97 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Thu, 10 Aug 2017 17:01:44 -0600 Subject: [PATCH 208/768] Added changelog info --- README.md | 2 +- changelog.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 00a4b03be..915b12867 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This library enables you to send and receive using infra-red signals on an Ardui Tutorials and more information will be made available on [the official homepage](http://z3t0.github.io/Arduino-IRremote/). -## Version - 2.2.3 +## Version - 2.4.0b ## Installation 1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. diff --git a/changelog.md b/changelog.md index 81339f2e6..92d647188 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +## 2.4.0 - 2017/08/10 + - Cleanup of hardware dependencies. Merge in SAM support [PR #437](https://github.com/z3t0/Arduino-IRremote/pull/437) + ## 2.3.3 - 2017/03/31 - Added ESP32 IR receive support [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/425) From 622e28bf692a7a49d68f5f63d2185c2bcd20c918 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 13 Aug 2017 11:05:12 -0600 Subject: [PATCH 209/768] Update library.properties --- library.properties | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/library.properties b/library.properties index 39fd814eb..0e23d4cf2 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,8 @@ name=IRremote -version=2.2.3 -author=shirriff -maintainer=shirriff +version=2.4.0 +author=shirriff, z3t0 +maintainer=z3t0 sentence=Send and receive infrared signals with multiple protocols -paragraph=Send and receive infrared signals with multiple protocols -category=Signal Input/Output -url=https://github.com/shirriff/Arduino-IRremote.git +category=Communication +url=https://github.com/z3t0/Arduino-IRremote architectures=* From b0d15b6020c5321a1fcb534789b998e6974b7643 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 13 Aug 2017 11:05:50 -0600 Subject: [PATCH 210/768] Modified library.json --- library.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.json b/library.json index d8cd523a7..95407e506 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/z3t0/Arduino-IRremote.git" }, - "version": "2.3.3", + "version": "2.4.0", "frameworks": "arduino", "platforms": "atmelavr", "authors" : From 635e8a923d6367d55cce000cb38f3d6934dc417c Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 13 Aug 2017 11:19:20 -0600 Subject: [PATCH 211/768] Restructuring directory as per #464 --- arduino-irremote.sublime-workspace | 240 ------------------ IRremote.cpp => src/IRremote.cpp | 0 IRremote.h => src/IRremote.h | 0 IRremoteInt.h => src/IRremoteInt.h | 0 boarddefs.h => src/boarddefs.h | 0 esp32.cpp => src/esp32.cpp | 0 irPronto.cpp => src/irPronto.cpp | 0 irRecv.cpp => src/irRecv.cpp | 0 irSend.cpp => src/irSend.cpp | 0 ir_Aiwa.cpp => src/ir_Aiwa.cpp | 0 ir_Denon.cpp => src/ir_Denon.cpp | 0 ir_Dish.cpp => src/ir_Dish.cpp | 0 ir_JVC.cpp => src/ir_JVC.cpp | 0 ir_LG.cpp => src/ir_LG.cpp | 0 ir_Lego_PF.cpp => src/ir_Lego_PF.cpp | 0 .../ir_Lego_PF_BitStreamEncoder.h | 0 ir_Mitsubishi.cpp => src/ir_Mitsubishi.cpp | 0 ir_NEC.cpp => src/ir_NEC.cpp | 0 ir_Panasonic.cpp => src/ir_Panasonic.cpp | 0 ir_RC5_RC6.cpp => src/ir_RC5_RC6.cpp | 0 ir_Samsung.cpp => src/ir_Samsung.cpp | 0 ir_Sanyo.cpp => src/ir_Sanyo.cpp | 0 ir_Sharp.cpp => src/ir_Sharp.cpp | 0 ir_Sony.cpp => src/ir_Sony.cpp | 0 ir_Template.cpp => src/ir_Template.cpp | 0 ir_Whynter.cpp => src/ir_Whynter.cpp | 0 sam.cpp => src/sam.cpp | 0 27 files changed, 240 deletions(-) delete mode 100644 arduino-irremote.sublime-workspace rename IRremote.cpp => src/IRremote.cpp (100%) rename IRremote.h => src/IRremote.h (100%) rename IRremoteInt.h => src/IRremoteInt.h (100%) rename boarddefs.h => src/boarddefs.h (100%) rename esp32.cpp => src/esp32.cpp (100%) rename irPronto.cpp => src/irPronto.cpp (100%) rename irRecv.cpp => src/irRecv.cpp (100%) rename irSend.cpp => src/irSend.cpp (100%) rename ir_Aiwa.cpp => src/ir_Aiwa.cpp (100%) rename ir_Denon.cpp => src/ir_Denon.cpp (100%) rename ir_Dish.cpp => src/ir_Dish.cpp (100%) rename ir_JVC.cpp => src/ir_JVC.cpp (100%) rename ir_LG.cpp => src/ir_LG.cpp (100%) rename ir_Lego_PF.cpp => src/ir_Lego_PF.cpp (100%) rename ir_Lego_PF_BitStreamEncoder.h => src/ir_Lego_PF_BitStreamEncoder.h (100%) rename ir_Mitsubishi.cpp => src/ir_Mitsubishi.cpp (100%) rename ir_NEC.cpp => src/ir_NEC.cpp (100%) rename ir_Panasonic.cpp => src/ir_Panasonic.cpp (100%) rename ir_RC5_RC6.cpp => src/ir_RC5_RC6.cpp (100%) rename ir_Samsung.cpp => src/ir_Samsung.cpp (100%) rename ir_Sanyo.cpp => src/ir_Sanyo.cpp (100%) rename ir_Sharp.cpp => src/ir_Sharp.cpp (100%) rename ir_Sony.cpp => src/ir_Sony.cpp (100%) rename ir_Template.cpp => src/ir_Template.cpp (100%) rename ir_Whynter.cpp => src/ir_Whynter.cpp (100%) rename sam.cpp => src/sam.cpp (100%) diff --git a/arduino-irremote.sublime-workspace b/arduino-irremote.sublime-workspace deleted file mode 100644 index f536803d0..000000000 --- a/arduino-irremote.sublime-workspace +++ /dev/null @@ -1,240 +0,0 @@ -{ - "auto_complete": - { - "selected_items": - [ - [ - "vb", - "vboMatrix" - ] - ] - }, - "buffers": - [ - ], - "build_system": "", - "build_system_choices": - [ - ], - "build_varint": "", - "command_palette": - { - "height": 275.0, - "last_filter": "blame", - "selected_items": - [ - [ - "blame", - "Git: Blame" - ], - [ - "install", - "Package Control: Install Package" - ], - [ - "diff", - "Git: Diff Current File" - ], - [ - "js", - "Set Syntax: JavaScript" - ], - [ - "i", - "Package Control: Install Package" - ], - [ - "instal", - "Package Control: Install Package" - ] - ], - "width": 510.0 - }, - "console": - { - "height": 126.0, - "history": - [ - "import urllib.request,os,hashlib; h = '2915d1851351e5ee549c20394736b442' + '8bc59f460fa1548d1514676163dafc88'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)" - ] - }, - "distraction_free": - { - "menu_visible": true, - "show_minimap": false, - "show_open_files": false, - "show_tabs": false, - "side_bar_visible": false, - "status_bar_visible": false - }, - "expanded_folders": - [ - "/C/Users/Rafi Khan/Documents/Arduino/libraries/Arduino-IRremote" - ], - "file_history": - [ - "/C/Users/Rafi Khan/Documents/Arduino/libraries/Arduino-IRremote/changelog.md", - "/C/Users/Rafi Khan/Documents/Development/Arduino-IRremote/arduino-irremote.sublime-project", - "/C/Users/Rafi Khan/Documents/Development/Arduino-IRremote/.gitignore", - "/C/Users/Rafi Khan/Documents/Development/magic/README.md", - "/C/Users/Rafi Khan/Documents/Development/magic/shader.frag", - "/C/Users/Rafi Khan/Documents/Development/magic/package.json", - "/C/Users/Rafi Khan/Documents/Development/magic/block.js", - "/C/Users/Rafi Khan/Documents/Development/magic/chunker.js", - "/C/Users/Rafi Khan/Documents/Development/magic/index.js", - "/C/Users/Rafi Khan/Documents/Development/magic/blocks", - "/C/Users/Rafi Khan/AppData/Roaming/Sublime Text 3/Packages/User/Preferences.sublime-settings", - "/C/Users/Rafi Khan/Documents/Development/magic/shader.vert", - "/C/Users/Rafi Khan/Documents/Development/magic/magic.sublime-project", - "/C/Users/Rafi Khan/Documents/Development/magic/node_modules/browserify/node_modules/syntax-error/node_modules/acorn/.tern-project", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/supermarket.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/takingavacation.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/TipCalculator.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/battleship.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/exam.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/pyglatin.py", - "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/student.py" - ], - "find": - { - "height": 28.0 - }, - "find_in_files": - { - "height": 0.0, - "where_history": - [ - ] - }, - "find_state": - { - "case_sensitive": false, - "find_history": - [ - "i", - "Direction", - ";", - ";\n", - "north", - "cubeMatrix", - ")\n", - "vec3.set", - "f", - ";", - "();\n", - "render", - "this", - "y" - ], - "highlight": true, - "in_selection": false, - "preserve_case": false, - "regex": false, - "replace_history": - [ - ], - "reverse": false, - "show_context": true, - "use_buffer2": true, - "whole_word": false, - "wrap": true - }, - "groups": - [ - { - "sheets": - [ - ] - } - ], - "incremental_find": - { - "height": 28.0 - }, - "input": - { - "height": 66.0 - }, - "layout": - { - "cells": - [ - [ - 0, - 0, - 1, - 1 - ] - ], - "cols": - [ - 0.0, - 1.0 - ], - "rows": - [ - 0.0, - 1.0 - ] - }, - "menu_visible": true, - "output.find_results": - { - "height": 0.0 - }, - "pinned_build_system": "", - "project": "arduino-irremote.sublime-project", - "replace": - { - "height": 52.0 - }, - "save_all_on_build": true, - "select_file": - { - "height": 0.0, - "last_filter": "", - "selected_items": - [ - [ - "json", - "package.json" - ], - [ - "inde", - "index.js" - ] - ], - "width": 0.0 - }, - "select_project": - { - "height": 0.0, - "last_filter": "", - "selected_items": - [ - ], - "width": 0.0 - }, - "select_symbol": - { - "height": 0.0, - "last_filter": "", - "selected_items": - [ - ], - "width": 0.0 - }, - "selected_group": 0, - "settings": - { - }, - "show_minimap": true, - "show_open_files": false, - "show_tabs": true, - "side_bar_visible": true, - "side_bar_width": 150.0, - "status_bar_visible": true, - "template_settings": - { - } -} diff --git a/IRremote.cpp b/src/IRremote.cpp similarity index 100% rename from IRremote.cpp rename to src/IRremote.cpp diff --git a/IRremote.h b/src/IRremote.h similarity index 100% rename from IRremote.h rename to src/IRremote.h diff --git a/IRremoteInt.h b/src/IRremoteInt.h similarity index 100% rename from IRremoteInt.h rename to src/IRremoteInt.h diff --git a/boarddefs.h b/src/boarddefs.h similarity index 100% rename from boarddefs.h rename to src/boarddefs.h diff --git a/esp32.cpp b/src/esp32.cpp similarity index 100% rename from esp32.cpp rename to src/esp32.cpp diff --git a/irPronto.cpp b/src/irPronto.cpp similarity index 100% rename from irPronto.cpp rename to src/irPronto.cpp diff --git a/irRecv.cpp b/src/irRecv.cpp similarity index 100% rename from irRecv.cpp rename to src/irRecv.cpp diff --git a/irSend.cpp b/src/irSend.cpp similarity index 100% rename from irSend.cpp rename to src/irSend.cpp diff --git a/ir_Aiwa.cpp b/src/ir_Aiwa.cpp similarity index 100% rename from ir_Aiwa.cpp rename to src/ir_Aiwa.cpp diff --git a/ir_Denon.cpp b/src/ir_Denon.cpp similarity index 100% rename from ir_Denon.cpp rename to src/ir_Denon.cpp diff --git a/ir_Dish.cpp b/src/ir_Dish.cpp similarity index 100% rename from ir_Dish.cpp rename to src/ir_Dish.cpp diff --git a/ir_JVC.cpp b/src/ir_JVC.cpp similarity index 100% rename from ir_JVC.cpp rename to src/ir_JVC.cpp diff --git a/ir_LG.cpp b/src/ir_LG.cpp similarity index 100% rename from ir_LG.cpp rename to src/ir_LG.cpp diff --git a/ir_Lego_PF.cpp b/src/ir_Lego_PF.cpp similarity index 100% rename from ir_Lego_PF.cpp rename to src/ir_Lego_PF.cpp diff --git a/ir_Lego_PF_BitStreamEncoder.h b/src/ir_Lego_PF_BitStreamEncoder.h similarity index 100% rename from ir_Lego_PF_BitStreamEncoder.h rename to src/ir_Lego_PF_BitStreamEncoder.h diff --git a/ir_Mitsubishi.cpp b/src/ir_Mitsubishi.cpp similarity index 100% rename from ir_Mitsubishi.cpp rename to src/ir_Mitsubishi.cpp diff --git a/ir_NEC.cpp b/src/ir_NEC.cpp similarity index 100% rename from ir_NEC.cpp rename to src/ir_NEC.cpp diff --git a/ir_Panasonic.cpp b/src/ir_Panasonic.cpp similarity index 100% rename from ir_Panasonic.cpp rename to src/ir_Panasonic.cpp diff --git a/ir_RC5_RC6.cpp b/src/ir_RC5_RC6.cpp similarity index 100% rename from ir_RC5_RC6.cpp rename to src/ir_RC5_RC6.cpp diff --git a/ir_Samsung.cpp b/src/ir_Samsung.cpp similarity index 100% rename from ir_Samsung.cpp rename to src/ir_Samsung.cpp diff --git a/ir_Sanyo.cpp b/src/ir_Sanyo.cpp similarity index 100% rename from ir_Sanyo.cpp rename to src/ir_Sanyo.cpp diff --git a/ir_Sharp.cpp b/src/ir_Sharp.cpp similarity index 100% rename from ir_Sharp.cpp rename to src/ir_Sharp.cpp diff --git a/ir_Sony.cpp b/src/ir_Sony.cpp similarity index 100% rename from ir_Sony.cpp rename to src/ir_Sony.cpp diff --git a/ir_Template.cpp b/src/ir_Template.cpp similarity index 100% rename from ir_Template.cpp rename to src/ir_Template.cpp diff --git a/ir_Whynter.cpp b/src/ir_Whynter.cpp similarity index 100% rename from ir_Whynter.cpp rename to src/ir_Whynter.cpp diff --git a/sam.cpp b/src/sam.cpp similarity index 100% rename from sam.cpp rename to src/sam.cpp From 31968a4875af21736dda61b4c3c734ebfa6c13f4 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 13 Aug 2017 11:29:12 -0600 Subject: [PATCH 212/768] Removed redundant preprocessor directives In the newer versions of the IDE it is sufficient to simply include the Arduino.h header file. Fixes #463 --- src/IRremoteInt.h | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/IRremoteInt.h b/src/IRremoteInt.h index 1c319acbf..1baa05d6d 100644 --- a/src/IRremoteInt.h +++ b/src/IRremoteInt.h @@ -18,15 +18,9 @@ #define IRremoteint_h //------------------------------------------------------------------------------ -// Include the right Arduino header +// Include the Arduino header // -#if defined(ARDUINO) && (ARDUINO >= 100) -# include -#else -# if !defined(IRPRONTO) -# include -# endif -#endif +#include //------------------------------------------------------------------------------ // This handles definition and access to global variables From a406f3b9f97864c23cc7fb76f5deb04f5e09c9f8 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 13 Aug 2017 11:42:39 -0600 Subject: [PATCH 213/768] Removed blinking led It is difficult to maintain this over different architectures and also not entirely that useful. Fixes #462 --- keywords.txt | 1 - src/IRremote.cpp | 11 ----------- src/IRremote.h | 3 +-- src/IRremoteInt.h | 2 -- src/boarddefs.h | 27 +-------------------------- src/irRecv.cpp | 17 +---------------- 6 files changed, 3 insertions(+), 58 deletions(-) diff --git a/keywords.txt b/keywords.txt index f2b9a4957..ea6e0192c 100644 --- a/keywords.txt +++ b/keywords.txt @@ -14,7 +14,6 @@ IRsend KEYWORD1 # Methods and Functions (KEYWORD2) ####################################### -blink13 KEYWORD2 decode KEYWORD2 enableIRIn KEYWORD2 resume KEYWORD2 diff --git a/src/IRremote.cpp b/src/IRremote.cpp index f41f81878..c8730d7b3 100644 --- a/src/IRremote.cpp +++ b/src/IRremote.cpp @@ -127,7 +127,6 @@ ISR (TIMER_INTR_NAME) { TIMER_RESET; - // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on] // digitalRead() is very slow. Optimisation is possible, but makes the code unportable uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); @@ -185,14 +184,4 @@ ISR (TIMER_INTR_NAME) break; } -#ifdef BLINKLED - // If requested, flash LED while receiving IR data - if (irparams.blinkflag) { - if (irdata == MARK) - if (irparams.blinkpin) digitalWrite(irparams.blinkpin, HIGH); // Turn user defined pin LED on - else BLINKLED_ON() ; // if no user defined LED pin, turn default LED pin for the hardware on - else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on - else BLINKLED_OFF() ; // if no user defined LED pin, turn default LED pin for the hardware on - } -#endif // BLINKLED } diff --git a/src/IRremote.h b/src/IRremote.h index 928284361..40f28dc2f 100644 --- a/src/IRremote.h +++ b/src/IRremote.h @@ -172,9 +172,8 @@ class IRrecv { public: IRrecv (int recvpin) ; - IRrecv (int recvpin, int blinkpin); + IRrecv (int recvpin); - void blink13 (int blinkflag) ; int decode (decode_results *results) ; void enableIRIn ( ) ; bool isIdle ( ) ; diff --git a/src/IRremoteInt.h b/src/IRremoteInt.h index 1baa05d6d..08f162e51 100644 --- a/src/IRremoteInt.h +++ b/src/IRremoteInt.h @@ -41,8 +41,6 @@ typedef // The fields are ordered to reduce memory over caused by struct-padding uint8_t rcvstate; // State Machine state uint8_t recvpin; // Pin connected to IR data from detector - uint8_t blinkpin; - uint8_t blinkflag; // true -> enable blinking of pin on IR processing uint8_t rawlen; // counter of entries in rawbuf unsigned int timer; // State timer, counts 50uS ticks. unsigned int rawbuf[RAWBUF]; // raw data diff --git a/src/boarddefs.h b/src/boarddefs.h index 5c49465ef..5751ba700 100644 --- a/src/boarddefs.h +++ b/src/boarddefs.h @@ -47,29 +47,10 @@ // is not configurable on the current board. //------------------------------------------------------------------------------ -// Defines for blinking the LED +// Soft Carrier fallback for SAM and SAMD architectures // -#if defined(CORE_LED0_PIN) -# 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__) || defined(__AVR_ATmega2560__) -# define BLINKLED 13 -# define BLINKLED_ON() (PORTB |= B10000000) -# define BLINKLED_OFF() (PORTB &= B01111111) - -#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) -# define BLINKLED 0 -# define BLINKLED_ON() (PORTD |= B00000001) -# define BLINKLED_OFF() (PORTD &= B11111110) - #elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) -# define BLINKLED LED_BUILTIN -# define BLINKLED_ON() (digitalWrite(LED_BUILTIN, HIGH)) -# define BLINKLED_OFF() (digitalWrite(LED_BUILTIN, LOW)) - # define USE_SOFT_CARRIER // Define to use spin wait instead of delayMicros() //# define USE_SPIN_WAIT @@ -79,8 +60,6 @@ # define SEND_PIN 9 #elif defined(ESP32) - // No system LED on ESP32, disable blinking by NOT defining BLINKLED - // avr/interrupt.h is not present # undef HAS_AVR_INTERRUPT_H @@ -90,10 +69,6 @@ // Supply own enbleIRIn # undef USE_DEFAULT_ENABLE_IR_IN -#else -# define BLINKLED 13 -# define BLINKLED_ON() (PORTB |= B00100000) -# define BLINKLED_OFF() (PORTB &= B11011111) #endif //------------------------------------------------------------------------------ diff --git a/src/irRecv.cpp b/src/irRecv.cpp index b549dac1c..8498e16a4 100644 --- a/src/irRecv.cpp +++ b/src/irRecv.cpp @@ -99,15 +99,11 @@ int IRrecv::decode (decode_results *results) IRrecv::IRrecv (int recvpin) { irparams.recvpin = recvpin; - irparams.blinkflag = 0; } -IRrecv::IRrecv (int recvpin, int blinkpin) +IRrecv::IRrecv (int recvpin) { irparams.recvpin = recvpin; - irparams.blinkpin = blinkpin; - pinMode(blinkpin, OUTPUT); - irparams.blinkflag = 0; } @@ -142,17 +138,6 @@ void IRrecv::enableIRIn ( ) } #endif // USE_DEFAULT_ENABLE_IR_IN -//+============================================================================= -// Enable/disable blinking of pin 13 on IR processing -// -void IRrecv::blink13 (int blinkflag) -{ -#ifdef BLINKLED - irparams.blinkflag = blinkflag; - if (blinkflag) pinMode(BLINKLED, OUTPUT) ; -#endif -} - //+============================================================================= // Return if receiving new IR signals // From 563c82c6c4fbce090590fd0c30f7c8301a4b2652 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 13 Aug 2017 11:46:58 -0600 Subject: [PATCH 214/768] Removed pronto "protocol" Fixes #466 --- examples/IRremoteInfo/IRremoteInfo.ino | 1 - src/IRremote.h | 23 -- src/irPronto.cpp | 513 ------------------------- 3 files changed, 537 deletions(-) delete mode 100644 src/irPronto.cpp diff --git a/examples/IRremoteInfo/IRremoteInfo.ino b/examples/IRremoteInfo/IRremoteInfo.ino index c3f329754..45cf7236e 100644 --- a/examples/IRremoteInfo/IRremoteInfo.ino +++ b/examples/IRremoteInfo/IRremoteInfo.ino @@ -188,7 +188,6 @@ void dumpProtocols() { Serial.print(F("DISH: ")); printSendEnabled(SEND_DISH); printDecodeEnabled(DECODE_DISH); Serial.print(F("SHARP: ")); printSendEnabled(SEND_SHARP); printDecodeEnabled(DECODE_SHARP); Serial.print(F("DENON: ")); printSendEnabled(SEND_DENON); printDecodeEnabled(DECODE_DENON); - Serial.print(F("PRONTO: ")); printSendEnabled(SEND_PRONTO); Serial.println(F("(Not Applicable)")); } void printSendEnabled(int flag) { diff --git a/src/IRremote.h b/src/IRremote.h index 40f28dc2f..6038a92ed 100644 --- a/src/IRremote.h +++ b/src/IRremote.h @@ -73,27 +73,9 @@ #define DECODE_DENON 1 #define SEND_DENON 1 -#define DECODE_PRONTO 0 // This function doe not logically make sense -#define SEND_PRONTO 1 - #define DECODE_LEGO_PF 0 // NOT WRITTEN #define SEND_LEGO_PF 1 -//------------------------------------------------------------------------------ -// When sending a Pronto code we request to send either the "once" code -// or the "repeat" code -// If the code requested does not exist we can request to fallback on the -// other code (the one we did not explicitly request) -// -// I would suggest that "fallback" will be the standard calling method -// The last paragraph on this page discusses the rationale of this idea: -// http://www.remotecentral.com/features/irdisp2.htm -// -#define PRONTO_ONCE false -#define PRONTO_REPEAT true -#define PRONTO_FALLBACK true -#define PRONTO_NOFALLBACK false - //------------------------------------------------------------------------------ // An enumerated list of all supported formats // You do NOT need to remove entries from this list when disabling protocols! @@ -117,7 +99,6 @@ typedef DISH, SHARP, DENON, - PRONTO, LEGO_PF, } decode_type_t; @@ -340,10 +321,6 @@ class IRsend //...................................................................... # if SEND_DENON void sendDenon (unsigned long data, int nbits) ; -# endif - //...................................................................... -# if SEND_PRONTO - void sendPronto (char* code, bool repeat, bool fallback) ; # endif //...................................................................... # if SEND_LEGO_PF diff --git a/src/irPronto.cpp b/src/irPronto.cpp deleted file mode 100644 index 0f530a900..000000000 --- a/src/irPronto.cpp +++ /dev/null @@ -1,513 +0,0 @@ -#define TEST 0 - -#if TEST -# define SEND_PRONTO 1 -# define PRONTO_ONCE false -# define PRONTO_REPEAT true -# define PRONTO_FALLBACK true -# define PRONTO_NOFALLBACK false -#endif - -#if SEND_PRONTO - -//****************************************************************************** -#if TEST -# include - void enableIROut (int freq) { printf("\nFreq = %d KHz\n", freq); } - void mark (int t) { printf("+%d," , t); } - void space (int t) { printf("-%d, ", t); } -#else -# include "IRremote.h" -#endif // TEST - -//+============================================================================= -// Check for a valid hex digit -// -bool ishex (char ch) -{ - return ( ((ch >= '0') && (ch <= '9')) || - ((ch >= 'A') && (ch <= 'F')) || - ((ch >= 'a') && (ch <= 'f')) ) ? true : false ; -} - -//+============================================================================= -// Check for a valid "blank" ... '\0' is a valid "blank" -// -bool isblank (char ch) -{ - return ((ch == ' ') || (ch == '\t') || (ch == '\0')) ? true : false ; -} - -//+============================================================================= -// Bypass spaces -// -bool byp (char** pcp) -{ - while (isblank(**pcp)) (*pcp)++ ; -} - -//+============================================================================= -// Hex-to-Byte : Decode a hex digit -// We assume the character has already been validated -// -uint8_t htob (char ch) -{ - if ((ch >= '0') && (ch <= '9')) return ch - '0' ; - if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ; - if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ; -} - -//+============================================================================= -// Hex-to-Word : Decode a block of 4 hex digits -// We assume the string has already been validated -// and the pointer being passed points at the start of a block of 4 hex digits -// -uint16_t htow (char* cp) -{ - return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | - (htob(cp[2]) << 4) | (htob(cp[3]) ) ) ; -} - -//+============================================================================= -// -bool sendPronto (char* s, bool repeat, bool fallback) -{ - int i; - int len; - int skip; - char* cp; - uint16_t freq; // Frequency in KHz - uint8_t usec; // pronto uSec/tick - uint8_t once; - uint8_t rpt; - - // Validate the string - for (cp = s; *cp; cp += 4) { - byp(&cp); - if ( !ishex(cp[0]) || !ishex(cp[1]) || - !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ; - } - - // We will use cp to traverse the string - cp = s; - - // Check mode = Oscillated/Learned - byp(&cp); - if (htow(cp) != 0000) return false; - cp += 4; - - // Extract & set frequency - byp(&cp); - freq = (int)(1000000 / (htow(cp) * 0.241246)); // Rounding errors will occur, tolerance is +/- 10% - usec = (int)(((1.0 / freq) * 1000000) + 0.5); // Another rounding error, thank Cod for analogue electronics - freq /= 1000; // This will introduce a(nother) rounding error which we do not want in the usec calcualtion - cp += 4; - - // Get length of "once" code - byp(&cp); - once = htow(cp); - cp += 4; - - // Get length of "repeat" code - byp(&cp); - rpt = htow(cp); - cp += 4; - - // Which code are we sending? - if (fallback) { // fallback on the "other" code if "this" code is not present - if (!repeat) { // requested 'once' - if (once) len = once * 2, skip = 0 ; // if once exists send it - else len = rpt * 2, skip = 0 ; // else send repeat code - } else { // requested 'repeat' - if (rpt) len = rpt * 2, skip = 0 ; // if rpt exists send it - else len = once * 2, skip = 0 ; // else send once code - } - } else { // Send what we asked for, do not fallback if the code is empty! - if (!repeat) len = once * 2, skip = 0 ; // 'once' starts at 0 - else len = rpt * 2, skip = once ; // 'repeat' starts where 'once' ends - } - - // Skip to start of code - for (i = 0; i < skip; i++, cp += 4) byp(&cp) ; - - // Send code - enableIROut(freq); - for (i = 0; i < len; i++) { - byp(&cp); - if (i & 1) space(htow(cp) * usec); - else mark (htow(cp) * usec); - cp += 4; - } -} - -//+============================================================================= -#if TEST - -int main ( ) -{ - char prontoTest[] = - "0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 - "0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 - "0010 0030 0010 0aa6"; // 104 - - sendPronto(prontoTest, PRONTO_ONCE, PRONTO_FALLBACK); // once code - sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_FALLBACK); // repeat code - sendPronto(prontoTest, PRONTO_ONCE, PRONTO_NOFALLBACK); // once code - sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_NOFALLBACK); // repeat code - - return 0; -} - -#endif // TEST - -#endif // SEND_PRONTO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#if 0 -//****************************************************************************** -// Sources: -// http://www.remotecentral.com/features/irdisp2.htm -// http://www.hifi-remote.com/wiki/index.php?title=Working_With_Pronto_Hex -//****************************************************************************** - -#include -#include - -#define IRPRONTO -#include "IRremoteInt.h" // The Arduino IRremote library defines USECPERTICK - -//------------------------------------------------------------------------------ -// Source: https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet -// -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls -// -char prontoTest[] = - "0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 - "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 - "0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 - "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 - "0010 0030 0010 0aa6"; // 104 - -//------------------------------------------------------------------------------ -// This is the longest code we can support -#define CODEMAX 200 - -//------------------------------------------------------------------------------ -// This is the data we pull out of the pronto code -typedef - struct { - int freq; // Carrier frequency (in Hz) - int usec; // uSec per tick (based on freq) - - int codeLen; // Length of code - uint16_t code[CODEMAX]; // Code in hex - - int onceLen; // Length of "once" transmit - uint16_t* once; // Pointer to start within 'code' - - int rptLen; // Length of "repeat" transmit - uint16_t* rpt; // Pointer to start within 'code' - } -pronto_t; - -//------------------------------------------------------------------------------ -// From what I have seen, the only time we go over 8-bits is the 'space' -// on the end which creates the lead-out/inter-code gap. Assuming I'm right, -// we can code this up as a special case and otherwise halve the size of our -// data! -// Ignoring the first four values (the config data) and the last value -// (the lead-out), if you find a protocol that uses values greater than 00fe -// we are going to have to revisit this code! -// -// -// So, the 0th byte will be the carrier frequency in Khz (NOT Hz) -// " 1st " " " " length of the "once" code -// " 2nd " " " " length of the "repeat" code -// -// Thereafter, odd bytes will be Mark lengths as a multiple of USECPERTICK uS -// even " " " Space " " " " " " " -// -// Any occurence of "FF" in either a Mark or a Space will indicate -// "Use the 16-bit FF value" which will also be a multiple of USECPERTICK uS -// -// -// As a point of comparison, the test code (prontoTest[]) is 520 bytes -// (yes, more than 0.5KB of our Arduino's precious 32KB) ... after conversion -// to pronto hex that goes down to ((520/5)*2) = 208 bytes ... once converted to -// our format we are down to ((208/2) -1 -1 +2) = 104 bytes -// -// In fariness this is still very memory-hungry -// ...As a rough guide: -// 10 codes cost 1K of memory (this will vary depending on the protocol). -// -// So if you're building a complex remote control, you will probably need to -// keep the codes on an external memory device (not in the Arduino sketch) and -// load them as you need them. Hmmm. -// -// This dictates that "Oscillated Pronto Codes" are probably NOT the way forward -// -// For example, prontoTest[] happens to be: A 48-bit IR code in Denon format -// So we know it starts with 80/40 (Denon header) -// and ends with 10/aa6 (Denon leadout) -// and all (48) bits in between are either 10/10 (Denon 0) -// or 10/30 (Denon 1) -// So we could easily store this data in 1-byte ("Denon") -// + 1-byte (Length=48) -// + 6-bytes (IR code) -// At 8-bytes per code, we can store 128 codes in 1KB or memory - that's a lot -// better than the 2 (two) we started off with! -// -// And serendipitously, by reducing the amount of data, our program will run -// a LOT faster! -// -// Again, I repeat, even after you have spent time converting the "Oscillated -// Pronto Codes" in to IRremote format, it will be a LOT more memory-hungry -// than using sendDenon() (or whichever) ...BUT these codes are easily -// available on the internet, so we'll support them! -// -typedef - struct { - uint16_t FF; - uint8_t code[CODEMAX]; - } -irCode_t; - -//------------------------------------------------------------------------------ -#define DEBUGF(...) printf(__VA_ARGS__) - -//+============================================================================= -// String must be block of 4 hex digits separated with blanks -// -bool validate (char* cp, int* len) -{ - for (*len = 0; *cp; (*len)++, cp += 4) { - byp(&cp); - if ( !ishex(cp[0]) || !ishex(cp[1]) || - !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ; - } - - return true; -} - -//+============================================================================= -// Hex-to-Byte : Decode a hex digit -// We assume the character has already been validated -// -uint8_t htob (char ch) -{ - if ((ch >= '0') && (ch <= '9')) return ch - '0' ; - if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ; - if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ; -} - -//+============================================================================= -// Hex-to-Word : Decode a block of 4 hex digits -// We assume the string has already been validated -// and the pointer being passed points at the start of a block of 4 hex digits -// -uint16_t htow (char* cp) -{ - return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | - (htob(cp[2]) << 4) | (htob(cp[3]) ) ) ; -} - -//+============================================================================= -// Convert the pronto string in to data -// -bool decode (char* s, pronto_t* p, irCode_t* ir) -{ - int i, len; - char* cp; - - // Validate the Pronto string - if (!validate(s, &p->codeLen)) { - DEBUGF("Invalid pronto string\n"); - return false ; - } - DEBUGF("Found %d hex codes\n", p->codeLen); - - // Allocate memory to store the decoded string - //if (!(p->code = malloc(p->len))) { - // DEBUGF("Memory allocation failed\n"); - // return false ; - //} - - // Check in case our code is too long - if (p->codeLen > CODEMAX) { - DEBUGF("Code too long, edit CODEMAX and recompile\n"); - return false ; - } - - // Decode the string - cp = s; - for (i = 0; i < p->codeLen; i++, cp += 4) { - byp(&cp); - p->code[i] = htow(cp); - } - - // Announce our findings - DEBUGF("Input: |%s|\n", s); - DEBUGF("Found: |"); - for (i = 0; i < p->codeLen; i++) DEBUGF("%04x ", p->code[i]) ; - DEBUGF("|\n"); - - DEBUGF("Form [%04X] : ", p->code[0]); - if (p->code[0] == 0x0000) DEBUGF("Oscillated (Learned)\n"); - else if (p->code[0] == 0x0100) DEBUGF("Unmodulated\n"); - else DEBUGF("Unknown\n"); - if (p->code[0] != 0x0000) return false ; // Can only handle Oscillated - - // Calculate the carrier frequency (+/- 10%) & uSecs per pulse - // Pronto uses a crystal which generates a timeabse of 0.241246 - p->freq = (int)(1000000 / (p->code[1] * 0.241246)); - p->usec = (int)(((1.0 / p->freq) * 1000000) + 0.5); - ir->code[0] = p->freq / 1000; - DEBUGF("Freq [%04X] : %d Hz (%d uS/pluse) -> %d KHz\n", - p->code[1], p->freq, p->usec, ir->code[0]); - - // Set the length & start pointer for the "once" code - p->onceLen = p->code[2]; - p->once = &p->code[4]; - ir->code[1] = p->onceLen; - DEBUGF("Once [%04X] : %d\n", p->code[2], p->onceLen); - - // Set the length & start pointer for the "repeat" code - p->rptLen = p->code[3]; - p->rpt = &p->code[4 + p->onceLen]; - ir->code[2] = p->rptLen; - DEBUGF("Rpt [%04X] : %d\n", p->code[3], p->rptLen); - - // Check everything tallies - if (1 + 1 + 1 + 1 + (p->onceLen * 2) + (p->rptLen * 2) != p->codeLen) { - DEBUGF("Bad code length\n"); - return false; - } - - // Convert the IR data to our new format - ir->FF = p->code[p->codeLen - 1]; - - len = (p->onceLen * 2) + (p->rptLen * 2); - DEBUGF("Encoded: |"); - for (i = 0; i < len; i++) { - if (p->code[i+4] == ir->FF) { - ir->code[i+3] = 0xFF; - } else if (p->code[i+4] > 0xFE) { - DEBUGF("\n%04X : Mark/Space overflow\n", p->code[i+4]); - return false; - } else { - ir->code[i+3] = (p->code[i+4] * p->usec) / USECPERTICK; - } - DEBUGF("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]); - } - DEBUGF("|\n"); - - ir->FF = (ir->FF * p->usec) / USECPERTICK; - DEBUGF("FF -> %d\n", ir->FF); - - return true; -} - -//+============================================================================= -// -void irDump (irCode_t* ir) -{ - int i, len; - - printf("uint8_t buttonName[%d] = {", len); - - printf("%d,%d, ", (ir->FF >> 8), ir->FF & 0xFF); - printf("%d,%d,%d, ", ir->code[0], ir->code[1], ir->code[2]); - - len = (ir->code[1] * 2) + (ir->code[2] * 2); - for (i = 0; i < len; i++) { - printf("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]); - } - - printf("};\n"); - -} - -//+============================================================================= -// -int main ( ) -{ - pronto_t pCode; - irCode_t irCode; - - decode(prontoTest, &pCode, &irCode); - - irDump(&irCode); - - return 0; -} - -#endif //0 From 542516f116d5ce61c9153e44553b77bf7599eec1 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Sun, 13 Aug 2017 12:03:54 -0600 Subject: [PATCH 215/768] Revert "Removed pronto "protocol"" This reverts commit 563c82c6c4fbce090590fd0c30f7c8301a4b2652. --- examples/IRremoteInfo/IRremoteInfo.ino | 1 + src/IRremote.h | 23 ++ src/irPronto.cpp | 513 +++++++++++++++++++++++++ 3 files changed, 537 insertions(+) create mode 100644 src/irPronto.cpp diff --git a/examples/IRremoteInfo/IRremoteInfo.ino b/examples/IRremoteInfo/IRremoteInfo.ino index 45cf7236e..c3f329754 100644 --- a/examples/IRremoteInfo/IRremoteInfo.ino +++ b/examples/IRremoteInfo/IRremoteInfo.ino @@ -188,6 +188,7 @@ void dumpProtocols() { Serial.print(F("DISH: ")); printSendEnabled(SEND_DISH); printDecodeEnabled(DECODE_DISH); Serial.print(F("SHARP: ")); printSendEnabled(SEND_SHARP); printDecodeEnabled(DECODE_SHARP); Serial.print(F("DENON: ")); printSendEnabled(SEND_DENON); printDecodeEnabled(DECODE_DENON); + Serial.print(F("PRONTO: ")); printSendEnabled(SEND_PRONTO); Serial.println(F("(Not Applicable)")); } void printSendEnabled(int flag) { diff --git a/src/IRremote.h b/src/IRremote.h index 6038a92ed..40f28dc2f 100644 --- a/src/IRremote.h +++ b/src/IRremote.h @@ -73,9 +73,27 @@ #define DECODE_DENON 1 #define SEND_DENON 1 +#define DECODE_PRONTO 0 // This function doe not logically make sense +#define SEND_PRONTO 1 + #define DECODE_LEGO_PF 0 // NOT WRITTEN #define SEND_LEGO_PF 1 +//------------------------------------------------------------------------------ +// When sending a Pronto code we request to send either the "once" code +// or the "repeat" code +// If the code requested does not exist we can request to fallback on the +// other code (the one we did not explicitly request) +// +// I would suggest that "fallback" will be the standard calling method +// The last paragraph on this page discusses the rationale of this idea: +// http://www.remotecentral.com/features/irdisp2.htm +// +#define PRONTO_ONCE false +#define PRONTO_REPEAT true +#define PRONTO_FALLBACK true +#define PRONTO_NOFALLBACK false + //------------------------------------------------------------------------------ // An enumerated list of all supported formats // You do NOT need to remove entries from this list when disabling protocols! @@ -99,6 +117,7 @@ typedef DISH, SHARP, DENON, + PRONTO, LEGO_PF, } decode_type_t; @@ -321,6 +340,10 @@ class IRsend //...................................................................... # if SEND_DENON void sendDenon (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_PRONTO + void sendPronto (char* code, bool repeat, bool fallback) ; # endif //...................................................................... # if SEND_LEGO_PF diff --git a/src/irPronto.cpp b/src/irPronto.cpp new file mode 100644 index 000000000..0f530a900 --- /dev/null +++ b/src/irPronto.cpp @@ -0,0 +1,513 @@ +#define TEST 0 + +#if TEST +# define SEND_PRONTO 1 +# define PRONTO_ONCE false +# define PRONTO_REPEAT true +# define PRONTO_FALLBACK true +# define PRONTO_NOFALLBACK false +#endif + +#if SEND_PRONTO + +//****************************************************************************** +#if TEST +# include + void enableIROut (int freq) { printf("\nFreq = %d KHz\n", freq); } + void mark (int t) { printf("+%d," , t); } + void space (int t) { printf("-%d, ", t); } +#else +# include "IRremote.h" +#endif // TEST + +//+============================================================================= +// Check for a valid hex digit +// +bool ishex (char ch) +{ + return ( ((ch >= '0') && (ch <= '9')) || + ((ch >= 'A') && (ch <= 'F')) || + ((ch >= 'a') && (ch <= 'f')) ) ? true : false ; +} + +//+============================================================================= +// Check for a valid "blank" ... '\0' is a valid "blank" +// +bool isblank (char ch) +{ + return ((ch == ' ') || (ch == '\t') || (ch == '\0')) ? true : false ; +} + +//+============================================================================= +// Bypass spaces +// +bool byp (char** pcp) +{ + while (isblank(**pcp)) (*pcp)++ ; +} + +//+============================================================================= +// Hex-to-Byte : Decode a hex digit +// We assume the character has already been validated +// +uint8_t htob (char ch) +{ + if ((ch >= '0') && (ch <= '9')) return ch - '0' ; + if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ; + if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ; +} + +//+============================================================================= +// Hex-to-Word : Decode a block of 4 hex digits +// We assume the string has already been validated +// and the pointer being passed points at the start of a block of 4 hex digits +// +uint16_t htow (char* cp) +{ + return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | + (htob(cp[2]) << 4) | (htob(cp[3]) ) ) ; +} + +//+============================================================================= +// +bool sendPronto (char* s, bool repeat, bool fallback) +{ + int i; + int len; + int skip; + char* cp; + uint16_t freq; // Frequency in KHz + uint8_t usec; // pronto uSec/tick + uint8_t once; + uint8_t rpt; + + // Validate the string + for (cp = s; *cp; cp += 4) { + byp(&cp); + if ( !ishex(cp[0]) || !ishex(cp[1]) || + !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ; + } + + // We will use cp to traverse the string + cp = s; + + // Check mode = Oscillated/Learned + byp(&cp); + if (htow(cp) != 0000) return false; + cp += 4; + + // Extract & set frequency + byp(&cp); + freq = (int)(1000000 / (htow(cp) * 0.241246)); // Rounding errors will occur, tolerance is +/- 10% + usec = (int)(((1.0 / freq) * 1000000) + 0.5); // Another rounding error, thank Cod for analogue electronics + freq /= 1000; // This will introduce a(nother) rounding error which we do not want in the usec calcualtion + cp += 4; + + // Get length of "once" code + byp(&cp); + once = htow(cp); + cp += 4; + + // Get length of "repeat" code + byp(&cp); + rpt = htow(cp); + cp += 4; + + // Which code are we sending? + if (fallback) { // fallback on the "other" code if "this" code is not present + if (!repeat) { // requested 'once' + if (once) len = once * 2, skip = 0 ; // if once exists send it + else len = rpt * 2, skip = 0 ; // else send repeat code + } else { // requested 'repeat' + if (rpt) len = rpt * 2, skip = 0 ; // if rpt exists send it + else len = once * 2, skip = 0 ; // else send once code + } + } else { // Send what we asked for, do not fallback if the code is empty! + if (!repeat) len = once * 2, skip = 0 ; // 'once' starts at 0 + else len = rpt * 2, skip = once ; // 'repeat' starts where 'once' ends + } + + // Skip to start of code + for (i = 0; i < skip; i++, cp += 4) byp(&cp) ; + + // Send code + enableIROut(freq); + for (i = 0; i < len; i++) { + byp(&cp); + if (i & 1) space(htow(cp) * usec); + else mark (htow(cp) * usec); + cp += 4; + } +} + +//+============================================================================= +#if TEST + +int main ( ) +{ + char prontoTest[] = + "0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 + "0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 + "0010 0030 0010 0aa6"; // 104 + + sendPronto(prontoTest, PRONTO_ONCE, PRONTO_FALLBACK); // once code + sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_FALLBACK); // repeat code + sendPronto(prontoTest, PRONTO_ONCE, PRONTO_NOFALLBACK); // once code + sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_NOFALLBACK); // repeat code + + return 0; +} + +#endif // TEST + +#endif // SEND_PRONTO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#if 0 +//****************************************************************************** +// Sources: +// http://www.remotecentral.com/features/irdisp2.htm +// http://www.hifi-remote.com/wiki/index.php?title=Working_With_Pronto_Hex +//****************************************************************************** + +#include +#include + +#define IRPRONTO +#include "IRremoteInt.h" // The Arduino IRremote library defines USECPERTICK + +//------------------------------------------------------------------------------ +// Source: https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet +// -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls +// +char prontoTest[] = + "0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 + "0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 + "0010 0030 0010 0aa6"; // 104 + +//------------------------------------------------------------------------------ +// This is the longest code we can support +#define CODEMAX 200 + +//------------------------------------------------------------------------------ +// This is the data we pull out of the pronto code +typedef + struct { + int freq; // Carrier frequency (in Hz) + int usec; // uSec per tick (based on freq) + + int codeLen; // Length of code + uint16_t code[CODEMAX]; // Code in hex + + int onceLen; // Length of "once" transmit + uint16_t* once; // Pointer to start within 'code' + + int rptLen; // Length of "repeat" transmit + uint16_t* rpt; // Pointer to start within 'code' + } +pronto_t; + +//------------------------------------------------------------------------------ +// From what I have seen, the only time we go over 8-bits is the 'space' +// on the end which creates the lead-out/inter-code gap. Assuming I'm right, +// we can code this up as a special case and otherwise halve the size of our +// data! +// Ignoring the first four values (the config data) and the last value +// (the lead-out), if you find a protocol that uses values greater than 00fe +// we are going to have to revisit this code! +// +// +// So, the 0th byte will be the carrier frequency in Khz (NOT Hz) +// " 1st " " " " length of the "once" code +// " 2nd " " " " length of the "repeat" code +// +// Thereafter, odd bytes will be Mark lengths as a multiple of USECPERTICK uS +// even " " " Space " " " " " " " +// +// Any occurence of "FF" in either a Mark or a Space will indicate +// "Use the 16-bit FF value" which will also be a multiple of USECPERTICK uS +// +// +// As a point of comparison, the test code (prontoTest[]) is 520 bytes +// (yes, more than 0.5KB of our Arduino's precious 32KB) ... after conversion +// to pronto hex that goes down to ((520/5)*2) = 208 bytes ... once converted to +// our format we are down to ((208/2) -1 -1 +2) = 104 bytes +// +// In fariness this is still very memory-hungry +// ...As a rough guide: +// 10 codes cost 1K of memory (this will vary depending on the protocol). +// +// So if you're building a complex remote control, you will probably need to +// keep the codes on an external memory device (not in the Arduino sketch) and +// load them as you need them. Hmmm. +// +// This dictates that "Oscillated Pronto Codes" are probably NOT the way forward +// +// For example, prontoTest[] happens to be: A 48-bit IR code in Denon format +// So we know it starts with 80/40 (Denon header) +// and ends with 10/aa6 (Denon leadout) +// and all (48) bits in between are either 10/10 (Denon 0) +// or 10/30 (Denon 1) +// So we could easily store this data in 1-byte ("Denon") +// + 1-byte (Length=48) +// + 6-bytes (IR code) +// At 8-bytes per code, we can store 128 codes in 1KB or memory - that's a lot +// better than the 2 (two) we started off with! +// +// And serendipitously, by reducing the amount of data, our program will run +// a LOT faster! +// +// Again, I repeat, even after you have spent time converting the "Oscillated +// Pronto Codes" in to IRremote format, it will be a LOT more memory-hungry +// than using sendDenon() (or whichever) ...BUT these codes are easily +// available on the internet, so we'll support them! +// +typedef + struct { + uint16_t FF; + uint8_t code[CODEMAX]; + } +irCode_t; + +//------------------------------------------------------------------------------ +#define DEBUGF(...) printf(__VA_ARGS__) + +//+============================================================================= +// String must be block of 4 hex digits separated with blanks +// +bool validate (char* cp, int* len) +{ + for (*len = 0; *cp; (*len)++, cp += 4) { + byp(&cp); + if ( !ishex(cp[0]) || !ishex(cp[1]) || + !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ; + } + + return true; +} + +//+============================================================================= +// Hex-to-Byte : Decode a hex digit +// We assume the character has already been validated +// +uint8_t htob (char ch) +{ + if ((ch >= '0') && (ch <= '9')) return ch - '0' ; + if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ; + if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ; +} + +//+============================================================================= +// Hex-to-Word : Decode a block of 4 hex digits +// We assume the string has already been validated +// and the pointer being passed points at the start of a block of 4 hex digits +// +uint16_t htow (char* cp) +{ + return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | + (htob(cp[2]) << 4) | (htob(cp[3]) ) ) ; +} + +//+============================================================================= +// Convert the pronto string in to data +// +bool decode (char* s, pronto_t* p, irCode_t* ir) +{ + int i, len; + char* cp; + + // Validate the Pronto string + if (!validate(s, &p->codeLen)) { + DEBUGF("Invalid pronto string\n"); + return false ; + } + DEBUGF("Found %d hex codes\n", p->codeLen); + + // Allocate memory to store the decoded string + //if (!(p->code = malloc(p->len))) { + // DEBUGF("Memory allocation failed\n"); + // return false ; + //} + + // Check in case our code is too long + if (p->codeLen > CODEMAX) { + DEBUGF("Code too long, edit CODEMAX and recompile\n"); + return false ; + } + + // Decode the string + cp = s; + for (i = 0; i < p->codeLen; i++, cp += 4) { + byp(&cp); + p->code[i] = htow(cp); + } + + // Announce our findings + DEBUGF("Input: |%s|\n", s); + DEBUGF("Found: |"); + for (i = 0; i < p->codeLen; i++) DEBUGF("%04x ", p->code[i]) ; + DEBUGF("|\n"); + + DEBUGF("Form [%04X] : ", p->code[0]); + if (p->code[0] == 0x0000) DEBUGF("Oscillated (Learned)\n"); + else if (p->code[0] == 0x0100) DEBUGF("Unmodulated\n"); + else DEBUGF("Unknown\n"); + if (p->code[0] != 0x0000) return false ; // Can only handle Oscillated + + // Calculate the carrier frequency (+/- 10%) & uSecs per pulse + // Pronto uses a crystal which generates a timeabse of 0.241246 + p->freq = (int)(1000000 / (p->code[1] * 0.241246)); + p->usec = (int)(((1.0 / p->freq) * 1000000) + 0.5); + ir->code[0] = p->freq / 1000; + DEBUGF("Freq [%04X] : %d Hz (%d uS/pluse) -> %d KHz\n", + p->code[1], p->freq, p->usec, ir->code[0]); + + // Set the length & start pointer for the "once" code + p->onceLen = p->code[2]; + p->once = &p->code[4]; + ir->code[1] = p->onceLen; + DEBUGF("Once [%04X] : %d\n", p->code[2], p->onceLen); + + // Set the length & start pointer for the "repeat" code + p->rptLen = p->code[3]; + p->rpt = &p->code[4 + p->onceLen]; + ir->code[2] = p->rptLen; + DEBUGF("Rpt [%04X] : %d\n", p->code[3], p->rptLen); + + // Check everything tallies + if (1 + 1 + 1 + 1 + (p->onceLen * 2) + (p->rptLen * 2) != p->codeLen) { + DEBUGF("Bad code length\n"); + return false; + } + + // Convert the IR data to our new format + ir->FF = p->code[p->codeLen - 1]; + + len = (p->onceLen * 2) + (p->rptLen * 2); + DEBUGF("Encoded: |"); + for (i = 0; i < len; i++) { + if (p->code[i+4] == ir->FF) { + ir->code[i+3] = 0xFF; + } else if (p->code[i+4] > 0xFE) { + DEBUGF("\n%04X : Mark/Space overflow\n", p->code[i+4]); + return false; + } else { + ir->code[i+3] = (p->code[i+4] * p->usec) / USECPERTICK; + } + DEBUGF("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]); + } + DEBUGF("|\n"); + + ir->FF = (ir->FF * p->usec) / USECPERTICK; + DEBUGF("FF -> %d\n", ir->FF); + + return true; +} + +//+============================================================================= +// +void irDump (irCode_t* ir) +{ + int i, len; + + printf("uint8_t buttonName[%d] = {", len); + + printf("%d,%d, ", (ir->FF >> 8), ir->FF & 0xFF); + printf("%d,%d,%d, ", ir->code[0], ir->code[1], ir->code[2]); + + len = (ir->code[1] * 2) + (ir->code[2] * 2); + for (i = 0; i < len; i++) { + printf("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]); + } + + printf("};\n"); + +} + +//+============================================================================= +// +int main ( ) +{ + pronto_t pCode; + irCode_t irCode; + + decode(prontoTest, &pCode, &irCode); + + irDump(&irCode); + + return 0; +} + +#endif //0 From 4eb95a32721e340a96c1abc0262fc17ea2ebca0b Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Mon, 14 Aug 2017 17:12:02 -0600 Subject: [PATCH 216/768] Revert "Removed blinking led" This reverts commit a406f3b9f97864c23cc7fb76f5deb04f5e09c9f8. --- keywords.txt | 1 + src/IRremote.cpp | 11 +++++++++++ src/IRremote.h | 3 ++- src/IRremoteInt.h | 2 ++ src/boarddefs.h | 27 ++++++++++++++++++++++++++- src/irRecv.cpp | 17 ++++++++++++++++- 6 files changed, 58 insertions(+), 3 deletions(-) diff --git a/keywords.txt b/keywords.txt index ea6e0192c..f2b9a4957 100644 --- a/keywords.txt +++ b/keywords.txt @@ -14,6 +14,7 @@ IRsend KEYWORD1 # Methods and Functions (KEYWORD2) ####################################### +blink13 KEYWORD2 decode KEYWORD2 enableIRIn KEYWORD2 resume KEYWORD2 diff --git a/src/IRremote.cpp b/src/IRremote.cpp index c8730d7b3..f41f81878 100644 --- a/src/IRremote.cpp +++ b/src/IRremote.cpp @@ -127,6 +127,7 @@ ISR (TIMER_INTR_NAME) { TIMER_RESET; + // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on] // digitalRead() is very slow. Optimisation is possible, but makes the code unportable uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); @@ -184,4 +185,14 @@ ISR (TIMER_INTR_NAME) break; } +#ifdef BLINKLED + // If requested, flash LED while receiving IR data + if (irparams.blinkflag) { + if (irdata == MARK) + if (irparams.blinkpin) digitalWrite(irparams.blinkpin, HIGH); // Turn user defined pin LED on + else BLINKLED_ON() ; // if no user defined LED pin, turn default LED pin for the hardware on + else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on + else BLINKLED_OFF() ; // if no user defined LED pin, turn default LED pin for the hardware on + } +#endif // BLINKLED } diff --git a/src/IRremote.h b/src/IRremote.h index 40f28dc2f..928284361 100644 --- a/src/IRremote.h +++ b/src/IRremote.h @@ -172,8 +172,9 @@ class IRrecv { public: IRrecv (int recvpin) ; - IRrecv (int recvpin); + IRrecv (int recvpin, int blinkpin); + void blink13 (int blinkflag) ; int decode (decode_results *results) ; void enableIRIn ( ) ; bool isIdle ( ) ; diff --git a/src/IRremoteInt.h b/src/IRremoteInt.h index 08f162e51..1baa05d6d 100644 --- a/src/IRremoteInt.h +++ b/src/IRremoteInt.h @@ -41,6 +41,8 @@ typedef // The fields are ordered to reduce memory over caused by struct-padding uint8_t rcvstate; // State Machine state uint8_t recvpin; // Pin connected to IR data from detector + uint8_t blinkpin; + uint8_t blinkflag; // true -> enable blinking of pin on IR processing uint8_t rawlen; // counter of entries in rawbuf unsigned int timer; // State timer, counts 50uS ticks. unsigned int rawbuf[RAWBUF]; // raw data diff --git a/src/boarddefs.h b/src/boarddefs.h index 5751ba700..5c49465ef 100644 --- a/src/boarddefs.h +++ b/src/boarddefs.h @@ -47,10 +47,29 @@ // is not configurable on the current board. //------------------------------------------------------------------------------ -// Soft Carrier fallback for SAM and SAMD architectures +// Defines for blinking the LED // +#if defined(CORE_LED0_PIN) +# 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__) || defined(__AVR_ATmega2560__) +# define BLINKLED 13 +# define BLINKLED_ON() (PORTB |= B10000000) +# define BLINKLED_OFF() (PORTB &= B01111111) + +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) +# define BLINKLED 0 +# define BLINKLED_ON() (PORTD |= B00000001) +# define BLINKLED_OFF() (PORTD &= B11111110) + #elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) +# define BLINKLED LED_BUILTIN +# define BLINKLED_ON() (digitalWrite(LED_BUILTIN, HIGH)) +# define BLINKLED_OFF() (digitalWrite(LED_BUILTIN, LOW)) + # define USE_SOFT_CARRIER // Define to use spin wait instead of delayMicros() //# define USE_SPIN_WAIT @@ -60,6 +79,8 @@ # define SEND_PIN 9 #elif defined(ESP32) + // No system LED on ESP32, disable blinking by NOT defining BLINKLED + // avr/interrupt.h is not present # undef HAS_AVR_INTERRUPT_H @@ -69,6 +90,10 @@ // Supply own enbleIRIn # undef USE_DEFAULT_ENABLE_IR_IN +#else +# define BLINKLED 13 +# define BLINKLED_ON() (PORTB |= B00100000) +# define BLINKLED_OFF() (PORTB &= B11011111) #endif //------------------------------------------------------------------------------ diff --git a/src/irRecv.cpp b/src/irRecv.cpp index 8498e16a4..b549dac1c 100644 --- a/src/irRecv.cpp +++ b/src/irRecv.cpp @@ -99,11 +99,15 @@ int IRrecv::decode (decode_results *results) IRrecv::IRrecv (int recvpin) { irparams.recvpin = recvpin; + irparams.blinkflag = 0; } -IRrecv::IRrecv (int recvpin) +IRrecv::IRrecv (int recvpin, int blinkpin) { irparams.recvpin = recvpin; + irparams.blinkpin = blinkpin; + pinMode(blinkpin, OUTPUT); + irparams.blinkflag = 0; } @@ -138,6 +142,17 @@ void IRrecv::enableIRIn ( ) } #endif // USE_DEFAULT_ENABLE_IR_IN +//+============================================================================= +// Enable/disable blinking of pin 13 on IR processing +// +void IRrecv::blink13 (int blinkflag) +{ +#ifdef BLINKLED + irparams.blinkflag = blinkflag; + if (blinkflag) pinMode(BLINKLED, OUTPUT) ; +#endif +} + //+============================================================================= // Return if receiving new IR signals // From 7245efd2f5eeeb12986236ec806f03912a002fe3 Mon Sep 17 00:00:00 2001 From: Bengt Martensson Date: Fri, 18 Aug 2017 01:32:01 +0200 Subject: [PATCH 217/768] Fix some minor problems in boarddefs.h and IRremote.cpp (#505) * Removed some trailing spaces in IRremote.cpp. * IRremote.cpp: fix some compiler warnings (-Wall -Wextra). Remark: braces necessitated by the macro nature of DBG_PRINTLN. * boarddefs.h: removed spurious #. Nuked trailing spaces. Credits: bengtmartensson --- src/IRremote.cpp | 31 +++++++++++++++++-------------- src/boarddefs.h | 8 ++++---- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/IRremote.cpp b/src/IRremote.cpp index f41f81878..f21f41b0e 100644 --- a/src/IRremote.cpp +++ b/src/IRremote.cpp @@ -52,11 +52,12 @@ int MATCH (int measured, int desired) DBG_PRINT(TICKS_HIGH(desired), DEC); bool passed = ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); - if (passed) + if (passed) { DBG_PRINTLN(F("?; passed")); - else - DBG_PRINTLN(F("?; FAILED")); - return passed; + } else { + DBG_PRINTLN(F("?; FAILED")); + } + return passed; } //+======================================================== @@ -68,7 +69,7 @@ int MATCH_MARK (int measured_ticks, int desired_us) DBG_PRINT(measured_ticks * USECPERTICK, DEC); DBG_PRINT(F("us vs ")); DBG_PRINT(desired_us, DEC); - DBG_PRINT("us"); + DBG_PRINT("us"); DBG_PRINT(": "); DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS) * USECPERTICK, DEC); DBG_PRINT(F(" <= ")); @@ -78,11 +79,12 @@ int MATCH_MARK (int measured_ticks, int desired_us) bool passed = ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); - if (passed) + if (passed) { DBG_PRINTLN(F("?; passed")); - else - DBG_PRINTLN(F("?; FAILED")); - return passed; + } else { + DBG_PRINTLN(F("?; FAILED")); + } + return passed; } //+======================================================== @@ -94,7 +96,7 @@ int MATCH_SPACE (int measured_ticks, int desired_us) DBG_PRINT(measured_ticks * USECPERTICK, DEC); DBG_PRINT(F("us vs ")); DBG_PRINT(desired_us, DEC); - DBG_PRINT("us"); + DBG_PRINT("us"); DBG_PRINT(": "); DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS) * USECPERTICK, DEC); DBG_PRINT(F(" <= ")); @@ -104,11 +106,12 @@ int MATCH_SPACE (int measured_ticks, int desired_us) bool passed = ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); - if (passed) + if (passed) { DBG_PRINTLN(F("?; passed")); - else - DBG_PRINTLN(F("?; FAILED")); - return passed; + } else { + DBG_PRINTLN(F("?; FAILED")); + } + return passed; } //+============================================================================= diff --git a/src/boarddefs.h b/src/boarddefs.h index 5c49465ef..f70ac4596 100644 --- a/src/boarddefs.h +++ b/src/boarddefs.h @@ -85,7 +85,7 @@ # undef HAS_AVR_INTERRUPT_H // Sending not implemented -# undef SENDING_SUPPORTED# +# undef SENDING_SUPPORTED // Supply own enbleIRIn # undef USE_DEFAULT_ENABLE_IR_IN @@ -161,7 +161,7 @@ || defined(__AVR_ATmega164P__) //#define IR_USE_TIMER1 // tx = pin 13 #define IR_USE_TIMER2 // tx = pin 14 - + //MegaCore - ATmega64, ATmega128 #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) #define IR_USE_TIMER1 // tx = pin 13 @@ -624,7 +624,7 @@ #define TIMER_RESET #define TIMER_ENABLE_PWM // Not presently used #define TIMER_DISABLE_PWM -#define TIMER_ENABLE_INTR NVIC_EnableIRQ(TC3_IRQn) // Not presently used +#define TIMER_ENABLE_INTR NVIC_EnableIRQ(TC3_IRQn) // Not presently used #define TIMER_DISABLE_INTR NVIC_DisableIRQ(TC3_IRQn) #define TIMER_INTR_NAME TC3_Handler // Not presently used #define TIMER_CONFIG_KHZ(f) @@ -645,7 +645,7 @@ #ifndef SENDPIN_ON #define SENDPIN_ON(pin) digitalWrite(pin, HIGH) #endif - + #ifndef SENDPIN_OFF #define SENDPIN_OFF(pin) digitalWrite(pin, LOW) #endif From 24dd940107c978102fe2a04a7baf49949bde1e73 Mon Sep 17 00:00:00 2001 From: Bengt Martensson Date: Sun, 20 Aug 2017 23:49:57 +0200 Subject: [PATCH 218/768] Moving private includes to sub-directory, #464 (#507) * Add missing "paragraph" to library.properties. * Move not-to-be-exported includes to subdirectory. Remove #include "IRremoteInt.h" from a number of files since it now does not work any more, and since IRremote.h #includes it already. This resolves #464. * Remove #include from examples, too. * Make ir_Lego_PF_BitStreamEncoder.h exported (again). * Revoked fe24095 (paragraph) to keep 1-1 correspondance to #464. --- examples/IRtest/IRtest.ino | 1 - .../LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino | 1 - src/IRremote.cpp | 3 +-- src/IRremote.h | 2 +- src/esp32.cpp | 1 - src/irRecv.cpp | 1 - src/irSend.cpp | 3 +-- src/ir_Aiwa.cpp | 1 - src/ir_Denon.cpp | 1 - src/ir_Dish.cpp | 1 - src/ir_JVC.cpp | 1 - src/ir_LG.cpp | 1 - src/ir_Lego_PF.cpp | 1 - src/ir_Mitsubishi.cpp | 1 - src/ir_NEC.cpp | 1 - src/ir_Panasonic.cpp | 1 - src/ir_RC5_RC6.cpp | 1 - src/ir_Samsung.cpp | 1 - src/ir_Sanyo.cpp | 1 - src/ir_Sharp.cpp | 1 - src/ir_Sony.cpp | 1 - src/ir_Template.cpp | 1 - src/ir_Whynter.cpp | 1 - src/{ => private}/IRremoteInt.h | 0 src/{ => private}/boarddefs.h | 0 src/sam.cpp | 3 +-- 26 files changed, 4 insertions(+), 27 deletions(-) rename src/{ => private}/IRremoteInt.h (100%) rename src/{ => private}/boarddefs.h (100%) diff --git a/examples/IRtest/IRtest.ino b/examples/IRtest/IRtest.ino index 4845a4a4d..b30256386 100644 --- a/examples/IRtest/IRtest.ino +++ b/examples/IRtest/IRtest.ino @@ -10,7 +10,6 @@ */ #include -#include // Dumps out the decode_results structure. // Call this after IRrecv::decode() diff --git a/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino b/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino index e43d06c2e..1afafe5b6 100644 --- a/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino +++ b/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino @@ -4,7 +4,6 @@ */ #include -#include IRsend irsend; diff --git a/src/IRremote.cpp b/src/IRremote.cpp index f21f41b0e..0d63b7774 100644 --- a/src/IRremote.cpp +++ b/src/IRremote.cpp @@ -20,8 +20,7 @@ // Defining IR_GLOBAL here allows us to declare the instantiation of global variables #define IR_GLOBAL -# include "IRremote.h" -# include "IRremoteInt.h" +#include "IRremote.h" #undef IR_GLOBAL #ifdef HAS_AVR_INTERRUPT_H diff --git a/src/IRremote.h b/src/IRremote.h index 928284361..e95e068c7 100644 --- a/src/IRremote.h +++ b/src/IRremote.h @@ -21,7 +21,7 @@ //------------------------------------------------------------------------------ // The ISR header contains several useful macros the user may wish to use // -#include "IRremoteInt.h" +#include "private/IRremoteInt.h" //------------------------------------------------------------------------------ // Supported IR protocols diff --git a/src/esp32.cpp b/src/esp32.cpp index ef4d79476..9710098c2 100644 --- a/src/esp32.cpp +++ b/src/esp32.cpp @@ -3,7 +3,6 @@ // This file contains functions specific to the ESP32. #include "IRremote.h" -#include "IRremoteInt.h" // "Idiot check" #ifdef USE_DEFAULT_ENABLE_IR_IN diff --git a/src/irRecv.cpp b/src/irRecv.cpp index b549dac1c..f3e12aae1 100644 --- a/src/irRecv.cpp +++ b/src/irRecv.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //+============================================================================= // Decodes the received IR message diff --git a/src/irSend.cpp b/src/irSend.cpp index a01b5a012..0561408b6 100644 --- a/src/irSend.cpp +++ b/src/irSend.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" #ifdef SENDING_SUPPORTED //+============================================================================= @@ -136,4 +135,4 @@ void IRsend::custom_delay_usec(unsigned long uSecs) { //} } -#endif // SENDING_SUPPORTED \ No newline at end of file +#endif // SENDING_SUPPORTED diff --git a/src/ir_Aiwa.cpp b/src/ir_Aiwa.cpp index 50ec58d8c..78cd48aa0 100644 --- a/src/ir_Aiwa.cpp +++ b/src/ir_Aiwa.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // AAA IIIII W W AAA diff --git a/src/ir_Denon.cpp b/src/ir_Denon.cpp index c54e28654..848af79db 100644 --- a/src/ir_Denon.cpp +++ b/src/ir_Denon.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" // Reverse Engineered by looking at RAW dumps generated by IRremote diff --git a/src/ir_Dish.cpp b/src/ir_Dish.cpp index fa8e06516..e2f5c15d8 100644 --- a/src/ir_Dish.cpp +++ b/src/ir_Dish.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // DDDD IIIII SSSS H H diff --git a/src/ir_JVC.cpp b/src/ir_JVC.cpp index eeec20fe9..2a418cb66 100644 --- a/src/ir_JVC.cpp +++ b/src/ir_JVC.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // JJJJJ V V CCCC diff --git a/src/ir_LG.cpp b/src/ir_LG.cpp index ba532cb60..476196a6d 100644 --- a/src/ir_LG.cpp +++ b/src/ir_LG.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // L GGGG diff --git a/src/ir_Lego_PF.cpp b/src/ir_Lego_PF.cpp index 37d507ceb..9f9c515f6 100644 --- a/src/ir_Lego_PF.cpp +++ b/src/ir_Lego_PF.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" #include "ir_Lego_PF_BitStreamEncoder.h" //============================================================================== diff --git a/src/ir_Mitsubishi.cpp b/src/ir_Mitsubishi.cpp index 7f83e530f..751ed82ef 100644 --- a/src/ir_Mitsubishi.cpp +++ b/src/ir_Mitsubishi.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // MMMMM IIIII TTTTT SSSS U U BBBB IIIII SSSS H H IIIII diff --git a/src/ir_NEC.cpp b/src/ir_NEC.cpp index 3b4932100..284eab8af 100644 --- a/src/ir_NEC.cpp +++ b/src/ir_NEC.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // N N EEEEE CCCC diff --git a/src/ir_Panasonic.cpp b/src/ir_Panasonic.cpp index dc0dd7317..13288d2c1 100644 --- a/src/ir_Panasonic.cpp +++ b/src/ir_Panasonic.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // PPPP AAA N N AAA SSSS OOO N N IIIII CCCC diff --git a/src/ir_RC5_RC6.cpp b/src/ir_RC5_RC6.cpp index 10e79278e..402ded73d 100644 --- a/src/ir_RC5_RC6.cpp +++ b/src/ir_RC5_RC6.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //+============================================================================= // Gets one undecoded level at a time from the raw buffer. diff --git a/src/ir_Samsung.cpp b/src/ir_Samsung.cpp index 224487dbc..b605b000b 100644 --- a/src/ir_Samsung.cpp +++ b/src/ir_Samsung.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // SSSS AAA MMM SSSS U U N N GGGG diff --git a/src/ir_Sanyo.cpp b/src/ir_Sanyo.cpp index c775d6118..754444d87 100644 --- a/src/ir_Sanyo.cpp +++ b/src/ir_Sanyo.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // SSSS AAA N N Y Y OOO diff --git a/src/ir_Sharp.cpp b/src/ir_Sharp.cpp index 73462c5bc..da0af1a35 100644 --- a/src/ir_Sharp.cpp +++ b/src/ir_Sharp.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // SSSS H H AAA RRRR PPPP diff --git a/src/ir_Sony.cpp b/src/ir_Sony.cpp index 31e67cf78..b3e15ef47 100644 --- a/src/ir_Sony.cpp +++ b/src/ir_Sony.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // SSSS OOO N N Y Y diff --git a/src/ir_Template.cpp b/src/ir_Template.cpp index eee2b0bb2..2b895e144 100644 --- a/src/ir_Template.cpp +++ b/src/ir_Template.cpp @@ -92,7 +92,6 @@ Regards, */ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // diff --git a/src/ir_Whynter.cpp b/src/ir_Whynter.cpp index a830562c6..5ec373de4 100644 --- a/src/ir_Whynter.cpp +++ b/src/ir_Whynter.cpp @@ -1,5 +1,4 @@ #include "IRremote.h" -#include "IRremoteInt.h" //============================================================================== // W W H H Y Y N N TTTTT EEEEE RRRRR diff --git a/src/IRremoteInt.h b/src/private/IRremoteInt.h similarity index 100% rename from src/IRremoteInt.h rename to src/private/IRremoteInt.h diff --git a/src/boarddefs.h b/src/private/boarddefs.h similarity index 100% rename from src/boarddefs.h rename to src/private/boarddefs.h diff --git a/src/sam.cpp b/src/sam.cpp index 06575891c..4cb1b9f13 100644 --- a/src/sam.cpp +++ b/src/sam.cpp @@ -1,7 +1,6 @@ // Support routines for SAM processor boards #include "IRremote.h" -#include "IRremoteInt.h" #if defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) @@ -99,4 +98,4 @@ void TC3_Handler(void) } } -#endif // defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) \ No newline at end of file +#endif // defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) From 5bbd55c65015a387063fd3877c58ee4affedd20e Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 22 Aug 2017 15:47:20 -0600 Subject: [PATCH 219/768] Fix #510 --- library.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/library.properties b/library.properties index 0e23d4cf2..56f8a78f4 100644 --- a/library.properties +++ b/library.properties @@ -3,6 +3,7 @@ version=2.4.0 author=shirriff, z3t0 maintainer=z3t0 sentence=Send and receive infrared signals with multiple protocols +paragraph=Find more information at https://github.com/z3t0/Arduino-IRremote category=Communication url=https://github.com/z3t0/Arduino-IRremote architectures=* From e206e122e5afbf2a495671dbb8fba5cf67ef849a Mon Sep 17 00:00:00 2001 From: Bengt Martensson Date: Wed, 23 Aug 2017 21:57:05 +0200 Subject: [PATCH 220/768] Doxygen API documentation in the sense of #461 (#512) * new file: Doxyfile; #461. * Doxygen related documentation to two files. (Not complete.) #461. --- Doxyfile | 2417 +++++++++++++++++++++++++++++++++++++ src/IRremote.h | 105 +- src/private/IRremoteInt.h | 35 +- 3 files changed, 2516 insertions(+), 41 deletions(-) create mode 100644 Doxyfile diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 000000000..a4274ab79 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,2417 @@ +# Doxyfile 1.8.13 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "IRremote" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = YES + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = src src/private . + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = README.md + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = api-doc + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /