00001 // IRheli.h 00002 // 00003 /// \author Mike McCauley (mikem@open.com.au) 00004 /// 00005 // Copyright (C) 2010 Mike McCauley 00006 // $Id: IRheli.h,v 1.1 2010/07/18 21:34:33 mikem Exp mikem $ 00007 00008 #ifndef IRheli_h 00009 #define IRheli_h 00010 00011 #include <IRrc.h> 00012 00013 /// Defines the channel codes for use with setChannel 00014 enum 00015 { 00016 IR_HELI_CHANNEL_A = 0x3, 00017 IR_HELI_CHANNEL_B = 0x2, 00018 IR_HELI_CHANNEL_C = 0x1, 00019 }; 00020 00021 /// Masks for octet 1 00022 #define IR_HELI_MASK_RUDDER 0xf0 00023 #define IR_HELI_MASK_ELEVATOR 0x0f 00024 00025 /// Masks for octet 2 00026 #define IR_HELI_MASK_RUDDERTRIM 0x1f 00027 00028 /// Flags in octet 2 00029 #define IR_HELI_FLAG_RUDDER_LEFT 0x80 00030 #define IR_HELI_FLAG_ELEVATOR_UP 0x40 00031 #define IR_HELI_FLAG_RUDDERTRIM_LEFT 0x20 00032 00033 ///////////////////////////////////////////////////////////////////// 00034 /// \class IRheli IRheli.h <IRheli.h> 00035 /// \brief Control class for Chinsese 3 channel Infra-red Coaxial helicopters etc. 00036 /// 00037 /// Subclass of IRrc for typical 3 channel Chinese coaxial helicopters like: 00038 /// \li MicroTwister (as relabelled in Australia) 00039 /// \li Copter V-MAX hypersonic 00040 /// \li etc. 00041 /// 00042 /// \par Basic usage 00043 /// 00044 /// \li instantiate an instance of IRheli 00045 /// \li Call setCommand when new commands become available 00046 /// \li Call poll as frequently as possible to retransmit the last command at the appropriate 00047 /// retransmission interval. 00048 /// 00049 /// The poll() call retransmits the most recently set command at an appropriate interval. 00050 /// The appropriate interval depends on the channel in use, and the intervals for each channel have been 00051 /// chosen to minimise collissions between multiple IRheli transmnitters that might be active in 00052 /// the same room at the same time. 00053 /// 00054 /// \par Protocol 00055 /// 00056 /// Protocol as described in http://www.rcgroups.com/forums/showthread.php?t=1231421&page=2 00057 /// as follows: 00058 /// Commands are preceded by the preamble and followed by the postamble 00059 /// 00060 /// byte,bit explanation. Bits numbered from MSB (transmitted first) to LSB (transmitted last) 00061 /// \li 1,1 fix (always zero) 00062 /// \li 1,2...8 throttle 00063 /// \li 2,1...4 rudder 00064 /// \li 2,5...8 elevator 00065 /// \li 3,1 1=left rudder, 0=right rudder 00066 /// \li 3,2 1=nose up, 0=nose down 00067 /// \li 3,3 1=trim left, 0=trim right 00068 /// \li 3,4...8 trim 00069 /// \li 4,1...2 channel: 11=A, 10=B, 01=C 00070 /// \li 4,3...8 checksum = sum of first 3 octets + 0x0f 00071 /// 00072 /// 00073 class IRheli : public IRrc 00074 { 00075 public: 00076 /// Constructor. 00077 IRheli(); 00078 00079 /// Specifies the channel the helico-tper listens to, A, B or C. Each helicoipter is hardwired 00080 /// For a specific channel, which is usually marked on the side of the helicopter. 00081 /// \param[in] channel Channel to use, IR_HELI_CHANNEL_A, IR_HELI_CHANNEL_C, IR_HELI_CHANNEL_C 00082 void setChannel(uint8_t channel); 00083 00084 /// Sets the comand to be sent next time poll() is called. Encodes the settings of throttle, 00085 /// rudder, elevator and ruddertrim and channel into the complete command, including checksum. 00086 /// The resulting command will be transmitted at appropriate intervals if poll() is called frequently 00087 /// enough. 00088 /// \param[in] throttle Throttle setting. 0 is min, max is 255 00089 /// \param[in] rudder Rudder setting. 0 = full left, 127 = neutral 255 = full right 00090 /// \param[in] elevator Elevator setting. 0 = full nose down, 127 = neutral 255 = full nose up 00091 /// \param[in] ruddertrim RudderTrim setting. 0 = full left, 127 = neutral 255 = full right 00092 void setCommand(uint8_t throttle, uint8_t rudder, uint8_t elevator, uint8_t ruddertrim); 00093 00094 /// Sends immediately a command for the specified control setting. The same command will be sent 00095 /// thereafer when poll() is called and a retransmission is required. 00096 /// Caution: blocks until the command is sent. 00097 /// \param[in] throttle Throttle setting. 0 is min, max is 255 00098 /// \param[in] rudder Rudder setting. 0 = full left, 127 = neutral 255 = full right 00099 /// \param[in] elevator Elevator setting. 0 = full nose down, 127 = neutral 255 = full nose up 00100 /// \param[in] ruddertrim RudderTrim setting. 0 = full left, 127 = neutral 255 = full right 00101 void sendCommand(uint8_t throttle, uint8_t rudder, uint8_t elevator, uint8_t ruddertrim); 00102 00103 /// If a command is due to be retransmitted, resends the last set command. 00104 /// Caution: If a command is to be sent, blocks for about 40ms until the command is sent. 00105 void poll(); 00106 00107 protected: 00108 /// Sends the most recently set command 00109 void sendCurrentCommand(); 00110 00111 /// The currently selected channel, as set by setChannel(). Defaults to IR_HELI_CHANNEL_A. 00112 uint8_t _channel; 00113 00114 private: 00115 00116 /// Time the last command was sent in milliseconds 00117 unsigned long _lastCommandTime; 00118 00119 /// The most recently set command. 00120 uint8_t _commandRaw[4]; 00121 }; 00122 00123 #endif