Loading...

PWM Tutorial

As discussed in the previous tutorial, the speed of the motors is controlled by a pulse width modulation signal. In this tutorial we will cover some of the finer details of this and you can try out the concepts on your T-Bot. If you don't have an oscilloscope, don't worry, some images of the scope signals are presented here for convenience.

The N20 motors have very low inductance (~ 8.5 uH). This means they are very responsive which is what we want. However, care has to be taken to manage low inductance motors properly with a PWM signal. The default frequency for the PWM signal produced by the Arduino is 490 Hz. While the motors can’t keep up with this, there is a still a detectable response which manifests as a rather irritating noise. Typically, low inductance motors require high PWM frequencies. The plot below shows the PWM voltage signal data measured using an oscilloscope and the calculated current ripple for two PWM frequencies (the x data is scaled by a factor of two to create a dataset of half the frequency). You can see how the ripple gets more pronounced as the frequency is reduced.

AT Button

Fortunately, the PWM frequency can be increased by changing the Arduino’s clock prescaler.

The following images show the arduino PWM signal and the rapid response from the TB6612FNG amplifier. You can try setting the prescaler according to the numbers below and check the output using your oscilloscope. Alternatively, you can simply listen to hear the differences in the motor response.

  • 5
  • 4
  • 3
  • 2
  • 1
  • 30 Hz
  • 122 Hz
  • 490 Hz - Default - Unpleasant noise
  • 3925 Hz - Very unpleasant noise
  • 31399 Hz - Above audible frequencies

This invalidates millis() and micros() which should be multiplied by the prescaler.

The PWM control signal

AT Button

The PWM control rising edge 5.2 ns

AT Button

The PWM amplified rising edge - 9.8 ns

AT Button

Now for the T-Bot code.

Set motor dead bands to zero.

#include "Motor.h"
    const int m1ndb = 0 , m1pdb = 0, m2ndb = 0 , m2pdb = 0;
//const int m1ndb = 34 , m1pdb = 34, m2ndb = 34 , m2pdb = 34; // T-Bot

Configure control pins and speed scale factor.

// Set pins and meters per second factor
const int m2stby = 6, m2ain1 = 4, m2ain2 = 5, m2pwmpin = 9,  mpsfactor = 1;
Motor m1 = Motor(m2ain1, m2ain2, m2stby, m2pwmpin, m1ndb, m1pdb, mpsfactor);

const int m1stby = 6, m1ain1 = 8, m1ain2 = 7,  m1pwmpin = 10;
Motor m2 = Motor(m1ain1, m1ain2, m1stby, m1pwmpin, m2ndb, m2pdb, mpsfactor);

Stop the noise! This is where we set the prescaler to 1.

void setup() {
  int Eraser = 7; // this is 111 in binary and is used as an eraser  TCCRnB where n 
  int Prescaler = 1;// this could be a number in [1 , 5]. In this case, 3 corresponds in binary to 011.   
  TCCR1B &= ~Eraser; // this operation (AND plus NOT),  set the three bits in TCCR3B to 0
  TCCR1B |= Prescaler;//this operation (OR), replaces the last three bits in TCCR2B with our new value 011
Serial.begin(115200);

}

Now you can set the motor speed. You can choose values between -255 to 255.

}

void loop() {
  m1.speed(127);  // Right Motor
  m2.speed(127);  // Left Motor
}