Let's Make Robots!

Software PWM

wolfc's picture

I was hoping to avoid wrighting my own software pwm for the pic but it looks like i've arrived there.  the motors and tracks I hot glued toghther don't drive straigh so the only way I can think of fixing it is to use PWM to slow down one motor.  I know I could use the one hardware pwm to slow down just one motor but thats going to be used in the future for somthing else so I have to create the pwm myself in software.

 I like how you can set the hardware and it will continue to work while the pic is doing other things.  I'd like to have the same sort of functionallity with the software pwm.  this leads me to think that I should use the timers and interrupts to create the PWM.  I've been looking for some examples that are simple to follow but I haven't come across a good one yet.  I guess what I'm looking for are the basic steps (psuedocode) to creating the PWM on a Pic18XXXX microcontroller.  

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Jimmy_K's picture
wolfc's picture
I modified my routine for a higher resolution but now the code is flaky.  it works for a while then seems to just stop working.  I need to modify my routine for measuring the distance with the SRF05 since the interrrupts have made this very inaccurate.  I think this is also where my code stalls.    I'd also like to figure out a way to reduce the number of interrupts but still have a good resolution so I can get the servo in the right position. 
BaseOverApex's picture

Have you tried steppig throught he code witht he "stopwatch" enabled in the IDE?

You may find that the ISR is taking longer to execute than the timeout period.

wolfc's picture

my original plan was to use the hardware pwm for the srevo but for some reason I cant seem to get it down to 50Hz.  the lowest I could get it was about 500 hz.  Now I need to figure out an interrupt routine that will work for both the servo and the pwm for the motors.  Modifying my routine for the motor pwm didnt seem to work too well.  it doesn't seem to have enough resolution. 

 

I have a 8Mhz internal clock and I need some ideas.  

RascalRobot's picture

I use a timer for my servos. If you have an 8 MHz internal clock ( I am assuming Fosc = 8Mhz ), then your timers will be driven at 2Mhz ( Fosc / 4 ). However, and this is what I do, prescale your 16 bit timer by 2, so it counts micro seconds. Now you can turn on a servo pin, set your timer to overflow at 1000 - 2000 microseconds, and in the interrupt routine, turn off the output pin. To do the long delay of 20 milliseconds, set your timer to overflow at 20,000 microseconds.

I wish there was a way to attacah a file. I could let you see my servo.asm file which controls 4 servos on an 18F4620.

BaseOverApex's picture

If you use a timer overflow at the end of the mark time and at the end of the space time, doesn't that mean that you can only have one servo under control ata  time? I can see how the end of the space would be the same for all four servos, but the ends of their respective marks might all be different.

RascalRobot's picture

I use one timer and do one servo "mark" at a time. I store the "mark" time as a 16 bit value, measured in microseconds. The final "space" time is always 30000 microseconds ( 30 mSec ). So if all servos are at their minimum of 1 mSec, then the total cycle time is 34 mSec. If all servos are at the maximum of 2 mSec, than the total cycle time is 38 mSec. I also put a 470 ohm resitor in series with the drive signal. This setup has been driving 2 HS311 and 2 HS425BB servos without jitter.

BaseOverApex's picture

I thought as much. Driving one servo's easy. Two is OKay. Four, I start to get the jitters. I really want to drive 16 servos, though.

RascalRobot's picture

that's too many for one timer to handle.
So your requiremetns are ...

1) 16 Servo Outputs
2) Programmable Servo Positions
3) I2C / Serial to recieve new position data

Is the micro doing anything else, like reading sensors or analyzing data, or is this a standalone servo controller chip ?

BaseOverApex's picture

Initially it was, but I took those functions off and decided to go with an MCU per function strung together on I2C.

It's not that it's too much for one timer. In fact a 16-bit timer provides loads more resolution than I need. It's the fact that the comparison of the timer with the demanded position, 16 times occupies more processor cycles than the length of one step of resolution.

I'm thinking four servos per controller and several controllers on an I2C bus.