Improve your programming with Arduino: PWM management

Introduction

In this tutorial, you will learn how to improve your programming with Arduino: PWM management, If you have used servo motors with the Arduino libraries or have controlled the speed of a motor, you will already have an idea of ​​what PWM is. A very specific duty cycle is used for servos and in other applications you may need to precisely change the frequency. However, to be able to use this functionality in various outputs, the libraries build the signals in a very particular way. Variations of a few microseconds can influence the operation, causing “blinks” in the position of the servos.

For this, we will show you how to handle the registers that control the PWM module so that you can define with great precision the signals that you handle.

Obtaining PWM outputs can be achieved simply by working with the analogWrite() function, as it handles a signal that varies its pulse width. However, the frequency of this signal is fixed and we do not have full control to manipulate it. One way to have more control over a pulse width signal is to directly generate the signal by turning the outputs on and off with the millis() and micros() functions. The downside to this is that you can’t perform other instructions and leave the PWM in the background. To handle several tasks at the same time, we handle the records directly.

Hardware Required

Components#Buy From Amazon
Arduino UNO1Buy Now
Led 5mm1Buy Now
Resistor 1K1Buy Now
37 in 1 Sensors kit1Buy Now
Jumper WiresfewBuy Now
Breadboard1Buy Now
9v DC Adapter (Optional)1Buy Now
SG90-servo-PWM-Output

Configuration Registers

The PWM signal can be realized by 3 registers, called Timer0, Timer1, and Timer2. These registers control the PWM outputs. Registers TCCRnA and TCCRnB are used to set the frequencies and pulse width. The configuration of these registers can be further complicated by the different modalities and specific cases that can occur when configuring them. It is also useful to mention that these registers are grouped into a set of bits, and these are their functions:

  • The bits that handle the way the signal is generated (Waveform Generation Mode bits WGM ): control the way we handle the timer.
    (These bits are spread across the two registers)
  • Clock Select (CS) bits – these control the Prescaler of the timer
  • Bits (COMnA): enable/disable/invert output A
  • Bits (COMnB): enable/disable/invert output B
TCCR2A-and-TCCR2B-Timer-counter-control-register-A-and-B

The OCRnA and OCRnB registers set the levels at which outputs A and B will be affected. When the timer equals those values, the corresponding output will change according to the mode specified by the previous registers.

In this tutorial, we are going to handle registers in 2 modes: Fast PWM and Phase-correct PWM. The difference between these two is how the microcontroller operates internally to generate the signals. Let’s see how to configure them:

Fast PWM

This piece of code configures Fast PWM mode on pins 3 and 11, using Timer 2. To summarize the changes in the registers, we will say that the waveform configuration bits in WGM select fast PWM mode. Sending data 10 to COM2A and COM2B provides a non-inverting signal to outputs A and B. Setting the CS bits to 100 indicates that we use the 64 Prescaler. The compare registers are arbitrarily set to 180 and 50 to control the width pulse of outputs A and B.

Code

//For more Projects: www.arduinocircuit.com

void setup() {
  pinMode(3, OUTPUT);
  pinMode(11, OUTPUT);
  
  TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS22);
  
  OCR2A = 180;
  OCR2B = 50;
}

void loop() {
  // Put your main code here to run repeatedly:
}

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 to 0. The output turns off when the timer reaches the compare value and then goes back. This results in a more symmetrical signal. The output frequency will be approximately half the value for fast PWM mode since the timer must count back and forth.

Code

//For more Projects: www.arduinocircuit.com

void setup() {
  pinMode(3, OUTPUT);
  pinMode(11, OUTPUT);
  
  TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);
  TCCR2B = _BV(CS22);
  
  OCR2A = 180;
  OCR2B = 50;
}

void loop() {
  // Put your main code here to run repeatedly:
}

Both methods produce PWM signals, the difference is that fast PWM mode can reach higher frequencies, which can be used in power supplies and motor controllers. The phase-correct mode allows you to have a more exact signal, but it does not reach such high frequencies. This tutorial for Improve your programming with Arduino: PWM management

Leave a Comment


error: