DIY laser projector part 3: digital to analog conversion

In the previous post we tried to move a dot around an oscilloscope screen by hooking up an arduino and feeding voltages to the scope. However, the Arduino is only capable of outputting 0V or 5V. The function to write intermediate values uses Pulse Width Modulation which rapidly switches the voltage between 0V and 5V. This is useless to us since it just caused the dot to jump between 0V and 5V.

This post is a bit more technical. If anything is not clear, just leave a note in the comments.

Low pass filter

My first thought to solve this problem was to use something called a low pass filter. This is a simple arrangement which uses a capacitor and a resistor like this:

(For anyone unsure of what a capacitor is, just think of it as a little battery – when voltage is applied to it, it charges up. When the voltage is switched off, it discharges)

DSCF3107 (3)

Low pass filter

Basically, the time taken for the capacitor to charge and discharge ‘smooths out’ the signal. Problem is:

  • no low pass filter is perfect, the output voltage still varies somewhat.
  • The better the filter is at smoothing the signal (ie, the bigger the capacitor), he longer the response time. A bigger capacitor takes longer to charge up and so the voltage takes longer to reach the desired voltage. This is useless for our application where we need really fast response times.
Comparison of signals from Arduino. This particular signal would move a dot instantly from one point of the screen to another. The low pass filter smoothes out the signal but not perfectly.

Comparison of signals from Arduino. This particular signal would move a dot instantly from one point of the screen to another. The low pass filter smoothes out the signal but not perfectly.

To be honest, I knew this would be the case. After a search on the arduino website, I figured out a better solution:

Sending the signal

The first part of the solution is not to use analogWrite from the Arduino. The fact that this function relies on pulse width modulation makes it useless to us. But…the only other way to send voltages is to use digitalWrite. As discussed before, this can only send a voltage of 5v or 0v through each pin. How on Earth can this be of any use to us when we need to send a whole range of voltages to move the dot to a whole range of positions?

We use more than one pin

This sounds a bit odd at first – how can we use multiple pins to send a single voltage to the scope? Let’s find out

Parallel outputs

Let’s forget about the oscilloscope for now and just hook up wires to pins 1,2,3 and 4 on the Arduino.

4 output pins from the Arduino

4 output pins from the Arduino

Set these pins to be outputs and we can send all the following combinations through the pins (NOTE – from now on, I won’t refer to the pins being at 5V or 0V; I’ll just write ‘1’ for a pin at 5V and ‘0’ for a pin at 0V) :

Pin 1 Pin 2 Pin 3 Pin 4
 

 

 

 

 

 

     Pin values

0 0 0 0
0 0 0 1
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1

So, there are 16 different combinations we can set the pins to using digitalWrite. But, hold on a second, do those combinations look familiar? They are binary numbers! In fact, in the table above, they are numbers 0 to 15 in binary.

So, it looks like we can send numbers 0 to 15 from the Arduino. But these ‘numbers’ are in the form of binary across 4 separate wires. Not much use for moving a dot around an oscilloscope. What we need is some kind of device which can take these binary numbers, from the multiple wires and do the following:

  • convert the binary numbers to a decimal value (decimal just means ‘normal numbers’ ie, 1,2,3…etc).
  • Scale these decimal values between 0V and 5V – ie the range of voltages we are planning on sending to the oscilloscope.
  • Send the voltage down a single wire so it can be fed into the oscilloscope
  • Do this very very quickly and to a high level of accuracy.

Surely such a device must be pretty complicated? Nah, you can make one in 5 minutes with just these:

We can build something to convert our binary signal to useful voltages with just a handful of resistors

We can build something to convert our binary signal to useful voltages with just a handful of resistors

Honestly.

The resistor ladder

In the example we are discussing, there are 4 output wires producing the binary output from the arduino. If we hook up some resistors like this, they will do everything we require:

r ladder

Resistor ladder schematic. This arrangement of resistors will convert the binary signal from the Arduino into a useful voltage for the scope.

As many people will have figured out, this is a type of digital to analog converter. It takes a digital signal from the Arduino (the binary values from the multiple pins) and converts it to an analog signal (the voltage to the oscilloscope).

Why on Earth does this work?

It took me a while to understand why this works. Like anything involving electricity, I had to use the hydraulic analogy

Turns out there is a great way of visualising what’s going on in an electric circuit. All you have to do is imagine the following:

  • Electric current is flowing water – they behave the same in this analogy.
  • The voltage is the water pressure.
  • Wires are pipes.
  • Resistors are restrictions in the pipe.

So, if we apply the hydraulic analogy to the resistor ladder, we’d get a contraption something like this:

Using the hydraulic analogy, the resistor ladder (above image) would be equivalent to this arrangement of pipes and taps.

Using the hydraulic analogy, the resistor ladder (above image) would be equivalent to this arrangement of pipes and taps.

Turning on a tap is the same as setting a pin on the Arduino to 5V (or, 1 in the binary list above). Let’s play around with the taps:

  • Imagine turning on tap D only, we’d only get a really small pressure on the output. This is the same as setting pin 4 to HIGH – we only get a small voltage to the oscilloscope.
  • Now imagine turning on tap A only. We’d get a far higher pressure at the output. It wouldn’t quite be the full pressure of the input taps because some water would flow to the drain, but not much.
  • Now imagine turning on all 4 taps. We’d get full pressure at the output.

Imagine the pressure at the taps is 5 Bar. So, we can send a range of values from 0 Bar to 5 Bar to the output. But, remember, water pressure = voltage. So, using the pins from the Arduino to send multiple 5V outputs through a resisstor ladder, we can achieve voltages between 0V and 5V!

Furthermore, since the digitalWrite function changes the voltage of the pins from 0V to 5V extremely quickly, and the resistors are ‘passive’, the resistor ladder converts the digital signal to an analog one almost instantaneously.

Raising the resolution

The only problem now is that we can only send 16 different values by using 4 wires. This still isn’t a great deal of use to us for drawing images on the oscilloscope. We need a higher resolution. Easy – we just use more wires and feed into a longer resistor ladder like this:

8 bit resistor ladder, as used in the final design to give an image resolution of 256X256

8 bit resistor ladder, as used in the final design to give an image resolution of 256X256

I chose to use 8 wires. This gives 2^8 = 256 possible positions for each input. The binary numbers are 8 digits, or bits, long. Ever heard of people referring to 80’s computer games as 8 bit? Yep, that’s why!

But one second…the Arduino I was using before only had 14 pins. We need 16 pins now. This is easy to fix, I just used a different type of Arduino called the Arduino Mega. This one has 54 pins available which is pretty epic.

Dealing with the code

When I figured this out, I had images of having to tell the Arduino to write 8 seperate High/Low values to each pin every time I wanted to move the dot. Of course, this would be completely impractical (the ‘dot’ moves thousands of times in the final presentation). Luckily, the Arduino has a built in function to deal with this. You just plug in the wires to the appropriate pins and these pins are then referred to as a ‘PORT’. You just tell the Arduino the value you want this port to be set to (any number between 0 and 255, to correspond with the desired dot position). The Arduino then takes care of the binary outputs for you.

Let’s do a quick example. The arduino is hooked up to the scope like this:

Arrangement to send signals to scope through ports viaresistor ladders.

Arrangement to send signals to scope through ports viaresistor ladders.

And we run the following code:

void setup() {

//this sets up the arduino
//we tell it that we are using 2 ports (consisting of 8 pins each)
//each port will have a range of values from 0-255
DDRA=255;   //PORTA initialise
DDRB=255;   //PORTB initialise

}

//commence recurring loop
void loop{
PORTA=153;//move dot 3/5ths of way across screen horizontally
PORTB=153;//move dot 3/5ths of way way across screen vertically
}

Here’s what we get on the screen:

oscilloscope screen with above code running

oscilloscope screen with above code running

Excellent – we can now put a dot anywhere we want on the screen just by telling it to send the appropriate value to PORT A or PORT B.

But how do we draw the sort of thing we need? How do we do lines? Circles? Curves.

We’ll find that out in the next post!

Summary of where we are

  • We can put a dot anywhere on an oscilloscope screen.
  • In order to do so we send a parallel signal through a pair of resistor ladders using digitalWrite.
  • Next we need to learn how to draw things with the dot by moving it (and then we’ll use the laser).

Further reading

http://www.tek.com/blog/tutorial-digital-analog-conversion-%E2%80%93-r-2r-dac excellent guide into how resistor ladders work and the mathematics of why they work.

https://www.arduino.cc/en/Main/ArduinoBoardMega2560 more info on the arduino mega

https://www.mathsisfun.com/binary-number-system.html simple guide to counting with binary

https://www.youtube.com/watch?v=_tABS7AX8D8 someone else doing exactly what is described in this post – really good explanation of the resistor ladder and the whole setup in general.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s