Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 7th February 2008, 01:45 AM   #1
Default Junebug Servo C18 code.

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
    }
}
Have fun.

Mike.
Project file attached.

Last edited by Pommie; 6th July 2008 at 04:29 PM.
Pommie is online now  
Old 7th February 2008, 04:43 PM   #2
Default

Is there really that few people experimenting with the Junebug that nobody found this post interesting?

Mike.
Pommie is online now  
Old 7th February 2008, 04:54 PM   #3
Default

Were you expecting people to throw a party?

You might also consider that people sleep occasionally, interested parties may be in different time zones.
__________________
PIC programmer software, and PIC Tutorials at:
http://www.winpicprog.co.uk
Nigel Goodwin is online now  
Old 7th February 2008, 05:04 PM   #4
Default

Quote:
Originally Posted by Nigel Goodwin
Were you expecting people to throw a party?

You might also consider that people sleep occasionally, interested parties may be in different time zones.
Well, no, I wasn't expecting a party. I'm just surprised that it fell down the list when similar posts had multiple replies. I'm also surprised that Bill who's kit I am indirectly promoting did not at least comment.

Mike.
Pommie is online now  
Old 7th February 2008, 05:47 PM   #5
Default

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>
__________________
Bill
Smart Kits build Smart People

http://www.blueroomelectronics.com/
blueroomelectronics is offline  
Old 7th February 2008, 05:52 PM   #6
Default

Quote:
Originally Posted by blueroomelectronics
I've noticed many C18 programs use
#include <p18Cxxxx.h>
I don't do C, but assembler programs use an include file for the same reason.
__________________
PIC programmer software, and PIC Tutorials at:
http://www.winpicprog.co.uk
Nigel Goodwin is online now  
Old 7th February 2008, 06:43 PM   #7
Talking What are C header files for?

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
August Treubig is offline  
Old 7th February 2008, 07:13 PM   #8
Default

Quote:
Originally Posted by Pommie
Is there really that few people experimenting with the Junebug that nobody found this post interesting?
I found it interesting too! But had some trouble with my MPlab when I tested the code. The project wouldn't build due to some linker script error. Gonna try on another laptop. I've just built a servo tester with a 16F684, and asm code from a Myke Predko book. Not much more than a pot and the pic. I'm in the process of building a R/C helicopter, and needed something to center the servoes, in the absence of a radio system. A switch to make the circuit output exactly 1,5 ms for center position would be nice. A two position switch, to choose between center lock and normal operation. Would also be good if the pic outputs 1,5 ms until the pot reaches center position. That would avoid wrecking the servo gears if the switch is moved when the pot is at either end. (if the servo stalls because of mechanical limitis in the model)

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...
Odin is offline  
Old 7th February 2008, 07:34 PM   #9
Default

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.
__________________
Bill
Smart Kits build Smart People

http://www.blueroomelectronics.com/
blueroomelectronics is offline  
Old 8th February 2008, 02:23 PM   #10
Default

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
Mike, K8LH is offline  
Old 8th February 2008, 02:27 PM   #11
Default

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...
Mike, K8LH is offline  
Old 8th February 2008, 03:04 PM   #12
Default

Quote:
Originally Posted by Mike, K8LH
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...
Might have a go at that tomorrow. Good to see you back, been anywhere nice?

Mike.
Pommie is online now  
Old 8th February 2008, 04:37 PM   #13
Default

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?
hosh is offline  
Old 9th February 2008, 05:02 AM   #14
Default

Quote:
Originally Posted by Odin
I'm in the process of building a R/C helicopter, and needed something to center the servoes, in the absence of a radio system. A switch to make the circuit output exactly 1,5 ms for center position would be nice. A two position switch, to choose between center lock and normal operation. Would also be good if the pic outputs 1,5 ms until the pot reaches center position. That would avoid wrecking the servo gears if the switch is moved when the pot is at either end. (if the servo stalls because of mechanical limitis in the model)
Here is a version that will go fully left if button 1 pressed, center if button 2 pressed and fully right if button 3 pressed. If you press all 3 buttons together it will take up the position defined by the pot.

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.
Pommie is online now  
Old 9th February 2008, 04:04 PM   #15
Default

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
__________________
Bill
Smart Kits build Smart People

http://www.blueroomelectronics.com/
blueroomelectronics is offline  
Reply

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



All times are GMT. The time now is 02:59 PM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker