![]() | ![]() | ![]() |
| |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
![]() |
| | Tools |
| | #1 |
|
On another thread someone asked about C18 servo code and I wrote a simple version. It occurred to me that it wouldn't be too difficult to make this work on the Junebug and so here it is. This code reads the potentiometer on AN1 (VR1) and sets the position of a servo on RB3 to match it. Switches 1,2,3 & 8 on. Code: #include <p18f1320.h>
#pragma config WDT = OFF, LVP = OFF, OSC = INTIO2
#define ServoPin LATBbits.LATB3
#define ServoTris TRISBbits.TRISB3
void main(void){
int ServoPos;
OSCCON=0x70; //Osc=8MHz
ADCON0=0b00000101; //A2D on and select AN1
ADCON1=0x7d; //A1 = analogue
ADCON2=0b10110101; //Right justify - Fosc/16
ServoTris=0; //make servo pin output
ServoPin=0; //Servo output off
CCP1CON=0b00001011; //Special event trigger
T1CON=0b10010001; //Timer 1 on with Pre=2
ServoPos=1500; //set servo to mid position
CCPR1=ServoPos; //set CCP initial value
while(1){
while(!PIR1bits.CCP1IF); //wait for CCP interrupt bit
ServoPin=0; //end pulse
CCPR1=20000-ServoPos; //Off time = 20mS - Servo Time
PIR1bits.CCP1IF=0; //clear int flag
ADCON0bits.GO=1; //start conversion
while(ADCON0bits.GO); //Wait for it to complete
ServoPos=ADRES+1000; //Pos will be 1mS to 2.023mS
while(!PIR1bits.CCP1IF); //wait for int flag
ServoPin=1; //start pulse
CCPR1=ServoPos; //Servo time in uS
PIR1bits.CCP1IF=0; //clear int flag
}
}
Mike. Project file attached. Last edited by Pommie; 6th July 2008 at 04:29 PM. | |
| |
| | #2 |
|
Is there really that few people experimenting with the Junebug that nobody found this post interesting? Mike. | |
| |
| | #3 |
|
Were you expecting people to throw a party? ![]() You might also consider that people sleep occasionally, interested parties may be in different time zones. | |
| |
| | #4 | |
| Quote:
Mike. | ||
| |
| | #5 |
|
Sorry about that Mike, I've just had my head buried in the Ladybug project. Your code looks great, I'm starting to be able to read and understand C18. I've noticed many C18 programs use #include <p18Cxxxx.h> | |
| |
| | #6 | |
| Quote:
| ||
| |
| | #7 |
|
The inclusion of 18cxxxx is done to get the proper definitions for your target pic (given that it is an 18). This is the first few lines of 18cxxxx.h #ifndef _P18CXXX_H #define _P18CXXX_H #if defined(__18C242) #include <p18c242.h> #elif defined(__18C252) #include <p18c252.h> #elif defined(__18C442) #include <p18c442.h> #elif defined(__18C452) #include <p18c452.h> So, by picking your target as say and 18F1320, then p18f1320.h will get included. Why don't we just include p18f1320.h directly. Well suppose you change targets to "say" a 18F4620, then you have to edit the include line. This is just the way it is done for proper coding. So what is in p18f1320.h It will hold the definitions for all the memory locations (TRISA, LATA, etc) that you will be using in the program. With the header files, the compiler doesn't have to have "hard coded" things built in. Microchip can build a new pic with things in slightly different places and they just create a new header file and the compiler can find where they are. I highly recommend that you go view the header files. Mine are in c:\MCC18\h
__________________ August Treubig AG5AT | |
| |
| | #8 | |
| Quote:
Another use is for sending signals to an electronic speed controller (ESC). I've done that with an ESC for a brushless motor. Most ESCs woun't arm before you send them a zero throttle signal, 1,0 ms. Wouldn't harm if the servo tester just sent 1,0 ms until the pot is at zero throttle after boot up. And maybe a blinking LED if the pot is at > zero throttle. My sport R/C helicopter turned into a attack helicopter the other day. Spinning up at full speed on top of a table inside my garage. Falling down, chopping a big chunk of the table plate, while I was running for my life... | ||
| |
| | #9 |
|
Watch out with powering the Servo with your USB port. Using a powered hub will help as they can deliver the current a servo motor will need.
| |
| |
| | #10 |
|
I'm sorry Mike. I've been "off the air", so to speak, for a few days. I always enjoy studying your code. This one is an excellent example and very nicely commented. Well done Sir... Mike | |
| |
| | #11 |
|
Mike, May I suggest an interrupt version of that code for newcomers to study? The ISR vector setup isn't quite as intuitive as it is in some other languages. Regards... | |
| |
| | #12 | |
| Quote:
Mike. | ||
| |
| | #13 |
|
Pommie, Thanks for the code. I have ordered a junebug and one of my future projects will need this exact code. Corse, I still need to go through the tuts and learn C! But it still lets me see actual code and I tend to learn better from examples that I can dissect.
__________________ Don't touch that wire........Um......are you ok? | |
| |
| | #14 | |
| Quote:
I also changed it to use interrupts because, as Mike said, it isn't as intuitive as one would imagine. Mike. Code: #include <p18f1320.h>
#pragma config WDT = OFF, LVP = OFF, OSC = INTIO2
#define ServoPin LATBbits.LATB3
#define ServoTris TRISBbits.TRISB3
void ccp1_isr();
volatile int ServoPos; //used to hold the servo position
#pragma code low_vector=0x18 //setup the ISR vector
void low_interrupt (){
_asm GOTO ccp1_isr _endasm //jump to interrupt handler
}
#pragma code
#pragma interruptlow ccp1_isr //the ISR
void ccp1_isr(){
if(ServoPin==1){ //will be 1 if we are at end of pulse
ServoPin=0; //turn off servo output
CCPR1=20000-ServoPos; //Off time = 20mS - Servo Time
}
else{
ServoPin=1; //turn on servo output
CCPR1=ServoPos; //On time
}
PIR1bits.CCP1IF=0; //clear int flag
}
#pragma code
void main(){
OSCCON=0x70; //Osc=8MHz
ADCON0=0b00000101; //A2D on and select AN1
ADCON1=0x7d; //A1 = analogue
ADCON2=0b10110101; //Right justify - Fosc/16
ServoTris=0; //make bit 0 output
ServoPin=0; //Servo output off
CCP1CON=0b00001011; //Special event trigger
T1CON=0b10010001; //Timer 1 on with Pre=2
ServoPos=1500; //set servo to mid position
CCPR1=ServoPos; //set CCP initial value
PIE1bits.CCP1IE=1; //enable CCP1 interrupt
INTCONbits.PEIE=1; //enable peripheral interrupts
INTCONbits.GIE=1; //enable glogal interrupts
INTCON2bits.RBPU=0; //enable port b week pullups
while(1){ //loop forever
static char Mode=0; //0 = use ADC, 1=fixed pos
static char Keys; //holds previous key values
char OldKeys,Edges; //local variables
while(!ServoPin); //Wait for start of servo pulse
while(ServoPin); //wait for end - makes for good debounce
OldKeys=Keys; //make a copy of keys
Keys=PORTB&0b00100101; //get switch state
Keys^=0b00100101; //make pressed keys = 1
if(Keys==0b00100101) //all 3 pressed?
Mode=0; //yes, set to use ADC input
Edges=(Keys^OldKeys); //keep only keys that have changed
Edges&=Keys; //keep only new key presses - not key releases
if(Mode==0){ //are we using the pot?
ADCON0bits.GO=1; //yes, start conversion
while(ADCON0bits.GO); //Wait for it to complete
ServoPos=ADRES+1000; //Pos will be 1mS to 2.023mS
}
if(Edges!=0) //any key pressed
Mode=1; //switch to fixed mode
if(Edges==0b00000001) //Key 1 pressed
ServoPos=1000; //set servo fully left
if(Edges==0b00000100) //key 2?
ServoPos=1500; //set center
if(Edges==0b00100000) //key 3?
ServoPos=2000; //set fully right
}
}
Last edited by Pommie; 9th February 2008 at 05:34 AM. | ||
| |
| | #15 |
|
Thanks Pommie, I'm starting to C the light. ![]() Now I've got to learn what pragma do, I originally thought it was for CONFIG now it also seems to be like ORG | |
| |
|
| Tags |
| c18, code, junebug, servo |
| Thread Tools | |
| Display Modes | |
| |
Similar | ||||
| Title | Starter | Forum | Replies | Latest |
| MP Lab Program Help | bamafan54 | Micro Controllers | 5 | 7th January 2009 03:16 PM |
| servo motor program code | basf_12 | Electronic Projects Design/Ideas/Reviews | 8 | 31st October 2006 03:57 AM |
| Tough assembly program for the PIC16F84 | asmpic | Micro Controllers | 34 | 3rd December 2004 07:50 PM |
| how to understand this code!!! | indie | Electronic Projects Design/Ideas/Reviews | 3 | 11th September 2004 08:39 PM |
| An error in pic16f84a, why? | Zener_Diode | Micro Controllers | 6 | 11th April 2004 03:55 AM |