Variable Frequency PWM (Pulse Width Modulation) Signal Generation Using Timers of Arduino (Atmega328p Microcontroller) - Arduino Fast PWM
Variable Frequency PWM (Pulse Width Modulation) Signal Generation Using Timers of Arduino (Atmega328p Microcontroller) - Arduino Fast PWM
In this post i am going to explain how to generate PWM of variable frequency using Atmega328 microcontroller?
OR how to generate a variable frequency PWM signal using Arduino Uno? Arduino uno board contains an atmel
Atmega328 microcontroller on it. I am going to generate a PWM of 50% duty cycle on frequencies between
10Hz to 100Hz. Frequency is changed using a potetiometer/variable resistor connected to an analog pin of the
POPULAR POSTS
Arduino. Changing frequency value is displayed on 16×2 character lcd.
Atmega/Arduino Timers
Fading/Controlling
First of all you need to understand about the timers of Atmega328 microcontroller and the registers associated led/brightness using
with them. Atmega328 has 3 timers. Timer-0, Timer-1 and Timer-2. To generate a variable frequency we have to Potentiometer(Variab
con gure the registers associated with these timers. Resistor) and
Arduino Uno
Arduino Pins associated with its timers
We can generate variable frequency or output variable frequency pwm on Atmega328 microcontroller pins Di erence between
(OC0A, OC0B, Oc1A, OC1B, OC2A, Oc2B). All these pins are associated with timers of Atmega328p. OCnX interfacing character
16×2 lcd in 4-bit and
represents “Output Compare” match. When ever timer/counter value is matched with the prede ned value in a
8-bit mode with
register OCR1A or ICR1 the OCnx pins gets control and now you can do di erent things. With this “Output microcontroller
compare match” principle we can accomplish di erent tasks. Output a variable pwm (pulse width modulation)
signal and so on. I am going to output a variable frequency pwm signal using this principle. Timers registers with DronStudy:
associated timers and arduino pin numbers is shown below.. Educating India’s
students one at a
time
Webinar: Designing
for HP 3D Jet Fusion –
10 Tips You Need to
Know
So to Output a variable frequency we have to calculate the value for ICR1 register. For example to generate a
100Hz frequency using 16MHz timer and prescaler of 8 the value for ICR1 comes out to be.
Now to output a PWM on variable frequency we have to con gure OCR1A register. I am going to output a PWM
of duty cycle 50%. Take the above generated frequency 100Hz as reference. To generate PWM of 50% duty RECENT ARTICLES
cycle. We have to invert the signal output from low to high and high to low after every 5ms since the frequency
in 100Hz. SB Components’ BreadPi is a new multi-
purpose hat for Raspberry Pi systems
For this to happen we have to set some bits in timer registers TCCR1A and TCCR1B. In TCCR1A set the mode of Student engineers invent robotic system to
the timer. I set Fast PWM. By selecting bits COM1A1,COM1B1. Selecting these bits will make your pins OC1A and safeguard underground workers
OC1B to output fast PWM. Intel’s Horse Ridge to optimize commercial
quantum computers
Intel launches RealSense LIDAR Camera
technology
LoRaWAN in action
Now when mode is selected we have to do one more thing select the wave form. I selected PWM phase and
frequency correction mode.
To study about the mode please consult the datasheet topic 16.9.5 Phase and Frequency Correct PWM Mode. I
bet reading the topic “16.9.5 Phase and Frequency Correct PWM Mode” will clear you all about generating
variable frequency PWM using Arduino(Atmega328p).
1
2 #include <LiquidCrystal.h>
3 LiquidCrystal lcd(13, 12, 5, 4, 3, 2);
4 int Pwmpin=9;//Pwm Output Pin
5 int Fchange= A0;//Frequency change through Potentiometer
6 //int Button=1;//Button to change the frequency
7 void setup()
8 {
9 lcd.begin(16, 2); // set up the LCD's number of columns and rows:
10 pinMode(Pwmpin, OUTPUT);//Pwm pin as Output
11 //pinMode(Button, INPUT);//Button as Input
12 TCCR1A=_BV(COM1A1)|_BV(COM1B1);//Non-inverted Mode
13 TCCR1B=_BV(WGM13)|_BV(CS11);//Prescalar 8
14 lcd.setCursor(0, 0);//Lcd Coulomb 0 Row 1
15 lcd.print("Pwm Period = 50%");
16 }
17
18 void loop(){
19 float freq=0;
20 float count=10000,countt=0,Pinput=0;
21
22 while(1){
23 ICR1=count;//variable Frequency
24 countt=2*8*count;
25 freq= int(16000000/countt);
26 OCR1A=int(count/2);
27 lcd.setCursor(0, 1);//Lcd Coulomb 0 Row 2
28 lcd.print("Pwm Freq =");
29 lcd.print(freq);
30 count=10000;
31 Pinput=analogRead(A0);//Read input value
32 Pinput=(Pinput/0.0113);
33 count=count+Pinput;
34 if(count>=100000)
35 {
36 count=10000;
37 }
38 delay(1000);
39 }
40 }
1
2 #include <LiquidCrystal.h>
3 LiquidCrystal lcd(13, 12, 5, 4, 3, 2);
4 int Pwmpin=9;//Pwm Output Pin
5 int Fchange= A0;//Frequency change through Potentiometer
6 //int Button=1;//Button to change the frequency
7 void setup()
8 {
9 lcd.begin(16, 2); // set up the LCD's number of columns and rows:
10 pinMode(Pwmpin, OUTPUT);//Pwm pin as Output
11 //pinMode(Button, INPUT);//Button as Input
12 TCCR1A=_BV(COM1A1)|_BV(COM1B1);//Non-inverted Mode
13 TCCR1B=_BV(WGM13)|_BV(CS11);//Prescalar 8
14 lcd.setCursor(0, 0);//Lcd Coulomb 0 Row 1
15 lcd.print("Pwm Period = 50%");
16 }
17
18 void loop(){
19 float freq=0;
20 float count=10000,countt=0,Pinput=0;
21
22 while(1){
23 ICR1=count;//variable Frequency
24 countt=2*8*count;
25 freq= int(16000000/countt);
26 OCR1A=int(count/2);
27 lcd.setCursor(0, 1);//Lcd Coulomb 0 Row 2
28 lcd.print("Pwm Freq =");
29 lcd.print(freq);
30 count=10000;
31 Pinput=analogRead(A0);//Read input value
32 Pinput=(Pinput/0.0113);
33 count=count+Pinput;
34 if(count>=100000)
35 {
36 count=10000;
37 }
38 delay(1000);
39 }
40 }
Important Update: Due to many questions on what is 0.0113 in code? Here is its explanation. Since i am
generating variable frequency between 10 Hz to 100 Hz. For generating frequency of 10 Hz count(in code) or
ICR1 value is 100000 and for 100Hz count or ICR1 value is 10000(You can calculate values in upper given
formula). You know that analogread() function of arduino reads 1023 when voltage at corresponding analog pin
is 5 volts. 0.0113 is increasing this 5v corresponding value to match the needed input for pwm function. For
example
For generating 10Hz signal. You input 4.8 volts.
Code Flow
Pinput will be Pinput=1015; // 4.8 volts at arduino analog pin reading
Pinput=(1015/0.0113); —> Pinput=89823;
count= 10000+89823;
count=99823; //If we put this count value back in above formula we get 10.01 Hz frequency
The maximum analog channel can read is 1023 and Pinput value goes to 1023/0.0113=90530 or
count=10000+90530= 100530. Which lower down the frequency to 9.9 Hz and since we want to remain in the
bracket of 10 to 100Hz so we can not go more high. I hope 0.0113 makes sense now. Its just a value to remain
in 10000 to 100000 bracket.
Variable Frequency PWM(Pulse Width Modulation) signal generation using Timers of Arduino(Atmega328p
Microcontroller)/Arduino Fast PWM
Download the project code, folder includes project simulation on proteaus and Arduino Project .ini
le. If you have any questions regarding project code write them below in the projects section.
Copyright © 2019 WTWH Media LLC. All Rights Reserved. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of WTWH Media
Privacy Policy | Advertising | About Us