Chuyển tới nội dung
Home » Pwm Code For Arduino | Simple Pulse Width Modulation With Analogwrite

Pwm Code For Arduino | Simple Pulse Width Modulation With Analogwrite

PWM in Arduino-Pulse Width Modulation

Pulse Width Modulation

Pulse Width Modulation, or PWM, is a technique for getting analog results with digital means. Digital control is used to create a square wave, a signal switched between on and off. This on-off pattern can simulate voltages in between the full Vcc of the board (e.g., 5 V on UNO, 3.3 V on a MKR board) and off (0 Volts) by changing the portion of the time the signal spends on versus the time that the signal spends off. The duration of “on time” is called the pulse width. To get varying analog values, you change, or modulate, that pulse width. If you repeat this on-off pattern fast enough with an LED for example, the result is as if the signal is a steady voltage between 0 and Vcc controlling the brightness of the LED.

PWM Examples

PWM has several uses:

  • Dimming an LED
  • Providing an analog output; if the digital output is filtered, it will provide an analog voltage between 0% and 100%.
  • Generating audio signals.
  • Providing variable speed control for motors.
  • Generating a modulated signal, for example to drive an infrared LED for a remote control.
PWM in Arduino-Pulse Width Modulation
PWM in Arduino-Pulse Width Modulation

Conclusion

This article helps explain the PWM modes of the Arduino. I found the documentation of the different modes somewhat opaque, and the off-by-one issues unexplained.

Suggested changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. You can read more on how to contribute in the contribution policy.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.

Basics of PWM (Pulse Width Modulation)

Learn how PWM works and how to use it in a sketch..

The Fading example demonstrates the use of analog output (PWM) to fade an LED. It is available in the File->Sketchbook->Examples->Analog menu of the Arduino software.

Pulse Width Modulation, or PWM, is a technique for getting analog results with digital means. Digital control is used to create a square wave, a signal switched between on and off. This on-off pattern can simulate voltages in between the full Vcc of the board (e.g., 5 V on UNO, 3.3 V on a MKR board) and off (0 Volts) by changing the portion of the time the signal spends on versus the time that the signal spends off. The duration of “on time” is called the pulse width. To get varying analog values, you change, or modulate, that pulse width. If you repeat this on-off pattern fast enough with an LED for example, the result is as if the signal is a steady voltage between 0 and Vcc controlling the brightness of the LED.

In the graphic below, the green lines represent a regular time period. This duration or period is the inverse of the PWM frequency. In other words, with Arduino’s PWM frequency at about 500Hz, the green lines would measure 2 milliseconds each. A call to analogWrite() is on a scale of 0 – 255, such that

requests a 100% duty cycle (always on), and

analogWrite(255)

is a 50% duty cycle (on half the time) for example.

analogWrite(127)

On some microcontrollers PWM is only available on selected pins. Please consider the pinout diagram of your board to find out which ones you can use for PWM. They are denoted with a tilde sign (~).

Once you get this example running, grab your Arduino and shake it back and forth. What you are doing here is essentially mapping time across the space. To our eyes, the movement blurs each LED blink into a line. As the LED fades in and out, those little lines will grow and shrink in length. Now you are seeing the pulse width.

Written by Timothy Hirzel

Suggested changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. You can read more on how to contribute in the contribution policy.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.

Arduino PWM

The PWM (Pulse Width Modulation) is a method of controlling the average voltage. It is a stream of voltage pulses that reduces the electric power supplied by the electrical signal. The effective voltage is controlled by the width of individual pulses in a stream of voltage pulses of a PWM signal.

The common use of PWM pins includes controlling LEDs and DC Motors.

The PWM in LED controls the frequency of the light. It means the LED will be ON/OFF at a frequency detectable by our eyes.

The PWM in DC Motors acts like a pulse train of a DC signal. The DC motors receive a high or low electrical power input based on the width of the PWM pulses.

We can also use PWM for voltage regulation, audio signal generation, devices control (pump, hydraulics, etc.), servo motor, etc.

Principle of PWM

The state of the Digital Input/Output pins in Arduino is either HIGH ( 1 ) or LOW ( 0).

Here,

HIGH means the voltage is approx to 5V.

LOW means the voltage is equivalent to 0 volts.

The PWM is a square wave signal, which is represented as:

The duty cycle of the rectangular pulse is shown below:

Here,

to: It is the duration of the signal when the signal is HIGH.

tc: It is the total duration of the signal as the sum of HIGH and LOW.

Duty cycle of a PWM wave

As defined above, the duty cycle is the ratio of the pulse width to the total width of a signal.

Consider the below image:

The above image displays the wave at different duty cycles.

We can control the effective voltage of the DC motor in Arduino by regulating the PWM duty cycle.

For example,

Arduino UNO

Arduino UNO board consists of 14 digital Input/Output pins, where pin 11, 10, 9, 6, 5, and 3 are PWM pins. The pinMode(), digitalRead(), digitalWrite() functions control the operation of non-PWM pins.

The pinMode() function is used to declare the specific pin as input/output. The digitalRead is used to read the HIGH or LOW state of a pin.

We need to use the analogWrite() to set the duty cycle of a PWM (Pulse Width Modulation) pulse.

Let’s discuss analogWrite() in detail.

analogWrite()

It writes a PWM value or analog value to a pin. We can light an LED with varying brightness with the help of analogWrite(). It is also used to drive a motor at varying speeds.

When an analogWrite() function is called, a stable rectangular wave of particular duty cycle is generated by the specified PWM pin until the next analogWrite() is called on that same pin.

The PWM pins are present on every Arduino Board. The frequency can also vary for some PWM pins present on the particular board.

For example,

The PWM pins on the Arduino Leonardo/Micro are 3, 5, 6, 9, 10, 11, and 13. The frequency on pin 3 and 11 will be 980Hz, while other PWM pins have 490Hz of frequency.

The syntax is:

where,

pin: Specified PWM pin on the board

value: It determines the value of the duty cycle between 0 and 255.

The data type used here is int.

Note: The analogWrite( ) function is not related to the analogRead() or analog pins.
What is the difference between analogRead() and analogWrite()?

The main differences between analogRead() and analogWrite() are listed below:

Let’s understand with an example.

In the case of the PWM pin, we will specify the value instead of HIGH or LOW.

For example,

HIGH = 255

LOW = 0

Consider the below code:

Here, the LED will light at full brightness.

Let’s discuss an example to control the brightness of the LED.

How to calculate Arduino PWM?

The analogWrite() function discussed above is used to generate a PWM signal in Arduino.

The value associated with the analog signal is from 0 to 255. It means 256 levels of values.

The maximum voltage read by the Arduino is 5V.

We can determine the output PWM voltage by using the below formula:

PWM voltage = ( Duty cycle/ 256) x 5V

Code Example

Let’s discuss a method to control the brightness of an LED connected to the PWM pin.

Here, we have connected the LED to the PWM pin 6.

Consider the below code.

In the above example, the brightness of the LED will decrease according to the specified value of brightness.

Next TopicArduino Library

Secrets of Arduino PWM

Learn about Pulse Width Modulation techniques

Code mẫu

/* Fading Light This example shows how to fade an LED on pin 10 using the analogWrite() function. */ int ledPin = 6; // the pin that the LED is attached to void setup() { // declare pin 9 to be an output: pinMode(ledPin,OUTPUT); // initialize serial communication at 9600 bits per second: Serial.begin(9600); } void loop(){ fadeOn(2000,5); fadeOff(2000,5); } void fadeOn(unsigned int time,int increament){ //change the brightness by FOR statement for (byte value = 0 ; value < 255; value+=increament){ // print out the value: Serial.println(value); // set the brightness of pin 10: analogWrite(ledPin, value); delay(time/(255/5)); } } void fadeOff(unsigned int time,int decreament){ //change the brightness by FOR statement for (byte value = 255; value >0; value-=decreament){ Serial.println(value); analogWrite(ledPin, value); delay(time/(255/5)); } }

Arduino Tutorial 8: Understanding Pulse Width Modulation (PWM) and the Arduino Analog Write Command
Arduino Tutorial 8: Understanding Pulse Width Modulation (PWM) and the Arduino Analog Write Command

Bit-Banging Pulse Width Modulation

You can “manually” implement PWM on any pin by repeatedly turning the pin on and off for the desired times. e.g.

1void setup()2{3 pinMode(13, OUTPUT);4}56void loop()7{8 digitalWrite(13, HIGH);9 delayMicroseconds(100); // Approximately 10% duty cycle @ 1KHz10 digitalWrite(13, LOW);11 delayMicroseconds(1000 – 100);12}

This technique has the advantage that it can use any digital output pin. In addition, you have full control the duty cycle and frequency. One major disadvantage is that any interrupts will affect the timing, which can cause considerable jitter unless you disable interrupts. A second disadvantage is you can’t leave the output running while the processor does something else. Finally, it’s difficult to determine the appropriate constants for a particular duty cycle and frequency unless you either carefully count cycles, or tweak the values while watching an oscilloscope.

A more elaborate example of manually PWMing all pins may be found here.

PWM Examples

PWM has several uses:

  • Dimming an LED
  • Providing an analog output; if the digital output is filtered, it will provide an analog voltage between 0% and 100%.
  • Generating audio signals.
  • Providing variable speed control for motors.
  • Generating a modulated signal, for example to drive an infrared LED for a remote control.
How to generate high frequency PWM signal using Arduino Uno R3 | Arduino Programming for Beginners
How to generate high frequency PWM signal using Arduino Uno R3 | Arduino Programming for Beginners

Simple Pulse Width Modulation with analogWrite


analogWrite

The Arduino’s programming language makes PWM easy to use; simply call

, where

analogWrite(pin, dutyCycle)

is a value from 0 to 255, and pin is one of the PWM pins (3, 5, 6, 9, 10, or 11). The

dutyCycle

function provides a simple interface to the hardware PWM, but doesn’t provide any control over frequency. (Note that despite the function name, the output is a digital signal, often referred to as a square wave.)

analogWrite()

Probably 99% of the readers can stop here, and just use

, but there are other options that provide more flexibility.

analogWrite

Giải thích code

void fadeOn(unsigned int time,int increament){ //change the brightness by FOR statement for (byte value = 0 ; value < 255; value+=increament){ // print out the value: Serial.println(value); // set the brightness of pin 10: analogWrite(ledPin, value); delay(time/(255/5)); } }

Trong vòng lặp for điều kiện đưa ra khi giá trị Led = 0, thỏa value < 255 thì Led sẽ tăng thêm một giá trị nói một cách nôm na là giá trị càng tăng lên đồng nghĩa với việc đèn Led sẽ sáng dần lên và ngược lại.

analogWrite(ledPin, value);

Xung PWM

Xung là các trạng thái cao / thấp (HIGH/LOW) về mức điện áp được lặp đi lặp lại. Đại lượng đặc trưng cho 1 xung PWM (Pulse Width Modulation) bao gồm tần số (frequency) và chu kì xung (duty cycle).

Tần số là gì?

Tần số là số lần lặp lại trong 1 đơn vị thời gian. Đơn vị tần số là Hz, tức là số lần lặp lại dao động trong 1 giây.

Lấy ví dụ, 1Hz = 1 dao động trong 1 giây. 2Hz = 2 dao động trong 1 giây. 16MHz = 16 triệu dao động trong 1 giây.

Hoạt động của xung trong thực tế

Khoảng cách giữa 2 vạch màu xanh là một xung

analogWrite Tỉ lệ Chu kỳ xung
0/255 0%
64/255 25%
127/255 50%
191/255 75%
255/255 100%

Hàm

analogWrite()

là một lệnh được ghi giá trị trên một chân của Arduino. Các chân PWM (~) thường xuất hiện trên Board Arduino Uno là 3, 5, 6, 9, 10, 11.

Các chân PWM thường dùng để điều khiển độ sáng của một đèn Led hay là điều khiển động và sử dụng trong điều khiển Servo.

Arduino | Tìm Hiểu Bản Chất Băm Xung PWM Arduino Kèm Code Chi Tiết || PWM In Arduino
Arduino | Tìm Hiểu Bản Chất Băm Xung PWM Arduino Kèm Code Chi Tiết || PWM In Arduino

Using the ATmega PWM Registers Directly

The ATmega168P/328P chip has three PWM timers, controlling 6 PWM outputs. By manipulating the chip’s timer registers directly, you can obtain more control than the analogWrite function provides.

The AVR ATmega328P datasheet provides a detailed description of the PWM timers, but the datasheet can be difficult to understand, due to the many different control and output modes of the timers.

A word on the relationship between the Arduino language and the datasheet may be in order here.

The Atmega 168/328 timers.

The ATmega328P has three timers known as Timer 0, Timer 1, and Timer 2. Each timer has two output compare registers that control the PWM width for the timer’s two outputs: when the timer reaches the compare register value, the corresponding output is toggled. The two outputs for each timer will normally have the same frequency, but can have different duty cycles (depending on the respective output compare register).

Each of the timers has a prescaler that generates the timer clock by dividing the system clock by a prescale factor such as 1, 8, 64, 256, or 1024. The Arduino has a system clock of 16MHz and the timer clock frequency will be the system clock frequency divided by the prescale factor. Note that Timer 2 has a different set of prescale values from the other timers.

The timers are complicated by several different modes. The main PWM modes are “Fast PWM” and “Phase-correct PWM”, which will be described below. The timer can either run from 0 to 255, or from 0 to a fixed value. (The 16-bit Timer 1 has additional modes to supports timer values up to 16 bits.) Each output can also be inverted.

The timers can also generate interrupts on overflow and/or match against either output compare register, but that’s beyond the scope of this article.

Timer Registers

Several registers are used to control each timer. The Timer/Counter Control Registers TCCRnA and TCCRnB hold the main control bits for the timer. (Note that TCCRnA and TCCRnB do not correspond to the outputs A and B.) These registers hold several groups of bits:

  • Waveform Generation Mode bits (WGM): these control the overall mode of the timer. (These bits are split between TCCRnA and TCCRnB.)
  • Clock Select bits (CS): these control the clock prescaler
  • Compare Match Output A Mode bits (COMnA): these enable/disable/invert output A
  • Compare Match Output B Mode bits (COMnB): these enable/disable/invert output B

The Output Compare Registers OCRnA and OCRnB set the levels at which outputs A and B will be affected. When the timer value matches the register value, the corresponding output will be modified as specified by the mode.

The bits are slightly different for each timer, so consult the datasheet for details. Timer 1 is a 16-bit timer and has additional modes. Timer 2 has different prescaler values.

Fast PWM

In the simplest PWM mode, the timer repeatedly counts from 0 to 255. The output turns on when the timer is at 0, and turns off when the timer matches the output compare register. The higher the value in the output compare register, the higher the duty cycle. This mode is known as Fast PWM Mode. The following diagram shows the outputs for two particular values of OCRnA and OCRnB. Note that both outputs have the same frequency, matching the frequency of a complete timer cycle.

Fast PWM Mode

The following code fragment sets up fast PWM on pins 3 and 11 (Timer 2). To summarize the register settings, setting the waveform generation mode bits WGM to 011 selects fast PWM. Setting the COM2A bits and COM2B bits to 10 provides non-inverted PWM for outputs A and B. Setting the CS bits to 100 sets the prescaler to divide the clock by 64. (Since the bits are different for the different timers, consult the datasheet for the right values.) The output compare registers are arbitrarily set to 180 and 50 to control the PWM duty cycle of outputs A and B. (Of course, you can modify the registers directly instead of using

, but you do need to set the pins to output.)

pinMode()

1pinMode(3, OUTPUT);2 pinMode(11, OUTPUT);3 TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);4 TCCR2B = _BV(CS22);5 OCR2A = 180;6 OCR2B = 50;

On the Arduino Duemilanove, these values yield:

  • Output A frequency: 16 MHz / 64 / 256 = 976.5625Hz
  • Output A duty cycle: (180+1) / 256 = 70.7%
  • Output B frequency: 16 MHz / 64 / 256 = 976.5625Hz
  • Output B duty cycle: (50+1) / 256 = 19.9%

The output frequency is the 16MHz system clock frequency, divided by the prescaler value (64), divided by the 256 cycles it takes for the timer to wrap around. Note that fast PWM holds the output high one cycle longer than the compare register value.

Phase-Correct PWM

The second PWM mode is called phase-correct PWM. In this mode, the timer counts from 0 to 255 and then back down to 0. The output turns off as the timer hits the output compare register value on the way up, and turns back on as the timer hits the output compare register value on the way down. The result is a more symmetrical output. The output frequency will be approximately half of the value for fast PWM mode, because the timer runs both up and down.

Phase-Correct PWM example

The following code fragment sets up phase-correct PWM on pins 3 and 11 (Timer 2). The waveform generation mode bits WGM are set to to 001 for phase-correct PWM. The other bits are the same as for fast PWM.

1pinMode(3, OUTPUT);2 pinMode(11, OUTPUT);3 TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);4 TCCR2B = _BV(CS22);5 OCR2A = 180;6 OCR2B = 50;

On the Arduino Duemilanove, these values yield:

  • Output A frequency: 16 MHz / 64 / 255 / 2 = 490.196Hz
  • Output A duty cycle: 180 / 255 = 70.6%
  • Output B frequency: 16 MHz / 64 / 255 / 2 = 490.196Hz
  • Output B duty cycle: 50 / 255 = 19.6%

Phase-correct PWM divides the frequency by two compared to fast PWM, because the timer goes both up and down. Somewhat surprisingly, the frequency is divided by 255 instead of 256, and the duty cycle calculations do not add one as for fast PWM. See the explanation below under “Off-by-one”.

Varying the timer top limit: fast PWM

Both fast PWM and phase correct PWM have an additional mode that gives control over the output frequency. In this mode, the timer counts from 0 to OCRA (the value of output compare register A), rather than from 0 to 255. This gives much more control over the output frequency than the previous modes. (For even more frequency control, use the 16-bit Timer 1.)

Note that in this mode, only output B can be used for PWM; OCRA cannot be used both as the top value and the PWM compare value. However, there is a special-case mode “Toggle OCnA on Compare Match” that will toggle output A at the end of each cycle, generating a fixed 50% duty cycle and half frequency in this case. The examples will use this mode.

In the following diagram, the timer resets when it matches OCRnA, yielding a faster output frequency for OCnB than in the previous diagrams. Note how OCnA toggles once for each timer reset.

Fast PWM Mode with OCRA top

The following code fragment sets up fast PWM on pins 3 and 11 (Timer 2), using OCR2A as the top value for the timer. The waveform generation mode bits WGM are set to to 111 for fast PWM with OCRA controlling the top limit. The OCR2A top limit is arbitrarily set to 180, and the OCR2B compare register is arbitrarily set to 50. OCR2A’s mode is set to “Toggle on Compare Match” by setting the COM2A bits to 01.

1pinMode(3, OUTPUT);2 pinMode(11, OUTPUT);3 TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);4 TCCR2B = _BV(WGM22) | _BV(CS22);5 OCR2A = 180;6 OCR2B = 50;

On the Arduino Duemilanove, these values yield:

  • Output A frequency: 16 MHz / 64 / (180+1) / 2 = 690.6Hz
  • Output A duty cycle: 50%
  • Output B frequency: 16 MHz / 64 / (180+1) = 1381.2Hz
  • Output B duty cycle: (50+1) / (180+1) = 28.2%

Note that in this example, the timer goes from 0 to 180, which takes 181 clock cycles, so the output frequency is divided by 181. Output A has half the frequency of Output B because the Toggle on Compare Match mode toggles Output A once each complete timer cycle.

Varying the timer top limit: phase-correct PWM

Similarly, the timer can be configured in phase-correct PWM mode to reset when it reaches OCRnA.

Phase-Correct PWM with OCRA top The following code fragment sets up phase-correct PWM on pins 3 and 11 (Timer 2), using OCR2A as the top value for the timer. The waveform generation mode bits WGM are set to to 101 for phase-correct PWM with OCRA controlling the top limit. The OCR2A top limit is arbitrarily set to 180, and the OCR2B compare register is arbitrarily set to 50. OCR2A’s mode is set to “Toggle on Compare Match” by setting the COM2A bits to 01.

1pinMode(3, OUTPUT);2 pinMode(11, OUTPUT);3 TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);4 TCCR2B = _BV(WGM22) | _BV(CS22);5 OCR2A = 180;6 OCR2B = 50;

On the Arduino Duemilanove, these values yield:

  • Output A frequency: 16 MHz / 64 / 180 / 2 / 2 = 347.2Hz
  • Output A duty cycle: 50%
  • Output B frequency: 16 MHz / 64 / 180 / 2 = 694.4Hz
  • Output B duty cycle: 50 / 180 = 27.8%

Note that in this example, the timer goes from 0 to 180 and back to 0, which takes 360 clock cycles. Thus, everything is divided by 180 or 360, unlike the fast PWM case, which divided everything by 181; see below for details.//

Off-by-one

You may have noticed that fast PWM and phase-correct PWM seem to be off-by-one with respect to each other, dividing by 256 versus 255 and adding one in various places. The documentation is a bit opaque here, so I’ll explain in a bit of detail.

Suppose the timer is set to fast PWM mode and is set to count up to an OCRnA value of 3. The timer will take on the values 012301230123… Note that there are 4 clock cycles in each timer cycle. Thus, the frequency will be divided by 4, not 3. The duty cycle will be a multiple of 25%, since the output can be high for 0, 1, 2, 3, or 4 cycles out of the four. Likewise, if the timer counts up to 255, there will be 256 clock cycles in each timer cycle, and the duty cycle will be a multiple of 1/256. To summarize, fast PWM divides by N+1 where N is the maximum timer value (either OCRnA or 255).

Now consider phase-correct PWM mode with the timer counting up to an OCRnA value of 3. The timer values will be 012321012321… There are 6 clock cycles in each timer cycle (012321). Thus the frequency will be divided by 6. The duty cycle will be a multiple of 33%, since the output can be high for 0, 2, 4, or 6 of the 6 cycles. Likewise, if the timer counts up to 255 and back down, there will be 510 clock cycles in each timer cycle, and the duty cycle will be a multiple of 1/255. To summarize, phase-correct PWM divides by 2N, where N is the maximum timer value.

The second important timing difference is that fast PWM holds the output high for one cycle longer than the output compare register value. The motivation for this is that for fast PWM counting to 255, the duty cycle can be from 0 to 256 cycles, but the output compare register can only hold a value from 0 to 255. What happens to the missing value? The fast PWM mode keeps the output high for N+1 cycles when the output compare register is set to N so an output compare register value of 255 is 100% duty cycle, but an output compare register value of 0 is not 0% duty cycle but 1/256 duty cycle. This is unlike phase-correct PWM, where a register value of 255 is 100% duty cycle and a value of 0 is a 0% duty cycle.

Timers and the Arduino

The Arduino supports PWM on a subset of its output pins. It may not be immediately obvious which timer controls which output, but the following table will clarify the situation. It gives for each timer output the output pin on the Arduino (i.e. the silkscreened label on the board), the pin on the ATmega chip, and the name and bit of the output port. For instance Timer 0 output OC0A is connected to the Arduino output pin 6; it uses chip pin 12 which is also known as PD6.

Timer output Arduino output Chip pin Pin name
OC0A 12 PD6
OC0B 11 PD5
OC1A 15 PB1
OC1B 10 16 PB2
OC2A 11 17 PB3
OC2B PD3

The Arduino performs some initialization of the timers. The Arduino initializes the prescaler on all three timers to divide the clock by 64. Timer 0 is initialized to Fast PWM, while Timer 1 and Timer 2 is initialized to Phase Correct PWM. See the Arduino source file wiring.c for details.

The Arduino uses Timer 0 internally for the millis() and delay() functions, so be warned that changing the frequency of this timer will cause those functions to be erroneous. Using the PWM outputs is safe if you don’t change the frequency, though.

The

function sets the appropriate pin to PWM and sets the appropriate output compare register to duty_cycle (with the special case for duty cycle of 0 on Timer 0). The

analogWrite(pin, duty_cycle)

function turns off PWM output if called on a timer pin. The relevant code is wiring_analog.c and wiring_digital.c.

digitalWrite()

If you use

you get a duty cycle of 0%, even though pin 5’s timer (Timer 0) is using fast PWM. How can this be, when a fast PWM value of 0 yields a duty cycle of 1/256 as explained above? The answer is that

analogWrite(5, 0)

“cheats”; it has special-case code to explicitly turn off the pin when called on Timer 0 with a duty cycle of 0. As a consequency, the duty cycle of 1/256 is unavailable when you use `analogWrite“ on Timer0, and there is a jump in the actual duty cycle between values of 0 and 1.

analogWrite

Some other Arduino models use dfferent AVR processors with similar timers. The Arduino Mega uses the ATmega1280 (datasheet), which has four 16-bit timers with 3 outputs each and two 8-bit timers with 2 outputs each. Only 14 of the PWM outputs are supported by the Arduino Wiring library, however. Some older Arduino models use the ATmega8 (datasheet), which has three timers but only 3 PWM outputs: Timer 0 has no PWM, Timer 1 is 16 bits and has two PWM outputs, and Timer 2 is 8 bits and has one PWM output.

Troubleshoot

It can be tricky to get the PWM outputs to work. Some tips:

  • You need to both enable the pin for output and enable the PWM mode on the pin in order to get any output. I.e. you need to do pinMode() and set the COM bits.
  • The different timers use the control bits and prescaler differently; check the documentation for the appropriate timer.
  • Some combinations of bits that you might expect to work are reserved, which means if you try to use them, they won’t work.
  • For example, toggle mode doesn’t work with fast PWM to 255, or with output B.
  • Make sure the bits are set the way you think. Bit operations can be tricky, so print out the register values with the binary (BIN) formatter and make sure they are what you expect.
  • Make sure you’re using the right output pins. See the table above.
  • You’ll probably want a decoupling capacitor to avoid spikes on the output.

An oscilloscope is very handy for debugging PWM if you have access to one. If you don’t have one, I recommend using your sound card and a program such as xoscope.

Simple Pulse Width Modulation with analogWrite


analogWrite

The Arduino’s programming language makes PWM easy to use; simply call

, where

analogWrite(pin, dutyCycle)

is a value from 0 to 255, and pin is one of the PWM pins (3, 5, 6, 9, 10, or 11). The

dutyCycle

function provides a simple interface to the hardware PWM, but doesn’t provide any control over frequency. (Note that despite the function name, the output is a digital signal, often referred to as a square wave.)

analogWrite()

Probably 99% of the readers can stop here, and just use

, but there are other options that provide more flexibility.

analogWrite

Tạo Xung PWM Với Arduino UNO R3 | Điện tử DAT
Tạo Xung PWM Với Arduino UNO R3 | Điện tử DAT

Using the ATmega PWM Registers Directly

The ATmega168P/328P chip has three PWM timers, controlling 6 PWM outputs. By manipulating the chip’s timer registers directly, you can obtain more control than the analogWrite function provides.

The AVR ATmega328P datasheet provides a detailed description of the PWM timers, but the datasheet can be difficult to understand, due to the many different control and output modes of the timers.

A word on the relationship between the Arduino language and the datasheet may be in order here.

The Atmega 168/328 timers.

The ATmega328P has three timers known as Timer 0, Timer 1, and Timer 2. Each timer has two output compare registers that control the PWM width for the timer’s two outputs: when the timer reaches the compare register value, the corresponding output is toggled. The two outputs for each timer will normally have the same frequency, but can have different duty cycles (depending on the respective output compare register).

Each of the timers has a prescaler that generates the timer clock by dividing the system clock by a prescale factor such as 1, 8, 64, 256, or 1024. The Arduino has a system clock of 16MHz and the timer clock frequency will be the system clock frequency divided by the prescale factor. Note that Timer 2 has a different set of prescale values from the other timers.

The timers are complicated by several different modes. The main PWM modes are “Fast PWM” and “Phase-correct PWM”, which will be described below. The timer can either run from 0 to 255, or from 0 to a fixed value. (The 16-bit Timer 1 has additional modes to supports timer values up to 16 bits.) Each output can also be inverted.

The timers can also generate interrupts on overflow and/or match against either output compare register, but that’s beyond the scope of this article.

Timer Registers

Several registers are used to control each timer. The Timer/Counter Control Registers TCCRnA and TCCRnB hold the main control bits for the timer. (Note that TCCRnA and TCCRnB do not correspond to the outputs A and B.) These registers hold several groups of bits:

  • Waveform Generation Mode bits (WGM): these control the overall mode of the timer. (These bits are split between TCCRnA and TCCRnB.)
  • Clock Select bits (CS): these control the clock prescaler
  • Compare Match Output A Mode bits (COMnA): these enable/disable/invert output A
  • Compare Match Output B Mode bits (COMnB): these enable/disable/invert output B

The Output Compare Registers OCRnA and OCRnB set the levels at which outputs A and B will be affected. When the timer value matches the register value, the corresponding output will be modified as specified by the mode.

The bits are slightly different for each timer, so consult the datasheet for details. Timer 1 is a 16-bit timer and has additional modes. Timer 2 has different prescaler values.

Fast PWM

In the simplest PWM mode, the timer repeatedly counts from 0 to 255. The output turns on when the timer is at 0, and turns off when the timer matches the output compare register. The higher the value in the output compare register, the higher the duty cycle. This mode is known as Fast PWM Mode. The following diagram shows the outputs for two particular values of OCRnA and OCRnB. Note that both outputs have the same frequency, matching the frequency of a complete timer cycle.

Fast PWM Mode

The following code fragment sets up fast PWM on pins 3 and 11 (Timer 2). To summarize the register settings, setting the waveform generation mode bits WGM to 011 selects fast PWM. Setting the COM2A bits and COM2B bits to 10 provides non-inverted PWM for outputs A and B. Setting the CS bits to 100 sets the prescaler to divide the clock by 64. (Since the bits are different for the different timers, consult the datasheet for the right values.) The output compare registers are arbitrarily set to 180 and 50 to control the PWM duty cycle of outputs A and B. (Of course, you can modify the registers directly instead of using

, but you do need to set the pins to output.)

pinMode()

1pinMode(3, OUTPUT);2 pinMode(11, OUTPUT);3 TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);4 TCCR2B = _BV(CS22);5 OCR2A = 180;6 OCR2B = 50;

On the Arduino Duemilanove, these values yield:

  • Output A frequency: 16 MHz / 64 / 256 = 976.5625Hz
  • Output A duty cycle: (180+1) / 256 = 70.7%
  • Output B frequency: 16 MHz / 64 / 256 = 976.5625Hz
  • Output B duty cycle: (50+1) / 256 = 19.9%

The output frequency is the 16MHz system clock frequency, divided by the prescaler value (64), divided by the 256 cycles it takes for the timer to wrap around. Note that fast PWM holds the output high one cycle longer than the compare register value.

Phase-Correct PWM

The second PWM mode is called phase-correct PWM. In this mode, the timer counts from 0 to 255 and then back down to 0. The output turns off as the timer hits the output compare register value on the way up, and turns back on as the timer hits the output compare register value on the way down. The result is a more symmetrical output. The output frequency will be approximately half of the value for fast PWM mode, because the timer runs both up and down.

Phase-Correct PWM example

The following code fragment sets up phase-correct PWM on pins 3 and 11 (Timer 2). The waveform generation mode bits WGM are set to to 001 for phase-correct PWM. The other bits are the same as for fast PWM.

1pinMode(3, OUTPUT);2 pinMode(11, OUTPUT);3 TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);4 TCCR2B = _BV(CS22);5 OCR2A = 180;6 OCR2B = 50;

On the Arduino Duemilanove, these values yield:

  • Output A frequency: 16 MHz / 64 / 255 / 2 = 490.196Hz
  • Output A duty cycle: 180 / 255 = 70.6%
  • Output B frequency: 16 MHz / 64 / 255 / 2 = 490.196Hz
  • Output B duty cycle: 50 / 255 = 19.6%

Phase-correct PWM divides the frequency by two compared to fast PWM, because the timer goes both up and down. Somewhat surprisingly, the frequency is divided by 255 instead of 256, and the duty cycle calculations do not add one as for fast PWM. See the explanation below under “Off-by-one”.

Varying the timer top limit: fast PWM

Both fast PWM and phase correct PWM have an additional mode that gives control over the output frequency. In this mode, the timer counts from 0 to OCRA (the value of output compare register A), rather than from 0 to 255. This gives much more control over the output frequency than the previous modes. (For even more frequency control, use the 16-bit Timer 1.)

Note that in this mode, only output B can be used for PWM; OCRA cannot be used both as the top value and the PWM compare value. However, there is a special-case mode “Toggle OCnA on Compare Match” that will toggle output A at the end of each cycle, generating a fixed 50% duty cycle and half frequency in this case. The examples will use this mode.

In the following diagram, the timer resets when it matches OCRnA, yielding a faster output frequency for OCnB than in the previous diagrams. Note how OCnA toggles once for each timer reset.

Fast PWM Mode with OCRA top

The following code fragment sets up fast PWM on pins 3 and 11 (Timer 2), using OCR2A as the top value for the timer. The waveform generation mode bits WGM are set to to 111 for fast PWM with OCRA controlling the top limit. The OCR2A top limit is arbitrarily set to 180, and the OCR2B compare register is arbitrarily set to 50. OCR2A’s mode is set to “Toggle on Compare Match” by setting the COM2A bits to 01.

1pinMode(3, OUTPUT);2 pinMode(11, OUTPUT);3 TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);4 TCCR2B = _BV(WGM22) | _BV(CS22);5 OCR2A = 180;6 OCR2B = 50;

On the Arduino Duemilanove, these values yield:

  • Output A frequency: 16 MHz / 64 / (180+1) / 2 = 690.6Hz
  • Output A duty cycle: 50%
  • Output B frequency: 16 MHz / 64 / (180+1) = 1381.2Hz
  • Output B duty cycle: (50+1) / (180+1) = 28.2%

Note that in this example, the timer goes from 0 to 180, which takes 181 clock cycles, so the output frequency is divided by 181. Output A has half the frequency of Output B because the Toggle on Compare Match mode toggles Output A once each complete timer cycle.

Varying the timer top limit: phase-correct PWM

Similarly, the timer can be configured in phase-correct PWM mode to reset when it reaches OCRnA.

Phase-Correct PWM with OCRA top The following code fragment sets up phase-correct PWM on pins 3 and 11 (Timer 2), using OCR2A as the top value for the timer. The waveform generation mode bits WGM are set to to 101 for phase-correct PWM with OCRA controlling the top limit. The OCR2A top limit is arbitrarily set to 180, and the OCR2B compare register is arbitrarily set to 50. OCR2A’s mode is set to “Toggle on Compare Match” by setting the COM2A bits to 01.

1pinMode(3, OUTPUT);2 pinMode(11, OUTPUT);3 TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);4 TCCR2B = _BV(WGM22) | _BV(CS22);5 OCR2A = 180;6 OCR2B = 50;

On the Arduino Duemilanove, these values yield:

  • Output A frequency: 16 MHz / 64 / 180 / 2 / 2 = 347.2Hz
  • Output A duty cycle: 50%
  • Output B frequency: 16 MHz / 64 / 180 / 2 = 694.4Hz
  • Output B duty cycle: 50 / 180 = 27.8%

Note that in this example, the timer goes from 0 to 180 and back to 0, which takes 360 clock cycles. Thus, everything is divided by 180 or 360, unlike the fast PWM case, which divided everything by 181; see below for details.//

Off-by-one

You may have noticed that fast PWM and phase-correct PWM seem to be off-by-one with respect to each other, dividing by 256 versus 255 and adding one in various places. The documentation is a bit opaque here, so I’ll explain in a bit of detail.

Suppose the timer is set to fast PWM mode and is set to count up to an OCRnA value of 3. The timer will take on the values 012301230123… Note that there are 4 clock cycles in each timer cycle. Thus, the frequency will be divided by 4, not 3. The duty cycle will be a multiple of 25%, since the output can be high for 0, 1, 2, 3, or 4 cycles out of the four. Likewise, if the timer counts up to 255, there will be 256 clock cycles in each timer cycle, and the duty cycle will be a multiple of 1/256. To summarize, fast PWM divides by N+1 where N is the maximum timer value (either OCRnA or 255).

Now consider phase-correct PWM mode with the timer counting up to an OCRnA value of 3. The timer values will be 012321012321… There are 6 clock cycles in each timer cycle (012321). Thus the frequency will be divided by 6. The duty cycle will be a multiple of 33%, since the output can be high for 0, 2, 4, or 6 of the 6 cycles. Likewise, if the timer counts up to 255 and back down, there will be 510 clock cycles in each timer cycle, and the duty cycle will be a multiple of 1/255. To summarize, phase-correct PWM divides by 2N, where N is the maximum timer value.

The second important timing difference is that fast PWM holds the output high for one cycle longer than the output compare register value. The motivation for this is that for fast PWM counting to 255, the duty cycle can be from 0 to 256 cycles, but the output compare register can only hold a value from 0 to 255. What happens to the missing value? The fast PWM mode keeps the output high for N+1 cycles when the output compare register is set to N so an output compare register value of 255 is 100% duty cycle, but an output compare register value of 0 is not 0% duty cycle but 1/256 duty cycle. This is unlike phase-correct PWM, where a register value of 255 is 100% duty cycle and a value of 0 is a 0% duty cycle.

Timers and the Arduino

The Arduino supports PWM on a subset of its output pins. It may not be immediately obvious which timer controls which output, but the following table will clarify the situation. It gives for each timer output the output pin on the Arduino (i.e. the silkscreened label on the board), the pin on the ATmega chip, and the name and bit of the output port. For instance Timer 0 output OC0A is connected to the Arduino output pin 6; it uses chip pin 12 which is also known as PD6.

Timer output Arduino output Chip pin Pin name
OC0A 12 PD6
OC0B 11 PD5
OC1A 15 PB1
OC1B 10 16 PB2
OC2A 11 17 PB3
OC2B PD3

The Arduino performs some initialization of the timers. The Arduino initializes the prescaler on all three timers to divide the clock by 64. Timer 0 is initialized to Fast PWM, while Timer 1 and Timer 2 is initialized to Phase Correct PWM. See the Arduino source file wiring.c for details.

The Arduino uses Timer 0 internally for the millis() and delay() functions, so be warned that changing the frequency of this timer will cause those functions to be erroneous. Using the PWM outputs is safe if you don’t change the frequency, though.

The

function sets the appropriate pin to PWM and sets the appropriate output compare register to duty_cycle (with the special case for duty cycle of 0 on Timer 0). The

analogWrite(pin, duty_cycle)

function turns off PWM output if called on a timer pin. The relevant code is wiring_analog.c and wiring_digital.c.

digitalWrite()

If you use

you get a duty cycle of 0%, even though pin 5’s timer (Timer 0) is using fast PWM. How can this be, when a fast PWM value of 0 yields a duty cycle of 1/256 as explained above? The answer is that

analogWrite(5, 0)

“cheats”; it has special-case code to explicitly turn off the pin when called on Timer 0 with a duty cycle of 0. As a consequency, the duty cycle of 1/256 is unavailable when you use `analogWrite“ on Timer0, and there is a jump in the actual duty cycle between values of 0 and 1.

analogWrite

Some other Arduino models use dfferent AVR processors with similar timers. The Arduino Mega uses the ATmega1280 (datasheet), which has four 16-bit timers with 3 outputs each and two 8-bit timers with 2 outputs each. Only 14 of the PWM outputs are supported by the Arduino Wiring library, however. Some older Arduino models use the ATmega8 (datasheet), which has three timers but only 3 PWM outputs: Timer 0 has no PWM, Timer 1 is 16 bits and has two PWM outputs, and Timer 2 is 8 bits and has one PWM output.

Troubleshoot

It can be tricky to get the PWM outputs to work. Some tips:

  • You need to both enable the pin for output and enable the PWM mode on the pin in order to get any output. I.e. you need to do pinMode() and set the COM bits.
  • The different timers use the control bits and prescaler differently; check the documentation for the appropriate timer.
  • Some combinations of bits that you might expect to work are reserved, which means if you try to use them, they won’t work.
  • For example, toggle mode doesn’t work with fast PWM to 255, or with output B.
  • Make sure the bits are set the way you think. Bit operations can be tricky, so print out the register values with the binary (BIN) formatter and make sure they are what you expect.
  • Make sure you’re using the right output pins. See the table above.
  • You’ll probably want a decoupling capacitor to avoid spikes on the output.

An oscilloscope is very handy for debugging PWM if you have access to one. If you don’t have one, I recommend using your sound card and a program such as xoscope.

Pulse Width Modulation

Pulse Width Modulation, or PWM, is a technique for getting analog results with digital means. Digital control is used to create a square wave, a signal switched between on and off. This on-off pattern can simulate voltages in between the full Vcc of the board (e.g., 5 V on UNO, 3.3 V on a MKR board) and off (0 Volts) by changing the portion of the time the signal spends on versus the time that the signal spends off. The duration of “on time” is called the pulse width. To get varying analog values, you change, or modulate, that pulse width. If you repeat this on-off pattern fast enough with an LED for example, the result is as if the signal is a steady voltage between 0 and Vcc controlling the brightness of the LED.

LED fade using Arduino | PWM in Arduino (Pulse Width Modulation) Explained | Arduino tutorial 18
LED fade using Arduino | PWM in Arduino (Pulse Width Modulation) Explained | Arduino tutorial 18

Bit-Banging Pulse Width Modulation

You can “manually” implement PWM on any pin by repeatedly turning the pin on and off for the desired times. e.g.

1void setup()2{3 pinMode(13, OUTPUT);4}56void loop()7{8 digitalWrite(13, HIGH);9 delayMicroseconds(100); // Approximately 10% duty cycle @ 1KHz10 digitalWrite(13, LOW);11 delayMicroseconds(1000 – 100);12}

This technique has the advantage that it can use any digital output pin. In addition, you have full control the duty cycle and frequency. One major disadvantage is that any interrupts will affect the timing, which can cause considerable jitter unless you disable interrupts. A second disadvantage is you can’t leave the output running while the processor does something else. Finally, it’s difficult to determine the appropriate constants for a particular duty cycle and frequency unless you either carefully count cycles, or tweak the values while watching an oscilloscope.

A more elaborate example of manually PWMing all pins may be found here.

Conclusion

This article helps explain the PWM modes of the Arduino. I found the documentation of the different modes somewhat opaque, and the off-by-one issues unexplained.

Suggested changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. You can read more on how to contribute in the contribution policy.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.

Arduino PWM

The PWM (Pulse Width Modulation) is a method of controlling the average voltage. It is a stream of voltage pulses that reduces the electric power supplied by the electrical signal. The effective voltage is controlled by the width of individual pulses in a stream of voltage pulses of a PWM signal.

The common use of PWM pins includes controlling LEDs and DC Motors.

The PWM in LED controls the frequency of the light. It means the LED will be ON/OFF at a frequency detectable by our eyes.

The PWM in DC Motors acts like a pulse train of a DC signal. The DC motors receive a high or low electrical power input based on the width of the PWM pulses.

We can also use PWM for voltage regulation, audio signal generation, devices control (pump, hydraulics, etc.), servo motor, etc.

Principle of PWM

The state of the Digital Input/Output pins in Arduino is either HIGH ( 1 ) or LOW ( 0).

Here,

HIGH means the voltage is approx to 5V.

LOW means the voltage is equivalent to 0 volts.

The PWM is a square wave signal, which is represented as:

The duty cycle of the rectangular pulse is shown below:

Here,

to: It is the duration of the signal when the signal is HIGH.

tc: It is the total duration of the signal as the sum of HIGH and LOW.

Duty cycle of a PWM wave

As defined above, the duty cycle is the ratio of the pulse width to the total width of a signal.

Consider the below image:

The above image displays the wave at different duty cycles.

We can control the effective voltage of the DC motor in Arduino by regulating the PWM duty cycle.

For example,

Arduino UNO

Arduino UNO board consists of 14 digital Input/Output pins, where pin 11, 10, 9, 6, 5, and 3 are PWM pins. The pinMode(), digitalRead(), digitalWrite() functions control the operation of non-PWM pins.

The pinMode() function is used to declare the specific pin as input/output. The digitalRead is used to read the HIGH or LOW state of a pin.

We need to use the analogWrite() to set the duty cycle of a PWM (Pulse Width Modulation) pulse.

Let’s discuss analogWrite() in detail.

analogWrite()

It writes a PWM value or analog value to a pin. We can light an LED with varying brightness with the help of analogWrite(). It is also used to drive a motor at varying speeds.

When an analogWrite() function is called, a stable rectangular wave of particular duty cycle is generated by the specified PWM pin until the next analogWrite() is called on that same pin.

The PWM pins are present on every Arduino Board. The frequency can also vary for some PWM pins present on the particular board.

For example,

The PWM pins on the Arduino Leonardo/Micro are 3, 5, 6, 9, 10, 11, and 13. The frequency on pin 3 and 11 will be 980Hz, while other PWM pins have 490Hz of frequency.

The syntax is:

where,

pin: Specified PWM pin on the board

value: It determines the value of the duty cycle between 0 and 255.

The data type used here is int.

Note: The analogWrite( ) function is not related to the analogRead() or analog pins.
What is the difference between analogRead() and analogWrite()?

The main differences between analogRead() and analogWrite() are listed below:

Let’s understand with an example.

In the case of the PWM pin, we will specify the value instead of HIGH or LOW.

For example,

HIGH = 255

LOW = 0

Consider the below code:

Here, the LED will light at full brightness.

Let’s discuss an example to control the brightness of the LED.

How to calculate Arduino PWM?

The analogWrite() function discussed above is used to generate a PWM signal in Arduino.

The value associated with the analog signal is from 0 to 255. It means 256 levels of values.

The maximum voltage read by the Arduino is 5V.

We can determine the output PWM voltage by using the below formula:

PWM voltage = ( Duty cycle/ 256) x 5V

Code Example

Let’s discuss a method to control the brightness of an LED connected to the PWM pin.

Here, we have connected the LED to the PWM pin 6.

Consider the below code.

In the above example, the brightness of the LED will decrease according to the specified value of brightness.

Next TopicArduino Library

Description

Writes an analog value (PWM wave) to a pin. Can be used to light a LED at varying brightnesses or drive a motor at various speeds. After a call to

analogWrite()

, the pin will generate a steady rectangular wave of the specified duty cycle until the next call to

analogWrite()

(or a call to

digitalRead()

or

digitalWrite()

) on the same pin.

Board PWM Pins * PWM Frequency

UNO (R3 and earlier), Nano, Mini

3, 5, 6, 9, 10, 11

490 Hz (pins 5 and 6: 980 Hz)

UNO R4 (Minima, WiFi) *

3, 5, 6, 9, 10, 11

490 Hz

Mega

2 – 13, 44 – 46

490 Hz (pins 4 and 13: 980 Hz)

GIGA R1 **

2 – 13

500 Hz

Leonardo, Micro, Yún

3, 5, 6, 9, 10, 11, 13

490 Hz (pins 3 and 11: 980 Hz)

UNO WiFi Rev2, Nano Every

3, 5, 6, 9, 10

976 Hz

MKR boards *

0 – 8, 10, A3, A4

732 Hz

MKR1000 WiFi **

0 – 8, 10, 11, A3, A4

732 Hz

Zero **

3 – 13, A0, A1

732 Hz

Nano 33 IoT **

2, 3, 5, 6, 9 – 12, A2, A3, A5

732 Hz

Nano 33 BLE/BLE Sense ****

1 – 13, A0 – A7

500 Hz

Due ***

2-13

1000 Hz

101

3, 5, 6, 9

pins 3 and 9: 490 Hz, pins 5 and 6: 980 Hz

* These pins are officially supported PWM pins. While some boards have additional pins capable of PWM, using them is recommended only for advanced users that can account for timer availability and potential conflicts with other uses of those pins. ** In addition to PWM capabilities on the pins noted above, the MKR, Nano 33 IoT, Zero and UNO R4 boards have true analog output when using

analogWrite()

on the

DAC0

(

A0

) pin.*** In addition to PWM capabilities on the pins noted above, the Due and GIGA R1 boards have true analog output when using

analogWrite()

on pins

DAC0

and

DAC1

.
**** Only 4 different pins can be used at the same time. Enabling PWM on more than 4 pins will abort the running sketch and require resetting the board to upload a new sketch again.

You do not need to call

pinMode()

to set the pin as an output before calling

analogWrite()

.The

analogWrite

function has nothing to do with the analog pins or the

analogRead

function.

Syntax


analogWrite(pin, value)

Parameters


pin

: the Arduino pin to write to. Allowed data types:

int

.

value

: the duty cycle: between 0 (always off) and 255 (always on). Allowed data types:

int

.

Returns

Nothing

Description

Writes an analog value (PWM wave) to a pin. Can be used to light a LED at varying brightnesses or drive a motor at various speeds. After a call to

analogWrite()

, the pin will generate a steady rectangular wave of the specified duty cycle until the next call to

analogWrite()

(or a call to

digitalRead()

or

digitalWrite()

) on the same pin.

Board PWM Pins * PWM Frequency

UNO (R3 and earlier), Nano, Mini

3, 5, 6, 9, 10, 11

490 Hz (pins 5 and 6: 980 Hz)

UNO R4 (Minima, WiFi) *

3, 5, 6, 9, 10, 11

490 Hz

Mega

2 – 13, 44 – 46

490 Hz (pins 4 and 13: 980 Hz)

GIGA R1 **

2 – 13

500 Hz

Leonardo, Micro, Yún

3, 5, 6, 9, 10, 11, 13

490 Hz (pins 3 and 11: 980 Hz)

UNO WiFi Rev2, Nano Every

3, 5, 6, 9, 10

976 Hz

MKR boards *

0 – 8, 10, A3, A4

732 Hz

MKR1000 WiFi **

0 – 8, 10, 11, A3, A4

732 Hz

Zero **

3 – 13, A0, A1

732 Hz

Nano 33 IoT **

2, 3, 5, 6, 9 – 12, A2, A3, A5

732 Hz

Nano 33 BLE/BLE Sense ****

1 – 13, A0 – A7

500 Hz

Due ***

2-13

1000 Hz

101

3, 5, 6, 9

pins 3 and 9: 490 Hz, pins 5 and 6: 980 Hz

* These pins are officially supported PWM pins. While some boards have additional pins capable of PWM, using them is recommended only for advanced users that can account for timer availability and potential conflicts with other uses of those pins. ** In addition to PWM capabilities on the pins noted above, the MKR, Nano 33 IoT, Zero and UNO R4 boards have true analog output when using

analogWrite()

on the

DAC0

(

A0

) pin.*** In addition to PWM capabilities on the pins noted above, the Due and GIGA R1 boards have true analog output when using

analogWrite()

on pins

DAC0

and

DAC1

.
**** Only 4 different pins can be used at the same time. Enabling PWM on more than 4 pins will abort the running sketch and require resetting the board to upload a new sketch again.

You do not need to call

pinMode()

to set the pin as an output before calling

analogWrite()

.The

analogWrite

function has nothing to do with the analog pins or the

analogRead

function.

Syntax


analogWrite(pin, value)

Parameters


pin

: the Arduino pin to write to. Allowed data types:

int

.

value

: the duty cycle: between 0 (always off) and 255 (always on). Allowed data types:

int

.

Returns

Nothing

Bài 4: PWM | Thay đổi ánh sáng của LED trên Arduino

Chúc mừng bạn đã trãi qua 3 bài học đầu tiên trong khóa học lập trình Arduino cho người mới bắt đầu. Chắc bạn củng cảm thấy tự học arduino cũng không hề khó chút nào phải không?

Bài viết hôm nay mình sẽ hướng dẫn các bạn cách bật một con LED sáng dần và tắt dần như thế nào? Qua đó, các bạn sẽ tìm hiểu thêm một hàm mới là analogWrite() và cách sử dụng các chân PWM(băm xung arduino).

Arduino PWM: Pulse Width Modulation
Arduino PWM: Pulse Width Modulation

Keywords searched by users: pwm code for arduino

Reading Pwm Receiver Signal Using Arduino With Interrupt - Part 2 - Youtube
Reading Pwm Receiver Signal Using Arduino With Interrupt – Part 2 – Youtube
Pwm In Arduino-Pulse Width Modulation - Youtube
Pwm In Arduino-Pulse Width Modulation – Youtube
Arduino Pwm Tutorial - Hackster.Io
Arduino Pwm Tutorial – Hackster.Io
Arduino Pwm: Pulse Width Modulation - Youtube
Arduino Pwm: Pulse Width Modulation – Youtube
Arduino Code Walkthrough - Isrs, Pwm, Motor Control, Reading Rc Signals -  Youtube
Arduino Code Walkthrough – Isrs, Pwm, Motor Control, Reading Rc Signals – Youtube
Arduino Pwm Tutorial - Hackster.Io
Arduino Pwm Tutorial – Hackster.Io
Arduino Pwm In Arduino | Arduino
Arduino Pwm In Arduino | Arduino
Analog Write And Working Of Pwm In Arduino - Geeksforgeeks
Analog Write And Working Of Pwm In Arduino – Geeksforgeeks

See more here: kientrucannam.vn

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *