Go Down

Topic: Help with PWM @ 66.8 Hz? (Read 1 time) previous topic - next topic

krileyll

how to produce a square wave with PWM for the Arduino Mega Development Board? i need the output wave to be at 5 volts and at a frequency of 66.8 Hz and the duty cycle of 10%.

Any help will be appreciate it

Thanks,

halabut

With an opamp.
This is how to make a square wave oscillator from an opamp with variable duty cycle (shown with 50%):
http://www.facstaff.bucknell.edu/mastascu/eLessonsHTML/UsefulCircuits/SqWaveGenerator.htm
Some general opamp information: http://www.opencircuits.com/Op_amp
also try this book, it's mostly single sided opamps, which is probably what you'd be using, and has a good collection of circuits:
http://focus.ti.com/lit/an/slod006b/slod006b.pdf

Alec

-- Alec

Grumpy_Mike

You have no need of any external hardware to do this.

First of all you have to set the PWM frequency to the one you want. See this thread for a discussion:-
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1252073278/7#7

Then for a 10% duty cycle just do an :- analogWrite(pin,25);
With pin being the PWM pin number of your choice.

krileyll

#3
Nov 02, 2009, 05:44 pm Last Edit: Nov 02, 2009, 05:44 pm by krileyll Reason: 1
I really dont understand how manipulate the code of prescaling of the frequency to create the PWM? Also, how can you create identical PWM outputs at 66.8 Hz?


Grumpy_Mike

Quote
I really dont understand how manipulate the code of prescaling of the frequency to create the PWM?

You just poke the number in that gives you the delay you want. You work out the delay you want from the clock frequency (16MHz)

Quote
Also, how can you create identical PWM outputs at 66.8 Hz?


Once you set the PWM output frequenncy they all run at the same speed.

#5
Nov 03, 2009, 05:16 am Last Edit: Nov 03, 2009, 05:35 am by selfonlypath Reason: 1
Here is an example that runs on mega board using 16bit-timer number 5
Code: [Select]
int outputPsuB = 45;  // Timer5-B

void setup()
{
// PSU outputs via timer5
 pinMode(outputPsuB, OUTPUT);  // select Pin as ch-B
 
 TCCR5A = B00100010; // Phase correct PWM change at OCR5A
 TCCR5B = B10010;  // prescaling by 8 the system clock
 OCR5A = 14970; // 66,8002672Hz
 OCR5B = 1497; // 10% PWM
 }  


Suppose you prescale by 1024 instead of 8, you still can have roughly 66,8Hz but with less precision
Code: [Select]
int outputPsuB = 45;  // Timer5-B

void setup()
{
// PSU outputs via timer5
 pinMode(outputPsuB, OUTPUT);  // select Pin as ch-B
 
 TCCR5A = B00100010; // Phase correct PWM change at OCR5A
 TCCR5B = B10101;  // prescaling by 1024 the system clock
 OCR5A = 117; // 66,7735Hz
 OCR5B = 12; // 10,26% PWM
 }  

and so on.

Please take time to check atmega1280 data sheet section on timers because there are different ways to generate PWM frequency with different stability: fast PWM, phase correct PWM, phase & frequency correct PWM.

With one 16-bit timer, once you set its frequency by blocking OCRnA, you still have two indepedent PWM outputs via OCRnB and OCRnC.

Of course, you can generate more 66,8Hz PWM outputs by using timer1, timer3 & timer4.

Worthwhile noting you can delay or phase shift same 66,8Hz and 10%PWM by controlling TCNTn counters of respective timers.

If you need more outputs, then use timer0 and timer2 which is 8bit hence less resolution and different register access but it works. Care shoudl be taken with timer0 because it handles millis() and micros() subroutines.

P.S.1. If you need many PWM outputs with same frequency, PWM and phase, best to use only one timer output pin and build electronic hardware multiple drivers so you can save atmega1280 timers for other use because they are very precious.

P.S.2. Please look excellent document for pin allocation & timer mapping:
http://spreadsheets.google.com/pub?key=rtHw_R6eVL140KS9_G8GPkA&gid=0

krileyll

@selfonlypath Thanks your all your help so far with helping creating code for PWM. I was wondering is there a particular reason why you didnt use any of the PWM timers on pins 2-13?
or if its even possible to?  

what the code would be for a 2nd PWM at the same frequency and duty cycle as the first one? I need it for controlling a servo motor one PWM for forward and reverse and the other PWM for left and right.



#8
Nov 09, 2009, 05:11 am Last Edit: Nov 09, 2009, 05:18 am by selfonlypath Reason: 1
hey krileyll
Quote
I was wondering is there a particular reason why you didnt use any of the PWM timers on pins 2-13? or if its even possible to?


I gave you an example working with timer5 which only can handle pins 44-45-46.

Of course, I'm using in my lab pins between 2-13 related to timer1, timer3 and timer4 to set any PWM frequency and duty cycle as well as timer0 and timer1 except these last two timers are only 8bit precision.

Quote
what the code would be for a 2nd PWM at the same frequency and duty cycle as the first one? I need it for controlling a servo motor one PWM for forward and reverse and the other PWM for left and right.


really easy, for example with same frequency but 20% and 30% using same timer:
Code: [Select]

int outputPsuB5 = 45;  // Timer5-B
int outputPsuC5 = 44;  // Timer5-C

void setup()
{
// PSU outputs via timer5
 pinMode(outputPsuB5, OUTPUT);  // select Pin as ch-B
 pinMode(outputPsuC5, OUTPUT);  // select Pin as ch-C
 
 TCCR5A = B00100010; // Phase correct PWM change at OCR5A
 TCCR5B = B10010;  // prescaling by 8 the system clock
 OCR5A = 14970; // 66,8002672Hz
 OCR5B = 1497; // 10% PWM on channel B5
 OCR5C = 2994; // 20% PWM on channel C5
}


or another way with same frequency but 20% and 30% using two independent timers:
Code: [Select]

int outputPsuB5 = 45;  // Timer5-B
int outputPsuB4 = 7;  // Timer4-B

void setup()
{
// PSU outputs via timer5 and timer 4
 pinMode(outputPsuB5, OUTPUT);  // select Pin as ch-B5
 pinMode(outputPsuB4, OUTPUT);  // select Pin as ch-B4
 
 TCCR5A = B00100010; // Phase correct PWM change at OCR5A
 TCCR5B = B10010;  // prescaling by 8 the system clock
 OCR5A = 14970; // 66,8002672Hz
 OCR5B = 4991; // 30% PWM on channel B5

 TCCR4A = B00100010; // Phase correct PWM change at OCR4A
 TCCR4B = B10010;  // prescaling by 8 the system clock
 OCR4A = 14970; // 66,8002672Hz
 OCR4B = 1497; // 10% PWM on channel B4

}



#9
Nov 12, 2009, 04:41 am Last Edit: Nov 12, 2009, 04:44 am by selfonlypath Reason: 1
Oups, slight error, TCCR4A or TCCR5A should be for correct phase PWM:
Code: [Select]
TCCR4A = B00100011; // Phase correct PWM change at OCR4A
TCCR5A = B00100011; // Phase correct PWM change at OCR5A

otherwise previous code:
Code: [Select]
TCCR4A = B00100010; // Phase correct PWM change at OCR4A
TCCR5A = B00100010; // Phase correct PWM change at OCR5A

was based on PWM interrupt capture trigger source ICR.

From http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1257929313/0#3

Sorry about that...

Go Up