By Sergio Biagioni
This article shows how to program an Arduino Mega 2560 using Simulink to receive the signals from a an R/C Receiver. The article begins with a sequence of three videos that explain how to set up, deploy and change the parameters of the RC Receive driver block. This block is placed in the Simulink model to allow the user to generate code which receives signals from an R/C receiver. After the videos, the article explains what the driver block does, how to set up the hardware, and goes over the material present in the videos in more detail.
To set up the RC Receive driver block, see the following video;
To deploy the RC Receive driver block onto the Arduino Mega 2560, see the following video;
To change the parameters of the RC Receive driver block, i.e. Sample Time and Pin Numbers, see the following video;
One common question when working with different robots is how to use an R/C controller to control it. Standard robotics has the R/C receiver send a servo-style pwm signal directly to the servo motors or the motor controller as indicated by the diagram below with Method 1. Many roboticists look to change this relationship by placing a microcontroller in between the R/C receiver and the motors as shown with Method 2. This allows the user to create fly/drive-by-wire programs on the microcontroller where you can for example, design traction control algorithms. You could even take it one step farther by using one of the channels on the R/C Controller to switch the code between different operating modes i.e. R/C control vs. Automated. This example will show how to program an Arduino Mega 2560 using Simulink to receive R/C signals. A second article will be made to demonstrate a drive-by-wire program with a four-wheel vehicle, and will show how to use one of the channels to switch between remote and autonomous modes.
Figure 1. Methods of R/C control.
The output of the R/C receiver consists of 4 servo style signals. Servo signals are pulses with a width of about 1-2 ms and a period of about 20 ms. The length of 1 ms is the minimum pulse, 2 ms is the maximum pulse and 1.5 ms is the neutral pulse. There are two types of servo motors, continuous servos and position servos. For a continuous servo, the length of the pulse corresponds to the speed of rotation. For a position servo, the length of the pulse corresponds to the angular position of the servo. When controlling aircraft with an R/C remote, the receiver is connected to position servos.
Figure 2. Servo signals [ image source ].
When a neutral pulse is sent to a continuous servo the servo stops. When a maximum pulse is sent to the continuous servo, the servo moves full speed in one direction i.e. clockwise at 180 °/s. When the minimum pulse is sent the continuous servo moves full speed in the opposite direction i.e. counterclockwise at 180 °/s . Any value in between these ranges corresponds to a particular speed.
Similarly, when a neutral pulse is sent to a position servo, the servo moves to a neutral position. When a maximum pulse is sent to a position servo, the servo moves to some angle in one direction i.e. clockwise to +90°. When the minimum pulse is sent the position servo moves to some angle in the opposite direction i.e. counterclockwise to -90°. Any value in between these ranges corresponds to a particular angle.
We recommend completing Getting Started with Arduino Mega 2560 Hardware.
To run this example you will need the following hardware:
- Controller board:
- Arduino Mega 2560 board
- USB cable
- Radio Control:
- Generic R/C controller and receiver
- Debug Circuit:
- 4x LEDs
- 4x 100 Ohm Resistor
- Connect pins 2, 3, 18, and 19 to the 4 channels on the R/C receiver.
- Supply power to the R/C receiver. I supplied 5V from the Arduino 5V pin to an ESC which then plugged into the receiver.
Figure 3. Circuit diagram.
Figure 4. Physical circuit.
Setting up the environment needs to be performed only once per version of MATLAB that you have installed. If you have performed these steps before, please ignore this section.
- Make sure that a compiler is installed. You can set up the compiler by typing (>> mex –setup) at the MATLAB command window. If no compilers show up when you type this command determine which compiler you should use and download from here:
For my Windows 7 machine running MATLAB 64-bit, I am using the Windows SDK 7.1compiler, which is free.
- Type (>> targetinstaller) to set up the Arduino
- Setting up the driver block needs to be performed only once. If you change the underlying code in the block, you will need to set up the driver block again.
- To use the custom driver block, 3 files need to be generated;
- sfcn_rcinterupt.[mex], where [mex] can be mexw32, mexw64, mexmaci64 depending on your OS and version of MATLAB. For my Windows 7 machine using MATLAB 64-bit, the extension is .mexw64.
- Open the rcreceive.slx model.
- Open the “RC Receive” S-function Builder block.
- Click “Build”
- Type (>> modify(‘sfcn_rcreceive’) at the MATLAB Command Window
- Verify that your working directory or “Current Folder” is the folder where the following files are located (i.e. C:\rcdriverblock):
2. Open the model “rcreceive” if not opened already.
3. Click the “Run” button to enter external mode.
4. If you move the joysticks corresponding to channels 1,2,3 and 4 on pins 2,3,18, and 19, the corresponding values in the Display block and Scope will change. If the values go over 1750, the corresponding LEDs will turn on.
Figure 5. Live view of joystick signals.
This driver block attaches externally triggered interrupts to the pins that are specified in the block. These interrupts are bidirectionally triggered (i.e. when the input goes from high to low or low to high). The code in this block uses the two triggers to measure the length of the input pulse. As the joystick moves in the up or right direction, the pulse gets larger, and the code returns a larger value.
For more information on this, feel free to check out the following blog, which describes the c implementation of the algorithm in the Arduino IDE:
Show how to use the R/C remote with a mobile platform, i.e. drive by wire.