ZPCB.COM HOME |
Order Online PayPal |
a powerful technique for digital synthesis of analog functions
Digital
to Analog Anything (DAA) is a technique for digitally mixing two input functions in
precise, integral ratios to produce an output function that is partway between the two.
DAA
is a generalization of Bresenhams Algorithm, a classic Vector to Raster converter, which is described in detail below. At the start
of this project, I was casting about and considering different ways of using the Z8s
built in comparators to make the required voltage measurements. The standard way is to
generate a reference voltage with a PWM based D/A converter, feed it into the
comparators reference input, and let the comparator tell you whether the input
waveform is above or below the reference. My first attempt using a traditional PWM
didnt give me the accuracy (because of IRQ latency and fixed overhead required to
change the Timer values) or resolution required to meet the products accuracy
specification. Having used Bresenhams Algorithm in numerous stepper motor based
products, I realized it might be useful, with modifications, as a D/A converter. And
because only integers and simple arithmetic are involved, it is ideally suited for small
microcontrollers like ZiLOGs Z8. The required code and the execution time were
likewise minimal.
Bresenhams
Algorithm
First
published in IBMs system Journal in 1965 under the title Algorithms for Computer
Control of a Digital Plotter, Bresenhams Algorithm has found applications in stepper
motor based X-Y plotters and raster output devices like video cards and NC controls. Given
a vector (x,y) the algorithm calculates a move profile a series of discrete steps
along the coordinate axes or at 45 degrees to approximate the vector. The algorithm is
simple to express:
Pseudo
code:
SUM
= 0
I
= X
DO
Take an X Step
SUM = SUM + Y
If SUM >= X then
Take a Y Step too
SUM = SUM - X
Endif
Decrement I
LOOP
until I = 0
Example:
Vector X=10 Y=3
Iteration I Sum
X Step
Y Step
Angle
1
10 3
Yes
No
0
2
9
6
Yes
No
0
3
8
9
Yes
No
0
4
7
(1)2
Yes
Yes
45
5
6
5
Yes
No
0
6
5
8
Yes
No
0
7
4
(1)1
Yes
Yes
45
8
3
4
Yes
No
0
9
2
7
Yes
No
0
10 1 (1)0
Yes
Yes
45
resulting
in the final coordinate of (10,3)

The
algorithm as shown can only to handle vectors between 0 and 45 degrees.
(X
>= Y >= 0). For other octants, first re-sign so both are postive. And if Y > X
swap X & Y to keep the angle <= 45 degrees.
Beyond
Bresenham Digital to Analog Anything
Digital
to Analog Anything takes any two inputs (not just X and Y)
and digitally mixes them in precise, integral ratios to produce an output function that is
partway between the two.
I
will detail three of the prominent applications of DAA I devised for use in the Vehicle
Systems Monitor:
· Generating
an analog output signal (for comparator reference input) resolution 1 parts in 2772,
between 0 and 5 volts
· Displaying
Red. Or Green. Or 58 colors between - simultaneously on three
bi-color LEDs
· Sweeping
the beeper frequency between 0 and 2500 Hz with 10 Hz resolution
PWM
DAA mixing 0 volts & 5 volts to produce intermediate voltages
A
traditional PWM D/A converter is implemented by varying the mark/space ratio of a fixed
frequency signal. The Pulse Width Modulated waveform may be subsequently low pass
filtered to produce intermediate a DC analog level.
The
DAA technique uses a fixed decision rate, where the algorithm decides at
specific intervals whether to set the output voltage to 0 or 5 volts. This can yield a
higher switching frequency that is more easily filtered. More importantly, because the
firmware overhead is low , it is possible to run multiple, simultaneous, independent DAAs
from a single timer interrupt.
DAA
dithering between 5 volts and 0 volts produces an analog output with almost arbitrary
resolution and very good accuracy, without the need for sub-microsecond timing resolution
or worry about IRQ latency and overhead.
For
example: let the desired output voltage be the 3/10 full scale or 1.5 volts. This
correspond to a vector
5volts = 7, 0volts = 3. Unlike the vector
example which was dithering between 0 degrees and 45 degrees, we are dithering between
0volts and 5 volts.
So
Numerator = 3 like before, but Denominator = 3 + 7 or 10.
Also,
in this case we execute the loop indefinitely, or as long as we desire the output. No loop
counter is required. The loop must be executed frequently for minimal AC ripple and at a
constant rate for good absolute accuracy. A timer IRQ is ideal for this purpose.
Set
NUM = 3, DENOM = 10 (to generate 3/10 full
scale output)
SUM
= 0
Every
Timer IRQ:
DO
SUM = SUM + NUM
IF SUM < DENOM THEN
SET OUTPUT = LOW
ELSE
SET
OUTPUT = HIGH
SUM
= SUM DENOM
ENDIF
LOOP
Theres
no reason you cant use almost any denominator - especially with properly sized and
selected low pass filter components. I use 2,772 in the Vehicle Systems Monitor. This
allows me to conveniently express the Numerator in centi-volts (10 mV steps = 10mV
resolution) and helps keep the code readable.

Both
waveforms have a 30% on time. The DAA (top graph) produced signal, when low pass filtered,
produces the least peak to peak ripple. More importantly, it is more accurate than a
normal PWM and has much better resolution. (excluding Hardware PWM on Z8 Plus)
Bi-color
LEDs produce intermediate colors by mixing Red and Green
This
technique is used in varying the color of a bi-color LEDs from deep red through yellow to
green in sixty steps.
FOR
RED, set NUM = 0, DENOM = 60
All Red
FOR
YELLOW, set NUM = 56, DENOM = 60
Mostly Green, some Red
FOR
GREEN, set NUM = 60, DENOM = 60 All Green
For
example, YELLOW:
Set
NUM = 56, DENOM = 60
SUM
= 0
Every
Timer IRQ:
DO
SUM = SUM + NUM
IF SUM < DENOM THEN
LIGHT LED RED
ELSE
LIGHT LED GREEN
SUM
= SUM DENOM
ENDIF
LOOP
It
is possible to extend this technique to simultaneously vary the LED brightness and blink
rate. Just add a few dimensions. And no low pass filter is required here your eyes
perform that function automatically. (Unless youre chewing ice or jerking your head
around violently and blinking your eyes while staring at the LEDs.)
Piezo-electric
Audio Transducer mix 0Hz and 2500 Hz in various ratios to digitally synthesize
intermediate frequencies.
And
finally, I use DAA to Frequency Modulate the beeper. The system requires a loud beeper.
The electronics enclosure is sealed, and cabin noise is already oppressive. The selected
beeper produces very high SPLs, but only when driven at resonance frequency. And resonance
varies from unit to unit. The solution was to sweep the frequency in a chirp-like fashion
thereby guaranteeing some time at resonance for every beeper.
In
this case I used a denominator of 256 this makes the subtraction automatic.
SUM
= SUM DENOM is calculated by ignoring the high byte of the previous add, and the
whole process can be implemented in three Z8 instructions.
NUM
is any # between 0 and 255
DENOM
is implied to be 256
DO
SUM = SUM + NUM
IF Carry (SUM >= 256) THEN
Toggle
Output to Beeper
ENDIF
LOOP
In
Z8 assembly, this is literally:
SERVICE_BEEPER:
ADD rBeep_Sum,rBeep_Frequency ;SUM = SUM + NUM
JR NC,DONE_TOGGLE
;no overflow, jump around
XOR rP2_IMAGE,#00000011b
;Toggle the beeper
DONE_TOGGLE:
.
.
continue with other code here
If
this routine is called by a timer interrupt, then
Output
Frequency = (Timer IRQ Frequency)/2 * NUM/256
The
foreground routine to sweep through various frequencies looks like this:
Set
NUM = Value #1
Wait
a few mS
Set
NUM = Value #2
Wait
a few mS
Set
NUM = Value #3
Wait
a few mS
Set
NUM = Value #4
Wait
a few mS
.
.
etc.
Summary
ZPCB.COM HOME |
Order Online PayPal |