Automated data logging and temperature control for thick-film process analysis

advertisement
Dept. of Medical Physics and Bioengineering
Implanted Devices Group
Automated data logging and temperature
control for thick-film process analysis
MSc Radiation Physics: Final Report
Author: Alexander James Messenger
Supervisors: Dr. Anne Vanhoestenberghe
Ms Kylie de Jager
Word Count: 9840
11/08/2010
Abstract
This report gives an account of how a bespoke data logger was built to monitor
manufacturing processes in a clean room. The device was built using a microcontroller unit
with inbuilt ADCs and assembled in an enclosure with a modular hardware design, which
allows it to be easily repaired and augmented. The modules for the device include an LCD
and keypad for user interface; type J/K thermocouple amplifiers for measuring temperature,
and a constant current source array for measuring resistance. The device also includes a 16
channel multiplexer, and SD card reader for data storage. The device has been demonstrated
to take measurements at regular intervals for up to 24 hours and store the data in a format
compatible with most PCs. Although more time needs to be spent fine tuning and verifying
the performance of the device, it is clear it is an effective solution for the environment it is
designed to work in. Notes are included with this report suitable for someone wishing to build
or modify the device.
ii
Acknowledgements
I would firstly like to thank Anne Vanhoestenberghe for her continued help and support
throughout the project, and Kylie de Jager for also taking time to help me. I would also like to
thank Martin Fry, Joe Evans, Tim Perkins and Nick Donaldson who all helped with solutions
to some of the problems that arose during the course of the project.
iii
Table of Contents
1.
2.
Abstract
Acknowledgements
Abbreviations
Introduction
Existing Solutions
2.1
2.2
2.3
Data Acquisition Devices
Microcontroller Units
Available MCUs
3.
Hardware Design
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
3.10
3.11
Thermocouple Amplifiers
DC - DC Converter
LCD
Keypad
Enclosure
External SD card
Grounding Issues and Interference
Current Source Array
Operational Amplifier
Multiplexer
Level Changers
4.
Software Design
4.1
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
4.10
4.11
Reading from an ADC
Taking a Temperature Reading
Writing to a File
Data Formatting
Data Management
Parameters
Program and Memory Hierarchy
LCD
Keypad
Multiplexer and Current Source
Main Data Logging Program
5.
Results and Discussion
ii
iii
vi
1
1
2
2
3
4
5
6
8
9
9
11
11
11
13
14
15
17
17
18
18
19
19
20
21
21
22
23
23
24
24
24
26
28
29
30
30
31
31
5.1 Resistance Measurements
5.1.1 Current Source Ramp Time
5.1.2 Measurement Stability
5.1.3 Calculated Resistance
5.2 Temperature Measurements
5.3 Further Discussion
5.3.1 Long Data Runs
5.3.2 AC/DC Power Supply
5.3.3 Battery Power
iv
6.
Conclusion and Further Work
6.1 Humidity Sensor
6.2 Profilometer
6.3 Real-Time Clock Backup
References
Appendices
32
33
33
33
34
(I) Calculations
(II) User Guide
i)
Getting Started
ii) Setting up an Experiment
iii) Calibrating the Thermocouple
iv) Running an Experiment
v) Plotter Beta
vi) Interfacing with a PC
vii) Loading Programs
viii) Saving to Flash
ix) Reloading the Entire Data-logging Program
(III) Schematics
(IV) Program Code
(V) Contact details
v
34
35
37
37
37
39
39
41
41
42
43
43
45
50
61
Abbreviations
Except for the most commonly used abbreviations, all the following are defined on their first use in
the report.
ABS –
ADC –
ASCII –
BASIC –
CMOS –
CPU –
CR –
DAC –
DAQ –
DIP –
HID –
I2C –
IC –
IDG –
LCD –
LED –
LF –
MCU –
MOSFET –
Op-Amp –
PC –
PCB –
RAM –
RH –
RS232 –
RTC –
SD –
SIP –
SPI –
TTL –
UART –
UCL –
USB –
Acrylonitrile Butadiene Styrene
Analogue to Digital Converter
American Standard Code for Information Interchange
Beginner's All-purpose Symbolic Instruction Code
Complementary metal–oxide–semiconductor
Central Processing Unit
Carriage Return
Digital to Analogue Converter
Data Acquisition Device
Dual In-Line Package
Human Interface Device
Inter-Integrated Circuit
Integrated Circuit
Implanted Devices Group
Liquid Crystal Display
Light Emitting Diode
Line Feed
Microcontroller Unit
Metal–Oxide–Semiconductor Field-Effect Transistor
Operational Amplifier
Personal Computer
Printed Circuit Board
Random Access Memory
Relative Humidity
Recommended Standard 232
Real Time Clock
Secure Digital
Single In-Line Package
Serial Peripheral Interface Bus
Transistor Transistor Logic
Universal Asynchronous Receiver/Transmitter
University College London
Universal Serial Bus
vi
1. Introduction
The Implanted Devices Group (IDG) operates a clean-room at the Dept. of Medical Physics
at UCL, in which a number of manufacturing processes are undertaken. Many of the
processes such as the production of thick film resistors are sensitive to the conditions (e.g.
temperature or humidity) they are produced under, however this particular manufacturing
process takes of the order of days; so to better understand how the conditions affect the final
product, a form of automated data-logging and process control is required. Although there is
a specific interest in the thick film process, the automated system should ideally be versatile
enough, that it can be used with other experiments with minimal alteration. Most of the
equipment in the clean room is fitted with sensors that give analogue signals, so the system
should be able to accommodate this as well as reading digital signals.
Measurements are expected to be made approximately every hour, of course a system that
can work at higher frequency may be desirable for other future experiments, but the key
concern is making a system that is stable over the period of days, weeks or more. The system
will likely be monitoring many items in a process at once; therefore it should be able to
accept many inputs. Another key consideration is easy communication with a PC, somebody
unfamiliar with the system should easily be able to set it up and interface with any PC.
Finally the system would be more effective if it could also give output signals for possible
control of the processes that it is monitoring (e.g. temperature control).
2. Existing Solutions
Clearly data-acquisition is not a new problem, having laid out what criteria the system should
fulfil in the introduction, this chapter aims to explore some solutions that are available to buy
off the shelf and discuss their advantages and disadvantages.
Most scientists and engineers will be familiar with products marketed as „Data Acquisition
Devices‟ (DAQ), typically an array of Analogue to Digital Converters (ADC) connected
directly to a PC, listed below are several examples of these.
1
2.1 Data Acquisition Devices
PicoLog 1000 Series [1], a DAQ with 12 or 16 ADC inputs at a resolution of 10 or 12 bits
respectively, which depends on the model, both have a maximum sampling rate of 1 MSs-1
(Though this is in truth limited by the sample buffer in the DAQ). Connects directly to a PC
over USB and is supplied with proprietary data logging software. (£105/£159)
National Instruments NI USB-6008 [2], another 12 bit DAQ with 8 ADC inputs and a 10 KSs1
sample rate. Connects directly to a PC. (£99). Has software available similar to the above,
but at an additional cost of £600. Both of these DAQs are fairly reasonable solutions for
measuring and logging analogue signals, however both are fundamentally dependent on a PC
for operation. In a normal laboratory situation this would not normally be a problem, but in
the clean-room it is necessary to have a neat self contained solution.
Datataker DT80 [3] –A versatile powerful DAQ with 15 ADC inputs suitable for reading
voltages, current, resistance and frequency with an effective 18bit resolution. Can store data
to USB (max 512MiB) or to FTP after configuration with PC; can be powered from the mains
or battery. (£1915.25) This is a fairly impressive DAQ which has an advantage over the two
previously mentioned, in that it can function independently from a PC once it has been
initially set up. The only real drawback aside from the relatively complex set up is the price.
The devices listed so far are all viable solutions but none are ideal; in the context of the cleanroom environment, a system that is completely self-contained would be best. It was decided
that it would be useful for the purposes of the project to develop a device in the department.
This would allow the project to cover the areas of product and circuit design as well as
conducting scientific experiments and finally, creating a system that is truly fit for purpose.
By designing a system from the ground up, it can be built to work truly independent from a
PC with a suitable form of data storage and all remain contained within a single enclosure.
2.2 Microcontroller Units
A device that can be programmed to interpret ADC inputs and do something meaningful with
the information is a Microcontroller Unit (MCU). An MCU is a relatively simple CPU with
supporting functions such as timers and serial and analogue I/O; it has a small amount of
programmable memory that could be used to run a program for reading and storing analogue
2
signals, and digital outputs suitable for process control. Many MCUs have multiple ADCs
(and DACs) built-in [4].
The Accuracy of an ADC is described by the number of bits it uses (quantisation), therefore
we need to know what accuracy will likely be required of the device when choosing an ADC.
Knowing the furnaces operate up to 1000˚C and a typical K-type thermocouple has an
accuracy of 1.5˚C (below 300˚C then progressively less accurate) [5,6], a 10bit ADC or better
would be suitable to cover this range. Humidity sensors are inherently not very accurate and
there is little meaning in accuracy exceeding +/- 1% RH due to the effects of drift [7], so an 8
bit ADC would be sufficient for acquiring data [Appendices: Calculation 1].
An MCU has the advantage of being able to store data permanently to memory; some
offering an on-board memory of up to 32KiB and above (though a certain portion of this must
be dedicated to program storage). In addition to using the on board memory it is also possible
to interface with an SD card module. A typical SD card module works with either a UART or
SPI interface and should be compatible with card sizes of up to at least 2GiB of storage (This
arises from limitations in the FAT16 filing system) [8][9]. Higher capacity modules are
available, but a typical reading with a timestamp is of the order of 20 bytes [Section 4.5] and on a
2GiB card this equates to 105 readings. An obvious advantage to using a SD card for storage
is that it can easily be removed from the system and read and analysed on a separate PC.
When selecting an appropriate MCU it should be noted that some companies also offer
development boards which are PCBs designed specifically for that chip with basic useful
features such as power switches, serial ports and DC inputs; and another advantage is the
microcontroller pins are much more accessible.
2.3 Available MCUs
The Amtel ATMega32 is an MCU with 32KB of memory for program and data storage, and
8 ADC channels at 10bits [10]. It has on-board UART suitable for communication with PC and
SD and there is a development board available equipped with RS232 communication, DC
regulator, port connectors and various LEDs and DIP switches (£19 from India) [11]. There is
also another development board for the same MCU available that is slightly more compact,
3
featuring just the DC regulator and ports but also supplied with C and BASIC compilers
(£35.24) [12].
The PIC family of MCUs is another option, an example of which is the PIC18F4550
featuring the same 32KB memory, but also 13 ADC channels at 10bits [13]. The PIC
manufacturers conveniently supply USB drivers to allow direct USB communication with a
PC including HID and Mass Storage support, which would be advantageous considering most
modern PCs are equipped with USB rather than serial ports. A development board is
available, the PIC-USB-4550 (£20.88) [14] featuring a USB connection and AC/DC regulator,
and ample space for additional components.
Another member of the PIC family that would also be suitable is the PIC32MX340-512 [15];
this MCU has a larger 512KiB flash memory, 32KiB RAM and 16 ADC channels at 10bits. It
is supplied with a development board [16] that includes USB connection, real-time clock, DC
regulator, port connectors and microSD card interface built in. The board is also supplied
with a variant of the BASIC programming language (PIC-32-Basic) which is interactive i.e. it
allows calculations and functions to be written, executed; and results (interpreted) returned
immediately. The DC regulator will accept power via USB or from an auxiliary DC source.
This MCU/development board combination has an in built SD card slot and a good amount of
available memory and ADC channels available at low cost (£38.55); so it was selected for use
in the automated data-logging system.
3. Hardware Design
Having selected the ByVac BV513 development board as the basis for the automated datalogging system, this chapter gives an account of the different components that were used to
build the system. Although the system is the product of an MSc project, it should be
emphasised that it is expected to be used as a bona-fide item of scientific equipment after the
project is completed. To facilitate this, the system has been made to be as modular as
possible, both in hardware and software; this allows any part that is not needed or faulty, to
be isolated, removed and or repaired. All of the individual modules for the system were first
tested using breadboard to verify all the components where functioning correctly. After this
the modules where fabricated using stripboard, on which all the ICs and components where
4
soldered. 2.54mm pitch header pins and sockets where used to interconnect all of the
modules.
The following report has been separated into sections that correspond to the various modules
of the system. It should also be noted that the majority of the hardware and software was
developed concurrently, but for purposes of clarity they have been separated into different
chapters. There are some small items of theoretical background included with the account of
the practical work, but they haven‟t been separated into distinct chapters as they aid the flow
of the report. For more technical details of how the system was developed, the appendices
have information suitable for someone wishing to alter or expand the system.
3.1 Thermocouple Amplifiers
Many of the processes in the IDG laboratories are conducted in furnaces. Type J or K
thermocouples are the best method for measuring temperature inside a furnace, as they are
low cost and cover a large temperature range. The basic theory behind a thermocouple is that
a junction between two metals produces a voltage related to a temperature differential. There
are a few hurdles to overcome when using one to take measurements.

VoC-1 is typically very small e.g. a type K generates approx 41μVoC-1 [5,6].

VoC-1 is non-linear, particularly above 375oC [5,6].

A thermocouple does not measure absolute temperature, only a temperature
difference, thus a measurement can only be made if the temperature of one of the
junctions (the cold junction) is known [6].
To solve these problems an Analogue Devices AD595AQ Thermocouple Amplifier IC was
selected, which has in-built cold junction compensation and outputs a linear voltage to
temperature response at a more convenient level of 10mVoC-1. The AD595AQ accepts a
supply voltage of +5V to +15V. This is useful as the MCU can supply 5V but it limits the
temperature range to 300oC for type K, thus for higher readings a higher supply is required. A
DC converter was used to supply the +15V, which is described in a later section. The ADCs
on the MCU are rated from 0V to a maximum +3.3V; therefore the output from the
AD595AQ is stepped down using a resistive divider.
5
Vout
2
1+ 2
Vin
(1)
The voltage output given by the AD595AQ is a signal, so resistors in the KΩ range should be
used to minimise current draw. In this case values of R1 3.9KΩ and
Calculation 2]
2
1.1KΩ [Appendices:
where chosen. Two AD595AQs where mounted on stripboard, both with resistive
dividers to reduce the output voltages. Care must be taken when connecting a thermocouple
to the amplifier, as using anything other than thermocouple wiring will change how
thermocouple behaves. To connect the AD595AQs to the back-panel, type K thermocouple
extension wire was soldered directly to the back-panel terminals, as opposed to copper wire
with pins and sockets.
fig.1 AD955AQ Thermocouple Amplifier Module
3.2 DC - DC Converter
A +15V power supply is required to make the full use of the AD595AQ temperature range, it
is also useful for other modules in the system, for example it reduces the internal resistance of
the multiplexers used later in the project. The BV513 board has a built-in DC regulator that
will supply +5V from either USB or auxiliary power; by powering the DC converter from the
board all the components will be functional using either power source.
The DC converter selected was the „MAX773 high efficiency DC-DC converter‟, a type of
switched-mode power supply (SMPS), specifically a flyback boost converter. The basic
theory of operation is that an inductor tends to resist changes in current; when charged it acts
as a load and absorbs energy, and when discharged it acts as an energy source. The voltage it
produces during the discharge phase is related to the rate of change of current, and not to the
6
original charging voltage, thus allowing different input and output voltages [17]. By adjusting
the duty cycle of the charging voltage (the ratio of on/off time), the amount of power
transferred can be controlled.
There were some initial problems with the set up of the DC converter. Having used the
recommended values of resistors, capacitors and inductor [18], the IC was seen to continuously
draw an exceptional amount of current (more than 200mA) in an attempt to raise the output
voltage to the required +15V, on small load (10KΩ). A large current draw is expected during
start up, but this is expected to be for a maximum 20µs, and afterward drop to no more than
110µA [18]. It was found that the Rsense resistor was lower than necessary to give the output
current required, by changing it from 100mΩ to 560mΩ the IC could reach the required +15V
on an open circuit,; however this took approximately 15s (depending on the current limit of
the power supply) and this would immediately drop as soon as even a minor load (10KΩ)
was placed across the outputs. Checking the circuit with an oscilloscope revealed that current
in the inductor was ramping up to a high level before the current-limit comparator could turn
off the ramp; this meant that the recommended inductor value of 22µH was being saturated
and not sufficient for use in the circuit. By selecting an inductor such that
(2)
the current would have sufficient time to ramp up to a high level [18]. By using a 100µH
inductor [Appendix: Calculation 3] the DC-DC converter began working as it should. The working
circuit was then mounted to stripboard, featuring a single power input and five rows of power
outputs to serve multiple modules. Initially the circuit did not function correctly when
permanently mounted to stripboard, this was caused by some stray wire sitting underneath the
stripboard, making contact with the solder joints. It was also later pointed out that the IC
should not be directly soldered to the board, but rather fitted to an IC socket, that makes the
IC easier to replace; all subsequent modules where fitted with these sockets.
7
fig.2 MAX773 DC DC Converter Module
In the course of the project a need arose for a -15V rail. The MAX773 module was replaced
with a similar IC, the „MAX743 Dual Output, Switch-Mode egulator‟ which could supply
both the -15V and +15V. This particular IC did not need external N-channel MOSFETs, but
otherwise required twice as many external components to drive the two power rails; however,
the module was still able to fit in the original space allocated for the first DC converter by
carefully planning the component layout, and using a second layer of stripboard mounted to
the top of using nylon spacers. There are multiple power output sockets fitted to the second
layer of stripboard, and power pins that protrude underneath the first layer that allow power
cables to be run underneath the base-plate.
fig.3 MAX743 Dual Output DC DC Converter
3.3 LCD
When the system was shown to be capable of taking readings from the ADCs and storing to
SD, an LCD was selected to enable the user to check the system is working as it should, and
allow the user to set up the system as required. A graphical LCD was chosen that would
allow large user menus and many readings to be shown simultaneously, compared to for
example a typical two line LCD. The LCD selected is a BV4512 which has 128x64 pixels
and is fitted with an I2C controller which features line and rectangle drawing functions and
8
ASCII character set allowing eight lines of 21 characters. The I2C interface is useful as it
allows multiple devices to be connected to the same bus, and only uses two data wires
making connections simpler than serial communication for example.
3.4 Keypad
To enable a user to interact with the system a numerical keypad was integrated, allowing
navigation of the user menus, and entry of settings for the experimental runs. The keypad is a
BV4506, which has 12 keys and also uses the I2C interface. The keypad and LCD where
connected together using 4-way ribbon cable, which corresponds to the two data lines, power
line and ground line. The connectors on each end of the cable where made with the standard
2.54mm pitch pins, and double row sockets, allowing the cables to be piggy-backed to each
other, and thus enabling both devices to be plugged into a single bus. The I2C interface also
requires both data lines to be held high, this was achieved by making a small connector with
10KΩ pull-up resistors, to plug in the end of one of the cables.
3.5 Enclosure
During the prototyping of the system, the parts where held together using a cardboard shell,
this was subsequently replaced with a Hammond Instrument Case, with an ABS plastic body,
and aluminium front and rear panels. The LCD and keypad were fitted to the faceplate using
a pillar drill make a hole in the middle, manually cutting with a coping saw and finishing with
a file. The LCD has mounting holes, so these where marked and drilled into the faceplate,
and the LCD secured in place with M3 screws, nuts and nylon washers. The keypad does
have mounting holes, but they are extremely close to the protruding part of the keypad, so it
was easier to make the cut-out a tight fit, and hold the keypad in place purely by friction.
fig.4 LCD and Keypad fitted to the Aluminium Face-plate
9
Most of the modules are made from 2.54mm pitch stripboard. To mount the modules inside
the enclosure, a large piece of 2.54mm pitch matrix board is used as a base-plate. This has the
advantage that when drilling the mounting holes for modules; they are always perfectly
aligned with the base-plate, and the modules can easily be stacked and connected on top each
other. The base-plate is secured to the enclosure using M3 screws and Nylon spacers, as are
the modules to the base-plate.
The MCU development board does not have any mounting holes (or any space for them), so a
mounting bracket had to be made to secure it inside the enclosure. The USB port for the
MCU must be accessible from the rear of the enclosure; this was again achieved by drilling,
cutting and filing. The back-plate can only be installed and removed vertically, and therefore
when the USB port of the MCU is fitted to the back-plate, the MCU as a whole can only be
installed and removed vertically. Many project boxes are available that have the inside walls
lined with grooves designed for slotting PCB and stripboard into; and also have plastic
adaptors that allow the board to be mounted horizontally rather than vertically. By taking a
small project box and cutting out one of the sides (with part of the base still attached), drilling
holes in the base and fitting to the base-plate, a bracket suitable for vertically sliding the
MCU was made.
fig.5 ABS Case shown fitted with MCU bracket, SD card reader, base-plate, nylon mounting spacers
and power sockets
To allow the system to be powered from the mains as well as USB, a DC power jack is fitted
to the rear panel and connected to the MCU via the usual 2.54mm sockets. To prevent the
10
MCU taking power from USB and an auxiliary source at the same time, a jumper was used to
select the source; though this would be problematic to access when the box was sealed, so a
power select switch was instead fitted to the rear panel by drilling, cutting, filing and securing
with epoxy adhesive.
3.6 External SD card
Although the MCU is fitted with a microSD card reader, it was not feasible to mount the
MCU to the case in such a way that both the USB port and microSD card where easily
accessible. A solution to this was to fit a separate full size SD card reader to the rear panel
and connect to the MCU via 8-way ribbon cable. This proved advantageous, as the full size
SD cards are easier to handle than their microSD counterparts.
fig.6 Back-Panel of the Device, shown with the external SD card,
power switch, USB, DC and Multiplexer Terminals
3.7 Grounding Issues and Interference
During experiments with the MCU mounted inside the enclosure, the system began to
experience some intermittent large drops in the LCD contrast, an indication that a large
current was being drawn from one of the circuits. The current drops where absent if the DC
converter was disconnected, or by waving a hand near the grounded back panel, so the
problem was likely caused by bad wiring. To reduce the interference, all of the inter-module
cables where replaced with twisted-pair cables, the connectors where covered in heat-shrink
and 0.22µF decoupling capacitors where connected across the power pins of every module.
3.8 Current Source Array
To analyse the thick film resistor process, change in resistance needs to be measured. The
ADCs on the MCU measure voltage, so one way to read a resistance as a voltage is by using
a constant current source. The LM334 is a three terminal current source that can be set
11
between 1µA and 10mA using a resistor, Rset [19]. The value of the resistor being measured is
unknown and will depend on the application considered for the data-logger; so a range of
constant currents is needed to give an appropriate voltage signal. Using a dual four channel
multiplexer, UTC4502, two ranges of current sources could be selected, one for more
accurately determining lower resistances, one for covering a broad range of higher
resistances.
Current (mA) Rset (Ω)
Current (µA) Rset (Ω)
10
6.8
2000
33
5
13
200
330
1
63
20
3.3K
0.5
130
2
33K
fig.7 Chart showing the required Rset resistors to set the LM334 current sources
[Appendices: Calculation 4]
Originally it was planned to use the multiplexer to select the resistance over the Rset
terminals, however, the values of Rset were expected to range from 6.8Ω to 33KΩ, and the
internal resistance of the multiplexer was expected to be approximately 80Ω when running on
a +15V power supply [20]. This would significantly affect the majority of the current values,
particularly as the internal resistance of the multiplexer cannot be assumed to remain
constant. To solve this, separate current sources are used with their respective resistors, and
the multiplexer selects which source to supply power to. The outputs of all the current
sources on each half of the multiplexer are connected together, and the half of the multiplexer
in use is selected using a jumper. To control if the current source is on or off, the inhibit pin
on the multiplexer is used.
fig.8 UTC4502 Multiplexer and Current Source Array
12
fig. 9 Multiplexer and Current Source array schematic
3.9 Operational Amplifier
To measure the voltage across the resistors while only drawing a small amount of current, an
operational amplifier (op-amp) is connected to the current source module output. The op-amp
(OP97) is set up as a standard non-inverting amplifier with a very low input bias current of
100pA [21], the output gain set by a resistive voltage divider
(3)
The gain is set to a value of 10, using 9KΩ and 1KΩ resistors; however this is easily
adjustable as the resistors are not directly soldered to the stripboard, but mounted using
turned pin sockets that allow easy removal. The common-mode range of the OP97 typically
extends to within 1V of either of the power rails, and functions most effectively in the middle
that range. For most effective operation in the system then, the OP97 requires a power range
of -15V and +15V, hence the need for the aforementioned dual output DC-DC converter. To
control the input offset, a 5KΩ potentiometer is connected across the two offset null pins.
With the gain at 10, the MDU should be able to read resistances in the ranges of 10Ω to
2.8KΩ and 50Ω to 70KΩ [Appendices: Calculation 5].
13
3.10 Multiplexer
For multiple resistors (or other experiments) to be tested at once, a 16 channel multiplexer
(HEF4067B) is fitted to the system. The outputs of the multiplexer are connected to the backpanel with eight way screw terminals. The screw terminals used where not supplied with a
necessary plug required for making the internal connection to the multiplexer. As the sockets
are a 5.08mm pitch, spare round pins were fitted to the sockets and soldered to every other
track of 2.54mm pitch stripboard, thereby making a removable connector.
fig.10 Rear terminals and fabricated removable connector
The terminals are fitted to the back-panel using M2.5 screws, nuts and several washers to
ensure the terminals are not obscured by the lip of the ABS case. To measure the voltage drop
just across the resistor being tested and second demultiplexer is required.
fig.11 Measuring voltage across an unknown resistor using only a mux, and a mux/demux
combination
The figure above shows how the system was originally set up to measure the voltage drop at
the current source before the multiplexer (left). The multiplexer has an approximate ON
14
resistance of 60Ω [22], so in the first set up, the op-amp will measure the voltage drop across
both the multiplexer and the resistor; this would be a problem if the unknown resistor is a low
value compared to the multiplexer. In the second example (right), the voltage is measured at
the unknown resistor through a demultiplexer; the current draw by the op-amp is extremely
low (max 100pA) so the 60Ω internal resistance of the demultiplexer does not affect the
voltage reading. The demultiplexer is connected to the multiplexer by mounting it directly
above, and using long, 2.54mm pitch pin and socket connectors.
fig.12 16 Channel Multiplexers shown on separate stripboard and fitted stacked together
There was an issue with the multiplexer/demultiplexer module when first used in an
experimental run, that when it was turned on it drew far too much current. This was found to
be caused by a barely visible hair-thin piece of copper stripboard track still joining the
common input and +15V rail together; this shows how much care and attention needs to paid
when working with the stripboard.
3.11 Level Changers
The PIC32MX340-512 has digital inputs and outputs that work at the 3.3V TTL level. This
voltage is sometimes sufficient to control +5V CMOS ICs, but most of the modules in the
system use a +15V supply, and as such require a high voltage control signal. The system uses
two hex level shifters (CD4504B), one for the current source module and the other for the
multiplexer/demultiplexer module; this raises the 3.3V digital outputs to a suitable +15V.
15
fig.13 4504B Level Changers
fig.14 The Enclosure showing all of the hardware modules mounted and fitted
fig.15 The fully assembled enclosure
16
4. Software Design
The BV513 is supplied with PIC32-Basic, which is a variant of interpreted BASIC running
on a 32bit microcontroller. It is purpose written for the environment and can take advantage
of the available Flash and RAM. The language works via a simple terminal emulator, so no
specialist software needs installing, and the software is all contained on the Microcontroller.
All that is required to interface with the MCU is the terminal emulator (BV-Com.exe) and the
USB FTDI driver. Functions and programs can be typed directly into the console, executed
and saved; however this is cumbersome particularly if any mistakes are made or code needs
to be rewritten. A more effective method is to write the entire program in a text editor such as
PSPad (or notepad), save as a „.bas‟ file, and use the command „tload‟ at the terminal console
to copy the program to the MCU memory.
The following chapter describes how the code works and was written, built-in commands are
written in bold and explicitly called commands; functions that have been written by me are
also written in bold and explicitly called functions. Footnotes are also used in this section;
they are not directly relevant for this report but would be useful for somebody continuing
development on the system.
4.1 Reading from an ADC
To function as a data-logging system the MCU needs to be able to read voltage from the
ADCs, use and or store the value. To take an ADC reading, the ADC channel needs to be
opened, this is achieved using the command „openadc<sample><list of inputs>‟i. The
command „adc(<channel>)„ will return the value of the ADC channel entered in the
parenthesis. The ADC has a resolution of 10 bits, so the value returned by the function is a
number from 0 to 1023 and corresponds to a voltage between 0V and 3.3V. The voltage on
the first ADC channel can therefore be displayed to the console by using the following
example code:ii
i
<sample> is between 1 to 31, with 1 being approximately 1.5µs and <list of inputs> is a list of the
channels to be opened separated by commas e.g. openadc 10 0,1,2,8
ii
Most variables do not need to be defined (with the ‟dim„ statement) prior to use in PIC32-Basic;
with the exceptions of arrays, and variables used in branches or loops, e.g. for j=1 to 10 etc. The type
of variable may be defined by following with a symbol e.g. „a$‟ is a string, „a#‟ is a floating point
,‟a&‟ is a character, „a%‟ is an unsigned integer and „a‟ is an integer
17
openadc 31 0
a=adc(0)*3.3/1023
print a
4.2 Taking a Temperature Reading
The AD595AQ gives a voltage output of 10mVoC-1 and is connected to a voltage divider
giving VOUT = 0.22VIN so the actual response will be 2.2mVoC-1. With the AD595AQ
connected and using the same code as before with the additional voltage temperature
response, a temperature reading can be taken.
print adc(0)*3.3/(1023*0.0022)
To ensure the readings are accurate, a program to calculate the voltage-temperature response
manually from a known temperature source and save the result has also been written
[calibrat.bas].
4.3 Writing to a File
The system can make measurements but also needs to store them; this is done by writing a
file to the SD card and saving strings inside the file (a string in this case being a collection of
ASCII characters). A file is opened for reading or writing using command
‟openfile(<filename><mode>)‟, and has an associated integer file number between 1 and 4
(i.e. four files may be open at once) e.g.iii
F openfile(“test.dat”,‟w‟)
Strings can be written with command ‟write$ <fn>[;start] <string>‟, and read with command
„read$(<fn>,<max>)‟, the following shows how to save and retrieve a string:iv
„w‟ indicates the file is to be written to, and could also be „r‟ for read, or „a‟ for amend. „F‟ will
contain the file number <fn>. It is also important to close the file once it is no longer needed,
particularly when it has been written to otherwise the contents may not be updated and the file
corrupted.
iv
iii. [;start] allows the string to be written at a given offset from the start of the file; <max> is the
maximum number of characters to read and can be an integer or the word „max‟.
iii
18
fn openfile(“test.dat”,‟w‟)
fn openfile(“test.dat”,‟r‟)
a$ ”Hello World”
a$=read$(fn,max)
write$ fn a$
print a$
closefile fn
closefile fn
4.4 Data Formatting
To work as a data-logger the system needs to take readings at regular intervals and store them
in an easily understandable, accessible manner. Using the „write$’ command continues
writing one string after another, for example, if three readings like „23.3‟, „27.2‟ and „35.6‟
are stored using „write$’, the result using „read$’ or opening the file on a PC will be
„23.327.235.6‟, which is not particularly useful. To make the data file a little easier to digest,
the file can be formatted using non-visible ASCII characters and the „write$’ command.
ASCII character constants can be assigned to a string using „*‟ e.g.
a$ ”ABC”+*0x44+*0x45+*0x46
would make a$ ”ABCDEF”. Horizontal tab (*0x09) is used to separate multiple readings
and their respective times, and the combination of „carriage return (CR)‟ (*0x0d) and „line
feed (LF)‟ (*0x0a) is used to create a new line in the text file. This allows the data to be
arranged in clear columns and rows when it is opened in a text editor, and is suitably
formatted for opening in a spreadsheet program such as excel.v
4.5 Data Management
The data management program [data.bas] collates the useful functions that have been written
that are relevant to writing files, so that they can easily be used with other programs on the
device. The „datalogcheck’ function will first look to see if the “data.cfg” file exists, this
normally contains an integer detailing what the last data file number was. If the file does not
exist, the function proceeds to check through the file names “data<XXXX>.dat” where
<XXXX> is an integer up to 1000, to see if any data files exist. If data files do exist an error
v
PIC32-Basic has some undocumented eccentricities, if a character constant is the first part of a
string to be written, it needs to be preceded with “”, i.e. a string of nothing, otherwise it won‟t work.
Also the carriage return, line feed constants MUST be entered in that order, or the formatting will not
work. Horizontal tabs were used as they make the data easy to read when opened in a text editor;
comma separated variables may be used by replacing *0x09 with *0x2C
19
message is given and the user is prompted to check the disk. If no data files exist, the
“data.cfg” file is created and set to one.
After using the „datalogcheck’ function, the „newfile’ function may be used. The “data.cfg”
file is opened, the integer is read, increased by one, and the file closed; the program then
creates a file called “data<XXXX>.dat”, leaves it open and uses the command „keep’ to
leave the file number available in the RAM. „resetlog’ will set the “data.cfg” file back to one.
The MCU is equipped with a real-time clock and date, however if the MCU power supply is
turned off, the time and date are lost and reset to spurious values. The main data-logging
program uses the real-time clock as a timer, so the function „resetclock‟ sets the clock to
00:00:00, after which the clock continues counting as normal. The st function writes a
combination of strings to the currently open data file (e.g. data5.dat); firstly a new line using
the CR LF character constants, the number of days into the data run and finally the time.
The‟ srTEMP(<temp>)’ function will write to the current data file, a horizontal tab, and a
temperature reading to one decimal place. The „srVOLT(<volt>)’ function will write to the
current data file, a horizontal tab, and a voltage reading to three decimal places. The
„timeconvert(<timestring>)’ function will take a standard time in string format (such as the
one given by the system clock e.g. 10:24:41) and return a result in seconds (e.g. 37481),
which is useful for long term scheduling.
4.6 Parameters
Also included in the data management program are a set of functions written to store and find
named „parameters‟ on SD that may be of relevance to one or more programs. „paramopen’
opens the file “config.cfg” where all the parameters are kept. „paramclose’ will write the
string “END” and close the “config.cfg” file. „paramstore(<name>,<value>)’ will write the
name of the parameter, an „ ‟ character, the parameter value and a horizontal tab. Originally
the parameters had to be called in the exact order they were stored, and the function to call
them was very sensitive to any unexpected events (e.g. one more named parameter than
expected, or one more character than expected). To solve this, a more robust function
„callparam(<name>)’ was written, it will open the “config.cfg” file, search for the parameter
<name> and return a value of any length. To change a parameter
20
„changeparam(<name>,<value>)‟ will search the “config.cfg” file and alter the stored
parameter value without having to call every value and rewrite the filevi.
4.7 Program and Memory Hierarchy
Programs on the BV513 are loaded to and executed in the RAM; many programs can be
stored on the SD card, but the program memory available in the RAM is limited to
approximately 18KiB, as 14KiB is used by the Micro-Bos and system [23]. This means that
space can run out quickly, especially considering that the data management program alone
takes up almost 6KiB. Fortunately, functions can be permanently saved to the flash memory
and each one called only when required, so space in the RAM is not wasted holding the code.
All the critical functions are stored in the flash and small individual programs are stored on
the SD card; they call each other with the command „run <program filename>‟ which clears
the RAM before loading the new program.vii
4.8 LCD
The LCD works via the I2C interface, which needs to first be opened using the command
„i2copen <speed>‟ where <speed> is in Hz (the BV4512 works at a maximum 400KHz).
Commands are sent using the command „i2cwrite <address> <value>‟, where <address> is
the device address (0x42), and <value> is a byte. The program to run the LCD and its
functions is stored in the flash, and calling it opens the I2C channel and sets the LCD address.
Functions written for the LCD include
vi
The total length of all the parameters is currently limited to 256 bytes, this can be extended, or the
code could be redesigned to allow a parameter file of any length
vii
The MCU can be made to begin running programs without the aid of the PC by including a file in
the root directory of the SD card called “auto.bas”. For a program to run immediately when it is
called, it must have a function somewhere in it with the same name as the program filename. The
hardware chapter explains that a second SD card is included in the system enclosure. The built-in
microSD card is mounted as „a:‟ and the external SD as „b:‟.
21
Lcd
Open I2C and check device address
Lcdcls
Clear LCD display and reset cursor
lcdc(<char>)
Put character to LCD
lcdic(<char>)
Put inverted character to LCD
lcds(<string>)
Print string to LCD
lcdis(<string>)
Print inverted string to LCD
lcdlp(<line>,<pos>)
Set cursor line and position
lcdhline(<x>,<y>,<length>)
Draw horizontal line
lcdvline(<x>,<y>,<length>)
Draw vertical line
lcdnbox(<x>,<y>,<xlength>,<ylength>) Draw unfilled rectangle
lcdfbox(<x>,<y>,<xlength>,<ylength>)
Draw filled rectangle
fig.16 Table of composed LCD functions:viii
4.9 Keypad
The keypad also works on the I2C interface at a different address to the LCD. The „keypad’
function is similar to the „lcd‟ function, opening the I2C channel and checking the device
address (0x62). The keypad must also have commands read from it and this done using the
„i2cread <address> <value>‟, where <value> must be a one dimensional array, even if only
one byte is expected. The keypad was originally set-up using the scheduling feature of the
MCU; however, there were issues with the holding of variables inside scheduled functions, so
the following functions are only called when an input is expected. The keypad has a 16 key
buffer, so the keypad is first asked how many keys exist in the buffer, if it is more than 0 the
keys are read and saved in an array.
viii
The LCD has 8 lines and 21 positions available for ASCII characters. <line> is a value from 0 to
7, with 0 being the top line. <pos> is a value from 0 to 20, with 0 being the leftmost position. <x> is 0
to 127 and <y> is 0 to 63.
22
keypad
Open I2C channel and test device address
keycheck
Find out how many keys are in the buffer
keyread
Read those keys from the buffer
kget
Wait for input and give it as a result (useful for user
menus)
kgetmul#(<size>) Wait for a number of <size> digits, also accepting a
decimal point, give it as a result, and print each character
to the LCD (so the user can verify the input)
fig.17 Table of keypad functions
4.10 Multiplexer and Current Source
The 16 channel multiplexer and the dual four channel multiplexer are controlled via the
digital outputs of the MCU. The output ports are set using the „setport <port> as <I/O>‟
command, where <port> is the port name, and <I/0> is either the word „input‟ or „output‟.
The channel is then selected by converting the decimal number to the individual digits of a
binary number, which are used to set the output port values.
4.11 Main Data Logging Program
The main data-logging program [readstar.bas] works as the focal point for all the previously
written functions. The program first checks if the settings file [config.cfg] exists, if it doesn‟t,
the program displays an error message; if the settings file is present, all the parameters (i.e.
the experiment length, measurement interval, number of multiplexer channels and
thermocouple calibration) are called and saved to the RAM. The real-time clock is used to
schedule the reading interval by converting it to a time in seconds, and checking when the
next reading should be (rather than using the built-in scheduling process, which as previously
mentioned is a bit buggy). Column titles are written at the beginning of the file, so it is clear
what data is being stored. If a reading is taken from one of the ADCs, a conversion to
temperature is made for channels 1 and 2, whilst the others are stored as a raw voltage, or as a
calculated resistance. The program also checks if the user has pressed the „#‟ key, which will
prematurely end the data-logging run, save the data file, and return to the main menu.ix
ix
There were some initial issues with the main data-logging program consistently running out of
memory after eight minutes of a data run. This was due to a ‘dim‟ statement located within a loop,
and was found using the ‘adr()’ command to show where all the variables were being kept in the
memory.
23
Before data-logging begins, the voltage is read at each multiplexer channel due to be used
with the current sources OFF. If the multiplexer channel is properly connected to a resistive
load connected to ground, the reading should be 0V. If the connection is not present, the op
amp be floating, and in this circuit will tend to rise toward the positive rail. If the ADC
reading is significantly more than 0V the LCD displays an error message telling the user to
check the appropriate channel connection. After this the current source for each channel is
chosen, firstly by selecting the highest current ON and reading the voltage across the channel.
If the voltage is near the maximum measurable value (usually within 0.8V of the 15V rail) a
lower current source is selected and measured. The process is repeated until the voltage falls
within the measurable range and the selection is stored to memory.
5. Results and Discussion
Each of the modules made for the system were individually tested both at the breadboard and
stripboard stages. However assembling the entire system and getting all the modules to work
in unison did prove to be challenging. As such there was limited time to fully verify the
performance of the system, but this chapter aims to give some insight into how it behaves.
5.1 Resistance Measurements
5.1.1 Current Source Ramp Time
A perfect current source would have a discontinuous jump between the OFF and ON states.
Such perfect sources do not exist, so it takes a measurable amount of time for the charge to
build; if the charge builds very quickly there may also be some overshoot from the target
current. The following charts are taken directly from a digital oscilloscope and show how the
voltage ramps up for each of the current sources. The loads for each of the current sources
where chosen using a resistance box, such that the voltage would be approximately at the
halfway point of the data-loggers measurable voltage range (0V to +1.5V on the 10x Gain
setup).
24
5mA source with 155Ω Load
800
1000
600
800
Millivolts
Millivolts
10mA Current Source with 62Ω Load
400
200
600
400
200
0
0
0
0.5
1
1.5
2
2.5
0
1
Microseconds
3
Microseconds
1mA Current Source with 620Ω Load
0.5mA Current Source , 1.56KΩ Load
800
1000
600
800
Millivolts
Millivolts
2
400
200
600
400
200
0
0
0
1
2
3
4
5
0
Microseconds
2
4
6
Microseconds
fig.18 LM334 current source ramp-time graphs
At first glance the response looks fairly erratic at the different current levels; however this is
consistent with the behaviour documented in the LM334 datasheet [19]. The voltage reaches a
stable level in no more than 5µs, so for many data-logging applications almost no allowance
needs to be made in the code for the ramp time. The delay between activating the current
source and taking a measurement is included in the user options. At the time of writing the
second set of current sources (2µA to 2000µA) is not functioning, so their respective ramp
time graphs could not also be included. The wiring for these sources is no different from the
working sources bar the RSET resistors, so the problem is likely due to stray wire, bad solder
joint or faulty IC as they have been observed working within the last few weeks running up to
this report.
25
5.1.2 Measurement Stability
The device was tested to verify that the measurements made were not subject to drift over an
experimental run. This was achieved by using various passive components of fixed value, so
the voltage readings on each channel should stay constant over the entire run. Resistors were
used that fell below, in the middle of, and above the observable range of the device. A 2.2µF
capacitive load was also included, and two RC circuits where the resistor and capacitor were
in parallel. The RC circuits where chosen such that the time constant τ would be very small
compared to the measurement delay for one circuit (i.e. between the current source switching
ON and the ADC readout), and approximately the same as the measurement delay for the
other circuit. What is expected is the small τ circuit should rise toward the maximum voltage
quickly, and the large τ circuit will only rise to a certain voltage in-between the minimum and
maximum given by.
(4)
(5)
The interval between separate measurements is large compared to both time constants, so
both RC circuits should discharge to a very low level in between readings. The following test
ran overnight for nine hours, with a five minute interval and 2.5 second delay between
current switch ON and measurement.
Measurement Stability Test over 9 hours
Voltage (Volts)
1.6
1.4
1MΩ (10mA)
1.2
1KΩ (1mA)
100Ω (10mA)
1
68Ω (10mA)
0.8
33Ω (10mA)
0.6
10Ω (10mA)
0.4
0.56Ω (10mA)
0.2
2.2µF (10mA)
0
2.2µF + 1MΩ (1mA)
0
1
2
3
4
5
6
7
8
9
2.2µF + 1KΩ (10mA)
Time (Hours)
fig.19 ADC read-outs for ten passive components connected to constant current sources over 9 hours
26
The chart shows the voltage readings are for the most part fairly stable, with the exception of
the voltages at the top of the measurable range. A voltage reading at the top of the
measurement range indicates the resistance is too high to read or an open circuit; the value
that it will reach is determined by the op amp which swings within approximately 0.5V of the
positive rail [21]. The op-amp is not particularly accurate at the limit of its range, so the
fluctuations at high voltage seen in the first few hours are not cause for too much concern;
though there is a small change in some of the other channels so it was worth investigating
further. After replacing the AC/DC adaptor (which is discussed in more detail later) another
measurement stability test was taken over a period of 45 hours, with a 15 minute interval and
2.5 second delay.
Measurement Stability Test over 45 Hours with new AC/DC adaptor
1.6
1.4
1MΩ (10mA)
Voltage (Volts)
1.2
1KΩ (1mA)
100Ω (10mA)
1
68Ω (10mA)
0.8
33Ω (10mA)
0.6
10Ω (10mA)
0.4
0.56Ω (10mA)
0.2
2.2µF (10mA)
2.2µF + 1MΩ (1mA)
0
0
5
10
15
20
25
30
35
40
45
2.2µF + 1KΩ (10mA)
Time (Hours)
fig.20 ADC read-outs for ten passive components connected to constant current sources over 45 hours
This chart shows a significant improvement in the voltage measurement stability, giving
confirmation that the original AC/DC adaptor was of inferior quality. The voltages for both
charts are consistent with what would be expected for the current source / load combinations.
The capacitive load measurements for both charts are also consistent with what was expected,
the purely capacitive maintained high voltage as did the low τ, 2.2µF + 1KΩ circuit. The high
τ, 2.2µF + 1MΩ circuit was also close to the expected value of +1.02V [Appendix: Calculation 6], and
27
very consistent. Although the data-logger will function with capacitive loads, the automatic
current selection is programmed to check for loads that reach the maximum voltage within
the delay time; hence the automatic current selection is not ideal for capacitive loads. The
automatic current selector could be made more robust by making several voltage
measurements over a certain period, and check to see if it is constant or changing. The data
logger automatically selected 10mA for the 1MΩ as the resistance was well outside the
measurable range, and used it by default as the current source. A feature could be added to
the code to alert the user if the preliminary test detects an out of range resistor, or
automatically decide not to measure the channel.
5.1.3 Calculated Resistance
The device is capable of taking a voltage measurement across a resistor and calculating the
resistance by using a saved measurement of the constant current level. The following is a
chart to show how much the calculated resistances from the device differ from a set of known
resistances of 1% tolerance.
Relative Error of Measured Resistance Against True Resistance
3
Relative Error(%)
2
1
0
0
50
100
150
200
250
300
350
-1
-2
-3
True Resistance (Ω)
fig.21 Plot to show resistance calculation accuracy for a set of known resistors
It should be noted that the multiplexer channels have a ΔRON resistance of up to 5Ω [22], so
each multiplexer channel needs to be calibrated independently to give an accurate resistance
reading, but there was not sufficient time to do this. This chart does not cover the whole
28
range of measurable resistances for this particular set-up (10Ω to 2.8KΩ), and is only
intended to give an approximate indication of the accuracy that may be expected from the
device.
5.2 Temperature Measurements
The following also shows the thermocouple read out over the same nine hour and 45 hour
runs as the measurement stability tests.
Temperature Measurement over Nine Hours
25
Temperature (Celsius)
24
23
22
21
20
19
18
17
0
1
2
3
4
5
6
7
8
Time (Hours)
fig.22 Chart to show thermocouple temperature measurement over 9 hours
29
9
Temperature Measurement over 45 Hours
27.0
Temperature (Celsius)
26.0
25.0
24.0
23.0
22.0
21.0
20.0
0
5
10
15
20
25
30
35
40
45
Time (Hours)
fig.22 Chart to show thermocouple temperature measurement over 9 hours
The signal does appear a bit noisy, but it should be appreciated that type K thermocouples are
not particularly well suited for accurate room temperature measurements, and the relative
error in a measurement is much better at higher temperatures.
5.3 Further Discussion
5.3.1 Long Data Runs
The device is expected to be used on experimental runs of the order of days, so several
experiments were set to run for 24 hours and over. Two 24 hours experimental runs where set
off on the 300mA AC/DC adaptor, however there was noticeable change in the screen
contrast when taking readings, and the system froze after 30 minutes and also 5 hours. The
device only draws a maximum 210mA so the AC/DC adaptor should have no issue providing
this. Yet the issue was repeatable and switching to USB or a laboratory supply alleviated the
issues with the screen, and the following two 24 hour runs were a success.
The device was then set to run for 48 hours, however after 24 hours the device continued
running, but not taking measurements and storing them to the SD card. It was noticed that the
LCD day counter was not turning over when passing the 24 hour mark; this was due to a bug
30
in the main data-logging program. The bug was an unsigned integer used to mark when the
next reading was due „NEXTTIME%‟, however the part of the code used to count the days
used the variable „NEXTTIME‟. This made the program never pass the first day mark and
loop continuously for the first 24 hours, not expecting another reading to be taken until that
24 hours had passed. This was fixed by setting all of the variables to the correct unsigned
integer format, and adding a new day turnover variable that activates when the clock string is
equal to 23:59:59. The program has been verified to work past one day by setting the clock
start to 23:59:30, and observing the behaviour of the device. The device was then set to run
for up to 3 days and was still successfully running at 45 hours, after which the experimental
run was selected to end prematurely so the data could be collected and have time to be
analysed.
5.3.2 AC/DC Power Supply
The original AC/DC adaptor caused many problems with the screen contrast, interference and
system crashes. The rating for the adaptor was a 300mA output at +5V, which should easily
meet the requirements of the device (max 210mA). The problem was repeatable with the
adaptor; but was completely absent when using either a laboratory power supply current
limited to 300mA, or USB power. Another AC/DC adaptor was subsequently found in the lab
rated for 1A at +5V; the issues were also absent when using this power source so it can be
safely concluded that the original adaptor was faulty, or not built to the stated specifications.
5.3.3 Battery Power
Battery power was considered as an option to make the data-logger more portable. The entire
system draws between 800mW to 1050mW with a backlit LCD, or between 600mW to
850mW unlit. The relatively large swing in power consumption arises when the current
source is in use. A large capacity AA size battery can be expected to deliver up to 2.85Ah of
charge at 1.2V [24], so at least four batteries are required to deliver enough voltage. Larger
batteries are also available, but to achieve the necessary voltage requires a set of batteries or
single battery approaching the size of the data-logger, so this detracts somewhat from the
portability argument.
So in a situation where the power consumption is at its lowest (Unlit LCD and large reading
interval, so the spikes in power draw are negligible), with 600mW of power draw at 5V and
31
four 2.85Ah batteries, we would expect a maximum run time of 22 hours [Appendix: Calculation 7].
This is a reasonable amount of time, but a lot of the data acquisition is expected to be over
longer periods than this. The data-logger is expected to be near a mains power socket most of
the time, so battery power is not currently a pressing issue. Should battery power later be
required it is recommended that either a high voltage (up to 10V, as the MCU has a regulator
allowing supplies between 5V to 10V) battery, or a DC converter is used to account for the
voltage drop seen when the battery is low on charge.
6. Conclusion and Further Work
Although there has not been enough time to fully test and debug the device, I am confident
that it is well suited to the original aims of the project, and suitable for other applications in
the department. In summary, the device has been verified to take temperature measurements
from multiple thermocouples covering a range of 0˚C to 1250˚C, and measure voltages
between 0V to +15V with a variable gain to improve accuracy at lower voltage levels. It can
also use a selection of constant current sources to measure a range of resistances (currently
set up for between 10Ω and 2.8KΩ). The appropriate current level is automatically selected so
the voltage across the unknown resistance is within the measurable range, and the resistance
value is stored. The device functions correctly when connected to a load with significant
capacitance and is also capable of monitoring multiple loads with a 16 channel multiplexer.
The measurements are taken at regular intervals, adjustable from 1s to 23h59m59s and the
results stored to an SD card in a data format that is compatible with almost any modern PC.
The user interface is clear and concise, with a fair amount of error checking; so a user that is
unfamiliar with the device should be able set it up and collect data with relative ease. The
hardware and software design is very modular so it can easily be adapted to new experiments
and interface with other equipment. There are still eight digital input / outputs, 13 ADC
channels, I2C interface and serial interface available, so there is plenty of scope for further
expansion of the system.
The following suggests some future work, more considerable than the fine-tuning of
hardware and software mentioned throughout this report.
32
6.1 Humidity Sensor
Some processes in the IDG laboratory are dependent on the humidity in the air; the HIH4000-002 is a small SIP IC that gives a linear voltage output against relative humidity. Two
of these ICs were ordered but they were not interfaced with MCU as other modules in the
project had a higher priority. Interfacing should be a simple case of a connecting to an ADC
channel with a resistive divider and minor addition the program code.
6.2 Profilometer
The profilometer can communicate over RS232 serial connection with options to set the
speed, parity and stop bits. This protocol is compatible with the MCU, but the RS232
interface requires a negative voltage swing of at least -3V so an additional hardware module
would need to be made to facilitate this. The PIC32-Basic system also allows for „plug-ins‟ to
be written in C and run above the operating system and make the code run more efficiently
[26]
; this would be necessary if a large amount of data is expected to be read from the
profilometer.
6.3 Real-Time Clock Backup
The MCU has a real-time clock and date, but these are reset to spurious values when the
power is turned off. A useful feature would be to keep the RTC running when not connected
to mains or USB power. This would allow the data files to be correctly time-stamped, and for
absolute time readings to be used with each measurement. To do this a BV4236 Real Time
Clock & Temperature Sensor could be added to the system. This module works over the I2C
interface and uses a cell battery to power its own RTC which is always on [25]. The module
also has a programmable alarm, so features such as delayed start from standby could also be
implemented or even put the device in standby in between readings, significantly reducing
the overall power consumption.
33
References
[1] PicoLog 1000 Series - http://www.picotech.com/multi-channel-daq.html
[2] National Instruments NI USB-6008 - http://sine.ni.com/nips/cds/view/p/lang/en/nid/14604
[3] Datataker DT80 - http://www.bellflowsystems.co.uk/grant-data-taker-dt80-complete-data-loggingkit.html
[4] S. Heath (2003). Embedded systems design. EDN series for design engineers (2nd ed). pg.11-12
Newnes. ISBN 9780750655460.
[5] "Technical Notes: Thermocouple Accuracy". IEC 584-2(1982)+A1(1989)
http://www.microlink.co.uk/tctable.html
[6] Manual on the Use of Thermocouples in Temperature Measurements. ASTM, 1974
[7] K. Bull Catching the Drift. - http://www.veriteq.com/download/whitepaper/catching-the-drift.pdf
[8] MicroDrive SD Module - http://www.saelig.com/product/ST001.htm
[9] DOSonCHIP FAT16/32 IC http://www.coolcomponents.co.uk/catalog/product_info.php?cPath=27&products_id=101
[10] Amtel ATMega32 - http://www.futurlec.com/Atmel/ATMEGA32.shtml
[11] AVR Development Board http://robokits.co.in/shop/index.php?main_page=product_info&products_id=14
[12] ATMega32 Development Board - http://www.active-robots.com/products/controllr/m32db.shtml
[13] PIC18F4550 - http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010300
[14] PIC-USB-4550 Development Board http://www.coolcomponents.co.uk/catalog/product_info.php?products_id=87
[15] PIC32MX340-512 - http://www.pic32.byvac.com/bv513_specs.php
[16] ByVac BV513 PIC32 Development - Board http://www.byvac.co.uk/mi_bv513.php
[17] W. Erickson, D. Maksimović. (2001) Fundamentals of power electronics (2nd ed) pg 23-31
Springer ISBN 0471429082
[18] Maxim MAX773 DC DC Converter Datasheet – pg. 2-3,11,16
[19] National Semiconductor LM334 Adjustable Current Source Datasheet – pg. 1,4-5
[20] Motorola 4052 Dual 4 Channel Multiplexer Datasheet – pg. 4
[21] Analog Devices OP97 Operational Amplifier Datasheet – pg.1
[22] Phillips HEF4067 16 Channel Multiplexer Datasheet – pg. 5
[23] ByVac PIC32 Internals - http://www.pic32.byvac.com/pic32_internals.php#speed
[24] Farnell AA battery - http://uk.farnell.com/ansmann/5035201/battery-rechargeable-nimhaa/dp/1453781
[25] RTC Backup - http://www.byvac.co.uk/in_rtc.php
[26] PIC32-Basic Plug-in Introduction - http://www.pic32.byvac.com/ar_plugin.html.php
34
Appendices
(I) Calculations
1.)
Accuracy required for thermocouple:
1.5˚C / 1250˚C = 0.12%
ln(1 / 1.2E-3) / ln(2) = 9.70
so 10 bits are required
Accuracy measurement for RH does not need to exceed 1%
ln(1 / 0.01) / ln(2) = 6.64
so 8 bits are required
2.)
VOUT = (15V x 1.1KΩ) / (3.9KΩ 1.1KΩ) = 3.3V
3.)
Using the time of 2µs, and the current limit trip level of 200mV / RSENSE stipulated in
the datasheet, with a 5V input:
L ≥ (5V x 2µs) / (200mV / (560mΩ x 2)) = 56µH
4.)
Using:
so 100µH is sufficient
given by the LM334 datasheet
ISET
RSET
E-12 Series
10 mA
6.81 Ω
6.8 Ω
5 mA
13.6 Ω
13 Ω
1 mA
68.1 Ω
68 Ω
0.5 mA
136 Ω
130 Ω
2000 µA 34.0 Ω
33 Ω
200 µA
340 Ω
330 Ω
20 µA
3.40 KΩ 3.3 KΩ
2 µA
34.0 KΩ 33 KΩ
The E-12 series is a standardised set of resistor values that allows a resistor within
10% of the specified value to be selected. Accuracy higher than this is not usually
required as most resistors are made to a fairly loose tolerance.
35
5.)
Using a minimum voltage measurement of 1V and a maximum 14V and a gain of 10,
the device should be able to measure a total resistance in the ranges:
1V / (10 x 10mA) = 10Ω
to
14V / (10 x 0.1mA) = 2.8KΩ
And
1V / (10 x 2000µA) = 50Ω
to
14V / (10 x 20µA) = 70KΩ
Note: 20µA was used as the lower current limit as it was realised that at 2µA there is
likely to be a significant contribution from Johnson noise, and quantisation error.
Even 20µA would likely require more thorough grounding of all the modules in the
circuit.
6.)
(15V / Gain 10) x (1-e^(-2.5s/(2.2µF x 1MΩ))) = 1.019V
7.)
2.85Ah x 1.2V x 4 / 600mW = 22.8h
36
II) User Guide
i) Getting Started
Setting up the device to take readings is very simple provided it is set up correctly. I will
firstly explain how the correctly set up device works; then progressively explain how the
hardware and software is structured so the user can understand how the device is set up. For
in depth detail on how to develop code to use the MCU, the ByVac PIC32-Basic website
(http://www.pic32.byvac.com/downloads.php) has ample detail, with articles on how to use
many of the interfaces and features.
The device may be run from USB or a DC adaptor; there is a power source select switch on
the real panel that also functions as a regular power switch when only one source is
connected. The device may take several seconds to power up, after which the splash screen
will be displayed and the device will load the main menu. If this does not happen, firstly
check the SD card containing the program files is installed in the rear panel. Alternatively
sometimes the device does not switch on immediately if it has been powered down for a
while; this is likely due to the large initial current draw from the DC converter affecting the
MCU start-up. Simply switch the power off then on again, and the device should start
normally.
ii) Setting up an Experiment
The items on the menu are selected with the numerical keypad. The main data-logging
program must first have the experimental settings entered before it can be run. If no settings
file exists (usually only if the SD card has been erased, or the reset configuration option is
used) then the data-logging program will display an error message prompting the settings to
37
be entered; if the file does exist, the main program will use the last settings entered. To enter
new experimental settings, select option 3.
This program will firstly display the current settings if they exist, the user is then asked
whether they wish to keep the current settings or enter new ones. Some of the options have a
range of values with a variable amount of digits, so the „#‟ key acts as an enter key if
required. The bottom line of the screen displays tips on what values the program is expecting,
and if the user enters an invalid setting (e.g. 3 temperature channels, or 18 mux channels) the
bottom line explains what valid entries are available. After entering all the new settings, they
are displayed for several seconds and the device returns to the main menu.
Parameter
Description
Duration
Total experiment length (Maximum 99 days, 23hours, 59 mins and 59secs)
Interval
Time between measurements (Maximum 23hours, 59 mins and 59secs)
Temp Chn
How many thermocouple channels to use (Maximum 2)
MUX Chn
How many multiplexer channels to use (Maximum 16)
Volt/Res
Save either a voltage reading or calculated resistance from the multiplexer
channel (0 for Voltage, 1 for Resistance)
Pause
Time between the current source switch ON and taking the measurement
(Maximum 9999ms)
38
iii) Calibrating the Thermocouple
As mentioned in the main report, the thermocouple amplifier gives a linear voltage to
temperature response, expected to be 2.2mV/˚C. To be absolutely sure that this is correct,
there is the thermocouple calibration program which calculates the true response from a
known temperature source (boiling water is usually convenient and accurate).
Any existing settings are firstly displayed and the user is asked whether or not to overwrite
them. The program then asks for the temperature of the known sources and then proceeds to
measure the voltage response 1280 times over a period of about seven seconds, displaying a
progress bar on the bottom of the screen (1280 was a convenient number to combine the 128
pixel progress bar with a large number of readings). The results of the calibration are then
displayed and the user is asked once more if they want to replace the existing settings, after
which the device returns to the main menu.
iv) Running an Experiment
Once the experimental settings have bet set up and the thermocouples are calibrated, the user
may now begin the main data-logging program. Firstly the SD card is checked for the
[data.cfg] file, which contains the number of the last data file created. If it does not exist the
card is checked for existing data files to make sure nothing is accidently overwritten. If files
do exist the user is told to check the card; otherwise the [data.cfg] file is created and set to 1.
39
The program reads the file number in the [data.cfg] file, increases it by one, updates the file
and closes it. The new number is then used to create a [dataXXXX.dat] file, where XXXX is
the file number, and the file name is held in the RAM. Every time a reading is taken, the
program opens the [dataXXXX.dat] file for amendment, saves the time, saves all the relevant
readings, starts a new line, then closes the file until the next reading is taken. This reduces the
likelihood of the SD card being corrupted if the device should crash for any reason.
The experimental set up is then checked. Any multiplexer channels being used should be
connected to a resistor which should in turn be connected to ground. This means the ADC
reading for that channel should be 0V or at least very close to it. If the channel is not
connected properly, the op-amp will naturally rise toward the positive rail, so the ADC
reading will be near maximum (+3.3V). The program checks for this, and if any of the active
channels are significantly above 0V, the user is told to check the connection of the relevant
channel.
If the experimental set up is tested as correct, the appropriate current source is selected for
each channel. The highest current source is used first; if the voltage reading is too high to be
meaningful, a lower current source it selected until the voltage is in the measurable range.
The number of the current source used for each channel is saved to memory, and saved at the
beginning of the data file.
All the preliminary features of the main data-logging program are finished, and the device
begins taking and saving readings. The experimental duration and the elapsed time are both
displayed at the bottom of the screen, and the most recent temperature readings are displayed
40
if the any of the thermocouples are being used. When a reading is being taken, this is also
displayed on the screenx.
The program also allows the user to end the experiment prematurely by pressing the „#‟ key
twice.
v) Plotter Beta
This is a program that was written to test and demonstrate the graphic capabilities of the LCD
display. It was anticipated that it may be used to create a real time plot of one of the
measurements as an option in the main data-logging program, but for the time being, it just
displays a variety of mathematical functions to show what a plot may look like.
vi) Interfacing with a PC
Alterations can be made to the programs on the SD card, but connecting to the PC is useful as
any errors that occur in a new piece of code can quickly be identified through the terminal
emulator.
x
The elapsed time does not update on screen whilst a reading is being taken, but the real-time clock
is still running and will update as normal once the device has finished measuring and saving.
41
To interface with a PC all that is required is the terminal emulator [BV-Com.exe] and USB
FTDI drivers, both available from the ByVac website. After opening the [BV-Com.exe]
program, the Baud rate should be set to 115,200 with 8 data bits and 1 stop bit. Once
connected, the MCU should respond with a sign on message and if the main program is
installed on the MCU, this will execute automatically.
If the main program runs automatically, only to 0-9 „#‟ and „.‟ keys will be available on the
keyboard. By selecting option „0‟, the program on the MCU will end, and all the keyboard
keys and features of the terminal will be available.
vii) Loading Programs
Code and programs can be directly typed and executed in the console, but if any mistakes are
made the whole code must be rewritten and saved code cannot be edited. It is therefore
advisable to type the code in a test editor, save as a [.bas] file and load to the MCU. PSPad is
42
a useful text editor, as it can be easily configured with a syntax colours file that indicates if
typed commands are recognised (again available from the website) Programs can be loaded
directly to the RAM on the MCU using the load command at the terminal, where the user
will then be prompted to select a [.bas] file in explorer.. Programs may also directly uploaded
to the SD card using the tload <filename> command, where <filename> is the full destination
filename (e.g. readstar.bas). Saved programs may then be run using the run <filename>
command; in this case it is not necessary to include the extension, as [.bas] is assumed for a
program. If a program is run, the MCU looks for a function with same name as the filename
in the code and executes it first. To automatically start a program when the MCU powers on,
a file called [auto.bas] may be placed in the root directory of the SD card, or saved to flash
viii) Saving to Flash
Functions or entire programs may be saved to the 512KiB flash memory. This has the
advantage that the code does not need to be held in the RAM when it is not in use, but is still
accessible to any program currently running. As such the core parts of the data-logging
program are held in the flash, which include, the „data management and multiplexer control‟,
„lcd control‟, „keypad control‟ and „splash screen‟. To save code to the flash it is first
executed in the RAM. Before the program space is cleared the fsave all command is used;
this copies and saves everything in the RAM to the flash memory.
ix) Reloading the Entire Data-logging Program
All the data-logging program parts are kept in the folder [b:\mainprog], which is opened and
the main menu executed by the [auto.bas] file in the root directory. Should any code in the
flash need to be changed or re-uploaded, back-ups of the core programs are also stored in this
folder. Below is an example of clearing the entire flash with fclear all, and uploading all of
the core program parts.
43
The error displayed after running [data.bas] is normal; it arises because there is no function in
the program called „data‟.
Most of the code I have written for the MCU has notes describing what each section does, so
I should be fairly clear to a developer how the code all fits together. As always for more
detail on the commands available on the MCU and how to make the most the resources it has,
consult the ByVac PIC32-Basic website.
44
(III) Schematics
(Schematic 1 – AD595AQ Thermocouple Amplifer)
The inputs must be connected to the rear screw terminals using type J or K thermocouple
extension wire.
Two of these ICs are mounted to a single module to allow two thermocouples to be read at
once, the outputs are connected to separate ADC inputs.
Pin 1 should be grounded, unless the connected thermocouple is grounded.
45
(Schematic 2 – First DC-DC Converter, MAX773)
L1 was originally fitted with a 22µH inductor, and 1 at 100mΩ, however these values were
not correct for powering the system.
46
(Schematic 3 – Second DC-DC converter, dual voltage regulator MAX743)
47
(Schematic 4 – Multiplexer, Demultiplexer and Level Changer Modules)
The numbered outputs are connected to the unknown resistors, which are then connected to
ground
48
(Schematic 5 – Current Sources, Dual Multiplexer and Level Changer)
49
(IV) Program Code
Auto.bas
function auto
if currentcard()<0 then
lcd
lcdcls
a3$=" INSERT SD CARD"
lcdlp(3,0)
lcds(a3$)
print " TERMINAL READY"
new
else
cd b:\mainprog
run start
endif
endf
//
Calibrat.bas
//Calibration function
//Take reading at high T, the
AD595AQ is designed to give
linear temp
//response
//Default Settings
constant MAX_V# 3.3
//Maximum ADC voltage
constant BITS# 1024 //No of
ADC bits
function calibrat
lcd
keypad
lcdcls
a=fileexists(calib.cfg)
if a=1 then
callcalib
print "Already Calibrated!"
print "Channel 1:
"+format$("#.######",V_OVER_
C#)
print "Channel 2:
"+format$("#.######",V_OVER_
C2#)
print "Enter new settings?
1.Yes 0.No "
a0$=" CALIBRATION
"
a2$=" Already Calibrated!"
a3$="Channel 1: "
a4$="Channel 2: "
a7$="Overwrite? 1.Yes
0.No"
lcdcls
lcdlp(0,0)
lcdis(a0$)
lcdlp(2,0)
lcds(a2$)
lcdlp(3,0)
lcds(a3$)
lcds(format$("#.######",V_OVE
R_C#))
lcdlp(4,0)
lcds(a4$)
lcds(format$("#.######",V_OVE
R_C2#))
lcdlp(7,0)
lcdis(a7$)
MENU=kget
if MENU<>1 then
run mainmenu
endif
endif
openadc 31 0
openadc 31 1
print "Note: This assumes the
AD595AQ gives a linear
Voltage/Temp Response"
print "and that at 0C the voltage
is 0V"
a0$=" CALIBRATION
"
a2$="Enter High Temp Value"
a3$="Temp CH1: "
lcdcls
lcdlp(0,0)
lcdis(a0$)
lcdlp(2,0)
lcds(a2$)
lcdlp(3,0)
lcds(a3$)
//Establish Voltage at high T
print "Enter high temperature
reading "
HIGH_T_INPUT#=kgetmul#(5)
a4$="Temp CH2: "
lcdlp(4,0)
lcds(a4$)
HIGH_T_INPUT2#=kgetmul#(5)
print "Reading..."
HIGH_T#=0
HIGH_T2#=0
dim j
for j=1 to 1280
HIGH_T#=HIGH_T#+adc(0)
50
HIGH_T2#=HIGH_T2#+adc(1)
wait 5
if mod(j,10)=0 then
i2cwrite LCDADR 9 j/10 7
255
endif
next
HIGH_T#=HIGH_T#*(MAX_V#/
BITS#)/1280
HIGH_T2#=HIGH_T2#*(MAX_
V#/BITS#)/1280
//Calculate V/C response
VC#=HIGH_T#/HIGH_T_INPUT
#
VC2#=HIGH_T2#/HIGH_T_INP
UT2#
screen$=format$("#.######",VC#
)
screen2$=format$("#.######",VC
2#)
print "Voltage/Temp Response
is CH1: "+screen$
print "Voltage/Temp Response
is CH2: "+screen2$
print "Save? 1.Yes 0.No "
a5$="V/C CH1: "
a6$="V/C CH2: "
a7$="Save?
1.Yes 0.No"
lcdlp(5,0)
lcds(a5$)
lcds(screen$)
lcdlp(6,0)
lcds(a6$)
lcds(screen2$)
lcdlp(7,0)
lcdis(a7$)
MENU=kget
if MENU=1 then
fn=openfile("calib.cfg",'w')
write$ fn screen$+"
"+screen2$
closefile fn
endif
run mainmenu
endf
Data.bas
//DATA MANAGEMENT and
DIGITAL OUTPUT CONTROL
// 16 Channel Mutliplexer Ports
constant MA0$ "d1"
constant MA1$ "d2"
constant MA2$ "d3"
constant MA3$ "d4"
constant ME0$ "d5"
// Dual 4 Channel Current Source
Multiplexer Ports
constant CA0$ "d10"
constant CB0$ "d9"
constant CE0$ "d8"
//Current data file number check
//(Will take a few seconds if
data.cfg is missing)
//Uses "data.cfg" to keep a log of
the last file number used
//If "data.cfg" is missing, checks
for any data files so nothing
//is overwritten accidentally
function datalogcheck
cd b:\data
//Check if config file exists
a=fileexists("data.cfg")
if a=1 then
fn=openfile("data.cfg",'r')
FILENUM=read$(fn,5)
closefile fn
else
//See if any data files exist
dim j,check
for j=1 to 99
a=fileexists("data"+j+".dat")
if a=1 then
check=j
endif
//Need to wait briefly
otherwise file system crashes
wait 1
next
//If any files exist check>0
if check=0 then
print "No Data found,
Creating new Log file"
fn=openfile("data.cfg",'w')
write$ fn "0"
closefile fn
else
print "WARNING Log file
Missing but data exists!"
print "Creating new Log
starting at last data file found"
fn=openfile("data.cfg",'w')
write$ fn check
closefile fn
endif
endif
endf
// Create new data file
// Note leaves the file OPEN!
// Needs to be closed once youre
finished to prevent corruption!
function newfile
cd b:\data
fn=openfile("data.cfg",'r')
FILENUM=read$(fn,5)
closefile fn
fn=openfile("data.cfg",'w')
FILENUM=FILENUM+1
write$ fn FILENUM
closefile fn
fn=openfile("data"+FILENUM+".
dat",'w')
write$ fn ""
closefile fn
keep
endf
//Reset Log File
function resetlog
cd b:\data
input "Reset File Number? Data
may be overwritten [y/n] " choice$
if choice$=y then
fn=openfile("data.cfg",'w')
write$ fn "0"
closefile fn
endif
endf
//Reset Clock
//Clock always sets itself to an
arbitaty value
//after power outage
function resetclock
settime "00:00:0"
endf
//Write time to data file
//notes down the time in the data
file, includes CR + LF
//Note: ensure DAYS$ is also in
use
function st
51
fn=openfile("data"+FILENUM+".
dat",'a')
write$ fn
""+*0x0d+*0x0a+DAYS+*0x3a+t
ime$()
endf
//Write reading to data file
//File MUST be OPEN first
//Closefile fn if last reading taken
//Includes preceding horizontal tab
function srTEMP(VALUE#)
write$ fn
""+*0x09+format$(###.#,VALUE
#)
endf
function srVOLT(VALUE#)
write$ fn
""+*0x09+format$(#.###,VALUE
#)
endf
function srRES(VALUE#)
write$ fn
""+*0x09+format$(###.#,VALUE
#)
endf
// 30/01/10
// Call stored parameter
// Searches the file for the named
parameter PAR$, if the name is
found the
// variable PARVAL$ will contain
all following characters until an
"@" is found
// note, doesnt like files with CR or
LF
function callparam(PAR$)
parfile=openfile("config.cfg",'r')
dim
FILESTRING$[:256],STAR,PAR
VAL$,END
FILESTRING$=read$(parfile,256)
closefile parfile
STAR=instr(FILESTRING$,PAR
$)
if STAR=0 then
PARVAL$="No parameter
by that name"
else
STAR=STAR+len(PAR$)+1
PARVAL$=mid$(FILESTRING$,
STAR,256)
END=instr(PARVAL$,*0x09)
if (END-1)=len(VAL$) then
END=instr(PARVAL$,*0x09)
parfile=openfile("config.cfg",'a')
write$ parfile;STAR-1
VAL$
closefile parfile
else
print "Parameter length not
the same as original!"
endif
endif
endf
PARVAL$=left$(PARVAL$,(EN
D-1))
endif
dim FILESTRING$[:2]=0
keep
endf
// Store a parameter
function paramopen
parfile=openfile("config.cfg",'w')
write$ parfile ""+*0x09
keep
endf
function
paramstore(NAME$,VAL$)
write$ parfile
NAME$+"="+VAL$+*0x09
endf
function paramclose
write$ parfile "END"
closefile parfile
endf
// 02/02/10
// Find and change parameter
// MAKE SURE ITS THE RIGHT
LENGTH!
function
changeparam(PAR$,VAL$)
parfile=openfile("config.cfg",'r')
dim
FILESTRING$[:256],STAR,PAR
VAL$,END
FILESTRING$=read$(parfile,256)
closefile parfile
STAR=instr(FILESTRING$,PAR
$)
if STAR=0 then
PARVAL$="No parameter
by that name"
else
STAR=STAR+len(PAR$)+1
PARVAL$=mid$(FILESTRING$,
STAR,256)
// 14/02/10 Copied from main
function to keep available in flash
// 20/07/10 Updated for new main
reading program
//New Call
function callsettings
callparam(DAYSX)
DAYS=PARVAL$
callparam(TOTALTIMEX)
TOTALTIME$=PARVAL$
callparam(INTERVALX)
INTERVAL$=PARVAL$
TOTALSEC=timeconvert(TOTAL
TIME$)+(DAYS*24*60*60)
callparam(TEMPCHNX)
TEMPCHN=PARVAL$
callparam(RESISCHNX)
RESISCHN=PARVAL$
callparam(VOLTRESX)
VOLTRES=PARVAL$
callparam(PAUSEX)
PAUSE=PARVAL$
keep
endf
// 01/03/10 Edited calibration
function so settings are handled
seperatly
// to the other settings
function callcalib
fn=openfile("calib.cfg",'r')
V_OVER_C#=read$(fn,8)
space$=read$(fn,1)
V_OVER_C2#=read$(fn,8)
closefile fn
keep
endf
//Convert time string (xx:xx:xx) to
time in seconds
52
function
timeconvert(TIMESTRING$)
HOUR=mid$(TIMESTRING$,1,2
)
MIN=mid$(TIMESTRING$,4,2)
SEC=mid$(TIMESTRING$,7,2)
result
(HOUR*60*60)+(MIN*60)+SEC
endf
// 20/07/10 Select 16ch MUX
channel
//select multiplexer port, between
0 and 15
function MUXselect(CHNS)
port ME0$ 0
port MA3$ int(CHNS/8)
CHNS=mod(CHNS,8)
port MA2$ int(CHNS/4)
CHNS=mod(CHNS,4)
port MA1$ int(CHNS/2)
CHNS=mod(CHNS,2)
port MA0$ CHNS
endf
//Current source MUX, 0 to 3
function
curMUXselect(CURLEV)
port CE0$ 0
port CA0$ int(CURLEV/2)
CURLEV=mod(CURLEV,2)
port CB0$ CURLEV
endf
//Inhibit both MUXs
function MUXkill
port ME0$ 1
port CE0$ 1
endf
//Set the digital outputs for the
MUX and N-Mos
function setoutputs
setport MA0$ as output
setport MA1$ as output
setport MA2$ as output
setport MA3$ as output
setport ME0$ as output
setport CA0$ as output
setport CB0$ as output
setport CE0$ as output
port MA0$ 0
port MA1$ 0
port MA2$ 0
port MA3$ 0
port ME0$ 1
port CA0$ 0
port CB0$ 0
port CE0$ 1
endf
// ----------------- DATA
MANAGEMENT END ------------------
entercon.bas
//Check for, show and enter
experimental settings
function entercon
lcd
keypad
lcdcls
a=fileexists(config.cfg)
a0$="EXPERIMATAL
SETTINGS"
a1$="Duration: "
a2$="Interval: "
a3$="Temp Chn: "
a4$=" MUX Chn: "
a5$="Volt/Res: "
a6$=" Pause: "
a7$="Overwrite? 1.Yes 0.No"
MENU=1
if a=1 then
callsettings
lcdcls
lcdlp(0,0)
lcdis(a0$)
lcdlp(1,0)
lcds(a1$)
lcds(DAYS)
lcdc(58)
lcds(TOTALTIME$)
lcdlp(2,0)
lcds(a2$)
a$=" "
lcds(a$)
lcds(INTERVAL$)
lcdlp(3,0)
lcds(a3$)
lcds(TEMPCHN)
lcdlp(4,0)
lcds(a4$)
lcds(RESISCHN)
lcdlp(5,0)
lcds(a5$)
if VOLTRES=0 then
lcds(Volt)
else
lcds(Res)
endif
lcdlp(6,0)
lcds(a6$)
lcds(PAUSE)
lcds(ms)
lcdlp(7,0)
lcdis(a7$)
MENU=kget
endif
//Input new settings
if MENU=1 then
lcdcls
lcdlp(0,0)
lcdis(a0$)
paramopen
a7$=" Format: dd:hh:mm:ss "
lcdlp(7,0)
lcdis(a7$)
lcdlp(1,0)
lcds(a1$)
//[:3] is used to set the string
length to save memory
dim
DAYS$[:3],HOURS$[:3],MINS$[
:3],SECS$[:3]
//First get the days of experimental
length
DAYS$=kget
lcds(DAYS$)
DAY$=kget
lcds(DAY$)
DAYS$=DAYS$+DAY$
lcdc(58)
dim j
TOTALTIME$=""
//This gets the time in the 00:00:00
format
for j=1 to 8
select j
case 3
lcdc(58)
TOTALTIME$=TOTALTIME$+"
:"
case 6
lcdc(58)
TOTALTIME$=TOTALTIME$+"
:"
default
TIME$=kget
lcds(TIME$)
TOTALTIME$=TOTALTIME$+
TIME$
endselect
next
paramstore(DAYSX,DAYS$)
53
paramstore(TOTALTIMEX,TOT
ALTIME$)
//Get interval in seconds 'ss'
a7$=" Format: hh:mm:ss "
lcdlp(7,0)
lcdis(a7$)
lcdlp(2,0)
lcds(a2$)
lcds(a$)
INTERVAL$=""
for j=1 to 8
select j
case 3
lcdc(58)
INTERVAL$=INTERVAL$+":"
case 6
lcdc(58)
INTERVAL$=INTERVAL$+":"
default
TIME$=kget
lcds(TIME$)
INTERVAL$=INTERVAL$+TIM
E$
endselect
next
paramstore(INTERVALX,INTER
VAL$)
//No of temp channels
a7$=" No of Temp channels "
lcdlp(7,0)
lcdis(a7$)
lcdlp(3,0)
lcds(a3$)
j=0
while j=0
TEMPCHN$=kget
if TEMPCHN$>2 then
a7$=" Must be 0, 1, or 2
"
lcdlp(7,0)
lcdis(a7$)
else
lcdlp(3,10)
lcds(TEMPCHN$)
j=1
endif
wend
paramstore(TEMPCHNX,TEMPC
HN$)
//No of resistor channels
a7$="Multiplexer Channels "
lcdlp(7,0)
lcdis(a7$)
lcdlp(4,0)
lcds(a4$)
j=0
while j=0
lcdlp(4,10)
RESISCHN=kgetmul#(2)
if RESISCHN>16 then
a7$=" Must be 0 to 16
"
lcdlp(7,0)
lcdis(a7$)
lcdlp(4,10)
lcdc(32)
lcdc(32)
else
lcdlp(4,10)
lcds(RESISCHN)
j=1
endif
wend
RESISCHN$=RESISCHN
paramstore(RESISCHNX,RESISC
HN$)
//Set Current Level
a7$="Voltage / Resistance"
lcdlp(7,0)
lcdis(a7$)
lcdlp(5,0)
lcds(a5$)
j=0
while j=0
VOLTRES$=kget
if VOLTRES$>1 then
a7$=" Must be 0 to 1
"
lcdlp(7,0)
lcdis(a7$)
else
lcdlp(5,10)
if VOLTRES$=0 then
lcds(Volt)
else
lcds(Res)
endif
j=1
endif
wend
paramstore(VOLTRESX,VOLTR
ES$)
//Pause between current on and
reading
a7$="Pause B4 Reading
(ms)"
lcdlp(7,0)
lcdis(a7$)
lcdlp(6,0)
lcds(a6$)
PAUSE$=kgetmul#(4)
paramstore(PAUSEX,PAUSE$)
paramclose
lcdlp(7,0)
a7$="
Done
"
lcdis(a7$)
wait 1500
endif
run mainmenu
endf
keypad.bas
//Keypad interface
//Multiple value call "kgetmul#()"
uses LCD subroutines
constant KEYADR 0x62
//Initialisation
function keypad
i2copen 400000
if i2ctest(KEYADR) = 0 then
print "Device not connected
at address ";hex$(KEYADR)
endif
dim
keys[16],keychk[1],keyrun,w,v
keep
endf
//Check for keys in buffer
function keycheck
i2cwrite KEYADR 1
i2cread KEYADR, keychk[1];1
endf
//Get keys from buffer
function keyread
i2cwrite KEYADR 4
i2cread KEYADR,
keys[1];keychk[1]
keychk[1]=0
endf
//Wait for and return number input
(or * or #)
function kget
w=0
while w=0
keycheck
keychk=keychk[1]
if keychk>0 then
keyread
keys=keys[1]
54
w=1
endif
if key?(2)=1 then
keys=key(2)
keys=keys-48
if keys=-13 then
keys=10
endif
if keys=-6 then
keys=11
endif
w=1
if keys<0 then
w=0
endif
if keys>11 then
w=0
endif
endif
wend
result keys
endf
//Enter a multiple digit number inc
"." with # to complete
//Also prints to LCD so must set
line and position first!
//SIZE sets a limit on digits to be
entered
//Note "." counts as a digit toward
SIZE
function kgetmul#(SIZE)
v=0
ordmag=1
sign=1
kval=0
kvalt#=0
CSIZE=0
while v=0
kval=kget
breakif kval=10
if kval=11 then
if sign=-1 then
goto goto1
endif
sign=-1
CSIZE=CSIZE+1
lcdc(46)
goto goto1
endif
if sign=1 then
kvalt#=kval+kvalt#*10
CSIZE=CSIZE+1
endif
if sign=-1 then
kvalt#=kvalt#+kval*(10^(ordmag*
sign))
ordmag=ordmag+1
CSIZE=CSIZE+1
endif
lcds(kval)
label goto1
breakif SIZE=CSIZE
wend
result kvalt#
endf
lcd.bas
// LCD Control
constant LCDADR 0x42
function lcdhelp
print
print "Functions - lcdinit"
print "
lcdc(char)"
print "
lcds(string)"
print "
lcdlp(line,pos)"
print "
lcdcls"
print "
lcdhline(x,y,length)"
print "
lcdvline(x,y,length)"
print " x=0 to 127 y=0 to 63"
print "
lcdnbox(x,y,xlength,ylength"
print "
lcdfbox(x,y,xlength,ylength"
print
endf
// initialise and check address
function lcd
i2copen 400000
if i2ctest(LCDADR) = 0 then
print "Device not connected
at address ";hex$(LCDADR)
endif
endf
// ----------- Text functions --------------------//
// put character to display
function lcdc(c)
i2cwrite LCDADR 0x20 c
endf
// put inverted colour character to
display
function lcdic(c)
i2cwrite LCDADR 0x21 c
endf
function lcds(s$)
dim j
for j = 1 to len(s$)
lcdc(asc(s$,j))
next
endf
// print inverted colour string
function lcdis(s$)
dim j
for j = 1 to len(s$)
lcdic(asc(s$,j))
next
endf
// set line and current position, line
is 0 or 7 snd
// postion is 0 to 20
function lcdlp(line,pos)
i2cwrite LCDADR 0x25 line
pos // set line & pos
endf
// clear screen and home cursor
function lcdcls
i2cwrite LCDADR 0x05
endf
// -------------- Graphic Functions --------------//
// Draw horizontal and vertical
lines atarting at given
// co-ordimates where
// x: horixontal 0-127
// y: vertical 0-63
function lcdhline(x,y, length)
i2cwrite LCDADR 0x12 x y
length
endf
function lcdvline(x,y, length)
i2cwrite LCDADR 0x14 x y
length
endf
//
// Draws a box N no fill F filled
// x,y are the top left hand corner
of the box and
// xl, yl are the lengths of the sides
function lcdnbox(x,y,xl,yl)
i2cwrite LCDADR 0x16 x y xl
yl
endf
function lcdfbox(x,y,xl,yl)
i2cwrite LCDADR 0x18 x y xl
yl
endf
// prints string to display
55
mainmenu.bas
//Main Program Main Menu
function mainmenu
lcd
keypad
lcdcls
print
print " THERMOCOUPLE
READING PROGRAM"
print " -------------------------------"
print
print " 1. Begin temperature
logging"
print " 2. Calibrate the
thermocouple"
print " 3. Enter configuration
settings"
print " 4. Reset configuration"
print " 5. Plotter BETA"
print " 6. Current Source
BETA"
print " 9. Run Snake"
print
a0$=" MAIN MENU
"
a2$="1.Begin Data-Logging"
a3$="2.Calibrate TC"
a4$="3.Configure"
a5$="4.Reset Configuration"
a6$="5.Run Plotter BETA"
a7$="6.Current Source BETA"
lcdlp(0,0)
lcdis(a0$)
lcdlp(2,0)
lcds(a2$)
lcdlp(3,0)
lcds(a3$)
lcdlp(4,0)
lcds(a4$)
lcdlp(5,0)
lcds(a5$)
lcdlp(6,0)
lcds(a6$)
lcdlp(7,0)
lcds(a7$)
MENU=kget
select MENU
case 1
run readstar
case 2
run calibrat
case 3
run entercon
case 4
run resetcon
case 5
run plotter
case 6
run pulstart
case 9
run snake
case 0
lcdcls
a3$=" Consult PC
Terminal"
lcdlp(3,0)
lcds(a3$)
print " EXIT"
new
default
run mainmenu
endselect
endf
lcdlp(0,0)
lcdis(a0$)
lcdlp(2,0)
lcds(a2$)
lcdlp(3,0)
lcds(a3$)
lcdlp(4,0)
lcds(a4$)
lcdlp(5,0)
lcds(a5$)
lcdlp(6,0)
lcds(a6$)
lcdlp(7,0)
lcds(a7$)
endf
// Convert second array of y points
to a byte matrix suitable for direct
sending
// to the LCD and SUM them to
the final byte matrix
function convertmatrixsum
for CP=1 to 128
PLOT=63-MATRIXD&[CP]
BYTE=mod(PLOT,8)
PLOT=(PLOT-BYTE)/8
BYTE=2^(BYTE)
plotterbeta.bas
//Fast map of byte matrix to screen
~ 3.55s
//Note: The bytes have to be
mapped in this unusual order due
to unexpected bad
//
behaviour from LCD, this
only affects the mapping time by a
few ms
function bytemap
lcdcls
dim i,j,k
CP=0
for j=0 to 1
for i=0 to 7
i2cwrite LCDADR 8 i
i2cwrite LCDADR 7 64*j
for k=0 to 63
i2cwrite LCDADR 3
MATRIXB&[(64*j)+k+1,i+1]
CP=CP+1
next
next
next
endf
//Compare two arrays of y points,
if two points are the same then
clear one
//to prevent duplication
function comparematrix
for CP=1 to 128
if
MATRIXC&[CP]=MATRIXD&[
CP] then
MATRIXD&[CP]=64
endif
next
endf
//Plotter Beta
function plotter
lcd
keypad
lcdcls
showmenu
dim
MATRIXC&[128],MATRIXD&[1
28],TIMERES,CP,MATRIXB&[1
28,8]
MENU=kget
select MENU
case 1
tester(1)
case 2
tester(2)
case 3
tester(3)
case 4
test1
case 5
test2
case 6
run mainmenu
default
run plotter
endselect
keep
endf
//LCD Menu
function showmenu
a0$=" PLOTTER (BETA) "
a2$="1.Plot Linear"
a3$="2.Plot Exp"
a4$="3.Plot Sinusoidal"
a5$="4.Plot Exp&Sine"
a6$="5.Plot Combination"
a7$="6.Return to Main Menu"
MATRIXB&[CP,PLOT+1]=BYT
E+MATRIXB&[CP,PLOT+1]
next
endf
//Convert array of y points to a
byte matrix suitable for direct
sending to
//the LCD
function convertmatrix
for CP=1 to 128
PLOT=63-MATRIXC&[CP]
BYTE=mod(PLOT,8)
PLOT=(PLOT-BYTE)/8
BYTE=2^(BYTE)
MATRIXB&[CP,PLOT+1]=BYT
E
next
endf
56
//Clear Bytemap
function clearbytemap
dim i,j
for i=1 to 128
for j=1 to 8
MATRIXB$[i,j]=0
next
next
endf
//TEST: Combine two functions
and plot
function test1
calc
for TIMERES=1 to 128
MATRIXC&[TIMERES]=33+int(
31*sin(2*PI*TIMERES/128))
MATRIXD&[TIMERES]=int(64^
(TIMERES/128))
next
comparematrix
convertmatrix
convertmatrixsum
bytemap
wait 2500
run plotter
endf
SECON=kgetmul#(1)
calc
for TIMERES=1 to 128
MATRIXC&[TIMERES]=choose
plot(FIRST,TIMERES)
//TEST: Compose a standard array
of y points for a plot, convert to
//the suitable byte matrix, and send
via the FAST mapping function
function tester(MEN)
calc
select MEN
case 1
for TIMERES=1 to 128
MATRIXC&[TIMERES]=lin(TI
MERES)
next
case 2
for TIMERES=1 to 128
MATRIXC&[TIMERES]=exp(TI
MERES)
next
case 3
for TIMERES=1 to 128
MATRIXC&[TIMERES]=sine(TI
MERES)
next
endselect
convertmatrix
bytemap
wait 2500
run plotter
endf
//test any two functions
function test2
lcdcls
a2$=" First function: "
a3$=" Second function: "
a5$=" 1.Lin 2.Inv-Lin"
a6$=" 3.Exp 4.Inv-Exp"
a7$=" 5.Sine 6.Inv-Sine"
lcdlp(5,0)
lcds(a5$)
lcdlp(6,0)
lcds(a6$)
lcdlp(7,0)
lcds(a7$)
lcdlp(2,0)
lcds(a2$)
FIRST=kgetmul#(1)
lcdlp(3,0)
lcds(a3$)
MATRIXD&[TIMERES]=choose
plot(SECON,TIMERES)
next
comparematrix
convertmatrix
convertmatrixsum
bytemap
wait 2500
run plotter
endf
function chooseplot(PL,VA)
select PL
case 2
PV=ilin(VA)
case 3
PV=exp(VA)
case 4
PV=iexp(VA)
case 5
PV=sine(VA)
case 6
PV=isine(VA)
default
PV=lin(VA)
endselect
result PV
endf
function lin(VAL)
result int((VAL)/2)
endf
function ilin(VAL)
result 64-int((VAL)/2)
endf
function exp(VAL)
result int(64^(VAL/128))
endf
function iexp(VAL)
result 64-int(64^(VAL/128))
endf
function sine(VAL)
result
33+int(31*sin(2*PI*VAL/128))
endf
function isine(VAL)
57
result 31int(31*sin(2*PI*VAL/128))
endf
function calc
lcdcls
a3$="CALCULATING"
lcdlp(3,5)
lcds(a3$)
endf
readstar.bas
//Main Data Logging program
//Default Settings
constant MAX_V# 3.3
//Maximum ADC voltage
constant PUL_V# 15 //Current
source voltage
constant BITS# 1024 //No of
ADC bits
constant GAIN# 10
//Op-amp
gain
constant THRESHOLDMAX#
14.28 //Voltage maximum before
droping the current
constant OFFSET# 1
//Additonal MUX resistance
// Current Levels
constant CUR0# 10.23
constant CUR1# 5.350
constant CUR2# 1.014
constant CUR3# 0.515
function readstar
//Set up main program
dim
fn,i,j,k,READING#[2],CURRENT
&[16]
keep
lcd
keypad
lcdcls
a0$=" DATA LOGGING "
a3$="
TESTING"
a7$=" Press # to Exit "
lcdlp(0,0)
lcdis(a0$)
lcdlp(3,0)
lcds(a3$)
lcdlp(7,0)
lcdis(a7$)
a=fileexists("config.cfg")
if a=0 then
configerror
endif
a=fileexists("calib.cfg")
if a=0 then
configerror
endif
callsettings
callcalib
setoutputs
for k=0 to 2
openadc 30 k
next
//Check all resisors are grounded
for k=1 to RESISCHN
m=k-1
MUXselect(m)
READINGZ#=readvoltage
if READINGZ#>0.1 then
a3$=" CHECK
CHANNEL: "
a4$=" CONNECTION!
"
lcdlp(3,0)
lcds(a3$)
lcds(k)
lcdlp(4,0)
lcds(a4$)
wait 3000
cd b:\mainprog
run mainmenu
endif
next
//Get data file ready
datalogcheck
newfile
//Find out current level to use
fn=openfile("data"+FILENUM+".
dat",'a')
write$ fn "Current: "
if TEMPCHN>0 then
for j=1 to TEMPCHN
write$ fn ""+*0x09
next
endif
for k=1 to RESISCHN
m=k-1
MUXselect(m)
A=testcurrent
CURRENT&[k]=A
print CURRENT&[k]
write$ fn ""+*0x09+A
next
write$ fn
""+*0x0d+*0x0a+*0x0d+*0x0a
closefile fn
//-------------resetclock
NEXTTIME%=0
DAYSX=0
a3$="
"
lcdlp(3,0)
lcds(a3$)
a2$="Temp1:"
a3$="Temp2:"
a5$="Elapsed:"
a6$=" Total: "
if TEMPCHN>0 then
lcdlp(2,0)
lcds(a2$)
endif
if TEMPCHN>1 then
lcdlp(2,10)
lcds(a3$)
endif
lcdlp(5,0)
lcds(a5$)
lcdlp(6,0)
lcds(a6$)
if DAYS<10 then
lcdc(48)
endif
lcds(DAYS)
lcdc(58)
lcds(TOTALTIME$)
//Give titles to the readings in the
file
fn=openfile("data"+FILENUM+".
dat",'a')
write$ fn "TIME "
if TEMPCHN>0 then
for j=1 to TEMPCHN
write$ fn
""+*0x09+TEMP+j
next
endif
if RESISCHN>0 then
for j=1 to RESISCHN
if VOLTRES=0 then
write$ fn
""+*0x09+VOLT+j
else
write$ fn
""+*0x09+RES+j
endif
next
endif
closefile fn
//Begin data logging
TIMESTR$=time$()
INTERVAL=timeconvert(INTER
VAL$)
while
(DAYSX*86400)+timeconvert(ti
me$())<=TOTALSEC
//Print time every second
if TIMESTR$<>time$() then
58
lcdlp(5,9)
if DAYSX<10 then
lcdc(48)
lcds(DAYSX)
lcdlp(5,11)
else
lcds(DAYSX)
endif
lcdc(58)
lcds(time$())
TIMESTR$=time$()
endif
//Take readings
if
NEXTTIME%<=(DAYSX*86400
)+timeconvert(time$()) then
lcdlp(1,7)
lcds(READING)
print
print time$()+" ";
st
if TEMPCHN>0 then
readtemp
endif
if RESISCHN>0 then
for k=1 to RESISCHN
m=k-1
A=CURRENT&[k]
MUXselect(m)
curMUXselect(A)
wait PAUSE
READINGZ#=readvoltage
MUXkill
select A
case 0
CURL#=CUR0#
case 1
CURL#=CUR1#
case 2
CURL#=CUR2#
case 3
CURL#=CUR3#
endselect
READINGZ#=READING#[1]
READINGZ#=READINGZ#/GAI
N#
if VOLTRES=0 then
print
format$(#.###,READINGZ#)+"
";
srVOLT(READINGZ#)
else
READINGZ#=(1000*READING
Z#/CURL#)-OFFSET#
print
format$(###.#,READINGZ#)+"
";
srRES(READINGZ#)
endif
next
endif
closefile fn
lcdlp(1,7)
a0$="
"
lcds(a0$)
NEXTTIME%=NEXTTIME%+IN
TERVAL
lcdlp(2,20)
lcdc(32)
lcdlp(3,20)
lcdc(32)
endif
//Loop Break
breakif key?(2)=1
keycheck
if keychk[1]>1 then
keyread
endif
breakif keys[1]=10
//Increment DAYSX counter at
23:59:59
if
timeconvert(time$())=86399 then
resetclock
DAYSX=DAYSX+1
wait 800
endif
wend
//Finish
closefile fn
print "Finished"
cd b:\mainprog
run mainmenu
endf
function configerror
print "Must set configuration
first!"
a2$=" Must enter"
a3$=" configuration"
a4$=" settings first!"
lcdlp(2,0)
lcds(a2$)
lcdlp(3,0)
lcds(a3$)
lcdlp(4,0)
lcds(a4$)
wait 1500
run mainmenu
endf
function readtemp
for j=1 to 200
for k=1 to TEMPCHN
m=k-1
READING#[k]=READING#[k]+a
dc(m)
next
next
j=j-1
for k=1 to TEMPCHN
select k
case 1
READING#[k]=READING#[k]*(
MAX_V#/BITS#)/(j*V_OVER_C
#)
print
format$(###.#,READING#[k])+"
";
lcdlp(2,6)
lcds(format$(###,READING#[1]))
srTEMP(READING#[k])
case 2
READING#[k]=READING#[k]*(
MAX_V#/BITS#)/(j*V_OVER_C
2#)
print
format$(###.#,READING#[k])+"
";
lcdlp(2,16)
lcds(format$(###,READING#[2]))
srTEMP(READING#[k])
endselect
READING#[k]=0
next
endf
function readvoltage
for j=1 to 200
READING#[1]=READING#[1]+a
dc(2)
next
j=j-1
READING#[1]=READING#[1]*(
PUL_V#/BITS#)/j
result READING#[1]
59
endf
function testcurrent
i=0
CURSET=0
while i<4
curMUXselect(i)
wait 50
for j=1 to 10
READING#[1]=READING#[1]+a
dc(2)
next
port CE0$ 1
j=j-1
READING#[1]=READING#[1]*(
PUL_V#/BITS#)/j
print READING#[1]+" ";
if READING#[1] >
THRESHOLDMAX# then
i=i+1
else
CURSET=i
i=4
endif
wend
result CURSET
endf
//
//
resetcon.bas
//Reset Configuration
function resetcon
lcd
keypad
lcdcls
a0$=" RESET
CONFIGURATION "
lcdlp(0,0)
lcdis(a0$)
a=fileexists(config.cfg)
if a=1 then
a2$=" Confirm Deletion? "
lcdlp(2,0)
lcds(a2$)
a3$=" CONFIG.CFG"
lcdlp(3,0)
lcds(a3$)
a7$=" 1.Yes 0.No "
lcdlp(7.0)
lcdis(a7$)
MENU=kget
if MENU=1 then
del config.cfg
a7$="
DONE
"
lcdlp(7,0)
lcdis(a7$)
wait 1500
endif
else
a2$="CONFIG.CFG not
found!"
lcdlp(2,0)
lcds(a2$)
wait 1500
endif
run mainmenu
endf
splash.bas
//Splash screen
function splash
lcd
lcdcls
a$=" Implanted
"
b$=" Devices Group "
c$=" Automated
"
d$=" Data-logger "
lcdnbox(0,0,128,64)
lcdlp(1,0)
lcds(a$)
lcdlp(2,0)
lcds(b$)
lcdhline(6,30,116)
lcdhline(8,32,112)
lcdlp(5,0)
lcds(c$)
lcdlp(6,0)
lcds(d$)
wait 2000
a$=" Designed and Built "
b$="
by
"
c$=" Alex Messenger "
Lines: 1482
60
d$="
2010
"
lcdlp(1,0)
lcds(a$)
lcdlp(2,0)
lcds(b$)
lcdhline(6,30,116)
lcdhline(8,32,112)
lcdlp(5,0)
lcds(c$)
lcdlp(6,0)
lcds(d$)
wait 1500
lcdfbox(0,0,128,64)
i2cwrite LCDADR 0x19 0 0
128 64
lcdcls
endf
(V) Contact details
Alexander James Messenger
a.j.messenger@live.com
12 Milton Lane
01732 874159
Kings Hill
07989 363425
West Malling
Kent
ME19 4HP
61
Download