Simultaneously Reading Two PWM Signals from an RC Receiver with Arduino

Written by: Brandon Tsuge

|

|

Time to read min

In this post, I build on a previous blog entry and show how to simultaneously read two PWM signals from an RC receiver.

Parts Needed

For this example, you'll need:

The only difference between the parts needed for this example and the parts used in the previous example is that there will be additional jumpers needed to connect to the second RC receiver channel.

Wiring the Circuit

  • Start by connecting 5V and ground to channel 3 on the receiver.

  • Then connect the signal pin on the receiver to pin 2 on the Arduino.

  • Next connect the signal from channel 4 to pin 3 on the Arduino.

  • The ground on channel 4 should also be connected to ground on the Arduino.

  • It is not necessary to connect 5V to this channel since, the 5V connected to channel 3 powers the entire receiver.

  • Pins 2 and 3 are used because these are the only pins that are capable of external interrupts on the Arduino Uno.

Below is the wiring diagram for this circuit.

Remote Control Wiring Diagram

Arduino Code

For algorithmic simplicity, create two sets of variables and two separate functions for each RC channel. Start by defining the variables RCPinFWD to 2 and RCPinSide to 3. These are pin assignments for the two different channels.

#define RCPinFWD 2
#define RCPinSide 3 

Then create volatile long variables StartTimeFWD, CurrentTimeFWD, and PulsesFWD. In addition, create an integer variable PulseWidthFWD. All of these should be initialized to 0. Use the same naming convention to create the variables for the side-to-side channel.

volatile long StartTimeFWD = 0;
volatile long CurrentTimeFWD = 0;
volatile long PulsesFWD = 0;
int PulseWidthFWD = 0;

volatile long StartTimeSide = 0;
volatile long CurrentTimeSide = 0;
volatile long PulsesSide = 0;
int PulseWidthSide = 0;

In the setup, set the baud rate to 9600 and both pins to INPUT_PULLUP

  Serial.begin(9600);
  pinMode(RCPinFWD, INPUT_PULLUP);
  pinMode(RCPinSide, INPUT_PULLUP);

Next create interrupts for both pins with the following lines of code:

  attachInterrupt(digitalPinToInterrupt(RCPinFWD),PulseTimerFWD,CHANGE);
  attachInterrupt(digitalPinToInterrupt(RCPinSide),PulseTimerSide,CHANGE);

These will call the functions PulseTimerFWD or PulseTimerSide whenever a change in the signal is detected from pins 2 or 3. Both of these functions carry out the same instructions for their associated pins. For example, for the forward channel, PulseTimerFWD starts by setting the variable CurrentTimeFWD to micros(), which outputs the time that the sketch has been running in microseconds. Then, if CurrentTimeFWD is greater than StartTimeFWD, subtract CurrentTimeFWD by StartTimeFWD and save it to PulsesFWD. Then, reset StartTimeFWD by setting it equal to CurrentTimeFWD. Repeat this for the other channel with the same naming convention.

void PulseTimerFWD(){
  CurrentTimeFWD = micros();
  if (CurrentTimeFWD > StartTimeFWD){
    PulsesFWD = CurrentTimeFWD - StartTimeFWD;
    StartTimeFWD = CurrentTimeFWD;
  }
}
void PulseTimerSide(){
  CurrentTimeSide = micros();
  if (CurrentTimeSide > StartTimeSide){
    PulsesSide = CurrentTimeSide - StartTimeSide;
    StartTimeSide = CurrentTimeSide;
  }
}

In the loop, if PulsesFWD is less than 2000, save it to the PulseWidthFWD variable. Repeat this for the side-to-side channel as well. Lastly, create the print statements.

void loop() {
  //only save pulse lengths that are less than 2000 microseconds
  if (PulsesFWD < 2000){
    PulseWidthFWD = PulsesFWD;
  } 
  if (PulsesSide < 2000){
    PulseWidthSide = PulsesSide;
  } 
  Serial.print(PulseWidthFWD);
  Serial.print("    ");
  Serial.println(PulseWidthSide);
}

After uploading the serial plotter will show the signals being read from both channels. The completed Arduino sketch can be found here.

RC Receiver Reading with Arduino

The Bored Robot LLC is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to Amazon.com