Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
IRReceiver.h
00001 // IR Remote Receiver 00002 // 00003 // This is a multi-protocol receiver for IR remote control signals. The 00004 // IR signals are physically received through an external sensor. Our 00005 // reference device is the TSOP384xx, but most other IR remote sensors 00006 // are similar in design and will proably work. We have two main requirements 00007 // for the sensor: first, it has to demodulate the IR carrier wave; second, 00008 // it has to present a single-wire digital signal representing the demodulated 00009 // IR status. We assume active low signaling, where 0V on the signal line 00010 // represents "IR ON" and Vcc represents "IR OFF". It would be fairly easy 00011 // to adapt the code to the opposite signaling sense, but I haven't bothered 00012 // to parameterize this because I haven't seen any active-high sensors. The 00013 // sensor also obviously has to be electrically compatible with the KL25Z, 00014 // which mostly means that it runs on a 3.3V supply. If your sensor uses 00015 // a different supply voltage, it might still be workable, but you might 00016 // need to interpose a voltage level converter on the logic input to make 00017 // sure that the KL25Z GPIO pin doesn't go above 3.3V, as these pins aren't 00018 // tolerant of higher voltages. 00019 // 00020 // How to wire the sensor 00021 // 00022 // To physically wire the sensor, you just need to connect the sensor's 00023 // Vs and GND pins to the the 3.3V out (P3V3) and GND on the KL25Z, 00024 // respectively, and connect its "OUT" or "data" pin (pin 1 on a TSOP384xx) 00025 // to a free, interrupt-capable GPIO on the KL25Z. On the KL25Z, all PTAxx 00026 // and PTDxx ports are interrupt-capable (and conversely, PTBxx, PTCxx, and 00027 // PTExx ports aren't, so you can't use one of those). You should check the 00028 // data sheet for the sensor you're using to see if any other external 00029 // components are required; e.g., the TSOP384xx data sheet recommends a 00030 // capacitor and resistor for ESD protection and power supply conditioning. 00031 // The data sheet will include a diagram showing the suggested application 00032 // wiring if there are any special considerations like that. Note that the 00033 // TSOP384xx data sheet doesn't specify exact values for the resistor and 00034 // capacitor, so I'll mention what I'm using in my test setup: 220 ohms for 00035 // the resistor, 150nF for the capacitor. 00036 // 00037 // How to use it in your application 00038 // 00039 // To use the receiver in an application, first create an IRReceiver object, 00040 // telling it which pin to use as the sensor input, and how big you want the 00041 // raw sample buffer to be. The raw buffer needs to be big enough to hold 00042 // samples that arrive during each iteration of your main loop, so you need 00043 // approximately one buffer entry per 250us of your main loop's maximum 00044 // iteration time. If RAM isn't tight in your app, just pick a fairly large 00045 // size (maybe 200 entries); if RAM is tight, figure your worst-case main loop 00046 // time, divide by 250us, and add maybe 25% or 50% padding. Once you create 00047 // the receiver object, call enable() to enable reception. You can do this 00048 // once at the outset, or you can selectively enable() and disable() it at 00049 // any time if you only need reception at specific times. Reception takes 00050 // a small amount of CPU time (in interrupt mode) whenever signals arrive, 00051 // so if you have a time-critical task to do at a time when reception isn't 00052 // useful, you can turn it off to avoid any latency from IR interrupts. 00053 // 00054 // IRReceiver *rx = new IRReceiver(PTA13, 32); 00055 // rx->enable(); 00056 // 00057 // If you're using the companion transmitter class in the same application 00058 // to create a device that's both an IR transmitter and receiver, you might 00059 // want to tell the receiver about the transmitter, via setTransmitter(). 00060 // This causes the receiver to ignore incoming signals whenever the 00061 // transmitter is sending, so that you don't receive your own transmissions. 00062 // This isn't necessary if the receiver is positioned so that it can't see 00063 // the transmitter's signals. 00064 // 00065 // rx->setTransmitter(tx); 00066 // 00067 // Once you have a receiver set up and enabled, you need to call its process() 00068 // method on each iteration of your main loop. This method takes all of the 00069 // signals that have been received since the last call and runs them through 00070 // the protocol decoders. To minimize time spent in interrupt handlers, the 00071 // interrupt handlers merely queue the messages internally; this makes them 00072 // return extremely quickly, so that they don't add any significant latency 00073 // for other hardware or timer interrupts your application might use. 00074 // 00075 // rx->process(); 00076 // 00077 // Also in your main loop, read incoming IR remote codes by calling 00078 // readCommand() on the receiver. If a command is available, this will read 00079 // it into an IRCommand object, which tells you the protocol the sender used 00080 // (see IRProtocolID.h), and provides a "universal" representation of the 00081 // command. The universal representation is protocol-specific mapping of 00082 // the raw data bits to an integer value. We try to do this in a way that's 00083 // most useful per protocol, with two main goals in mind. First, if there 00084 // are any internal bits that are more structural than meaningful, such as 00085 // checksums or other integrity checks, we generally remove them. Second, 00086 // if there are published tables of codes from a manufacturer, we try to 00087 // match the format used there, to make it easier to verify that codes are 00088 // as expected and to make it easier to construct apps around specific types 00089 // of remotes. 00090 // 00091 // IRCommand cmd; 00092 // while (rx->readCommand(cmd)) { process the command; } 00093 // 00094 // You can also optionally read the raw incoming data, by calling processOne() 00095 // instead of process(). processOne() runs a reading through the protocol 00096 // decoders but also hands it back to you. Raw samples are simply "IR ON" 00097 // and "IR OFF" signals with the time the IR was continuously on or off. 00098 // The raw samples are useful if you want to build something like a repeater 00099 // that only has to replicate the physical IR signals without regard to the 00100 // underlying data bits. Raw signals are obviously also very useful if you 00101 // want to analyze an unknown protocol and figure out how to write a new 00102 // encoder/decoder for it. One thing that raw signals aren't great for, 00103 // somewhat counterintuitively, is for building a learning remote. Many of 00104 // the protocols have special ways of handling repeated codes (e.g., when 00105 // holding down a key) that make verbatim repetition of a signal problematic 00106 // for learning remote use. If you just repeat a raw code, the receiver 00107 // might be confused into thinking that one key press looks like several 00108 // key presses, or vice versa. It's better when possible to decode a signal 00109 // into a recognized protocol, store the decoded bit data rather than the 00110 // raw signals as the "learned" code, and then reconstruct the appropriate 00111 // signal for transmission by re-encoding the learned bit code using the 00112 // protocol's known structure. 00113 // 00114 // 00115 // Internal architecture 00116 // 00117 // The IRReceiver object is simply a coordinator that manages the sensor 00118 // hardware interface, reads the raw signals from the sensor, and passes 00119 // the raw signals to the protocol objects for decoding. For each protocol 00120 // we recognize, we define a specialized handler class for the protocol. 00121 // Each protocol handler implements a state machine for decoding signals 00122 // using its protocol. When IRReceiver reads a raw signal, it simply passes 00123 // it to each of the protocol handlers in turn. They all operate as 00124 // independent state machines, so in effect we have specialized receivers 00125 // for all of the protocols operating in parallel, all eavesdropping on the 00126 // same incoming stream of signals. When one of the protocol handlers 00127 // successfully decodes a complete "command" (a key press on a remote, in 00128 // most cases), it adds the command to our queue, using a universal 00129 // representation that we define. Clients can then read the incoming 00130 // commands from the queue without worrying about the raw signal details. 00131 // 00132 // It might sound chaotic to have all of these different protocol decoders 00133 // working on the same data at the same time, but in practice the various 00134 // protocols have enough internal structure that only the "right" handler 00135 // will be able to do anything with a given signal, and the rest will just 00136 // ignore it, and bide their time until something shows up that they can make 00137 // sense of. It might also sound like a lot of overhead, but in practice 00138 // it's very lightweight: it takes about 4% CPU to service the decoding 00139 // process while a signal is actually coming in, and essentially 0% when 00140 // the IR airwaves are silent. What's more, that 4% CPU time is all in 00141 // application context, not in interrupt context, so it doesn't contribute 00142 // any latency to any other hardware interrupts you need to handle in your 00143 // application. 00144 // 00145 // The individual protocol state machines are all very simple, typically 00146 // doing just a few integer compares on the incoming timing data per signal. 00147 // They also require very little state, usually on the order of a few 'int's 00148 // per decoder, which translates to a small RAM footprint. The decoders 00149 // operate incrementally and decode in near real time, so decoded commands 00150 // appear essentially at the same time that their signals finish. 00151 // 00152 // Note that, unlike some other MCU IR libraries, we don't any have sort 00153 // of global receiver state. In particular, we don't try to guess about 00154 // message boundaries globally. All of the boundary detection and protocol 00155 // state is in the individual protocol decoders. That eliminates the need 00156 // for heuristics or special cases to guess about what "usually" indicates 00157 // a message boundary across all protocols. There are enough special cases 00158 // to make such guesses problematic, which becomes apparent if you look at 00159 // the code in libraries that work that way. Since we don't need to know 00160 // about message boundaries globally, we don't need to make such guesses or 00161 // apply such special cases. We simply deal in the raw pulses and let 00162 // each decoder separately judge for itself where its own message boundaries 00163 // are. This might seem odd, because the implication is that one decoder 00164 // might think we're in the middle of a message while another decoder 00165 // thinks we're on a boundary. But that's just fine, and it's exactly 00166 // why we shouldn't be making those judgments globally: if two protocols 00167 // have contradictory rules like that, the way to reconcile it is to accept 00168 // that there really is no correct global judgment, and leave it to the 00169 // decoders to track their own states independently. 00170 // 00171 // We receive signals from the sensor via interrupts on the input GPIO pin. 00172 // This allows for the most accurate timing possible, which is important 00173 // because IR coding is entirely in the signal timing. Interrupts gives us 00174 // much more accurate timing than polling would for obvious reasons. As 00175 // mentioned above, though, we try to minimize the time we spend in IRQ 00176 // context, since time spent in one interrupt handler translates to added 00177 // latency for any other interrupts that occur at the same time. To 00178 // accomplish this, the interrupt handlers don't do any decoding at all. 00179 // They simply add the incoming signal data to an internal queue and then 00180 // return. We do the decoding work back in application context, by having 00181 // the main loop call our process() routine periodically. This takes signal 00182 // readings off of the queue and runs them through the decoders. This 00183 // introduces a small amount of lag time between physically receiving a 00184 // signal and decoding it, but the lag time is only on the order of the 00185 // main loop run time. In most MCU applications this is a very short 00186 // time, perhaps only microseconds or perhaps as long as a few millseconds. 00187 // But in any case it's almost always so short that a user can't perceive 00188 // the delay, so for all practical purposes decoding is done in real time. 00189 // 00190 // 00191 // How IR remotes work in general 00192 // 00193 // IR remote controls work by transmitting timed pulses of infrared light. 00194 // These pulses are modulated in two ways: first, with a "carrier", which 00195 // is a PWM signal operating at a fixed, relatively high frequency; and 00196 // second, with a lower frequency data signal superimposed on the PWM 00197 // signal. (And I suppose you could say there's a third layer of 00198 // modulation in the IR light itself, since that's an electromagnetic 00199 // wave operating at an even higher frequency of around 300 THz.) 00200 // 00201 // Carrier: The PWM carrier uses a fixed frequency, usually around 40kHz. 00202 // The carrier doesn't encode any data, since it's just constant fixed-length 00203 // pulses. Its function, rather, is to provide a regular oscillating signal 00204 // that receivers can use to distinguish data signals from ambient light. 00205 // This is necessary because the IR light wavelengths are also contained 00206 // in sunlight and ordinary household lighting. (Fluourescent lights even 00207 // have their own characteristic oscillating frequencies in the IR band, so 00208 // the receiver not only has to distinguish the signal from constant 00209 // amgient light levels but also from other types of oscillating light 00210 // levels. The PWM carrier frequencies used in remotes are chosen based 00211 // on the practical need to distinguish remote control signals from the 00212 // common household interference sources.) Receivers can separate the 00213 // an oscillating PWM signal at a particular frequency from other signals 00214 // through a process known as demodulation, which is the same mechanism 00215 // that radio receivers use to pluck AM or FM signals from the jumble of 00216 // background noise in the radio spectrum. 00217 // 00218 // For our purposes, we don't worry about demodulation in the software, 00219 // since the sensor hardware does that part of the job. Each type of sensor 00220 // is designed to demodulate a particular carrier frequency, so you should 00221 // choose a sensor based on the types of remotes you plan to use it with. 00222 // Most CE manufacturers have more or less standardized on 38kHz, which is 00223 // why we recommend the TSOP384xx series. Not everyone is at exactly 38kHz, 00224 // but most are within 2kHz plus or minus, and the TSOP seems to demodulate 00225 // signals within a few kHz of its nominal frequency very well. 38kHz seems 00226 // to be a good centerpoint for home electronics devices, which is why we 00227 // recommend the 38kHz part as a "universal" receiver. If your application 00228 // only needs to receive from one specific remote (rather than act as a 00229 // universal receiver), you might be better served with a different TSOP 00230 // part that's tuned to your transmitter's carrier frequency, if that's 00231 // something other than 38kHz. 00232 // 00233 // Data signal: The data signal is superimposed on the PWM carrier by 00234 // turning the PWM'ed IR source on and off at a lower, variable frequency. 00235 // These longer on/off pulses are of different lengths. The data bits are 00236 // encoded in the varying lengths, although there's no one true way of 00237 // doing this. Each protocol has its own way of representing bits as 00238 // combinations of on times and off times, which we'll come to shortly. 00239 // 00240 // "On" pulses are called "marks", and "off" pulses are called "spaces". 00241 // The terms come from wired asynchronous protocols, which share many 00242 // properties with IR signals at this level. 00243 // 00244 // Note that each pulse has to be long enough to contain some minimum 00245 // number (maybe 5-10) of PWM pulses, because otherwise the demodulator 00246 // wouldn't be able to detect the presence or absence of the underlying 00247 // PWM pulses. This makes IR remote codes fairly slow in terms of data 00248 // rate, since the absolute minimum time per bit is the time in the shortest 00249 // data pulse. Most codings actually use at least two pulses per bit for 00250 // the sake of signal integrity, so the effective data rate lower still. 00251 // Fortunately, this is all rather unimportant, since IR remotes don't 00252 // need a very high data rate. They're mostly used to transmit button 00253 // presses made by hand by a human user, which are at a fairly low rate 00254 // to start with; plus, the amount of data per button is minuscule, 00255 // usually from 8 to 32 bits. 00256 // 00257 // Encodings 00258 // 00259 // The timing of the marks and spaces carries the information, but exactly 00260 // how it does this is a whole separate matter, known as an encoding. An 00261 // encoding is a mapping from '0' and '1' bits to a pattern of marks and 00262 // spaces, and vice versa. At first glance, it might seem that you could 00263 // just use a mark as a '1' and a space as a '0', and in fact some protocols 00264 // do something like this. But that simple approach has some big drawbacks 00265 // arising from the lack of a shared clock between sender and receiver. 00266 // Most encodings therefore do something to embed a timing signal of some 00267 // sort within the data signal, by using the lengths of the pulses to encode 00268 // bits rather than just the presence of the pulses. 00269 // 00270 // There are probably an infinite number of possible ways to do this in 00271 // principle. Fortunately, the CE companies have only put a finite number 00272 // of them into practice. In fact, it seems that we can cover practically 00273 // all of the remotes out there by considering a small handful of encoding 00274 // schemes. Here are the main ones, and the ones we can use in this 00275 // receiver library: 00276 // 00277 // - Async bit stream. This is basically the IR equivalent of a wired 00278 // UART. Each code word consists of a fixed number of bits. Each bit 00279 // is represented by IR ON for '1' and IR OFF for '0', transmitted for 00280 // a fixed time length. To transmit, simply turn the IR on and off in 00281 // sequence for the fixed bit time per bit. To receive and decode, 00282 // observe whether the IR signal is on or off in each time window. 00283 // This type of protocol looks simple, but it presents some difficulties 00284 // in implementation, because it doesn't provide any cues embedded in 00285 // the IR signal to help the receiver synchronize with the sender or 00286 // recognize the boundaries of code words, as all of the other common 00287 // protocols do. That might be why this class seems to be rarely used 00288 // in real applications. Protocols based on simple async bits usually 00289 // add something at the protocol level that helps the reciever detect 00290 // word boundaries and check signal integrity. 00291 // 00292 // - Pulse distance coding, also known as space length coding. In this 00293 // scheme, marks are all of equal length, but spaces come in two lengths, 00294 // A and B, where B is much longer than A (usually twice as long, but it 00295 // could be even longer). A encodes 0 and B encodes 1. The marks serve 00296 // as regular clock signals, allowing the receiver to keep in sync with 00297 // the sender, and the long and short space times (A and B) are different 00298 // enough that the receiver can easily distinguish them reliably, even 00299 // with a low-precision clock. This scheme is probably the most widely 00300 // used in CE products, because it's the encoding used by the NEC 00301 // protocol, which most Japanese CE companies use. 00302 // 00303 // - Pulse length coding, also known as mark length coding. This is simply 00304 // the inverse of pulse distance coding: spaces are all of equal length, 00305 // and marks come in two lengths, with the short mark encoding 0 and the 00306 // long mark encoding 1. This is practically the same in all meaningful 00307 // ways as the space length coding; the only reason both kinds exist is 00308 // probably that either someone had a bad case of NIH or they wanted to 00309 // avoid paying a patent royalty. Mark length coding is the scheme Sony 00310 // uses (in their SIRCS protocol). 00311 // 00312 // - Manchester coding. The message is divided into time slices of 00313 // equal size, one bit per slice. Within each slice, the IR is on for 00314 // half the window and off for half the window. The 0 and 1 bits are 00315 // encoded by the direction of the transition: if a bit window starts 00316 // with a mark (IR ON) and ends with a space (IR OFF), it's a '1'; if it 00317 // starts with a space and ends with a mark, it's a '0'. Or vice versa. 00318 // Each mark or space therefore lasts for either 1/2 or 1 bit time 00319 // length, never longer. This makes it fairly easy for the receiver to 00320 // distinguish the two time lengths, even with a fairly low-precision 00321 // clock, since they're so different. It's also easy for the receiver 00322 // to distinguish each bit, since there's always at least one transition 00323 // (mark to space or space to mark) per bit. What's more, '0' and '1' 00324 // bits take the same time to transmit (unlike the mark-length and 00325 // space-length protocols), so every code word (assuming a fixed bit 00326 // count) takes the same time regardless of the bit values within. 00327 // Manchester modulation is used in the Philips RC5 and RC6 protocols, 00328 // which are widely used among European CE companies. 00329 // 00330 // Protocols 00331 // 00332 // On top of the encoding scheme, there's another level of structure called 00333 // a protocol. A given protocol uses a given encoding for the data bits, 00334 // but then also adds some extra structure. 00335 // 00336 // For starters, the IR protocols all work in terms of "code words". In 00337 // computer terms, a code word amounts to a datatype with a fixed number 00338 // of bits. For example, the NEC protocol uses a 32-bit code word: each 00339 // button press is represented by a 32-bit transmission. A single key 00340 // press usually maps to a single code word, although not always; the 00341 // Pioneer protocol, for example, transmits two words for certain buttons, 00342 // using a special "shift" code for the first word to give a second meaning 00343 // to the second word, to extend the possible number of commands that would 00344 // be otherwise limited by the number of bits in a single code word. 00345 00346 // Second, most of the IR protocols add special non-data signals that 00347 // mark the beginning and/or end of a code word. These are usually just 00348 // extra-long marks or spaces, which are distinguishable from the marks 00349 // and spaces within a code word because they're too long to be valid in 00350 // the data encoding scheme. These are important to reliable communication 00351 // because the sender and receiver don't have any other way to share state 00352 // with each other. Consider what would happen if someone walked in the 00353 // way while you were transmitting a remote code: the receiver would miss 00354 // at least a few data bits, so it would be out of sync with the sender. 00355 // If there weren't some way to distinguish the start of a code word from 00356 // the IR pulses themselves, the receiver would now be permanently out 00357 // of sync from the sender by however many bits it missed. But with the 00358 // special "header" code, the receiver can sync up again as soon as the 00359 // next code word starts, since it can tell from the timing that the 00360 // header can't possibly be a bit in the middle of a code word. 00361 00362 00363 #ifndef _IRRECEIVER_H_ 00364 #define _IRRECEIVER_H_ 00365 00366 #include <mbed.h> 00367 00368 #include "IRRemote.h" 00369 #include "IRCommand.h" 00370 #include "circbuf.h" 00371 #include "FastInterruptIn.h" 00372 00373 00374 // IR receiver protocol interface. This contains functions that we only 00375 // want to make accessible to the protocol decoders. 00376 class IRRecvProIfc 00377 { 00378 public: 00379 // write a command to the command queue 00380 void writeCommand(IRCommand &cmd) { commands.write(cmd); } 00381 00382 protected: 00383 // Decoded command queue. The protocol handlers add commands here 00384 // as soon as they decode them. 00385 CircBuf<IRCommand, 8> commands; 00386 }; 00387 00388 00389 // IR Remote Receiver 00390 class IRReceiver : protected IRRecvProIfc 00391 { 00392 public: 00393 // Construct a receiver with the given data input pin. The receiver 00394 // is initially disabled. To start receiving signals, call enable(). 00395 // 00396 // Choose a raw buffer size according to the longest iteration time 00397 // for your main application loop between the required periodic calls 00398 // to our process() function. The interrupt handlers write pulse times 00399 // to the raw buffer as the pulses arrive, and these are held in the 00400 // buffer until they're removed by process(). The raw buffer only needs 00401 // to be big enough for the "backlog" that occurs between the real-time 00402 // incoming signals and the main loop's processing calls. The fastest 00403 // IR pulses are about 250us long, so size the buffer according to how 00404 // many 250us intervals will occur in the worst case, that is, the 00405 // longest main loop iteration. If the main loop always runs in 2.5ms 00406 // or shorter, that means you need about a 10-element buffer. To be 00407 // conservative, size it at perhaps 2x the expected maximum. 00408 // 00409 IRReceiver(PinName rxpin, size_t rawBufCount); 00410 00411 // Destructor 00412 ~IRReceiver(); 00413 00414 // Optionally connect to a transmitter, to suppress reception while 00415 // we're transmitting. This prevents spuriously receiving our own 00416 // transmissions, if our IR LED and sensor are physically close enough 00417 // to one another that our sensor would pick up light from our LED. 00418 // If the two are physically isolated so that we can't receive our 00419 // own transmissions, it's not necessary to connect the transmitter 00420 // here, as there's no restriction on the software side on sending 00421 // and receiving simultaneously - the suppression is only needed to 00422 // avoid self-interference with the physical IR signals. 00423 void setTransmitter(class IRTransmitter *transmitter) 00424 { 00425 this->transmitter = transmitter; 00426 } 00427 00428 // Enable/disable our interrupt handlers. If the main program 00429 // doesn't need IR input, it can disable the receiver so that 00430 // it doesn't consume any CPU time handling interrupts. 00431 void enable(); 00432 void disable(); 00433 00434 // Read a command. Returns true if a command was available, filling 00435 // in 'cmd'. Returns false (without blocking) if no commands are 00436 // available. 00437 bool readCommand(IRCommand &cmd) { return commands.read(cmd); } 00438 00439 // Is a command ready to read? 00440 bool isCommandReady() { return commands.readReady(); } 00441 00442 // Process signals received. The application main loop must call this 00443 // as frequently as possible to process incoming signals from the raw 00444 // buffer. This processes all samples in the raw buffer before 00445 // returning. 00446 void process(); 00447 00448 // Process and retrieve one raw pulse. The application main loop can 00449 // optionally call this, instead of process(), if it wants to retrieve 00450 // each raw sample for its own purposes in addition to running them 00451 // through the protocol state machines. If no sample is available, we 00452 // immediately return false - the routine doesn't block waiting for a 00453 // sample. If a sample is available, we fill in 'sample' with the pulse 00454 // time in microseconds, and set 'mark' to true if the sample was a mark, 00455 // false if it's a space. 00456 // 00457 // To use this instead of process(), on each main loop iteration, call 00458 // this function in an inner loop until it returns false. That'll ensure 00459 // that all pending samples have been processed through the protocol 00460 // state machines and that maximum buffer space is available for the next 00461 // main loop iteration. 00462 bool processOne(uint32_t &sample, bool &mark); 00463 00464 // Process and retrieve one raw pulse. This works the same as the 00465 // two-argument version above, but returns the sample in our internal 00466 // format: the sample value is a time reading in 2us units, and the low 00467 // bit is 1 for a mark, 0 for a space. To convert to a time reading in 00468 // microseconds, mask out the low bit and multiply by 2. 00469 bool processOne(uint16_t &sample); 00470 00471 // Maximum pulse length in microseconds. Anything longer will simply 00472 // be represented with this value. This is long enough that anything 00473 // longer has equivalent meaning in any of our protocols. Generally, 00474 // space longer than this will only occur in a silent interval between 00475 // transmissions (that is, while no one is sending any codes), and a 00476 // mark longer than this could only be interference or noise. 00477 // 00478 // This value should be chosen so that it's high enough to be readily 00479 // distinguishable (in terms of our error tolerance) from the longest 00480 // *meaningful* space or pulse in any protocol we need to handle, but 00481 // not much higher than that. It shouldn't be too long because it has 00482 // a role as an inactivity timeout on receive: we can't always know 00483 // that a signal has ended until there's inactivity for this amount 00484 // of time. If the timeout is too long, it can become noticable as 00485 // lag time in recognizing signals. In practice, the longest gap time 00486 // between repeating signals in commonly used protocols is in the 00487 // neighboorhood of 100ms. 00488 // 00489 // This value is chosen to be the largest we can fit into a 16-bit 00490 // int, taking into account our 2X scaling and our use of the low bit 00491 // for a mark/space indicator. That leaves us with 14 bits and 2X scale. 00492 static const uint32_t MAX_PULSE = 131068; 00493 00494 private: 00495 // Input pin. Reads from a TSOP384xx or similar sensor. Any 00496 // sensor should work that demodulates the carrier wave and 00497 // gives us an active-low input on the pin. 00498 // 00499 // Note that we use our FastInterruptIn replacement instead of the 00500 // mbed InterruptIn. We don't actually need the higher speed here of 00501 // FastInterruptIn, but we have to use it anyway because other parts 00502 // of the system use it. The two classes don't play nice together: 00503 // the whole app has to use one or the other. 00504 FastInterruptIn pin; 00505 00506 // IR raw data buffer. The interrupt handlers store the pulse 00507 // timings here as they arrive, and the process() routine reads from 00508 // the buffer. 00509 // 00510 // Samples here are limited to 16 bits, so the longest time that 00511 // can be represented is 65535us. Anything longer is capped to this. 00512 // 00513 // To keep track of marks vs spaces, we set the low-order bit of 00514 // each sample time to 1 for a mark and 0 for a space. That means 00515 // that the times are only good to 2us precision, but that's plenty 00516 // of precision for all of the IR protocols, since the shortest time 00517 // bases are around 250us. 00518 CircBufV<uint16_t> rawbuf; 00519 00520 // Pulse timer. We reset the timer at the start of each pulse, so 00521 // it tells us the duration thus far of the current pulse at any 00522 // given time. We stop the timer (without resetting) any time a 00523 // pulse reaches the maximum length, to ensure that the timer never 00524 // rolls over, even in the indefinite gap between codes. 00525 Timer pulseTimer; 00526 00527 // flag: the pulse timer has reached IR_MAX_PULSE 00528 bool pulseAtMax; 00529 00530 // current pulse state: mark = 1, space = 0 00531 bool pulseState; 00532 00533 // start the pulse timers with the new pulse state (1=mark, 0=space) 00534 void startPulse(bool newPulseState); 00535 00536 // end the current pulse, checking that the pulse state matches the 00537 // current state 00538 void endPulse(bool lastPulseState); 00539 00540 // process a pulse through our protocol handlers 00541 void processProtocols(uint32_t t, bool mark); 00542 00543 // rise and fall interrupt handlers for the input pin 00544 static void cbFall(void *obj) { ((IRReceiver *)obj)->fall(); } 00545 static void cbRise(void *obj) { ((IRReceiver *)obj)->rise(); } 00546 void fall(); 00547 void rise(); 00548 00549 // timeout for time-limited states 00550 Timeout timeout; 00551 00552 // timeout handler for a pulse (mark or space) 00553 void pulseTimeout(void); 00554 00555 // Connected transmitter. If this is set, we'll suppress reception 00556 // while the transmitter is sending a signal, to avoid receiving our 00557 // own transmissions. 00558 class IRTransmitter *transmitter; 00559 }; 00560 00561 #endif
Generated on Thu Jul 14 2022 12:20:36 by 1.7.2