Analog Output
Just as with input, there are times when we want an output with a range greater than 0 or 1. We might want to control the brightness of a lamp, for example, or the turn of a pointer on a dial, or the height of something hanging from a rope. In those cases, we need to make an analog output.
The most likely things that we might want to vary directly from a microcontroller are lights, sound devices, or things controlled by motors and other mechanical transducers (a mechanical transducer is something that converts electrical energy into mechanical energy — motors are the most common example). For the most part, there will be some other component in between the microcontroller and the final output device. There are lighting dimmers, motor controllers, and so forth, most of which can be controlled using some form of serial digital communication, which we’ll talk about later.
The Arduino, the PIC, BX-24 and other digital microcontrollers can’t produce a varying voltage, they can only produce a high voltage (in our case 5V) or low (in our case 0V). So instead, we "fake" an analog voltage by producing a series of voltage pulses at regular intervals, and varying the width of the pulses. This is called pulse width modulation (PWM). The resulting average voltage is sometimes called a pseudo-analog voltage.
In the graph below, we pulse our pin high for the same length of time we pulse it low. The time the pin is high (called the pulsewidth) is about half the total time it takes to go from low to high to low again. This ratio is called the duty cycle. The duty cycle is 50%,and the average voltage is about half the total voltage.

If we make the duty cycle less than 50% by pulsing for a shorter amount of time than we pause, we get a lower effective voltage:

The pulsewidth is usually a very small time, on the order of a few microseconds or milliseconds at most.
On the PIC, the easiest way to create a modulated pulse is the pulseout command. It looks like this:
PicBasic Pro:
pulsout pin, pulsewidth
Pin refers to the pin you’re going to pulse
Pulsewidth is the length of time each pulse takes, in seconds. It’s dependent on your PIC’s clock speed. For a 4MHz clock, the shortest possible pulse (e.g. period = 1) is 10 microseconds. With a 20MHz clock, it’s 2 microseconds.
If the pin was high before the pulsout command, the pulse will go low and back to high. If the pin was low beforehand, the pulse will go high, then back to low.
On the BX-24, the pulse out command looks like this:
BX-24:
call pulseout(pin, pulsewidth, state)
Pin (a byte value) refers to the pin you’re going to pulse
Pulsewidth (a single value) is the length of time each pulse takes, in seconds. The range is about 1.085 microseconds to 71.1 milliseconds (0.00002 to 0.071 seconds)
State (a byte value) is the state that the pin will be in when pulsed. If state = 1, the pin will normally be low, and pulse high. If state = 0, the pin will normally be high, and pulse low.
Wiring/Arduino:
On the Wiring and Arduino boards, there is no pulseut command. However, there are two ways to create a series of pulses: analogWrite() or writing your own pulseout.
analogWrite():
The pins marked PWM (pins 9 – 11 on Arduino, PWM 0 – 5 on Wiring) can be pulsed using the analogOut() command, like so:
analogWrite(pin, pulsewidth);
Pin refers to the pin you’re going to pulse
Pulsewidth is a value from 0 – 255. 0 corresponds to 0 volts, and 255 corresponds to 5 volts. Every change of one point changes the pseudo-analog output voltage by 5/255, or 0.0196 volts.
Write your own pulseOut:
Here’s an example of a pulseOut() function for Wiring/Arduino:
void setup() {
// make pin 13 an output pin.
// You'll pulse the LED on this pin:
pinMode(13, OUTPUT);
}
void loop() {
// read an analog input, 0 - 1023:
int pulse = analogRead(0);
// use that value to pulse an LED on pin 13:
pulseOut(13, pulse, HIGH);
}
void pulseOut(int pinNumber, int pulseWidth, int state) {
// only pulse if the pulseWidth value
// is greater than 0:
if (pulseWidth > 0) {
// if the pulse should be high, go high then low:
if (state == HIGH) {
digitalWrite(pinNumber, HIGH);
delayMicroseconds(pulseWidth);
digitalWrite(pinNumber, LOW);
delayMicroseconds(pulseWidth);
}
// if the pulse should be low, go low then high:
else {
digitalWrite(pinNumber, LOW);
delayMicroseconds(pulseWidth);
digitalWrite(pinNumber, HIGH);
delayMicroseconds(pulseWidth);
}
}
}
For most applications, it’s better to use the analogWrite() command, because the microcontroller maintains the PWM even after you give the command.
Applications of Analog Output
DC Motor Speed Control
Using a pulseout command, it is possible to vary the speed of a DC motor. We use the same transistor circuit as we did to turn on and off the motor, but instead of putting the output pin of the microcontroller high or low, we use pulseout command on it. The range of the required pulseout varies depending on the motor and the transistor used, but a range from 0.0002 to 0.02 is a good starting range. The varying pseudo-analog voltage on the base of the transistor creates a corresponding variance on the current flowing through the motor, and the motor spins at a variable rate.





One Reply to “Analog Output”
Comments are closed.