Menu

AVR PWM for Servo updates Guide

kent_twt4
2017-05-31
2017-05-31
  • kent_twt4

    kent_twt4 - 2017-05-31

    This is a guide to setup the AVR PWM for updating a servo in the background. This demo is for sweeping a regular servo through it's motion or a continous servo backwords, neutral, and forward. The long waits are used to measure the PWM pulse width values.

    #chip mega328, 16
    
    '**********
    'step 1:  pick TIMER, and PWM pin, which will be timer1 for it is a 16
    'bit timer, and OC1A for the pin.
    
    #define Servo1 PortB.1
    Dir Servo1 OUT   'pin OC1A or Pin 9 on the UNO board
    
    'step 2:  set the MODE wanted, which is phase correct and a TOP of ICR1
    'so we can set the 20ms update frequency/period accurately.  From table
    '16-4, mode 10 is required:
    
    Set WGM13 ON
    Set WGM12 OFF
    Set WGM11 ON
    Set WGM10 OFF
    
    'step 3:  pick the PRESCALE for reasonable step resolution, say 250
    '(over 2ms) steps.  Since 2ms is 10% of the 50 Hz (i.e. 20ms update) we
    'will look for a TOP value (ICR1) of 2500.  Using the formula from the
    'data sheet, and available prescales. TOP or ICR1 = (16000000 / 2 *
    '50 * 64)- 1 = 2499; so 250 is the duty cycle for 2ms with the prescale
    'at 64.  Set clock select or prescale bits:
    
    Set CS12 OFF
    Set CS11 ON
    Set CS10 ON
    
    'step 4:  set the PERIOD or frequency per previous TOP/ICR1 calculation:
    'Servo Update = 2499 for 50Hz/20ms
    
    ICR1H = 9
    ICR1L = 195
    
    'step 5:  Start DUTY CYCLE at servo center, using OC1A pin of Timer1.
    '1.5ms or approximately 3/4 * 250 = 187:
    'test neutral for continous servo
    
    Dim ServoPeriod1 as Word
    OCR1AH = 0
    OCR1AL = 187
    
    'step 6:  set PWM MODE BITS to startup the module.
    
    Set COM1A1 On
    Set COM1A0 Off
    '**********
    
    Dim steps as Word
    wait 5 s
    
    Main:
    steps = 90
    SetDuty (steps)
    wait 5 s
    For steps = 90 to 187
      SetDuty (steps)
      wait 20 ms
    Next
    wait 5 s
    For steps = 187 to 290
      SetDuty (steps)
      wait 20 ms
    Next
    wait 5 s
    goto Main
    
    sub SetDuty (ServoPeriod1)
      OCR1AH = ServoPeriod1_H
      OCR1AL = ServoPeriod1
    end sub
    
     
  • stan cartwright

    stan cartwright - 2017-05-31

    I copy pasted that to gcb and saved. I'll give ita try...well scope and mess with. All those silly register bit names...if tey are...like arduino guide to timers and pwm/cmmp.
    I'll see now what it does,

     
  • stan cartwright

    stan cartwright - 2017-05-31

    It crashed gcb when I flashed hex.on it. avrdude errors. I get back sir l8r

     
  • stan cartwright

    stan cartwright - 2017-05-31

    GCB hex file crashed xloader. cntrl/alt/del job. No compile errors.No make hex errors.
    The p in #chip mega328, 16 but now scoping it won't trigger

     
  • kent_twt4

    kent_twt4 - 2017-05-31

    Not familiar with xloader, but I just did a copy and paste, make hex and no compiler problems. Reflash with avrisp Mark ii and super bloated atmel studio 7. Getting PWM period of 50Hz, and pulse widths of 0.720ms, 1.496ms, and 2.321ms as expected with DVM.

     
  • stan cartwright

    stan cartwright - 2017-05-31

    Is the sub working ... 8 bit val to lo hi or moi not with it?? complicated stuff on pic to.

     
  • stan cartwright

    stan cartwright - 2017-05-31

    I stuck the p in mega328 and hexflash from GCB ok but nowt solid on portb.1 pin 9 arduino uno on scope

     
  • stan cartwright

    stan cartwright - 2017-05-31

    It's a works for me thing. Please re check, I send stuff and missed a bit lots.

     
  • stan cartwright

    stan cartwright - 2017-05-31

    maybe not the rightt bits for uno Set WGM13 ON
    Set WGM12 OFF
    Set WGM11 ON
    Set WGM10 OFF
    I'm just guessing cos the arduino guide says not uno but I'm not certain...baffled by science

     
  • stan cartwright

    stan cartwright - 2017-05-31

    there's activity on several pwm pins. My scope won't trigger though

     
  • kent_twt4

    kent_twt4 - 2017-05-31

    Sub works, otherwise would not get correct pulse widths. Period and duty cycle word values need to be loaded in correct order for the "timer" which is the high register first, then low register, per recent conversation with William. "HAVE TO USE THAT SUB" for the duty cycle values, otherwise gcb will try and load the low register first, which is no bueno.

    Should work as unmodified, so I think it may be the tool chain. You have been using xloader all along with no problems? Xloader works with a specific bootloader, is it the correct one? If not, then try a different version of xloader, or the required bootloader? I use 328p device with Studio 7 programming tool. I am currently on gcb 95.008, I'll try on 97.01 and see what happens, seems like I did this before.

    Just reflashed once again from cut and paste, with 95.008, and still good results. The WGM3:WGM0 bits are correctly set for the TC1 PWM mode 10.

    EDIT: said WGM3:WGM0 meant WGM13:WGM10 bits.

     

    Last edit: kent_twt4 2017-05-31
  • kent_twt4

    kent_twt4 - 2017-05-31

    Separate power supply for servo I hope,.... if it is hooked up? grounds need to be connected too.

     
  • stan cartwright

    stan cartwright - 2017-06-01

    Hi again. My cheapo dso managed to trigger but the signal is swamped with other signals.! KHz is dominant.. It won't drive a servo. Why am I getting non result. I'm using v.97 and came with it pwm in include/lowlevel not test pwm but tried that to.
    I've been looking at https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM fo insight.
    Looksl ike mains hum. I put a do loop at line 51.

     

    Last edit: stan cartwright 2017-06-01
  • stan cartwright

    stan cartwright - 2017-06-01

    Sorted.Works ok. Dunno why didn't work. Nice work Kent.

     
  • kent_twt4

    kent_twt4 - 2017-06-01

    Looks like you are getting the Hantek DSO sorted out? Sometimes when chasing 1's and 0's the results can be inexplicable :). Don't have that tool, so no help here on how to run it. Try the pulse width setting for ms timing? Here is a pic of the Saleae clone logic tool zoomed in.

     
  • stan cartwright

    stan cartwright - 2017-06-01

    Cheapo dso is not a substitute for old analogue scope I found. I wouldn't have sorted all that code you did myself. Great job.

     
  • stan cartwright

    stan cartwright - 2017-06-02

    Sorry to distract you but could you run 3 servos off this routine by stopping and starting similar code cos there's time for 3 routines. Sorry if that's a dumb question. Is there a gcb pic version of hpwm servo or method for pic with hpwm? All the new timer and now hpwm new dev I get lost keeping up.. Brill this complicated stuff is being made easier.

     
  • kent_twt4

    kent_twt4 - 2017-06-02

    Yes on using three servos with AVR hardware PWM, but I think it would have to be a large pinout AVR device like the atmeg2560. The '2560 has four 16bit timers, with each timer having 3 PWM channels OCRxA, OCRxB, and OCRxC. The '328p 16 bit timer only has two PWM channels OCR1A, and OCR1B connected to the 16 bit timer1.

    In order to get the three servos using the 328p, I would probably us the above method to control two servo's like for robot drive and use the PWM period interrupt to update a third servo. start a timer2, turn on a pin for third servo, wait for timer2 compare match to fire another interrupt to set the third servo pin off. Sounds complicated, there is probably a better way of thinking on this others may want to elaborate.

    Not aware of gcb servo command, or similar PIC HPWM routine, but servo's have been discussed in the past, so a search can lead to some demo code for more servos?

     
  • stan cartwright

    stan cartwright - 2017-06-02

    I haven't checked all pics compare and hpwm capabilities. I would think some pis might be similar to 2560
    I like simple robots and built a line follower that used two fitec 9g servos modded for continuous. It used 50hz interrupt pulseouts and worked. I want another normal servo for a distance sensor holder.I'll wire scope it and see what happens without another solutin. Maybe I'm hoping too much and why they sell servo controller boards :)

     
  • kent_twt4

    kent_twt4 - 2017-06-02

    I am sure the 50Hz interrupt is a good strategy, it is the way it is mostly done?

    I have used the PIC16f1572 before for driving leds, it has four 16bit PWM, kind of rediculous really for an eight pin device. That could do four servos in hardware PWM. You probably need more pins though, so look for one using Microchip MAPS found here http://www.microchip.com/maps/microcontroller.aspx to find what you need.

     
  • stan cartwright

    stan cartwright - 2017-06-06

    I didn't know about that. Thank you.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.