bd10264_.gif (185 bytes)
Hi-Tech Card HOME

bd10264_.gif (185 bytes)
ZPCB.COM HOME
bd10264_.gif (185 bytes)
Order Online PayPal

bd10264_.gif (185 bytes)
E-Mail


Digital to Analog Anything (DAA)
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. This article desctibes three useful functions: generating a DC comparator reference voltage, varying the color of a 'bi-color'  LED, and chirping (frequency sweeping) an audi transducer. It was originally pulled out of an appendix that described an automotive product I designed - thus the references to the Vehicle Systems Monitor.

 

DAA is a generalization of Bresenham’s 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 Z8’s 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 comparator’s 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 didn’t give me the accuracy (because of IRQ latency and fixed overhead required to change the Timer values) or resolution required to meet the product’s accuracy specification. Having used Bresenham’s 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 ZiLOG’s Z8. The required code and the execution time were likewise minimal.

 

Bresenham’s Algorithm

First published in IBM’s system Journal in 1965 under the title Algorithms for Computer Control of a Digital Plotter, Bresenham’s 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

 

There’s no reason you can’t 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 you’re 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

DAA is a powerful technique for Digital to Analog conversion and more. It is easy to understand and trivial to implement – all you need is a Timer Interrupt, a couple of registers, and a few lines of code.

 


bd10264_.gif (185 bytes)
Hi-Tech Card HOME

bd10264_.gif (185 bytes)
ZPCB.COM HOME
bd10264_.gif (185 bytes)
Order Online PayPal

bd10264_.gif (185 bytes)
E-Mail