DAC using arduino and 1 resistor
remember those software selectable weak (20k) pull-ups on the input pins of the Arduino ?
It occurred to me that those can be used as a programmable voltage divider: configuring a few ports with pull-up in parallel lowers the overall value of that resistance. if you want less pins (and thus 20k resistors) parallel, put the surplus of input pins into high-impedance mode.
now you can create voltages between 0 and "a bit under your board's supply voltage". These voltages are measured over the external resistor.
here is the general table of values, assuming 20k pull-ups and a 20k resistor to ground [table] 0 pins pull up -> 0 volts 1 pin pullup -> 1/2 of Vcc 2 pin pullup -> 2/3 of Vcc 3 pin pullup -> 3/4 of Vcc 4 pin pullup -> 4/5 of Vcc I'm sure you see the pattern by now [/table]
when increasing and then decreasing the number of pull-ups you get a nice positive half-sinus with these values.
You can play with the value of the external resistor to get the voltages you might want.
Naturally you can also use these pull-ups as part of an ordinary R-2R resistor ladder, but check if all your pull-up resistors have equal value. The data sheet says minimum = 20kOhm and maximum = 50kOhm, so there is quite a bit of spread...
you can use your Arduino ADC in order to measure the actual voltages. since there are several ways to (e.g.) pick 2 pullups from 4 pins you can select the combination of pins that give the most accurate/desirable value.
I have cobbled together a concept sketch and a sketch to try out maximum attainable frequency. I reached 500 kHz with the fast version. However, the amplitude of that signal was only half a volt. the shape of the sinus was very smooth and symmetrical.
The slower concept sketch did about 110 kHz, having an amplitude of 2 volts on my 16 MHz Duamilanuove. it was a bit more jagged. When lowering the frequency the signal becomes the sequence of stepped half-sines again.
so, this is a nice way to implement high frequency sine generator. at lower frequency you will have to smooth (filter) the sequence of stepped half-sines into something more resembling a true and smooth sine, I guess.
if only ATMEL had provided a choice between pull-up and pull-down; then a full sine could be generated. If anybody knows a trick to flip the signal upside down in order to complete the negative part of the sine, I'm most interested. I tried hooking the ground of the scope onto an OUTPUT pin, hoping to create a negative voltage that way, but that did not do the trick.
This signal generator depends on the current the INPUT pins will PROVIDE. that is not a lot, since input pins expect to sink current. So, the signal should not be loaded by whatever you send the signal into. You WILL need some amplifier or at least something to deliver the signal at less output impedance. a FET or OpAmp should do the trick.
Still, not bad for a single resistor...
Regards, Ronald van Aalst
Ps, this might be old hat to you, but I have never seen the input pullups used this way. On the other hand, most things have already been tried, so let me know if you saw a comparable trick somewhere.