RC Interface (DxI/DxO)

The Basics

The Arduino Nano Carrier makes it easy to use the Arduino Nano with standard radio control (RC) components, such as radio receivers and servos. Eight channels of RC interface pins are provided at the top of the Arduino Nano Carrier board. For each channel, there is an input and and output. The inputs are labeled DxI and the output are labeled DxO, where x = {2,3,...,9} to correspond to an Arduino Nano digital I/O pin number.

Each input and each output has three pins which correspond to a standard RC interface cable (a.k.a. servo cable, receiver cable, or PWM cable).  The three pins connect to ground, 5V, and a signal. The table below summarizes the purposes of these connections, which differ between the inputs and outputs.

 Digital Inputs
(D2I, D3I, ... , D9I)

Ground (GND):
Signal ground (connected to power ground in one place on the Arduino Nano Carrier).

Power (5V):
Signal 5V supply, sourced from the Arduino Nano's on-board regulator capable of supplying up to 500mA (total). This can supply the radio receiver with a clean 5V. See the power supply section for more details.

Signal (SIG):
Input signal (PWM) from a single radio receiver channel. Set the corresponding pin on the Arduino Nano as an INPUT.
Digital Outputs
(D2O, D3O, ... , D9O)

Ground (GND):
Power ground (connected to signal ground in one place on the Arduino Nano Carrier).

Power (5V):
Power 5V supply, sourced from the switching regulator. This can supply up to 3A (total) to drive servos. See the power supply section for more details.

Signal (SIG):
Output signal (PWM) to a single servo or motor controller. Set the corresponding pin on the Arduino Nano as an OUTPUT.

Standard RC interface cable is either {black, red, white} or {brown, orange, yellow}. In either case, the darkest color is GND, the middle is 5V, and the lightest is SIG. For example:

If you are having trouble reading in a receiver signal or controlling a servo, check that the cable is connected correctly.

By virtue of the connections on the Arduino Nano Carrier, each channel can be used in one of the following three modes:
  • Receiver input only: Connect only DxI, set the corresponding Arduino Nano pin Dx as an INPUT, and use pulseIn() to read in signals from a receiver.
  • Servo output: Connect DxO and set the Arduino Nano pin Dx as an OUTPUT. Use digitalWrite() and delayMicroseconds() or the Arduino servo library to produce output signals to control a servo or motor controller. In this state, input signals are ignored even if DxI is connected.
  • Pass-through: Connect DxI and DxO and set the Arduino Nano pin Dx as an INPUT. In this mode, signals are passed directly from DxI to DxO, with no action from the Arduino Nano. 
Note: You must turn off the Arduino Nano microprocessor's internal pull-up resistors when Dx is set as an INPUT. To do this, you can use digitalWrite(x,LOW) where x is the pin number or the following global pull-up disable command (works on all pins):

MCUCR |= (1 << PUD);

The following sections explain the nature of the RC interface signal (PWM) and the connections on the Arduino Nano Carrier that create these three modes, as well as how they can be used to switch between autonomous and radio control (or a mix of both).

RC Interface Signal (PWM)

The white or yellow wire of the RC interface cable carries a digital signal that corresponds to a position command (for a servo) or a speed command (for a motor). As a digital signal, the voltage is either high (5V) or low (0V). The signal conveys information in a sequence of 5V pulses, and it is the duration, or width, of the pulse that matters:

A neutral pulse is 1.5ms in width. The two extremes are typically 1.0ms and 2.0ms, though some servos or controllers accept wider bands. The time between pulses is typically 20ms, though it can vary greatly without affecting the servo performance. However, servos will "time out" or stop running after some time without a command. Typically, 10-20ms between pulses is safe.

The Arduino programming environment has convenient functions and libraries for working with RC interface signals. They are:
  • The pulseIn() function, which reads in the pulse width in microseconds and stores it in a variable.
  • The servo library, which contains functions for automatically generating servo pulses on output pins with the correct pulse timing.

RC Interface Modes

The three modes listed above are a byproduct of both physical connections between DxI, DxO, and the Arduino Nano pin Dx and software switches that change the function of the Arduino Nano pin. To illustrate this, a simplified schematic of a single channel (2) is presented below in each of the three states. All eight channels follow the same format.

First, as a receiver input only:

In this mode, only D2I is connected (to the radio receiver). Pin D2 is set as an INPUT using pinMode(2, INPUT). This command disconnects the D2 output signal. Additionally, digitalWrite(2, LOW) is used to disconnect the internal pull-up resistor, which otherwise connects D2 to 5V. The D2 input is connected solely to the radio receiver and can read in pulses using the pulseIn(2,HIGH) command.

Next, as a servo output:

Now, a servo is connected to D2O. Pin D2 is set as an OUTPUT using pinMode(2, OUTPUT). This connectes the D2 output signal, which can be generated by digitalWrite() or by the servo libarary. Because of the 2.2kΩ resistor between D2O and D2I, the D2 output signal generated by the Arduino will take precedence even if the radio receiver is connected to D2I. The path of least resistance is from the D2 output signal to the servo. The state of the pull-up resistor does not matter in this mode.

Finally, as a pass-through channel:

In this mode, pin D2 is again configured as an input (and the pull-up resistor disabled). Now, a servo is connected to D2O. Because the path of least resistance (in fact the only path) is from D2I to D2O, through the 2.2kΩ resistor, the receiver signal controls the servo directly, as if the servo were plugged into that receiver channel. No programming is required to "pass" the signal through.

Simple RC/Autonomous Switch

A simple way to set up a robot capable of both autonomous and radio control would be to use the servo output and pass-through modes described above. In this configuration, both DxI and DxO are used:

In this mode, each receiver channel is mapped directly to a servo: {1:A, 2:B, 3:C, 4:D}. As a consequence, in pass-through mode, no re-mapping is possible; the receiver controls the servos exactly as it would if they were connected directly to it. However, by putting specific channels into servo output mode, you can selectively enable the autonomous control on that channel, where the Arduino Nano's output signal overrides that of the radio receiver. Because this is done on a channel-by-channel basis, it is possible to have some autonomous and some RC channels at the same time.

RC/Autonomous Switch with Remapping

The disadvantage of the simple configuration above is that it does not afford any possibility of remapping servo channels for more complex radio control algorithms. To overcome this, you can use four separate input and output channels:

Now, D2I-D5I are used in receiver input only mode and D6O-D9O are used in servo output mode. This decouples the receiver channels from specific servos. The Arduino Nano can remap receiver channels in software. This can be useful for things like mixing left and right drive onto a single joystick, or activating more complex maneuvers with only four inputs.

The disadvantage of this configuration is that the Arduino Nano must put out servo signals at all times, either remapped or relayed from the receiver or generated autonomously. There is no way to simply revert to radio control.

There are many other modes, including combinations of the two presented here, that can be used to create complex radio control, autonomous and semi-autonomous controllers.

Further reading: RC Controller sample code and single-stick driving.
For code examples, see Extended Servo Range.
Excellent Sparkfun tutorial: https://www.sparkfun.com/tutorials/348