Infrared remote library for Arduino: send and receive infrared signals with multiple protocols Port from Arduino-IRremote https://github.com/z3t0/Arduino-IRremote
IRremote.cpp
00001 //****************************************************************************** 00002 // IRremote 00003 // Version 2.0.1 June, 2015 00004 // Copyright 2009 Ken Shirriff 00005 // For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html 00006 // 00007 // Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers 00008 // Modified by Mitra Ardron <mitra@mitra.biz> 00009 // Added Sanyo and Mitsubishi controllers 00010 // Modified Sony to spot the repeat codes that some Sony's send 00011 // 00012 // Interrupt code based on NECIRrcv by Joe Knapp 00013 // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 00014 // Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ 00015 // 00016 // JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) 00017 // LG added by Darryl Smith (based on the JVC protocol) 00018 // Whynter A/C ARC-110WD added by Francesco Meschia 00019 //****************************************************************************** 00020 00021 // Defining IR_GLOBAL here allows us to declare the instantiation of global variables 00022 #define IR_GLOBAL 00023 # include "IRremote.h" 00024 # include "IRremoteInt.h" 00025 #undef IR_GLOBAL 00026 00027 //+============================================================================= 00028 // The match functions were (apparently) originally MACROs to improve code speed 00029 // (although this would have bloated the code) hence the names being CAPS 00030 // A later release implemented debug output and so they needed to be converted 00031 // to functions. 00032 // I tried to implement a dual-compile mode (DEBUG/non-DEBUG) but for some 00033 // reason, no matter what I did I could not get them to function as macros again. 00034 // I have found a *lot* of bugs in the Arduino compiler over the last few weeks, 00035 // and I am currently assuming that one of these bugs is my problem. 00036 // I may revisit this code at a later date and look at the assembler produced 00037 // in a hope of finding out what is going on, but for now they will remain as 00038 // functions even in non-DEBUG mode 00039 // 00040 int MATCH (int measured, int desired) 00041 { 00042 DBG_PRINT("Testing: "); 00043 DBG_PRINT(TICKS_LOW(desired), DEC); 00044 DBG_PRINT(" <= "); 00045 DBG_PRINT(measured, DEC); 00046 DBG_PRINT(" <= "); 00047 DBG_PRINTLN(TICKS_HIGH(desired), DEC); 00048 00049 return ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); 00050 } 00051 00052 //+======================================================== 00053 // Due to sensor lag, when received, Marks tend to be 100us too long 00054 // 00055 int MATCH_MARK (int measured_ticks, int desired_us) 00056 { 00057 DBG_PRINT("Testing mark "); 00058 DBG_PRINT(measured_ticks * USECPERTICK, DEC); 00059 DBG_PRINT(" vs "); 00060 DBG_PRINT(desired_us, DEC); 00061 DBG_PRINT(": "); 00062 DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS), DEC); 00063 DBG_PRINT(" <= "); 00064 DBG_PRINT(measured_ticks, DEC); 00065 DBG_PRINT(" <= "); 00066 DBG_PRINTLN(TICKS_HIGH(desired_us + MARK_EXCESS), DEC); 00067 00068 return ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) 00069 && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); 00070 } 00071 00072 //+======================================================== 00073 // Due to sensor lag, when received, Spaces tend to be 100us too short 00074 // 00075 int MATCH_SPACE (int measured_ticks, int desired_us) 00076 { 00077 DBG_PRINT("Testing space "); 00078 DBG_PRINT(measured_ticks * USECPERTICK, DEC); 00079 DBG_PRINT(" vs "); 00080 DBG_PRINT(desired_us, DEC); 00081 DBG_PRINT(": "); 00082 DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS), DEC); 00083 DBG_PRINT(" <= "); 00084 DBG_PRINT(measured_ticks, DEC); 00085 DBG_PRINT(" <= "); 00086 DBG_PRINTLN(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); 00087 00088 return ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) 00089 && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); 00090 } 00091 00092 //+============================================================================= 00093 // Interrupt Service Routine - Fires every 50uS 00094 // TIMER2 interrupt code to collect raw data. 00095 // Widths of alternating SPACE, MARK are recorded in rawbuf. 00096 // Recorded in ticks of 50uS [microseconds, 0.000050 seconds] 00097 // 'rawlen' counts the number of entries recorded so far. 00098 // First entry is the SPACE between transmissions. 00099 // As soon as a the first [SPACE] entry gets long: 00100 // Ready is set; State switches to IDLE; Timing of SPACE continues. 00101 // As soon as first MARK arrives: 00102 // Gap width is recorded; Ready is cleared; New logging starts 00103 // 00104 void IRrecv::timer_isr () 00105 { 00106 // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on] 00107 // digitalRead() is very slow. Optimisation is possible, but makes the code unportable 00108 uint8_t irdata = _recvpin.read(); 00109 00110 irparams.timer++; // One more 50uS tick 00111 if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_OVERFLOW ; // Buffer overflow 00112 00113 switch(irparams.rcvstate) { 00114 //...................................................................... 00115 case STATE_IDLE: // In the middle of a gap 00116 if (irdata == MARK) { 00117 if (irparams.timer < GAP_TICKS) { // Not big enough to be a gap. 00118 irparams.timer = 0; 00119 00120 } else { 00121 // Gap just ended; Record duration; Start recording transmission 00122 irparams.overflow = false; 00123 irparams.rawlen = 0; 00124 irparams.rawbuf[irparams.rawlen++] = irparams.timer; 00125 irparams.timer = 0; 00126 irparams.rcvstate = STATE_MARK; 00127 } 00128 } 00129 break; 00130 //...................................................................... 00131 case STATE_MARK: // Timing Mark 00132 if (irdata == SPACE) { // Mark ended; Record time 00133 irparams.rawbuf[irparams.rawlen++] = irparams.timer; 00134 irparams.timer = 0; 00135 irparams.rcvstate = STATE_SPACE; 00136 } 00137 break; 00138 //...................................................................... 00139 case STATE_SPACE: // Timing Space 00140 if (irdata == MARK) { // Space just ended; Record time 00141 irparams.rawbuf[irparams.rawlen++] = irparams.timer; 00142 irparams.timer = 0; 00143 irparams.rcvstate = STATE_MARK; 00144 00145 } else if (irparams.timer > GAP_TICKS) { // Space 00146 // A long Space, indicates gap between codes 00147 // Flag the current code as ready for processing 00148 // Switch to STOP 00149 // Don't reset timer; keep counting Space width 00150 irparams.rcvstate = STATE_STOP; 00151 } 00152 break; 00153 //...................................................................... 00154 case STATE_STOP: // Waiting; Measuring Gap 00155 if (irdata == MARK) irparams.timer = 0 ; // Reset gap timer 00156 break; 00157 //...................................................................... 00158 case STATE_OVERFLOW: // Flag up a read overflow; Stop the State Machine 00159 irparams.overflow = true; 00160 irparams.rcvstate = STATE_STOP; 00161 break; 00162 } 00163 }
Generated on Fri Jul 15 2022 02:03:08 by 1.7.2