Creating a true analog output with arduino +++

I am looking for a way to create a true analog output with the arduino plus another component. I am reading an analog in, doing some processing to the signal to smooth it, and then writing an analog out. What I am using this for can not accept the PWM signal of the arduino. Even with it cranked up to 32kHz it is still too slow. I have a simple RC filter on it as well. I was thinking that a DAC would be the ticket, but I am not sure how analog of a signal it creates?

Any suggestions..

Thanks,
Ryan

What are the shapes of the input and output waveforms? What is the required throughput?

Right now, my input is from a voltage divider that features a force sensitive resistor. The input is then a variable voltage that is relatively slow. I am trying to slow this down and condition it to an output. I actually have two FSR voltage dividers that I am taking through an algorithm to create the PWM output voltage.

If there is no pressure on either FSR the output is 2.5V. If one is pressed the output drops, if the other is pressed the output increases. The output is being read by another arduino, which from what I have experienced, doesn't really like PWM inputs. So I want to create a true variable voltage analog output. I could live with steps, but I would want a large amount of steps.

I am a mechanical engineer, so this stuff is a bit different for me and I am just learning the arduino. I have been using it for a few months now, but this problem has me stumped.

Thanks in advance for your help,
Ryan

The AD7524 DAC uses what is called an R-2R ladder.

I made one myself using surface mount resistors...

Take a look. http://www2.informatik.hu-berlin.de/~hochmuth/bvp/ad7524.pdf

or here:

From what you've described about your application, it sounds like a DAC will work fine.

If you can tolerate the output going up or down in discrete steps between values at least. The output will not be smooth unless you update it at the same rate that it changes and even so, the smallest change possible between updates will determined by how many bits resolution are available.

For example, a 12-bit DAC will give you a step size of about 1.22 mV for 5V full scale.

Thanks, I think the 12 bit DAC is what I am looking for. Could you recommend one that is simple to use with the arduino. I can treat these the same as a shift register correct? With a shift out to send the information as long as I control the clock and data pins??? I think I know how to use it, but if there is one available that has a tutorial somewhere that would be great....

Thanks again,
Ryan

The AD5321 is a I2C (two-wire) 12bit DAC available for about $8 from DIGIKEY. I've never actually used one, but I2C will seriously cut down on the pins needed to control it.

http://www.arduino.cc/playground/Learning/I2C

Take a look at the MCP4821 from Microchip. It's $2.71 from Digi-Key and has an SPI interface which works pretty much like a shift register. It's also available in an 8-pin DIP which makes it handy to breadboard with.

It's just sort of SPI. It has a chip select, clock and serial-in pin and a load pin so you can pretend it's just a shift register.

Awesome, I think I am going to order a few of the MCP4821's from digikey just because of the price.

Thanks again for all your help,
Ryan

Cool! let us know how they work out for you.

Just a thought, have you tried smoothing your pwm with a capacitor? That would definitely give you an analog voltage, though it would have some fluctuation. You can reduce fluctuation with a higher capacitance, but that would slow the reaction time when you try to change voltages. I haven't done all the math, but you might be able to find a happy medium that will work for you.

Yes, I have been using a capacitor and resistor to smooth the signal. It works alright, but I need the response time, so the smoother the signal, the slower with the RC filter.

Thanks for the input, I'll let you know when I get the DAC how it works.

Well I got my DACs in and I am trying to write to them using the shiftout command and I am getting no response. I have the latch, clock and data pins setup appropriately (atleast what works with the shift register).

I am currently not using the SHDN (shutdown on active low) or LDAC (not really sure what this does).

I think I may have to treat this more like SPI because of needing 16 bits of data out to setup the DAC appropriately (first 4 bits at setup, last 12 are the Vout value).

Could someone point me to a place to look for some help with this!!! I am a little lost! (Stupid me thought it would be easy).

So here is what I have come up with. I am shifting out the 0010 first to setup the DAC
0 - output A
0 - don't care
1 - gain select of 1x
0 shut down disabled

Now my problem is with my second shiftout of my DAC value. I can get it to cycle between zero and a max of 0.258 V right now. Any idea why it won't go to the full 5V?

Thanks,
Ryan

int CS = 2;
int SCK = 3;
int SDI = 4;
int LDAC = 5;

void setup(){

// Setup input and output modes
pinMode(CS, OUTPUT);
pinMode(SCK, OUTPUT);
pinMode(SDI, OUTPUT);
pinMode(LDAC, OUTPUT);
digitalWrite(CS, HIGH);
digitalWrite(LDAC, HIGH);

}

void loop(){
digitalWrite(CS, LOW);
digitalWrite(LDAC, HIGH);
shiftOut(SDI, SCK, LSBFIRST, 0010);
shiftOut(SDI, SCK, LSBFIRST, 4095);
digitalWrite(CS, HIGH);
digitalWrite(LDAC, LOW);
digitalWrite(LDAC, HIGH);

delay(1000);

digitalWrite(CS, LOW);
digitalWrite(LDAC, HIGH);
shiftOut(SDI, SCK, LSBFIRST, 0010);
shiftOut(SDI, SCK, LSBFIRST, 0);
digitalWrite(CS, HIGH);
digitalWrite(LDAC, LOW);
digitalWrite(LDAC, HIGH);

delay(1000);

}

Look at the SPI EEPROM examples. I'm not sure if shiftout uses the Atmega168s SPI register but that will make your life easier. (I think)

Here's a playground article on it. The little spi_transfer function is handy

If you're not on a battery you can tie /SHDN high. Ditto with with /LDAC. The output will be transfered on the rising edge of /CS if you do this (manual pg 14).

shiftout reference says your value is a byte, so you're only sending 255 (or whatever 4025%256 is) in the first part

I think you need to go
shiftout(SDI, SCK, LSB, (byte)(value>>8));
shiftout(SDI, SCK, LSB, value);

or combine the set parameters with your data bitwise

so
upper_half = 0b0010|(0b00001111&value)
lower_half = value

lower_half will be truncated to 8 bits by the shiftout function