Our final project involved the design of a fully functional, multi-purpose digital thermometer. This was our attempt at producing a portable device that could be widely used for a variety of different purposes. For example, think of the many situations where the precise measurement of temperature is of high importance. Temperature control and monitoring is important in homes for the comfort of its occupants... it is important for gardeners who want to carefully monitor the atmospheric conditions within a greenhouse... it is important in ensuring the correct operation of various electronic devices where many components may have a sensitive dependence on temperature.
Furthermore, our portable digital thermometer could be valuable as a scientific tool in the laboratory. Its ability to accurately measure temperatures to within .1° in FOUR (yes, count them, four!) temperature scales (Fahrenheit, Celsius, Kelvin, and Rankine) adds to its functionality. Just think, no need to go to a table anymore to convert a temperature you just measured to another scale! As a household device, our multi-function digital thermometer is useful for its ability to carefully record and store the extreme temperatures reached in its environment. By simply pressing the appropriate button on its user interface, you can easily display the maximum or minimum value recorded.
Likewise, our digital thermometer comes equipped with an alarm feature which allows the user to program a specific temperature range. This is accomplished by entering lower and upper bound temperatures via four push buttons on the user interface. When the temperature recorded by this device crosses one of these boundary points, the "alarm" is triggered by flashing a message (HOT! or COLD) in the display window. Additional functionality has been added to this feature regarding the options for changing these boundary temperatures, which will be explained later.
In addition, whenever the ambient temperature reaches either of the extreme "alarm" temperatures, one of the port pins goes active low (i.e. turns ON). PortB[6] is low when it is too hot, and PortB[7] is low when it is too cold. The user can easily interface with these two port pins to add any kind of functionality desired.
Overall, this feature, in particular, greatly extends the applicability of our digital thermometer. The temperature-range interrupt feature could enable this device as a control unit which drives an air conditioner, fan, or heater in a climate controlled environment... or it could send a control signal to turn on a sprinkler system if the upper threshold is passed. The possibilities are endless!
Our digital thermometer is driven by an Atmel AT90S/L8535 microcontroller chip which controls and interfaces with our different I/O components. The various I/O components include:
- An array of 7 push buttons which accept user input and form the user interface
- A 16 X 1 LCD display for easy viewing of temperature values and messages
- A National Semiconductor LM 34 Precision Fahrenheit Temperature Sensor (3 pin)
We chose the LM 34 temperature sensor over other temperature sensing devices (such as the LM 35) due to its accuracy. Its base temperature scale is in Fahrenheit which has a higher resolution than the Celsius scale. Furthermore, it allows us to accurately record temperatures down to .1°F since a 10 mV change on the Vout pin of the sensor corresponds to a 1°F temperature change (Thus a 1 mV change corresponds to a .1°F change).
Using the LM 34, we are able to display temperatures in 4 different scales: Fahrenheit (the base scale), Celsius, Kelvin, and Rankine. Conversions are based on the following formulas:
- °F (measured)
- °C = 5/9 (°F - 32)
- °K = °C + 273 = 5/9 (°F - 32) + 273
- °R = °F + 460
Additionally, we take advantage of the built-in ADC (Analog-to-Digital Converter) on our 8535 chip to process our analog temperature/voltage waveform... Since the temperature is actually measured as a continuous voltage waveform, we need to take discrete samples of the voltage at a regular time period -- in our case this was 50 ms. Calculations are then performed within the program to do the necessary conversions.
Finally, we decided to use a 16 X 1 LCD display for the visual display since it gave us just enough room to display a temperature and alarm message if necessary. Moreover, the large font size makes for easier reading. Although this is actually the largest component in our device, it is still small enough to ensure that our entire device can be packaged into a small portable unit.
Before we wrote any assembly code for our digital thermometer, we first aimed to describe our device in a behavioral sense by writing pseudocode. This forced us to understand the order and timing of various events that we wanted to occur. To accomplish this task, we decided that the cleanest way to execute events was to have a main program loop which scheduled a sequence of tasks every 50ms. The tasks to be executed would come in the following order (in pseudocode):
main{-check if 50 ms reached....brne mainthis code every 50 ms -get the s// executetate of the push buttons (i.e. pushed, held, released...)-reload 50 ms timer -sample the current temperaturery... -clear LCD (get ready to display) -update various s-update the extreme temperatures (max/min) if necess aettings (as received by the push buttons) -toggle between temperature scales (if called for)e (if called for) -convert temperature value to appr-inc/dec max/min alarm temperatures (if called for) -display the recorded max/min temperatu ropriate scale -display the temperature -display °[F, C, K, or R] -check to see if alarm temperature reached rjmp main}
From this behavioral model, we then began writing the assembly code, using the pseudocode as a skeleton. We encapsulated each of the different tasks as a separate function to increase the modularity of our program and to make the main loop clean and easy to follow.
To avoid possible register conflicts (or a lack of registers in general), we chose to locally define the registers we needed within a given subroutine. Moreover, we stored most of the variables that we use in our program in SRAM. String constants are stored in FLASH. To make the program easier to read (and thus be modified later on) we chose to give many memory locations the same name as the registers which would temporarily use the values at these locations.
One interesting feature that we incorporated into our digital thermometer was a variable speed increment/decrement of the alarm temperatures...a characteristic common among many digital alarm clocks. Our works as follows: If one of the 4 buttons that control incrementation/ decrementation of the alarm temperatures ispressed (for less than 1 sec), then the temperature value changes by steps of .1°F. If the button is held (for >1 sec), then the temperature value changes by steps of .5°F. The coding for this feature was simplified by having a well designed state machine (debouncer) within the button status procedure.
One additional goal of our device, in attempt to make something that would be small and have a low cost overhead, was to have a compact code size. This forced us to look for various ways to optimize our code, and if possible, share areas of common code. For example, one section of code where this was possible was within the "ConvertTemp" procedure. We shared the code which calculates °C = 5/9 (°F - 32) with the Kelvin conversion code since °K = °C + 273. Also, in the "UpdateSettings" routine, there are 2 instances where both MinPrompt and MaxPrompt are called, but we only need a single copy of each.
Finally, other characteristics of our source code include:
- 3 dedicated routines to display characters/strings on the LCD
- 1 routine, "Bin2ASC", which converts a binary temperature value stored in SRAM ("disptemp") into ASCII in the form "xxx.x°[F, C, K, or R]" and stores the ASCII string into SRAM ("ASCIItemp")
- 1 timer overflow ISR (interrupts every 1 ms)
- 1 flag to indicate if a temperature is negative, "isneg"...this occurs for Celsius temperatures where °F - 32 < 0.
In terms of hardware, our device makes use of all 4 ports on the Atmel chip.
- Port A interfaces with the LM34 temperature sensor.
- Port B interfaces with any "add-ons" such as a fan or heater (here's it's an LED)
- Port C interfaces with the LCD. We chose to use Port C as opposed to Port D (as was used in the reference LCD code) because the push buttons are connected to Port D on the STK-200 development board.
- PortD is connected to the push buttons.
The wiring scheme for the LCD display is as follows:
LCDpin Connection------ ----------2 +5 vo1 gnd lts - from a port piner (trimpot ends go to gnd and +5) 4 PortC63 trimpot wi p 5 PortC5 6 PortC4 7-10 no connection4 PortC311 PortC0 12 PortC1 13 PortC21
Ease of Use
Our thermometer is very easy to use. The increment and decrement buttons mimic those of an alarm clock. When any of these buttons are held down for a long time (> 1 sec), the increment and decrement amounts change from a step size of .1° to .5°. Similarly, you can change temperature scales simply by repeatedly pressing a toggle button. The recorded maximum and minimum temperatures are also easily displayed by pressing the display max or display min push buttons.
Accuracy
Our digital thermometer is accurate in measuring temperatures to within .1°. Fahrenheit (°F) is used as the base temperature scale, and all conversions are made from this temperature scale. Formulas for computing the other scales are as follows:
- °C = 5/9 (°F - 32)
- °K = °C + 273 = 5/9 (°F - 32) + 273
- °R = °F + 460
We tested our conversion source code for several temperature values in °F, and the corresponding values in °C, °K, and °R were all within .2° of the expected values, but mostly within .1°...(see table below) Pretty good considering minor truncations are unavoidable when performing divisions such as 1/9. Notice, too, how these slight aberrations only occur for the Celsius and Kelvin values.
°F (base value) | Measured °C | Expected °C | Measured °K | Expected °K | Measured °R | Expected °R |
65.0 | 18.3 | 18.33 | 291.3 | 291.33 | 525 | 525 |
71.9 | 22.1 | 22.166 | 295.2 | 295.166 | 531.9 | 531.9 |
75.0 | 23.8 | 23.88 | 296.8 | 296.88 | 535 | 535 |
80.3 | 26.7 | 26.833 | 299.7 | 299.833 | 540.3 | 540.3 |
Extendability
As mentioned earlier, the feature of being able to detect temperature boundaries set by the user makes our digital thermometer very extendable. Port pins B[7] and B[6] go active low when it is either too hot or too cold, respectively. Thus, this could act as the control signal to drive/trigger an external device such as a fan, heater, safety valve, etc...
After going through the many stages of design and then finally testing and verification of our multi-purpose digital thermometer, there are many ideas that we came up with along the way; ideas to enhance this project if we were to do it again or change our existing design approach.
Ideas
- Modify the existing LCD code to contain a 32 byte buffer - 16 bytes to contain the current display, and 16 bytes to contain data that is queued to be displayed. If the two halves are different, a highly optimized routine displays the output buffer on the LCD. This reduces the flicker on the display, noticeable on cheap LCDs.
- Use nonvolatile memory to store data, such as alarm temperatures, or to log temperature. The temperature data can then be exported through a RS232 interface to a computer, and analyzed. A more advanced model could measure other quantities, such as air pressure, and use some heuristics to predict the weather (all on one chip).
- Change the button interface to use chording to control functions. This will reduce the amount of buttons (and data lines) required to interface with the outside world.
File Listing:
- final.asm - The main assembly file
- lcdc.asm - The assembly file for various LCD functions
- 8535def.inc - The include file for Atmel AT90S/L8535 micrcontrollers
LM 34 Fahrenheit temperature sensor
View of LCD display and LM 34 sensor
Schematic of push buttons/ functions
0 comments:
Post a Comment