[solved] piezo element as position control device (improving voltage resolution)


Im trying to apply a DC voltage to a piezoelectric device, with the intent to achieve controlled motion on the nano-scale.

I have a 20v power supply, the piezo disk from a regular buzzer, and an arduino uno.

lets say applying 1v DC to the piezo will cause a 10 nanometer deflection in the crystal. Then the full 20v would allow for a working range of 200nm. Im ok with this, but I'm trying to come up with a way to accurately control voltage steps so that I can have at least 1024 discrete positions. That is, increment the applied voltage by about 20mV, from 0 to 20.

I've been thinking about it but I can't come up with any output method that would give me 1024 possible values.

the best I can come up with is to use the PWM library to change the frequency of the output PWM signal. Doing this I think I could easily output 1024 different square wave signals, each with 50% duty cycle, but different frequencies. then use some kind of tone decoder to convert the output PWM signal to a predetermined DC voltage. But with 1024 possible frequencies, I think I would need some kind of FFT...

Am I making this too complicated? I'm just limited by the 256 possible outputs of analogWrite. is there a way to use more than one analog output pins to get to higher resolutions?

any suggestions would be appreciated!


Use a digital to analogue converter e.g. PCF8591 driving a precision op-amp

The precision op-amp will be needed to convert the voltage 5V range of the PCF8591 to the larger voltage you need



Seems like this chips "analog" output is also 8 bits. allowing for 256 possible steps.

Is this any different from using the uno's 8 bit DAC directly?

AnalogWrite on the normal Arduino chips ATMega328 and ATMega2560 and ATMega32U4 are not a true Analog output

They are just PWM (Pulse width modulation)

You can convert PWM to a voltage using a low pass filter, (external circuit consisting of resistors and capacitors and possibly an op-amp), however the non-linearities of low pass filters make it difficult to convert PWM to an exact DC voltage.

You may be better off using an Arduino Due as it has an internal Digital to Analogue converter, but Due is a 3.3V device and uses a completely different microcontroller to the standard Arduino's and some libraries may not work with the Due

I understand your first reply more clearly now.

So I send the desired output value to a DAC using I2C or SPI communication, allowing any number of possible outputs...i was hung up on how to "tell" the DAC what value to output, but i see now.

Now I just need to find an appropriate 12 bit DAC. something like the MCP4922 looks good since it has multiple channels, though 3 channels would be better for x,y,z motion.

thanks for the advice!