Programming A Driverless Car Chapter 14: Pulse Width Modulation
In this chapter we will deal with how do we use PWM and why do we use it. We will start by talking about what if a digital micro controller or processor can easily process digital input or output signals?
Analog outputs can be stimulated using pulse width modulation. Like in case of a light bulb, we can either switch on the LED or switch off the LED. But if we want to generate analog output or control the light of the LED, it can be stimulated with pulse width modulation.
In a digital pulse, the time frame in which the pulse remains high is called full period. So, if a pulse remains high constantly for one period we can say it’s duty cycle is 100%. If it is low, then DC will be 0%. Within this period if the pulse stays high for full period, the energy cycle is 100% and the duty cycle is 100%, then the generated voltage will be 5 volts. In case of digital form, it is either high or low i.e either 5V or 0V. But it can vary within the period by 50% then the voltage generated will be 2.5V. Just by changing the width we will be able to change the duty cycle.
Pulse Width Modulation with arduino-
PWM is a way to provide a variable signal from a given set signal. We vary the width of the signal and generate the output voltage. PWM does this by changing the pulse width, which in turn, changes the duty cycle of a square wave to alter how much power is supplied to the attached component. It varies because the signal takes the duty cycle and averages the power signal that is output.
PWM generates analog output by varying the duty cycle of the square wave by changing the width of the square wave.
-Microcontroller allows only 2 stages- High and Low.
-”Fake” analog using PWM
-Virtual digital to analog converter
-It is a technique for getting analog results with digital means.
PM on Arduino:
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 500 Hz, the green lines would measure 2 milliseconds each. For ex. A call to analogWrite() is on a scale of 0-255, such that analogWrite(255) requests a 100% duty cycle( always on), and analogWrite(127) is a 50% duty cycle.
In general cases:
- Can’t use digital pins to directly supply say 2.5V, but can pulse the output on and off really fast to produce the same effect.
- The on-off pulsing happens so quickly, the connected output device “sees” the result as reduction in the voltage.
In case the width of the pulse is high, only for 75%, the output generated duty cycle will only be 75%, and glow with a brightness of 75%.
In case of arduino we have 3 timers, and from the timers we have 6 PWM pins. The command used: analogWrite(pin, Value)
Value is duty cycle: between 0 to 255
Examples:
analogWrite(9,128) for a 50% duty cycle.
analogWrite(11,64) for a 25% duty cycle.
Fig- Arduino Panel
The pin will be anywhere in between from 3,5,6,9,10 and 11. And the value will be anywhere between 0 to 255.
LAB- Working with Pulse Width Modulation:
This program is all about controlling the speed of the motor or brightness of LED. PWM is available at 6 pin arduino channel.
int led=11;
int i=0;
void setup()
{
pinMode(led,OUTPUT);
}
void loop()
{
for(i=0;i<256;i++)
{
analogWrite(11,i);
delay(10);
}
delay(100);
#to bring led’s brightness from highest to low
for(i=255; i>0;i--)
{
analogWrite(11,i);
delay(10);
}
delay(100);
}
Save the program, compile the program and upload it.
Fig. Live LED Platform to check LED going ON/OFF
You can see this going dim to bright and bright to dim by plugging in the ports 11 and 13.
LAB: Robot Speed Controlling Using Delay and PWM
We will control the speed of the robot by this program. We will control 2 motors using PWM.
First we will start by writing Arduino code:
int m11=6;
int m12=9;
int m21=10;
int m22=11;
int i=0;
void setup()
{
pinMode(m11,OUTPUT);
pinMode(m12,OUTPUT);
pinMode(m21,OUTPUT);
pinMode(m22,OUTPUT);
}
void loop()
{
i=150;
for(i=150;i<256;i+=30) ----- it will rotate with a speed difference of 30 bits after 256 and come back to 150
{
digitalWrite(m11,LOW)
analogWrite(m12,i)
digitalWrite(m21,LOW)
analogWrite(m22,i)
delay(3000);
#this if for taking turn for the robots
digitalWrite(m11,LOW)
analogWrite(m12,i)
digitalWrite(m21,LOW)
analogWrite(m22,0)
delay(1000);
#for going straight
digitalWrite(m11,LOW)
analogWrite(m12,i)
digitalWrite(m21,LOW)
analogWrite(m22,i)
delay(3000);
#for making turns again
digitalWrite(m11,LOW)
analogWrite(m12,i)
digitalWrite(m21,LOW)
analogWrite(m22,0)
delay(1000);
digitalWrite(m11,LOW)
analogWrite(m12,i)
digitalWrite(m21,LOW)
analogWrite(m22,i)
delay(3000);
#for making a third turn
digitalWrite(m11,LOW)
analogWrite(m12,i)
digitalWrite(m21,LOW)
analogWrite(m22,0)
delay(1000);
#for straight
digitalWrite(m11,LOW)
analogWrite(m12,i)
digitalWrite(m21,LOW)
analogWrite(m22,i)
delay(3000);
#for fourth turn
digitalWrite(m11,LOW)
analogWrite(m12,i)
digitalWrite(m21,LOW)
analogWrite(m22,0)
delay(1000);
#for making it go straight
digitalWrite(m11,LOW)
analogWrite(m12,i)
digitalWrite(m21,LOW)
analogWrite(m22,i)
delay(3000);
#for stopping the robot
digitalWrite(m11,LOW)
analogWrite(m12,0) ---- need to stop both the wheels
digitalWrite(m21,LOW)
analogWrite(m22,0)
delay(2000);
}
}
Compile the code, upload it and see the results.
LAB- Controlling Angular Movement of a Robot using delay and PWM
By this program, we will make the robot learn to take a turn. We need to control the time in which it takes a turn for that we will control its angle.
int m11=6;
int m12=9;
int m21=10;
int m22=11;
void setup()
{
pinMode(m11,OUTPUT);
pinMode(m12,OUTPUT);
pinMode(m21,OUTPUT);
pinMode(m22,OUTPUT);
#declare the baud rate
Serial.begin(9600);
}
void loop()
{
while(Serial.available())
{
char data= Serial.read();
if(data==’r’)
{
right();
}
else if(data== ‘l’)
{
left();
}
else if (data== ‘s’)
{
stoprobot();
}
else if(data== ‘a’)
{
right()
delay(500);
stoprobot();
}
else if(data== ‘b’)
{
right();
delay(800);
stoprobot();
}
else if(data== ‘c’)
{
right();
delay(1000);
stoprobot();
}
else if(data== ‘d’)
{
right();
delay(1200);
stoprobot();
}
else if(data== ‘e’)
{
left();
delay(500);
stoprobot();
}
else if(data== ‘f’)
{
left();
delay(800);
stoprobot();
}
else if(data== ‘g’)
{
left();
delay(1000);
stoprobot();
}
else if(data== ‘h’)
{
left();
delay(1200);
stoprobot();
}
}
}
void right()
{
digitalWrite(m11,LOW)
analogWrite(m12,200)
digitalWrite(m21,LOW)
digitalWrite(m22,LOW)
}
void left()
{
digitalWrite(m11,LOW)
digitalWrite(m12,LOW)
digitalWrite(m21,LOW)
analogWrite(m22,200) ------ By using this the robot will move slowly, easy to control it while taking a turn
}
void stop()
{
digitalWrite(m11,LOW)
digitalWrite(m12,LOW)
digitalWrite(m21,LOW)
digitalWrite(m22,LOW)
}
We will see later that the robot will be taking turns based on this program.