logo
background
 Home and Links
 Your PC and Security
 Server NAS
 Wargames
 Astronomy
 PhotoStory
 DVD making
 Raspberry Pi
 PIC projects
 Other projects
 Next >>
[The simple R-2R binary DAC] [Ternary  logic] [The Hybrid approach] [PWM]
The Binary (R/2R), Ternary (3R/4R) and Hybrid DAC fo a low end PIC

The simple R-2R binary DAC

One deficiency of the low-end PIC's is the lack of any Digital to Analogue (DAC) output (or Pulse Width Modulation - PWM) allowing simple servo motor control) circuit. Fortunately, a handful of resistors can convert 5 or 6 'binary' bits into a stepped control voltage forming a simple DAC

4bit R-2R chain DAC for low end PIC
The 'easy' way to build a DAC is to use the classic R-2R resistor 'chain'.

The chain consists of a series of resistors 'R', with each bit is connected to the chain via double that resistance (2R).

So long as the drive pins output 'the same' voltages (and are capable of delivering 'reasonable' current') this will yield a binary weighted output voltage at the 'top' of the chain (assuming zero current is drawn from the top of the chain, i.e. the top is fed to an 'infinite impedance', like the input to an Op Amp)

For more on designing your own DAC, expand the note below

(+) D to A conversion - (R2R DAC)

[top]

Ternary (or 'trinary') logic

Using 'n' pins, binary gets you 2^n states, ternary 3^n. This makes a real difference to the number of pins needed very quickly = 3 binary bits (2^3) is only 8 states, whist 3 ternary (3^3) is 27 ! To get a 64 state DAC we would need 6 binary bits, whilst 4 ternary bits (or 'tets') gives us 81 states and 5^3 = 243 ! All PIC's have i/o pins that can generate 3 states = these are '1' (typically 4.3v), '0' (typically 0v6) and 'off' (input mode = 'tri-state' i.e. 'no voltage')

3bit ternary 3R-4R chain DAC for low end PIC
When the PIC pin is used as an output, the divider resistors will dominate the current draw. If we want to keep within 20mA**, Rdivider = 5/.02 = 250 ohms, or nearest E24 (5%) = 270 ohms (although we are using 5% resistors that's the 'absolute value' accuracy - in any 'random' batch you should be able to find 2 resistors making a 'matched pair' (i.e. correct ratio) to within the accuracy of your multimeter (typ 4 digits i.e. .1%) and that's all we need).

**The PIC has both a pin limit (20/25mA) and a 'total PORT' limit (typically 100mA). So you can build a 5 pin DAC at 20mA per pin, but a 6 pin DAC means reducing the current from each to 100/6 = 16mA .. of course when driving (or sinking) 20mA the pin output voltage will won't be 4.3v (or .6v) !

Next we consider the resistor 'ladder'. For ternary, the ladder ratios need to be 3R/4R (rather than R/2R). Since the 'chain' resistors must be high enough to avoid impacting the 'divider' resistor effect, the 'obvious' choice is 75k and 100k.

For more on designing your own Ternary DAC, expand the note below

(+) Ternary DAC - (R3R)



(-) Hybrid ternary bit conversion - (code)


Conversion from 7 bit binary to hybrid control (3 ternary + 2 binary)

The 3 hybrid ternary bits require 2 control bits each, i.e. 6 control bits for all 3.
The 'top' two hybrid bits are binary, so that's 2 more control bits = 8 bits in total (lucky, that :-) )

There are two basic ways of converting a 7 bit 'count' into the 'hybrid' control byte = by calculation or by LUT (Look-Up-Table)

A LUT will be faster (and the output control 'bit definitions' can be whatever you like) but, on the other hand, a calculation may deliver a solution in fewer total instructions, which is vital on the low end devices (eg. the 16F54 which only has 512 instruction space !)

Control LUT

A hybrid DAC built with 3 ternary + 2 binary control bits has 108 distinct states, so the LUT will have 108 entries (one for each control byte), plus a few extra 'steering' instructions.

The advantages of a LUT is that the 'conversion' doesn't have to be 'linear' = for example you could code a (1/4) sine-wave function (for AC waveform generation) or a "+/-" offset about a middle value.

If the hybrid DAC output is controlling a servo motor, and the +/- value is derived from a speed feedback circuit, you might want the LUT to code a (fast) 'speed up' ramp (from zero) and a 'gradual change' about the 'mid point' ... which would be 'offset' from the 'count 50' code.

For example, 'count 128' (0x80 = top bit set) could be defined as the 'mid point', with (say) +/- 32 counts either side (so 0x60 - 0xA0, 64 values) for 'mid speed control', leaving 108-64 = 40 counts for 'speed up from zero to (low) mid point'

The observant will note that the 'speed up' count runs from 0x00 - 0x5F, which is 96 counts.

Since we want a 'fast speed up' (and to avoid wasting too many extra LUT locations), counts of less than 0x60 would be 'divided by 4' (or even 8) before being used as a look-up address, so the 'extra' locations for speed-up will be reduced to 24 (or 12), resulting a 64+24 = 88 (76) entry table.


Defining the control byte

One problem with all DAC outputs is how to prevent 'glitches' when the 'drive' bit values are changed. This is especially difficult with a tri-state system (because the 'set tri-state (TRIS)' command and 'set PORT (output latch) bits' commands both require the control bits to be in the Accumulator = so there will be at least a 2 instruction delay between setting tri-state and setting bits.

To minimise 'glitches', the output bits could be changed 'one step at a time' in such a way that there are no 'big jumps' in the output value - although that means keeping a copy of the previous settings (as reading the PORT gets the pins 'state' (not the output latch settings), and reading TRIS gets 0's)

On the other hand, in many applications, a 'glitch' that is 'corrected' after 2 CLK's of a 1 MIPS CPU may not be noticeable


Of course things are a little simpler if only 4 (3 ternary + 1 binary) bits are being used with a 16F5x device (all the 16F5x devices have a 4 bit 'PORT A', which means the 'control' byte can can be formed of 4 TRIS bits + 4 PORT bits = grouping into 4 bits means the SWAPF command can be used to 'switch nibbles' between TRIS A and PORT A).







This note last modified: 17th Aug 2017 16:21.

[top]

[top]

The Hybrid approach

From LTspice we discover that a 3 pin 'ternary' DAC (so 3x3x3 = 27 levels) 'works' well, however above this the 'half voltage' divider of a 4th ternary bit pin overwhelms the voltages of the 3 lower bits to such a degree that the final ouptut voltage 'steps' are 'reversed' when the 4th bit is switched 'off'.

However we still want to get as many 'steps' as possible from the available i/o pins. So, how can we get over 50 steps with only 4 bits (and over 100 steps with only 5 pins) ?

3bit ternary 3R-4R chain DAC for low end PIC
The 'trick' is to run the 4th (and 5th) bit in 'binary' mode. 4 bits gets us 3x3x3x2 = 54 states whilst 4 binary bits is only 16 states (and 5 pins can deliver 3x3x3x2x2 = 108 states) ! To get anywhere near this, we would need 7 binary bits (which delivers 127 levels), whilst a 'pure binary' 5 bits would only deliver 32 states !

Using 180R for the 'half step' (2v5) divider resisters means each PIC pin sources or sinks 10mA (at 0v6/4v3). Using 3 bits from an 8 bit PIC i/o port uses 30mA, but the 4th bit consumes less than 1mA. This leaves some 70mA (of the 100mA PORT total) to be divided amongst the remaining 4 bits (about 17mA for each). This will need to be taken into account when deciding what to use the other bits for


[top]

PWM

Modern servo motor control circuits are all driven by Pulse Width Modulation. However it's difficult to achieve both a high enough PWM frequency (20kHz is about the minimium) and a decent resolution using a low-end PIC with it's internal (or simple external R-C) 4MHz OSC.

Typically you will want better than 1% speed control.
 
This implies at least 100 'step' PWM mark-space ratio - and assuming you can achieve 1 CPU CLK control this means a 100 CLK cycle time = whihc inturn is only 10kHz PWM frequency (4MHz OSC = 1MHz CLK, 1Mz/100 = 10kHz PWM)
 
The 'trick' is use a 50 step PWM mark-space and obtain a 'half step' resolution by switch from one PWM to the next each alternative cycle (so, for example, switching from PWM step 24 to step 25 (in a 50 step system) gives you '24.5' (== step 49 in a 100 step system)

(+) Pulse Width Modulation - (PWM)

Next page :- PIC low voltage ac motor control

[top]