Infrared remote library for Arduino: send and receive infrared signals with multiple protocols Port from Arduino-IRremote https://github.com/z3t0/Arduino-IRremote

Dependents:   Lilnija_29012017 NucleoF042K6_IRReceiver

Committer:
yuhki50
Date:
Thu Mar 10 15:39:34 2016 +0000
Revision:
7:c82a0d54a024
Parent:
3:17440cf7ab90
change USECPERTICK

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yuhki50 0:70c8e56bac45 1 //******************************************************************************
yuhki50 0:70c8e56bac45 2 // IRremote
yuhki50 0:70c8e56bac45 3 // Version 2.0.1 June, 2015
yuhki50 0:70c8e56bac45 4 // Copyright 2009 Ken Shirriff
yuhki50 0:70c8e56bac45 5 // For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
yuhki50 0:70c8e56bac45 6 //
yuhki50 0:70c8e56bac45 7 // Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
yuhki50 0:70c8e56bac45 8 // Modified by Mitra Ardron <mitra@mitra.biz>
yuhki50 0:70c8e56bac45 9 // Added Sanyo and Mitsubishi controllers
yuhki50 0:70c8e56bac45 10 // Modified Sony to spot the repeat codes that some Sony's send
yuhki50 0:70c8e56bac45 11 //
yuhki50 0:70c8e56bac45 12 // Interrupt code based on NECIRrcv by Joe Knapp
yuhki50 0:70c8e56bac45 13 // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
yuhki50 0:70c8e56bac45 14 // Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
yuhki50 0:70c8e56bac45 15 //
yuhki50 0:70c8e56bac45 16 // JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
yuhki50 0:70c8e56bac45 17 // LG added by Darryl Smith (based on the JVC protocol)
yuhki50 0:70c8e56bac45 18 // Whynter A/C ARC-110WD added by Francesco Meschia
yuhki50 0:70c8e56bac45 19 //******************************************************************************
yuhki50 0:70c8e56bac45 20
yuhki50 0:70c8e56bac45 21 // Defining IR_GLOBAL here allows us to declare the instantiation of global variables
yuhki50 0:70c8e56bac45 22 #define IR_GLOBAL
yuhki50 0:70c8e56bac45 23 # include "IRremote.h"
yuhki50 0:70c8e56bac45 24 # include "IRremoteInt.h"
yuhki50 0:70c8e56bac45 25 #undef IR_GLOBAL
yuhki50 0:70c8e56bac45 26
yuhki50 0:70c8e56bac45 27 //+=============================================================================
yuhki50 0:70c8e56bac45 28 // The match functions were (apparently) originally MACROs to improve code speed
yuhki50 0:70c8e56bac45 29 // (although this would have bloated the code) hence the names being CAPS
yuhki50 0:70c8e56bac45 30 // A later release implemented debug output and so they needed to be converted
yuhki50 0:70c8e56bac45 31 // to functions.
yuhki50 0:70c8e56bac45 32 // I tried to implement a dual-compile mode (DEBUG/non-DEBUG) but for some
yuhki50 0:70c8e56bac45 33 // reason, no matter what I did I could not get them to function as macros again.
yuhki50 0:70c8e56bac45 34 // I have found a *lot* of bugs in the Arduino compiler over the last few weeks,
yuhki50 0:70c8e56bac45 35 // and I am currently assuming that one of these bugs is my problem.
yuhki50 0:70c8e56bac45 36 // I may revisit this code at a later date and look at the assembler produced
yuhki50 0:70c8e56bac45 37 // in a hope of finding out what is going on, but for now they will remain as
yuhki50 0:70c8e56bac45 38 // functions even in non-DEBUG mode
yuhki50 0:70c8e56bac45 39 //
yuhki50 0:70c8e56bac45 40 int MATCH (int measured, int desired)
yuhki50 0:70c8e56bac45 41 {
yuhki50 0:70c8e56bac45 42 DBG_PRINT("Testing: ");
yuhki50 0:70c8e56bac45 43 DBG_PRINT(TICKS_LOW(desired), DEC);
yuhki50 0:70c8e56bac45 44 DBG_PRINT(" <= ");
yuhki50 0:70c8e56bac45 45 DBG_PRINT(measured, DEC);
yuhki50 0:70c8e56bac45 46 DBG_PRINT(" <= ");
yuhki50 0:70c8e56bac45 47 DBG_PRINTLN(TICKS_HIGH(desired), DEC);
yuhki50 0:70c8e56bac45 48
yuhki50 0:70c8e56bac45 49 return ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired)));
yuhki50 0:70c8e56bac45 50 }
yuhki50 0:70c8e56bac45 51
yuhki50 0:70c8e56bac45 52 //+========================================================
yuhki50 0:70c8e56bac45 53 // Due to sensor lag, when received, Marks tend to be 100us too long
yuhki50 0:70c8e56bac45 54 //
yuhki50 0:70c8e56bac45 55 int MATCH_MARK (int measured_ticks, int desired_us)
yuhki50 0:70c8e56bac45 56 {
yuhki50 0:70c8e56bac45 57 DBG_PRINT("Testing mark ");
yuhki50 0:70c8e56bac45 58 DBG_PRINT(measured_ticks * USECPERTICK, DEC);
yuhki50 0:70c8e56bac45 59 DBG_PRINT(" vs ");
yuhki50 0:70c8e56bac45 60 DBG_PRINT(desired_us, DEC);
yuhki50 0:70c8e56bac45 61 DBG_PRINT(": ");
yuhki50 0:70c8e56bac45 62 DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS), DEC);
yuhki50 0:70c8e56bac45 63 DBG_PRINT(" <= ");
yuhki50 0:70c8e56bac45 64 DBG_PRINT(measured_ticks, DEC);
yuhki50 0:70c8e56bac45 65 DBG_PRINT(" <= ");
yuhki50 0:70c8e56bac45 66 DBG_PRINTLN(TICKS_HIGH(desired_us + MARK_EXCESS), DEC);
yuhki50 0:70c8e56bac45 67
yuhki50 0:70c8e56bac45 68 return ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS))
yuhki50 0:70c8e56bac45 69 && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS)));
yuhki50 0:70c8e56bac45 70 }
yuhki50 0:70c8e56bac45 71
yuhki50 0:70c8e56bac45 72 //+========================================================
yuhki50 0:70c8e56bac45 73 // Due to sensor lag, when received, Spaces tend to be 100us too short
yuhki50 0:70c8e56bac45 74 //
yuhki50 0:70c8e56bac45 75 int MATCH_SPACE (int measured_ticks, int desired_us)
yuhki50 0:70c8e56bac45 76 {
yuhki50 0:70c8e56bac45 77 DBG_PRINT("Testing space ");
yuhki50 0:70c8e56bac45 78 DBG_PRINT(measured_ticks * USECPERTICK, DEC);
yuhki50 0:70c8e56bac45 79 DBG_PRINT(" vs ");
yuhki50 0:70c8e56bac45 80 DBG_PRINT(desired_us, DEC);
yuhki50 0:70c8e56bac45 81 DBG_PRINT(": ");
yuhki50 0:70c8e56bac45 82 DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS), DEC);
yuhki50 0:70c8e56bac45 83 DBG_PRINT(" <= ");
yuhki50 0:70c8e56bac45 84 DBG_PRINT(measured_ticks, DEC);
yuhki50 0:70c8e56bac45 85 DBG_PRINT(" <= ");
yuhki50 0:70c8e56bac45 86 DBG_PRINTLN(TICKS_HIGH(desired_us - MARK_EXCESS), DEC);
yuhki50 0:70c8e56bac45 87
yuhki50 0:70c8e56bac45 88 return ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS))
yuhki50 0:70c8e56bac45 89 && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS)));
yuhki50 0:70c8e56bac45 90 }
yuhki50 0:70c8e56bac45 91
yuhki50 0:70c8e56bac45 92 //+=============================================================================
yuhki50 0:70c8e56bac45 93 // Interrupt Service Routine - Fires every 50uS
yuhki50 0:70c8e56bac45 94 // TIMER2 interrupt code to collect raw data.
yuhki50 0:70c8e56bac45 95 // Widths of alternating SPACE, MARK are recorded in rawbuf.
yuhki50 0:70c8e56bac45 96 // Recorded in ticks of 50uS [microseconds, 0.000050 seconds]
yuhki50 0:70c8e56bac45 97 // 'rawlen' counts the number of entries recorded so far.
yuhki50 0:70c8e56bac45 98 // First entry is the SPACE between transmissions.
yuhki50 0:70c8e56bac45 99 // As soon as a the first [SPACE] entry gets long:
yuhki50 0:70c8e56bac45 100 // Ready is set; State switches to IDLE; Timing of SPACE continues.
yuhki50 0:70c8e56bac45 101 // As soon as first MARK arrives:
yuhki50 0:70c8e56bac45 102 // Gap width is recorded; Ready is cleared; New logging starts
yuhki50 0:70c8e56bac45 103 //
yuhki50 3:17440cf7ab90 104 void IRrecv::timer_isr ()
yuhki50 0:70c8e56bac45 105 {
yuhki50 0:70c8e56bac45 106 // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on]
yuhki50 0:70c8e56bac45 107 // digitalRead() is very slow. Optimisation is possible, but makes the code unportable
yuhki50 3:17440cf7ab90 108 uint8_t irdata = _recvpin.read();
yuhki50 0:70c8e56bac45 109
yuhki50 0:70c8e56bac45 110 irparams.timer++; // One more 50uS tick
yuhki50 0:70c8e56bac45 111 if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_OVERFLOW ; // Buffer overflow
yuhki50 0:70c8e56bac45 112
yuhki50 0:70c8e56bac45 113 switch(irparams.rcvstate) {
yuhki50 0:70c8e56bac45 114 //......................................................................
yuhki50 0:70c8e56bac45 115 case STATE_IDLE: // In the middle of a gap
yuhki50 0:70c8e56bac45 116 if (irdata == MARK) {
yuhki50 0:70c8e56bac45 117 if (irparams.timer < GAP_TICKS) { // Not big enough to be a gap.
yuhki50 0:70c8e56bac45 118 irparams.timer = 0;
yuhki50 0:70c8e56bac45 119
yuhki50 0:70c8e56bac45 120 } else {
yuhki50 0:70c8e56bac45 121 // Gap just ended; Record duration; Start recording transmission
yuhki50 0:70c8e56bac45 122 irparams.overflow = false;
yuhki50 0:70c8e56bac45 123 irparams.rawlen = 0;
yuhki50 0:70c8e56bac45 124 irparams.rawbuf[irparams.rawlen++] = irparams.timer;
yuhki50 0:70c8e56bac45 125 irparams.timer = 0;
yuhki50 0:70c8e56bac45 126 irparams.rcvstate = STATE_MARK;
yuhki50 0:70c8e56bac45 127 }
yuhki50 0:70c8e56bac45 128 }
yuhki50 0:70c8e56bac45 129 break;
yuhki50 0:70c8e56bac45 130 //......................................................................
yuhki50 0:70c8e56bac45 131 case STATE_MARK: // Timing Mark
yuhki50 0:70c8e56bac45 132 if (irdata == SPACE) { // Mark ended; Record time
yuhki50 0:70c8e56bac45 133 irparams.rawbuf[irparams.rawlen++] = irparams.timer;
yuhki50 0:70c8e56bac45 134 irparams.timer = 0;
yuhki50 0:70c8e56bac45 135 irparams.rcvstate = STATE_SPACE;
yuhki50 0:70c8e56bac45 136 }
yuhki50 0:70c8e56bac45 137 break;
yuhki50 0:70c8e56bac45 138 //......................................................................
yuhki50 0:70c8e56bac45 139 case STATE_SPACE: // Timing Space
yuhki50 0:70c8e56bac45 140 if (irdata == MARK) { // Space just ended; Record time
yuhki50 0:70c8e56bac45 141 irparams.rawbuf[irparams.rawlen++] = irparams.timer;
yuhki50 0:70c8e56bac45 142 irparams.timer = 0;
yuhki50 0:70c8e56bac45 143 irparams.rcvstate = STATE_MARK;
yuhki50 0:70c8e56bac45 144
yuhki50 0:70c8e56bac45 145 } else if (irparams.timer > GAP_TICKS) { // Space
yuhki50 0:70c8e56bac45 146 // A long Space, indicates gap between codes
yuhki50 0:70c8e56bac45 147 // Flag the current code as ready for processing
yuhki50 0:70c8e56bac45 148 // Switch to STOP
yuhki50 0:70c8e56bac45 149 // Don't reset timer; keep counting Space width
yuhki50 0:70c8e56bac45 150 irparams.rcvstate = STATE_STOP;
yuhki50 0:70c8e56bac45 151 }
yuhki50 0:70c8e56bac45 152 break;
yuhki50 0:70c8e56bac45 153 //......................................................................
yuhki50 0:70c8e56bac45 154 case STATE_STOP: // Waiting; Measuring Gap
yuhki50 0:70c8e56bac45 155 if (irdata == MARK) irparams.timer = 0 ; // Reset gap timer
yuhki50 0:70c8e56bac45 156 break;
yuhki50 0:70c8e56bac45 157 //......................................................................
yuhki50 0:70c8e56bac45 158 case STATE_OVERFLOW: // Flag up a read overflow; Stop the State Machine
yuhki50 0:70c8e56bac45 159 irparams.overflow = true;
yuhki50 0:70c8e56bac45 160 irparams.rcvstate = STATE_STOP;
yuhki50 0:70c8e56bac45 161 break;
yuhki50 0:70c8e56bac45 162 }
yuhki50 0:70c8e56bac45 163 }