RcTrainer
RcTrainer.h
1 // RcTrainer.h
2 // Author: Mike McCauley (mikem@airspayce.com)
3 // Copyright (C) 2013 Mike McCauley
4 // $Id: $
5 //
6 /// \mainpage RcTrainer library for Arduino
7 ///
8 /// This is the Arduino RcTrainer library.
9 /// It provides the ability to read the PPM encoded signal from an RC transmitter in trainer mode
10 /// containing the PPM encoded position of the servo channels.
11 ///
12 /// Many RC transmitters provide a trainer output that is designed to allow 2 tranmsitters
13 /// to be connected for training purposes. The transmitter has a socket for a training cable.
14 /// When configured for training, the tranmitter emits a signal on that socket that encodes the position
15 /// of all the transmitters control channels
16 ///
17 /// This library allows you to connect that training output signal to an Arduino, and to read the
18 /// channel outputs to control the Arduino.
19 ///
20 /// Example Arduino programs are included to show the main modes of use.
21 ///
22 /// The version of the package that this documentation refers to can be downloaded
23 /// from http://www.airspayce.com/mikem/arduino/RcTrainer/RcTrainer-1.0.zip
24 /// You can find the latest version at http://www.airspayce.com/mikem/arduino/RcTrainer
25 ///
26 /// \par Transmitters
27 ///
28 /// This library has been tested with the following transmitters:
29 ///
30 /// -Spektrum DX6i. The DX6i has a 3.5mm mono phone socket on the back. The signal is 3.3V p-p, normally high.
31 /// When you plug into the 'TRAINER' socket on the back, the transmitter comes on and sends the PPM signal
32 /// on the TRAINER socket. No radio signal is transmitted. Tested with Arduino Uno.
33 ///
34 /// \par Connecting to Arduino
35 ///
36 /// The connection between the transmitter and the Arduino must be electrically compatible,
37 /// and the connection must be made to one of the interrupt capable pins on the Arduino.
38 ///
39 /// Some transmitters emit a 3.3V signal. This is compatible with a 3.3V Arduino, and may be compatible with
40 /// a 5V Arduino.
41 ///
42 /// Some tramsmitters emit a 5V signal. This is compatible with a 5V Arduino, and may be compatible with
43 /// a 3.3V Arduino, provided the input is 5V tolerant.
44 ///
45 /// The transmitter must be connected to one of the interrupt capable pins. On Arduino Uno for example,
46 /// this means digital inputs D2 or D3 only. Other Arduinos may have the interrupts on other pins and
47 /// there may be more interrupts.
48 ///
49 /// Example for Spektrum DX6i and Arduino Uno:
50 /// \code
51 /// Arduino Spektrum DX6i
52 /// D2-----------TIP
53 /// GND----------RING
54 /// \endcode
55 ///
56 /// \par Installation
57 ///
58 /// Install in the usual way: unzip the distribution zip file to the libraries
59 /// sub-folder of your sketchbook.
60 ///
61 /// This software is Copyright (C) 2011 Mike McCauley. Use is subject to license
62 /// conditions. The main licensing options available are GPL V2 or Commercial:
63 ///
64 /// \par Open Source Licensing GPL V2
65 ///
66 /// This is the appropriate option if you want to share the source code of your
67 /// application with everyone you distribute it to, and you also want to give them
68 /// the right to share who uses it. If you wish to use this software under Open
69 /// Source Licensing, you must contribute all your source code to the open source
70 /// community in accordance with the GPL Version 2 when your application is
71 /// distributed. See http://www.gnu.org/copyleft/gpl.html
72 ///
73 /// \par Commercial Licensing
74 ///
75 /// This is the appropriate option if you are creating proprietary applications
76 /// and you are not prepared to distribute and share the source code of your
77 /// application. Contact info@airspayce.com for details.
78 ///
79 /// \par Revision History
80 ///
81 /// \version 1.0 Initial release
82 
83 #ifndef RCTRAINER_h
84 #define RCTRAINER_h
85 
86 #if ARDUINO >= 100
87 #include <Arduino.h>
88 #else
89 #include <wiring.h>
90 #endif
91 
92 // These defs cause trouble on some versions of Arduino
93 #undef round
94 #undef double
95 
96 /////////////////////////////////////////////////////////////////////
97 /// \class RcTrainer RcTrainer.h <RcTrainer.h>
98 /// \brief Read servo positions from RC Transmitter in Trainer mode
99 ///
100 /// This class provides the ability to read servo positions from a PPM encoded
101 /// digital signal, such as the one emitted by an RC traansmitter in Trainer mode.
103 {
104 public:
105 /// Maximum number of permitted channels.
106 #define RCTRAINER_MAX_CHANNELS 10
107 /// Minimum interfame interval in microseconds
108 #define RCTRAINER_MIN_INTERFRAME_INTERVAL 3000
109 
110  /// Constructor
111  /// Creates a new RcTrainer. You have multiple RcTrainer instances connected to
112  /// different inputs. If the interrupt number is out of
113  /// range for your processor, RcTrainer will silently fail to work correctly.
114  /// \param[in] interrupt This is the number of the interrupt pin (not the digital input pin number)
115  /// that is connected to the transmitter. The mapping from interrupt number to digital pin number
116  /// depends on your Arduino. See http://arduino.cc/en/Reference/attachInterrupt for details
117  RcTrainer(uint8_t interrupt = 0);
118 
119  /// Read the raw channel value for the specified channel.
120  /// The raw channel value is the length of the PPM pulse for that channel in microseconds
121  /// The range of values seen will depend on your transmitter, and the position of the stick
122  /// connected to that channel, and the configuration of the transmitter.
123  /// On the DX6i, the range of raw channel values varies from about 1096 to 1916, with
124  /// the stick midpoints at about 1512.
125  /// \param[in] channel The number of the channel to get.
126  /// \return The raw channel value in microseconds. If the channel number is out of range for that
127  /// transmitter, or if it is more than RCTRAINER_MAX_CHANNELS, returns 0.
128  int16_t getChannelRaw(uint16_t channel);
129 
130  /// Reads a scaled channel value
131  /// The raw channel value for the selected channel is mapped according to the specified parameters
132  /// so that the result always lies in the range mapToLow to mapToHigh.
133  /// Raw alues are scaled using the Arduino map() function, so that raw values in the range
134  /// mapFromLow to mapFromHigh are scaled to lie in the range mapToLow to mapToHigh.
135  /// The result is contrained to lie in the range mapToLow to mapToHigh.
136  /// The default values are suitable for use with the DX6i, and scale the channels to the range 0-1023.
137  /// \param[in] channel The number of the channel to get.
138  /// \param[in] mapFromLow
139  /// \param[in] mapFromHigh
140  /// \param[in] mapToLow
141  /// \param[in] mapToHigh
142  /// \return The raw channel value scaled according to the map arguments.
143  /// If the channel number is out of range for that
144  /// transmitter, or if it is more than RCTRAINER_MAX_CHANNELS, returns 0 scaled as per the map arguments
145  int16_t getChannel(int16_t channel, int16_t mapFromLow = 1096, int16_t mapFromHigh = 1916, int16_t mapToLow = 0, int16_t mapToHigh = 1023);
146 
147 private:
148  /// Array of instances connected to interrupts 0 to 6
149  static RcTrainer* _RcTrainerForInterrupt[];
150 
151  uint8_t _nextChannelNumber;
152  uint16_t _channels[RCTRAINER_MAX_CHANNELS];
153  uint32_t _lastInterruptTime;
154 
155  void interruptHandler();
156  static void interruptHandler0();
157  static void interruptHandler1();
158  static void interruptHandler2();
159  static void interruptHandler3();
160  static void interruptHandler4();
161  static void interruptHandler5();
162 };
163 
164 /// @example dx6i.ino
165 /// Print out servo positions from a Spektrum DX6i in trainer mode
166 
167 #endif