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 (~ 2.6 mH) see Measuring Inductance. 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.
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.
|
|
millis() and micros() are still valid.
The PWM control signal
The PWM control rising edge 5.2 ns (light can only travel about 1.5 m in this time!)
The amplified PWM rising edge - 9.8 ns
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 }