NCDLib – Random Code for Controlling NCD Devices

Sometimes I like to write code to simplify my life, particularly when I need to call the same routines over and over.  Over the years, I have pieced a few code elements together to help make the NCD Component Library easier for me to use.  Some of this code is old, some is new, some is tested heavily, and some of it is random ideas I have had over the years.  A recent post on the forum prompted me to release the code, as I have been meaning to do this for a long time anyway.  This code represents a new class for Visual Studio, and I frequently call many of the routines in this class.  I would really like to point out two class items that have been added, as they greatly simplify communications to the I2C port on Fusion, BridgeX5, and other USART to I2C converters we manufacture (some of which are very small).  The I2C code class works with all of them, so have fun and hopefully you find something of use.  Please note a working implementation of this library is ALWAYS included with Base Station source code, which will soon be posted on GitHub.

Using this Library, the following function calls are now possible, making I2C communications much more like Python or Arduino controllers:

NCDLib.I2C.Write

NCDLib.I2C.Read

The above function will wrap up your RAW I2C Address and variables (as found in the datasheet of your I2C chip) and communicate to the I2C device via serial communications.  I hope to add direct support for many common chips over the next few years, but for now, here is a sample of the commands working with a MCP3428:

NCDLib.I2C.Chip.MCP3428.Setup_Channel(NCDComponent1, 0, GetAddressInteger(ADDR_A.SelectedItem), 1, Resolution, Gain)

Complete source code for these functions are shown below.  I would advise picking out what you need, as there are many functions below that are completely irrelevant and random (as they are used by Base Station).

Imports System.Reflection
Imports System.IO
Imports System.Windows.Forms
Imports NCD

Public Class NCDLib

    Public Class Wireless


        Public Class S3B_API

            Public Class ZigBeeData
                Public Addr As Array        ' Address in data frame
                Public Data As Array        ' Data in data frame
                Public Valid As Boolean     ' if the data is valid
            End Class
            Public Shared Sub Send(ByRef _ncd As NCD.NCDComponent, ByVal Address As Array, ByVal TXData As Array)
                'This function is used to format and send API data for S3B Modules, making communications with remote devices much easier

                Dim API As New ArrayList
                Dim DataLength As Integer
                Dim MSB_Length As Byte
                Dim LSB_Length As Byte
                Dim CkSum As Integer
                Dim Temporary As Integer

                DataLength = TXData.Length + 14      'Calculate the Length of the Array
                MSB_Length = DataLength >> 8
                LSB_Length = DataLength And 255

                Debug.Print(MSB_Length.ToString)
                Debug.Print(LSB_Length.ToString)


                API.Add(126)        '0,Header        0x7e
                API.Add(MSB_Length) '1,Length of Packet MSB
                API.Add(LSB_Length) '2,Length of Packet LSB
                API.Add(16)          '3,Reserved
                API.Add(0)          '4,Reserved no response come back to make read eaiser
                API.AddRange(Address)
                API.Add(255)        ' 0xfffe
                API.Add(254)        ' 0xfffe
                API.Add(0)          ' 15 set max hops, 0 for maxium
                API.Add(0)          ' 16, options 0, for disable ack
                API.AddRange(TXData)

                'Calculate Checksum
                CkSum = 0
                For Temporary = 3 To API.Count - 1
                    CkSum = CkSum + API(Temporary)
                Next
                CkSum = 255 - CkSum Mod 256

                API.Add(CkSum)
                Debug.Print(CkSum)

                'Send API Frame to Device
                'im d As Byte() = CType(API.ToArray(GetType(Byte)), Byte())
                Dim d(API.Count - 1) As Byte
                For i = 0 To API.Count - 1
                    d(i) = API(i)
                Next
                NCDLib.WriteBytes(_ncd, 0, d)


            End Sub

            Public Shared Function Receive(ByRef _ncd As NCD.NCDComponent) As ZigBeeData
                Dim rec As New ZigBeeData
                rec.Valid = False
                'This function is used to receive and decode API data from S3B Modules, this function will return Address and Data to the caller
                Dim r As Integer
                r = _ncd.ReadByte()
                If (r <> 126) Then
                    Return rec
                End If
                Dim msb, lsb As Integer
                msb = _ncd.ReadByte
                lsb = _ncd.ReadByte
                If (msb = -1) Or (lsb = -1) Then
                    Return rec
                End If

                'read length
                Dim nLen As Integer = msb * 256 + lsb
                Dim frameType As Integer
                frameType = _ncd.ReadByte
                If (frameType <> &H90) Then
                    Return rec
                End If
                ' read 8 bytes address
                Dim addr As New ArrayList
                For i = 1 To 8
                    Dim na As Integer
                    na = _ncd.ReadByte()
                    If (na <> -1) Then
                        addr.Add(na)
                    Else
                        Return rec
                    End If
                Next
                ' read 0xfffe
                Dim reserved As Integer
                reserved = _ncd.ReadByte()
                If (reserved = -1) Then
                    Return rec
                End If
                reserved = _ncd.ReadByte()
                If (reserved = -1) Then
                    Return rec
                End If
                Dim options As Integer

                ' read options
                options = _ncd.ReadByte()
                If (options = -1) Then
                    Return rec
                End If
                Dim recData As New ArrayList
                For i = 1 To nLen - 12
                    Dim rd As Integer = _ncd.ReadByte
                    If (rd <> -1) Then
                        recData.Add(rd)
                    Else
                        Return rec
                    End If
                Next
                Dim checksum As Integer = _ncd.ReadByte()
                If (checksum = -1) Then
                    Return rec
                End If
                Dim addr1(8 - 1) As Byte
                For i = 0 To 7
                    addr1(i) = addr(i)
                Next
                Dim data1(recData.Count - 1) As Byte
                For i = 0 To recData.Count - 1
                    data1(i) = recData(i)
                Next
                rec.Addr = addr1
                rec.Data = data1
                rec.Valid = True
                Return rec
            End Function
        End Class

    End Class


    Public Class Safe


        Public Shared Function FusionFirmwareVersionCheck(ByVal RequiredFirmwareVersionLarge As Integer, ByVal RequiredFirmwareVersionSmall As Integer, ByVal CurrentFirmwareVersionLarge As Integer, ByVal CurrentFirmwareVersionSmall As Integer, DialogBox As Boolean)
            'The purpose of this function is to check a require firmware version against a current firmware version
            'If it's safe, this function returns True, otherwise, it returns false

            'Default this Function to Fail, Make it PROVE True
            FusionFirmwareVersionCheck = False

            Dim RequiredWord As Integer = 0
            Dim CurrentWord As Integer = 0

            RequiredWord = (RequiredFirmwareVersionLarge * 256) + RequiredFirmwareVersionSmall
            CurrentWord = (CurrentFirmwareVersionLarge * 256) + CurrentFirmwareVersionSmall

            If CurrentWord >= RequiredWord Then
                FusionFirmwareVersionCheck = True
            Else
                If DialogBox = True Then
                    MsgBox("Fusion Firmware Version 4." + Str(RequiredFirmwareVersionLarge) + "." + Str(RequiredFirmwareVersionSmall) + " or Later is Required to Set Counter Events, Please Contact NCD Support to Arrange for a Firmware Upgrade.  Your Fusion Controller is Using Firmware Version 4." + Str(CurrentFirmwareVersionLarge) + "." + Str(CurrentFirmwareVersionSmall) + ".")
                End If
            End If


            Return FusionFirmwareVersionCheck

        End Function

        Public Shared Function Limit_8BIT(ByVal Value As Integer)
            If Value > 255 Then Value = 255
            If Value < 0 Then Value = 0
            Limit_8BIT = Value
        End Function
        Public Shared Function Limit_10BIT(ByVal Value As Integer)
            If Value > 1023 Then Value = 1023
            If Value < 0 Then Value = 0
            Limit_10BIT = Value
        End Function
        Public Shared Function Limit_12BIT(ByVal Value As Integer)
            If Value > 4095 Then Value = 4095
            If Value < 0 Then Value = 0
            Limit_12BIT = Value
        End Function
        Public Shared Function Limit_16BIT(ByVal Value As Integer)
            If Value > 65535 Then Value = 65535
            If Value < 0 Then Value = 0
            Limit_16BIT = Value
        End Function

        Public Shared Function Limit_Value(ByVal Value As Integer, LowerLimit As Integer, UpperLimit As Integer)


            If Value > UpperLimit Then Value = UpperLimit
            If Value < LowerLimit Then Value = LowerLimit
            Limit_Value = Value
        End Function
    End Class
    Public Class Fusion


        Public Const CON_BlockCount = 64
        Public Const CON_AllConfiguration = 0
        Public Const CON_DeviceConfiguration = 1
        Public Const CON_ProxrRelayMap = 2
        Public Const CON_Taralist = 3
        Public Const CON_ReactorStandard = 4
        Public Const CON_ReactorTLEE = 5
        Public Const CON_RemoteAccess = 6
        Public Const MAX_DATA_SIZE = &H8100 ' max size of data block is 16K




        Public Shared Sub SaveTLEEBlock(ByRef _ncd As NCD.NCDComponent, _BlockID As Integer, F As Array)

            Debug.Print("SaveTLEEBlock: " & _BlockID.ToString)
            Dim ckSum As Integer = 0

            'Filter F Array
            For temp As Integer = 0 To 15
                If F(temp) < 0 Then F(temp) = 0
                If F(temp) > 255 Then F(temp) = 255
            Next

            'Compute Checksum
            ckSum = 0
            For temp = 0 To 15
                ckSum = ckSum + F(temp)
            Next temp
            ckSum = (ckSum And 255)

            NCDLib.WriteBytesAPI(_ncd, True, 0, 4, NCDLib.Math.GetLSB(_BlockID), NCDLib.Math.GetMSB(_BlockID), F(0), F(1), F(2), F(3), F(4), F(5), F(6), F(7), F(8), F(9), F(10), F(11), F(12), F(13), F(14), F(15), ckSum)

            Debug.Print("END SaveTLEEBlock")

        End Sub
        Public Shared Function LoadTLEEBlock(ByRef _ncd As NCD.NCDComponent, _BlockID As Integer)

            Debug.Print("LoadTLEEBlock: " & _BlockID.ToString)
            Dim ckSum As Integer = 0
            Dim F As Array

            NCDLib.WriteBytesAPI(_ncd, True, 0, 3, NCDLib.Math.GetLSB(_BlockID), NCDLib.Math.GetMSB(_BlockID))
            F = NCDLib.ReadBytesAPI(_ncd, True, 17)

            If (Not (F Is Nothing)) Then
                If (F.Length < 16) Then
                    Debug.Print(F.Length)
                End If
                For Temp As Integer = 0 To 15
                    ckSum = ckSum + F(Temp)
                Next

                ckSum = (ckSum And 255)

                If ckSum = F(16) Then
                    Debug.Print("Block Loaded")
                    Return F
                Else
                    Debug.Print("--------------> CKSUM ERROR: " & F(16) & " " & ckSum)
                End If
            End If

            For Temp As Integer = 0 To 15
                F(Temp) = 255   'Return FF to User for Code Handling
            Next
            Debug.Print("ERROR: LoadTLEEBlock")
            Return F

        End Function

    End Class
    Public Class ReactorV2

        Public Shared Function Translate(Method As String, Dat As Integer, LongDescription As Boolean) 'As String

            Try

                ' (Distance3.Value * 0.25) / 12) : CM3.Text = String.Format("{0:f1}", (Distance3.Value * 0.25) * 2.54)
                'OK 8-Bit Analog Voltage
                'OK 10-Bit Analog Voltage
                'OK 12-Bit Analog Voltage
                'OK 16-Bit Analog Voltage
                'Distance in Inches
                'Distance in Feet
                'Distance in Centimeters
                'Distance in Meters
                'Temperature in Celsius
                'Temperature in Fahrenheit
                'Current in Amps/ma

                Debug.Print("Translate")
                Debug.Print(Method)
                Debug.Print(Dat)


                Select Case Method

                    Case "8-Bit Analog Voltage"
                        Dim Voltage As Integer = 5
                        Dim Level As Integer = Dat
                        Dim Result As String
                        If LongDescription = False Then
                            Result = String.Format("{0:f2} V", (Voltage / 256) * Level)
                        Else
                            Result = String.Format("{0:f2} Volts.  No Not Exceed +5VDC On ANY Analog Input.", (Voltage / 256) * Level)
                        End If
                        Return Result

                    Case "10-Bit Analog Voltage"
                        Dim Voltage As Integer = 5
                        Dim Level As Integer = Dat
                        Dim Result As String
                        If LongDescription = False Then
                            Result = String.Format("{0:f2} V", (Voltage / 1024) * Level)
                        Else
                            Result = String.Format("{0:f2} Volts.  No Not Exceed +5VDC On ANY Analog Input.", (Voltage / 1024) * Level)
                        End If
                        Return Result

                    Case "12-Bit Analog Voltage"
                        Dim Voltage As Integer = 5
                        Dim Level As Integer = Dat
                        Dim Result As String
                        If LongDescription = False Then
                            Result = String.Format("{0:f2} V", (Voltage / 4096) * Level)
                        Else
                            Result = String.Format("{0:f2} Volts.  No Not Exceed +5VDC On ANY Analog Input.", (Voltage / 4096) * Level)
                        End If

                        Return Result

                    Case "16-Bit Analog Voltage"
                        Dim Voltage As Integer = 5
                        Dim Level As Integer = Dat
                        Dim Result As String
                        If LongDescription = False Then
                            Result = String.Format("{0:f2} V", (Voltage / 65536) * Level)
                        Else
                            Result = String.Format("{0:f2} Volts.  No Not Exceed +5VDC On ANY Analog Input.", (Voltage / 65536) * Level)
                        End If
                        Return Result

                    Case "Distance in Inches"
                        Dim Level As Integer = Dat
                        Dim Result As String
                        If LongDescription = False Then
                            Result = String.Format("{0:f2} In", (0.25 * Level))
                        Else
                            Result = String.Format("{0:f2} Inches", (0.25 * Level))
                        End If
                        Return Result

                    Case "Distance in Feet"
                        Dim Level As Integer = Dat
                        Dim Result As String
                        If LongDescription = False Then
                            Result = String.Format("{0:f2} Ft", (0.25 * Level) / 12)
                        Else
                            Result = String.Format("{0:f2} Feet", (0.25 * Level) / 12)
                        End If
                        Return Result

                    Case "Distance in Centimeters"
                        Dim Level As Integer = Dat
                        Dim Result As String
                        If LongDescription = False Then
                            Result = String.Format("{0:f2} cm", (0.25 * Level) * 2.54)
                        Else
                            Result = String.Format("{0:f2} Centimeters", (0.25 * Level) * 2.54)
                        End If
                        Return Result

                    Case "Distance in Meters"
                        Dim Level As Integer = Dat
                        Dim Result As String
                        If LongDescription = False Then
                            Result = String.Format("{0:f2} M", ((0.25 * Level) * 2.54) / 10)
                        Else
                            Result = String.Format("{0:f2} Meters", ((0.25 * Level) * 2.54) / 10)
                        End If
                        Return Result

                    Case "Current in Amps/ma ACS712ELCTR-05B 185mv per Amp"
                        Dim Sensativity As Double = 0.185
                        'If Translator.SelectedItem = "ACS712ELCTR-05B 185mv per Amp" Then Sensativity = 0.185
                        'If Translator.SelectedItem = "ACS712ELCTR-20A 100mv per Amp" Then Sensativity = 0.1
                        'If Translator.SelectedItem = "ACS712ELCTR-30A 66mv per Amp" Then Sensativity = 0.066
                        Dim BitVolts As Double = 5 / 256     'BitVolts = 5 Volts Divided by 256 (8-Bit has 256 Posibilities)
                        Dim CalcCurrent As Double = (Dat * BitVolts) / Sensativity
                        Dim Result As String
                        If LongDescription = False Then
                            Result = String.Format("{0:f2} A", CalcCurrent)
                        Else
                            Result = String.Format("{0:f2} Amps.  Amperage Values are Approximate.", CalcCurrent)
                        End If
                        Return Result

                End Select


            Catch

                Debug.Print("Unable to Translate")

            End Try

            Return 0

        End Function


        Public Shared InterpreterListSize As Integer = 10
        Public Shared Function InterpreterList()
            Dim DropOptions(InterpreterListSize) As String

            '   B(13) = 0  8-Bit Analog Voltage
            '   B(13) = 1  10-Bit Analog Voltage
            '   B(13) = 2  12-Bit Analog Voltage
            '   B(13) = 3  16-Bit Analog Voltage
            '   B(13) = 4  Distance in Inches
            '   B(13) = 5  Distance in Feet
            '   B(13) = 6  Distance in Centimeters
            '   B(13) = 7  Distance in Meters
            '   B(13) = 8  Temperature in Celsius
            '   B(13) = 9  Temperature in Fahrenheit
            '   B(13) = 10 Current in Amps/ma ACS712ELCTR-05B 185mv per Amp

            DropOptions(0) = "8-Bit Analog Voltage"
            DropOptions(1) = "10-Bit Analog Voltage"
            DropOptions(2) = "12-Bit Analog Voltage"
            DropOptions(3) = "16-Bit Analog Voltage"
            DropOptions(4) = "Distance in Inches"
            DropOptions(5) = "Distance in Feet"
            DropOptions(6) = "Distance in Centimeters"
            DropOptions(7) = "Distance in Meters"
            DropOptions(8) = "Temperature in Celsius"
            DropOptions(9) = "Temperature in Fahrenheit"
            DropOptions(10) = "Current in Amps/ma ACS712ELCTR-05B 185mv per Amp"
            Return DropOptions
        End Function


        Public Class MasterEventList_4_0_0
            'Versions BEFORE 4.0.3
            Public Shared EventListSize_Base As Integer = 231   'Contains Events that do not require Parameters
            Public Shared EventListSize_All As Integer = 240    'Contains All Events including those that require Parameters

            'Versions 4.0.3 and AFTER!
            'Public Shared EventListSize_Base As Integer = 245   'Contains Events that do not require Parameters
            'Public Shared EventListSize_All As Integer = 245    'Contains All Events including those that require Parameters

            ''4.0.3 and Later Use these variables
            'Public Shared EventListSize_MIN As Integer = 241
            'Public Shared EventListSize_MAX As Integer = 245    '241-245 Do NOT Require Parameters

        End Class

        Public Class MasterEventList_4_0_3
            'Versions BEFORE 4.0.3
            'Public Shared EventListSize_Base As Integer = 231   'Contains Events that do not require Parameters
            'Public Shared EventListSize_All As Integer = 240    'Contains All Events including those that require Parameters

            'Versions 4.0.3 and AFTER!
            Public Shared EventListSize_Base As Integer = 245   'Contains Events that do not require Parameters
            Public Shared EventListSize_All As Integer = 245    'Contains All Events including those that require Parameters

            ''4.0.3 and Later Use these variables
            'Public Shared EventListSize_MIN As Integer = 241
            'Public Shared EventListSize_MAX As Integer = 245    '241-245 Do NOT Require Parameters


        End Class

        Public Class MasterEventList_4_0_5
            'Versions BEFORE 4.0.3
            'Public Shared EventListSize_Base As Integer = 231   'Contains Events that do not require Parameters
            'Public Shared EventListSize_All As Integer = 240    'Contains All Events including those that require Parameters

            'Versions 4.0.3 and AFTER!
            Public Shared EventListSize_Base As Integer = 249   'Contains Events that do not require Parameters
            Public Shared EventListSize_All As Integer = 249    'Contains All Events including those that require Parameters

            ''4.0.3 and Later Use these variables
            'Public Shared EventListSize_MIN As Integer = 241
            'Public Shared EventListSize_MAX As Integer = 245    '241-245 Do NOT Require Parameters

        End Class



    End Class

    Public Class Math

        Public Shared Function GetMSB(ByVal V As UInt16) As Byte
            Dim Result As Byte = 0
            Result = V >> 8
            Return Result
        End Function
        Public Shared Function GetLSB(ByVal V As UInt16) As Byte
            Dim Result As Byte = 0
            Result = V And 255
            Return Result
        End Function
        ''' <summary>
        ''' Set bit of byte to specific value
        ''' </summary>
        ''' <param name="v">byte to set</param>
        ''' <param name="pos">position of bit, start from 0, </param>
        ''' <param name="bitValue">value of bit, 0 or 1</param>
        ''' <returns>byte with specific bit set</returns>
        ''' <remarks></remarks>
        Public Shared Function SetBitEnum(ByVal v As Byte, ByVal pos As Byte, ByVal bitValue As enumBitValue) As Byte
            If (pos > 7) Then
                Throw New ArgumentOutOfRangeException("Position", pos, "Position should range from 0 to 7")
            End If

            Return SetBit(v, pos, CByte(bitValue))
        End Function
        Public Enum enumBitValue
            [ON]
            Off
        End Enum
        ''' <summary>
        ''' Get specfic bit of byte
        ''' </summary>
        ''' <param name="v">value of byte</param>
        ''' <param name="pos">position of byte</param>
        ''' <returns>0 or 1</returns>
        ''' <remarks></remarks>
        Public Shared Function GetBit(ByVal v As Byte, ByVal pos As Byte) As Byte
            If (pos > 7) Then
                Throw New ArgumentOutOfRangeException("Position", pos, "Position should range from 0 to 7")
            End If

            Dim result As Byte = v
            ' set the bit to sepecific value
            ' bitValue << pos   ' calculate the value of bit in byte
            ' v1 And v2 do an and operation 
            Dim value As Byte = 1 << pos
            result = CByte(v And value)
            If (result > 0) Then
                result = 1
            End If
            Return result
        End Function
        Public Shared Function GetBit16(ByVal v As UInt16, ByVal pos As Byte) As Byte
            If (pos > 15) Then
                Throw New ArgumentOutOfRangeException("Position", pos, "Position should range from 0 to 15")
            End If

            Dim result As UInt16 = v
            ' set the bit to sepecific value
            ' bitValue << pos   ' calculate the value of bit in byte
            ' v1 And v2 do an and operation 
            Dim value As UInt16 = 1 << pos
            result = CUInt(v And value)
            If (result > 0) Then
                result = 1
            End If
            Return result
        End Function
        ''' <summary>
        ''' Set bit of byte to specific value
        ''' </summary>
        ''' <param name="v">byte to set</param>
        ''' <param name="pos">position of bit, start from 0, </param>
        ''' <param name="bitValue">value of bit, 0 or 1</param>
        ''' <returns>byte with specific bit set</returns>
        ''' <remarks></remarks>
        Public Shared Function SetBit(ByRef v As Byte, ByVal pos As Byte, ByVal bitValue As Byte) As Byte
            If (pos > 7) Then
                Throw New ArgumentOutOfRangeException("Position", pos, "Position should range from 0 to 7")
            End If

            If (bitValue > 1) Then
                Throw New ArgumentOutOfRangeException("Bit Value", bitValue, "Bit Value should range from 0 to 1")
            End If

            Dim result As Byte = v
            ' set the bit to sepecific value
            ' bitValue << pos   ' calculate the value of bit in byte
            ' v1 And v2 do an and operation 
            Dim value As Byte = 1 << pos
            result = CByte(v Or value)
            result = CByte(result - value)
            ' we use CByte to conver the result to byte forcely
            ' calculate the value if a byte with that bit only set to the specfic value
            'If Bit Value is 0, it is not modified, but if Bit Value is 1 then Bit is Turned On
            value = bitValue << pos

            result = CByte(result + value)
            v = result
            Return result
        End Function
        Public Shared Function SetBit16(ByRef v As UInt16, ByVal pos As Byte, ByVal bitValue As Byte) As UInt16
            If (pos > 15) Then
                Throw New ArgumentOutOfRangeException("Position", pos, "Position should range from 0 to 7")
            End If

            If (bitValue > 1) Then
                Throw New ArgumentOutOfRangeException("Bit Value", bitValue, "Bit Value should range from 0 to 1")
            End If

            Dim result As UInt16 = v
            ' set the bit to sepecific value
            ' bitValue << pos   ' calculate the value of bit in byte
            ' v1 And v2 do an and operation 
            Dim value As UInt16 = 1 << pos
            result = CUInt(v Or value)
            result = CUInt(result - value)
            ' we use CByte to conver the result to byte forcely
            ' calculate the value if a byte with that bit only set to the specfic value
            'If Bit Value is 0, it is not modified, but if Bit Value is 1 then Bit is Turned On
            ' to convert bitValue to CUint is very IMPORTANT, otherwise it will works like byte only
            value = CUInt(bitValue) << pos

            result = CUInt(result + value)
            v = result
            Return result
        End Function
        Public Shared Function DecToBinaryString(ByVal V As Byte) As String
            Dim str As String = String.Empty
            Dim i As Integer = 0
            For i = 0 To 7
                If GetBit(V, i) = 0 Then
                    str = str + "0"
                Else
                    str = str + "1"
                End If
            Next
            Return str
        End Function
        Public Shared Function DecToBinaryStringStandard(ByVal V As Byte) As String
            Dim str As String = String.Empty
            Dim i As Integer = 0
            For i = 7 To 0 Step -1
                If GetBit(V, i) = 0 Then
                    str = str + "0"
                Else
                    str = str + "1"
                End If
            Next
            Return str
        End Function
        Public Shared Function BinaryStringToDec(ByVal V As String) As Byte
            Return System.Convert.ToByte(V, 2)
        End Function
        Public Shared Function DecToHexString(ByVal V As Byte) As String
            'Return String.Format("{0:X2}", V)
            Return V.ToString("X2")
        End Function

        Public Shared Function HexStringToDec(ByVal V As String) As Byte
            Return Byte.Parse(V, Globalization.NumberStyles.AllowHexSpecifier)
        End Function

        ''' <summary>
        ''' Convert an byte to binary code decimal
        ''' </summary>
        ''' <param name="v"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function ConvertToBCD(ByVal v As Byte) As Byte
            Dim a As Byte = System.Math.Floor(v / 10)
            Dim b As Byte = v Mod 10
            Return a * 16 + b
        End Function

        ''' <summary>
        ''' Convert an binary code decimal to decimal
        ''' </summary>
        ''' <param name="v"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function ConvertFromBCD(ByVal v As Byte) As Byte
            Dim a As Byte = System.Math.Floor(v / 16)
            Dim b As Byte = v Mod 16
            Return a * 10 + b
        End Function

    End Class


    ''' <summary>
    ''' File IO class handle all File's IO operation
    ''' </summary>
    ''' <remarks></remarks>
    Public Class FileIO
        Public Shared Function SaveDialog()

        End Function
        Public Shared Function LoadDialog()

        End Function
        Public Shared Function SaveQuiet()

        End Function
        Public Shared Function LoadQuiet()

        End Function
        Public Shared Function CheckFileExistance()

        End Function
    End Class
    Public Class DeviceInitialization
        Public Shared Function Discover_Baud_Rate(ByRef _ncd As NCDComponent) As Boolean
            '_ncd.SerialPort.StopBits = Ports.StopBits.Two
            Dim Result As Boolean = False
            Dim test As Integer = 0
            '_ncd.SerialPort.BaudRate = 115200
            test = Test_2WAY_RAW(_ncd)
            test = Test_2WAY_RAW(_ncd)
            If test = 85 Or test = 86 Then
                Result = True
                Return Result
                Exit Function
            End If
            _ncd.BaudRate = 57600
            test = Test_2WAY_RAW(_ncd)
            test = Test_2WAY_RAW(_ncd)
            If test = 85 Or test = 86 Then
                Result = True
                Return Result
                Exit Function
            End If
            _ncd.BaudRate = 9600
            test = Test_2WAY_RAW(_ncd)
            test = Test_2WAY_RAW(_ncd)
            If test = 85 Or test = 86 Then
                Result = True
                Return Result
                Exit Function
            End If
        End Function
        Public Shared Function Test_Compatibility(ByRef _ncd As NCDComponent) As Boolean
            '_ncd.SerialPort.StopBits = Ports.StopBits.Two

            Dim Result As Boolean = False
            Dim test As Integer = 0

            '_ncd.SerialPort.DiscardInBuffer()    'Clear Serial Port
            _ncd.Purge()
            System.Threading.Thread.Sleep(10)
            '_ncd.WriteByte(254)
            'System.Threading.Thread.Sleep(1)
            '_ncd.WriteByte(246)
            NCDLib.WriteBytes(_ncd, 1, 254, 246)
            _ncd.SetTcpWritePace(1)
            _ncd.Flush()
            System.Threading.Thread.Sleep(10)
            '_ncd.WriteBytes(New Byte() {254, 246})

            Dim IDA As Integer = _ncd.ReadByte()
            Dim IDB As Integer = _ncd.ReadByte()
            Dim IDC As Integer = _ncd.ReadByte()
            Dim IDD As Integer = _ncd.ReadByte()


            If IDA >= 64 And IDA <= 69 Then
                Result = True
            Else
                'Result = True
                MsgBox("This software is not designed to work with the controller you are using.")
            End If

            Return Result
            Exit Function

            '_ncd.SerialPort.BaudRate = 115200
            'test = Test_2WAY_RAW(_ncd)
            'test = Test_2WAY_RAW(_ncd)
            'If test = 85 Or test = 86 Then
            '    Result = True
            '    Return Result
            '    Exit Function
            'End If
            '_ncd.SerialPort.BaudRate = 57600
            'test = Test_2WAY_RAW(_ncd)
            'test = Test_2WAY_RAW(_ncd)
            'If test = 85 Or test = 86 Then
            '    Result = True
            '    Return Result
            '    Exit Function
            'End If
            '_ncd.SerialPort.BaudRate = 9600
            'test = Test_2WAY_RAW(_ncd)
            'test = Test_2WAY_RAW(_ncd)
            'If test = 85 Or test = 86 Then
            '    Result = True
            '    Return Result
            '    Exit Function
            'End If
        End Function
        Public Shared Function Test_2WAY_RAW(ByRef _ncd As NCDComponent) As Integer
            '_ncd.SerialPort.ReadTimeout = 500
            '_ncd.SerialPort.DiscardInBuffer()
            _ncd.Purge()
            NCDLib.WriteBytes(_ncd, 1, 254, 33)
            _ncd.SetTcpWritePace(1)
            _ncd.Flush()
            Dim result As Integer = _ncd.ReadByte
            Return result
        End Function
        Public Shared Function Test_For_Configuration_Mode(ByRef _ncd As NCDComponent) As Boolean

            Dim result As Boolean = False
            Dim retry As Integer = 0
            If (Not _ncd.IsOpen) Then
                Return False
            End If
Restart:
            '_ncd.SerialPort.ReadTimeout = 1000
            '_ncd.SerialPort.DiscardInBuffer()
            _ncd.Purge()
            NCDLib.WriteBytes(_ncd, 1, 254, 33)
            _ncd.SetTcpWritePace(1)
            _ncd.Flush()

            Dim result2 As Integer = _ncd.ReadByte
            Debug.Print("Result of Communications " + result2.ToString)

            If result2 <> 85 Then
                If result2 <> 86 Then
                    retry = retry + 1
                    If retry < 4 Then
                        GoTo Restart
                    End If
                End If
            End If

            If result2 = 85 Then
                MsgBox("Cannot Save.  Controller is in Runtime Mode and Must be Set to Program Mode.  Move PGM/RUN Jumpter to PGM positon and Try Again.")
                result = False
                Return result
            Else
                If result2 = 86 Then
                    Debug.Print("Controller is ready for this program.")
                    result = True
                    Return result
                Else
                    MsgBox("Unable to Communicate with Controller.")
                    result = False
                    Return result
                End If
            End If

        End Function
        Public Shared Function SerialPortDialog()

        End Function
        Public Shared Function ZigBee_S1Dialog()

        End Function
        Public Shared Function ZB_S2Dialog()

        End Function
        Public Shared Function XSC_Dialog()

        End Function
        Public Shared Function DM_Dialog()

        End Function
    End Class
    Public Class EEPROMIO

        Const Filter As String = "NCD EEPROM FILES(*.ncd)|*.ncd|All Files(*.*)|(*.*)"

        Const DefaultFilename As String = "EEPROM.ncd"

        Public EEPROM As Byte() = New Byte(255) {}

        Public Function SaveDialog() As Boolean
            Dim result As Boolean = False
            Dim SaveFileDialog1 As SaveFileDialog = New SaveFileDialog
            SaveFileDialog1.InitialDirectory = GetDefaultNCDFileFolder()
            SaveFileDialog1.Filter = Filter
            SaveFileDialog1.FileName = "EEPROM.NCD"
            If (SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK) Then
                SaveFile(SaveFileDialog1.FileName, EEPROM)
                result = True
            Else
                result = False
            End If
            Return result
        End Function
        Public Sub SaveFileQuite()
            Dim file As String = GetDefaultNCDFilePath()
            SaveFile(file, EEPROM)
        End Sub
        ''' <summary>
        ''' Save file to specific path
        ''' </summary>
        ''' <param name="filename"></param>
        ''' <param name="data"></param>
        ''' <remarks></remarks>
        Public Sub SaveFile(ByVal filename As String, ByVal data As Byte())
            Try
                Dim sw As BinaryWriter = New BinaryWriter(File.Open(filename, FileMode.Create))
                Dim version As Integer = 1
                Dim length As Integer = data.Length
                Dim i As Integer = 0
                sw.Write(version)
                sw.Write(length)
                sw.Write(data, 0, length)
                Dim chksum As Integer = GetCheckSum(data)
                sw.Write(chksum)
                sw.Flush()
                sw.Close()
                DumpEEPROM()
            Catch ex As Exception
                Throw New Exception("Write ncd file failure")
            End Try
        End Sub
        Public Sub LoadFileQuite()
            Dim filename As String = GetDefaultNCDFilePath()
            EEPROM = LoadFile(filename)
        End Sub
        ''' <summary>
        ''' Load file from specific path
        ''' </summary>
        ''' <param name="filename"></param>
        ''' <returns>bytes read from file</returns>
        ''' <remarks></remarks>
        ''' <exception cref="Exception">Corrupt NCD File</exception>
        Public Function LoadFile(ByVal filename As String) As Byte()
            Dim data As Byte() = Nothing
            Try
                Dim sr As BinaryReader = New BinaryReader(File.Open(filename, FileMode.Open))
                Dim version As Integer = sr.ReadInt32()
                Dim length As Integer = sr.ReadInt32()
                data = sr.ReadBytes(length)
                Dim checksum As Integer = sr.ReadInt32()
                If (checksum <> GetCheckSum(data)) Then
                    Throw New Exception("Corrupt NCD File")
                End If
                sr.Close()
            Catch ex As Exception
                Throw New Exception("Corrupt NCD File")
            End Try
            Return data
        End Function
        Public Function LoadDialog() As Boolean
            Dim result As Boolean = False
            Dim OpenFileDialog1 As OpenFileDialog = New OpenFileDialog
            OpenFileDialog1.InitialDirectory = GetDefaultNCDFileFolder()
            OpenFileDialog1.FileName = DefaultFilename
            OpenFileDialog1.Filter = Filter
            If (OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK) Then
                EEPROM = LoadFile(OpenFileDialog1.FileName)
                result = True
            Else
                result = False
            End If
            Return result
        End Function
        Public Sub DumpEEPROM()
            Debug.Print("begin dump")
            Dim i As Integer = 0
            For i = 0 To EEPROM.Length - 1
                System.Diagnostics.Debug.Write(NCDLib.Math.DecToHexString(EEPROM(i)) + " ")
                If (i Mod 16) = 0 Then
                    System.Diagnostics.Debug.WriteLine("")
                End If
            Next
            Debug.Print("end dump")

        End Sub
        Private Function GetDefaultNCDFileFolder() As String
            ' get current executing assembly
            Dim app As Assembly = Assembly.GetExecutingAssembly()
            Dim locationPath As String = Path.GetDirectoryName(app.ManifestModule.FullyQualifiedName)
            'Dim ncdFilePath As String = locationPath + "\EEPROM.ncd"
            'Return ncdFilePath
            Return locationPath
        End Function
        Private Function GetDefaultNCDFilePath()
            Return GetDefaultNCDFileFolder() + "\" + DefaultFilename
        End Function
        ''' <summary>
        ''' Get the checksum of array
        ''' </summary>
        ''' <param name="a"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Function GetCheckSum(ByVal a As Byte()) As Integer
            Dim i As Integer = 0
            Dim checksum As Integer = 0
            For i = 0 To a.Length - 1
                checksum = checksum + a(i)
            Next
            Return checksum
        End Function

        ''' <summary>
        ''' This function is used to store EEPROM Data to NCD CPU 
        ''' </summary>
        ''' <returns>Assume This Function Fails Unless Otherwise Notified by Result</returns>
        ''' <remarks></remarks>
        Public Function To_Chip(ByRef _ncd As NCD.NCDComponent, ByRef _block As Byte) As Boolean
            Dim retry As Integer = 0
RetryIt:
            Dim result As Boolean = False
            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return result                                           'Return Result to the Caller and Exit Function
            End If

            If _block = 15 Then
                Debug.Print("Block 15 Cannot be Stored by this Function...Quietyly Emulating Storage of this block...")
                result = True
                Return result
            End If

            '_ncd.SerialPort.DiscardInBuffer()
            _ncd.Purge()

            'If (_ncd.UsingComPort) Then
            NCDLib.WriteBytes(_ncd, 2, 0, 2, _block)
            _ncd.SetTcpWritePace(2)
            _ncd.Flush()
            DELA()
            Dim Checksum As Integer = 0                                   'Define Checksum
            For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                _ncd.WriteByte(EEPROM(DataByte + (_block * 16)))        'One Byte at a Time
                DELA()
                Checksum += EEPROM(DataByte + (_block * 16))            'Include Each Byte in the Checkum Value
                'Debug.Print("Storing 2:" + EEPROM(DataByte + (_block * 16)).ToString)
            Next DataByte
            Checksum = Checksum And 255
            _ncd.WriteByte(Checksum)                                    'Send the Checksum Value to the Controller


            Dim ReturnValue As Integer = _ncd.ReadByte()                   'Wait for the Controller to Respond with 85 Confirmation Byte
            If ReturnValue = 85 Then                                    'If 85 is Returned from the controller
                result = True                                           'This Function was successful and the Result is True
            Else
                retry = retry + 1
                Debug.Print("retry " + retry.ToString)
                If retry < 4 Then
                    GoTo RetryIt
                End If
            End If

            Return result                                               'Return Result to Caller and Exit Function
        End Function

        ''' <summary>
        ''' This function is used to store EEPROM Data to NCD CPU 
        ''' </summary>
        ''' <returns>Assume This Function Fails Unless Otherwise Notified by Result</returns>
        ''' <remarks></remarks>
        Public Function To_ChipFast(ByRef _ncd As NCD.NCDComponent, ByRef _block As Byte) As Boolean
            Dim retry As Integer = 0
RetryIt:
            Dim result As Boolean = False
            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return result                                           'Return Result to the Caller and Exit Function
            End If

            If _block = 15 Then
                Debug.Print("Block 15 Cannot be Stored by this Function...Quietyly Emulating Storage of this block...")
                result = True
                Return result
            End If

            _ncd.Purge()

            'If (_ncd.UsingComPort) Then
            _ncd.WriteBytes(0, 2, _block)
            '_ncd.SetTcpWritePace(2)
            _ncd.Flush()
            Dim Checksum As Integer = 0                                   'Define Checksum
            For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                _ncd.WriteByte(EEPROM(DataByte + (_block * 16)))        'One Byte at a Time
                Checksum += EEPROM(DataByte + (_block * 16))            'Include Each Byte in the Checkum Value
            Next DataByte
            Checksum = Checksum And 255
            _ncd.WriteByte(Checksum)                                    'Send the Checksum Value to the Controller


            'Else
            'Dim Checksum As Integer = 0                                   'Define Checksum
            'Dim tmp(0 To 19) As Byte
            'tmp(0) = 0
            'tmp(1) = 2
            'tmp(2) = _block
            'For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
            '    '_ncd.WriteByte(EEPROM(DataByte + (_block * 16)))        'One Byte at a Time
            '    tmp(DataByte + 3) = EEPROM(DataByte + (_block * 16))
            '    Checksum += EEPROM(DataByte + (_block * 16))            'Include Each Byte in the Checkum Value
            '    'Debug.Print("Storing 2:" + EEPROM(DataByte + (_block * 16)).ToString)
            'Next DataByte
            'Checksum = Checksum And 255
            'tmp(19) = Checksum
            ''_ncd.SetTcpWritePace(0)

            ''_ncd.WriteByte(Checksum)                                    'Send the Checksum Value to the Controller
            'Threading.Thread.Sleep(1000)
            'End If

            Dim ReturnValue As Integer = _ncd.ReadByte()                   'Wait for the Controller to Respond with 85 Confirmation Byte
            If ReturnValue = 85 Then                                    'If 85 is Returned from the controller
                result = True                                           'This Function was successful and the Result is True
            Else
                retry = retry + 1
                Debug.Print("retry " + retry.ToString)
                If retry < 4 Then
                    GoTo RetryIt
                End If
            End If

            Return result                                               'Return Result to Caller and Exit Function
        End Function



        ''' <summary>
        ''' This function is used to store EEPROM Data to NCD CPU 
        ''' </summary>
        ''' <returns>Assume This Function Fails Unless Otherwise Notified by Result</returns>
        ''' <remarks></remarks>
        Public Shared Function To_EEPROM_Chip(ByRef _ncd As NCD.NCDComponent, ByVal _blockId As Integer, ByVal blockData As Byte()) As Boolean
            Dim retry As Integer = 0
RetryIt:
            Dim result As Boolean = False
            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return result                                           'Return Result to the Caller and Exit Function
            End If

            '_ncd.SerialPort.DiscardInBuffer()
            'DELA()
            '_ncd.WriteByte(0)                                           'Send Header Byte
            'DELA()
            '_ncd.WriteByte(4)                                           'Send Store Command
            'DELA()
            '_ncd.WriteByte(NCDLib.Math.GetLSB(_blockId))                                      'Send Block
            'DELA()
            '_ncd.WriteByte(NCDLib.Math.GetMSB(_blockId))                                      'Send Block

            '_ncd.WriteBytes(New Byte() {0, 4, NCDLib.Math.GetLSB(_blockId), NCDLib.Math.GetMSB(_blockId)})
            NCDLib.WriteBytes(_ncd, 2, 0, 4, NCDLib.Math.GetLSB(_blockId), NCDLib.Math.GetMSB(_blockId))
            _ncd.SetTcpWritePace(2)
            _ncd.Flush()
            DELA()
            Dim Checksum As Integer = 0                                   'Define Checksum
            For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                _ncd.WriteByte(blockData(DataByte))        'One Byte at a Time
                DELA()
                Checksum += blockData(DataByte) 'Include Each Byte in the Checkum Value
                'Debug.Print("Storing 2:" + EEPROM(DataByte + (_block * 16)).ToString)
            Next DataByte
            Checksum = Checksum And 255
            _ncd.WriteByte(Checksum)                                    'Send the Checksum Value to the Controller

            Dim ReturnValue As Integer = _ncd.ReadByte()                   'Wait for the Controller to Respond with 85 Confirmation Byte
            If ReturnValue = 85 Then                                    'If 85 is Returned from the controller
                result = True                                           'This Function was successful and the Result is True
            Else
                retry = retry + 1
                If retry < 4 Then
                    GoTo RetryIt
                End If
            End If

            Return result                                               'Return Result to Caller and Exit Function
        End Function


        ''' <summary>
        ''' This function is used to store EEPROM Data to NCD CPU 
        ''' </summary>
        ''' <returns>Assume This Function Fails Unless Otherwise Notified by Result</returns>
        ''' <remarks></remarks>
        Public Shared Function To_EEPROM_ChipFast(ByRef _ncd As NCD.NCDComponent, ByVal _blockId As Integer, ByVal blockData As Byte()) As Boolean
            Dim retry As Integer = 0
RetryIt:
            Dim result As Boolean = False
            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return result                                           'Return Result to the Caller and Exit Function
            End If

            '_ncd.TRIIWriteBytes(0, 4, NCDLib.Math.GetLSB(_blockId), NCDLib.Math.GetMSB(_blockId))
            'Dim Checksum As Integer = 0                                   'Define Checksum
            'For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
            '    _ncd.TRIIWriteBytes(blockData(DataByte))        'One Byte at a Time
            '    Checksum += blockData(DataByte) 'Include Each Byte in the Checkum Value
            '    'Debug.Print("Storing 2:" + EEPROM(DataByte + (_block * 16)).ToString)
            'Next DataByte
            'Checksum = Checksum And 255
            '_ncd.TRIIWriteBytes(Checksum)                                    'Send the Checksum Value to the Controller
            '_ncd.SetTcpWritePace(0)
            '_ncd.Flush()

            'Dim ReturnValue As Integer = _ncd.ReadByte()                   'Wait for the Controller to Respond with 85 Confirmation Byte
            'If ReturnValue = 85 Then                                    'If 85 is Returned from the controller
            '    result = True                                           'This Function was successful and the Result is True
            'Else
            '    Debug.Print(ReturnValue.ToString)

            '    retry = retry + 1
            '    Debug.Print("retry save to eeprom " & retry)
            '    If retry < 4 Then
            '        GoTo RetryIt
            '    End If
            'End If

            Dim a As ArrayList = New ArrayList
            a.Add(0)
            a.Add(4)
            a.Add(NCDLib.Math.GetLSB(_blockId))
            a.Add(NCDLib.Math.GetMSB(_blockId))

            'WriteBytesAPI(_ncd, True, 0, 4, NCDLib.Math.GetLSB(_blockId), NCDLib.Math.GetMSB(_blockId))
            Dim Checksum As Integer = 0                                   'Define Checksum
            For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                'WriteBytesAPI(_ncd, True, blockData(DataByte))        'One Byte at a Time
                a.Add(blockData(DataByte))
                Checksum += blockData(DataByte) 'Include Each Byte in the Checkum Value
                'Debug.Print("Storing 2:" + EEPROM(DataByte + (_block * 16)).ToString)
            Next DataByte
            Checksum = Checksum And 255
            'WriteBytesAPI(_ncd, True, Checksum)                                    'Send the Checksum Value to the Controller
            a.Add(Checksum)
            Dim aB(a.Count - 1) As Byte
            For i As Integer = 0 To a.Count - 1
                aB(i) = a(i)
            Next
            WriteBytesAPI(_ncd, True, aB)
            _ncd.SetTcpWritePace(0)
            _ncd.Flush()

            Dim ReturnValue As Integer = ReadByteAPI(_ncd, True)                   'Wait for the Controller to Respond with 85 Confirmation Byte
            If ReturnValue = 85 Then                                    'If 85 is Returned from the controller
                result = True                                           'This Function was successful and the Result is True
            Else
                Debug.Print(ReturnValue.ToString)

                retry = retry + 1
                Debug.Print("retry save to eeprom " & retry)
                If retry < 4 Then
                    GoTo RetryIt
                End If
            End If


            Return result                                               'Return Result to Caller and Exit Function
        End Function

        ''' <summary>
        ''' This function is used to store EEPROM Data to NCD CPU 
        ''' </summary>
        ''' <returns>Assume This Function Fails Unless Otherwise Notified by Result</returns>
        ''' <remarks></remarks>
        Public Function To_Chip_PROTECTED(ByRef _ncd As NCD.NCDComponent, ByRef _block As Byte) As Boolean
            Dim retry As Integer = 0
RetryIt:
            Dim result As Boolean = False
            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return result                                           'Return Result to the Caller and Exit Function
            End If

            If _block <> 15 Then
                Debug.Print("This Function Only Works for Block 15")
                result = False
                Return result
            End If
            '_ncd.SerialPort.DiscardInBuffer()
            'DELA()
            '_ncd.WriteByte(0)                                           'Send Header Byte
            'DELA()
            '_ncd.WriteByte(2)                                           'Send Store Command
            'DELA()
            '_ncd.WriteByte(15)                                         'Send Block 15 ONLY
            'DELA()

            '_ncd.WriteBytes(New Byte() {0, 2, 15})
            NCDLib.WriteBytes(_ncd, 2, 0, 2, 15)
            _ncd.SetTcpWritePace(2)
            _ncd.Flush()

            Dim Checksum As Integer = 0                                   'Define Checksum
            For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                _ncd.WriteByte(EEPROM(DataByte + (_block * 16)))        'One Byte at a Time
                DELA()
                Checksum += EEPROM(DataByte + (_block * 16))            'Include Each Byte in the Checkum Value
                'Debug.Print("Storing 2:" + EEPROM(DataByte + (_block * 16)).ToString)
            Next DataByte
            Checksum = Checksum And 255
            _ncd.WriteByte(Checksum)                                    'Send the Checksum Value to the Controller

            Dim ReturnValue As Integer = _ncd.ReadByte()                   'Wait for the Controller to Respond with 85 Confirmation Byte
            If ReturnValue = 85 Then                                    'If 85 is Returned from the controller
                result = True                                           'This Function was successful and the Result is True
            Else
                retry = retry + 1
                If retry < 4 Then
                    GoTo RetryIt
                End If
            End If

            Return result                                               'Return Result to Caller and Exit Function
        End Function

        ''' <summary>
        ''' This function is used to store EEPROM Data to NCD CPU 
        ''' </summary>
        ''' <returns>Assume This Function Fails Unless Otherwise Notified by Result</returns>
        ''' <remarks></remarks>
        Public Function To_Chip_ProtectedFast(ByRef _ncd As NCD.NCDComponent, ByRef _block As Byte) As Boolean
            Dim retry As Integer = 0
RetryIt:
            Dim result As Boolean = False
            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return result                                           'Return Result to the Caller and Exit Function
            End If

            If _block <> 15 Then
                Debug.Print("This Function Only Works for Block 15")
                result = False
                Return result
            End If
            _ncd.WriteBytes(0, 2, 15)
            _ncd.SetTcpWritePace(0)
            _ncd.Flush()

            Dim Checksum As Integer = 0                                   'Define Checksum
            For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                _ncd.WriteByte(EEPROM(DataByte + (_block * 16)))        'One Byte at a Time
                _ncd.Flush()
                Checksum += EEPROM(DataByte + (_block * 16))            'Include Each Byte in the Checkum Value
                'Debug.Print("Storing 2:" + EEPROM(DataByte + (_block * 16)).ToString)
            Next DataByte
            Checksum = Checksum And 255
            _ncd.WriteByte(Checksum)                                    'Send the Checksum Value to the Controller
            _ncd.Flush()

            Dim ReturnValue As Integer = _ncd.ReadByte()                   'Wait for the Controller to Respond with 85 Confirmation Byte
            If ReturnValue = 85 Then                                    'If 85 is Returned from the controller
                result = True                                           'This Function was successful and the Result is True
            Else
                retry = retry + 1
                If retry < 4 Then
                    GoTo RetryIt
                End If
            End If

            Return result                                               'Return Result to Caller and Exit Function
        End Function



        ''' <summary>
        ''' This function is used to Get EEPROM Data from NCD CPU
        ''' </summary>
        ''' <returns>Assume This Function Fails Unless Otherwise Notified by Result</returns>
        ''' <remarks></remarks>
        Public Function From_Chip(ByRef _ncd As NCD.NCDComponent, ByRef _block As Byte) As Boolean
            Dim result As Boolean = False
            Dim Retrys As Integer = 0

Retry:
            Dim ErrorCode As Integer = 0

            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return result                                           'Return Result to the Caller and Exit Function
            End If

            Try
                'If (_ncd.UsingComPort) Then
                '    DELA()
                '    _ncd.WriteByte(0)                                           'Send Header Byte
                '    DELA()
                '    _ncd.WriteByte(1)                                           'Send Retrieve Command Byte
                '    DELA()
                '    _ncd.WriteByte(_block)                                      'Send Block
                '    DELA()

                'Else
                '    _ncd.WriteBytes(New Byte() {0, 1, _block})

                'End If
                _ncd.SetTcpWritePace(2)
                NCDLib.WriteBytes(_ncd, 2, 0, 1, _block)
                _ncd.Flush()
                Threading.Thread.Sleep(50)
                Dim Checksum As Integer = 0                                    'Define Checksum
                For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                    EEPROM(DataByte + (_block * 16)) = _ncd.ReadByte()      'One Byte at a Time
                    'Debug.Print(EEPROM(DataByte + (_block * 16)).ToString)
                    Checksum += EEPROM(DataByte + (_block * 16))            'Include Each Byte in the Checkum Value
                    Threading.Thread.Sleep(30)
                Next DataByte
                Checksum = Checksum And 255

                Dim ReturnValue As Byte = _ncd.ReadByte()                   'Wait for the Controller to Respond with Checksum Value

                If ReturnValue = Checksum Then                              'If Checksum Matches Returned Value from the controller
                    Debug.Print("CORRECT" + _block.ToString)
                    result = True 'This Function was successful and the Result is True
                    ErrorCode = 0
                Else
                    Debug.Print("ERROR: CHECKSUM")
                    ErrorCode = 1
                End If
            Catch
                Debug.Print("Communication Error.")
                ErrorCode = 2
            End Try

            If ErrorCode <> 0 Then
                Debug.Print("RETRY ERROR")
                Retrys = Retrys + 1
                If Retrys < 10 Then
                    GoTo Retry
                End If
            End If

            Return result                                               'Return Result to Caller and Exit Function
        End Function

        ''' <summary>
        ''' This function is used to Get EEPROM Data from NCD CPU
        ''' </summary>
        ''' <returns>Assume This Function Fails Unless Otherwise Notified by Result</returns>
        ''' <remarks></remarks>
        Public Function From_ChipFast(ByRef _ncd As NCD.NCDComponent, ByRef _block As Byte) As Boolean
            Dim result As Boolean = False
            Dim Retrys As Integer = 0

Retry:
            Dim ErrorCode As Integer = 0

            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return result                                           'Return Result to the Caller and Exit Function
            End If

            Try
                _ncd.SetTcpWritePace(2)
                _ncd.WriteBytes(0, 1, _block)
                _ncd.Flush()
                'Threading.Thread.Sleep(50)
                Dim Checksum As Integer = 0                                    'Define Checksum
                For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                    EEPROM(DataByte + (_block * 16)) = _ncd.ReadByte()      'One Byte at a Time
                    'Debug.Print(EEPROM(DataByte + (_block * 16)).ToString)
                    Checksum += EEPROM(DataByte + (_block * 16))            'Include Each Byte in the Checkum Value
                    'Threading.Thread.Sleep(30)
                Next DataByte
                Checksum = Checksum And 255

                Dim ReturnValue As Byte = _ncd.ReadByte()                   'Wait for the Controller to Respond with Checksum Value

                If ReturnValue = Checksum Then                              'If Checksum Matches Returned Value from the controller
                    Debug.Print("CORRECT" + _block.ToString)
                    result = True 'This Function was successful and the Result is True
                    ErrorCode = 0
                Else
                    Debug.Print("ERROR: CHECKSUM")
                    ErrorCode = 1
                End If
            Catch
                Debug.Print("Communication Error.")
                ErrorCode = 2
            End Try

            If ErrorCode <> 0 Then
                Debug.Print("RETRY ERROR")
                Retrys = Retrys + 1
                If Retrys < 10 Then
                    GoTo Retry
                End If
            End If

            Return result                                               'Return Result to Caller and Exit Function
        End Function


        ''' <summary>
        ''' Read a block, return null if fail
        ''' </summary>
        ''' <param name="_ncd"></param>
        ''' <param name="_block"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function ReadBlock(ByRef _ncd As NCD.NCDComponent, ByRef _block As Byte) As Byte()
            Dim data(15) As Byte

            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return Nothing                                            'Return Result to the Caller and Exit Function
            End If

            Try
                'DELA()
                '_ncd.WriteByte(0)                                           'Send Header Byte
                'DELA()
                '_ncd.WriteByte(1)                                           'Send Retrieve Command Byte
                'DELA()
                '_ncd.WriteByte(_block)                                      'Send Block
                '_ncd.WriteBytes(New Byte() {0, 1, _block})
                NCDLib.WriteBytes(_ncd, 2, 0, 1, _block)
                _ncd.SetTcpWritePace(2)
                _ncd.Flush()
                _ncd.SetTcpWritePace(0)
                DELA()
                Dim Checksum As Integer = 0                                    'Define Checksum
                For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                    data(DataByte) = _ncd.ReadByte()      'One Byte at a Time
                    'Debug.Print(EEPROM(DataByte + (_block * 16)).ToString)
                    Checksum += data(DataByte)            'Include Each Byte in the Checkum Value
                Next DataByte
                Checksum = Checksum And 255

                Dim ReturnValue As Byte = _ncd.ReadByte()                   'Wait for the Controller to Respond with Checksum Value

                If ReturnValue = Checksum Then                              'If Checksum Matches Returned Value from the controller
                    Debug.Print("CORRECT" + _block.ToString)
                Else
                    Debug.Print("ERROR: CHECKSUM")
                    data = Nothing
                End If
            Catch
                Debug.Print("Communication Error.")
                data = Nothing
            End Try
            Return data
        End Function


        ''' <summary>
        ''' Write a block to chip
        ''' </summary>
        ''' <param name="_ncd"></param>
        ''' <param name="_blockId"></param>
        ''' <param name="blockData"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function WriteBlock(ByRef _ncd As NCD.NCDComponent, ByVal _blockId As Integer, ByVal blockData As Byte()) As Boolean
            Dim result As Boolean = False
            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return result                                           'Return Result to the Caller and Exit Function
            End If

            '_ncd.SerialPort.DiscardInBuffer()
            'DELA()
            '_ncd.WriteByte(0)                                           'Send Header Byte
            'DELA()
            '_ncd.WriteByte(2)                                           'Send Store Command
            'DELA()
            '_ncd.WriteByte(_blockId)                                      'Send Block
            'DELA()

            _ncd.Purge()
            '_ncd.WriteBytes(0, 2, _blockId)
            NCDLib.WriteBytes(_ncd, 2, 0, 2, _blockId)
            _ncd.SetTcpWritePace(2)
            _ncd.Flush()
            If (_ncd.UsingComPort) Then
                Dim Checksum As Integer = 0                                   'Define Checksum
                For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                    _ncd.WriteByte(blockData(DataByte))        'One Byte at a Time
                    DELA()
                    Checksum += blockData(DataByte) 'Include Each Byte in the Checkum Value
                    'Debug.Print("Storing 2:" + EEPROM(DataByte + (_block * 16)).ToString)
                Next DataByte
                Checksum = Checksum And 255
                _ncd.WriteByte(Checksum)                                    'Send the Checksum Value to the Controller
            Else
                Dim Checksum As Integer = 0                                   'Define Checksum
                _ncd.WriteBytes(blockData)        'One Byte at a Time
                For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                    Checksum += blockData(DataByte) 'Include Each Byte in the Checkum Value
                    'Debug.Print("Storing 2:" + EEPROM(DataByte + (_block * 16)).ToString)
                Next DataByte
                Checksum = Checksum And 255
                _ncd.WriteByte(Checksum)                                    'Send the Checksum Value to the Controller

            End If


            Dim ReturnValue As Integer = _ncd.ReadByte()                   'Wait for the Controller to Respond with 85 Confirmation Byte
            If ReturnValue = 85 Then                                    'If 85 is Returned from the controller
                result = True                                           'This Function was successful and the Result is True
            Else
                result = False
            End If

            Return result                                               'Return Result to Caller and Exit Function

        End Function

        ''' <summary>
        ''' This function is used to Get EEPROM Data from NCD CPU
        ''' </summary>
        ''' <returns>Assume This Function Fails Unless Otherwise Notified by Result</returns>
        ''' <remarks></remarks>
        Public Shared Function From_EEPROM_Chip(ByRef _ncd As NCD.NCDComponent, ByVal _blockNo As UShort) As Byte()
            Dim result As Boolean = False
            Dim Retrys As Integer = 0
            Dim _data(15) As Byte

Retry:
            Dim ErrorCode As Integer = 0

            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return Nothing                                           'Return Result to the Caller and Exit Function
            End If

            Try
                'DELA()
                '_ncd.WriteByte(0)                                           'Send Header Byte
                'DELA()
                '_ncd.WriteByte(3)                                           'Send Retrieve Command Byte
                'DELA()
                '_ncd.WriteByte(NCDLib.Math.GetLSB(_blockNo))                                      'Send Block
                'DELA()
                '_ncd.WriteByte(NCDLib.Math.GetMSB(_blockNo))                                      'Send Block
                'DELA()

                '_ncd.WriteBytes(New Byte() {0, 3, NCDLib.Math.GetLSB(_blockNo), NCDLib.Math.GetMSB(_blockNo)})
                NCDLib.WriteBytes(_ncd, 2, 0, 3, NCDLib.Math.GetLSB(_blockNo), NCDLib.Math.GetMSB(_blockNo))
                _ncd.SetTcpWritePace(2)
                _ncd.Flush()
                Dim Checksum As Integer = 0                                    'Define Checksum
                For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                    _data(DataByte) = _ncd.ReadByte()      'One Byte at a Time
                    'Debug.Print(EEPROM(DataByte + (_block * 16)).ToString)
                    Checksum += _data(DataByte)            'Include Each Byte in the Checkum Value
                Next DataByte
                Checksum = Checksum And 255

                Dim ReturnValue As Byte = _ncd.ReadByte()                   'Wait for the Controller to Respond with Checksum Value

                If ReturnValue = Checksum Then                              'If Checksum Matches Returned Value from the controller
                    Debug.Print("CORRECT")
                    result = True 'This Function was successful and the Result is True
                    ErrorCode = 0
                Else
                    Debug.Print("ERROR: CHECKSUM")
                    _data = Nothing
                    ErrorCode = 1
                End If
            Catch
                Debug.Print("Communication Error.")
                ErrorCode = 2
            End Try

            If ErrorCode <> 0 Then
                Debug.Print("RETRY ERROR")
                Retrys = Retrys + 1
                If Retrys < 10 Then
                    GoTo Retry
                End If
            End If

            Return _data                                               'Return Result to Caller and Exit Function
        End Function

        ''' <summary>
        ''' This function is used to Get EEPROM Data from NCD CPU
        ''' </summary>
        ''' <returns>Assume This Function Fails Unless Otherwise Notified by Result</returns>
        ''' <remarks></remarks>
        Public Shared Function From_EEPROM_ChipFast(ByRef _ncd As NCD.NCDComponent, ByVal _blockNo As UShort) As Byte()
            Dim result As Boolean = False
            Dim Retrys As Integer = 0
            Dim _data(15) As Byte

Retry:
            Dim ErrorCode As Integer = 0

            If Not _ncd.IsOpen Then                                     'Check to Make Sure Port is Open
                Debug.Print("Port is not opened")                       'Debug if Port is Closed
                Return Nothing                                           'Return Result to the Caller and Exit Function
            End If

            Try
                _ncd.WriteBytes(0, 3, NCDLib.Math.GetLSB(_blockNo), NCDLib.Math.GetMSB(_blockNo))
                _ncd.SetTcpWritePace(2)
                _ncd.Flush()
                Dim Checksum As Integer = 0                                    'Define Checksum
                For DataByte As Integer = 0 To 15                           'Send EEPROM Data to Controller
                    _data(DataByte) = _ncd.ReadByte()      'One Byte at a Time
                    'Debug.Print(EEPROM(DataByte + (_block * 16)).ToString)
                    Checksum += _data(DataByte)            'Include Each Byte in the Checkum Value
                Next DataByte
                Checksum = Checksum And 255

                Dim ReturnValue As Byte = _ncd.ReadByte()                   'Wait for the Controller to Respond with Checksum Value

                If ReturnValue = Checksum Then                              'If Checksum Matches Returned Value from the controller
                    Debug.Print("CORRECT")
                    result = True 'This Function was successful and the Result is True
                    ErrorCode = 0
                Else
                    Debug.Print("ERROR: CHECKSUM")
                    _data = Nothing
                    ErrorCode = 1
                End If
            Catch
                Debug.Print("Communication Error.")
                ErrorCode = 2
            End Try

            If ErrorCode <> 0 Then
                Debug.Print("RETRY ERROR")
                Retrys = Retrys + 1
                If Retrys < 10 Then
                    GoTo Retry
                End If
            End If

            Return _data                                               'Return Result to Caller and Exit Function
        End Function



        Public Shared Sub DELA()
            System.Threading.Thread.Sleep(10)
        End Sub


    End Class


    Shared Sub WriteBytes(ByRef ncdObj As NCD.NCDComponent, ByVal sleep As Integer, ByVal ParamArray data As Byte())
        For i As Integer = 0 To data.Length - 1
            ncdObj.WriteByte(data(i))
            Threading.Thread.Sleep(sleep)
        Next
        'If (ncdObj.UsingComPort) Then
        '    For i As Integer = 0 To data.Length - 1
        '        ncdObj.WriteByte(data(i))
        '        Threading.Thread.Sleep(sleep)
        '    Next
        'Else
        '    ncdObj.WriteBytes(data)
        'End If

    End Sub
    ''' <summary>
    ''' string format for sending and receiving string, 0 for decimal as default and 1 for hex
    ''' </summary>
    ''' <remarks></remarks>
    Private Shared StringFormat As Integer = 0


    ''' <summary>
    ''' method to setup the showing format. 0 for deciaml, 1 for hex
    ''' </summary>
    ''' <param name="format"></param>
    ''' <remarks></remarks>
    Public Shared Sub SetStringFormat(ByVal format As Integer)
        StringFormat = format
    End Sub

    ''' <summary>
    ''' static varible for last send data, in decimal string
    ''' </summary>
    ''' <remarks></remarks>
    Private Shared LastSendString As String

    ''' <summary>
    ''' static varible for last received data, in decimal string
    ''' </summary>
    ''' <remarks></remarks>
    Private Shared LastRecString As String

    ''' <summary>
    ''' return the last send command in decimal format
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetLastTransmitString() As String
        Return LastSendString
    End Function

    ''' <summary>
    ''' return the last received data in decimal format
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetLastReceivingString() As String
        Return LastRecString
    End Function

    ''' <summary>
    ''' return the string with space in current format
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Shared Function GetShowString(ByVal num As Integer) As String
        If StringFormat = 0 Then
            Return num.ToString & " "
        End If
        Return String.Format("0x{0:X2} ", num)
    End Function

    Public Shared Function WriteBytesAPI(ByRef ncdObj As NCD.NCDComponent, ByVal UsingAPI As Boolean, ByVal ParamArray data() As Byte) As Boolean


        LastSendString = ""

        ncdObj.Purge()
        If (UsingAPI) Then
            ncdObj.SetTcpWritePace(0)
            ' write in api mode
            Dim ApiPackage As ArrayList = New ArrayList
            ApiPackage.Add(170)                 ' header
            LastSendString = LastSendString & GetShowString(170)
            ApiPackage.Add(data.Length)         ' length
            LastSendString = LastSendString & GetShowString(data.Length)
            ApiPackage.AddRange(data)           ' data
            Dim checksum As Integer = 170 + data.Length
            For i As Integer = 0 To data.Length - 1
                checksum = checksum + data(i)
                LastSendString = LastSendString & GetShowString(data(i))
            Next
            checksum = checksum Mod &H100
            ApiPackage.Add(checksum)            ' check sum
            LastSendString = LastSendString & GetShowString(checksum)
            Dim b(ApiPackage.Count - 1) As Byte


            Debug.Print("API START")
            For i = 0 To ApiPackage.Count - 1
                b(i) = ApiPackage(i)
                Debug.Print(b(i).ToString)
            Next
            Debug.Print("API STOP")

            ncdObj.WriteBytes(b)
            ' Dim j = ncdObj.ReadByte()
            'For Each it In ApiPackage
            '    ncdObj.WriteByte(it)
            'Next
            ncdObj.Flush()
        Else
            ncdObj.WriteBytes(data)
            ncdObj.Flush()
            For Each d As Integer In data
                LastSendString = LastSendString & GetShowString(d)
            Next
        End If

        'If (NCDComponent1.UsingComPort) Then
        '    For i As Integer = 0 To data.Length - 1
        '        NCDComponent1.WriteByte(data(i))
        '        ' Threading.Thread.Sleep(sleep)
        '    Next
        'Else
        '    NCDComponent1.WriteBytes(data)
        'End If
        Return True
    End Function

    ' return data back from module
    Public Shared Function ReadBytesAPI(ByRef ncdObj As NCD.NCDComponent, ByVal UsingAPI As Boolean, ByVal bytesCount As Integer) As Byte()
        'Debug.Print("START READ BYES")
        LastRecString = ""
        ncdObj.Sleep(200) ' to all load/save routing work, some times it can't get data back
        Dim rdata As ArrayList = New ArrayList
        If (UsingAPI) Then
            Dim ack As Integer = ncdObj.ReadByte()
            If (ack <> 170) Then
                ncdObj.Purge()
                Return Nothing
            End If
            LastRecString += GetShowString(170)
            Dim length As Integer
            length = ncdObj.ReadByte()
            If (length <> bytesCount) Then
                ncdObj.Purge()
                Return Nothing
            End If
            LastRecString += GetShowString(length)
            Dim checkSumC As Integer = 170 + length
            For m As Integer = 0 To bytesCount - 1
                Dim d As Integer = ncdObj.ReadByte()
                If (d = -1) Then            ' time out
                    Return Nothing
                End If
                rdata.Add(d)
                checkSumC = checkSumC + d
                LastRecString += GetShowString(d)
            Next
            Dim checksum As Integer
            checksum = ncdObj.ReadByte
            If (checksum = -1 Or (checksum <> (checkSumC Mod &H100))) Then
                ncdObj.Purge()
                Return Nothing
            End If
            LastRecString += GetShowString(checksum)
        Else
            For m As Integer = 0 To bytesCount - 1
                Dim d As Integer = ncdObj.ReadByte()
                If (d = -1) Then            ' time out
                    Return Nothing
                End If
                rdata.Add(d)
                LastRecString += GetShowString(d)
            Next
        End If
        'Report Data to User
        Dim dataRec() As Byte
        ReDim dataRec(bytesCount - 1)
        For i As Integer = 0 To bytesCount - 1
            dataRec(i) = rdata(i)
        Next
        'Debug.Print("END READ BYES")
        Return dataRec
    End Function
    Public Shared Function Read_Digi_900HP_APIFrame(ByRef ncdObj As NCD.NCDComponent)

        LastRecString = ""
        Dim rdata As ArrayList = New ArrayList
        Dim length_MS As Integer
        Dim length_LS As Integer
        Dim length As Integer  'Setup a Length of Packet Integer
        Dim BytesCount As Integer = 0 'XXX is the Unknown Number of Bytes
        Dim D As Integer

        '126 00 23 144 00 19 162 00 65 91 117 195 255 254 193 127 01 00 01 01 91 128 99 237 03 39 81 

        Dim ack As Integer = ncdObj.ReadByte()      'Look For a Header
        If (ack <> 126) Then                        'If an Invalid Head is Received Exit this Routine
            ncdObj.Purge()
            Return Nothing
        End If
        LastRecString += GetShowString(126)         'Add Data into the Last Received String

        length_MS = ncdObj.ReadByte()                  'Define the Length Value Based on the Packet
        LastRecString += GetShowString(length_MS)      'Add Data into the Last Received String

        length_LS = ncdObj.ReadByte()                  'Define the Length Value Based on the Packet
        LastRecString += GetShowString(length_LS)      'Add Data into the Last Received String

        length = (length_MS * 256) + length_LS


        Dim checkSumC As Integer = 0 '170 + length     'Setup a Checksum Value to Include the 170 Header and Length Values

        ' Dim d As Integer = ncdObj.ReadByte()    'Receive the Byte of Data from the User
        rdata.Add(D)                              'Add a NULL Byte into the D Array


        For m As Integer = 1 To length              'Count Through Each Byte in the Length Value
            Dim Rx As Integer = ncdObj.ReadByte()    'Receive the Byte of Data from the User
            'Debug.Print(d.ToString + " m:" + m.ToString)
            rdata.Add(Rx)                            'Add the Received Byte to the rData Array
            checkSumC = checkSumC + Rx               'Add the Received Data into the Checksum
            LastRecString += GetShowString(Rx)       'Add Data into the Last Received String
        Next

        Dim checksum As Integer                     'Setup a Checksum Value
        checksum = ncdObj.ReadByte                  'Read the Checksum from Device
        If (checksum = -1) Then 'Or (checksum <> (checkSumC Mod &H100))) Then      'Compare Received Checksum with Computed Checksum, If INVALID
            ncdObj.Purge()                          'Exit this Function and Return NO Data
            Return Nothing
        End If
        LastRecString += GetShowString(checksum)    'Add the Checksum Value into the Last Received String

ReturnData:

        'Report Data to User
        Dim dataRec() As Byte
        ReDim dataRec(length)

        'Debug.Print("Total Bytes Received:")
        dataRec(0) = length
        ' Debug.Print(dataRec(0))

        ' Debug.Print("Data Bytes:")
        For i As Integer = 1 To length
            dataRec(i) = rdata(i)
            'Debug.Print(dataRec(i))
        Next
        ' Debug.Print("Error???")
        ' Debug.Print(dataRec(0))

        Return dataRec

    End Function

    ' return data back from module
    Public Shared Function ReadUnknownNumberOfBytesAPI(ByRef ncdObj As NCD.NCDComponent, ByVal UsingAPI As Boolean) As Byte()
        LastRecString = ""
        Dim rdata As ArrayList = New ArrayList
        Dim length As Integer                       'Setup a Length of Packet Integer
        Dim BytesCount As Integer = 0 'XXX is the Unknown Number of Bytes

        Dim D As Integer

        If (UsingAPI) Then                              'Am I in API Mode????'YES
            Dim ack As Integer = ncdObj.ReadByte()      'Look For a Header
            If (ack <> 170) Then                        'If an Invalid Head is Received Exit this Routine
                ncdObj.Purge()
                Return Nothing
            End If
            LastRecString += GetShowString(170)         'Add Data into the Last Received String


            length = ncdObj.ReadByte()                  'Define the Length Value Based on the Packet
            LastRecString += GetShowString(length)      'Add Data into the Last Received String

            Dim checkSumC As Integer = 170 + length     'Setup a Checksum Value to Include the 170 Header and Length Values

            ' Dim d As Integer = ncdObj.ReadByte()    'Receive the Byte of Data from the User
            rdata.Add(D)                              'Add a NULL Byte into the D Array


            For m As Integer = 1 To length              'Count Through Each Byte in the Length Value
                Dim Rx As Integer = ncdObj.ReadByte()    'Receive the Byte of Data from the User
                'Debug.Print(d.ToString + " m:" + m.ToString)
                rdata.Add(Rx)                            'Add the Received Byte to the rData Array
                checkSumC = checkSumC + Rx               'Add the Received Data into the Checksum
                LastRecString += GetShowString(Rx)       'Add Data into the Last Received String
            Next

            Dim checksum As Integer                     'Setup a Checksum Value
            checksum = ncdObj.ReadByte                  'Read the Checksum from Device
            If (checksum = -1 Or (checksum <> (checkSumC Mod &H100))) Then      'Compare Received Checksum with Computed Checksum, If INVALID
                ncdObj.Purge()                          'Exit this Function and Return NO Data
                Return Nothing
            End If
            LastRecString += GetShowString(checksum)    'Add the Checksum Value into the Last Received String

        Else
            For m As Integer = 0 To 255     'Read 256 Bytes MAX
                Dim Rx As Integer = ncdObj.ReadByte()
                If (Rx = -1) Then            ' time out
                    BytesCount = m + 1
                    GoTo ReturnData
                End If
                rdata.Add(Rx)
                LastRecString += GetShowString(Rx)
            Next
        End If

ReturnData:

        'Report Data to User
        Dim dataRec() As Byte
        ReDim dataRec(length)

        'Debug.Print("Total Bytes Received:")
        dataRec(0) = length
        ' Debug.Print(dataRec(0))

        ' Debug.Print("Data Bytes:")
        For i As Integer = 1 To length
            dataRec(i) = rdata(i)
            'Debug.Print(dataRec(i))
        Next
        ' Debug.Print("Error???")
        ' Debug.Print(dataRec(0))

        Return dataRec

    End Function

    ' return data back from module, used for command only have one byte come back
    Public Shared Function ReadByteAPI(ByRef ncdObj As NCD.NCDComponent, ByVal UsingAPI As Boolean) As Integer
        Dim r As Integer = -1
        Dim rData As Byte() = ReadBytesAPI(ncdObj, UsingAPI, 1)

        If (rData Is Nothing) Then
            Return -1
        End If
        r = rData(0)
        Return r
    End Function

    Public Shared Function StoreExtendedEEPROMonCPU(ByRef ncdObj As NCD.NCDComponent, Start As Integer, ParamArray Bytes() As Byte)
        Debug.Print("Writing Extended EEPROM DEBUG")
        'Store Menu Selection

        Dim MSB As Integer = (Start And 65280) / 256 '>> 8
        Dim LSB As Integer = (Start And 255)
        Dim DataBytes(Bytes.Length + 3) As Byte
        DataBytes(0) = 254
        DataBytes(1) = 56
        DataBytes(2) = MSB
        DataBytes(3) = LSB
        ' DataBytes(4) = Bytes.Length
        Array.Copy(Bytes, 0, DataBytes, 4, Bytes.Length)

        'NCDLib.WriteBytesAPI(NCDComponent1, True, 254, 56, MSB, LSB, Bytes, DataBytes)
        NCDLib.WriteBytesAPI(ncdObj, True, DataBytes)
        Dim rData2 As Byte() = NCDLib.ReadBytesAPI(ncdObj, True, 1)

        '99fdgsdfasdfa
        'afasdf()

        If (Not (rData2 Is Nothing)) Then
            Debug.Print(rData2.ToString)
            StoreExtendedEEPROMonCPU = rData2
        Else
            MsgBox("Firmware Update Required for Fusion Controller: Unable to store extended data (NCDLib.StoreExtendedEEPROMonCPU")
        End If


    End Function


    Public Shared Function ReadExtendedEEPROMonCPU(ByRef ncdObj As NCD.NCDComponent, Start As Integer, Length As Integer) As Byte()

        Dim MSB As Integer = (Start And 65280) / 256 '>> 8
        Dim LSB As Integer = (Start And 255)

        '  NCDLib.EEPROMIO.ReadBlock(NCDComponent1, 0)
        '254 55 1   0   16
        'Load Menu Settings from Controller
        NCDLib.WriteBytesAPI(ncdObj, True, 254, 55, MSB, LSB, Length)        'Force Communications using API (Regardless of User Settings)
        Dim rData As Byte() = NCDLib.ReadBytesAPI(ncdObj, True, Length)  'Force Communications using API (Regardless of User Settings)
        ' CMD_Data("Read 8-Bit 8-Channels at a Time:", "", False)
        'If (Not (rData Is Nothing)) Then
        Return rData
        ' End If


    End Function

    Public Class I2C
        Shared I2CError As String = ""

        Public Class Device
            Public Shared Function RealWorldDisplay(Raw As Long, Type As String, Resolution As Integer, Gain As Integer) As String
                Debug.Print(">>>>>>>>>>>>>>>>>>>>>TYPE:")
                Debug.Print(Type)

                Dim ResolutionMultiplier As Decimal
                ' Dim GainDivider As Decimal = 1

                ' If Gain = 0 Then GainDivider = 1 'x1 Gain
                ' If Gain = 1 Then GainDivider = 2 'x2 Gain
                ' If Gain = 2 Then GainDivider = 4 'x4 Gain
                ' If Gain = 3 Then GainDivider = 8 'x8 Gain

                If Type = "4-20mA" Then
                    If Resolution = 0 Then ResolutionMultiplier = (0.0107)    '12-Bit
                    If Resolution = 1 Then ResolutionMultiplier = (0.0027)    '14-Bit
                    If Resolution = 2 Then ResolutionMultiplier = (0.00068)   '16-Bit
                    Return (Raw * ResolutionMultiplier).ToString + " mA"
                End If
                If Type = "0-20mA" Then
                    If Resolution = 0 Then ResolutionMultiplier = (0.0107)   '12-Bit
                    If Resolution = 1 Then ResolutionMultiplier = (0.0027)   '14-Bit
                    If Resolution = 2 Then ResolutionMultiplier = (0.00068)  '16-Bit
                    Return (Raw * ResolutionMultiplier).ToString + " mA"
                End If
                If Type = "0-40mA" Then
                    If Resolution = 0 Then ResolutionMultiplier = (0.0216)   '12-Bit
                    If Resolution = 1 Then ResolutionMultiplier = (0.0054)   '14-Bit
                    If Resolution = 2 Then ResolutionMultiplier = (0.00134)  '16-Bit
                    Return (Raw * ResolutionMultiplier).ToString + " mA"
                End If
                If Type = "0-5V ADC" Then
                    If Resolution = 0 Then ResolutionMultiplier = (0.0049)   '12-Bit
                    If Resolution = 1 Then ResolutionMultiplier = (0.00122)  '14-Bit
                    If Resolution = 2 Then ResolutionMultiplier = (0.00031)   '16-Bit
                    Return (Raw * ResolutionMultiplier).ToString + " V"
                End If
                If Type = "0-10V ADC" Then
                    If Resolution = 0 Then ResolutionMultiplier = (0.0098)   '12-Bit
                    If Resolution = 1 Then ResolutionMultiplier = (0.00244)  '14-Bit
                    If Resolution = 2 Then ResolutionMultiplier = (0.00061)   '16-Bit
                    Return (Raw * ResolutionMultiplier).ToString + " V"
                End If
                If Type = "0-20V ADC" Then
                End If
                If Type = "0-24V ADC" Then
                End If

                Return ""
            End Function
        End Class

        Public Class Chip
            Public Class MCP3428
                Public Shared Sub SetChannelResolutionGain(ByRef ncdObj As NCD.NCDComponent, Port As Integer, Address As Integer, Channel As Integer, Resolution As Integer, Gain As Integer)

                    If Channel > 3 Then GoTo InvalidSettings
                    If Resolution > 2 Then GoTo InvalidSettings
                    If Gain > 3 Then GoTo InvalidSettings

                    Dim CRG As Integer
                    Dim BitChannel As Integer
                    Dim BitConversion As Integer = 16  'Conversion Mode =    Bit 4 = 1
                    Dim BitResolution As Integer
                    Dim BitGain As Integer

                    'Channel = 0 to 3                Bit 6-5
                    If Channel = 0 Then BitChannel = 0
                    If Channel = 1 Then BitChannel = 32
                    If Channel = 2 Then BitChannel = 64
                    If Channel = 3 Then BitChannel = 96

                    'Resolution = 0 to 2  Bit 3-2
                    If Resolution = 0 Then BitResolution = 0    '12-Bit Resolution
                    If Resolution = 1 Then BitResolution = 4    '14-Bit Resolution
                    If Resolution = 2 Then BitResolution = 8    '16-Bit Resolution

                    'Gain = 0 to 3        Bit 1-0
                    If Gain = 0 Then BitGain = 0    'x1 Gain
                    If Gain = 1 Then BitGain = 1    'x2 Gain
                    If Gain = 2 Then BitGain = 2    'x4 Gain
                    If Gain = 3 Then BitGain = 3    'x8 Gain

                    CRG = BitChannel + BitConversion + BitResolution + BitGain

                    'Debug.Print("-----------CRG----------- " + Channel.ToString)
                    'Debug.Print(NCDLib.Math.DecToBinaryStringStandard(CRG))

                    NCDLib.I2C.Write(ncdObj, Port, Address, CRG)

                    Exit Sub

InvalidSettings:
                    Debug.Print("---------------------------------------------------")
                    Debug.Print("ERROR: MCP3428 Invalid Parameters")
                    If Channel > 3 Then Debug.Print("ERROR: MCP3428 Invalid Channel")
                    If Resolution > 2 Then Debug.Print("ERROR: MCP3428 Invalid Resolution")
                    If Gain > 3 Then Debug.Print("ERROR: MCP3428 Invalid Gain")
                    Debug.Print("---------------------------------------------------")
                End Sub

                Public Shared Sub Setup_Channel(ByRef ncdObj As NCD.NCDComponent, Port As Integer, Address As Integer, Channel As Integer, Resolution As Integer, Gain As Integer)

                    NCDLib.I2C.Chip.MCP3428.SetChannelResolutionGain(ncdObj, Port, Address, Channel, Resolution, Gain)

                End Sub

                Public Shared Function Read_Channel(ByRef ncdObj As NCD.NCDComponent, Port As Integer, Address As Integer, Channel As Integer, Resolution As Integer, Gain As Integer)


                    'NCDLib.I2C.Chip.MCP3428.SetChannelResolutionGain(ncdObj, Port, Address, Channel, Resolution, Gain)

                    'Wait for I2C Chip to Finish ADC Conversion
                    If Resolution = 2 Then
                        ncdObj.Sleep(66) ' Delay 1/15th Second
                    End If

                    Dim result() As Byte = NCDLib.I2C.Read(ncdObj, Port, Address, 2)

                    If Not (result Is Nothing) Then
                        If (result.Length = 3) Then
                            Dim d As Long

                            'Debug.Print("---------Resolution---" + Resolution.ToString)

                            If Resolution = 0 Then
                                'Debug.Print("12-Bit Resolution")
                                d = (result(1) And &HF) * 256 + result(2) '(result(1) * 256 + result(2))
                            Else
                                ' Debug.Print("High Resolution")
                                d = (result(1) * 256) + result(2) '(result(1) * 256 + result(2))
                            End If
                            Debug.Print(d.ToString)
                            Read_Channel = d
                            Return Read_Channel
                        End If
                    End If
                    Return -1

                End Function
            End Class
        End Class


        Public Shared Function Write(ByRef ncdObj As NCD.NCDComponent, I2C_Port As Integer, Address As Integer, ByVal ParamArray TXDAT As Byte()) As Byte()
            '    _ERROR.Visible = False
            Dim PortSetting As Integer = I2C_Port + 50
            Dim AddressSetting As Integer = Address * 2
            Dim TransmitCount As Integer = TXDAT.Length
            Dim ReceiveCount As Integer = 0 'RXBytes
            Dim aI(TransmitCount + 4) As Byte

            I2CError = ""
            aI(0) = 188                  'Byte 0
            aI(1) = PortSetting          'Byte 1
            aI(2) = TransmitCount + 1    'Byte 2
            aI(3) = AddressSetting       'Byte 3
            aI(TransmitCount + 4) = ReceiveCount    'Last Byte
            For i1 As Integer = 0 To TransmitCount - 1
                aI(i1 + 4) = TXDAT(i1) 'Int(txArray(i1).Text)
            Next
            NCDLib.WriteBytesAPI(ncdObj, True, aI)
            'Debug.Print("Command:")
            'For Each a In aI
            '    Debug.Print(a)
            'Next
            'Debug.Print("--------------END Command")
            '      _ERROR.Visible = False
            Dim rData As Byte() = NCDLib.ReadUnknownNumberOfBytesAPI(ncdObj, True)
            If (Not (rData Is Nothing)) Then
                If rData(0) = 4 Then    'If we received 4 bytes of data
                    If rData(1) = 188 Then
                        If rData(4) = 67 Then
                            I2CError = ("I2C Write - Error Package:")
                            '                     _ERROR.Visible = True
                            If rData(2) = 90 Then
                                If rData(3) = (255 - 90) Then
                                    I2CError = ("ERROR: I2C Device Did Not Acknowledge.  Make Sure the Correct I2C Port and Address are Selected.  Make Sure SDA and SCL lines are not reversed.")
                                End If
                            End If
                            If rData(2) = 91 Then
                                If rData(3) = (255 - 91) Then
                                    I2CError = ("ERROR: Device took Tool Long to Respond.")
                                End If
                            End If
                            If rData(2) = 92 Then
                                If rData(3) = (255 - 92) Then
                                    I2CError = ("ERROR: Count Not Set the Address of the Device.")
                                End If
                            End If
                        End If
                    End If
                End If
                Return rData
            Else
                I2CError = ("NO DATA RECEIVED")
            End If
        End Function


        Public Shared Function Read(ByRef ncdObj As NCD.NCDComponent, I2C_Port As Integer, Address As Integer, RXBytes As Integer) As Byte()
            '_ERROR.Visible = False
            Dim PortSetting As Integer = I2C_Port + 50
            Dim AddressSetting As Integer = (Address * 2) + 1
            Dim TransmitCount As Integer = 0 'TXDAT.Length
            Dim ReceiveCount As Integer = RXBytes
            Dim aI(TransmitCount + 4) As Byte

            I2CError = ""
            aI(0) = 188                  'Byte 0
            aI(1) = PortSetting          'Byte 1
            aI(2) = TransmitCount + 1    'Byte 2
            aI(3) = AddressSetting       'Byte 3
            aI(TransmitCount + 4) = ReceiveCount    'Last Byte
            'For i1 As Integer = 0 To TransmitCount - 1
            ' aI(i1 + 4) = TXDAT(i1) 'Int(txArray(i1).Text)
            ' Next
            NCDLib.WriteBytesAPI(ncdObj, True, aI)
            'Debug.Print("Command:")
            'For Each a In aI
            '    Debug.Print(a)
            'Next
            'Debug.Print("--------------END Command")

            '------------------------------------------------------------------------------------------
            '_ERROR.Visible = False
            Dim rData As Byte() = NCDLib.ReadUnknownNumberOfBytesAPI(ncdObj, True)
            If (Not (rData Is Nothing)) Then
                If rData(0) = 4 Then    'If we received 4 bytes of data
                    If rData(1) = 188 Then
                        If rData(4) = 67 Then
                            I2CError = "I2C Read - Error Package:"

                            '_ERROR.Visible = True
                            If rData(2) = 90 Then
                                If rData(3) = (255 - 90) Then
                                    I2CError = ("ERROR: I2C Device Did Not Acknowledge.  Make Sure the Correct I2C Port and Address are Selected.  Make Sure SDA and SCL lines are not reversed.")
                                End If
                            End If
                            If rData(2) = 91 Then
                                If rData(3) = (255 - 91) Then
                                    I2CError = ("ERROR: Device took Tool Long to Respond.")
                                End If
                            End If
                            If rData(2) = 92 Then
                                If rData(3) = (255 - 92) Then
                                    I2CError = ("ERROR: Count Not Set the Address of the Device.")
                                End If
                            End If
                        End If
                    End If
                End If
                Return rData
            Else
                I2CError = ("NO DATA RECEIVED")
            End If
        End Function
    End Class

    End Class