servo update issue

I have a strange amalgamation of components, which has led to this project, so understand I am doing things a strange way, but there is a reason.

I have a RC receiver which outputs servo control pulses. I am running that into my sanguino, doing some maths to the values, and spitting out new servo control signals. the problem is it only seems to put out a pulse every .3 seconds, so something is odd. using micros i found the loop takes .4 seconds to run, so it seems to be only sending one pulse when write is called, so i tried copy pasting hte write command all over the place :roll_eyes: don't judge me, and the same behavior persisted. I had thought the servo.h kept the pulse train running in the background while code was running, so i didn't really expect this to help.

I tried running the sweep example sketch, and it worked fine. any help would be greatly appreciated.

This is my first arduino/sanguino project, most of my programming is done in matlab, so i am all kinds of new at this.

I had thought the servo.h kept the pulse train running in the background while code was running, so i didn't really expect this to help.

It does. The timing 'bootlneck' is most likely on the reading update values of the input pulses from the R/C receiver's servo output signals. But once you do write a value for a servo output the ppm pulse signal should continue outputing the last value written at around a 45-50msec rate I think. Not sure how you could profile the timing performance but maybe using the millis() counter and serial prints to the serial monitor you can get a feel for what the effective update rate is for your sketch.

If you post your code there are some sharp software types around here that can probably give you some good suggestions.

Lefty

this is my first micro-controller project ever, and i have no C experience, so i opted to take the cautious but ineffecient route, hence using longs for tons of values that could have been ints or bytes, to avoid any silly or unexpected mistakes or compatibility errors.

I threw a ton of serial write commands in there to see whats up, and the timing seems to claim i only get 1 servo pulse per run of the loop function, not a continuous train. i removed all those things for readability.

#include <Servo.h> 
 
Servo LDrive;
Servo RDrive;

int ch0Pin = 15;        //first channel
int ch1Pin = 16;        
int ch2Pin = 17;        
int ch3Pin = 18;        
int ch4Pin = 19;
int ch5Pin = 20;    
int LControllPin = 13;  //to motor controlls
int RControllPin = 14;

unsigned long RCin[7];   //8 channel RC remote

void setup()
{
  for (int ii = 0; ii < 8; ii++){
  RCin[ii]=1500;}
  
  pinMode(ch0Pin, INPUT);
  pinMode(ch1Pin, INPUT);
  pinMode(ch2Pin, INPUT);
  pinMode(ch3Pin, INPUT);
  pinMode(ch4Pin, INPUT);
  pinMode(ch5Pin, INPUT);
  
  LDrive.attach(LControllPin);
  RDrive.attach(RControllPin);

  Serial.begin(9600); 

  // prints initial value on chan 0 and says hi
  Serial.println(RCin[0]); 
  Serial.println("Setup Complete"); 
}

void loop(){
  
  long tP = 0;
  long directional = 0;
  long lP = 0;
  long rP = 0;
  long rT = 0;
  long lT = 0;
  long lServ = 90;
  long rServ = 90;
  
  RCupdate();
  directional = ABProfile();
  
  tP = throttlePerc();
  lP = directional/1000;
  rP = directional-lP*1000;
  
  lT = lP*tP/100;
  rT = rP*tP/100;
  
  lServ = map(lT, -150, 150, 0, 180);  //maps left drive percent (signed) to servo degrees, assumes 90 deg = 1500 us pulse
  rServ = map(rT, -150, 150, 0, 180);  //defaults set servo max min to 544 2400
  
  LDrive.write(lServ);
  RDrive.write(rServ);
}

void RCupdate(){
  RCin[0] = pulseIn(ch0Pin, HIGH);  //throttle
  RCin[1] = pulseIn(ch1Pin, HIGH);  //aile
  RCin[2] = pulseIn(ch2Pin, HIGH);  //elev
  RCin[3] = pulseIn(ch3Pin, HIGH);  
  RCin[4] = pulseIn(ch4Pin, HIGH);  //gear
  RCin[5] = pulseIn(ch5Pin, HIGH);  
}

long throttlePerc(){
  
  int neutral = 1500;
  long Tp;    //throttle percent, with sign

  if(RCin[2]==0)
  Tp=0;                //failsafe
  if(RCin[2]>neutral)
  Tp=((long)RCin[2]-neutral)/5;
  if(RCin[2]<=neutral && RCin[2]!=0)
  Tp=-(neutral-(long)RCin[2])/5;
  
  return Tp;
}

long ABProfile(){

long D = (long)RCin[1];     //aileron (chan 3) value
long Rp = 0;                //Right throttle percent value
long Lp = 0;                //Left
long DirP = 0;         //merged to pass as output, lp,rp

long ap = 10;  //percent of knees as read on remote monitor
long bp = 25;
long cp = 85;
long eep = 150;    //overange cutoff

long a =   ap*100000/131;    //percent 1000 to perserve accuracy
long b =   bp*100000/131;    //ex is 19084
long c =   cp*100000/131;
long ee = eep*100000/131;    //max 15,000,000/131 of 2,100,000,000

long taPos = 1500+500*a/100000;
long tbPos = 1500+500*b/100000;
long tcPos = 1500+500*c/100000;
long teePos = 1500+500*ee/100000;

long taNeg = 1500-500*a/100000;
long tbNeg = 1500-500*b/100000;
long tcNeg = 1500-500*c/100000;
long teeNeg = 1500-500*ee/100000;

if (D<taPos)              Rp= 100;
if (taPos<=D && D<tbPos)  Rp= 100-(D-taPos)*1293/1000;
if (tbPos<=D && D<tcPos)  Rp= 25 -(D-tbPos)*219/1000;
if (tcPos<=D && D<teePos) Rp=-25 -(D-tcPos)*426/1000;
if (teePos<=D)            Rp= -150;

if (D>taNeg)              Lp= 100;
if (taNeg>=D && D>tbNeg)  Lp= 100+(D-taNeg)*1293/1000;
if (tbNeg>=D && D>tcNeg)  Lp= 25 +(D-tbNeg)*219/1000;
if (tcNeg>=D && D>teeNeg) Lp=-25 +(D-tcNeg)*426/1000;
if (teeNeg>=D)            Lp= -150;

DirP=Lp*1000+Rp;

return DirP;
}

on the bright side i now know enough about registry thingys to konw what i need to make the fast PWM configed properly I THINK, but not enough to fully undertand the servo.h code to make sure it is setting up my timer and prescaller and all that fun stuff properly. untill a knight in armor swaggers thru this thread, i am going to learn about hand-modifying those values and see if i can't beat it into submission, but the fact the sweep demo seems to work fine makes me think its not a servo.h issue, although if i threw a long delay into the demo program, that would tell me if slowing down the loop slows down the pulse train, meaning the PWM is not working as it should be.