# Computerized Etch a Sketch

## Step 14: More programming(angles and curves)

To make the etch-a-sketch draw at an angle, you just gotta run both motors at the same time. Drawing at 45 degrees is pretty easy--just turn both motors on in the proper direction and it works. Angles other than 45 degrees are a little trickier. Let's say you wanted (for the sake of a round number) to draw a 26.6 degree line. This means you have to draw one unit vertically for every two units you draw horizontally. You could alternate back and forth between the horizontal and vertical motors in tiny increments, saying
drawLeft(2)
"drawUp(1)"
and loop that for a while, but that'll never be all that smooth.

Wouldn't it be much cooler to run both motors at the same time, and run the vertical motor(in this case) half as fast as the vertical motor?

The way to do this is with PWM. For those of you who aren't familiar with this wonderful thing, PWM stands for "Pulse Width Modulation" and is a way of approximating a value between 0 and 1 in a digital circuit.
Here's a brief rundown:
Let's say I have a chip that can produce either 0 or 5 volts. This chip drives an electric motor, and I'd really like to run it at half speed, or 2.5 volts. I can't produce that voltage directly from my digital chip, but maybe if I output 0 volts for a while and then 5 volts for the same amount of time, the average output would be 2.5 volts. If I do this really slowly, the motor will jerk on and off, but if I switch between 0 and 5 volts really quickly, the motor will run smoothly. This is because the motor has a damping effect, and for some high frequency, can't respond as quickly as the signal is changing, effectively averaging the voltage across it. Hooray! Now I can control a motor's speed!

"If I want to produce a different voltage, say, 3 volts, I would just keep the signal at 5 volts for 3/5 of the time. 2 volts, 2/5 of the time. Ad nauseum"

OK, so practically, I'd like to write a PWM routine that can output a pwm wave to both motors simultaneously.

void pwm(unsigned char horizontal, unsigned char vertical, unsigned char horizontal_direction, unsigned char vertical_direction, int magnitude)
{
unsigned char count,output;
output=0;
int length;
for(int length=0;length<magnitude;length++)
for(count=0;count<255;count++)
{
if(count<horizontal)
output|=_bv(horizontal_direction);
if(count<vertical)
output|=_bv(vertical_direction);
PORTB=output;
}
}

The angle you draw at (from the horizontal) will be pretty close to atan(vertical/horizontal).

Now you have a function that lets you specify the magnitude and direction of a drawn vector. This is the basic, fundamental component of any vector graphics renderer. Sweet!
Remove these ads by Signing Up