The best way to control a servo with a PIC


Closed Thread
Results 1 to 40 of 42

Hybrid View

  1. #1
    Join Date
    Jun 2007
    Location
    Mansfield, UK
    Posts
    697


    Did you find this post helpful? Yes | No

    Default

    Hmm, ive read the datasheet again. Aparently there is a register called TMR0. I cant seem to find any more information on that though. There is the prescaler but that does the oposite of what i want. I have heard that you can count how long something takes using the timer. Would you just have a loop and keep checking the current value? Is that value in TMR0? Ive not seen anything else about making the timer overflow at less than 256.

  2. #2
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by The Master View Post
    Hmm, ive read the datasheet again. Aparently there is a register called TMR0. I cant seem to find any more information on that though. There is the prescaler but that does the oposite of what i want. I have heard that you can count how long something takes using the timer. Would you just have a loop and keep checking the current value? Is that value in TMR0? Ive not seen anything else about making the timer overflow at less than 256.
    TMR0 is a register... Is this TMR0 a read-only register? Is it a write-only register? Is it a read/write register?
    If you can write to this TMR0 register as it's called, when can you write to it?
    Can you write to it while it's running? Or do you have to write to it while it's stopped?
    (I'm not dogging you at all...there's water around here somewhere...You just happen to be the horse )
    And no, for this particular item, there's not a lot of DIRECT information in the datasheets, but there is quite a bit of 'read-between-the-lines' stuff that applies to all registers and applies here...

  3. #3
    Join Date
    Jun 2007
    Location
    Mansfield, UK
    Posts
    697


    Did you find this post helpful? Yes | No

    Default

    I didnt see the answer to any of those questions when i read through the datasheet. Ill do some more reading tomorrow and probably some more google searches.

  4. #4
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by The Master View Post
    I didnt see the answer to any of those questions when i read through the datasheet. Ill do some more reading tomorrow and probably some more google searches.
    We don't need no steenkin' Google
    TMR0 is a register just like almost any other register, like any other byte of ram in the PIC. It just so happens that this register is increment on every instruction cycle (or every other one, or every 4th one, or whatever you've set it up to do).
    Does that help you out any?

  5. #5
    Join Date
    Jun 2007
    Location
    Mansfield, UK
    Posts
    697


    Did you find this post helpful? Yes | No

    Default

    I think so. I know the timer counts up to 256. Im guessing that register tells you its current count. I have read before that you can do that so i think i would keep checking it in a loop to see if it is above a certain value. If it is then there must be a way to reset it most likely disable it and enable it again.

    Just 'reading between the lines' of your post. I havnt checked yet but i wouldnt be supprised if you could set the value of the register to whatever you want after an interrupt so instead of counting 0-128 and checking in a loop you can start at 128 and count upto 255 which will allow the interrupt to work still

  6. #6
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by The Master View Post
    Just 'reading between the lines' of your post. I havnt checked yet but i wouldnt be supprised if you could set the value of the register to whatever you want after an interrupt so instead of counting 0-128 and checking in a loop you can start at 128 and count upto 255 which will allow the interrupt to work still
    BAM!
    So I think I can infer that you figured out that you can both read AND write the TMR0 register like any other R/W register out there. There's only a couple of 'catches' to writing the TMR0 register...and that item IS in the datasheet...
    Reload TMR0 with 128 (plus a small correction value depending on your code) and you're 51.2us can become 25.6us, or more, or less, depending on whatever you want to do...
    Works the same with the rest of the timers too...

  7. #7
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default

    Master, locate and download the MID RANGE MCU FAMILY REFERENCE MANUAL here:
    http://ww1.microchip.com/downloads/e...Doc/33023a.pdf
    Read Section 11 for detailed info on TIMER0.

  8. #8
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Ok, did some thinking, even easier plan to work with...

    Set up an interrupt routine to trigger a TRM1 overflow. PIC16F628A (or whatever), TMR1 prescale 1:2, you get an overflow interrupt 38.14 times per second, giving you about 26.21ms between interrupts. A servo needs at most a 2.5ms pulse to work right, and as you've figured out, 38 times per second should be good enough to hold position.
    So, you've got 26.21ms to work with, and 2.5ms for each servo. Should be able to handle 10 servo's here.
    So here's what some code might look like:
    Code:
    ....set up....
    ....Clear the pins, set up the variables, set up TMR1, set up the serial port, turn on TMR1 interrupts, turn on serial port receive interrupts
    inthandler:  'each time TMR1 overflows
    If TMR1 overflow interrupt
    ...clear the overflow flag
    ...put all servo pins low (even though they should be already)
    ...send out the pulse for servo 1 (all 2.5ms of it, high and low chunks included)
    ...send out the pulse for servo 2 thru 10 each in turn...
    ...check the RXIF flag in between each servo pulse, if there is one there, handle it in the main loop in the spare time after sending out all those pulses which probably won't total up to the total time between TMR1 interrupts...
    ...if the byte received by the serial port is an $FF, it'll mean that the next byte received is for servo 1, after that servo 2, after that servo 3, and so on...  This will also mean that a servo cannot have a position of $FF, which is okay, you're only losing one position.
    ...if it's not an $FF, it's for the next servo position in turn...
    RESUME
    mainloop: 'handle the received serial bytes and save them in the respective servo position variables...
    You get good enough framing for the individual servo pulses (about 38 per second), each servo gets the required 'high' time depending on the desired position, the rest of the time the pin is low (until the next TMR1 interrupt), and if you take care of the high and low time for each servo, in other words allotting 2.5ms per servo, each servo will get the right pulses at the same time in the TMR1 interrupt 'frame'...
    Of course, you'll have to 'convert' your received byte value to a value that'll fit inside that 2.5ms window, not really that hard, just multiply it by 10 will get you the full window plus a bit, but that might be too much for the servo's themselves.
    And if you're not using all 10 servo's, you could reload TMR1 with a 'correction value' and bring the refresh time for all the servo's up to 50hz. Theoretically, you should be able to drive 8 servo's at 50hz, but in a real world, probably only 7 because you'll have to have a bit of time left over for 'housekeeping' chores.
    If I get ambitious, I'll write up some actual code...if I get ambitious

  9. #9
    Join Date
    Jun 2007
    Location
    Mansfield, UK
    Posts
    697


    Did you find this post helpful? Yes | No

    Default

    Ive just done a quick bit of maths. I think if i set the timer to overflow when it reaches 39 (or start 39 before 255 ofcourse) then i should be able to get the resolution i want. I could in theory control quite a few servos by using almost identical code to the LED code. All i need to do is add that long pause in.

    Im always really ambitious so i might even try the origional plan again and control the servos from the same PIC as the LEDs. If i make the timer overflow every 39 instruction cycles that means it will run the PWM code every 7800ns. I can setup my own counter to only run the PWM code for the LEDs every 6 or 7 times the timer overflows. That should make the LED code run pretty much as normal. Now i can simply turn the servo output on then on each timer overflow count upto the servo value (plus a bit). The servo pulse range is 2000us so an overflow every 7.8us gives me a resolution of 256.41. If im not bothered about the 41 (and im not) then it matches the byte perfectly.

    I cant say if this method will work without trying it. It all depends on how many instruction cycles i have spare. I think its worth a try and i always have the seperate chip method if it fails.

    Edit: The type of servo im using seems happy to accept any length pulse i give it but if its outside of its range then it tries to turn too far and ends up buzzing at me
    Last edited by The Master; - 15th October 2008 at 09:32.

  10. #10
    T.Jackson's Avatar
    T.Jackson Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by skimask View Post
    We don't need no steenkin' Google
    I think someone got that from Sean Connery (The Untouchables)

  11. #11
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by T.Jackson View Post
    I think someone got that from Sean Connery (The Untouchables)
    Wrong again...

  12. #12
    T.Jackson's Avatar
    T.Jackson Guest


    Did you find this post helpful? Yes | No

    Default

    Straight away I thought of Sean Connery for some reason.

Similar Threads

  1. More Servo Woes
    By chrisshortys in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 13th May 2009, 08:40
  2. Help with Servo Control Please!
    By wireman22 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 7th June 2007, 18:15
  3. Servo control / UART / SPI help needed
    By Blackhawk in forum mel PIC BASIC
    Replies: 10
    Last Post: - 10th November 2006, 03:40
  4. How would i write this in pic basic pro (Servo controller)
    By Jhdgkss in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 10th February 2006, 08:21
  5. Control RC servo via Parallax Servo Control
    By cibotsan in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 17th September 2005, 08:18

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts