CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Model aircraft servo pulses

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

Model aircraft servo pulses
PostPosted: Sun Jun 26, 2016 5:03 pm     Reply with quote

Code:

///////////////////////////////////////////////////////////////////
//GENERATING 9 MODEL AIRCRAFT SERVO PULSES
//HITEC servo pulse 1520+/-500us
//setting the pulses to 1514+/-500us gives 250ns max pulse error
//on 1520+/-500us pulse output
//adding 62us to the pulses sum gives 313ns error to the 20ms period
//pulse9 is dummy time kept at 1020us
//generating 10 pulses is possible with the commented out line in case 10
//gives max error of 205us to the 20ms period
///////////////////////////////////////////////////////////////////
#include <18F26K22.h>
#device ADC=10
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES PUT                      //Power Up Timer
#FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
#FUSES NOHFOFST                 //High Frequency INTRC waits until stable before clocking CPU
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(internal=64MHz)

#define flashled PIN_A4
#define servo0 PIN_B0
#define servo1 PIN_B1
#define servo2 PIN_B2
#define servo3 PIN_B3
#define servo4 PIN_B4
#define servo5 PIN_B5
#define servo6 PIN_C3
#define servo7 PIN_C4
#define servo8 PIN_C5

int flashledcnt=0;
int pulses=0;
long pulse0=1514;
long pulse1=1514;
long pulse2=1514;
long pulse3=1514;
long pulse4=1514;
long pulse5=1514;
long pulse6=1514;
long pulse7=1514;
long pulse8=1514;
long pulse9=1014;//dummy pulse
long pulsestime=0;

#int_TIMER0
void TIMER0_isr(void)
{
   switch(pulses)
   {
      case 0:
      {
         output_high(servo0);
         set_timer0(65536-pulse0);//first pulse time
         pulsestime=pulse0;
         pulses++;
      }
      break;
      case 1:
      {
         output_high(servo1);
         output_low(servo0);
         set_timer0(65536-pulse1);
         pulsestime=pulsestime+pulse1;
         pulses++;
      }
      break;
      case 2:
      {
         output_high(servo2);
         output_low(servo1);
         set_timer0(65536-pulse2);
         pulsestime=pulsestime+pulse2;
         pulses++;
      }
      break;
      case 3:
      {
         output_high(servo3);
         output_low(servo2);
         set_timer0(65536-pulse3);
         pulsestime=pulsestime+pulse3;
         pulses++;
      }
      break;
      case 4:
      {
         output_high(servo4);
         output_low(servo3);
         set_timer0(65536-pulse4);
         pulsestime=pulsestime+pulse4;
         pulses++;
      }
      break;
      case 5:
      {
         output_high(servo5);
         output_low(servo4);
         set_timer0(65536-pulse5);
         pulsestime=pulsestime+pulse5;
         pulses++;
      }
      break;
      case 6:
      {
         output_high(servo6);
         output_low(servo5);
         set_timer0(65536-pulse6);
         pulsestime=pulsestime+pulse6;
         pulses++;
      }
      break;
      case 7:
      {
         output_high(servo7);
         output_low(servo6);
         set_timer0(65536-pulse7);
         pulsestime=pulsestime+pulse7;
         pulses++;
      }
      break;
      case 8:
      {
         output_high(servo8);
         output_low(servo7);
         set_timer0(65536-pulse8);
         pulsestime=pulsestime+pulse8;
         pulses++;
      }
      break;
      case 9:
      {
         output_low(servo8);
         set_timer0(65536-pulse9);//1000us dummy pulse
         pulsestime=pulsestime+pulse9;
         pulses++;
      }
      break;
      case 10:
      {
         set_timer0(45536+pulsestime+62);//to complement the period to 20ms
//         set_timer0(45536+pulsestime-141);//to complement the period to 20ms
         pulses=0;//to start the next sequence
         flashledcnt++;
      }
      break;   
   }
}
void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);//65.5 ms overflow
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   while(TRUE)
   {
      if(flashledcnt>=25)
      {
         flashledcnt=0;
         output_toggle(flashled);
      }   
   }
}
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Aug 11, 2016 3:32 pm     Reply with quote

this submission is surprisingly indeterminate in it's execution.
As soon as any of the pulse'n' values change -to alter servo position
- the cycling time between interrupt servicing becomes indeterminate.

if a lot of fast position changes are needed - the delay before the new position command is sent- is variable too.

this is use at your own peril code -IMHO
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 11, 2016 4:01 pm     Reply with quote

asmboy

Did you test the program in MPLAB and or with real hardware?
I am using the posted program for 10 years already on a few aircrafs, had never any problem.
16F876 and 18F252 at 16MHz clock
18F2520 and 18F25K20 at 32Mhz clock
18F26K22 at 64MHz on the last aircraft

But if you think the program should not be here, I will delete it

Best wishes
Joe
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Aug 11, 2016 4:44 pm     Reply with quote

tried with actual hardware and noticed variable delay as to when the new position command takes. Probably OK for model airplane but not for scientific optical instrument i am working on. very fast response to command stream needed in my app. working n another way t make it synchronous for all channels....
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 11, 2016 5:06 pm     Reply with quote

My previous software was in assembler so the glitch was 2 PC
Now can be up to 1 us. 1 us, from 1000 us is 0.1% . If the elevator range for example is +/- 22.5 degree if will result in 0.045 degree that is really nothing for a model aircraft.
This is the reason the program title is:
GENERATING 9 MODEL AIRCRAFT SERVO PULSES

I should mention also that the delay between the stick movement to servo movement should be 75 ms maximum not to see by eye delay between the command and the movement. The minimum for real time is defined 125 ms, but most model aircraft pilots will tell you that have delay at 125 ms, some at even 80 ms.

Best wishes
Joe
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Fri Aug 12, 2016 1:17 pm     Reply with quote

let me better explain the weakness to you.

if pulses=1
AND you change the value of pulse0 desiring an immediate start to a new position command EDGE to be set, the leading edge of the new servo command for channel 0 will not begin to change until all the other pulses duration have been walked through. can you understand what i am telling you ?

This is too slow and unresponsive in my app - and leads to my first complaint.
" indeterminate in it's execution. "
in the time domain - because it is.
in reality - your code is serial -multitasking.

i am doing it in a wholly different (parallel) way that allows the new "move-to" leading edge to be set from the foreground IMMEDIATELY and uses a countdown int16 array[8] that gets decremented for ALL actively being moved servo channels on each time tick interrupt. This method makes periodic refresh raise ALL active leading edges in parallel too.
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Fri Aug 12, 2016 7:27 pm     Reply with quote

Quote:
...the leading edge of the new servo command for channel 0 will not begin to change until all the other pulses duration have been walked through. can you understand what i am telling you ?

Yes I can. As I explained in my previous post, is not important for my application

Best wishes
Joe
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group