8/6/2019 App Note Kevin
1/40
How to Build a Basic Digital Thermometer with Serial
Interface
Developed By Kevin Scheel
ECE 480 Spring 07
3/30/2007
8/6/2019 App Note Kevin
2/40
Executive Summary:
Many consumers use digital thermometers every day and due to their usefulness theyhave become cheap and readily available. Most users only need to know if they have a
temperature or are running a fever and so a one time use and read system is preferable. In this
case outputting the result to an LCD is easier and gives the user immediate results. However,what if the user wants to keep track of their results digitally? In a situation such as this you
would want to be able to store temperatures in a file on a computer. This presents a problem
as most digital thermometers available today are meant for independent use. That is, they arenot designed to transmit their data anywhere outside the device itself. In this Application note
we will design a basic digital thermometer that can transmit the temperature data it receives to
a computer via the RS232 protocol.
This data can then be displayed by a computer program able to communicate with thedevice over serial, via a graphical or command line based program. Optionally, this data could
even be written to a database for permanent storage or simply a file for safe keeping.
Key Terms:
ADC Analog to digital converter(For more info see http://en.wikipedia.org/wiki/Analog-to-digital_converter)
MCU/PIC Microcontroller in our case this will be a PIC microcontroller used to manipulate
input analog signals to perform functions, it can be programmed using C to perform variousfunctions with a given input(s).
(for more info seehttp://en.wikipedia.org/wiki/PIC_microcontroller)
RS232 The protocol governing serial communications between electronic devices devices
(For more information on RS232 please see http://en.wikipedia.org/wiki/RS232)
GUI Graphical User Interface, a computer program utilizing a graphical method of
displaying and manipulating data via a keyboard, mouse, touch screen, stylus, etc.(For more information on GUIs please seehttp://en.wikipedia.org/wiki/GUI)
Op-Amp short for operational amplifier, this common electrical component that serves as
DC voltage amplifier. The amplification can be adjusted with the placement of varying
resistor values between the +/- inputs and the output pin.(For more information on op-amps please see http://en.wikipedia.org/wiki/Op-amp)
Thermistor a kind of resistor for which the resistance value changes based on the
temperature surrounding it.For more information on thermistors please seehttp://en.wikipedia.org/wiki/Thermistor)
Components list:Qty Part Number Description
1 PIC18F4520 Programmable microcontroller w/ ADC
1 MX045HS 40Mhz Crystal clock 1 MAX232 RS232 Line Driver/Reciever
1 Winford RJ-11 Standard 6 pin RJ-11 port for PIC programming
1 Winford DB-9 Standard DB-9 serial connector 1 LM324N Low power Op-Amp (quad)
http://en.wikipedia.org/wiki/Analog-to-digital_converterhttp://en.wikipedia.org/wiki/PIC_microcontrollerhttp://en.wikipedia.org/wiki/PIC_microcontrollerhttp://en.wikipedia.org/wiki/RS232http://en.wikipedia.org/wiki/GUIhttp://en.wikipedia.org/wiki/GUIhttp://en.wikipedia.org/wiki/Op-amphttp://en.wikipedia.org/wiki/Thermistorhttp://en.wikipedia.org/wiki/Thermistorhttp://en.wikipedia.org/wiki/Analog-to-digital_converterhttp://en.wikipedia.org/wiki/PIC_microcontrollerhttp://en.wikipedia.org/wiki/RS232http://en.wikipedia.org/wiki/GUIhttp://en.wikipedia.org/wiki/Op-amphttp://en.wikipedia.org/wiki/Thermistor8/6/2019 App Note Kevin
3/40
4 10uF capacitor
2 1 kohm resistor
1 10 kohm resistor 1 1.5 kohm resistor
1 22 ohm resistor
1 27 ohm resistor 2 Digital Thermometers with 100K ohm Thermistors
For Informationon our PIC18F4520, MAX232, and LM324 chips please see the linksin the sources section of this document.
Section A: Designing the Thermometer
Understanding how a Digital thermometer works will allow us to think about how we
wish to implement one in terms of components. A useful resource for this can be found via a
lab from the UCL department of Physics and Astronomy in the United Kingdom (found here
http://www.cmmp.ucl.ac.uk/~nts/teachinglabs/3c40-e5.pdf) .We know that a thermistor will allow us to measure a resistance value that can correspond to a
temperature after some testing and formula extraction. We also know that to transmit dataover serial we are going to need the MAX232 line driver/receiver and a digital signal to
transmit. This digital signal will be the temperature value we wish to be read by our computer
program. However, we need some way to change the resistance value into a voltage signal to
be changed into a transmittable digital signal. From the document I linked to above we findthe following flow chart which gives us a clue as to how to proceed.
Figure 1: Logical flow for a traditional Off the Shelf Thermometer (from lab 3C40-e5)
As the image above shows, we can utilize an op-amp to generate a voltage signal. We
will change the signal through use of the thermistor. We can use the resistance value of thethermistor to change the gain equation for the output of our operational amplifier. With our
analog voltage signal we can pass through an ADC, converting our value into a binary output.Normally, a commercial unit would then convert that binary voltage value into a binary
temperature value using conversion hardware, then that value would be output to a LCD
display. However, we will only be using the first three units in Figure one, as we wish only to
send that digital voltage signal over RS232. This has the added benefit of reducing the amount
http://www.cmmp.ucl.ac.uk/~nts/teachinglabs/3c40-e5.pdfhttp://www.cmmp.ucl.ac.uk/~nts/teachinglabs/3c40-e5.pdf8/6/2019 App Note Kevin
4/40
of hardware that we need since we can convert the ADC output to a temperature within our
GUI program itself.
Figure 2: Op-Amps and Gain equations (from lab 3C40-e5)
Above is an example of a traditional non-inverting amplifier making use of an op-amp
to amplify Vin. In our case we can simply use Rb, to restrict the flow of a standard 5v Vinbased on our temperature. This will provide us with an analog voltage value that we can workwith. To find the relationship between this signal and temperature we will have to do some
more testing which we will get to later on in this document.
For now we are concerned with what will be done once we have an analog signal. Asfigure 1 demonstrates, this value will be converted into a digital signal and we need to get that
value over to our GUI.. To do this we will use our PIC and our MAX232 chips. The
advantage to the PIC18F4520 is that it has a built in 10-bit ADC and can make use ofsoftware handshaking to transmit and receive serial signals with the help of the MAX232. For
a good tutorial on how to construct this part of the circuit we can use a pair of ECE480 labs
from Michigan State University available athttp://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab4.pdfand
http://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab3.pdf. These lab
explain how to construct a few PIC based circuits including a circuit capable of transmitting a
converted analog voltage signal to a GUI. From these two labs I have designed a circuitschematic for the circuit that we will need to use. Please see the schematic below and
construct it on a proto-board.
Figure 3: Thermometer Schematic (See Appendix A for full-sized schematic Pg. 14)
http://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab4.pdfhttp://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab3.pdfhttp://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab4.pdfhttp://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab3.pdf8/6/2019 App Note Kevin
5/40
Section B: Programming your PIC Microprocessor
Now that we have built our circuit we are ready to program the PIC microcontroller to
handle our data and output the correct digital voltage value to our MAX232 Chip. Below is
the code from the .c file we will be using to program the PIC. We will use MPLAB toprogram our PIC along with a Microchip MPLAB ICD 2 PIC programmer. (More
information can be found on this product here
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010046)
For instruction on programming you PIC please use the MSU LAB 3 pdf file, linked
to here http://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab3.pdf.information on programming the PIC18F4520 can be found in the first section. Please use the
code below. (Simply copy and paste)
#include #include
#include #pragma config LVP=OFF
#pragma config WDT=OFF
void rx_handler (void); //Declare the ISR function
unsigned char data;char data2[6] = {'S', 'c', 'h', 'e', 'e', 'l'};
long int count;
int dloop, dloop2, altflash, adc_result;void main()
{
OpenUSART (USART_TX_INT_OFF & USART_RX_INT_ON &USART_ASYNCH_MODE & USART_EIGHT_BIT &
USART_CONT_RX & USART_BRGH_LOW, 63);
RCONbits.IPEN = 1; /* Enable interrupt priority */IPR1bits.RCIP = 1; /* Make receive interrupt high priority */
INTCONbits.GIEH = 1; /* Enable all high priority interrupts */
OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_12_TAD,
ADC_CH0 & ADC_INT_OFF, 0); //open adc port for readingSetChanADC(ADC_CH1); //Set ADC to Pin 3
ADCON1 =0x00; //set VREF+ to VDD and VREF- to GND (VSS)
TRISD = 0x04;PORTDbits.RD0 = 0;
PORTDbits.RD3 = 0;
PORTDbits.RD1 = 0;altflash = 1;
dloop = 0;
dloop2 = 0;
while(1)
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010046http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010046http://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab3.pdfhttp://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010046http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010046http://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab3.pdf8/6/2019 App Note Kevin
6/40
{
}
}//Lets the compiler know the location of the ISR
#pragma code rx_interrupt = 0x8
void rx_int (void){
_asm goto rx_handler _endasm
}#pragma code
//Lets the compiler know that this function is the ISR
#pragma interrupt rx_handler
void rx_handler (void){
unsigned char c;
altflash = !altflash;
c = getcUSART(); //get a single character off the USART linewhile(BusyUSART());
if (c == 'e'){
ConvertADC(); //perform ADC conversion
while(BusyADC()); //wait for result
adc_result = ReadADC(); //get ADC resultdata = adc_result >> 2;
putcUSART (data); //put a single character on the USART line
}PIR1bits.RCIF = 0; //reset the ISR flag.
}
After you have entered the code and built the project please program your PIC and
make sure it runs. If you have errors please go back and repeat the steps listed in ECE 480
Lab 3. Your MPLAB screen should look like the one below.
Figure 4: The MPLAB screen
8/6/2019 App Note Kevin
7/40
Section C: Building Your GUI
To view the the data on our computer we will need to design a simple graphical user
interface for a user to manipulate. For simplicity we will be using Visual Basic.NET, however
you can use which ever programming language you wish. You will however need a class ofsome sort to handle communications over RS232. A Sample class for visual basic can be
found in Appendix C. The code for our form can found below and should be added to a form
called Form1.vb. This form should appear under your solution explorer pane in VisualStudio.NET as seen in figure 5 below. Note that CRs232.vb is our RS232 driver located in
Appendix B (Pg. 15) of this tutorial.
Figure 5 : Solution Explorer Pane in Visual Studio with project information
If you need additional guidance please consult MSU Lab 4 found here
http://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab4.pdf. Please also use
the help function within Visual Studio to answer questions on how to create a new VBproject.
After you have your file structure setup please proceed to add the following code to yourForm1.vb file to create a GUI we can use.
http://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab4.pdfhttp://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab4.pdf8/6/2019 App Note Kevin
8/40
PublicClass Form1 Inherits System.Windows.Forms.Form Dim setRs232 AsNew Rs232 Dim serial_in AsString Dim x AsInteger Dim sf AsString Dim sr AsString Dim sleepf AsInteger Dim sample AsInteger DeclareSub Sleep Lib "kernel32" Alias "Sleep" (ByValdwMilliseconds AsLong)
#Region " Windows Form Designer generated code "
PublicSubNew() MyBase.New()
'This call is required by the Windows Form Designer.InitializeComponent()
'Add any initialization after the InitializeComponent() call
EndSub
'Form overrides dispose to clean up the component list. ProtectedOverloadsOverridesSub Dispose(ByVal disposing AsBoolean) If disposing Then IfNot (components IsNothing) Then
components.Dispose() EndIf EndIf MyBase.Dispose(disposing) EndSub
'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows FormDesigner 'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor. FriendWithEvents Button1 As System.Windows.Forms.Button FriendWithEvents TextBox1 As System.Windows.Forms.TextBox 'Friend WithEvents Chart1 As Dundas.Charting.WinControl.Chart FriendWithEvents Button7 As System.Windows.Forms.Button
PrivateSubInitializeComponent() Me.TextBox1 = New System.Windows.Forms.TextBox Me.Button7 = New System.Windows.Forms.Button Me.SuspendLayout() ' 'TextBox1 ' Me.TextBox1.Location = New System.Drawing.Point(120, 32) Me.TextBox1.Name = "TextBox1"
8/6/2019 App Note Kevin
9/40
8/6/2019 App Note Kevin
10/40
Section D: Calibrating Your Thermistor
After you have built your circuit you are ready to find the formula necessary for
converting your voltage value into a temperature value. This part of the process is quite
simple and straight forward. The simplest way to find your relationship is through testing.You will need the following items to run your test.
Equipment:
1 - Cup filled with ice
1- Cup filled with hot water
1- Thermometer or temperature probe
1 - 5V power supplyYour finished and operational circuit
To measure the relationship between voltage and temperature follow the following steps.
1) Connect up your circuit with 5V from your power supply.
2) Connect your Circuit to MP Lab via the RJ-11 port, build your code, program yourPIC, and finally run the program (Please see MSU labs for information on
programming in MP lab).
3) Open Visual Studio and run your GUI
4) Place the thermometer and your thermistor probe in warm water (*Warning, be carefulin dealing with water around your circuit and make sure that your thermistor is housed
properly*) It is recommended that you use the case from a store bought thermometer
to ensure that you will not have any water leakage, also the thermistor from thisproduct.
5) After the commercial thermometer has reached its final temperature record the
temperature and click get temperature in your GUI and record the voltage value thatappears in the text box to the right.
6) Repeat steps 4-6 at least 20 times, waiting a few minutes between each test to allow
for a significant temperature change in the water.7) After you have 20 or more data points enter your data either in Microsoft Excel or
MATLAB. Your table should look something like the one in figure 6 below.
temperature
in F vdc104.4 4.12
97.3 3.9025
97.4 3.902896.1 3.8955
95 3.8886
92.9 3.88
91.1 3.875391.5 3.55
96.5 3.8907
97 3.8947
97.7 3.89798.2 3.8985
8/6/2019 App Note Kevin
11/40
97.8 3.992
97.9 3.8963
Figure 6: Example Table of recorded Data
*Note: This data will vary from experiment to experiment depending on what resistance value
your thermistor operates at and the temperature of the water you are using/time between
measurements.
With this data you can graph the relationship and find a curve using the tools within
the given program. For more information on graphing in MS Excel please use the followinglink(http://chemed.chem.purdue.edu/genchem/lab/datareports/excel/plotting.html) After the
data has been plotted goto chart->add trend line and select exponential. This should give you
a formula for the best fit line of your data.
Change in Voltage vs.
Temperature
y = 3.125e0.0045x
3.5
3.6
3.7
3.8
3.9
4
4.1
4.2
Temperature in degrees
Fahrenheit
)Voltage
)VDC
Series1
Expon. (Series1)
Figure 7: Graph of Voltage vs. Temperature
From figure 7 we can see that our general formula is y = 3.125 .0045x with y equaling thevoltage and x equaling the temperature in degrees Fahrenheit. From this we can derive the
following equation to determine the temperature based on a given voltage value in decimalform (which is what we get in from our circuit). The resulting equation isTemperature = ln(voltage/3.125)/-0.0045. Lucky for us the natural log function can be used
in Visual Basic. Net with the command Math.Log(). Your GUI code should be modified to
display your new temperature result. By changing the following lines of code in Form1.vb.
http://chemed.chem.purdue.edu/genchem/lab/datareports/excel/plotting.htmlhttp://chemed.chem.purdue.edu/genchem/lab/datareports/excel/plotting.html8/6/2019 App Note Kevin
12/40
PrivateSub Button7_Click(ByVal sender As System.Object, ByVal e AsSystem.EventArgs) Handles Button7.Click
setRs232.Write("e")setRs232.Read(1)serial_in = setRs232.InputStreamStringx = AscW(CChar(serial_in))
TextBox1.Text = x * 0.0156'modify adc_result to reflect voltageinterms of vref EndSub
Change these lines to
PrivateSub Button7_Click(ByVal sender As System.Object, ByVal e AsSystem.EventArgs) Handles Button7.Click
setRs232.Write("e")setRs232.Read(1)serial_in = setRs232.InputStreamStringx = AscW(CChar(serial_in))TextBox1.Text = ((Math.Log(x * 0.0156) / 3.125) / 0.0045)
'modify adc_result to reflect voltage interms of vref EndSub
Section E: The Final Product
Now that we have calibrated our thermistor and made the correct changes to the code
in our GUI we are ready to hook everything up and run our circuit.Steps
1) Power on your circuit with a 5V power supply.2) Attach the MPLAB ICD 2, if it is no longer attached.
3) Program and run your PIC program
4) Open your Visual Studio Project and goto Debug-> Start to run your program in debug
mode.5) Place Thermistor and casing in a place over 90 degrees Fahrenheit along with an
additional thermometer to compare results (Such as under your arm). After the final
temperature has been reached by your commercial thermometer click on the GetTemperature button on your GUI to get output from your circuit, you should get the
same approximate value.
Congratulations! Your Screen should look like the one shown in figure 8 below.
8/6/2019 App Note Kevin
13/40
Conclusion:
Through this note we have designed and built a digital thermometer that can be usedwith a windows computer. The applications for such a device are wide ranging including, but
not limited to, medical thermometers and temperature sensors for a detection system. We have
designed this thermometer to be accurate to within 0.1 degree F, which should work for evenmedical applications. Your results will vary depending on the resistance value of your
thermistor and the sensitivity/tolerance of the thermistor itself. This may vary from
commercial product to commercial product. Other possible changes to this device includeprogramming the GUI in a language such as Qt for cross platform support, however this will
require a RS232 support class. Such classes can be found on the Internet, an example of one
such class can be found at http://qextserialport.sourceforge.net/. One might also use an API to
save the recorded data to a database file for future reference and comparison. This can also beaccomplished in Qt. This product is meant as a starting point for work with digital
thermometers and hopefully you have gained some insight into how such products function.
http://qextserialport.sourceforge.net/http://qextserialport.sourceforge.net/8/6/2019 App Note Kevin
14/40
Appendix A: Circuit Schematic
8/6/2019 App Note Kevin
15/40
Appendix B: Serial Driver Code
This code has been extracted from the files accompanying Michigan State University
ECE 480 Lab 4. Please see above links or the links in the reference Section (Pg.40) of
this note.
Imports System.Runtime.InteropServicesImports System.TextImports System.ThreadingImports System.ComponentModelImports System.IO
#Region "RS232"PublicClass Rs232 : Implements IDisposable '=================================================== ' ' Module : Rs232
' Description : Class for handling RS232 comunication withVB.Net ' Created : 10/08/2001 - 8:45:25 ' Author : Corrado Cavalli([email protected]) 'WebSite : www.codeworks.it/net/index.htm ' ' Notes : '-----------------------------------------------------------------------------------------------
'* Revisions *
'
' 02/12/2000 First internal alpha version built onframework beta1'
' 1st Public release Beta2 (10/08/2001) ' ' Rev.1 (28.02.2002) ' 1. Added ResetDev, SetBreak and ClearBreak to theEscapeCommFunction constants ' 2. Added the overloaded Open routine. ' 3. Added the modem status routines, properties and enum. ' 4. If a read times out, it now returns a EndOfStreamException(instead of a simple Exception). ' 5.Compiled with VS.Net final
' Rev.2 (01.03.2002) ' Added Async support ' ' Rev.3 (07.04.2002) ' Minor bugs fixed ' ' Rev.3 (05/05/2002) ' Fixed BuildCommmDCB problem '
8/6/2019 App Note Kevin
16/40
' Rev.4 (24/05/2002) ' Fixed problem with ASCII Encoding truncating 8th bit ' ' Rev.5 (27/05/2002) ' Added IDisposable / Finalize implementation ' ' Rev.6 (14/03/2003) ' Fixed problem on DCB fields Initialization ' ' Rev.7 (26/03/2003) ' Added XON/XOFF support ' ' Rev.8 (12/07/2003)
' Added support to COM port number greater than 4'' Rev.9 (15/07/2003)' Added CommEvent to detect incoming chars/events' Updated both Tx/Rx method from Non-Ovelapped to Overlapped mode' Removed unused Async methods and other stuff.'
' Rev.10 (21/07/2003) ' Fixed incorrect character handling when using EnableEvents() ' ' Rev.11 (12/08/2003) ' Fixed some bugs signaled by users '
' Rev.12 (01/09/2003)' Removed AutoReset of internal buffers and added PurgeBuffer()
method'' Rev.13 (02/09/2003)' Removed GetLastErrorUse in favour of Win32Exception()'' Rev.14 (14/09/2003)' Added IsPortAvailable() function' Revised some API declaration
' Fixed problem with Win98/Me OS ' ' Rev.15 (24/09/2003) ' Fixed bug introduced on Rev.14 ' ' Rev.16 (12/10/2003) ' Added SetBreak/ClearBreak() methods ' ' Rev.17 (02/11/2003) ' Fixed field on COMMCONFIG
'
' Rev.18 (03/03/2004)' Fixed bug: Testing mhRS for 0 is not correct'' Rev.19 (08/04/2004)' Fixed bug: Fixed bug on DTR property'' Rev.20 (12/07/2004)' CommEvent is no more raised on a secondary thread
' pEventsWatcher now uses a background thread'
8/6/2019 App Note Kevin
17/40
' Rev.21 (24/10/2004)' EscapeCommFunction declaration fixed' Pariti enum fixed to Parity'' Rev. 22 (05/03/2005)
' Fixed memory leak problem causing program closing ' without any message on some systems. ' Thanks to Ralf Gedrat for testing this scenario ' ' Rev.23 (05/04/2005) ' Fixed bug DisableEvents not working bug
' ' Rev.24 (20/04/2005)
' Fixed memory leak on Read method ' Added InBufferCount property ' IsPortAvailable method is now shared ' Thanks to Jean-Pierre ZANIER for the feedback
'==================================================='// Class Members
Private mhRS As IntPtr = New IntPtr(0) '// Handle to Com Port
Private miPort AsInteger = 1 '// Default is COM1 Private miTimeout As Int32 = 70 '// Timeout in ms Private miBaudRate As Int32 = 9600 Private meParity As DataParity = 0 Private meStopBit As DataStopBit = 0 Private miDataBit As Int32 = 8 Private miBufferSize As Int32 = 512 '// Buffers size default to 512bytes Private mabtRxBuf AsByte() '// Receive buffer Private meMode As Mode '// Class working mode
Private moThreadTx As Thread
Private moThreadRx As ThreadPrivate moEvents As Thread Private miTmpBytes2Read As Int32 Private meMask As EventMasks Private mbDisposed AsBoolean
Private mbUseXonXoff AsBooleanPrivate mbEnableEvents AsBooleanPrivate miBufThreshold As Int32 = 1Private muOvlE As OVERLAPPEDPrivate muOvlW As OVERLAPPEDPrivate muOvlR As OVERLAPPEDPrivate mHE As GCHandlePrivate mHR As GCHandlePrivate mHW As GCHandle
'----------------------------------------------------------------------------------------
#Region "Enums"'// Parity DataPublicEnum DataParity
Parity_None = 0Parity_Odd
Parity_Even
8/6/2019 App Note Kevin
18/40
Parity_MarkEndEnum'// StopBit DataPublicEnum DataStopBit
StopBit_1 = 1StopBit_2
EndEnum PublicEnum PurgeBuffers
RXAbort = &H2RXClear = &H8TxAbort = &H1TxClear = &H4
EndEnumPrivateEnum Lines
SetRts = 3ClearRts = 4SetDtr = 5ClearDtr = 6ResetDev = 7 ' // Reset device if possibleSetBreak = 8 ' // Set the device break line.
ClearBreak = 9 ' // Clear the device break line.EndEnum'// Modem Status PublicEnum ModemStatusBits
ClearToSendOn = &H10DataSetReadyOn = &H20RingIndicatorOn = &H40CarrierDetect = &H80
EndEnum'// Working modePublicEnum Mode
NonOverlappedOverlapped
EndEnum'// Comm Masks PublicEnum EventMasks
RxChar = &H1RXFlag = &H2TxBufferEmpty = &H4ClearToSend = &H8DataSetReady = &H10CarrierDetect = &H20Break = &H40StatusError = &H80Ring = &H100
EndEnum
#EndRegion#Region "Structures"
PrivateStructure DCBPublic DCBlength As Int32Public BaudRate As Int32Public Bits1 As Int32Public wReserved As Int16Public XonLim As Int16Public XoffLim As Int16Public ByteSize AsByte
8/6/2019 App Note Kevin
19/40
Public Parity AsBytePublic StopBits AsBytePublic XonChar AsCharPublic XoffChar AsCharPublic ErrorChar AsCharPublic EofChar AsCharPublic EvtChar AsCharPublic wReserved2 As Int16
EndStructure PrivateStructure
COMMTIMEOUTSPublic ReadIntervalTimeout As Int32Public ReadTotalTimeoutMultiplier As Int32Public ReadTotalTimeoutConstant As Int32Public WriteTotalTimeoutMultiplier As Int32Public WriteTotalTimeoutConstant As Int32
EndStructure PrivateStructure
COMMCONFIG Public dwSize As Int32
Public wVersion As Int16 Public wReserved As Int16 Public dcbx As DCB Public dwProviderSubType As Int32 Public dwProviderOffset As Int32 Public dwProviderSize As Int32 Public wcProviderData As Int16 EndStructure
PublicStructureOVERLAPPED Public Internal As Int32 Public InternalHigh As Int32 Public Offset As Int32 Public OffsetHigh As Int32 Public hEvent As IntPtr EndStructure
PrivateStructureCOMSTAT Dim fBitFields As Int32 Dim cbInQue As Int32 Dim cbOutQue As Int32 EndStructure
#EndRegion#Region "Constants"
PrivateConst PURGE_RXABORT AsInteger = &H2PrivateConst PURGE_RXCLEAR AsInteger = &H8
PrivateConst PURGE_TXABORT AsInteger = &H1PrivateConst PURGE_TXCLEAR AsInteger = &H4PrivateConst GENERIC_READ AsInteger = &H80000000PrivateConst GENERIC_WRITE AsInteger = &H40000000PrivateConst OPEN_EXISTING AsInteger = 3PrivateConst INVALID_HANDLE_VALUE AsInteger = -1PrivateConst IO_BUFFER_SIZE AsInteger = 1024PrivateConst FILE_FLAG_OVERLAPPED As Int32 = &H40000000PrivateConst ERROR_IO_PENDING As Int32 = 997PrivateConst WAIT_OBJECT_0 As Int32 = 0
8/6/2019 App Note Kevin
20/40
PrivateConst ERROR_IO_INCOMPLETE As Int32 = 996PrivateConst WAIT_TIMEOUT As Int32 = &H102&PrivateConst INFINITE As Int32 = &HFFFFFFFF
#EndRegion#Region "Win32API"
'// Win32 API PrivateSharedFunction
SetCommState(ByVal hCommDev As IntPtr, ByRef lpDCB As DCB) As Int32 EndFunction
PrivateSharedFunctionGetCommState(ByVal hCommDev As IntPtr, ByRef lpDCB As DCB) As Int32 EndFunction
PrivateSharedFunction BuildCommDCB(ByVal lpDef AsString, ByRef lpDCB AsDCB) As Int32 EndFunction
PrivateSharedFunctionSetupComm(ByVal hFile As IntPtr, ByVal dwInQueue As Int32, ByVal dwOutQueue
As Int32) As Int32 EndFunction
PrivateSharedFunctionSetCommTimeouts(ByVal hFile As IntPtr, ByRef lpCommTimeouts AsCOMMTIMEOUTS) As Int32 EndFunction
PrivateSharedFunctionGetCommTimeouts(ByVal hFile As IntPtr, ByRef lpCommTimeouts AsCOMMTIMEOUTS) As Int32 EndFunction
PrivateSharedFunctionClearCommError(ByVal hFile As IntPtr, ByRef lpErrors As Int32, ByReflpComStat As COMSTAT) As Int32 EndFunction
PrivateSharedFunctionPurgeComm(ByVal hFile As IntPtr, ByVal dwFlags As Int32) As Int32 EndFunction
PrivateSharedFunctionEscapeCommFunction(ByVal hFile As IntPtr, ByVal ifunc As Int32) AsBoolean EndFunction
PrivateSharedFunctionWaitCommEvent(ByVal hFile As IntPtr, ByRef Mask As EventMasks, ByReflpOverlap As OVERLAPPED) As Int32 EndFunction
PrivateSharedFunctionWriteFile(ByVal hFile As IntPtr, ByVal Buffer AsByte(), ByValnNumberOfBytesToWrite AsInteger, ByRef lpNumberOfBytesWritten AsInteger,
ByRef lpOverlapped As OVERLAPPED) AsInteger EndFunction
PrivateSharedFunctionReadFile(ByVal hFile As IntPtr, ByVal Buffer AsByte(), ByValnNumberOfBytesToRead AsInteger, ByRef lpNumberOfBytesRead AsInteger,ByRef lpOverlapped As OVERLAPPED) AsInteger EndFunction
PrivateSharedFunction CreateFile(ByVal lpFileName AsString, ByValdwDesiredAccess AsInteger, ByVal dwShareMode AsInteger, ByVal
8/6/2019 App Note Kevin
21/40
lpSecurityAttributes AsInteger, ByVal dwCreationDisposition AsInteger,ByVal dwFlagsAndAttributes AsInteger, ByVal hTemplateFile AsInteger) AsIntPtr EndFunction
PrivateSharedFunctionCloseHandle(ByVal hObject As IntPtr) AsBoolean EndFunction
PublicSharedFunctionGetCommModemStatus(ByVal hFile As IntPtr, ByRef lpModemStatus As Int32) AsBoolean EndFunction
PrivateSharedFunctionSetEvent(ByVal hEvent As IntPtr) AsBoolean EndFunction
PrivateSharedFunction CreateEvent(ByVal lpEventAttributes As IntPtr,ByVal bManualReset As Int32, ByVal bInitialState As Int32, ByVal lpName AsString) As IntPtr EndFunction
PrivateSharedFunction
WaitForSingleObject(ByVal hHandle As IntPtr, ByVal dwMilliseconds As Int32)As Int32 EndFunction
PrivateSharedFunctionGetOverlappedResult(ByVal hFile As IntPtr, ByRef lpOverlapped AsOVERLAPPED, ByRef lpNumberOfBytesTransferred As Int32, ByVal bWait AsInt32) As Int32 EndFunction
PrivateSharedFunctionSetCommMask(ByVal hFile As IntPtr, ByVal lpEvtMask As Int32) As Int32 EndFunction
PrivateSharedFunction GetDefaultCommConfig(ByVal lpszName AsString,ByRef lpCC As COMMCONFIG, ByRef lpdwSize AsInteger) AsBoolean EndFunction
PrivateSharedFunctionSetCommBreak(ByVal hFile As IntPtr) AsBoolean EndFunction
PrivateSharedFunctionClearCommBreak(ByVal hFile As IntPtr) AsBoolean EndFunction
#EndRegion#Region "Events"
PublicEvent CommEvent As CommEventHandler#EndRegion
#Region "Delegates"PublicDelegateSub CommEventHandler(ByVal source As Rs232, ByVal
Mask As EventMasks)#EndRegion
PublicProperty Port() AsInteger'==================================================='' Description : Comunication Port
8/6/2019 App Note Kevin
22/40
' Created : 21/09/2001 -11:25:49
''*Parameters Info*'' Notes :'===================================================Get
Return miPortEndGetSet(ByVal Value AsInteger)
miPort = ValueEndSet
EndPropertyPublicSub PurgeBuffer(ByVal Mode As PurgeBuffers)
'==================================================='2003 ALSTOM FIR S.p.A All rights reserved'
' Description : Purge Communication Buffer' Created : 01/09/03 - 10:37:39' Author : Corrado Cavalli'' *Parameters Info*'' Notes : This method will clear any
character into buffer, use TxAbort/RxAbort' to terminate
any pending overlapped Tx/Rx operation.'===================================================If (mhRS.ToInt32 > 0) Then PurgeComm(mhRS, Mode)
EndSubPublicOverridableProperty Timeout() AsInteger
'==================================================='' Description: Comunication timeout in
seconds' Created : 21/09/2001 -
11:26:50''*Parameters Info*'' Notes :'===================================================Get
Return miTimeoutEndGetSet(ByVal Value AsInteger)
miTimeout = CInt(IIf(Value = 0, 500, Value))'// If Port is open updates it on the flypSetTimeout()
EndSetEndPropertyPublicProperty Parity() As DataParity
'===================================================
8/6/2019 App Note Kevin
23/40
'' Description : Comunication parity' Created : 21/09/2001 -
11:27:15''*Parameters Info*'' Notes :'===================================================Get
Return meParityEndGetSet(ByVal Value As DataParity)
meParity = ValueEndSet
EndPropertyPublicProperty StopBit() As DataStopBit
'==================================================='
' Description: Comunication StopBit' Created : 21/09/2001 -
11:27:37''*Parameters Info*'' Notes :'===================================================Get
Return meStopBitEndGetSet(ByVal Value As DataStopBit)
meStopBit = ValueEndSet
EndPropertyPublicProperty BaudRate() AsInteger
'==================================================='' Description: Comunication BaudRate' Created : 21/09/2001 -
11:28:00''*Parameters Info*'' Notes :
'===================================================Get
Return miBaudRateEndGetSet(ByVal Value AsInteger)
miBaudRate = ValueEndSet
EndPropertyPublicProperty DataBit() AsInteger
'===================================================
8/6/2019 App Note Kevin
24/40
'' Description : Comunication DataBit' Created : 21/09/2001 -
11:28:20''*Parameters Info*'' Notes :'===================================================Get
Return miDataBitEndGetSet(ByVal Value AsInteger)
miDataBit = ValueEndSet
EndPropertyPublicProperty BufferSize() AsInteger
'==================================================='
' Description : Receive Buffer size' Created : 21/09/2001 -
11:33:05''*Parameters Info*'' Notes :'===================================================Get
Return miBufferSizeEndGetSet(ByVal Value AsInteger)
miBufferSize = ValueEndSet
EndPropertyPublicOverloadsSub Open()
'==================================================='' Description : Initializes and Opens
comunication port' Created : 21/09/2001 -
11:33:40''*Parameters Info*'
' Notes :'==================================================='// Get Dcb block,Update with current dataDim uDcb As DCB, iRc As Int32'// Set working modemeMode = Mode.OverlappedDim iMode As Int32 = Convert.ToInt32(IIf(meMode =
Mode.Overlapped, FILE_FLAG_OVERLAPPED, 0))'// Initializes Com PortIf miPort > 0 Then
8/6/2019 App Note Kevin
25/40
8/6/2019 App Note Kevin
26/40
ThrowNew ApplicationException("COM Port not defined,usePort property to set it before invoking InitPort")
EndIfEndSubPublicOverloadsSub Open(ByVal Port AsInteger, ByVal BaudRate As
Integer, ByVal DataBit AsInteger, ByVal Parity As DataParity, ByValStopBit As DataStopBit, ByVal BufferSize AsInteger)
'==================================================='' Description: Opens comunication port
(Overloaded method)' Created : 21/09/2001 - 11:33:40''*Parameters Info*'' Notes :'===================================================Me.Port = PortMe.BaudRate = BaudRate
Me.DataBit = DataBitMe.Parity = ParityMe.StopBit = StopBitMe.BufferSize = BufferSizeOpen()
EndSubPublicSub Close()
'==================================================='' Description: Close comunication channel' Created : 21/09/2001 -
11:38:00''*Parameters Info*'' Notes :'===================================================If mhRS.ToInt32 > 0 Then
If mbEnableEvents = TrueThenMe.DisableEvents()
EndIfDim ret AsBoolean = CloseHandle(mhRS)IfNot ret ThenThrowNew Win32ExceptionmhRS = New IntPtr(0)
EndIfEndSub
ReadOnlyProperty IsOpen() AsBoolean'==================================================='' Description: Returns Port Status' Created : 21/09/2001 -
11:38:51''*Parameters Info*'
8/6/2019 App Note Kevin
27/40
' Notes :'===================================================Get
ReturnCBool(mhRS.ToInt32 > 0)EndGet
EndPropertyPublicOverloadsSub Write(ByVal Buffer AsByte())
'==================================================='' Description: Transmit a stream' Created : 21/09/2001 -
11:39:51''*Parameters Info*' Buffer : Array of Byte()
to write' Notes :'===================================================Dim iRc, iBytesWritten AsInteger, hOvl As GCHandle
'-----------------------------------------------------------------
muOvlW = New OverlappedIf mhRS.ToInt32
8/6/2019 App Note Kevin
28/40
CloseHandle(muOvlW.hEvent) If (hOvl.IsAllocated = True) Then hOvl.Free()
EndTryEndIf
EndSubPublicOverloadsSub Write(ByVal Buffer AsString)
'==================================================='' Description : Writes a string to RS232' Created : 04/02/2002 - 8:46:42'' *Parameters Info*'' Notes : 24/05/2002 Fixed problem with
ASCII Encoding'===================================================Dim oEncoder AsNew System.Text.ASCIIEncodingDim oEnc As Encoding = oEncoder.GetEncoding(1252)'-------------------------------------------------------------Dim aByte() AsByte = oEnc.GetBytes(Buffer)
Me.Write(aByte)EndSubPublicFunction Read(ByVal Bytes2Read AsInteger) AsInteger
'==================================================='' Description: Read Bytes from Port' Created : 21/09/2001 -
11:41:17''*Parameters Info*' Bytes2Read : Bytes to read from
port' Returns :
Number of readed chars'' Notes :'===================================================Dim iReadChars, iRc AsInteger, bReading AsBoolean, hOvl As
GCHandle'--------------------------------------------------------------'// If Bytes2Read not specified uses BuffersizeIf Bytes2Read = 0 Then Bytes2Read = miBufferSizemuOvlR = New OverlappedIf mhRS.ToInt32
8/6/2019 App Note Kevin
29/40
iRc = ReadFile(mhRS, mabtRxBuf, Bytes2Read,iReadChars, muOvlR)
If iRc = 0 ThenIf Marshal.GetLastWin32Error()
ERROR_IO_PENDING ThenThrowNew ApplicationException("Read
pending error")Else
'// Wait for charactersiRc =
WaitForSingleObject(muOvlR.hEvent, miTimeout)SelectCase iRc
Case WAIT_OBJECT_0'// Some data received...If
GetOverlappedResult(mhRS, muOvlR, iReadChars, 0) = 0 ThenThrowNew
ApplicationException("Read pending error.")Else
Return iReadChars
EndIfCase WAIT_TIMEOUT
ThrowNewIOTimeoutException("Read Timeout.")
CaseElseThrowNew
ApplicationException("General read error.")EndSelect
EndIfElse
Return (iReadChars)EndIf
Finally'//Closes handleCloseHandle(muOvlR.hEvent)If (hOvl.IsAllocated) Then hOvl.Free()
EndTryEndIf
EndFunctionOverridableReadOnlyProperty InputStream() AsByte()
'==================================================='' Description: Returns received data as
Byte()' Created : 21/09/2001 -
11:45:06'
'*Parameters Info*'' Notes :'===================================================
Get Return mabtRxBuf EndGet EndProperty
OverridableReadOnlyProperty InputStreamString() AsString
8/6/2019 App Note Kevin
30/40
'==================================================='' Description : Return a string containing received
data' Created : 04/02/2002 - 8:49:55'' *Parameters Info*'' Notes :'===================================================Get
Dim oEncoder AsNew System.Text.ASCIIEncoding Dim oEnc As Encoding = oEncoder.GetEncoding(1252)
'-------------------------------------------------------------
IfNotMe.InputStream IsNothingThenReturnoEnc.GetString(Me.InputStream)
EndGetEndPropertyPublicSub ClearInputBuffer()
'==================================================='' Description: Clears Input buffer' Created : 21/09/2001 -
11:45:34''*Parameters Info*'' Notes : Gets all character until
end of buffer'===================================================If mhRS.ToInt32 > 0 Then
PurgeComm(mhRS, PURGE_RXCLEAR)EndIf
EndSubPublicWriteOnlyProperty Rts() AsBoolean
'==================================================='' Description: Set/Resets RTS Line' Created : 21/09/2001 -
11:45:34''*Parameters Info*'' Notes :
'===================================================Set(ByVal Value AsBoolean)
If mhRS.ToInt32 > 0 ThenIf Value Then
EscapeCommFunction(mhRS, Lines.SetRts)Else
EscapeCommFunction(mhRS, Lines.ClearRts)EndIf
EndIfEndSet
8/6/2019 App Note Kevin
31/40
EndPropertyPublicWriteOnlyProperty Dtr() AsBoolean
'==================================================='' Description: Set/Resets DTR Line' Created : 21/09/2001 -
11:45:34''*Parameters Info*'' Notes :'===================================================Set(ByVal Value AsBoolean)
If mhRS.ToInt32 > 0 ThenIf Value Then
EscapeCommFunction(mhRS, Lines.SetDtr)Else
EscapeCommFunction(mhRS, Lines.ClearDtr)EndIf
EndIfEndSet
EndPropertyPublicReadOnlyProperty ModemStatus() As ModemStatusBits
'==================================================='' Description : Gets Modem status' Created : 28/02/2002 - 8:58:04'' *Parameters Info*'' Notes :'===================================================Get
If mhRS.ToInt32
8/6/2019 App Note Kevin
32/40
'' Notes :'===================================================Return Convert.ToBoolean(ModemStatus And Line)
EndFunctionPublicProperty UseXonXoff() AsBoolean
'==================================================='' Description : Set XON/XOFF mode' Created : 26/05/2003 - 21:16:18'' *Parameters Info*'' Notes :'===================================================Get
Return mbUseXonXoffEndGetSet(ByVal Value AsBoolean)
mbUseXonXoff = Value
EndSetEndPropertyPublicSub EnableEvents()
'==================================================='' Description : Enables monitoring of incoming events' Created : 15/07/2003 - 12:00:56'' *Parameters Info*'' Notes :'===================================================If mhRS.ToInt32
8/6/2019 App Note Kevin
33/40
mbEnableEvents = False '// Thisshould kill the thread
EndSyncLock'// Let WaitCommEvent exit...If muOvlE.hEvent.ToInt32 0 Then
SetEvent(muOvlE.hEvent)moEvents = Nothing
EndIfEndSubPublicProperty RxBufferThreshold() As Int32
'==================================================='2003 www.codeworks.it All rights reserved'' Description : Numer of characters into input buffer' Created : 16/07/03 - 9:00:57' Author : Corrado Cavalli'' *Parameters Info*'
' Notes :'===================================================Get
Return miBufThresholdEndGetSet(ByVal Value As Int32)
miBufThreshold = ValueEndSet
EndProperty PublicSharedFunction IsPortAvailable(ByVal portNumber As Int32) AsBoolean '=================================================== '
2003 www.codeworks.it All rights reserved ' ' Description : Returns true if a specific port number issupported by the system ' Created : 14/09/03 - 17:00:57 ' Author : Corrado Cavalli ' ' *Parameters Info* ' portNumber : port number to check ' ' Notes : '=================================================== If portNumber
8/6/2019 App Note Kevin
34/40
'=================================================== '
2003 www.codeworks.it All rights reserved ' ' Description : Set COM in break modem ' Created : 12/10/03 - 10:00:57 ' Author : Corrado Cavalli ' ' *Parameters Info* ' ' ' Notes : '=================================================== If mhRS.ToInt32 > 0 Then If SetCommBreak(mhRS) = FalseThenThrowNew Win32Exception EndIf EndSub PublicSub ClearBreak() '=================================================== '
2003 www.codeworks.it All rights reserved ' ' Description : Clear COM break mode ' Created : 12/10/03 - 10:02:57 ' Author : Corrado Cavalli ' ' *Parameters Info* ' ' ' Notes : '=================================================== If mhRS.ToInt32 > 0 Then If ClearCommBreak(mhRS) = FalseThenThrowNew Win32Exception EndIf
EndSub PublicReadOnlyProperty InBufferCount() As Int32 '=================================================== '
2003 www.codeworks.it All rights reserved ' ' Description : Returns the number of bytes inside Rx buffer ' Created : 20/04/05 - 10:02:57 ' Author : Corrado Cavalli/Jean-PierreZANIER ' '
'=================================================== Get Dim comStat As COMSTAT Dim lpErrCode As Int32 Dim iRc As Int32
comStat.cbInQue = 0 If mhRS.ToInt32 > 0 Then
iRc = ClearCommError(mhRS, lpErrCode, comStat) Return comStat.cbInQue EndIf
8/6/2019 App Note Kevin
35/40
8/6/2019 App Note Kevin
36/40
EndSub PrivateSub pDispose() Implements IDisposable.Dispose '=================================================== ' ' Description : Handles correct class disposing Write ' Created : 27/05/2002 - 19:03:06 ' ' *Parameters Info* ' ' Notes : '=================================================== If (Not mbDisposed AndAlso (mhRS.ToInt32 > 0)) Then '// Closes Com Port releasing resources Try Me.Close() Finally
mbDisposed = True '// Suppress unnecessary Finalize overhead
GC.SuppressFinalize(Me) EndTry
EndIf
EndSub PrivateSub pEventsWatcher() '=================================================== '
2003 www.codeworks.it All rights reserved ' ' Description : Watches for all events raising events whenthey arrive to the port ' Created : 15/07/03 - 11:45:13 ' Author : Corrado Cavalli ' ' *Parameters Info* ' ' Notes : '=================================================== '// Events to watch Dim lMask As EventMasks = EventMasks.Break OrEventMasks.CarrierDetect Or EventMasks.ClearToSend Or _
EventMasks.DataSetReady Or EventMasks.Ring Or EventMasks.RxChar OrEventMasks.RXFlag Or _
EventMasks.StatusError Dim lRetMask As EventMasks, iBytesRead, iTotBytes, iErrMask AsInt32, iRc As Int32, aBuf AsNew ArrayList Dim uComStat As COMSTAT
'----------------------------------- '// Creates Event
muOvlE = New Overlapped Dim hOvlE As GCHandle = GCHandle.Alloc(muOvlE, GCHandleType.Pinned)
muOvlE.hEvent = CreateEvent(Nothing, 1, 0, Nothing) If muOvlE.hEvent.ToInt32 = 0 ThenThrowNewApplicationException("Error creating event for overlapped reading") '// Set mask
SetCommMask(mhRS, lMask) '// Looks for RxChar
8/6/2019 App Note Kevin
37/40
While mbEnableEvents = TrueWaitCommEvent(mhRS, lMask, muOvlE)
SelectCase WaitForSingleObject(muOvlE.hEvent, INFINITE) Case WAIT_OBJECT_0 '// Event (or abort) detected If mbEnableEvents = FalseThenExitWhile If (lMask And EventMasks.RxChar) > 0 Then '// Read incoming data
ClearCommError(mhRS, iErrMask, uComStat) If iErrMask = 0 Then Dim ovl AsNew Overlapped Dim hOvl As GCHandle = GCHandle.Alloc(ovl,GCHandleType.Pinned) ReDim mabtRxBuf(uComStat.cbInQue - 1) If ReadFile(mhRS, mabtRxBuf, uComStat.cbInQue,iBytesRead, ovl) > 0 Then If iBytesRead > 0 Then '// Some bytes read, fills temporarybuffer If iTotBytes < miBufThreshold Then
aBuf.AddRange(mabtRxBuf)iTotBytes += iBytesRead
EndIf '// Threshold reached?, raises event If iTotBytes >= miBufThreshold Then '//Copies temp buffer into Rxbuffer ReDim mabtRxBuf(iTotBytes - 1)
aBuf.CopyTo(mabtRxBuf) '// Raises event Try Me.OnCommEventReceived(Me,lMask) Finally
iTotBytes = 0aBuf.Clear()
EndTry EndIf EndIf EndIf If (hOvl.IsAllocated) Then hOvl.Free() EndIf Else '// Simply raises OnCommEventHandler event Me.OnCommEventReceived(Me, lMask) EndIf CaseElse
Dim sErr AsString = New Win32Exception().Message ThrowNew ApplicationException(sErr) EndSelect EndWhile '// Release Event Handle
CloseHandle(muOvlE.hEvent)muOvlE.hEvent = IntPtr.Zero
If (hOvlE.IsAllocated) Then hOvlE.Free()muOvlE = Nothing
EndSub
8/6/2019 App Note Kevin
38/40
#EndRegion
#Region "Protected Routines" ProtectedSub OnCommEventReceived(ByVal source As Rs232, ByVal mask AsEventMasks) '=================================================== '
2003 www.codeworks.it All rights reserved ' ' Description : Raises CommEvent ' Created : 15/07/03 - 15:09:50 ' Author : Corrado Cavalli ' ' *Parameters Info* ' ' Notes : '===================================================
Dim del As CommEventHandler = Me.CommEventEvent If (Not del IsNothing) Then Dim SafeInvoker As ISynchronizeInvoke Try
SafeInvoker = DirectCast(del.Target, ISynchronizeInvoke) Catch EndTry If (Not SafeInvoker IsNothing) Then
SafeInvoker.Invoke(del, NewObject() {source, mask}) Else
del.Invoke(source, mask) EndIf EndIf EndSub#EndRegion
EndClass#EndRegion
#Region "Exceptions"PublicClass CIOChannelException : Inherits ApplicationException
'==================================================='' Module : CChannellException' Description: Customized Channell Exception' Created : 17/10/2001 - 10:32:37'
' Notes : This exception israised when NACK error found
'===================================================SubNew(ByVal Message AsString)
MyBase.New(Message)EndSubSubNew(ByVal Message AsString, ByVal InnerException As Exception)
MyBase.New(Message, InnerException)EndSub
EndClass
8/6/2019 App Note Kevin
39/40
PublicClass IOTimeoutException : Inherits CIOChannelException'==================================================='' Description : Timeout customized exception' Created : 28/02/2002 - 10:43:43'' *Parameters Info*'' Notes :'===================================================SubNew(ByVal Message AsString)
MyBase.New(Message)EndSubSubNew(ByVal Message AsString, ByVal InnerException As Exception)
MyBase.New(Message, InnerException)EndSub
EndClass
#EndRegion
8/6/2019 App Note Kevin
40/40
Sources:
Key Term Information:
http://en.wikipedia.org/wiki/Analog-to-digital_converter
http://en.wikipedia.org/wiki/PIC_microcontroller
http://en.wikipedia.org/wiki/RS232http://en.wikipedia.org/wiki/GUI
http://en.wikipedia.org/wiki/Op-amp
http://en.wikipedia.org/wiki/Thermistor
Digital Thermometer Lab:
http://www.cmmp.ucl.ac.uk/~nts/teachinglabs/3c40-e5.pdf
PIC MCU and GUI Programming:
http://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab4.pdf
http://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab3.pdf
Datasheets for components:
http://www.national.com/ds/LM/LM124.pdfhttp://ww1.microchip.com/downloads/en/DeviceDoc/39631B.pdf
http://www.datasheetcatalog.com/datasheets_pdf/M/A/X/2/MAX232.shtml
http://en.wikipedia.org/wiki/Analog-to-digital_converterhttp://en.wikipedia.org/wiki/PIC_microcontrollerhttp://en.wikipedia.org/wiki/RS232http://en.wikipedia.org/wiki/GUIhttp://en.wikipedia.org/wiki/Op-amphttp://en.wikipedia.org/wiki/Thermistorhttp://www.cmmp.ucl.ac.uk/~nts/teachinglabs/3c40-e5.pdfhttp://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab4.pdfhttp://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab3.pdfhttp://www.national.com/ds/LM/LM124.pdfhttp://ww1.microchip.com/downloads/en/DeviceDoc/39631B.pdfhttp://www.datasheetcatalog.com/datasheets_pdf/M/A/X/2/MAX232.shtmlhttp://en.wikipedia.org/wiki/Analog-to-digital_converterhttp://en.wikipedia.org/wiki/PIC_microcontrollerhttp://en.wikipedia.org/wiki/RS232http://en.wikipedia.org/wiki/GUIhttp://en.wikipedia.org/wiki/Op-amphttp://en.wikipedia.org/wiki/Thermistorhttp://www.cmmp.ucl.ac.uk/~nts/teachinglabs/3c40-e5.pdfhttp://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab4.pdfhttp://www.egr.msu.edu/classes/ece480/goodman/ForMiniprojects/Lab3.pdfhttp://www.national.com/ds/LM/LM124.pdfhttp://ww1.microchip.com/downloads/en/DeviceDoc/39631B.pdfhttp://www.datasheetcatalog.com/datasheets_pdf/M/A/X/2/MAX232.shtml