Controlling servo motors using RC transmitter/receiver and Arudino

Hi, I am new to Arduino and to this forum and this is my first Arduino project besides the tutorials.

I am trying to control a servo using a rc transmitter/receiver and the Arudino. The reason why I am using a Arduino instead of connecting the servo directly to the RC receiver is that the RC can only generate a PWN of 1000 to 2000 while I need a PWM of 600 to 2400 to get the full range of motion of my servo. What I have tried to do is to read the value from pulseIn(), then mapping this value to 0 to 180 degree as written in code below (which utilizes servo library).

However, with this code, the motor behavior is weird. As I move the radio transmitter control stick through its range of motion, the motor rotates from 0 to 45 degrees, back from 45 to 0, 0 to 45, and back to 0 again instead of sweeping from 0 to 180 degrees. Could anyone please offer some help or advice?

Thank you very much

#include <Servo.h>
Servo myservo;

int ch1;
int ch2;
int ch3;
int degree;

void setup() {

pinMode(7, INPUT);
myservo.attach(9);

Serial.begin(9600);

}

void loop() {

ch3 = pulseIn(7, HIGH, 25000);
degree = ((ch3-1250)* 180)/700;
Serial.print("Channel 3:");
Serial.println(ch3);
myservo.write(degree);
delay(5);

}

Perhaps the servo is only capable of 90 degree movement.

Try

for (int pulseLen = 600; pulseLen < 2400; pulseLen += 4) {
  myServo.writeMicroseconds (pulseLen);
  delay (50);  
}

Hi, thanks for your response

I tried controlling with the built in example servo sweep code and the servo could move 180 degrees no problem .

http://www.servocity.com/html/hs-645mg_ultra_torque.html

Here is the link to the servo I am using and it is stated that it requires a pwm of 600usec to 2400usec for full 180degree range of motion. I have verified this with the servo manufacture, Hitec and they stated the same thing.

What do your serial prints tell you?

It varies from around 1200 to 1950 when I move the stick on the transmitter. Which I guess is the PWM from the transmitter? Seems to be in the approximate range of 1000 to 2000 of a typical tranmitter.

degree = ((ch3-1250)* 180)/700;

So, let's say "ch3" is 1950.
(1950 - 1250) = 700.
700 * 180 = 126000.

Oops.

Try promoting your constants to "long" degree = ((ch3-1250L)* 180L)/700L;

Edit: Or divide top and bottom by ten. :slight_smile: (Hey! It's Monday morning, and I haven't had any coffee yet)

You could automatically calibrate to whatever range the transmitter is sending, you will often find that is different even for channels on the same transmitter.

Here is an example of RC Code with calibration, it also stores the calibration in EEPROM so after the first calibration you only need to recalibrate if you change transmitters.

The bit you would need to change is inside if(gMode == MODE_RUN) this is designed to map steering and throttle channels into the left and right throttle values required for a tracked vehicle - not servos. You will want to use the map function to map the limited range from your RC Receiver into the full range allowed by your servos - i.e.

map(ch1Input,ch1InputMin,ch1InputMax,ch1OutputMin,ch1OutputMax)

Duane B

rcarduino.blogspot.com

Hey AWOL, thank you very much for the advice! Im getting full range of motion out of my servo now. I doubt I would have ever thought of or found that correction you suggested.

DuaneB, I will run into that problem sooner or later. Thanks for the tip in advance. I will work on it in the next few days.

I am facing another problem now. My servo seems to be able to move into position how every its "glitching" or pulsating around that position. Any idea what is going on?

Thanks

One of four things

  1. you need a common ground between the servos, receiver and arduino.

  2. too many volts, servos are usually best at 6 volts

  3. Not enough amps - you need separate power for the servos and arduino - check the links in my signature below

  4. if 1 to 3 are in place, its usually code.

Duane B

I've have ensured that the servo is getting 6v and sufficient current by connecting it to an external power supply. I have also connected it to common ground on the arduino. Servo sweep example ran without a problem.

When I check the serial prints. I notice the values fluctuating around the "set" values. Could this just be the servos reacting directly to the fluctuations. If so, how do you suggest I rectify it?

How big are the fluctuations in the input ?

Can you use microseconds instead of degrees, the first thing servo.write does is convert the angle to microseconds right after you did the opposite conversion. To drop both needless conversions use the value from pulsein directly with servo.writeMicroseconds.

It also means we don't need to consider the conversion to see where the variation is coming from.

What transmitter and receiver are you using ?

Duane B

Sorry for the late reply.

when the stick is moved to its lowest point for example, the input fluctuates between 1920 and 1940 and ocasionally peaking at 1960.

I am using a 6-channel 2.4Ghz Esky transmitter and receiver which I took from my helicopter.

Hi,

The fluctuation could be a result of radio construction, radio interference and timing errors from the Arduino, its not excessive and will result in small ticking movements in your servos.

You can reduce the Arduino timing errors by switching to the rcarduino fast servo library which is a little more efficient than the standard servo library.

Duane B

hello all ,

the above code works in controlling a brushless motor also... all u need to do is to eliminate the degree formula and connect ur receiver and esc to the respective ports...

but apart from the code running well , at high rpm there is a considerable delay of a few micro seconds which is reducing the output thrust..

and ideas on how to eliminate the delay ??

thank u for ur time...

sham

at high rpm there is a considerable delay of a few micro seconds

With a frame rate of 50Hz, it is hard to see how you can distinguish a few microseconds.
(BTW, sp. "you", "your")

Hi gedeo, could you please post the final code you are using

Hi gedeo, could you post the final code you are using

Don't forget attribution, Imjith. (you forgot the magic word too)