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 CCS Technical Support

Multiple R/C Servo PPM signal.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
StealthMicro



Joined: 10 Apr 2007
Posts: 17

View user's profile Send private message

Multiple R/C Servo PPM signal.
PostPosted: Thu Apr 30, 2009 11:33 am     Reply with quote

I have built a Flight Simulator like a helicopter seat that I need to interface with the R/C Transmitters. Right now I have to hack each transmitter and tap in to the pots to access the controls. It is a bit of a pain as I have to use a 24V power supply and voltage dividers to get the voltage ranges I need as the controls on the flight simulator do not have the same range of motion as the R/C transmitter does.

What I would like to do instead is send the signal out to the Buddy Box port on the transmitter and do it that way. I can use the A/D ports to convert the voltage to the PPM stream needed to control the servos using the buddy box port.

What I need is a way to generate the PPM signal. It basically is a signal that stretches 22.5 MS in length with a series of high lows between that signify the position of each servo.



Does anyone have a good way to generate this PPM stream? I know the PWM ports will not work here right as they are designed to give a repetitive stream not one that needs to be changed constantly correct?

Any ideas here would be greatly appreciated.
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Thu Apr 30, 2009 12:11 pm     Reply with quote

You can do that with a code in a timer ISR Wink
StealthMicro



Joined: 10 Apr 2007
Posts: 17

View user's profile Send private message

PostPosted: Thu Apr 30, 2009 12:16 pm     Reply with quote

bungee- wrote:
You can do that with a code in a timer ISR Wink


Give me a little example and you will be a hero!

I plan to use a 18F4550 so that I can utilize the USB port for some other stuff I need to do as well.

I would greatly appreciate a little code snippet if someone has the time to do it.
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Thu Apr 30, 2009 2:25 pm     Reply with quote

Here is the code for driving 8 servos from the same PIC. You can rewrite the ISR for your need. Basically you will need to turn my parallel code to serial one ;)


Code:
#include <18F4550.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HSPLL                    //High Speed Crystal/Resonator with PLL enabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES PUT                      //Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLPT1OSC                //Timer1 configured for higher power operation
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL12                    //Divide By 12(48MHz oscillator input)
#FUSES CPUDIV1                  //No System Clock Postscaler
#FUSES USBDIV                   //USB clock source comes from PLL divide by 2
#FUSES VREGEN                   //USB voltage regulator enabled
#FUSES ICPRT                    //ICPRT enabled

#use delay(clock=48000000)

// The code is written for servos to be on portB !!!

#use fast_io(B)   // We will take care of port direction


int8 servo[8];  // Value where the servo should be
int1 pause=1;     // Is this pause cycle
int8 pause_cycle,servo_cycle=0;


#int_TIMER2
void  TIMER2_isr(void)
{
int8  _i;

  if (!pause)        //Are we in servo cycle
   {
      if (servo_cycle<=64)    // First part of signal is allways 1ms long
      {
         Output_b(0xff);
         servo_cycle++;         
      }
      else
      {
         for (_i=0;_i<=8;_i++)   //set the actual delay of servos
         {
            if ((servo[_i]+64)<=servo_cycle) output_bit(pin_b1+_i,0);
         }
         if (servo_cycle>=64)    //End of servo cycle
         {
            servo_cycle=0;
            pause=1;
         }
      }
      servo_cycle++;
   }
  if (pause)   //Are we in pause cycle
   {
      pause_cycle++;
      if (pause_cycle==0) pause=0;
   }

}



void setup()
{


   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_1,16,11);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   set_tris_b(0);                      //PortB is output
   
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);


}



void main()
{
   setup();
   
   while (1)
   {
      delay_cycles(1);
   }
}
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Thu Apr 30, 2009 2:33 pm     Reply with quote

I forgot to point out that there are only 64 positions per servo if you use this code. Wink
ricard0g0mes



Joined: 19 May 2009
Posts: 6

View user's profile Send private message

PostPosted: Tue Jul 07, 2009 6:52 am     Reply with quote

delay_cycles() is where?
Ttelmah
Guest







PostPosted: Tue Jul 07, 2009 8:13 am     Reply with quote

Standard compiler function.
It isn't actually dong anything. It just puts a single 'NOP' instruction. The work is all done in the ISR.

Best Wishes
mbradley



Joined: 11 Jul 2009
Posts: 118
Location: California, USA

View user's profile Send private message Visit poster's website

PostPosted: Sat Jul 11, 2009 11:26 pm     Reply with quote

I have done this many times, to make simple multi servo cyclers and setup tools so people don't have to disconnect their receivers.

Super simple, if this is all your pic is going to do:
This is not complete code, but give you a starting point.
Code:
#define pinPPM PIN_C2

Each servo[i] should be from 1100 to 1900,
extended would be 1000 to 2000.
1500 would be servo center, or 1520 for JR servos.
Code:
output_high(pinPPM);

while(true)
{
   delay_ms(5);
   for (i=0; i<10; i++)
     {
     output_low(pinPPM);
     delay_us(servo[i]);
       output_high(pinPPM);
       delay_us(100);
     }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion 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