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
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.
- 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)
- 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
#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.
}
}