Giovanni
Carrera rev. 20/10/15
The aim of this work is to convert the unipolar AD and DA converters of Arduino
Due into bipolar with appropriate circuits. Bipolar analog inputs and outputs are required
in those cases in which the signals can take on also negative values; they have
as reference a more stable zero voltage or ground and not the half of the
supply voltage or something like that.
With the use of the proposed circuits, an Arduino Due system can be
easily employed in replacing an analog PID type controller, with greater potentiality
and flexibility. Acquisition systems, low frequency oscilloscopes or spectrum
analyzers and waveform generators are examples of additional applications.
ADC
input bipolar
We begin to see how to convert a unipolar analog input into bipolar. A simple
voltage divider, such as that illustrated in Figure 1, does this job well. Using the Ohm’s law we can easily obtain the
following formulas:
Assuming that the output current is zero, the
current through R1 and R2 will be that shown in the formula (1). In these
conditions, the output voltage Vo is that of the formula (2).
Suppose you want an input voltage V2
of ± 3.3V which should correspond to 0 and 3.3 V of output voltage. It can be shown that this statement is
satisfied if you put V1 equal to 3.3 V. By the formula (2), in fact, we have
that if V2 = -3.3 V, V0 = 0 only if R1 = R2 and in the case where V2 = +3.3 V, V0 =
3.3 V. So that the circuit meets our conditions if we
set V1 = + 3.3V = Vref, V2 = Vi (bipolar input) and R1 = R2. In order to get closer to the theoretical model
of the divider we must use an operational amplifier with high input impedance
and unity gain, like the one shown in Figure 2.
This type of operational amplifier can also work
with single power supply up to output voltage close to zero, although starts
to saturate to about 1 .5 V below the supply voltage, namely + 3.5V in our
case. This non-linearity becomes a merit because we want to limit the input of
the ADC. The voltage on input pins with respect to ground, as we can see on CPU
datasheet, must be in the range: -0.3V to +4.0 V, otherwise a permanent damage
can happen. For additional safety, a resistor of 100 Ω was also added in
series to the output, as shown in Figure 7.
DAC output became bipolar
To produce a bipolar signal is used a
non-inverting operational amplifier connected in a particular way, as shown in
Figure 3, i.e. with an offset Vr on the inverting input. In fact, a
non-inverting amplifier has the end of R1 connected to ground and, in the case
R1 = R2, has a gain G = 2.
The theory says that we can’t generate negative
signals without a negative generator, so this op amp requires also a
complementary negative supply.
Applying the theoretical model of the
operational amplifiers is obtained the following relation:
Vo
= Vi – I*R2 = Vi*(1 + K) – K*Vr
Where K = R2 /R1. Our conditions are as follows: if Vi = 0 than Vo = -Vr = -3.3 V and if Vi = + 3.3V than
Vo = Vr = +3.3 V. They are satisfied only if K = 1, that is, with equal
resistors that give a gain G = 2.
The
Arduino Due DAC
Arduino Due does not have an analog output
voltage from 0 V to Vref, this topic has
been widely discussed in my post “How
to modify analog output range of Arduino Due”. The circuit of figure 5, with a
gain equal to G = 3.3/2.2 = 1.5, reaches the desired output range from 0 to
3.3V.
Anti-aliasing filter
A useful thing is to put to the input a low-pass
filter to prevent noise aliasing which may arise if the input signal is not
band-limited. In figure 6 we can see the scheme of an active low-pass
Sallen-Key filter, second order and unity gain and the formula to calculate its cut-off
frequency.
In figure 7 we see the complete circuit scheme,
from left to right we can see: the low-pass filter (R1, R2, C1, C2 and U2B),
the bipolar to unipolar input circuit (R3, Rp1, R4 and U1A) , the differential
amplifier (R8, R9, R10, R11, R6, Rp2, R7 and U1B), the unipolar to bipolar
output circuit and the negative power supply (C7, C6 and U3).
The low pass filter, with the values shown in
the diagram has a cut-off frequency of approximately 220 Hz. The capacitor C1 =
2*C2 is realized with two parallel capacitors, everyone with the capacity equal
to C2.
The trimmer Rp1 must be adjusted to obtain on
the U1A output a voltage equal to Vref/2 = 1.65V with zero input. The typical
value of Arduino Due Vref is 3.3 V, but should be
measured with a precise DVM.
To calibrate the trimmer Rp2, it is necessary
to output to the DAC the minimum value, that is zero, and act on Rp2 until
bringing to a minimum the output voltage of U1B. These operational, powered
with single power supply, fail to give a zero output true, but there are very
close (a few mV).
Using battery power, the simpler and more
economical solution to generate the negative voltage of -5 V is to use an
ICL7660 which is a DC/DC charge pump converter. It has the advantage of
requiring only a pair of electrolytic capacitors, but has as a disadvantage
that the output voltage is not controlled and is reduced by increasing the
current. In our case, the dual op amp LM358, in addition to the advantages
already described, have also low power consumption.
The practical realization
In Figure 8 you can see the prototype realized
on a breadboard card.
The filters require passive components of good
precision, a tolerance of ± 1% is readily available for resistors but the
capacitors have tolerances around 10-20%, so they should be selected using a
capacitance meter.
The tests
Test of input circuits
In addition to the theory, necessary for the
development of a project, it is often required to make even the experimental
tests. Static measurements carried out on the prototype, with the purpose of
seeing his behaviour at the limits of the input/output range, have given very
interesting results.
For test purposes, I wrote a dedicated program
(see the software section), which is used also to calibrate the analog output. The
supply voltages measured on my system are: Vref = 3.310, V+5 = 5.032 and V-5 =
-4.975 volts.
The first tests have been quite disastrous in
regard to voltage values below one volts output I saw numbers that varied
greatly and randomly. From a search on the Internet, I discovered that the
problem was caused by the IDE Arduino (version 1.5.3), which had bugs in their
function analogRead () for Arduino Due. I recompiled my program with the latest
version 'nightly' and, fortunately,
things are back to normal.
Overcome the drawbacks mentioned, the results
of the linear regression were very good with a correlation of 0.9999981. With
the calibration results, we can convert the number N output from the converter:
Vi = N* 0.001609
– 3.3097 (3)
This is
precisely the formula to be used in the program to obtain the input voltage
expressed in volts. With it one can easily derive the actual input range that
goes from -3.310 V (N = 0) to 3.278 V (N = 4095). To make these calculations I
used Excel, but that's okay any spreadsheet or least squares program.
Tests of
output circuits
With a Vref = 3.31 V, and the power supply of 5.032
V, I measured a minimum voltage output by the DAC of 0.553 V and a maximum of
2,766 V, values very close to 1/6 and 5/6 of the Vref.
The measures on my Arduino Due of the output
circuits formed by the differential amplifier U1B, and the unipolar to bipolar
converter U2a also gave very good results with a correlation of 0.9999998. With the calibration results, we can
get the number to be
sent to the DAC to obtain the output voltage Vo:
N = INT(Vo*623.0613 + 2053.7584) (4)
Obviously the formulas (3) and (4) are valid
for my system and are obtained with the calibration measurements.
At the software level we must treat
the signals to be sent to the DAC or to be read by the ADC as 12 bits unsigned integers,
with a minimum of zero, corresponding to -Vo and a maximum of 212-1
= 4095, corresponding to +Vo. The ideal zero volts will be equal to 2048. In
essence, we have to work on integers: from -2048 (-Vo) to +2047 (+ Vo) and add
2048 before sending them to DAC or subtract 2,048 readings of ADC. If we want
to be more precise it is necessary to use the formulas (3) and (4) obtained by
linear regression of a number of measures that, in my case, ranged from 7 for
the DAC to 10-16 for ADC.
The
software
For tests on Arduino Due AD and DA converters,
I wrote a simple program that sends to the DAC0 values of N according to the table:
{0,512,1024,2048,3072,3584,4095}. They are generated in succession, each time we
press the button SSbutton connected to pin 32. At the same time are printed on
the LCD display of my system both the number sent to the DAC, both the number
read from the ADC on the channel A0. In the absence of the display, with minor
changes to the program, these data can be printed on the monitor of the Arduino
IDE via serial communication.
Bibliography
- "Active Low-Pass Filter Design”, Texas Instruments application Report SLOA049B - September 2002
- “Atmel ARM Cortex-M3 Product Family (SAM3)”, Atmel application note 42187A−SAM−10/2013