An I/O controller for virtual pinball machines: accelerometer nudge sensing, analog plunger input, button input encoding, LedWiz compatible output controls, and more.

Dependencies:   mbed FastIO FastPWM USBDevice

Fork of Pinscape_Controller by Mike R

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers IRRemote.h Source File

IRRemote.h

00001 // IR Remote Control send/receive library - common definitions
00002 
00003 #ifndef _IRREMOTE_H_
00004 #define _IRREMOTE_H_
00005 
00006 namespace IRRemote 
00007 {
00008 
00009     // Tolerance range for timing inaccuracies, as a percentage +/- of the 
00010     // reference time from the protocol specification.  Our measured signal
00011     // times will never exactly match the specification times, because
00012     // neither the receiver nor the transmitter have perfect clocks.  And
00013     // even if we had a perfect clock, we'd still be a little off due to
00014     // latencies in the detector hardware, the detector's signal processing
00015     // (demodulation, filtering), and our own latencies in detecting and
00016     // responding to signals on the input pin.  So we need to add a little
00017     // wiggle room in interpreting times: if the spec says we should see an 
00018     // X-microsecond IR-ON state (a "mark"), we can expect it to actually
00019     // range from X-error to X+error.  This tolerance value sets the error
00020     // range we'll accept.
00021     //
00022     // Typical Arduino IR receiver implementations use 30% tolerances.  I 
00023     // think we could be quite a bit tighter than that if we wanted to be,
00024     // since the biggest source of timing inaccuracies on the Arduino systems
00025     // is probably the Arduino itself - the CPU is fairly slow to start with,
00026     // and most of the Arduino code I've seen uses polling to detect signal
00027     // edges, which is inherently high-latency.  We're on a relatively fast
00028     // CPU, and we use interrupts to detect edges.  In my own measurements
00029     // of miscellaneous remotes, our readings seem to be within about 3% of 
00030     // spec, so I think 30% is far looser than we really need to be.
00031     //
00032     // The main reason to prefer tighter tolerances is that we want to
00033     // work with many different transmitters from different vendors, using 
00034     // different protocols.  Higher tolerances mean more ambiguity in
00035     // identifying timing signatures.  The tradeoff, of course, is that a
00036     // lower tolerance means more chance of rejecting borderline signals
00037     // that we could have interpreted properly.  This will probably have
00038     // to be fine-tuned over time based on practical experience.  For now,
00039     // it appears that the super loose Arduino levels work just fine, in
00040     // that we can still easily identify protocols.
00041     //const float tolerance = 0.3f;
00042     const int toleranceShl8 = 77;  // tolerance*256
00043     
00044     // Check a reading against a reference value using a specified
00045     // base value for figuring the tolerance.  This is useful when
00046     // looking for multiples of a base value, because it pegs the
00047     // tolerance window to the base value rather than allowing it
00048     // to grow at each multiple.
00049     inline bool inRange(int reading, int referenceVal, int baseVal)
00050     {
00051         int delta = (baseVal * toleranceShl8) >> 8;
00052         return reading > referenceVal - delta && reading < referenceVal + delta;
00053     }
00054 
00055     // Check a reading against a reference value, applying the tolerance
00056     // range to the reference value.
00057     inline bool inRange(int reading, int referenceVal) 
00058     {
00059         return inRange(reading, referenceVal, referenceVal);
00060     }
00061     
00062     // Test a reading against a reference value to see if it's out of
00063     // range of the reference value above.  This is equivalent to asking
00064     // if the value is NOT inRange() AND is higher than the reference
00065     // value.
00066     inline bool aboveRange(uint32_t val, uint32_t ref, uint32_t baseVal)
00067     {
00068         return val > ref + ((baseVal*(256-toleranceShl8)) >> 8);
00069     }
00070     
00071     // Test a reading against a reference value to see if it's in range
00072     // or above the range
00073     inline bool inRangeOrAbove(uint32_t val, uint32_t ref, uint32_t baseVal)
00074     {
00075         int delta = (baseVal * toleranceShl8) >> 8;
00076         return val > ref - delta;
00077     }
00078 }
00079 
00080 #endif