00001 // IRrc.h 00002 // 00003 // IRrc class for infra-red control 00004 // 00005 // Copyright (C) 2010 Mike McCauley 00006 // $Id: IRrc.h,v 1.1 2010/07/18 21:34:33 mikem Exp mikem $ 00007 00008 ///\mainpage IRrc library for Arduino 00009 /// 00010 /// IRrc provides classes for controlling a range of infra-red controlled devices such as 3 channel 00011 /// IR model helicopters and others. Such models all use a similar IR encoding scheme which is 00012 /// implemented in the IRrc class. Subclasses such as IRheli provide specific implementations and 00013 /// timings for a specific type of model or other device. 00014 /// 00015 /// Videos explaining how it works and what you can do with it can be found at: 00016 /// \li http://www.youtube.com/watch?v=CHZbIvcC5I0 00017 /// \li http://www.youtube.com/watch?v=lzRpyqnD6_M 00018 /// 00019 /// The version of the package that this documentation refers to can be downloaded 00020 /// from http://www.open.com.au/mikem/arduino/IRrc/IRrc-1.2.zip 00021 /// You can find the latest version at http://www.open.com.au/mikem/arduino/IRrc 00022 /// 00023 /// Tested on Arduino Duemilanove, Diecimila, Mega and Asynclabs Yellowjacket 00024 /// with arduino-0018 on OpenSuSE 11.1 00025 /// and avr-libc-1.6.2-5.11, 00026 /// cross-avr-binutils-2.19-9.1 and cross-avr-gcc43-4.3.3_20081022-9.3. 00027 /// 00028 /// IRrc can also interoperate with the RCKit libbary at http://www.open.com.au/mikem/arduino/RCKit to 00029 /// create infra-red models that can be controlled from your iPhone with the RCTx app from the Apple App Store 00030 /// at http://itunes.apple.com/app/rctx/id377833472?mt=8 00031 /// 00032 /// The Infra-Red protocol is a 38kHz carrier, modulated with a preamble, a variable number of octets 00033 /// followed by a postamble. Timings are specific for a particular model. 00034 /// 00035 /// The IRheli class provides a specific implementation for a Chinese 3 channel co-axial model helicopter. 00036 /// 00037 /// \par Basic usage 00038 /// 00039 /// You must instantiate a subclass of the IRrc class, such as the IRheli class. By default it will control 00040 /// an infra-red transmitter connected to Arduino digital output pin 3 (pin 9 on Arduino Mega). 00041 /// You then call sendMessage() 00042 /// (or a derivative) to send messages to the controlled device. IRrc will then modulate the infra-red 00043 /// tranmitter on the output pin according to the timings defined by the subclass. 00044 /// 00045 /// The carrier output is from PWM timer 2, with 50% duty cycle. It is turned on and off according to the 00046 /// bit timings and the bits in the message to be transmitted. 00047 /// 00048 /// \par Example Sketches 00049 /// 00050 /// 2 Example Arduino sketches are provided in the examples directory of the distribution 00051 /// to demonstrate the use of these classes: 00052 /// 00053 /// \li HeliDemo 00054 /// Receives simple commands on the Serial port and turns them into Infr-red commands for a 00055 /// coaxial helicopter using the IRheli class. A corresponding program js.pl, a Perl program for Linux, 00056 /// reads a Logitech or similar 00057 /// joystick and sends complying commands on a Serial port. This allows a 00058 /// coaxial helicopter to be controlled using a Logitech joystick connected to a Linux computer. 00059 /// js.pl can be found in the perl directory of the IRrc distribution. 00060 /// 00061 /// \li HeliRCRx 00062 /// Implements a RCRx Wi-Fi receiver, that receives RCOIP commands from an RCOIP compliant 00063 /// controller such as the iPhone RCTx transmitter and controls a 00064 /// coaxial helicopter using the IRheli class. Requires the RCRx library available from 00065 /// http://www/.open.com.au/mikem/arduino/RCRx and the RCTx iPhone app from 00066 /// http://itunes.apple.com/app/rctx/id377833472?mt=8 00067 /// This is the sketch that was used in the video http://www.youtube.com/watch?v=lzRpyqnD6_M 00068 /// 00069 /// \li USBJoystickHeli 00070 /// Controls a helicopter with a Logitech USB game pad connected to a Sparkfun USB Host shield. 00071 /// Requires the USB_Host_Shield library. The game pad is 00072 /// used as a mode 2 controller: throttle on left stick, elevator and rudder on right stick. 00073 /// Includes elevator and rudder trim buttons with button 1, 2, 3, 4. 00074 /// This is the sketch that was used in the video http://www.youtube.com/watch?v=CHZbIvcC5I0 00075 /// 00076 /// \par Electrical 00077 /// 00078 /// You can get a short range IR output by connecting an IR LED directly to an Arduino output pin and ground. 00079 /// This will provide about 25mA of drive for the LED, which is about 1/40th of what a commonly 00080 /// available IR LED is capable of, but will work for short ranges. 00081 /// 00082 /// A better alternative for greater range is to use a transistor driver to drive a higher current 00083 /// through several IR LEDs. See <a href="LED-Output.pdf">LED-Output.pdf</a> for 00084 /// sample circuit diagrams for LED connections. 00085 /// 00086 /// \par Installation 00087 /// 00088 /// Install in the usual way: unzip the distribution zip file to the libraries 00089 /// sub-folder of your sketchbook. 00090 /// 00091 /// \author Mike McCauley (mikem@open.com.au) 00092 /// 00093 /// This software and is Copyright (C) 2010 Mike McCauley. Use is subject to license 00094 /// conditions. The main licensing options available are GPL V2 or Commercial: 00095 /// 00096 /// \par Open Source Licensing GPL V2 00097 /// This is the appropriate option if you want to share the source code of your 00098 /// application with everyone you distribute it to, and you also want to give them 00099 /// the right to share who uses it. If you wish to use this software under Open 00100 /// Source Licensing, you must contribute all your source code to the open source 00101 /// community in accordance with the GPL Version 2 when your application is 00102 /// distributed. See http://www.gnu.org/copyleft/gpl.html 00103 /// 00104 /// \par Commercial Licensing 00105 /// This is the appropriate option if you are creating proprietary applications 00106 /// and you are not prepared to distribute and share the source code of your 00107 /// application. Contact info@open.com.au for details. 00108 /// 00109 /// \par Revision History 00110 /// \version 1.0 Initial release 00111 /// \version 1.1 Added videos and USBJoystickHeli example 00112 /// \version 1.2 Compiles under Ardiono 1.0 00113 00114 #ifndef IRrc_h 00115 #define IRrc_h 00116 #include <inttypes.h> 00117 00118 #define SYSCLOCK 16000000 // main Arduino clock 00119 00120 ///////////////////////////////////////////////////////////////////// 00121 /// \class IRrc IRrc.h <IRrc.h> 00122 /// \brief Low level infa-red output modulator, compatible with a number of infra-red controlled toys 00123 /// This is an abstract class that must be subclassed. 00124 /// Subclasses customise timings etc for particular toys and protocols. 00125 /// 00126 class IRrc 00127 { 00128 public: 00129 /// Constructor. 00130 IRrc(); 00131 00132 /// Sends the message pointed to by msg, with length len octets. Message is precended by the preamble 00133 /// with sendPreamble() and followed by the postamble with sendPostamble(). 00134 /// Each bit in the message is sent with the carrier enabled for the on time and disabled for the off time. 00135 /// Each octet is sent most significant bit first. 00136 /// Caution: this call blocks until the postamble has been sent 00137 /// \param[in] msg Pointer to the octets to be sent 00138 /// \param[in] len Message length in octets 00139 void sendMessage(const uint8_t* msg, uint8_t len); 00140 00141 /// Sends the preamble, which consists of the carrier on for the _preamble time, followed by carrier off 00142 /// for the _preambleGap time. 00143 void sendPreamble(); 00144 00145 /// Send the postamble which consists by default of a single One bit sent with sendOne() 00146 void sendPostamble(); 00147 00148 /// Encodes and sends a Zero bit, with the carrier on for _zeroOnTime microseconds, followed by 00149 /// off for _zeroOffTime microseconds. 00150 void sendZero(); 00151 00152 /// Encodes and sends a One bit, with the carrier on for _oneOnTime microseconds, followed by 00153 /// off for _oneOffTime microseconds. 00154 void sendOne(); 00155 00156 /// Enables IR output. The _carrierFrequency value controls the carrier frequency in Hertz. 00157 /// The IR output will be on pin 3 (OC2B) on most platforms, pin 9 on Arduino Mega. 00158 void enableCarrier(); 00159 00160 /// Disables the IR output, if necessary. 00161 /// The default implmentation does nothing. 00162 void disableCarrier(); 00163 00164 /// Turns the carrier on for the specified time. 00165 /// Blocks until complete. 00166 /// \param[in] time Time on in microseconds 00167 void carrierOn(uint16_t time); 00168 00169 /// Turns the carrier off for the specified time. 00170 /// Blocks until complete. 00171 /// \param[in] time 00172 void carrierOff(uint16_t time); 00173 00174 protected: 00175 // Subclasses have to set these in their constructor 00176 00177 /// IR Carrier frequence in Hertz 00178 uint16_t _carrierFrequency; 00179 00180 /// Length of the preamble carrier on time in microseconds 00181 uint16_t _preamble; 00182 00183 /// Length of the preamble gap off time in microseconds 00184 uint16_t _preambleGap; 00185 00186 /// Time that the carrier is on at the start of a Zero bit in microseconds 00187 uint16_t _zeroOnTime; 00188 00189 /// Time that the carrier is off at the end of a Zero bit in microseconds 00190 uint16_t _zeroOffTime; 00191 00192 /// Time that the carrier is on at the start of a One bit in microseconds 00193 uint16_t _oneOnTime; 00194 00195 /// Time that the carrier is off at the end of a One bit in microseconds 00196 uint16_t _oneOffTime; 00197 00198 private: 00199 }; 00200 00201 #endif