2. ii
Abstract
For this project we explored analog processing in an attempt to help the University of
Illinois’ Physics department perform power calculations in their optic labs. These labs perform
measurements using two monitoring sensors: a reference sensor and a test sensor. Calculations
are performed to measure the difference between them. In order to improve this process they
were looking to obtain a device that could complete these calculations accurately and
instantaneously. Our goal was to design a lab device that would take two inputs from both meters
and perform an analog division to represent the power ratio between the signals. This would
involve incorporating our design to work with the labs power meters and photon detectors and
then constructing analog circuitry to work with each signal. To complete the process a digital
processing design was then implemented to log the data through software, create a user interface,
and control a display for the system.
Through our design process we found that it was ideal to increase the role of software in
the design’s computations. It was also determined that due to the process by which photons occur
on the detector, our filter design would not extrapolate a representation of power with enough
accuracy for lab use. However, considering only the power meter aspect of our design, our
results proved this device is accurate enough to be used by the lab. Optimizing components and
improving the design of this instrument will further increase the accuracy by dropping the noise
level.
3. iii
Table of Contents
1. Introduction ..................................................................................................................................................1
1.1 Statement of Purpose.................................................................................................................................1
1.2 Functionality..............................................................................................................................................1
1.3 Block Descriptions ....................................................................................................................................1
2. Design ............................................................................................................................................................3
2.1 High Level Block Diagram and Software Flow Chart ..............................................................................3
2.2 Design Specifications................................................................................................................................4
2.2.1 Division Circuit ………………………………………………………………………………4
2.2.2 Filter Circuit………………………………………………………………………..…………6
2.2.3 Power Supply…………………………………………………………………………………8
2.2.4 Microcontroller…………………………………………………………………….…………9
2.2.5 24-Bit ADC……………………………………………………………………………….....10
2.2.6 Display………………………………………………………………………………………10
2.2.7 User Interface…………………………………………………………..……………………11
2.2.8 Memory……………………………………………………………………………………...11
3. Verification ................................................................................................................................................12
3.1 Analog Processing...................................................................................................................................12
3.2 Digital Processing....................................................................................................................................14
3.3 Tolerance Analysis..................................................................................................................................15
4. Cost Analysis................................................................................................................................................17
4.1 Labor .......................................................................................................................................................17
4.2 Parts.........................................................................................................................................................17
4.3 Total Cost................................................................................................................................................17
5. Conclusion....................................................................................................................................................18
3.1 Accomplishments ....................................................................................................................................18
3.2 Ethical Considerations.............................................................................................................................18
3.3 Future Work ............................................................................................................................................18
6. References ....................................................................................................................................................20
7. Appendices...................................................................................................................................................21
Appendix A – Requirements and Verification Table ....................................................................................21
Appendix B - Schematics..............................................................................................................................24
Appendix C – Source Code...........................................................................................................................27
4. 1
1. Introduction
1.1 Statement of Purpose
The University of Illinois physics department has an optics laboratory which performs
tests to determine the transmittance of different materials. The lab technicians currently perform
two separate measurements: a reference measurement from a light source transmitted only
through air, and a second measurement on light sent through, or reflected off, a tested material.
Both light beams come from the same source and are directed to the meter by a beam splitter.
Tedious hand calculations are necessary to then compare the two measurements. Also,
momentary changes in the optical source's strength can deter accurate results. Our project aimed
to solve these problems by designing an instrument that performs these measurements
automatically using the output of each power meter and photon detector. This eliminates the
necessity for awkward and possibly erroneous hand calculations, as well as accounts for small
errors through the instruments ability to perform these measurements in real-time.
This project has valuable use in the optics lab as it will eliminate hand calculations
entirely, allowing less steps to be involved in this calculation process. The software in the design
can also account for unexpected outliers due to power fluctuations. More importantly, this
project will provide a one-step process to output data onto a computer providing the ability to
plot the data on graphing software. This, along with averaging done inside the device, will
provide a strong representation of the dataset in an efficient, accurate, and convenient manner.
1.2 Functionality
The functionality of this project revolves around two major systems: digital processing
and analog processing. The analog processing was designed to incorporate signals from power
meters and photon detectors that are already existing in the labs. Output signals from the power
meters are fed into an analog division circuit that provides the power ratio used in this design. To
accommodate the photon detector output a separate filter circuit is required before entering the
division circuit. A switch is used to route each output signal through its respective process.
Digital processing involved digital conversion and a software element. The division
circuit output is converted to digital form through the use of an analog to digital converter
(ADC), which then relays the value to a microcontroller. This data is then processed by a
microcontroller that handles additional computations for the data. This microcontroller also acts
as the central unit for display, memory, and user interface communications. It provides the basis
to control the display, creates a navigable interface, and outputs results onto an SD card for data
logging purposes.
1.3 Block Descriptions
Power Meters: These meters output a 0-2 Volt signal that scales with the intensity of light
measured. This design was modeled after the Physic lab’s more common meter, the PM100D. A
BNC connector is used to connect to the analog output of the detector and integrate with our
design. These power meters are required to be used at both the source and reference
measurements for the device.
5. 2
Photon Detector: The Physics labs most common photon detector is the id100 series
manufactured by IDQ technologies. This detectors output is a SMB female jack that provides a
10 ns DC pulse every time a photon is detected at a maximum rate of 5 GHz. A 50 ohm load is
expected at its output. The device’s operation in our circuit will be to produce a value
representing photons/second using the frequency of incoming pulses as a basis for the
measurement.
Filter: The use of a low pass filter allows the easy conversion of the pulse output of the photon
detector into a nearly constant DC voltage. This low pass filter is of order 3 and easily realizable
with a few discrete passive components and the TL072CDR IC.
Division Circuit: This circuit performs the division of the source and target detector outputs.
The circuit was implemented using analog signals and performs the division function through a
series of op-amps. 0-2V DC inputs are provided from the external power meters and/or the
photon counter filter circuits, and the output is a 0-3.5V DC signal, representing the ratio of the
two input signals on a logarithmic scale. The output is sent to an Analog-to-Digital conversion
circuit to be used by the microcontroller.
Power Supply: The purpose of the power supply circuit is to convert 120V AC into the
necessary DC power levels required for the design. The output voltage levels should be
consistent from no load to full load, with minimal ripple and noise.
Switches: The purpose of the input switches is to select between the power meters and photon
detector filter circuits, depending on which is being used during testing. This allows for any
combination of Power Meters and Photon Counter to be used.
Microcontroller: The microcontroller is the main source of control. It handles all
communication between the memory, display, ADC, and user interface. Its functionality consists
of system initialization, data sampling, memory output, and data display. The controller
interfaces with the ADC to sample the result of the division circuit. The microcontroller used for
this project is an Arduino Uno R3. It is powered by a 12V supply and operated at a clock rate of
16MHz. [1]
Display: There are two primary functions of the display. First and foremost it displays a
navigable user interface to show system flow. Secondly, it displays real-time results of the
measured power ratio. It has programmable windows to change system settings, delete memory,
calibrate, and begin data sampling.
User Interface: The user interface allows the user to navigate and control display menus and
options. This interface controls the system flow. The microcontroller waits on each key press in
order to determine its next operation. The method of communication is I2
C. Button functionality
will be dependent on the current submenu the system is in. [2]
6. 3
2. Design
2.1 High Level Block Diagram and Software Flow Chart
Detector
Switch
LEGEND
Measurement
Instrumentation
Digital
Processing
Analog
Processing
Power
Supply
Analog Filter
Circuit
Detector
Switch
Division
Circuit
Analog Filter
Circuit
Power
Meter
Power
Meter
Photon
Detector
Photon
Detector
Microcontroller
Memory
Display &
User
Interface
Figure 1: High level block diagram
Set
Sample Rate
Set
Display Rate
Memory
Deletion
Calibration
Begin
Measurements
Figure 2: Software Flow Chart
7. 4
2.2 Design Specifications
2.2.1 Division Circuit
Figure 3: Division Circuit
The division circuit design is shown above in Figure 3. It can be broken down into three
smaller stages: 1st, the input switches; 2nd
, the logarithmic amplifiers; and 3rd, a differential
amplifier. The desired output from the overall circuit is a logarithmic representation of the ratio
between the two input voltages. The 1st
stage consists of the input selector switches.
Figure 4: Logarithmic Amplifier
In the 2nd
stage, two logarithmic amplifiers are used to convert the input signals to a logarithmic
representation, shown above in Figure 4. The non-inverting terminal of the op-amp is held at
ground, and using ideal op-amp calculations, the inverting terminal will also be at ground.
Therefore, the current through the input resistor will be equal to the current through the diode.
Equation (2.1) shows this relationship.
𝐼 𝐷 = 𝐼𝐼𝑁 =
𝑉 𝐼𝑁
𝑅
(Equation 2.1)
8. 5
The current through the diode is also represented by the ideal diode equation [3]
, shown in
Equation (2.2).
𝐼 𝐷 = 𝐼𝑆 (𝑒
(
𝑉 𝐷
𝑉 𝑇
)
− 1) (Equation 2.2)
Using Kirchhoff’s Voltage Law, the output voltage (VOUT) is equal to the inverse of the
diode voltage (VD). Combining the previous two equations below in Equation (2.3) the output
voltage is proportional to the natural log of the input voltage. It is scaled by the input resistance
(R), the saturation current of the diode (IS), and the thermal voltage of the diode (VT).
𝑉𝑂𝑈𝑇 = −𝑉𝐷 = −𝑉𝑇 ln (
𝑉 𝐼𝑁
𝐼 𝑆 𝑅
) (Equation 2.3)
Figure 5: Differential Amplifier
In the 3rd
stage, the two logarithmic signals from the previous stage are provided to a
differential amplifier via the resistors shown in Figure 5. The output can be calculated by
superposition. First, with V1 providing an input, and V2 at zero.
𝑉1 − 𝑉−
𝑅3
=
𝑉− − 𝑉𝑂𝑈𝑇
𝑅4
Because V2 = 0V, V+ and V- are also 0V. Therefore, the equation becomes simplified.
𝑉1
𝑅3
= −
𝑉 𝑂𝑈𝑇
𝑅4
Solving for Vout gives the following relationship of Equation (2.4):
𝑉𝑜𝑢𝑡 = −𝑉1(
𝑅4
𝑅3
) (Equation 2.4)
Now, performing the same analysis with V2 as the input, and V1 at zero:
𝑉− = 𝑉+ = 𝑉2(
𝑅6
𝑅5 + 𝑅6
)
9. 6
And the second equation becomes:
𝑉𝑂𝑈𝑇 − 𝑉−
𝑅4
=
𝑉−
𝑅3
Combining the two equations, and solving for Vout:
𝑉𝑜𝑢𝑡 = 𝑉2 (
𝑅6
𝑅5 + 𝑅6
) (
𝑅3 + 𝑅4
𝑅3
)
Selecting resistors R3 = R5, and R4 = R6, this simplifies to Equation (2.5):
𝑉𝑜𝑢𝑡 = 𝑉2(
𝑅4
𝑅3
) (Equation 2.5)
Finally, by superposition, Vout will be the sum of the Equations (2.4) and (2.5), into
Equation (2.6):
𝑉𝑂𝑢𝑡 = 𝑉2 (
𝑅4
𝑅3
) − 𝑉1 (
𝑅4
𝑅3
) = (𝑉2 − 𝑉1) (
𝑅4
𝑅3
) (Equation 2.6)
Finally, substituting the equations from the logarithmic amplifier stages (Equation (2.3)), into
Equation (2.6) the result for the division circuit becomes that shown below in Equation (2.7):
𝑉𝑂𝑢𝑡 = (−𝑉𝑇 ln (
𝑉1
𝐼𝑆 𝑅
) − −𝑉𝑇 ln (
𝑉2
𝐼𝑆 𝑅
)) (
𝑅4
𝑅3
) = −𝑉𝑇 (
𝑅4
𝑅3
) (ln (
𝑉1
𝐼𝑆 𝑅
) − ln (
𝑉2
𝐼𝑆 𝑅
)) = −𝑉𝑇 (
𝑅4
𝑅3
) l n (
𝑉1
𝑉2
)
𝑽 𝒐𝒖𝒕 = 𝑽 𝑻 (
𝑹 𝟒
𝑹 𝟑
) 𝐥 𝐧 (
𝑽 𝟐
𝑽 𝟏
) (Equation 2.7)
Because the natural log of V2/V1 approaches infinity as V1 approaches zero, the proper
resistance ratio for R4/R3 could not be obtained through simple mathematical calculation. Instead
it was obtained through pSpice simulations, with a ratio of 10.125/1 giving a maximum of 5V
output when V1 approached zero. During actual testing it was found that to prevent damage to
the ADC circuit, a regular diode and a Zener diode were necessary to clip the output voltage at -
0.3V and 3.5V, respectively.
The final output of the division circuit is the desired ratio of the two input signals in
logarithmic form, and scaled by the biasing resistors and diode thermal voltage. This logarithmic
ratio will be converted back to linear ratio by the microprocessor.
2.2.2 Filter Circuit
The simplest way to convert the output of the photon detector to a signal that is usable in
the division circuit is to use a low pass filter between the detector and the division circuit.
Alternatively, a counter could have been used to achieve this conversion. Using a counter would
have involved recording the number of photons detected per unit time. The counter would need
to be reset often and would be prone to overflow and missed detections. Keeping in mind the
faults of the counter design the decision was made to do the conversion with a low pass filter.
The filter will convert a pulse signal coming from the photon detector into a 0-2 VDC signal
which can be used by the division circuit. This method allows the end user to mix types of
detectors. Figure 6 shows the top level block diagram of the filter circuitry.
10. 7
Figure 6: Top Level Filter Block diagram
The first step of the filter design process is to prove that a low pass filter can fulfill the
role needed. In simulation software, generating an input to a low pass Butterworth filter with a
passband frequency of 500 kHz, the output is shown in the circuit diagram in Figure 7. This filter
is not a realistic filter as it is of order 14 and has a cutoff frequency which is too high. The
physics department requested a response range of 100 Hz to 5 MHz. Regardless, it is important
to show here how varying frequency content at the input of the filter effects its output, shown in
figure 7. This data shows that varying photon detection rate will produce linearly varying output
voltages.
From the output of the simulation, it can be shown that the output voltage stabilizes
within 8 microseconds. This is an acceptable rate because our ADC, at the microcontroller, will
sample this output on the order of a thousand samples per second. This sampling rate is well
below the stabilization rate and thus there is little chance of a sample being taken before the
output has stabilized.
Decreasing photon detection rate gives a decreasing output voltage. In this case, when
the frequency of incoming pulses goes below the cutoff frequency of the filter, the entire signal
is effectively passed through the filter and the output becomes unusable. Increasing photon
detection rate gives increasing output voltage.
Another important consideration is the cutoff frequency of the low pass filter. A filter
with a lower cutoff frequency gives an output which is less smooth in the passband and stabilizes
more slowly. A filter with a higher cutoff frequency gives an output which stabilizes more
quickly and is smoother in the passband. A good cutoff frequency for the detection levels needed
is 10 kHz. This cutoff frequency gives a stabilization time less than the sampling interval and a
flat passband.
Next, it was necessary to prove the filter circuit response was linear. At the maximum
output of the photon counter the output of the filter circuit needed to be 2 volts. Also, it was
necessary to show that at the minimum output of the photon counter, which in this case was
limited by the cutoff frequency of the filter, 10 kHz, the output of the filter was near zero. Then,
at a few points between the extremes the output of the filter circuit was shown to be linear.
11. 8
Finally, the filter was translated to a printed circuit board for assembly. The board
required two instances of the filter circuit. The filter required a dual op amp chip, the
TL072CDR, a few inductors, resistors, and capacitors.
The final filter design is a low pass Butterworth filter of order three. The component
values were determined via table lookup for a Butterworth low pass prototype filter. Cutoff
frequency was determined to be 10 kHz. Component values are shown as in the figure 7.
Figure 7: Filter Diagram with Component Values
2.2.3 Power Supply
The devices powered by this supply include: the Arduino microprocessor with associated
LCD display and operational amplifiers in both the division and filter circuits. The power
requirements for these devices are shown below in Table 1. To meet the requirements for all
devices and power levels, a supply capable of providing +/- 12V DC, at 6 watts was used.
Table 1: Power Requirements
Device Voltage
Required (V)
Max. Current
(mA)Note 1
Voltage Required
(V)
Max. Current (mA)Note
1
Arduino
Microprocessor
and LCD
Display
+9 to +12 VDC
~80 mA for Arduino
~100 mA @ 5V for
LCD display
-- --
Division
Circuit
Amplifiers (x3)
+5 to +18 VDC 4 mA each -5 to -18 VDC 4 mA each
Note 1: Maximum Currents are approximate based on datasheets and catalogues, with an added 15% for
safety margin
12. 9
Shown below in Figure 16 is the power supply design. It consists of a 6W self-contained
PWM switching power supply. [4]
A 1 amp slow blow fuse is used on the input to provide fault
protection. The 12uF capacitors (C3 and C4) provide an extra level of filtering to reduce output
voltage ripple, while the smaller 0.024uF capacitors (C1 and C2) are placed near the power
converter outputs for decoupling purposes.
Figure 8: Power Supply Circuit
2.2.4 Microcontroller
The microcontroller was programmed using the Arduino integrated development
environment (IDE) which is a set of C/C++ functions. [1]
In order to save processing power,
operations that are easily programmed through direct interaction with on-board components were
utilized instead. Programming entailed acknowledgement of user interface signals and respective
decision making based on the systems current state. Additionally, the microcontroller was used
to add a software conversion to our results and to computer the final power ratio output. Two
different types of communication were required to transmit data between the microcontroller and
its units: SPI and I2
C. User interface and display use the I2
C bus, and the SD card (memory) and
ADC use the SPI bus.
The design involved programming the microcontroller to communicate with all of these
devices, sometimes simultaneously. This required optimization of the code to perform with
minimal delays. Due to the two different communications, three clock cycles had to be accounted
for in the programming architecture. Both SPI and I2
C operate at separate clock cycles, and the
microcontroller at another clock cycle. For the Arduino Uno, SPI operates at 4 MHz, I2
C at 400
kHz, and the ATMEGA328 processor at 16 MHz. With a much higher clock rate on the
processor, the design required critically timed delays to avoid overlapping data transmission on
either bus.
The microcontroller processes the data that is passed from the ADC. By design, the
microcontroller uses software to create the functionality of an anti-logarithmic amplifier. The
reasoning behind not implementing a hardware amplifier was the operating ranges for diodes and
transistors. Due to our differential op amp acting as a divider, the operating range does not fit the
corner cases well enough to accurately translate the value to software. In order to compensate for
this, the microcontroller reads data from the ADC, scales it up to normal exponential value, and
performs an inverse-logarithm to the voltage. This equation is created by the curve-fitting
technique discussed on page 12.
13. 10
Equation (2.8) shows the methodology behind the process where Vin represents the value
from the ADC. Here A and B represent scaling factors on the equation to produce the desired
output based on the exponential curve. To produce a positive result a negative exponent is
required. This is not done in hardware due to the fact that the ADC can be destroyed by very
small negative voltages.
𝑅𝑎𝑡𝑖𝑜 ≡
𝐼2
′
𝐼1′
= 𝐴𝑒−(𝑉𝑖𝑛∗𝐵)
(Eq. 2.8)
2.2.5 24-Bit ADC
The ADC used in this system is the LTC2440. It is a 24-bit, high resolution, low noise
converter. This was needed to meet the lab requirement of 6 significant figures per data sample.
The Arduino Uno’s onboard ADC is only 10 bits of resolution and was therefore unusable. The
converter has programmable sampling speeds that the user can choose from. A key characteristic
however is that the higher sampling rate, the less accuracy in the data resolution. [5]
It operates at
a voltage between Vcc+0.3V and -0.3V. [6]
These voltage limits are established by wiring the
ADC as seen in Figure 15. We used the 5V supply from the Arduino for Vcc in this design. This
converter is very prone to burning out by overloading its voltage range. [7]
To prevent this, input
to the ADC is limited by a shunt diode to prevent negative voltage and a clipping diode to
prevent excessive positive voltage. Figure 10 shows how this is implemented. [6]
Figure 9: 24 bit ADC Circuit [3]
Figure 10: DC Circuit
2.2.6 Display
The display provides the user menus for each of the blocks in Figure 2. The user knows
what state the system is in based on the LCD screen’s current menu. Certain functionality of the
user interface is enabled and disabled depending on each submenu. The design involved
programming each submenu listed below to perform its respective operation.
Settings Menu: The settings menu offers two functions. The first is to choose the
sampling rate of the memory unit. The second is to choose the update rate on the display.
Once in submenu, options to scale each sampling rate are available via the user interface.
Clear Memory Menu: Overwrites the entire SD card to allow for a new and clean set of
data.
14. 11
Calibration Menu: The calibration menu waits on the user to press select. Its
functionality involves running the system for 10 seconds to stabilize the measurements
and averaging them together to get a value that is stored in the Arduino’s EEPROM.
Begin Measurement Menu: This submenu is the main programming design for this
system. It simultaneously works with the ADC, SD card, and display. The functionality
involves reading the ADC, performing the software conversion on the data, dividing by
the calibration value, and then outputting the result to both the display and memory at
their respective rates.
2.2.7 User Interface
Powered by the Arduino, the user interface provides the input to the microcontroller. It
has four directional buttons that can be programmed. Each button is active based on the systems
current submenu. Functionality for each button is as follows:
Scroll Left / Scroll Right: While in setting menus, these
scroll between the different sampling and display rates
Scroll up: Active in every menu except when beginning
measurements. This allows the user to revert to previous
menus and change selections. Figure 11: Keypad
Select: Active in every menu. Provides the ability to scroll down by selecting each menus
options and verifying it with the microcontroller.
2.2.8 Memory
The memory unit is a micro SD adapter for the Arduino made by Adafruit. It interfaces
with both FAT16 and FAT32 formatted cards. The board is powered directly through the
Arduino’s 5V on-board power supply. The memory is used to write every sample to a data file so
it can be averaged or plotted by graphing software.
This project requires storage over long sampling intervals. In order to estimate the ideal
operating time for this device a simple calculation is performed. Multiplying the memory per
sample by samples per unit time gives us memory per second. To estimate our storage capacity
in terms of time our SD memory was divided by this value. This calculation can be seen in
Equation (2.9).
(Eq. 2.9)
The maximum data transmission rates for this system would be a sampling rate of 4000 samples
per second with 4 bytes per sample. Using an 8GB SD card, max storage time is estimated
around 104.17 hours which absolves any worries about memory storage in this design.
Scroll
Up
Scroll
Left
Scroll
Right
Select
15. 12
3. Verification
3.1 Analog Processing
Division Circuit
After assembly, it was found during testing that while the output did represent a
logarithmic ratio of the two input signals, losses in the circuit preventing the output from being
the exact desired logarithmic ratio represented in Equation (2.7). However, testing various input
signals showed that the functionality of the circuit was accurate when compared to the different
test points. It was determined that the correction for the errors present would be completed
during software conversion.
Inverse Logarithmic Function
The logarithmic ratio that was originally provided to the microprocessor needs to be
converted back to a linear ratio of the two input signals. The original design was to perform this
function via an analog anti-logarithmic amplifier. This design was not working properly during
simulation when dealing with corner cases, so this design was thrown out.
The new design to convert the logarithmic ratio to a linear ratio involves empirical data
analysis and software conversion. After the division circuit was assembled, the division circuit
output was recorded at various input voltages. Over 100 data points were obtained, and the
output was compared to the mathematically calculated ratio of the two inputs. The resulting plot
is shown below in Figure 12. Using the software program CurveExpert, the equation of best fit
was obtained from this empirical data to convert the logarithmic ratio back to a linear
mathematical ratio.
Figure 12: Empirical Data
16. 13
The equation that fit this curve is shown below in Equation (3.1).
𝑅𝑎𝑡𝑖𝑜 = 0.91397 ∗ 𝑒−3.755399∗(𝐷𝑖𝑣𝑖𝑠𝑖𝑜𝑛 𝐶𝐼𝑟𝑐𝑢𝑖𝑡 𝑂𝑢𝑡𝑝𝑢𝑡)
(Equation 3.1)
Filter
In order to verify the functionality of the filter it was necessary to provide realistic inputs
to the filter and verify outputs are within the needed range. The verification was performed on
both filters. The maximum photon detection rate corresponds to a 10-ns 2 V pulse at 5 MHz.
This is the input which is required to produce a two volt output. The filter produced a 1.97 volt
output when given this input. On the other end of the input spectrum, the filter is required to
give a near zero input when given a detection rate near, but above, the cutoff frequency of the
filter. The filter was tested again at 50 kHz. It produced a 3 millivolt output. There is a floor
through which the filter output is unable to go below at the low end of the input range. This
floor is due to residual voltage residing on the PCB and not the output of the filter itself.
The output verification steps in the design process were repeated on the realized filter.
The output was checked for linearity from maximum and minimum output. This was done by
placing inputs to the filter ranging from the maximum detection rate to the minimum rate at
regular intervals. Inputs ranged from 5 MHz to 50 kHz. The outputs were observed to be linear
over the correct range of inputs. The requirement was for the filter to stabilize in a time less than
the sample interval. The smallest sample interval is 0.2 milliseconds and the filter was able to
stabilize within this time.
The filter was further tested to have a passband ripple less than 1 dB and stopband
attenuation of more than 20 dB as stated in the requirements and verification table (Appendix
A.1). Power consumption of the filter proved not to be an issue as the op amps compensated for
power lost in the ohmic losses of the filter. The op amps are powered by wall supply so that the
amount of power available to the filter was sufficient to negate the losses in the filter.
Power Supply
After assembling the finished circuit, it was found that while the power supply did
provide the necessary voltages at up to 6W, it only worked when the positive and negative legs
of the power supply were evenly loaded. This was due to the components in this design requiring
more power from the +12VDC side. This caused the common output of the power supply to
“float”. This meant that while the power supply still provided 24V from end to end, the ±12V to
common voltages varied. (I.E. 16V and -8V, 20V and -4V.)
17. 14
3.2 Digital Processing
Due to every digital component depending on the microcontroller, two steps were taken
to verify functionality. First, each unit was tested alone with the microcontroller in an attempt to
perform its simple functions without other parts of the system. Secondly, testing was done to
verify that each of these systems would run simultaneously.
ADC
Verification for the ADC was done using a code sample known as Beale Code,
referenced in Appendix C.3. This code involved hard wiring the sampling rate to either 5V or
ground to select between 3.5 kHz and 8 Hz sampling rates. The SPI line is intentionally wired to
ground to set a low sampling rate. The code was tested by having a function generator provide an
input to the ADC and programming the microcontroller to read the ADC over a SPI bus. No
problems were encountered in this process.
Memory
Two operations were necessary to verify memory operation: Write and delete. Using the
Arduino Uno’s built in SPI and SD libraries, simple sketches were programmed to write words to
a data file, and then delete them. The major concern was ensuring this could be done continually
without crashing. Thus, a never ending loop was created to make sure the file was properly
opening and closing without the code malfunctioning.
User Interface & Display
The testing for the user interface and the LCD display was quite simple. The 16x2 LCD
Shield came with an easy to integrate Arduino library. The wiring schematic is located in
Appendix B.3 and involved only 2 connections to communicate with the Arduino over I2
C. After
wiring the LCD shield to the Arduino simple sketches were programmed to create a menu. Using
only built in functions from the shields library; menus were able to be written to the display.
However, one flaw was encountered during implementation.
The microprocessor and the I2
C clock rates are different, and therefore the possibility of
them becoming out of sync is possible, which was not originally considered. The original
implementation involved continuously refreshing the display at the clock rate of the
microprocessor. This meant writing to the display at an incredible fast rate which forced the
display out of sync. Unable to properly diagnose the problem in time, the first LCD display
failed due to high stress on its processor. After diagnosing the problem, built in delays were
added between LCD functions and display print functions were removed from code loops.
Code Integration
The last step of the verification process on the digital side involved incorporating all the
individual code segments. To do this, a menu system was established by using a state machine.
Due to the nature of communicating with two modules over SPI as well as one over I2
C, timing
in the code was crucial. Programming the user interface to control the state machine flow
allowed implementation of functions at different times dependent on the system state. A critical
component to combining the code was changing the type of code used for the ADC. ‘Schaeffer
18. 15
Code,’ was used instead of the ‘Beale’ code discussed earlier. It is similar but allows for control
of the sampling rate.
The settings menu had two operations to perform. First the LCD display had to properly
show the current option for the sampling and display rates, and secondly it had to actually
program the ADC to sample at that rate. This was done by waiting on a select signal and then
setting the ADC sampling rate depending on what the menu is currently showing.
The calibration menu was similar to the setting menu, but instead of communicating with
the ADC, the ADC sampled a value and sent it to the microcontroller. Schaeffer code was
implemented here to sample the ADC and average values over a 10 second interval. This was
tested by printing each value onto the SD card and making sure the calibration value equaled the
average calculated in memory.
The measurement menu communicates with all modules. The first step calls the Schaeffer
function and samples the ADC. This value is then divided by the calibration value. After the
ADC performs its operation, the slave select changes so the value can be written to the SD card
which is on the same SPI bus. Additional functionality included displaying the value on the LCD
display. For testing purposes the main priority was to ensure the ADC could sample and write
data to the SD card in a repetitive fashion. The majority of this was trial and error to figure out
how to best perform this implementation. It was ultimately decided to create a very large array of
values from the output of the conversion function, and then the array was stored to the SD card.
3.3 Tolerance Analysis
The primary component of the design is the division circuit. Without precise
measurements by the division circuit, this device is inaccurate and useless. Thus, low tolerance
components are necessary to achieve a high level of accuracy. The physics department requested
the device to be accurate to six significant figures. The device is unable to achieve this level of
accuracy as the error introduced by the log amps and the differential amp is on the order of
1/10,000. This level of accuracy from the output of the division circuit is calculated using
resistors within 1/1000 of their claimed resistance value.
The output of the division circuit is the input to the ADC. The ADC has resolution of 18
bits. Resolution of 18 bits is accurate to 1/1,000,000. This means that the noise floor of the
ADC is 100 times smaller than the noise floor of the division circuit. For this reason, this error
was not calculated as it is negligible when compared to the division circuit.
The next source of error in the device is the mathematical function which converts the
output of the ADC into the desired quotient. An exponential regression was performed on
empirical data to determine a function with the best fit to the data. The fit of this function to the
data recorded at the output of the division circuit determines the accuracy of the last step of
division and thus is a component in the accuracy of the device. Since this calculation is
performed in software the accuracy of the calculation is on the order of 1/1020
. This meant that
the software does not introduce errors above the noise floor of the division circuit. The limit of
accuracy of the software is the accuracy of the regression function.
19. 16
At the output of the entire device, it was found that an error of 1/100 is produced.
Possible sources of this error include variations in the power supplied to the ADC, component
value tolerances, and ohmic losses due to hand soldering. The requirement for the accuracy of
the device is stated as 1/100000. The final device does not meet this requirement. Component
inaccuracies are the greatest contributor to this noise. As stated in the design review, the division
circuit is causing the most error. All other modules of the device have lower error by at least an
order of magnitude.
Some methods to reduce error in this device include selecting components with lower
tolerances and inaccuracies. Since the division circuit produces the most error in this device this
is a reasonable place to start eliminating error. Additionally, averaging can be performed in
software to further reduce variation due to noise. Depending on the length of time for which
values are averaged, noise can be reduced to a more acceptable level. With these two
improvements it is reasonable that the accuracy of the device can be brought to within the
requirements of the physics department.
20. 17
4. Cost Analysis
4.1 Labor
4.2 Parts
4.3 Total Cost
Section Total
Labor $67,500.00
Parts $122.19
Grand Total $67,622.19
Design Section Type Description Manufacturer Part # Price Quantity Total
Inductor 160uH API Delevan Inc. DN2313TR-ND $1.39 2 $2.78
Capacitor 0.12uF Murata Electronics 490-6430-2-ND $0.12 1 $0.12
Photon Conversion Circuit Subtotal $2.90
Op-Amps High Precision, Low Noise Op-Amp Texas Instruments OPA2227-EP $9.00 2 $18.00
Diode 1 Amp Rectifier MCC D1n4007 $0.17 2 $0.34
Resistor 10kΩ (+- .1%) 1/4W Stackpole Electronics RNF14BTE10K0 $0.91 4 $3.64
Resistor 1kΩ (+- .1%) 1/4W Yageo MFP-25BRD52-1k $0.46 2 $0.92
Resistor 100Ω (+- .1%) 1/4W TE Connectivity 1622796-2 $0.67 2 $1.34
Resistor 20Ω (+- .1%) 1/4W TE Connectivity 3-1879026-2 $0.67 2 $1.34
Detector Selection Toggle Switches Single Pole, Double Throw Toggle Switch Copal Electronics, Inc. ATE1E2M3-10-Z $2.87 2 $5.74
Division Circuit Subtotal $31.32
Microcontroller Arduino Arduino Uno - R3 Arduino A000066 $24.95 1 $24.95
Microcontroller ADC 24-Bit Low Noise High-Precision ADC Linearr Technology LTC2440 $7.25 1 $7.25
Memory SD Reader MicroSD Card Breakout Board Adafruit 254 $14.95 1 $14.95
Memory SD Card 8GB Class 6 SD SDHC Flash Memory AGPTek 700697066869 $3.99 1 $3.99
Display LCD RGB LCD and Keypad Adafruit 714 $24.95 1 $24.95
The Brain Subtotal $76.09
Power Supply Converter 6W AC to +/- 12VDC Power Converter Recom Power RAC06-12DC $17.85 1 $17.85
Power Supply Fuse 1 Amp Slow-Blow, 250VAC Littelfuse, Inc. 0229001.MXP $0.69 1 $0.69
Power Supply Fuse Carriage Fuse Carriage Littelfuse, Inc. 02540101Z $1.19 1 $1.19
Power Supply Capacitor 12uF, 63V Ceramic Plate Capacitor Panasonic Electric EEU-FC1J120 $0.33 2 $0.66
Power Supply Capacitor .024uF, 50V Film Capacitor AVX Corp 08055C243JAT4A $0.06 2 $0.12
Power Supply Power Cord Generic AC Power Cord Multiple N/A $2.04 1 $2.04
$0.00
Miscellaneous Subtotal $22.55
TOTAL COST $132.86
Engineer Hourly Rate
Total Hours
Invested
Total = Hourly rate
x 2.5 x Total Hours
Invested
Jon $37.50 240 $22,500
Mike $37.50 240 $22,500
Sean $37.50 240 $22,500
Total 720 $67,500
21. 18
5. Conclusion
5.1 Accomplishments
The completed design was demonstrated satisfactorily, with the exception of the power
supply circuit. As mentioned previously, the power supply design requires changes to
accommodate the different levels of loading on the +12V and -12V DC levels. Also, because the
ADC would be more accurate with a better regulated 5V DC supply than the Arduino provides, a
redesign of the power supply incorporating all three desired power levels would be apt.
As for the rest of the design, each section performed the required functions, with a total
combined error of just over 1%. More detailed analysis of this error was covered in section 3.
5.2 Ethical Considerations
While the entire IEEE Code of Ethics points applies when designing and implementing any
engineering project, the most applicable points to this design project are noted below, with the
actions we will take to meet them:
“To accept responsibility in making decisions consistent with safety, health, and welfare
of the public…”[8]
o We ensured that our completed design is safe for use by lab technicians, even
those unfamiliar with general electrical safety principles. This included ensuring
that there are no exposed electrical parts that could shock the user, and also
included fault protection to prevent hazardous conditions.
“To avoid injuring others, their property…”[8]
o Because this design is used with power meters and photon counters in the
Physics Optical lab, our design prevents the possibility of faults from damaging
other equipment.
“To be honest and realistic in stating claims...”[8]
o The Physics Department and Professor Kwiat are essentially our “customers” on
this project, and we ensured that we were realistic in our communication and did
not oversell on something we could not deliver.
5.3 Future Work
Moving forward with this project a few major concerns will have to be addressed. First
and foremost, our power supply implementation will have to change to account for even loading.
This is planned to be done by buying a market power supply to perform the operations we need
rather than designing our own.
Secondly, our filter will need to be redesigned to account for the Poisson distribution that
more accurately represents the output of the photon detector. This can be done through using a
DSP on the photon detector. For simplicity sake, the filter may be dropped entirely to focus on
the power meter aspect of the design.
22. 19
Third, it is critical that better components are placed on the PCB to reduce the noise floor.
This will involve using surface mount components, a more specific op-amp, and diodes with less
thermal loss. Using simulations, the maximum current in the system can be calculated and trace
widths can correspond to that value. Minimizing traces and thereby minimizing the total PCB
size will provide incredible noise reduction on the system.
Lastly, using a regulated power supply for the ADC will create a very accurate digital
conversion. Using the Arduino, 18 bits of accuracy was not achieved, as guaranteed by the
LTC2440 datasheet. By this datasheet, a minimum of 4uV of inaccuracy will be in the data under
ideal conditions. The unregulated Arduino supply was fluctuating far too much to be reliable and
was thus producing noise far greater than the 4uV minimum possible by the ADC.
23. 20
6. References
[1] ATMEL 8-BIT Microcontroller with 4/8/16/32KBYTES In-System Programmable Flash
Datasheet. Atmel Corporation. Oct. 2014. 1600 Technology Drive, San Jose, CA 95110 USA.
[2] RGB LCD Shield. Adafruit Industries. July 2014
[3] Sedra and Smith, Microelectronic Circuits, 6th
ed., Oxford University Press. 2009.
[4] RAC06-C Datasheet. Recom Power International. Gmunden, Austria. Mar. 2014
[5] Interfacing to High Speed ADCs via SPI. Analog Devices. 2005-2007. P.O. Box 9106
Norwood, MA02062-9106, USA
[6] LTC2440 24-Bit High Speed Differential ADC Datasheet. Linear Technology. 1630
McCarthy Blvd., Milpita, CA 95035-7417
[7] General Aplications of the LTC2440 24 BIT ADC. Rev 2.2. Steve Luce, Jan 2015
[8] IEEE Code of Ethics, IEEE Policies, section 7. Jan. 2015
24. 21
Appendix A. Requirements and Verification
A.1 Table of Requirements, Verification
Requirements Verification
Filter
1. Filter output varies at a rate lower than the
sampling rate of 1kHz
2. Filter power consumption is minimal.
3. Attenuation in the passband is <1dB,
stopband attenuation is >20dB
4. -3dB point lies at the cutoff frequency
5. Filter noise floor is below the noise floor of
the division circuit
6. Filter output is in range 0-2V
Filter
1. Use function generator to provide a signal
which varies over a range from 10 kHz to 20
MHz with 2 Volt amplitude, check that filter
output is stable within one period of sampling
time on an oscilloscope.
2. Measure power at the input terminals of the
filter and the output terminals of the filter,
power loss should be very near zero
3. Using a network analyzer, observe the
frequency response of the filter in the frequency
domain, ensure attenuation is <1db in the
passband and >20dB in the stopband
4. Using a network analyzer locate the -3dB point
ensure it lies at the cutoff frequency of 50 kHz
5. Using an oscilloscope observe the noise of both
the division circuit and the filter when they both
have nothing connected to them, observe that
the filter noise floor is lower than the division
circuit noise floor.
6. Using an multimeter, observe the output of the
filter, ensure it is in the range of 0-2 V
Division Circuit
1. Divides two analog signals within accuracy
2. Outputs a 0-5V signal to microcontroller
Division Circuit
1. Using known inputs from 2 separate function
generators, measure output of division circuit
with multimeter. Output voltage should vary
logarithmically.
2. With minimum difference (0V) between the
two input signals, circuit output should be 0V
(±30mV), as read on multimeter. With
maximum difference (~2V), circuit output
should be read maximum difference (~3.5V), as
read on multimeter.
Microcontroller
1. Reads from the ADC, performs
calculations, and stores data at greater
than or equal to 3.5kHz
2. Stores calibration memory on SRAM
Microcontroller
1. Using calculations, run the Arduino for a
sampled period of time and check to see if
the estimated number of samples are stored
into the memory.
2. Run the board and continuously write
SRAM to the memory to make sure it is
25. 22
3. Outputs ratio of current measurement
divided by calibration measurement to
the memory and display at different
rates
4. Write ratio to memory.
5. Communicates with 5 Interface buttons
on the display via I2
C.
6. Ability to clear memory
7. Scaling factor for the software inverse-
log function scales to accurate ratio
stored.
3. Verify output ratio is sampled value divided
by the calibration value.
4. Write ‘hello world’ continuously and check
if stored on memory.
5. Use on-board LED’s via I2
C to test buttons
6. Send clear signal from the microcontroller
to write over the SD card. Check SD card
via a computer to make sure no data is
entered.
7. Use function generators and test ADC’s
input to get correct scaling factor
Memory
1. Writes over 1.4Kb/sec via SPI
2. Capable of over 1 hour of data storage
3. Interfaces with FAT16 & FAT32 SD
cards
Memory
1. Write test code that outputs data with 4
bytes and run at the max 3.5 KHz rate of
the ADC to see if memory is writing
quickly enough.
2. Run the system for over 1 hour under ideal
conditions and check that the quantity of
data entries correspond to amount of
samples sent to memory.
3. Use both FAT16 and FAT32 SD cards and
test to see data is stored on memory.
Power Supply
1. AC/DC converter provides +12V and -
12V at full load, ±1%.
2. Less than ±2% ripple on voltage output
at full load.
Power Supply
1. Under full load conditions, measure
power supply output voltages with a
multimeter or oscilloscope.
2. Under full load conditions, and using an
oscilloscope, measure output voltage.
Voltage should always fall between
11.76 and 12.24V
Display
1. Continuously updates measurements at
the display update rate
2. Prompts user to power down and to
reset when buttons are pressed
Display
1. Write test code using random functions to
see if the display will continuously update
values at the correct interval.
2. Write interrupt code that prompts user
whether they actually want to reset or
power down. Verify that the execution of
these tasks does not occur until another key
26. 23
3. Displays a navigable interface between
menu options
4. Displays different settings for display
update rate and sampling rate.
press verifies the task.
3. Use directional buttons on interface to
make sure menu scrolls accordingly. Debug
software if incorrect.
4. Verify menu correctly displays the rate
levels when scrolling through menu. Debug
software if incorrect.
User Interface
1. All 5 buttons on the user interface
correctly output a signal when pressed
User Interface
1. Program each button to an LED on Arduino
or memory unit LED’s and check for light
on key press.
Detector Switches
1. Routes the AC signals from the power
meter and detector switch circuits
Detector Switches
1. Hook up both inputs to the switch. Use
multimeter to verify the correct signal is
being passed through the switch without
interference.
27. 24
Appendix B. Schematics
B.1 Microprocessor, ADC, LCD Display, SD card communication wiring
Below is the software configuration for the device. The components featured are the
microcontroller, memory, SD card, user interface, display, and ADC. The only input coming
from the circuit design is the data transferred from the ADC via serial connection, and
therefore is not included in the schematics. The circuit design schematics can be referenced
in their respective block descriptions in section 2.2.
The schematic shows two inputs to the SPI ports for the 24-Bit ADC and the SD memory
card. Using the DC pin 9 on the Arduino a second slave can be used so the second device can
interact with the BUS. The RGB LCD display is also shown, connecting to analog 4 and 5 on
the Arduino to communicate by I2
C. The schematic is the full wiring diagram and shows no
pin conflicts with the Arduino Uno R3.
28. 25
Drawn By: SAB
Microcontroller Schematic
TITLE: Microcontroller Circuit
FIGURE 2.2 REV:
1A
Date: 2/24/2015 10:58:27 AM Sheet: 1/1
30. 27
Appendix C. Source Code
C.1 Filter Matlab Code
As the filter generated by Agilent’s Advanced Design System is of order 14, MATLAB was used
to generate a filter of a reasonable order. The following code generates a Butterworth low pass
filter of order 3. This filter is a physically realizable filter with just a few components. Also, the
plot generated of the filtered signal shows that the order 3 filter is capable of performing the
work of the higher order filter to within reason. This filter takes about 100 microseconds to
stabilize. This is still acceptable as we will be sampling the output signal at a much slower rate,
on the order of thousands of samples per second. The input signal generated in the following
MATLAB code is comparable to that of the photon detectors limitations of detection.
2 function Hd = filter
3 % ECE 445
4 % Jonathan May
5 % jmmay3
6 % 2/23/2015
7
8 % design a filter and apply it to a square wave
9 % observe the response of the filter to determine order
10 % and best cutoff frequency
11
12 %FILTER Returns a discrete-time filter object.
13
14 % MATLAB Code
15 % Generated by MATLAB(R) 8.3 and the Signal Processing Toolbox 6.21.
16 % Generated on: 23-Feb-2015 16:38:46
17
18 % Butterworth Lowpass filter designed using FDESIGN.LOWPASS.
19
20 % All frequency values are in kHz.
21 Fs = 10000; % Sampling Frequency
22 N = 3; % Order
23 Fc = 50; % Cutoff Frequency
24
25 % Construct an FDESIGN object and call its BUTTER method.
26 h = fdesign.lowpass('N,F3dB', N, Fc, Fs);
27 Hd = design(h, 'butter');
28
29 % Get the transfer function values.
30 [b, a] = tf(Hd);
31
32 % Convert to a singleton filter.
33 Hd = dfilt.df2(b, a);
34
31. 28
35 % define the input signal
36 t = linspace(0, 100, 1000 );
37 duty = 10;
38 x = square(t,duty);
39
40 % remove negative values
41 x = x + ones(1,length(x));
42
43 plot(x)
44 hold on
45
46 % apply the filter
47 y = filter(b,a,x);
48 plot(y, ' r')
49 title('filtered photon detector signal');
50 ylabel('magnitude(V)');xlabel('time(us)');
51 legend('signal','filtered signal');
52
53 % [EOF]
Figure 19: MATLAB plot showing the input signal and the output of the filter
33. 30
pinMode (BUSYPIN, INPUT);
digitalWriteFast(SLAVESELECT, LOW); // take the SS pin low to select the chip
delayMicroseconds(1);
digitalWriteFast(SLAVESELECT, HIGH); // take the SS pin high to start new ADC conversion
SPI.begin(); // initialize SPI, covering MOSI,MISO,SCK signals
SPI.setBitOrder(MSBFIRST); // data is clocked in MSB first
SPI.setDataMode(SPI_MODE0); // SCLK idle low (CPOL=0), MOSI read on rising edge (CPHI=0)
SPI.setClockDivider(SPI_CLOCK_DIV16); // set SPI clock at 1 MHz. Arduino xtal = 16 MHz, LTC2440 max =
20 MHz
//SD card shit starts here
pinMode(8, OUTPUT);
if (!SD.begin(8)) {
// Serial.println("initialization failed!");
return;
}
// Serial.println("initialization done.");
lcd.begin(16, 2);
//configure menu
lcd.setBacklight(YELLOW);
delay(2);
lcd.setCursor(0, 0);
delay(2);
lcd.print("Electronic");
delay(2);
lcd.setCursor(0, 1);
delay(2);
lcd.print("Normalizer");
delay(2500);
} // setup()...
void loop()
{
uint8_t buttons = lcd.readButtons();
Menu();
}
void Menu() {
//Start Sample Rate code
SampleRate: // jump call -> This allows the up button to move up to the previous menu option, no functionality for
down button
delay(500); // should actually be some kind of flow control
//Variables
int buttons; // set first display for sample rate to start at 8sps
int rate_samp = 8; // set sample rate to start at 8sps
int state;
int nextstate = 1;
OSR_MODE = LTC2440_OSR_32768; // set beginning rate = 8SPS
lcd.setBacklight(BLUE);
delay(2);
38. 35
PrintDispRate(rate);
}
else if ( (buttons == BUTTON_LEFT) && (state == 4) ) {
rate = 10;
nextstate--;
PrintDispRate(rate);
}
}
// ****************************************************TRANSITION
*********************************************************
MemoryDelete: //Jump call
delay(500); // should actually be some kind of flow control
//Serial.begin(9600);
// Begin Option to delete memory off SD Card
// Start Memory Delete Code
//buttons = lcd.readButtons();
// LCD Reset and recolor
lcd.setBacklight(GREEN);
delay(2);
lcd.clear();
delay(2);
//LCD print logic for display
lcd.setCursor(0, 0);
delay(2);
lcd.print(" Delete Memory?");
delay(2);
lcd.setCursor(0, 1);
delay(2);
lcd.print("<--No Yes-->");
delay(2);
//state machine
nextstate = 1;
while ((state != 0) && (state != 100))
{
state = nextstate;
buttons = lcd.readButtons();
delay(20);
if (buttons == BUTTON_LEFT) {
goto Calibration; // move to calibration, we are not deleting
}
else if (buttons == BUTTON_RIGHT) {
nextstate = 100;
}
else if (buttons == BUTTON_UP) {
goto DisplayRate;
}
}
delay(200);
// Yes Selected, now delete the memory file!
if (state == 100)
{
//display logic to alert deletion
lcd.clear();
39. 36
delay(2);
lcd.setCursor(0, 0);
delay(2);
lcd.print("Deleting");
delay(2);
lcd.setCursor(0, 1);
delay(2);
lcd.print("Memory");
delay(500);
state = 1;
//actual deletion logic
//pinMode(10, OUTPUT);
//digitalWrite(10, HIGH); // Jon added this - it chip selects the SD card
delay(500);
if (SD.exists("data.txt")) {
SD.remove("data.txt");
lcd.clear();
delay(2);
lcd.setCursor(0, 0);
delay(2);
lcd.print("Memory Deleted");
delay(500);
goto MemoryDelete; // should this goto calibration ??
//add a new file at this point????
}
else {
lcd.clear();
delay(2);
lcd.setCursor(0, 0);
delay(2);
lcd.print("No Memory File");
delay(2);
lcd.setCursor(0, 1);
delay(2);
lcd.print("Exists");
delay(500);
goto MemoryDelete; //
}
}
//add a new file at this point if there isn't one, in case the file is empty
// code to delete the memory file goes here
//END OF MEMORY DELETION FILE
// ***************************************************** TRANSITION
*************************************************************************
// Calibration code, first ADC incorporation
Calibration:
delay(500);
nextstate = 1;
40. 37
double calib_value;
lcd.setBacklight(VIOLET);
delay(2);
lcd.clear();
delay(2);
lcd.setCursor(0, 0);
delay(2);
lcd.print("Calibrate Ready?");
delay(2);
lcd.setCursor(0, 1);
delay(2);
lcd.print("-----> To Begin");
delay(2);
while ((state != 0) && (state != 101)) {
state = nextstate;
buttons = lcd.readButtons();
delay(20);
if (buttons == BUTTON_RIGHT) {
nextstate = 101;
}
else if (buttons == BUTTON_UP) {
goto MemoryDelete;
}
}
if (state == 101) {
state = 1; // Reset Variable for next time we loop
lcd.clear();
delay(2);
lcd.setCursor(0, 0);
delay(2);
lcd.print("Calibrating.....");
delay(2);
lcd.setCursor(0, 1);
delay(2);
lcd.print("Please Wait...");
int maxx_calib = 10;// rate_samp * 10; // set calibration array length based on sample rate
double calib_array[maxx_calib];
for (int i = 0; i < maxx_calib; i++) {
// mikes function goes here
calib_array[i] = 0.913973 * pow(2.71828, -3.75539 * shfr_func(OSR_MODE));
Serial.println(calib_array[i], 7);
}
// get the average of the calib_array here:
double sum_calib = 0;
for (int i = 0; i < maxx_calib; i++) {
sum_calib = sum_calib + calib_array[i];
}
calib_value = sum_calib / maxx_calib;
42. 39
lcd.setCursor(0, 1);
lcd.print(data_array[25], DEC);
myFile = SD.open("data.txt", FILE_WRITE);
for (int i = 0; i < maxx; i++) {
myFile.println(data_array[i], 7);
// Serial.println("collecting data and writing to SD card");
//
Serial.println("collecting data and writing to SD card");
}
myFile.close();
buttons = lcd.readButtons();
}
//END Measurement Mode
goto MemoryDelete;
}
// SHAFFER CODE ///
////////////////////////////////
///////////////////////////////
//////////////////////////////
double shfr_func(int OSR_MODE) {
double GAIN = 1;
double OFFSET = 0;
double Volts_Out = 0; //set initial value to "0"
//quikeval_SPI_init(); // Configure the spi port for 4MHz SCK
//quikeval_SPI_connect(); // Connect SPI to main data port
//Serial.begin(115200); // Initialize and set baud rate for the serial port to the P
//begin ADC read and output loop
uint8_t adc_command; // The LTC2440 command word
int32_t adc_code = 0; // The LTC2440 code
double adc_voltage = 0; // The LTC2440 voltage
double adc_summe = 0; // sum of voltages in for-loop
double adc_average = 0; // averaged voltage after for-loop
uint16_t miso_timeout = 1000; // Used to wait for EOC
int i;
adc_command = OSR_MODE; // Build the OSR command code
for (i = 0; i < nsamples; i++)
{ //Begin "for"
if (!LTC2440_EOC_timeout(LTC2440_CS, miso_timeout)) // Check for EOC
{
LTC2440_read(LTC2440_CS, adc_command, &adc_code); // Throws out reading
adc_voltage = LTC2440_code_to_voltage(adc_code, LTC2440_vref);
} //End "if"
43. 40
adc_summe = adc_summe + adc_voltage;
} //End "for"
adc_average = adc_summe / nsamples; // Get average value over nsamples sum
Volts_Out = (adc_average) * (GAIN) + OFFSET; // Allow for linear ADC voltage output calibration
//Serial.println(Volts_Out, 7);
return Volts_Out; // REMEMBER THAT GAIN IS INITIALLY SET TO 1.0 AND OFFSET IS
SET TO 0.0
// Serial.println(Volts_Out, 6); // to 6 decimal places // Send Arduino Board Output from to serial
USB/com port
// to be read by PC/MAC/LINUX serial read program, input
} //end ADC read and output loop
//LCD Sample Rate Function
void PrintSampRate(int rate_samp) {
lcd.clear();
delay(2);
lcd.setCursor(0, 0);
delay(2);
lcd.print("Sample rate: ");
delay(2);
lcd.setCursor(0, 1);
delay(2);
lcd.print(rate_samp, DEC);
delay(2);
lcd.setCursor(5, 1);
delay(2);
lcd.print("per second");
delay(2);
}
// LCD Display Rate Function
void PrintDispRate(int rate) {
lcd.clear();
delay(2);
lcd.setCursor(0, 0);
delay(2);
lcd.print("Display Rate: ");
delay(2);
lcd.setCursor(0, 1);
delay(2);
lcd.print(rate, DEC);
delay(2);
lcd.setCursor(5, 1);
delay(2);
lcd.print("per minute");
delay(2);
}
44. 41
C.3 Beale ADC Code
#include <digitalWriteFast.h>
/*
BEALE CODE
Interface between Arduino DM board and Linear Tech LTC2440 24-bit ADC
Oct. 24 2012 John Beale
LTC2440 <----------> Arduino
10: /EXT : ground (use external serial clock)
11: /CS <- to digital pin 10 (SS pin)
12: MISO -> to digital pin 12 (MISO pin)
13: SCLK <- to digital pin 13 (SCK pin)
15: BUSY -> to digital pin 9 (low when result ready)
1,8,9,16: GND : all grounds must be connected
2: Vcc : +5V supply
3: REF+ : +5.0V reference
4: REF- : GND
5: IN+ : Input+
6: IN- : Input-
7: SDI : wire ADC Pin 7 high (+5 VDC) for a 6.9 Hz output rate, or low (GND) for 880 samples
per second.
NOTE: I strongly recommend wiring Pin 7 to +5 VDC to start - this will give you a very slow
but, easy to work with, sample rate. "nsamples" is set to one in the code below. This will give
you a 6.9 sample per second output rate.
14: Fo : GND (select internal 9 MHz oscillator)
*/
#include <SPI.h> // include the SPI library
#include <digitalWriteFast.h> // from http://code.google.com/p/digitalwritefast/downloads/list
// I had to update the WriteFast library for Arduino 1.0.1: replace "#include wiring.h" and
"#include WProgram.h"
// with "#include <Arduino>" in libraries/digitalwritefast/digitalWriteFast.h
#define VREF (5.0) // ADC voltage reference
#define PWAIT (19) // milliseconds delay between readings
#define SLAVESELECT 10 // digital pin 10 for CS/
#define BUSYPIN 9 // digital pin 9 for BUSY or READY/
const int nsamples = 1; // how many ADC readings to average together or CPS setting. nsamples
= 10 yeilds (880/10) or 110 samples per second.
45. 42
// SPI_CLOCK_DIV16 gives me a 1.0 MHz SPI clock, with 16 MHz crystal on Arduino
void setup() {
Serial.begin(9600); // set up serial comm to PC at this baud rate
pinMode (SLAVESELECT, OUTPUT);
pinMode (BUSYPIN, INPUT);
digitalWriteFast(SLAVESELECT,LOW); // take the SS pin low to select the chip
delayMicroseconds(1);
digitalWriteFast(SLAVESELECT,HIGH); // take the SS pin high to start new ADC conversion
SPI.begin(); // initialize SPI, covering MOSI,MISO,SCK signals
SPI.setBitOrder(MSBFIRST); // data is clocked in MSB first
SPI.setDataMode(SPI_MODE0); // SCLK idle low (CPOL=0), MOSI read on rising edge
(CPHI=0)
SPI.setClockDivider(SPI_CLOCK_DIV16); // set SPI clock at 1 MHz. Arduino xtal = 16 MHz,
LTC2440 max = 20 MHz
for (int i=0;i<2;i++) { // throw away the first few readings, which seem to be way off
SpiRead();
}
} // end setup()
//
=====================================================================
========
// Main Loop:
// acquire 'nsamples' readings, convert to units of volts, and send out on serial port
void loop() {
int i;
float uVolts; // average reading in microvolts
float datSum; // accumulated sum of input values
float sMax;
float sMin;
long n; // count of how many readings so far
float x,mean,delta,sumsq;
sMax = -VREF; // set max to minimum possible reading
sMin = VREF; // set min to max possible reading
sumsq = 0; // initialize running squared sum of differences
n = 0; // have not made any ADC readings yet
datSum = 0; // accumulated sum of readings starts at zero
for (i=0; i<nsamples; i++)
{
46. 43
x = SpiRead(); /// ORIGINAL DATA?
datSum += x;
if (x > sMax) sMax = x;
if (x < sMin) sMin = x;
n++;
} // end for (i..)
uVolts = datSum/ n; //Average over N modified original-works
Serial.println(uVolts,7); //original code included...Serial.print(uVolts,6);
} // end main loop
// =================================================================
// SpiRead() -- read 4 bytes from LTC2440 chip via SPI, return Volts
// =================================================================
float SpiRead(void) {
long result = 0;
byte sig = 0; // sign bit
byte b;
float v;
/*
(ADC) "Gain" is innitally set at 1.0 and offset is at 0.0. Adjust these values as needed. A typical
value
for gain with a 1 uV souce voltage and an op amp gain of 1000 would be GAIN = 1000.
These "word" equations might help you to get started:
ADC OUTPUT READING = (SOURCE VOLTS) * (OP AMP GAIN) * (ADC GAIN) [ = 1.0
in example above ]
OP AMP GAIN = (ADC OUTPUT READING) / [ (ADC GAIN) * (SOURCE VOLTS) ]
SOURCE VOLTS = ADC OUTPUT READING / [ (OP AMP GAIN) * (ADC GAIN ]
ADC input voltage = (SOURCE VOLTS) * (OP AMP GAIN) >>> The max safe neg #
of this expression is - 0.250 Volts
*/
float GAIN = 1; // Set GAIN to 1 to start - this varible is the ADC
// multiplacation factor of the ADC output number
float OFFSET = 0; //Offset of the serial number from zero
47. 44
while (digitalReadFast(BUSYPIN)==HIGH) {} // wait until ADC result is ready
digitalWriteFast(SLAVESELECT,LOW); // take the SS pin low to select the chip
delayMicroseconds(1); // probably not needed, only need 25 nsec delay
b = SPI.transfer(0xff); // B3
if ((b & 0x20) ==0) sig=1; // is input negative ?
b &=0x1f; // discard bits 25..31
result = b; //org code..."result = b";
result <<= 8;
b = SPI.transfer(0xff); // B2
result |= b;
result = result<<8;
b = SPI.transfer(0xff); // B1
result |= b;
result = result<<8;
b = SPI.transfer(0xff); // B0
result |= b;
digitalWriteFast(SLAVESELECT,HIGH); // take the SS pin high to bring MISO to hi-Z and start
new conversion
if (sig) result |= 0xf0000000; // if input is negative, insert sign bit (0xf0.. or 0xe0... ?)
v = result;
v = v / 16.0; // scale result down , last 4 bits are "sub-LSBs"
v = v * VREF / (2*(16777216)); // ORIGINAL CODE: +Vfullscale = +Vref/2, max scale (2^24
= 16777216)
/*
THE LINES BELOW ALLOW CALIBRATION OF THE ADC SERIAL OUTPUT VALUE
Change GAIN or OFFSET of the ADC OUTPUT for calibration of your source voltage. The line
below uses
the equation -> v = (GAIN) * (v) + (OFFSET). This is the straight line graph equation "y=ax+b".
The initial value of the GAIN is "1" and OFFSET is set to zero. For a non-linear source voltage
output change the equation
to fit your source equation.
*/
v=v*GAIN + OFFSET;
return(v);
}//END CODE HERE