Sun Jan 10 13:50:01 EST 2010
Using a USB-based temperature sensor, a windows-based temperature logging application will be developed which logs temperature over time. As well as the use of advanced windows contols and dialog boxes, the application will use multithreading to access the hardware including semaphores to interlock processes.
This Win32 application will do the following:
Via a menu item (Start) on the main window, ask the user for startup parameters such as sample interval (the time between samples) via a dialog box. This time can vary between 1 second and 60 seconds in length.
A thread will be used to read the temperature via a USB interface.
Once converted to actual temperatures, temperature vs. time will be displayed in a graph format on the main window (with time in seconds on the x-axis and temperature in degrees C on the y-axis).
After acquisition of data, data may be copied to the windows clipboard or saved to a text file as data pairs. A dialog box is required to get the filename (using GetSaveFileName).
The basic graph will look like this (from a 1994 article by Michael Covington in which a similar application was developed):

... of course yours will be in Celsius (not Fahrenheit as shown here), there are two possible ranges which can be selected based on the thermistor in use, and the X-axis will display sample time in seconds/minutes.
An advanced dialog box is required to allow the user to enter (via the keyboard) an integer for a sampling interval. This interval is placed into data which is accessible by both the thread and the windows proc. On the same dialog box, radio buttons select which interface to use (Joystick #1 or #2) and perhaps also the range to use (10°C to 30°C or -10°C to 50°C.)
The main window graphs data from an array to the screen. Line functions are used to display the graph which is a box. Lines are used not only for the box outline but also to demarcate intervals (e.g. every 20 samples and every degree C). The displayed x-axis must be calibrated in time (seconds) and the y-axis in temperature (degrees C). Lines are to be in black, the graph in a different colour. The display also shows, at the bottom of the screen, the sampling thread status as 'RUNNING' (in green), 'COMPLETE' (in yellow), or 'STOPPED' (in red).
As an exercise, use of GLOBAL variables should be avoided ... since you can pass a pointer to the thread, create static data structures in the windows proc and pass a pointer to the thread allowing the thread to access the data. Use of Globals will be penalized in this lab.
On startup, the thread which handles sampling is started immediately. Once the sampling parameter is selected by the user (in the main program via the dialog box), the sampling thread is started via a semaphore (using a WaitForSingleObject function in the thread) and proceeds to acquire 100 samples. The thread works by acquiring a sample from the USB interface at each sampling interval into a large array of data. Since sampling is done in a thread, a Sleep() function can be used to effect timing of samples. For example, to sample once per second the sampling thread would do the following:
Start: Wait for the samaphore to start the sampling process Do 100 times: - Acquire the sample from the interface - Send the main thread a message to redraw the graph - Sleep(1000) Goto Start
In theory, one could use a windows timer and sample from within the main windows proc however the point of this lab is learning so we will utilize a thread here (in many cases, such as Mark Csele's Logic Analyzer, a thread which can 'hang' while polling hardware must be used to interface to this hardware).
Once the thread is launched, it does NOT start sampling immediately but rather waits until a menu item 'START' is clicked to activate the thread initially.
The on-screen graph is updated continally after each sample is taken (the graph line moves to the right as data is acquired and plotted) ... it is a real-time display and is continually updated. The thread can simply send a message to the main program using the SendMessage function. When the main window receives this message it can simply draw the graph with as much data as available.
After 100 samples, the thread goes idle, waiting for the semaphore, and the application waits for a command (e.g. for the user to save the data). The user may restart sampling again (via a menu item) at which point the application clears the old data (and the on-screen graph) and resumes sampling.
The joystick interface may be used to measure resistance - that is, indeed, how an analog joystick works. The temperature sensor used in this lab is a thermistor — a resistor whose resistance is a function of temperature. Two thermistors are used on the interface with different ranges, one providing more sensitivity at room temperatures and the other providing a wider temperature range. Both thermistors are wired to Joystick #1 inputs with the X coordinate wired to an EPCOS type B57891M0224J000 thermistor and the Y coordinate wired to a MuRata type NTSD1WF104FPB30 thermistor. The "B57" type thermistor has a rated resistance of 220 kohms at 25°C and a Beta of 4600. The "NTSD1" type thermistor has a rated resistance of 100 kohms at 25°C and a Beta of 4250.
The number read from the joystick port represents resistance so it is best to convert to resistance immediately. By plotting the port value (a number, on the Y axis) versus the resistance of the joystick (in kohms, on the X axis), a slope of 151.35 and an intercept of -528.9 was found. Using the line equation y=mx+b rearranged as x=(y-b)/m we can express the resistance of the thermistor as Resistance (kohms) = (Number +528.9) / 151.35.
The complete spreadsheet [PDF; 19,230 bytes] showing data points plotted.
Now that we know the resistance of the thermistor, the fun begins because the thermistor is a non-linear device in which the resistance is an exponential function of temperature. The actual temperature in degrees Kelvin (°K) may be found according to:
T2 = (1/T1 - ln(R1/R2)/Beta)-1
where: T2 is the unknown temperature, T1 is 298.15°K (25°C), R2 is the resistance from the joystick port and R1 is the resistance at 298.15°K (25°C).
So, for a thermistor with a Beta of 3892 and R25°C=10 kohms, we convert T1=25°C to 298.15°K. If the resistance of the thermistor was found to be 7.11 kohms, the temperature could be found to be 306°K or simply 33°C.
Since the joystick port has a limited resistance range (about 225 kohms maximum) different ranges of thermistors were used allowing a wide range of temperatures to be recorded. The "NTSD1" thermistor is best utilized in the region from 0°C to 30°C (i.e., normal room temperature range) since that thermistor has a resistance of 209 kohms at 10°C whereas the "B57" thermistor with a wider range of resistance values and will hence allow higher temperature readings in the practical range 10°C to 50°C — lower temperatures will result in too high a resistance value to be effectively read.
Your application, then, must have a menu item to select which thermistor (and hence which range) is being used.
Since most computers lack a joystick port nowadays, a USB interface is provided. The joystick is used here since it is a native windows device and is supported without additional drivers under XP. Simply plug the interface into a USB connector and the joystick should be available.
On WM_CREATE, setup the joystick hardware and ensure it is available (if the USB interface is, for example, left unconnected you must detect that error). You can add a menu item allowing selection of Joystick Interface #1 or #2 as well (especially useful if you already have a joystick port on your PC but wish to use the USB interface anyway).
The above, completed perfectly, is sufficient for a mark of 70%. For the final 30% the following must be added:
Add a 'COPY' menu item which copies the screen graphics to the Windows clipboard allowing it to be pasted into another application. This requires the use of the OpenClipboard and SetClipboardData functions as well as the allocation of global system memory for the clipboard data itself.
Add a 'SAVE DATA' menu item which writes data to a selected filename in the form of (TIME,TEMP) data pairs. This requires the use of the GetSaveFileName function.
A dialog box to set the sampling interval
Radio buttons on the same dialog box to configure the joystick number/interface
A menu item or more dialog box radio buttons selection for the range to use
A menu item to start sampling initially, and restart after the system has finished
A menu item to copy the screen graphics to the windows clipboard
A menu item to save data in ASCII text form to a file
A dialog box to select the filename to save to (system)
An 'About' dialog box with your name
Marks are assigned not only to implementation of the windows controls, implementation of the thread, and all related communications (such as semaphores) but also for proper programming technique such as the avoidance of global variables, and clean-up of opened handles, etc.
The application must be completed in Visual C++ 2008 and must be able to be compiled in that environment.
On a R/W memory device (USB key or flash card), submit files for the ENTIRE PROJECT in a directory named \LAB3. This directory will contain the complete set of Visual C++ solution and project files. You may optionally do a 'build clean' to remove files that can be rebuilt anyway.
YOU MUST RETURN YOUR THERMISTOR ASSEMBLY AT THE SAME TIME.
Your project will be rebuilt during the marking process; source files in the \LAB3 directory will be left intact.
Non-working (crashing) projects will be penalized 10% and are required to be corrected. Ditto for submissions in which required files are missing prohibiting the immediate rebuilding of the project. Before submitting the lab, ensure it can be built on that memory device.
As usual, late labs lose 10% per day and receive a zero after 5 days late (April 23.)
Lab 3 notes | Back to CTEC1638 | Technology Courses | Technology at Niagara College