Go Down

Topic: Phase Correct PWM library? (Read 1 time) previous topic - next topic

rwgast

Im very new to Arduino, not micros or C though. Im currently building a robot with the brain based on a 32 bit 8 core Propeller and a Rasberry Pi. At this point ive got my mechanical platform running and I need to slam out a serial controlled motor controller and voltage and current monitoring system. I chose the ardruino for this part becuase after i watched jeremy blumbs video tutorials on arduino i was sold on its ease of use for processing tasks that dont need a ton of speed, i use to use the basic stamp for this but its to limited an atmega128 with the internal oscillator can do everything i need with no other chips thanks to its analog pins and interupts.

right now im just trying to get my motor control running quick without learning much. ive got the hbridge connected to an atmega328 bread board based arduino. i did some reading and want to set up 2 phase correct pwm channels. being new to avr/arduino im not understanding the registers and things very much and just want to get the bot running to find any mechanical issues. i was wondering if theres a pwm library that can easily set up a 100khz phase correct pwm for me with just a function call or something. i plan to get running now and read books later, the basics of arduino seem very easy i just really need to learn more about the acuall chip architecture

PaulS

Quote
i did some reading and want to set up 2 phase correct pwm channels.

To control electric motors, which wouldn't know phase correct PWM if it bit them in the ass?

PeterH


100khz phase correct pwm


Do you mean you want the PWM to be synchronised / phased correctly with respect to some external event? (Are you trying to build your own brushless motor controller?)
I only provide help via the forum - please do not contact me for private consultancy.

rwgast

Im sorry I should have been more clear on what im acually trying to do and what im talking about.

Yes i am making a serial based motor controller along with battery managment sytem using an Arduino and STM l293E. The plan is to connect the l293E to an atmega168 running on an internal 8mhz oscillator, the atmega168 will be handeling battery managment via its analog pins.  For motor control the plan is to have the atmega except commands from any serial communication source such as, Forward, Reverse, 45degree turn etc etc. When the arduino recives a serial command via a PC/Propeller Micro/Bluetooth module whatever, it should call a function using an interput. The motors im using also have encoders so I want to be able to have the option to use a closed loop feedback system to do a PID loop on the motors, or switch modes to open control with no error detection or speed compensation on the motors. All this stuff is a little down the line though...

Right now I have an arduino rbbk connected to my h bridge which is connected to two motors. Obviously changing the direction of the motors is no big deal thats just setting certain pins on the arduino  Hi and Low which, which are connected to the hbridge chips inputs. Right now all im trying to do is generate two different PWM signal lines using timer zeron, pins 5 and 6 correct? Bit banging PWM is fairly straight forward but one PWM locks up the whole micro to the task, so I obviously wont be able to generate two simaltanous PWM lines while monitoring batteries and serial and all that good stuff.

I googled around about how to use the arduinos timers for PWM generation and found this article http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM. It goes over three different way of using arduino for PWM, there is bit banging, Counter Based Fast PWM, and finally counter based Phase Correct PWM. Being farily new to the Arduino I dont understand the examples it looks as if there or'ing some flags to set a register or something... Im not real sure how to set the PWM frequency either.. I was hoping maybe there is a library using the fast pwm or phase correct pwm methods descrided in that article to dumb it down to something like this

startPWM(pin, frequency, duty cycle);

My hbridge is capable of 100khz signals, from what I know about motor control 200Khz is going to be a really nice PWM ramp for DC motor applications, if I cant use the Arduino to generate pwm frequency this hi thats OK, but I dont see why not, A propeller can do clock lines up to 125mhz and its only an 80mhz chip, so im assuming 100khz should be failry easy for a 16 or even 8mhz chip

PeterH

I would guess you need to use an external interrupt handler to start the output pulse and start a hardware timer which will trigger an interrupt handler to end the pulse. I can follow the general principles well enough to feel that it ought to be possible, but it'd require direct configuration of the hardware timers which I have no experience of. Given that you've found an article explaining how to do this sort of thing, I'm sure you'll figure it out with perseverance.
I only provide help via the forum - please do not contact me for private consultancy.

rwgast

Acually I just opend some book about robitcs and arduino it explained alot of this in a simpler fashion so I could just get it going. One thing im not understanding is there are certain flags for the timers to set the PWM frequency the highest one is only 62khz....  Do these chips max out there, is there no flexablitiy to set custom frequencys. Im starting to wonder if ive made a bad choice here it will get the job done just not as well as I hoped.

Im really not understanding why I cant flip a pin at 100khz and then set a duty cycle...

Nick Gammon

#6
Nov 21, 2012, 06:29 am Last Edit: Nov 21, 2012, 06:34 am by Nick Gammon Reason: 1
The Atmega328 has 3 timers all of which are capable of phase-correct PWM. Two are 8-bit timers, one is 16-bit.

I have some logic analyzer images of all the modes on Timer 0 here:

http://www.gammon.com.au/forum/?id=11504

You can get very high frequency phase-correct PWM. It is just a trade-off between frequency and duty cycle resolution.

This image, for example shows 40 KHz:



Code to generate that:

Code: [Select]

#include <TimerHelpers.h>
// Timer 0
// output    OC0A   pin 12  (D6)
// output    OC0B   pin 11  (D5)

const byte timer0OutputA = 6;
const byte timer0OutputB = 5;
 
void setup() {
  pinMode (timer0OutputA, OUTPUT);
  pinMode (timer0OutputB, OUTPUT);
  TIMSK0 = 0;  // no interrupts
  Timer0::setMode (5, Timer0::PRESCALE_1, Timer0::CLEAR_A_ON_COMPARE | Timer0::CLEAR_B_ON_COMPARE);
  OCR0A = 200;    // number of counts for a cycle
  OCR0B = 150;    // duty cycle within OCR0A
}  // end of setup

void loop() {}


The 40 KHz is because of the frequency counter being 200, so with a clock period of 62.5 nS the frequency will be:

Code: [Select]

1 / (62.5e-9 * 200) / 2 = 40000


Just reduce the counter to get a higher frequency. eg. 75 would give approx 106 KHz. You divide by 2 because that is the way phase-correct works. It counts up and then counts down again.

The only drawback here is that since the "top" is 75, you only have 75 units of duty cycle. In other words, the duty cycle can be 1/75, 2/75 and so on. That is, increments of 1.33% each time.

I strongly recommend the hardware PWM. It will give jitter-free pulses without relying on interrupts or anything else, and you can have up to three of them at once (although you usually reserve Timer 0 for timing, like counting milliseconds).

You can change the duty cycle on-the-fly by merely writing a different number fo OCR0B (the duty cycle register).

Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon

Just to amplify on my previous answer, you can actually have six PWM outputs if you are prepared to sacrifice flexibility of choice of frequency. If you are prepared to accept the "top" as being 256 (0xFF since it is zero-relative) then you can use both "sides" of the counter for PWM output (with different duty cycles).

Since you are committed to a count of 256 then the maximum frequency will be:

Code: [Select]
1 / (62.5e-9 * 256) / 2 = 31250

That is 31.25 KHz in phase-correct mode, or double that (62.5 KHz) in fast PWM mode. That is probably where you heard of a maximum of 62 KHz.

So it's all about choice. You choose if you want 3 outputs or 6, and you choose if you want a high PWM frequency, or a fine resolution of duty cycle.

Also if you use Timer 1 you have more resolution up your sleeve because that can count up to 16 bits, not 8.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon

Quote
Right now all im trying to do is generate two different PWM signal lines using timer zeron, pins 5 and 6 correct?


Yes they are the output for that timer. However as mentioned above you need to use a second timer (eg. Timer 2) if you want to have the extra control over the frequency.

When specifying your own frequency the "A" side of the timer counts up to the requested top, and the "B" side of the timer counts up to the duty cycle.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

rwgast

ok so i had to rewire my breadboard i was mistaken how each input works, i guess the forward and reverse pins of each motor need a pwm signal, this means i need two timers one for each motor, then i need to be able to control 4 seperate pins. im assuming if im using the timer on pins 10, 11 i can shut pin 11 off right?

the next question is, is there any reason to use phase correct over fast pwm? like i said i need to be able to convert this to work with an 8mhz setup easily. what is the fastest frequency with the best resalution i can generate at 8mhz on a 168? See this is why i was hoping for a library im gratefull for the code i just dont know enough about the atmegas to understand how this all works beyond coppy an pasting your code and fiddling with the timers

Go Up