diff --git a/doc/Doxyfile b/doc/Doxyfile
index ec0054f4..4e3dd91d 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -610,7 +610,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = ../libraries/LCD ../libraries/BlinkLED ../libraries/I2C ../libraries/RTC ../libraries/Melody ../libraries/PowerSave ../libraries/DMD .
+INPUT = ../libraries/LCD ../libraries/BlinkLED ../libraries/I2C ../libraries/RTC ../libraries/Melody ../libraries/PowerSave ../libraries/DMD ../libraries/IR .
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -688,7 +688,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
-IMAGE_PATH = ../libraries/BlinkLED/examples/Cylon ../libraries/BlinkLED/examples/Cylon4 ../libraries/BlinkLED/examples/StarTrek ../libraries/BlinkLED/examples/Charlieplex ../libraries/LCD/examples/HelloWorld ../libraries/LCD/examples/Form ../libraries/RTC/examples/AlarmClock ../libraries/DMD
+IMAGE_PATH = ../libraries/BlinkLED/examples/Cylon ../libraries/BlinkLED/examples/Cylon4 ../libraries/BlinkLED/examples/StarTrek ../libraries/BlinkLED/examples/Charlieplex ../libraries/LCD/examples/HelloWorld ../libraries/LCD/examples/Form ../libraries/RTC/examples/AlarmClock ../libraries/DMD ../libraries/IR
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
diff --git a/doc/ir-dumpir.dox b/doc/ir-dumpir.dox
new file mode 100644
index 00000000..d6833ca9
--- /dev/null
+++ b/doc/ir-dumpir.dox
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 Southern Storm Software, Pty Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+\file ir-dumpir.dox
+\page ir_dumpir Dumping Infrared Remote Control Codes
+
+This example uses the IRreceiver class to dump commands that are received
+from an infrared remote control that is compatible with the
+Philips RC-5 protocol.
+Commands are dumped to the serial port. The example needs a 3-pin
+infrared receiver connected to D2, GND, and 5V:
+
+\image html irchip.jpg
+
+The full source code for the example follows:
+
+\include IR/examples/DumpIR/DumpIR.pde
+*/
diff --git a/doc/mainpage.dox b/doc/mainpage.dox
index 8cfc9527..4848ccd5 100644
--- a/doc/mainpage.dox
+++ b/doc/mainpage.dox
@@ -85,6 +85,12 @@ The default implementation simulates the time and date based on the value of
\li \ref alarm_clock "Alarm Clock" example that uses the DS1307 or DS3232
realtime clock and the LCD library to implement an alarm clock.
+\section main_IR Infrared Control Library
+
+\li IRreceiver class that receives incoming RC-5 commands from an
+infrared remote control.
+\li \ref ir_dumpir "DumpIR" example that dumps all incoming RC-5 commands.
+
\section main_other Other
\li Melody plays a melody on a digital output pin using tone().
diff --git a/libraries/IR/IRreceiver.cpp b/libraries/IR/IRreceiver.cpp
new file mode 100644
index 00000000..c03296d6
--- /dev/null
+++ b/libraries/IR/IRreceiver.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2012 Southern Storm Software, Pty Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "IRreceiver.h"
+#if defined(ARDUINO) && ARDUINO >= 100
+#include
+#else
+#include
+#endif
+
+/**
+ * \class IRreceiver IRreceiver.h
+ * \brief Manages the reception of RC-5 commands from an infrared remote control.
+ *
+ * IRreceiver recognizes commands in the Philips RC-5 protocol.
+ * This is a fairly common infrared protocol, supported by most universal
+ * remote controls. Program the universal remote to simulate a Philips
+ * TV, VCR, CD player, etc.
+ *
+ * This class uses interrupts to process incoming bits from a standard 3-pin
+ * infrared receiver:
+ *
+ * \image html irchip.jpg
+ *
+ * Typically, pin 1 of the receiver should be connected to the Arduino
+ * interrupt pin (e.g. D2), pin 2 should be connected to GND, and pin 3
+ * should be connected to 5V. Consult the datasheet for your receiver to
+ * be sure though; some receivers may have different pin assignments.
+ *
+ * The receiver is initialized by constructing an instance of the
+ * IRreceiver class:
+ *
+ * \code
+ * IRreceiver ir;
+ * \endcode
+ *
+ * By default, interrupt 0 on pin D2 is used. To change to another interrupt,
+ * pass its number to the constructor:
+ *
+ * \code
+ * IRreceiver ir(1); // Interrupt 1 on pin D3
+ * \endcode
+ *
+ * Currently this class can only handle a single instance of IRreceiver being
+ * active in the application. It isn't possible to have separate IRreceiver
+ * instances on different pins. Usually this won't be a problem because
+ * the same receiver can process inputs from multiple remotes.
+ *
+ * The application retrieves incoming infrared commands by calling the
+ * command() function. The return value indicates the type of command:
+ *
+ * \code
+ * void loop() {
+ * switch (ir.command()) {
+ * case RC5_0: case RC5_1: case RC5_2: case RC5_3: case RC5_4:
+ * case RC5_5: case RC5_6: case RC5_7: case RC5_8: case RC5_9:
+ * // Process a digit
+ * ...
+ * break;
+ *
+ * case RC5_ERASE:
+ * // Backspace/erase last digit.
+ * ...
+ * break;
+ *
+ * case RC5_STANDBY:
+ * // Power on/off button.
+ * ...
+ * break;
+ * }
+ * }
+ * \endcode
+ *
+ * If the command is an auto-repeat of a previous button press, then the
+ * \ref AUTO_REPEAT flag will be set in the value returned from command().
+ * The application can choose to ignore all auto-repeats, process all
+ * auto-repeats, or choose which button to auto-repeat based on its code:
+ *
+ * \code
+ * void loop() {
+ * switch (ir.command()) {
+ * case RC5_INC_VOLUME:
+ * case IRreceiver::AUTO_REPEAT | RC5_INC_VOLUME:
+ * // Volume increase button pressed or held.
+ * ...
+ * break;
+ *
+ * case RC5_DEC_VOLUME:
+ * case IRreceiver::AUTO_REPEAT | RC5_DEC_VOLUME:
+ * // Volume decrease button pressed or held.
+ * ...
+ * break;
+ *
+ * case RC5_MUTE:
+ * // Mute button (ignore auto-repeat).
+ * ...
+ * break;
+ * }
+ * }
+ * \endcode
+ *
+ * By default, command codes will be generated for every type of RC-5 remote
+ * control, be it a TV, VCR, CD player, or something else. The application
+ * can distinguish between the remote controls using system(); noting that
+ * command() must be called before system() for the system value to be valid.
+ * For example, the following code could be used in a two-player video game
+ * where the first player's remote is configured as a TV and the second
+ * player's remote is configured as a VCR:
+ *
+ * \code
+ * void loop() {
+ * int cmd = ir.command();
+ * int sys = ir.system();
+ * if (sys == RC5_SYS_TV)
+ * player1(cmd);
+ * else if (sys == RC5_SYS_VCR)
+ * player2(cmd);
+ *
+ * ...
+ * }
+ * \endcode
+ *
+ * If the application only cares about a single system and wishes to ignore
+ * all other systems, it can configure a system filter at startup:
+ *
+ * \code
+ * IRreceiver ir;
+ *
+ * void setup() {
+ * ir.setSystemFilter(RC5_SYS_VCR);
+ * }
+ * \endcode
+ *
+ * The complete list of RC-5 system numbers and command codes is given in
+ * the RC5.h header file.
+ *
+ * \sa \ref ir_dumpir "DumpIR Example"
+ */
+
+static IRreceiver *receiver = 0;
+
+void _IR_receive_interrupt(void)
+{
+ receiver->handleInterrupt();
+}
+
+/**
+ * \var IRreceiver::AUTO_REPEAT
+ * \brief Flag that is added to the output of command() when the command
+ * is an auto-repeated button press rather than the original button press.
+ */
+
+/**
+ * \brief Constructs a new infrared remote control receiver that is attached
+ * to \a interruptNumber.
+ */
+IRreceiver::IRreceiver(int interruptNumber)
+ : _system(0)
+ , _systemFilter(-1)
+ , started(false)
+ , halfChange(false)
+ , lastChange(0)
+ , bits(0)
+ , bitCount(0)
+ , buffer(0)
+ , lastBuffer(0)
+{
+ switch (interruptNumber) {
+ case 0: default: pin = 2; break;
+ case 1: pin = 3; break;
+ case 2: pin = 21; break; // Arduino Mega only
+ case 3: pin = 20; break; // Arduino Mega only
+ case 4: pin = 19; break; // Arduino Mega only
+ case 5: pin = 18; break; // Arduino Mega only
+ }
+ receiver = this;
+ attachInterrupt(interruptNumber, _IR_receive_interrupt, CHANGE);
+}
+
+/**
+ * \brief Returns the next command from the remote control.
+ *
+ * Returns -1 if there is no new command, or the number between 0 and 127
+ * corresponding to the command. If the command is an auto-repeat button
+ * press rather than an original button press, then the \ref AUTO_REPEAT
+ * flag will be set.
+ *
+ * The companion function system() will return the system number for the
+ * command indicating whether the command is for a TV, VCR, CD player, etc.
+ * By default, all systems are reported; use setSystemFilter() to filter
+ * out commands from all but a specific system.
+ *
+ * The next call to command() will return -1 or the code for the next
+ * button press.
+ *
+ * The header file RC5.h contains a list of command codes for
+ * common remote controls.
+ *
+ * \sa system(), setSystemFilter()
+ */
+int IRreceiver::command()
+{
+ unsigned buf;
+
+ // Read the last-delivered sequence from the buffer and clear it.
+ cli();
+ buf = buffer;
+ buffer = 0;
+ sei();
+
+ // Bail out if no sequence or it is not for us.
+ if (!buf) {
+ _system = -1;
+ return -1;
+ }
+ if (_systemFilter != -1) {
+ if (((buf >> 6) & 0x1F) != _systemFilter) {
+ _system = -1;
+ return -1;
+ }
+ }
+
+ // Extract the command.
+ int cmd = buf & 0x3F;
+ if ((buf & 0x1000) == 0)
+ cmd += 64;
+
+ // Is this a new command or an auto-repeat of the previous command?
+ // Bit 11 will toggle whenever a new button press is started.
+ if (lastBuffer == buf)
+ cmd += AUTO_REPEAT;
+ else
+ lastBuffer = buf;
+ _system = (buf >> 6) & 0x1F;
+ return cmd;
+}
+
+/**
+ * \fn int IRreceiver::system() const
+ * \brief Returns the system number of the previous command(), indicating
+ * whether the command was for a TV, VCR, CD player, etc.
+ *
+ * The return value from this function is valid only after a call to
+ * command(). The next call to command() will clear the system value,
+ * possibly to -1 if there is no new command.
+ *
+ * The header file RC5.h contains a list of system numbers for
+ * common remote controls.
+ *
+ * \sa command(), setSystemFilter()
+ */
+
+/**
+ * \fn int IRreceiver::systemFilter() const
+ * \brief Returns the system to filter commands against, or -1 if no
+ * filter is set.
+ *
+ * If this value is -1, then all received systems are returned via command()
+ * and system() irrespective of whether they are for a TV, VCR, CD player,
+ * or some other type of system. If this value is set to anything other
+ * than -1, then only commands for that system are returned via command().
+ *
+ * \sa setSystemFilter(), system(), command()
+ */
+
+/**
+ * \fn void IRreceiver::setSystemFilter(int system)
+ * \brief Sets the \a system to filter commands against, or -1 to turn
+ * off the system filter.
+ *
+ * If \a system is -1, then all received systems are returned via command()
+ * and system() irrespective of whether they are for a TV, VCR, CD player,
+ * or some other type of system. If \a system is set to anything other
+ * than -1, then only commands for that system are returned via command().
+ * For example:
+ *
+ * \code
+ * IRreceiver ir;
+ * ir.setSystemFilter(RC5_SYS_VCR);
+ * \endcode
+ *
+ * \sa systemFilter(), system(), command()
+ */
+
+// Number of microseconds that the signal is HIGH or LOW for
+// indicating a bit. A 1 bit is transmitted as LOW for 889us
+// followed by HIGH for 889us. A 0 bit is HIGH, then LOW.
+#define IR_BIT_TIME 889
+
+// Number of microseconds to detect a long gap in the coding
+// corresponding to 2 time units HIGH or LOW. We actually check
+// for at least 1.5 time units to allow for slight variations
+// in timing on different remote controls.
+#define IR_LONG_BIT_TIME (889 * 6 / 4)
+
+// Maximum timeout for a single bit. If we don't see a rising edge
+// within this time, then we have lost sync and need to restart.
+#define IR_MAX_TIME (IR_BIT_TIME * 4)
+
+// Protocol details from http://en.wikipedia.org/wiki/RC-5
+void IRreceiver::handleInterrupt()
+{
+ bool value = digitalRead(pin);
+ unsigned long currentTime = micros();
+ if (!value) {
+ // Rising edge (input is active-LOW)
+ if (started && (currentTime - lastChange) > IR_MAX_TIME) {
+ // Too long since the last received bit, so restart the process.
+ started = false;
+ }
+ if (started) {
+ // We recognize bits on the falling edges, so merely
+ // adjust the "changed at last half-cycle" flag.
+ if ((currentTime - lastChange) > IR_LONG_BIT_TIME) {
+ // Long time since last falling edge indicates that the
+ // next bit will definitely be a 1.
+ halfChange = true;
+ } else {
+ halfChange = !halfChange;
+ }
+ lastChange = currentTime;
+ } else {
+ // Encountered the start bit - start receiving up to 14 bits.
+ lastChange = currentTime;
+ started = true;
+ halfChange = true;
+ bits = 0;
+ bitCount = 14;
+ }
+ } else if (started) {
+ // Falling edge
+ if ((currentTime - lastChange) > IR_LONG_BIT_TIME) {
+ // Long time since last rise indicates 1 followed by 0.
+ bits = (bits << 2) | 0x02;
+ --bitCount;
+ halfChange = true;
+ } else if (halfChange) {
+ // Rise was halfway through, so falling edge indicates a 1.
+ bits = (bits << 1) | 0x01;
+ halfChange = false;
+ } else {
+ // Rise was at the start, so falling edge indicates a 0.
+ bits <<= 1;
+ halfChange = true;
+ }
+ lastChange = currentTime;
+ --bitCount;
+ if (bitCount <= 0) {
+ // All 14 bits have been received, so deliver the value.
+ started = false;
+ buffer = bits;
+ }
+ }
+}
diff --git a/libraries/IR/IRreceiver.h b/libraries/IR/IRreceiver.h
new file mode 100644
index 00000000..39f5cc26
--- /dev/null
+++ b/libraries/IR/IRreceiver.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 Southern Storm Software, Pty Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef IRreceiver_h
+#define IRreceiver_h
+
+#include
+#include "RC5.h"
+
+class IRreceiver
+{
+public:
+ explicit IRreceiver(int interruptNumber = 0);
+
+ static const int AUTO_REPEAT = 128;
+
+ int command();
+ int system() const { return _system; }
+
+ int systemFilter() const { return _systemFilter; }
+ void setSystemFilter(int system) { _systemFilter = system; }
+
+private:
+ int _system;
+ int _systemFilter;
+ uint8_t pin;
+ bool started;
+ bool halfChange; // Value last changed half-way through bit cycle time.
+ unsigned long lastChange;
+ unsigned bits;
+ int8_t bitCount;
+ volatile unsigned buffer;
+ unsigned lastBuffer;
+
+ void handleInterrupt();
+
+ friend void _IR_receive_interrupt(void);
+};
+
+#endif
diff --git a/libraries/IR/RC5.h b/libraries/IR/RC5.h
new file mode 100644
index 00000000..64897464
--- /dev/null
+++ b/libraries/IR/RC5.h
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2012 Southern Storm Software, Pty Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef RC5_h
+#define RC5_h
+
+// http://en.wikipedia.org/wiki/RC-5#System_Number_Allocations
+#define RC5_SYS_TV 0 // TV receiver 1
+#define RC5_SYS_TV2 1 // TV receiver 2
+#define RC5_SYS_TXT 2 // Teletext
+#define RC5_SYS_TV_EXT 3 // Extension to TV 1 & 2
+#define RC5_SYS_LV 4 // Laservision player
+#define RC5_SYS_VCR 5 // VCR 1
+#define RC5_SYS_VCR2 6 // VCR 2
+#define RC5_SYS_SAT 8 // Satellite receiver 1
+#define RC5_SYS_VCR_EXT 9 // Extension to VCR 1 & 2
+#define RC5_SYS_SAT2 10 // Satellite receiver 2
+#define RC5_SYS_CD_VIDEO 12 // CD video player
+#define RC5_SYS_CD_PHOTO 14 // CD photo player
+#define RC5_SYS_PREAMP 16 // Audio preamplifier 1
+#define RC5_SYS_RADIO 17 // Radio tuner
+#define RC5_SYS_REC 18 // Casette recorder 1
+#define RC5_SYS_PREAMP2 19 // Audio preamplifier 2
+#define RC5_SYS_CD 20 // CD player
+#define RC5_SYS_COMBI 21 // Audio stack or record player
+#define RC5_SYS_AUDIO_SAT 22 // Audio satellite
+#define RC5_SYS_REC2 23 // Casette recorder 2
+#define RC5_SYS_CD_R 26 // CD recorder
+
+// http://en.wikipedia.org/wiki/RC-5#Command_Tables
+// Table 2, Common commands:
+#define RC5_0 0 // Digit 0
+#define RC5_1 1 // Digit 1
+#define RC5_2 2 // Digit 2
+#define RC5_3 3 // Digit 3
+#define RC5_4 4 // Digit 4
+#define RC5_5 5 // Digit 5
+#define RC5_6 6 // Digit 6
+#define RC5_7 7 // Digit 7
+#define RC5_8 8 // Digit 8
+#define RC5_9 9 // Digit 9
+#define RC5_INC_VOLUME 16 // Increase sound volume
+#define RC5_DEC_VOLUME 17 // Decrease sound volume
+#define RC5_INC_BRIGHTNESS 18 // Increase display brightness
+#define RC5_DEC_BRIGHTNESS 19 // Decrease display brightness
+#define RC5_INC_BASS 22 // Increase bass response
+#define RC5_DEC_BASS 23 // Decrease bass response
+#define RC5_INC_TREBLE 24 // Increase treble response
+#define RC5_DEC_TREBLE 25 // Decrease treble response
+#define RC5_BALANCE_LEFT 26 // Shift sound balance to left
+#define RC5_BALANCE_RIGHT 27 // Shift sound balance to right
+#define RC5_TRANSMIT_MODE 63 // Select remote transmit mode
+#define RC5_DIM 71 // Dim local display
+#define RC5_INC_LINEAR 77 // Increase linear control
+#define RC5_DEC_LINEAR 78 // Decrease linear control
+#define RC5_UP 80 // Move cursor up
+#define RC5_DOWN 81 // Move cursor down
+#define RC5_MENU_ON 82 // Switch display/screen menu on
+#define RC5_MENU_OFF 83 // Switch display/screen menu off
+#define RC5_AV_STATUS 84 // Display A/V system status
+#define RC5_LEFT 85 // Move cursor left
+#define RC5_RIGHT 86 // Move cursor right
+#define RC5_OK 87 // Acknowledge function at cursor
+#define RC5_SUBMODE 118 // Select sub-mode
+#define RC5_OPTIONS 119 // Select options sub-mode
+#define RC5_CONNECT_EURO 123 // Connect items via Euroconnector
+#define RC5_DISCONNECT_EURO 124 // Disconnect items via Euroconnector
+
+// http://en.wikipedia.org/wiki/RC-5#Command_Tables
+// Table 3, Common video system commands:
+#define RC5_INC_SATURATION 20 // Increase color saturation
+#define RC5_DEC_SATURATION 21 // Decrease color saturation
+#define RC5_PIP 88 // Picture-in-picture on/off
+#define RC5_PIP_SHIFT 89 // Picture-in-picture shift
+#define RC5_PIP_SWAP 90 // Picture-in-picture swap
+#define RC5_PIP_STROBE 91 // Strobe main picture on/off
+#define RC5_PIP_MULTI_STROBE 92 // Multi-strobe
+#define RC5_PIP_FREEZE_MAIN 93 // Main picture frame frozen
+#define RC5_PIP_MULTI_SCAN 94 // 3/9 multi-scan
+#define RC5_PIP_SOURCE 95 // Select picture-in-picture source
+#define RC5_PIP_MOSAIC 96 // Mosaic/multi-PIP
+#define RC5_PIP_NOISE 97 // Digital noise reduction of picture
+#define RC5_PIP_STORE 98 // Store main picture
+#define RC5_PIP_PHOTO_FINISH 99 // PIP strobe; display photo-finish
+#define RC5_PIP_RECALL 100 // Recall main stored picture
+#define RC5_PIP_FREEZE 101 // Freeze PIP
+#define RC5_PIP_UP 102 // Step up PIP options/source
+#define RC5_PIP_DOWN 103 // Step down PIP options/source
+
+// http://en.wikipedia.org/wiki/RC-5#Command_Tables
+// Table 4a, TV and VCR commands:
+#define RC5_123 10 // 1/2/3 digit entry
+#define RC5_11 11 // Channel/program/frequency 11
+#define RC5_STANDBY 12 // Standby
+#define RC5_MUTE 13 // Master mute/de-mute
+#define RC5_PREFERENCES 14 // Personal preference settings
+#define RC5_DISPLAY_INFO 15 // Display user info on screen
+#define RC5_INC_CONTRAST 28 // Increase picture contrast
+#define RC5_DEC_CONTRAST 29 // Decrease picture contrast
+#define RC5_SEARCH_UP 30 // Search up
+#define RC5_DEC_TINT 31 // Decrease tint/hue
+#define RC5_CHANNEL_UP 32 // Channel/program up
+#define RC5_CHANNEL_DOWN 33 // Channel/program down
+#define RC5_CHANNEL_LAST 34 // Last viewed channel/program
+#define RC5_STEREO_SELECT 35 // Select stereo channel/language
+#define RC5_STEREO_SPATIAL 36 // Spatial stereo
+#define RC5_STEREO_TOGGLE 37 // Toggle stereo/mono
+#define RC5_SLEEP_TIMER 38 // Sleep timer
+#define RC5_INC_TINT 39 // Increase tint/hue
+#define RC5_SWITCH_RF 40 // Switch RF inputs
+#define RC5_STORE 41 // Store/vote
+#define RC5_TIME 42 // Display time
+#define RC5_INC_SCAN 43 // Scan forward/increment
+#define RC5_DEC_SCAN 44 // Scan backward/decrement
+#define RC5_SECONDARY_MENU 46 // Secondary menu
+#define RC5_CLOCK 47 // Show clock
+#define RC5_PAUSE 48 // Pause
+#define RC5_ERASE 49 // Erase/correct entry
+#define RC5_REWIND 50 // Rewind
+#define RC5_GOTO 51 // Go to
+#define RC5_WIND 52 // Wind (fast forward)
+#define RC5_PLAY 53 // Play
+#define RC5_STOP 54 // Stop
+#define RC5_RECORD 55 // Record
+#define RC5_EXTERNAL1 56 // External 1
+#define RC5_EXTERNAL2 57 // External 2
+#define RC5_VIEW_DATA 59 // View data, advance
+#define RC5_12 60 // Channel 12 (or TXT/TV toggle)
+#define RC5_SYSTEM_STANDBY 61 // System standby
+#define RC5_CRISP 62 // Picture crispener (coutour boost)
+#define RC5_AUDIO_RESPONSE 70 // Audio response for speech/music
+#define RC5_SOUND_FUNCTIONS 79 // Select sound functions in sequence
+#define RC5_PIP_SIZE 104 // Alter PIP size step-by-step
+#define RC5_VISION_FUNCTIONS 105 // Select vision functions in sequence
+#define RC5_COLOR_KEY 106 // Colored or other special key
+#define RC5_RED 107 // Red button
+#define RC5_GREEN 108 // Green button
+#define RC5_YELLOW 109 // Yellow button
+#define RC5_CYAN 110 // Cyan button
+#define RC5_INDEX 111 // Index page/white function
+#define RC5_NEXT_OPTION 112 // Next option
+#define RC5_PREVIOUS_OPTION 113 // Previous option
+#define RC5_STORE_OPEN_CLOSE 122 // Store open/close
+#define RC5_PARENTAL_ACCESS 123 // Parental access via PIN code
+
+// http://en.wikipedia.org/wiki/RC-5#Command_Tables
+// Table 4b, TV1 and TV2 extension
+#define RC5_DEFAULT_VIDEO 10 // Default video settings (TV1)
+#define RC5_DEFAULT_AUDIO 11 // Default audio settings (TV1)
+#define RC5_PAYTV_CHANNEL_UP 28 // Pay TV channel up (TV1)
+#define RC5_PAYTV_CHANNEL_DOWN 29 // Pay TV channel down (TV1)
+#define RC5_RADIO_CHANNEL_UP 30 // Radio channel up (TV1)
+#define RC5_RADIO_CHANNEL_DOWN 31 // Radio channel down (TV1)
+#define RC5_TILT_FORWARD 32 // Tilt cabinet forward (TV1)
+#define RC5_TILT_BACKWARD 33 // Tilt cabinet backward (TV1)
+#define RC5_EXTERNAL3 56 // External 3 (TV1)
+#define RC5_EXTERNAL4 56 // External 4 (TV1)
+#define RC5_PICTURE_FORMAT 62 // 4:3 vs 16:9 (TV1)
+#define RC5_CHANNEL_10 67 // Channel 10
+#define RC5_CHANNEL_11 68 // Channel 11
+#define RC5_CHANNEL_12 69 // Channel 12
+#define RC5_DEFAULT_VIDEO2 72 // Default video settings (TV2)
+#define RC5_DEFAULT_AUDIO2 73 // Default audio settings (TV2)
+#define RC5_PAYTV_CHANNEL_UP2 88 // Pay TV channel up (TV2)
+#define RC5_PAYTV_CHANNEL_DOWN2 89 // Pay TV channel down (TV2)
+#define RC5_RADIO_CHANNEL_UP2 90 // Radio channel up (TV2)
+#define RC5_RADIO_CHANNEL_DOWN2 91 // Radio channel down (TV2)
+#define RC5_TILT_FORWARD2 104 // Tilt cabinet forward (TV2)
+#define RC5_TILT_BACKWARD2 105 // Tilt cabinet backward (TV2)
+#define RC5_EXTERNAL3_2 120 // External 3 (TV2)
+#define RC5_EXTERNAL4_2 121 // External 4 (TV2)
+#define RC5_CHANNEL_MENU 122 // Channel setting menu
+#define RC5_PICTURE_FORMAT2 126 // 4:3 vs 16:9 (TV2)
+
+// http://en.wikipedia.org/wiki/RC-5#Command_Tables
+// Table 5, Teletext commands
+#define RC5_NEXT_PAGE 10 // Next page
+#define RC5_PREVIOUS_PAGE 11 // Previous page
+// RC5_STANDBY 12 // Standby
+#define RC5_ENTER_PAGE_NUMBER 28 // Enter page number in memory
+#define RC5_SEQ_DISPLAY 29 // Sequential display of pages
+#define RC5_SEQ_DELETE 30 // Sequential display/deletion of pages
+#define RC5_EXCHANGE 32 // Exchange (Antiope function)
+#define RC5_MAIN_INDEX 33 // Main index
+#define RC5_ROW_ZERO 34 // Row zero (Antiope function)
+#define RC5_PRINT 38 // Print displayed page
+#define RC5_MIX 39 // Mix Antiope/TV pictures
+#define RC5_HOLD_PAGE 41 // Page hold
+// RC5_TIME 42 // Display time
+#define RC5_LARGE 43 // Large top/bottom/normal
+#define RC5_REVEAL 44 // Reveal/conceal
+#define RC5_TV_TXT 45 // TV/TXT
+#define RC5_TV_TXT_SUBTITLE 46 // TV + TXT/subtitle
+// RC5_ERASE 49 // Erase/correct entry
+#define RC5_NEWS_FLASH 62 // News flash (Antiope function)
+
+// http://en.wikipedia.org/wiki/RC-5#Command_Tables
+// Table 6, LaserVision commands
+#define RC5_PICTURE_NUMBER 10 // Display picture number/time
+#define RC5_CHAPTER_NUMBER 11 // Display chapter number
+// RC5_STANDBY 12 // Standby
+// RC5_MUTE 13 // Master mute/de-mute
+// RC5_DISPLAY_INFO 15 // Display user info on screen
+#define RC5_SHUFFLE 28 // Total shuffle play/repeat once
+#define RC5_REPEAT 29 // Repeat continuously
+#define RC5_SELECT_NEXT 30 // Select next option
+#define RC5_FAST_REVERSE 31 // Fast run reverse
+#define RC5_ENTRY 32 // Entry (prepare to program)
+#define RC5_AUTO_STOP 33 // Auto-stop at pre-programmed point
+#define RC5_SLOW_REVERSE 34 // Slow run reverse
+#define RC5_STEREO_CHANNEL1 35 // Select stereo sound channel 1/language 1
+#define RC5_STEREO_CHANNEL2 36 // Select stereo sound channel 2/language 2
+#define RC5_DEC_STILL 37 // Still increment reverse
+#define RC5_INC_SPEED 38 // Increase speed
+#define RC5_DEC_SPEED 39 // Decrease speed
+#define RC5_SLOW_FORWARD 40 // Slow run forward
+#define RC5_INC_STILL 41 // Still increment forward
+#define RC5_FAST_FORWARD 42 // Fast run forward
+#define RC5_SEARCH_USER_CHOICE 43 // Automatic search for user choice
+#define RC5_SEARCH_REVERSE 44 // Search in reverse
+#define RC5_TRAY 45 // Open/close tray
+#define RC5_SEARCH_FORWARD 46 // Search forward
+#define RC5_PLAY_REVERSE 47 // Play reverse/play opposite sound track
+// RC5_PAUSE 48 // Pause
+// RC5_ERASE 49 // Erase/correct entry
+// RC5_PLAY 53 // Play
+// RC5_STOP 54 // Stop
+#define RC5_CLEAR_MEMORY 58 // Clear memory all
+#define RC5_FREEZE_SEGMENT 59 // Freeze segment(s) indicated by picture numbers.
+#define RC5_TV_TXT_ALT 60 // TV/TXT toggle; RF switch (USA only)
+#define RC5_CX 62 // CX 1, 2, 3; toggle for CX noise reduction
+
+// http://en.wikipedia.org/wiki/RC-5#Command_Tables
+// Table 11, Preamplifier commands
+#define RC5_GEQ_L 10 // Graphic equalizer left
+#define RC5_GEQ_R 11 // Graphic equalizer right
+// RC5_STANDBY 12 // Standby
+// RC5_MUTE 13 // Master mute/de-mute
+// RC5_PREFERENCES 14 // Personal preference settings
+// RC5_DISPLAY_INFO 15 // Display user info on screen
+#define RC5_GEQ_L_AND_R 28 // Graphic equalizer left and right
+#define RC5_SPEAKER_SELECT 29 // Speaker select
+#define RC5_SCRATCH_FILTER 30 // Scratch filter on/off
+#define RC5_RUMBLE_FILTER 31 // Rumble filter on/off
+#define RC5_INC_STEP 32 // Step function +
+#define RC5_DEC_STEP 33 // Step function -
+#define RC5_SIGNAL_PATH 34 // Signal path options
+#define RC5_SPEAKER_A 35 // Speaker A on/off
+#define RC5_SURROUND_OPTIONS 37 // Surround sound options
+// RC5_SLEEP_TIMER 38 // Sleep timer
+#define RC5_SPEAKER_B 39 // Speaker B on/off
+#define RC5_SPEAKER_C 40 // Speaker C on/off
+#define RC5_TIMER_PROGRAM 41 // Timer program mode
+// RC5_TIME 42 // Display time
+#define RC5_INC_TIMER 43 // Timer +
+#define RC5_DEC_TIMER 44 // Timer -
+#define RC5_TIMER_MEMORY 45 // Open timer memory
+#define RC5_ACOUSTIC_CONTROL 46 // Open acoustic control setting memory
+#define RC5_ACOUSTIC_SELECT 47 // Select acoustic settings in memory
+// RC5_ERASE 49 // Erase/correct entry
+// RC5_CLEAR_MEMORY 58 // Clear memory all
+#define RC5_DYNAMIC_EXPAND 60 // Dynamic range expand
+#define RC5_DYNAMIC_COMPRESS 62 // Dynamic range compress
+#define RC5_SURROUND_SOUND 64 // Surround sound on/off
+#define RC5_BALANCE_FRONT 65 // Balance front
+#define RC5_BALANCE_REAR 66 // Balance rear
+#define RC5_LINEAR_SOUND 79 // Scroll linear sound functions
+#define RC5_RANDOM_NOISE 88 // Random noise generator on/off
+#define RC5_TIMER 89 // Timer on/off
+#define RC5_NEWS_TIMER 90 // News timer on/off
+#define RC5_INC_CENTER_VOLUME 102 // Increase center channel volume
+#define RC5_DEC_CENTER_VOLUME 103 // Decrease center channel volume
+#define RC5_INC_DELAY_SURROUND 104 // Increase delay front to surround
+#define RC5_DEC_DELAY_SURROUND 105 // Decrease delay front to surround
+#define RC5_LINEAR_PHASE 106 // Linear phase
+#define RC5_TAPE_MONITOR 122 // Tape monitor
+
+// http://en.wikipedia.org/wiki/RC-5#Command_Tables
+// Table 14, Compact disc player commands
+#define RC5_LOCAL_CURSOR 10 // Scroll local display cursor
+#define RC5_LOCAL_FUNCTION 11 // Scroll local display function
+// RC5_STANDBY 12 // Standby
+// RC5_MUTE 13 // Master mute/de-mute
+// RC5_DISPLAY_INFO 15 // Display user info on screen
+// RC5_SHUFFLE 28 // Total shuffle play/repeat once
+// RC5_REPEAT 29 // Repeat continuously
+#define RC5_INC_SELECT 30 // Select increment
+#define RC5_DEC_SELECT 31 // Select decrement
+#define RC5_NEXT 32 // Next
+#define RC5_PREVIOUS 33 // Previous
+#define RC5_INDEX_NEXT 34 // Index next
+#define RC5_INDEX_PREVIOUS 35 // Index previous
+#define RC5_PLAY_PROGRAM 36 // Play/program
+#define RC5_NOMINAL_SPEED 37 // Speed nominal
+// RC5_INC_SPEED 38 // Increase speed
+// RC5_DEC_SPEED 39 // Decrease speed
+// RC5_STORE 41 // Store/vote
+// RC5_INC_SCAN 43 // Scan forward/increment
+// RC5_TRAY 45 // Open/close tray
+#define RC5_CARTRIDGE 47 // Fast/select disc from catridge
+// RC5_PAUSE 48 // Pause
+// RC5_ERASE 49 // Erase/correct entry
+// RC5_REWIND 50 // Rewind
+// RC5_GOTO 51 // Go to
+// RC5_WIND 52 // Wind (fast forward)
+// RC5_PLAY 53 // Play
+// RC5_STOP 54 // Stop
+// RC5_CLEAR_MEMORY 58 // Clear memory all
+#define RC5_REPEAT_AB 59 // Repeat program marked A/B
+// RC5_DYNAMIC_EXPAND 60 // Dynamic range expand
+// RC5_DYNAMIC_COMPRESS 62 // Dynamic range compress
+#define RC5_DSP 91 // Digital signal processing on/off
+#define RC5_DSP_MUSIC 92 // Music mode (DSP)
+#define RC5_DSP_ACOUSTICS 93 // Select room acoustics (DSP)
+#define RC5_DSP_JAZZ 94 // Jazz/s-hall effect (DSP)
+#define RC5_DSP_POP 95 // Pop/s-hall effect (DSP)
+#define RC5_DSP_CLASSIC 96 // Classic/church music for music/room mode (DSP)
+#define RC5_DSP_EASY 97 // Easy/club music for music/room mode (DSP)
+#define RC5_DSP_DISCO 98 // Disco/stadium music for music/room mode (DSP)
+#define RC5_SECOND_FAVORITE 107 // Second favorite track selection
+#define RC5_FAVORITE 108 // Favorite track selection
+#define RC5_TITLE_INTO_MEMORY 109 // Title into memory
+#define RC5_FADE 120 // Fade in/out audio
+
+#endif
diff --git a/libraries/IR/examples/DumpIR/DumpIR.pde b/libraries/IR/examples/DumpIR/DumpIR.pde
new file mode 100644
index 00000000..a2ad9a2c
--- /dev/null
+++ b/libraries/IR/examples/DumpIR/DumpIR.pde
@@ -0,0 +1,196 @@
+/* This example is placed into the public domain */
+
+#include
+
+IRreceiver ir;
+
+static const char *systems[32] = {
+ "TV",
+ "TV2",
+ "TXT",
+ "TV_EXT",
+ "LV",
+ "VCR",
+ "VCR2",
+ "Sys7",
+ "SAT",
+ "VCR_EXT",
+ "SAT2",
+ "Sys11",
+ "CD_VIDEO",
+ "Sys13",
+ "CD_PHOTO",
+ "Sys15",
+ "PREAMP",
+ "RADIO",
+ "REC",
+ "PREAMP2",
+ "CD",
+ "COMBI",
+ "AUDIO_SAT",
+ "REC2",
+ "Sys24",
+ "Sys25",
+ "CD_R",
+ "Sys27",
+ "Sys28",
+ "Sys29",
+ "Sys30",
+ "Sys31"
+};
+
+// Selection of TV, VCR, and CD commands to assist with command identification.
+// May not be correct for all system types.
+static const char *commands[128] = {
+ "0",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "123",
+ "11",
+ "STANDBY",
+ "MUTE",
+ "PREFERENCES",
+ "DISPLAY_INFO",
+ "INC_VOLUME",
+ "DEC_VOLUME",
+ "INC_BRIGHTNESS",
+ "DEC_BRIGHTNESS",
+ "INC_SATURATION",
+ "DEC_SATURATION",
+ "INC_BASS",
+ "DEC_BASS",
+ "INC_TREBLE",
+ "DEC_TREBLE",
+ "BALANCE_LEFT",
+ "BALANCE_RIGHT",
+ "INC_CONTRAST",
+ "DEC_CONTRAST",
+ "SEARCH_UP",
+ "DEC_TINT",
+ "CHANNEL_UP",
+ "CHANNEL_DOWN",
+ "CHANNEL_LAST",
+ "STEREO_SELECT",
+ "STEREO_SPATIAL",
+ "STEREO_TOGGLE",
+ "SLEEP_TIMER",
+ "INC_TINT",
+ "SWITCH_RF",
+ "STORE",
+ "TIME",
+ "INC_SCAN",
+ "DEC_SCAN",
+ "TRAY",
+ "SECONDARY_MENU",
+ "CLOCK",
+ "PAUSE",
+ "ERASE",
+ "REWIND",
+ "GOTO",
+ "WIND",
+ "PLAY",
+ "STOP",
+ "RECORD",
+ "EXTERNAL_1",
+ "EXTERNAL_2",
+ "CLEAR_MEMORY",
+ "VIEW_DATA",
+ "12",
+ "SYSTEM_STANDBY",
+ "CRISP",
+ "TRANSMIT_MODE",
+ "Cmd64",
+ "Cmd65",
+ "Cmd66",
+ "Cmd67",
+ "Cmd68",
+ "Cmd69",
+ "AUDIO_RESPONSE",
+ "DIM",
+ "Cmd72",
+ "Cmd73",
+ "Cmd74",
+ "Cmd75",
+ "Cmd76",
+ "INC_LINEAR",
+ "DEC_LINEAR",
+ "SOUND_FUNCTIONS",
+ "UP",
+ "DOWN",
+ "MENU_ON",
+ "MENU_OFF",
+ "AV_STATUS",
+ "LEFT",
+ "RIGHT",
+ "OK",
+ "PIP",
+ "PIP_SHIFT",
+ "PIP_SWAP",
+ "PIP_STROBE",
+ "PIP_MULTI_STROBE",
+ "PIP_FREEZE_MAIN",
+ "PIP_MULTI_SCAN",
+ "PIP_SOURCE",
+ "PIP_MOSAIC",
+ "PIP_NOISE",
+ "PIP_STORE",
+ "PIP_PHOTO_FINISH",
+ "PIP_RECALL",
+ "PIP_FREEZE",
+ "PIP_UP",
+ "PIP_DOWN",
+ "PIP_SIZE",
+ "VERSION_FUNCTIONS",
+ "COLOR_KEY",
+ "RED",
+ "GREEN",
+ "YELLOW",
+ "CYAN",
+ "INDEX",
+ "NEXT_OPTION",
+ "PREVIOUS_OPTION",
+ "Cmd114",
+ "Cmd115",
+ "Cmd116",
+ "Cmd117",
+ "SUBMODE",
+ "OPTIONS",
+ "FADE",
+ "Cmd121",
+ "STORE_OPEN_CLOSE",
+ "CONNECT_EURO",
+ "DISCONNECT_EURO",
+ "Cmd125",
+ "Cmd126",
+ "Cmd127"
+};
+
+void setup() {
+ Serial.begin(9600);
+}
+
+void loop() {
+ int cmd = ir.command();
+ if (cmd >= 0) {
+ Serial.print("IR system=");
+ Serial.print(ir.system());
+ Serial.print(" (RC5_SYS_");
+ Serial.print(systems[ir.system()]);
+ Serial.print("), command=");
+ Serial.print(cmd & 0x7F);
+ Serial.print(" (RC5_");
+ Serial.print(commands[cmd & 0x7F]);
+ Serial.print(")");
+ if (cmd & IRreceiver::AUTO_REPEAT)
+ Serial.println(", auto-repeat");
+ else
+ Serial.println();
+ }
+}
diff --git a/libraries/IR/irchip.jpg b/libraries/IR/irchip.jpg
new file mode 100644
index 00000000..912f86b6
Binary files /dev/null and b/libraries/IR/irchip.jpg differ
diff --git a/libraries/IR/keywords.txt b/libraries/IR/keywords.txt
new file mode 100644
index 00000000..df7aab67
--- /dev/null
+++ b/libraries/IR/keywords.txt
@@ -0,0 +1,8 @@
+IRreceiver KEYWORD1
+
+command KEYWORD2
+system KEYWORD2
+systemFilter KEYWORD2
+setSystemFilter KEYWORD2
+
+AUTO_REPEAT LITERAL1