I am writing a basic autopilot for an RC plane using some sensors. I have programmed a function that allows for the autopilot to be disabled and allows for user control of the aircraft (fixed wing).

This means i need to use a pulseIN to read the PMW signal from the RC receiver and just relay it out to the wing servos+esc.

How can i relay this PMW signal from receiver to motors via the arduino. I want to do this so the autopilot can be disabled.

I'm not clear what the problem is. Can you read the signals from each channel output of the RC receiver? If so don't you just replace the values the autopilot would normally write with the RC channel values?


Couldn't you just use a length of wire?

Bottom line is that I'm unable to fly after an RC plane and open it up mid flight to rewire the plane to not use the autopilot. I think that if I could write some code that it might be a bit easier.

  1. Checks the Input of an aux input, if its HIGH
  2. Then read the receiver Pitch Roll PMW values
  3. Get those values (0-255) and use the servo lib. to output them via a PMW port.

Google "Arduino RC receiver" Lots of info. Here is the first hit.

Basic and not ideal but it will do what you say you want :

Connect each RC output to an Arduino input pin and RC GND to Arduino GND

Connect each servo to an Arduino output pin and servo GND to Arduino GND. Do NOT power the servos from the Arduino 5V output. They will take too much current. Use an external power source.

Use pulseIn() to read each channel in turn. A for loop and an array of pin numbers is useful

Pass the value read with pulseIn() to the appropriate output pin. ie, if the input stays HIGH for 1000 microseconds set the output HIGH for 1000 microseconds

Pulsein is not the ideal way to read RC receiver input.
Here are a few articles on the subject.

You will already be reading the values from the receiver to determine when the user has turned off autopilot.
When they do, simply stop sending the servos the output from your autopilot code and pass through the signals from your reads from the receiver.

Correct me if i am wrong, but I am trying to read the PMW values from the receiver, so why do i need to write a huge script to just read values from 0-255 and repeat them, for example by mapping the incoming values to the values being sent out?

Correct me if i am wrong,

Sorry, but you are wrong ?

The RC signals are pulses of between 1000 and 2000 microseconds in length, not values of between 0 and 255 and the servos expect to receive pulses in that range of values.

In any case, how do you propose to

just read values from 0-255

oh my!

THanks for telling me this.

Ill immediately look how to complete this task differently!

I was totally not aware of this.
Where might i find a chart of what pulse length is for what specific value (i.e. servo values)

Thanks helibob!

There is no chart needed. To a servo, roughly speaking, 1000 is full one way, 2000 is full the other way. For throttle (ESC) usually 1000 is closed, 2000 is fully open.

But anyway all you need to do is to read the pulse, whatever it is, and pass it on to the servo. You don't need to interpret it.


Where might i find a chart of what pulse length is for what specific value (i.e. servo values)

The servo position is proportional to the pulse length but bear in mind that not all servos can move through the same angle

If you want finer control over the servo position have a look at the writeMicroseconds() function of the Servo library. writeMicroseconds()

Okay thanks for that information.

So whats the definite way of reading this signal and then passing it on. I hear that i can get the signal, assign it to a "val", then write this "val" out to a pin.

  1. Does the output need to be pmw
  2. Whats the bottom line best way of simply reading the receiver value. (I was thinking digitalRead but i think it's not the correct function)


-Till (8:44 AWST)

  • my servos are ones that have a range of 180ø (90-center-90)

Also, my sensor requires a baud rate of 38400, if i need to a different seperate baud rate for the RC signals, how can this be achieved, or is this not a concern?


Whats the bottom line best way of simply reading the receiver value.

Here is an example that I wrote to expand the length of the pulses on 2 channels
It illustrates the use of pulseIn() to read the RC inputs but it would be better done using interrupts.

const byte yawInPin = 7;
const byte yawOutPin = 8;
unsigned long yawDuration;

const byte thrInPin = 9;
const byte thrOutPin = 10;
unsigned long thrDuration;

void setup()
  pinMode(yawInPin, INPUT);
  pinMode(yawOutPin, OUTPUT);

  pinMode(thrInPin, INPUT);
  pinMode(thrOutPin, OUTPUT);

void loop()
  yawDuration = pulseIn(yawInPin, HIGH);
  yawDuration = map(yawDuration, 1000, 1800, 980, 2020);
  digitalWrite(yawOutPin, HIGH);
  digitalWrite(yawOutPin, LOW);  

  thrDuration = pulseIn(thrInPin, HIGH);
  thrDuration = map(thrDuration, 1000, 2000, 980, 2020);
  digitalWrite(thrOutPin, HIGH);
  digitalWrite(thrOutPin, LOW);  

Thanks for writing some sample code. I understand what you have done, however why is the signal mapped to 980-2020? Is this the servo range in milliseconds? And how can i go about having two serial baud rates, one for the PMW signal and one for the accelerometer interface?

why is the signal mapped to 980-2020?

Because I was getting in a range between 1000 and 1800 microseconds and wanted an output between 980 to 2020 microseconds. You do not have to do this and could simply output the value received when you want manual control of the drone.

how can i go about having two serial baud rates, one for the PMW signal and one for the accelerometer interface?

My example does not use the serial interface. The Serial.begin() is simply there in my boilerplate empty sketch and I did not remove it. Does the accelerometer really use a serial interface ?

Well i have to communicate with the MPU6050 using serial and a bunch of 3d math libraries that make my life so much easier.

OK, but why do you think that you need to baud rates ?

i'm very so stupid, pardon that. I think i'm off my chaps. the baud rate was only present to communicate a hardware failure- a feature that i scrapped a long time ago

Thanks lol