Pages: [1]   Go Down
Author Topic: Read PPM Sum and output to servos (or Motors) question  (Read 599 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
 
   switch(val)
     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!

Thanks,
Marko



Code:
#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];
 }
 else
 {
 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
  
   Serial.println(channel[i]);
   lastReadChannel[i]=channel[i];
 }

 delay(400); //Delay
 conta=0;//Restart couter.
    }
  }
« Last Edit: December 17, 2012, 12:20:30 pm by serbcccc3 » Logged

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

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

rcarduino.blogspot.com
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Duane,

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.

Marko
Logged

Pages: [1]   Go Up
Jump to: