App Note Kevin

download App Note Kevin

of 40

Transcript of App Note Kevin

  • 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/Thermistor
  • 8/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.pdf
  • 8/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.pdf
  • 8/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.pdf
  • 8/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.pdf
  • 8/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.html
  • 8/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