1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Junebug Servo C18 code.

Discussion in 'Microcontrollers' started by Pommie, Feb 6, 2008.

  1. Odin

    Odin Member

    Joined:
    Jun 29, 2004
    Messages:
    43
    Likes:
    1
    Location:
    Norway
    Tested, and it works! Thanks a lot for the code examples. I know 16F-series fairly well, but I'm new to 18Fs. Need some time to learn. I'm to lazy to connect other pic's, now that I have the 18F1320 on the Junebug :)
    I have another wish also. Center position with middle button, small steps left/right with button 1 & 3. Could be used to test the resolution of the servos.
    I'll have a go at it later. I don't expect you to write the code for me, but if you find it interresting, please do. I program pics partly for learning, partly for practical use. Like most, I guess.
     
  2. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    The really nice thing about having a Junebug is that you can flip a couple of switches and instantly try a bit of code.

    It's really easy to do. If you want to have a go yourself then stop reading now.

    To do what you ask simply needs this change,
    Code (text):

            if(Edges==0b00000001        //Key 1 pressed
             &&ServoPos>1000)           //and servo not fully left
                ServoPos-=100;          //move servo a bit left
            if(Edges==0b00000100)       //key 2?
                ServoPos=1500;          //set center
            if(Edges==0b00100000        //Key 3 pressed
             &&ServoPos<2000)           //and servo not fully right
                ServoPos+=100;          //move a bit right
     
    If the steps are too bit change the 100 value.

    Edit, you probably want to experiment with the endstop values (1000 and 2000) as I believe most servos go beyond the 1-2mS range. Just tried my Futaba S3003 and the endstops seem to be 600 and 2400.

    That code is a little confusing, the lines are actaully,
    Code (text):

        if(Edges==0b00000001 && ServoPos>600)
        {
            ServoPos-=100;
        }
     
    I just split them so it looked tidy.

    Mike.
     
    Last edited: Feb 13, 2008
  3. simrantogether

    simrantogether New Member

    Joined:
    May 22, 2006
    Messages:
    433
    Likes:
    4
    Location:
    Bangalore
    Mike made a day...

    Wow,

    Mike made a day...

    Many posts in this thread in less time..

    Regards,

    Simran..:)
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Triode

    Triode Member

    Joined:
    Feb 11, 2009
    Messages:
    925
    Likes:
    22
    Location:
    Bay Area

    I just googled for "junebug c18 servo example" and it took me to a forum I frequent anyway, how convienient is that? Thanks for the code Pommie. I'll be making use of this when i get home.

    I've got a question already, where did you find out all the system variables your setting and what they do? such as "ADCON0bits.GO" I'm just starting on C18, and with 18F chips. I'm going to look through some of the microchip PDFs and see if I can find it.
     
    Last edited: Jun 15, 2009
  6. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    They're all listing in the data sheet. Here's the 18F1320 data sheet. If you mean the actual names, they pretty much follow the data sheet but if your unsure they're in the 18F1320.h file in C:\MCC18\h.

    Mike.
     
  7. Triode

    Triode Member

    Joined:
    Feb 11, 2009
    Messages:
    925
    Likes:
    22
    Location:
    Bay Area
    Thanks, I see a lot of the variables you used, but with "bits" at the end, what does that do?
     
  8. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,808
    Likes:
    135
    Location:
    morristown,tn
    ONLINE
    I'll have to give this a try with the junebug Looks good Mike. futz It's good to see you been a long time haven't seen you glad to see your still with us.I just tried it with a cheapo parallax servo works great Thanks Mike. good work.
     
    Last edited: Jun 15, 2009
  9. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    It's the way C18 accesses the individual bits in a variable. Other compilers use a syntax like adcon0.GO=1 (BoostC) but Microchip decided that typing practice was good for people and added bits into the middle of it and so in C18 it's ADCON0bits.GO=1. Another way to write it is ADCON0|=2; as the GO bit is bit 1 (I think).

    Mike.
     
  10. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    Haven't seen Futz for a long time, he seems to have stopped visiting. I guess that you didn't notice that this thread is over a year old.

    Mike.
     
  11. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,808
    Likes:
    135
    Location:
    morristown,tn
    ONLINE
    That why I didn't see it till today Triode stated it back up
    dope till I posted two times lol I looked at futz site to day he got into bigger toys
     
    Last edited: Jun 15, 2009
  12. Triode

    Triode Member

    Joined:
    Feb 11, 2009
    Messages:
    925
    Likes:
    22
    Location:
    Bay Area
    Well, like I said when I replied to it, I googled for exactly what this thread was about and ended up finding it here, where I already post, so why not bring it back.

    Thanks for clairifying that pommie, I had found the list of what each bit did in the variables, but I had never seen "bits" written in like that.
     
  13. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    If anyone is having problems with the interrupt driven version it is because I used the wrong interrupt vector.

    The line,
    Code (text):

    #pragma code low_vector=0x18    //setup the ISR vector
     
    Should be,
    Code (text):

    #pragma code low_vector=0x[COLOR="Red"]0[/COLOR]8    //setup the ISR vector
     
    The old version of the C18 compiler put NOPs between the vectors and so the code worked. The new version of the compiler puts code there and so it crashes.

    I noticed this as I needed the code to align a servo that had stripped its gears.

    Mike.
     
    Last edited: Oct 9, 2009
  14. yohanevindra

    yohanevindra New Member

    Joined:
    Nov 26, 2008
    Messages:
    143
    Likes:
    0
    Location:
    Sydney, Australia & Colombo, Sri Lanka
    hi mike,

    thanks for putting this code up. my application basically uses a PIC18 with a 10Mhx crystal connected to it. Will i have to make any modifications to this code, especially with regards to the delays?or is it the same regardless of the clock speed?
     
  15. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    With a 10MHz clock a 1mS pulse will be 1250 cycles. So multiply all time by 1.25 to get the new times. The line ServoPos=ADRES+1000; will need to be ServoPos=ADRES*5/4+1250;

    Note also the interrupt vector is wrong. See the post above yours.

    Mike.
     
  16. yohanevindra

    yohanevindra New Member

    Joined:
    Nov 26, 2008
    Messages:
    143
    Likes:
    0
    Location:
    Sydney, Australia & Colombo, Sri Lanka
    how did you do the maths for it?im a bit confused :S

    no mike, ur interrupt vector is correct..low priority interrupts are a 0x0018 and high priority is at 0x0008...
     
  17. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    The maths is simple, at 8MHz the timer would be clocked at 2MHz if the prescaler wasn't used. I set the prescaler to 2 and so the timer is clocked once every microsecond. With a 10MHz clock it is 10/8 (=1.25) times faster.

    The interrupt vector would be correct if I used interrupt priorities but I chose to use compatibility mode and so all interrupts go to the vector at 0x08.

    Mike.
     
  18. yohanevindra

    yohanevindra New Member

    Joined:
    Nov 26, 2008
    Messages:
    143
    Likes:
    0
    Location:
    Sydney, Australia & Colombo, Sri Lanka
    Code (text):

    #include <p18f452.h>

    #define ServoPin PORTAbits.RA2

    int ServoPosition;

    void CCP2_ISR();

    #pragma code high_pri_vec = 0x0008
    void high_pri_vec()
    {
        _asm
        GOTO CCP2_ISR
        _endasm
    }

    #pragma interrupt CCP2_ISR
    void CCP2_ISR()
    {  
        if(ServoPin==1)
        {
            ServoPin = 0;
            CCPR2 = 25000 - ServoPosition;
        }
        else
        {
            ServoPin = 1;
            CCPR2 = ServoPosition;
        }
        PIR2bits.CCP2IF = 0;
       
    }

    #pragma code
    void main()
    {
        ServoPin = 0;
        TRISAbits.TRISA2 = 0; //Set Pin A2 as an output for the Servo
        CCP2CON = 0b00001011; //Setup CCP2 to generate special event
        CCPR2 = ServoPosition;
        T3CON = 0b10011001; //Setup timer3, prescaler=2
        ServoPosition = 1875; //Mid point position for Servo
        TMR3H = 0;
        TMR3L = 0;
        PIE2bits.CCP2IE = 1; //Enable CCP2 interrupt
        INTCONbits.PEIE = 1; //Enable peripheral interrupts
        INTCONbits.GIE = 1; //Enable all interrupts
        while(1);
    }

     
    i modified the code, since i needed a program which enabled the servo position to be controlled outside of the main servo control program. basically this is a servo control program....i was testing it in the MPLAB SIM, and it seems like it is stuck in an endless loop. the timer goes up to a value above 200, but never above 300, and then simply restarts. as a result, the compare never occurs. what's wrong here?

    ok.so it seems like timer3 isnt accessing the high byte and counting up only to 256. what am i doing wrong?
     
    Last edited: Oct 24, 2009
  19. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    You are still using Timer1 for the CCP module. Try T3CON = 0b11011001;

    Mike.
     
  20. yohanevindra

    yohanevindra New Member

    Joined:
    Nov 26, 2008
    Messages:
    143
    Likes:
    0
    Location:
    Sydney, Australia & Colombo, Sri Lanka
    i changed tht...its still the same..now it seems to be giving me random values...

    any other registers i need to configure?
     
  21. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    You need to make A2 digital with ADCON1=0x07;

    Analogue pins always read back as zero.

    Mike.
     

Share This Page