PutDAC accuracy

Discussion specific to the ZX-1281 and ZX-1280 microcontrollers as well as the ZX-1281 and ZX-1280 Dev Boards.
Post Reply
pjc30943
Posts: 220
Joined: 01 December 2005, 18:45 PM

PutDAC accuracy

Post by pjc30943 »

Anyone able to obtain relatively accurate voltages using putDAC?

On the 1281ae, accuracy degrades (and is lower than commanded) as the commanded voltage nears 5V--indicating that the caps can't charge.
There are no other tasks running.

At a 0.8 (4V) desired output, for example, I get 3.7V. With 0.5 (2.5V) I get 2.37V. This obviously is a very large deviation.
At 0.2 (1V) it is okay.

I have 1uF and 220 Ohms, leading to a x2 multiplier for a 0..10V range--thus a proper buffer exists. I'm measuring with a nice Fluke directly after the filter, so the meter is high impedance as well.

Taking down to the purest level, even the following snippet in Main() is not accurate:

Code: Select all


public DACacc as single
DACVout = 0.5
do
  putDAC DACpin, DACVout, DACacc, 10
  sleep 0.0
loop
10 PWM outputs should be way more than enough, and the (almost) fastest refresh means it should be stable.

Anyone have thoughts on what I might be doing wrong?
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: PutDAC accuracy

Post by dkinzer »

pjc30943 wrote:Anyone able to obtain relatively accurate voltages using putDAC?
We use test code similar to the code below. My recollection is that we see voltages within a few tenths of a volt of the intended output as measured with a DVM with no other load.

The code cycles through a series of output voltages (0, 1.25, 2.5, 3.75 and 5.0), changing to the next output when a character is received on Com1.

Code: Select all

' This module tests DacPin() and PutDac().  Connect a 1K
' resistor from the output pin to a 4.7uF cap to ground.
' Measure the voltage at the R-C junction.

#if Option.TargetDevice = "ZX128e"
Private Const pin as Byte = 36
#elseif Option.TargetDevice = "ZX1281" Or Option.TargetDevice = "ZX1280"
Private Const pin as Byte = E.6
#else
Private Const pin as Byte = 14
#endif
Dim data as ByteVectorData({0, 63, 127, 192, 255})

'#define USE_PUTDAC

Sub Main()
   Dim idx as Byte, lastIdx as Byte
   Dim acc as Byte
   idx = 255
   lastIdx = 255
   Do
      ' see if a character has been received, move to the next voltage if so
      If (GetQueueCount(CByteArray(Register.RxQueue)) > 0) Then
         Dim b as Byte
         Call GetQueue(CByteArray(Register.RxQueue), b, 1)
         idx = idx + 1
      End If
      If (idx > CByte(UBound(data))) Then
         idx = 1
      End If

      ' if the index has changed, display the new output voltage
      If &#40;idx <> lastIdx&#41; Then
         Debug.Print "idx = "; CStr&#40;idx&#41;; ", Output = "; Fmt&#40;CSng&#40;data&#40;idx&#41;&#41; * 5.0 / 255.0, 1&#41;
         lastIdx = idx
      End If

      ' generate the pseudo-PWM signal
#ifdef USE_PUTDAC
      Call PutDac&#40;pin, data&#40;idx&#41;, acc, 3&#41;
#else
      Call DacPin&#40;pin, data&#40;idx&#41;, acc&#41;
#endif

      Call Delay&#40;0.01&#41;
   Loop
End Sub
- Don Kinzer
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

I performed some measurements with Don's testcase using a 1K resistor and 4.7uF cap. I tried both on a ZX-24 and a ZX-128e with similar results.

You need some kind of high impedance buffer to get the correct output voltage because any load will reduce the expected output voltage.
Last edited by mikep on 04 October 2007, 23:05 PM, edited 1 time in total.
Mike Perks
pjc30943
Posts: 220
Joined: 01 December 2005, 18:45 PM

Post by pjc30943 »

Thanks Mike and Don.

Too bad--apparently a separate DAC is in order for this app.
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

PutDAC is a poor man's solution and relies on pumping out sufficient pulses to provide an average voltage over time.

A PWM channel can achieve the same result without constant monitoring by the ZBasic application.

If you have 4 or 8 I/O bits free then a R-2R ladder can be used. An I2C "port expander" may be useful here if you don't have enough I/O pins.

Last but not least a separate DAC may be the best overall solution.
Mike Perks
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

I think we discussed it here before, but....

One can use an ADC pin on the output to sample the DAC voltage and adjust the parameters to get the desired voltage.

Also, if you need really fast response, you could develop a table of settings for the DAC, that get changed rapidly as the output cap initially charges. Essentially you drive the DAC at a high voltage setting briefly, then progressively decrease the setting as the cap charges. Maybe only 2 or 3 changes need to be made....

Also, you might develop a table of setttings that give a more accurate output voltage in the steady state. These exact settings will depend on the circuitry hooked to the DAC output.

-Tony
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: PutDAC accuracy

Post by dkinzer »

pjc30943 wrote:Anyone able to obtain relatively accurate voltages using putDAC?
I re-ran the test on a ZX-24 using a 1K resistor and 4.7uF cap. With Vcc at 5.03 volts, the result using PutDAC() with a count of 3 and using DACPin() was as shown in the table below. The voltage was measured at the R/C junction using a DVM with no other load. These results are similar to results that we've obtained over various VM versions.[table]
[row]Target[col]PutDAC, count=3[col]DACPin
[row]0.00[col]0.01[col]0.1
[row]1.25[col]1.23[col]1.24
[row]2.5[col]2.49[col]2.50
[row]3.75[col]3.74[col]3.76
[row]5.0[col]4.97[col]4.99
[/table]
Even with these results, this method of generating an analog voltage suffers from the obvious limitation of requiring frequent service by the processor. Using the hardware-based PWM functions is a better option although that does require using certain pins. Beyond that, using a dedicated DAC chip, R-2R ladder or other mechanism might be considered. I've used the LTC1451 12-bit serial-input DAC with good results.
- Don Kinzer
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

Just to be clear, I've attached an image of a schematic showing the proper R-C configuration to use for filtering the DAC output. This is a common low pass filter configuration.
Attachments
dac.jpg
dac.jpg (9.32 KiB) Viewed 10704 times
- Don Kinzer
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Re: PutDAC accuracy

Post by mikep »

dkinzer wrote:I re-ran the test on a ZX-24 using a 1K resistor and 4.7uF cap. With Vcc at 5.03 volts, the result using PutDAC() with a count of 3 and using DACPin() was as shown in the table below. The voltage was measured at the R/C junction using a DVM with no other load. These results are similar to results that we've obtained over various VM versions.
I can now reproduce your results. I left a ULN2803 load on the output pin. I guess no load means NO LOAD.
Mike Perks
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: PutDAC accuracy

Post by dkinzer »

mikep wrote:I can now reproduce your results.
Thanks for confirming the result.
- Don Kinzer
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Re: PutDAC accuracy

Post by spamiam »

mikep wrote:I can now reproduce your results. I left a ULN2803 load on the output pin. I guess no load means NO LOAD.
Hmmm, if the output is that dependent on load, then it might be necessary to have a voltage follower op-amp for many DAC purposes.

And/Or feedback to ADC might be helpful.

-Tony
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: PutDAC accuracy

Post by dkinzer »

spamiam wrote:f the output is that dependent on load, then it might be necessary to have a voltage follower op-amp for many DAC purposes.
You are correct. The filter capacitor is charged during the generation process to the average voltage of the pulse stream (q = C * V). Any current drawn from the capacitor will necessarily drain off charge from the capacitor's plates resulting in a lower voltage.

When the PutDAC() routine is not being executed, the voltage on the capacitor will decay depending on the load (including the internal leakage of the capacitor). The lower the load, the longer the period can be between PutDAC() calls while maintaining the voltage within a given range.
- Don Kinzer
Post Reply