IRrc
IRheli.h
1 // IRheli.h
2 //
3 /// \author Mike McCauley (mikem@airspayce.com)
4 ///
5 // Copyright (C) 2010 Mike McCauley
6 // $Id: IRheli.h,v 1.1 2010/07/18 21:34:33 mikem Exp mikem $
7 
8 #ifndef IRheli_h
9 #define IRheli_h
10 
11 #include <IRrc.h>
12 
13 /// Defines the channel codes for use with setChannel
14 enum
15 {
16  IR_HELI_CHANNEL_A = 0x3,
17  IR_HELI_CHANNEL_B = 0x2,
18  IR_HELI_CHANNEL_C = 0x1,
19 };
20 
21 /// Masks for octet 1
22 #define IR_HELI_MASK_RUDDER 0xf0
23 #define IR_HELI_MASK_ELEVATOR 0x0f
24 
25 /// Masks for octet 2
26 #define IR_HELI_MASK_RUDDERTRIM 0x1f
27 
28 /// Flags in octet 2
29 #define IR_HELI_FLAG_RUDDER_LEFT 0x80
30 #define IR_HELI_FLAG_ELEVATOR_UP 0x40
31 #define IR_HELI_FLAG_RUDDERTRIM_LEFT 0x20
32 
33 /////////////////////////////////////////////////////////////////////
34 /// \class IRheli IRheli.h <IRheli.h>
35 /// \brief Control class for Chinsese 3 channel Infra-red Coaxial helicopters etc.
36 ///
37 /// Subclass of IRrc for typical 3 channel Chinese coaxial helicopters like:
38 /// \li MicroTwister (as relabelled in Australia)
39 /// \li Copter V-MAX hypersonic
40 /// \li etc.
41 ///
42 /// \par Basic usage
43 ///
44 /// \li instantiate an instance of IRheli
45 /// \li Call setCommand when new commands become available
46 /// \li Call poll as frequently as possible to retransmit the last command at the appropriate
47 /// retransmission interval.
48 ///
49 /// The poll() call retransmits the most recently set command at an appropriate interval.
50 /// The appropriate interval depends on the channel in use, and the intervals for each channel have been
51 /// chosen to minimise collissions between multiple IRheli transmnitters that might be active in
52 /// the same room at the same time.
53 ///
54 /// \par Protocol
55 ///
56 /// Protocol as described in http://www.rcgroups.com/forums/showthread.php?t=1231421&page=2
57 /// as follows:
58 /// Commands are preceded by the preamble and followed by the postamble
59 ///
60 /// byte,bit explanation. Bits numbered from MSB (transmitted first) to LSB (transmitted last)
61 /// \li 1,1 fix (always zero)
62 /// \li 1,2...8 throttle
63 /// \li 2,1...4 rudder
64 /// \li 2,5...8 elevator
65 /// \li 3,1 1=left rudder, 0=right rudder
66 /// \li 3,2 1=nose up, 0=nose down
67 /// \li 3,3 1=trim left, 0=trim right
68 /// \li 3,4...8 trim
69 /// \li 4,1...2 channel: 11=A, 10=B, 01=C
70 /// \li 4,3...8 checksum = sum of first 3 octets + 0x0f
71 ///
72 ///
73 class IRheli : public IRrc
74 {
75 public:
76  /// Constructor.
77  IRheli();
78 
79  /// Specifies the channel the helico-tper listens to, A, B or C. Each helicoipter is hardwired
80  /// For a specific channel, which is usually marked on the side of the helicopter.
81  /// \param[in] channel Channel to use, IR_HELI_CHANNEL_A, IR_HELI_CHANNEL_C, IR_HELI_CHANNEL_C
82  void setChannel(uint8_t channel);
83 
84  /// Sets the comand to be sent next time poll() is called. Encodes the settings of throttle,
85  /// rudder, elevator and ruddertrim and channel into the complete command, including checksum.
86  /// The resulting command will be transmitted at appropriate intervals if poll() is called frequently
87  /// enough.
88  /// \param[in] throttle Throttle setting. 0 is min, max is 255
89  /// \param[in] rudder Rudder setting. 0 = full left, 127 = neutral 255 = full right
90  /// \param[in] elevator Elevator setting. 0 = full nose down, 127 = neutral 255 = full nose up
91  /// \param[in] ruddertrim RudderTrim setting. 0 = full left, 127 = neutral 255 = full right
92  void setCommand(uint8_t throttle, uint8_t rudder, uint8_t elevator, uint8_t ruddertrim);
93 
94  /// Sends immediately a command for the specified control setting. The same command will be sent
95  /// thereafer when poll() is called and a retransmission is required.
96  /// Caution: blocks until the command is sent.
97  /// \param[in] throttle Throttle setting. 0 is min, max is 255
98  /// \param[in] rudder Rudder setting. 0 = full left, 127 = neutral 255 = full right
99  /// \param[in] elevator Elevator setting. 0 = full nose down, 127 = neutral 255 = full nose up
100  /// \param[in] ruddertrim RudderTrim setting. 0 = full left, 127 = neutral 255 = full right
101  void sendCommand(uint8_t throttle, uint8_t rudder, uint8_t elevator, uint8_t ruddertrim);
102 
103  /// If a command is due to be retransmitted, resends the last set command.
104  /// Caution: If a command is to be sent, blocks for about 40ms until the command is sent.
105  void poll();
106 
107 protected:
108  /// Sends the most recently set command
109  void sendCurrentCommand();
110 
111  /// The currently selected channel, as set by setChannel(). Defaults to IR_HELI_CHANNEL_A.
112  uint8_t _channel;
113 
114 private:
115 
116  /// Time the last command was sent in milliseconds
117  unsigned long _lastCommandTime;
118 
119  /// The most recently set command.
120  uint8_t _commandRaw[4];
121 };
122 
123 #endif