Added Samsung protocol

This commit is contained in:
sstefanov
2014-05-23 12:20:39 +03:00
parent 239964fabf
commit 890ca057f6
3 changed files with 116 additions and 41 deletions

View File

@@ -65,6 +65,11 @@ int MATCH_SPACE(int measured_ticks, int desired_us) {
Serial.println(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); 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); 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 #endif
void IRsend::sendNEC(unsigned long data, int nbits) 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); mark(JVC_BIT_MARK);
space(0); 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) { void IRsend::mark(int time) {
// Sends an IR mark for the specified number of microseconds. // Sends an IR mark for the specified number of microseconds.
// The mark output is modulated at the PWM frequency. // The mark output is modulated at the PWM frequency.
@@ -439,6 +465,12 @@ int IRrecv::decode(decode_results *results) {
if (decodeJVC(results)) { if (decodeJVC(results)) {
return DECODED; return DECODED;
} }
#ifdef DEBUG
Serial.println("Attempting SAMSUNG decode");
#endif
if (decodeSAMSUNG(results)) {
return DECODED;
}
// decodeHash returns a hash on any input. // decodeHash returns a hash on any input.
// Thus, it needs to be last in the list. // Thus, it needs to be last in the list.
// If you add any decodes, add them before this. // If you add any decodes, add them before this.
@@ -896,6 +928,55 @@ long IRrecv::decodeJVC(decode_results *results) {
return DECODED; 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. * hashdecode - decode an arbitrary IR code.
* Instead of decoding using a standard encoding scheme * Instead of decoding using a standard encoding scheme

View File

@@ -45,6 +45,7 @@ public:
#define JVC 8 #define JVC 8
#define SANYO 9 #define SANYO 9
#define MITSUBISHI 10 #define MITSUBISHI 10
#define SAMSUNG 11
#define UNKNOWN -1 #define UNKNOWN -1
// Decoded value for NEC when a repeat code is received // Decoded value for NEC when a repeat code is received
@@ -70,6 +71,7 @@ private:
long decodeRC6(decode_results *results); long decodeRC6(decode_results *results);
long decodePanasonic(decode_results *results); long decodePanasonic(decode_results *results);
long decodeJVC(decode_results *results); long decodeJVC(decode_results *results);
long decodeSAMSUNG(decode_results *results);
long decodeHash(decode_results *results); long decodeHash(decode_results *results);
int compare(unsigned int oldval, unsigned int newval); int compare(unsigned int oldval, unsigned int newval);
@@ -100,6 +102,7 @@ public:
void sendPanasonic(unsigned int address, unsigned long data); 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 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: // private:
void sendSAMSUNG(unsigned long data, int nbits);
void enableIROut(int khz); void enableIROut(int khz);
VIRTUAL void mark(int usec); VIRTUAL void mark(int usec);
VIRTUAL void space(int usec); VIRTUAL void space(int usec);

View File

@@ -61,9 +61,6 @@
#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) #elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
#define IR_USE_TIMER1 // tx = pin 9 #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 // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
#else #else
//#define IR_USE_TIMER1 // tx = pin 9 //#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 // Pulse parms are *50-100 for the Mark and *50+100 for the space
// First MARK is the one after the long gap // First MARK is the one after the long gap
// pulse parameters in usec // pulse parameters in usec
#define NEC_HDR_MARK 9000 #define NEC_HDR_MARK 9000
#define NEC_HDR_SPACE 4500 #define NEC_HDR_SPACE 4500
#define NEC_BIT_MARK 560 #define NEC_BIT_MARK 560
#define NEC_ONE_SPACE 1600 #define NEC_ONE_SPACE 1600
#define NEC_ZERO_SPACE 560 #define NEC_ZERO_SPACE 560
#define NEC_RPT_SPACE 2250 #define NEC_RPT_SPACE 2250
#define SONY_HDR_MARK 2400 #define SONY_HDR_MARK 2400
#define SONY_HDR_SPACE 600 #define SONY_HDR_SPACE 600
#define SONY_ONE_MARK 1200 #define SONY_ONE_MARK 1200
#define SONY_ZERO_MARK 600 #define SONY_ZERO_MARK 600
#define SONY_RPT_LENGTH 45000 #define SONY_RPT_LENGTH 45000
#define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround #define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround
// SA 8650B // SA 8650B
#define SANYO_HDR_MARK 3500 // seen range 3500 #define SANYO_HDR_MARK 3500 // seen range 3500
#define SANYO_HDR_SPACE 950 // seen 950 #define SANYO_HDR_SPACE 950 // seen 950
#define SANYO_ONE_MARK 2400 // seen 2400 #define SANYO_ONE_MARK 2400 // seen 2400
#define SANYO_ZERO_MARK 700 // seen 700 #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_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
#define SANYO_RPT_LENGTH 45000 #define SANYO_RPT_LENGTH 45000
@@ -118,21 +115,21 @@
// Mitsubishi RM 75501 // 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 // 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_MARK 250 // seen range 3500
#define MITSUBISHI_HDR_SPACE 350 // 7*50+100 #define MITSUBISHI_HDR_SPACE 350 // 7*50+100
#define MITSUBISHI_ONE_MARK 1950 // 41*50-100 #define MITSUBISHI_ONE_MARK 1950 // 41*50-100
#define MITSUBISHI_ZERO_MARK 750 // 17*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_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
// #define MITSUBISHI_RPT_LENGTH 45000 // #define MITSUBISHI_RPT_LENGTH 45000
#define RC5_T1 889 #define RC5_T1 889
#define RC5_RPT_LENGTH 46000 #define RC5_RPT_LENGTH 46000
#define RC6_HDR_MARK 2666 #define RC6_HDR_MARK 2666
#define RC6_HDR_SPACE 889 #define RC6_HDR_SPACE 889
#define RC6_T1 444 #define RC6_T1 444
#define RC6_RPT_LENGTH 46000 #define RC6_RPT_LENGTH 46000
#define SHARP_BIT_MARK 245 #define SHARP_BIT_MARK 245
#define SHARP_ONE_SPACE 1805 #define SHARP_ONE_SPACE 1805
@@ -162,6 +159,14 @@
#define JVC_ZERO_SPACE 550 #define JVC_ZERO_SPACE 550
#define JVC_RPT_LENGTH 60000 #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 SHARP_BITS 15
#define DISH_BITS 16 #define DISH_BITS 16
@@ -175,13 +180,6 @@
#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK)) #define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1)) #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 // receiver states
#define STATE_IDLE 2 #define STATE_IDLE 2
#define STATE_MARK 3 #define STATE_MARK 3
@@ -216,6 +214,7 @@ extern volatile irparams_t irparams;
#define MIN_RC6_SAMPLES 1 #define MIN_RC6_SAMPLES 1
#define PANASONIC_BITS 48 #define PANASONIC_BITS 48
#define JVC_BITS 16 #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_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
#define TIMER_DISABLE_INTR (TIMSK1 = 0) #define TIMER_DISABLE_INTR (TIMSK1 = 0)
#endif #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) ({ \ #define TIMER_CONFIG_KHZ(val) ({ \
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
TCCR1A = _BV(WGM11); \ TCCR1A = _BV(WGM11); \
@@ -300,8 +293,6 @@ extern volatile irparams_t irparams;
#define TIMER_PWM_PIN 11 /* Arduino Mega */ #define TIMER_PWM_PIN 11 /* Arduino Mega */
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
#define TIMER_PWM_PIN 13 /* Sanguino */ #define TIMER_PWM_PIN 13 /* Sanguino */
#elif defined(__AVR_ATtinyX4__)
#define TIMER_PWM_PIN 6 /* ATTiny84 */
#else #else
#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */ #define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
#endif #endif