Thoughts on a Unique I2C-DAC Interface.

Lt2mc

Member
Hey All,
I have an interesting thought for improving the resolution of my I2C-DAC, and I am solicitation everyone's feedback. I have taken my LED life span project back up, and have successfully interfaced my I2C-DAC. Thanks Hippy for the insights last year, it was easier then I thought.

However, now I am not happy with the resolution I am getting, the DAC offers a resolution of 256 points across the DAC's Vdd, which in this case is ~5vdc. Unfortunately my LED driver's max Alog IN is 1.3v, which effectively takes my resolution down to ~66 points. With a lower Vdd (minimum is 2.8v) I could almost double my resolution. So my thought is, rather then add a 2.8v source to my board, why not use the DAC function on my 28x2 as a power source for the I2C-DAC by setting the fvr to ~2.8v?

Does this sound plausible, or am I just being lazy trying to solve a hardware issue with software?

Thanks,
 

premelec

Senior Member
Can you reduce Vref on the DAC? Or use a 10 or 12 bit DAC ;-0 - Possibly the fvr has too high source impedance for setting the DAC chip... you can use an LDR to reduce your 5v source... What is the driver's input impedance?
 

depeet

New Member
Unfortunately you didn't mention which DAC you are using. About 10 years ago we used a ADC which had a Vref-pin. With a resistor and a zenerdiode we applied 2,7volt on this pin. Perhaps your DAC has a similar feature.
 

hippy

Senior Member
So my thought is, rather then add a 2.8v source to my board, why not use the DAC function on my 28x2 as a power source for the I2C-DAC by setting the fvr to ~2.8v?
I expect the problem will be, as premelec notes, is that the PICAXE DAC only allows minimal current draw and needs to be buffered by an op-amp to be used as a voltage source but it does sound like it should work if you did.

It might be possible to connect the DAC direct to the ADC Vref if it has one but, again, an op-amp buffer would be recommended. A fixed voltage supply to Vref as depeet suggests should work.

The easiest option may be to reduce the PICAXE and ADC supply voltage to 3V3 which will automatically give a higher resolution, close to what one would get at 2V8.

Details of the I2C DAC being used may help brig forward other suggestions.
 

Lt2mc

Member
Wow, thanks for all the responses.

My bad, I should have given the DAC details up front. I am using an 8-bit Gravitech unit, that unfortunately does not have any external Vref-pin (at the board level). It is a nice component that fit within the 6-pin slot on my board, other then that I will have to dig deeper into the IC spec for Impedance details, vref pin, etc.

Buffering the PIC's DAC adds a level of complexity that I was trying to avoid. Reducing the supply voltage to 3v3 may be the simplest solution achieved by just swapping out my existing 5v source. I will have to review the entire circuit to make sure I won't be shorting (bad pun) any other component's minimal voltage.

I will mull over it through out the day, and let everyone what I will try.

Thanks All
 

hippy

Senior Member
Sorry; just realised you are talking DAC to drive the LED, not ADC to read a voltage. What I previously wrote should however still apply.

The Gravitech DAC appears to use a DAC5571 which doesn't have a Vref so the only means of control would be through adjusting its V+ voltage.

Because I2C is open-collector, it should be possible to run the DAC from 2V8 or 3V3 with the rest of the board at 5V. The I2C pull-ups would have to be external and go to the DAC V+, you must not use internal pull-ups, and you would have to be careful not to ever make SDA or SCL output high.
 

Pongo

Senior Member
Am I missing something? The DAC5571 has a buffered output and I doubt that the LED driver's Alog IN sucks a lot of current. Why not just do this the easy way and use a resistive voltage divider to reduce the DAC output voltage range to 0 to 1.3 volts?
 

Lt2mc

Member
Ok, that is down right embarrassing, talk about "not seeing the trees through the forest". Thanks Pongo, I can throw together a quick divider and continue my testing, while i wait for a new 3v3 VR. It is amazing, the more I learn, the more I forget. Thanks everyone for the help. BTW, I can't believe how many project options I2C opens up once you play with it. I am thinking of how to cut down on the mm2, and go mm3. :)
 

Lt2mc

Member
Alright, back at it with a good solid day of work. :) Followed unfortunately by even more questions. I got my new 3v3 VR, and every thing there works fine. However I am still having a resolution problem. I hit my max Vout (3.0v) when I have only writen a value of 0-15 to the DAC. I would think I should be able to write a value of 0-256 before maxing my Vout???

My question is, am I writing to the DAC improperly, or using the wrong type of variable? There is a section in the manual that I find confusing, and think it may have something to do with what I am fighting.

"...Location defines the start address of the data to be written,..." What does "Start address" mean? Does it mean I need to specify where to write my variable into the DAC?

These are the I2C setup and Write commands I am using;
symbol i2c_dac = %10011000 ;DAC address is $98
hi2csetup i2cmaster, i2c_dac, i2cslow, i2cbyte ;DAC setup as slave at $98 address
hi2cout(b10) ;b10 is any input variable 0-256

Everything looks like it should work, so right now I am struggling to determine if am fighting a hardware limitation (DAC) or a code problem.
Thanks in advance for any insights
 

hippy

Senior Member
hi2cout(b10) ;b10 is any input variable 0-256

From the datasheet, "The DAC5571 requires a start condition, a valid I2C address, a control-MSB byte, and an LSB byte for a single update ... The CTRL/MSB byte sets the operational mode of the DAC5571, and the four most significant bits. The DAC5571 then receives the LSB byte containing four least significant data bits followed by four don't care bits".

So you probably want something like ...
Code:
b0 = ? ; 0 to 255
w0 = b0 * 16
HI2cOut (b1,b0)
 

Lt2mc

Member
Hippy, You are the Man!! Thanks ever so much. Does this site have a "Beer Credit" button? If not it needs one. :cool:

After a cut n paste from you, and a little tweaking to fit my code, it works. With one driver (1.3max Vin) i get a resolution of 100, and on the other driver (2.5max Vin) I get a resolution of over 190. Way cool.
let b22 = b10 ;write DAC power to W11
let w11 = b22 * 16 ;Magic??
HI2cOut (b23,b22) ;b22 is any input variable 0-255

BTW, I am thinking now, if I eliminate the lower 20% of the LED Driver input (no visible light), I could bump up my usable resolution even more :unsure: See you all next weekend....
Thanks again
 

hippy

Senior Member
let w11 = b22 * 16 ;Magic??
The internal maths accumulator is 16-bit so when a byte is loaded into that it gets its most significant bits cleared -
Code:
              .-----------.
b22           | hgfe dcba | ---.
              `-----------'    |
    .---------------------.    |
Acc | 0000 0000 hgfe dcba | <--'
    `---------------------'
We then multiply by 16, which is the same as shifting it left 4 bits -
Code:
    .---------------------.
Acc | 0000 hgfe dcba 0000 |
    `---------------------'
That's then stored in w11 and the b23 and b22 bytes automatically get set as required -
Code:
    .-------------------------.
w11 | 0000 hgfe     dcba 0000 |
    `-------------------------'
    .-----------. .-----------.
b23 | 0000 hgfe | | dcba 0000 | b22
    `-----------' `-----------'
 

Lt2mc

Member
Thanks for the detailed explanation. Now what I was reading in the datasheet and manual makes more since, though it's execution is still makes my brain hurt. I have updated the remarks in my code from "Magic??" to "Ingenious!!".
Thanks again
 

wapo54001

Senior Member
I believe I'm getting something like 12-bit resolution using a 28x2, so maybe this information could be useful to you.

I use a 28x2 in a stereo preamplifier to control volume using four LDRs (current through the LEDs). In order to have a very precise control of an approximately 50db (logarithmic) attenuation range. To do that, I have to control all four LDR currents very precisely and logarithmically in a range of 10milliamps (LDR at about 25 ohms) to 10 microamps (25k ohms). I found that a linear 1024 step range would not at all do the resolution for a logarithmic LDR response so am autoswitching between two 1024 ranges and at 10 microamps the control is good to about +/- 1 microamp. I do this by putting the chip into a loop that continuously checks and corrects the current being delivered to each of the four LDRs and corrects the current drive accordingly. For me, the breakthrough came when I stopped trying to control the output current directly. Rather, I use a second pin per LDR to constantly read the current being delivered through the LDR at a resistor between the LDR and ground by reading the voltage drop at the resistor and using that information to change the current through the circuit up or down.

Someone with the right equipment measured the resulting control and said the left and right volumes tracked within .1db, and that's way better than a mechanical volume control. A calibration process involving storing required drive current for a given resistance per LDR allows me to closely align four LDRs which are not preselected for close tolerance with each other. This seems unnecessary for your application.

Using this method I believe I'm getting something on the order of 12 bits of resolution out of the 10 bit 28x2. The high value RC output control (driving a mosfet) is free running, with gate drive drifting up/down as determined by the reading on the resistor many times a second. Given the limitations of the Picaxe chips, I believe that best control is obtained not by directly controlling the output, but rather by reading the result of a given output and making very small corrections to the drive of the current source (a mosfet acts as a resistor in the path of the current).

The basic code to achieve this is available in the completed circuits area, the topic is a variable voltage regulator circuit.

For your application you could skip the 12-bit resolution using two 1024 ranges, just use one range.
 
Top