Go Down

Topic: Read PPM Sum and output to servos (or Motors) question (Read 1 time) previous topic - next topic


Dec 17, 2012, 06:16 pm Last Edit: Dec 17, 2012, 06:20 pm by serbcccc3 Reason: 1
Hi, I just have some questions on best practice with my existing code and any suggestions would be greatly appreciated.  My programming skills are pretty novice, but I understand the basics.

What I would like to do:
Read the PPM Sum with my Arduino from my Futaba 617fs receiver (Futaba 2.4ghz 7C tx being used) and then control servos (or my brushless motors, but just servos for now) with the 7 available channels.  Reason for running this through the arduino would be to at some point modify the servo signal being sent based on sensor input or something else ( i dont think this part is relavent yet, just some extra info)

What I have done so far:
With my attached code below that I found online and have modified a bit (not this version but the concepts are the same) i am able to receive the PPM sum into the Arduino and display all 7 channel values from the TX in the Serial Monitor successfully.  So that part good. I made comments in the code where I have put a CASE statement (not shown in code) that basically looks at the current channel and converts the channel value (usually from about 600-1450) and I map it to a usuable servo value (ie. map(channel,600,1450,0,180) and write that to the servo using myservo.write(servo).  This works to move the servo for the selected channel (albeit the damn servo is pretty jittery.  see below example of that code
Code: [Select]

    case 1:
      angle = map(channel[i],600,1450,0,180);
      myservo.write(servopin); //write to whichever servopin i have assigned here

Issues and Questions:
Using this code, I have what seems to be two issues.
1. The response is a bit slow from the actual movement of the stick on the TX to the value change of the received value in the arduino.  Is there a better way to write this code (i have seem some using interrupts, but I really dont understand how to use them)
2.  While I am able to use the received data and move my servo, because of the slow response in reading the values, and of the variations in the receiver input (ie. if channel 3 stick is not moved, the actual received value fluctuates a bit - for example it flutters from about 640-660 give or take a few) Is there a better way to "smooth" the received values from the tx such that the servo doesnt jitter a few degress when no tx input is being made?  
Also, when the TX input is given for a channel, the movement of the servo is a bit jittery as it goes to the endpoint desination.  For example, if i move the channel 3 stick from its low position to the highest position (moving slowly), the servo does move in conjunction with my stick movement (of course with a slight delay), but the movement is jittery as it goes from 0 to 180.  What would be a good way at smoothing that movement out?

Again, thanks for any help and advice anyone can offer. If I posted this in the wrong forum topic let me know and Ill move it.  If anyone has any better code to accomplish this too, I would love to see it, I am just trying to make this work.  I am more of a builder than a programmer so this has been a bit challenging!


Code: [Select]
#define channumber 7 // number of channels
#define filter 10 // Glitch Filter
int channel[channumber]; // read Channel values
int lastReadChannel[channumber]; // Last  values read
int conta=0; //couter

void setup()
 Serial.begin(9600); //Serial Begin
 pinMode(4, INPUT); //P Pin 4 as input


void loop()

 if(pulseIn(4, HIGH) > 3000) ///If pulse > 3000 useconds, continues
   for(int i = 0; i <= channumber-1; i++) // Read the pulses of the channels
channel[i]=pulseIn(4, HIGH);
   for(int i = 0; i <= channumber-1; i++) //Average the pulses
if((channel[i] > 2000) || (channel[i] <100))// If channel > max range, chage the value to the last pulse
 channel[i]= lastReadChannel[i];
channel[i]=(lastReadChannel[i]+channel[i])/2; //Average the last pulse eith the current pulse
conta++; //increment counter

   if(conta > filter)// If counter is > than filter, then prints values
for(int i = 0; i <= channumber-1; i++) //Cycle to print values
  Serial.print("CH"); ///Channel
  Serial.print(i+1); //  Channel number
  Serial.print(": ");

  //CASE statement inserted here to pull the channel value and convert it from its approx 600-1450 range received from tx to 0-180 range for servo control
  // write to the servo using servo library based on the 0-180 range value derived from the tx value

delay(400); //Delay
conta=0;//Restart couter.



I have a Series of detailed posts on using interrupts to read RC signals at rcarduino.blogspot.com

The most recent posts deal with ppm however you would do well to start with some of the earlier ones for background on why not to use pulseIn and how to use interrupts for RC Signals

There are full code examples with each of the posts

Duane B

Read this
then watch this




Thanks a lot for your response.  I just glanced at the blog and it looks like a wealth of information (nicely organized info as well:) ), and it looks like I have some reading to do.


Go Up