Results 1 to 20 of 20

Thread: VB newbie desperately needs programming help!!

  1. #1
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    VB newbie desperately needs programming help!!

    I am using a windows form application to interface with an arduino to turn on & off items mostly in my large garage - 2 light banks, furnace, compressor, 3 garage doors,... 12 buttons in all. I am starting the code for just 1 button to simplify things, then will expand to 12. I will put the code I came up with, along with an article on comp control where I got the idea, & pics of my hardware so far. I really do want to learn to do this, so I'm not asking for the code to be written, just let me know my mistakes & point me in the right direction! Any & all input will be greatly appreciated, I'm really excited about completion!

    Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    On Error Resume Next
    Dim SerialPort1 As Integer
    Dim Write As Object
    Dim onstate, outstring As Integer
    onstate = 0
    If Button1.Text = "Pin 6 on" Then
    Button1.Text = "Pin 6 off"
    onstate = 1
    outstring = "!"
    End If
    If Button1.Text = "Pin 6 off" And onstate = 0 Then
    Button1.Text = "Pin 6 on"
    outstring = "$"
    End If

    'SerialPort1(Write(outstring))

    End Sub

    End Class

    in the hardware pic, the small enclosure is a 13A 5V power supply so I can run inexpensive low voltage lines to electrical boxes with 5V relays doing the work. the middle enclosure is where the low voltage lines will hook up. there is an outlet on top, because they will be situated next to the furnace which currently plugs into a wall outlet - it will plug there. the third enclosure houses the Arduino, 9V supply for it, & relay banks that the arduino controls via VB, those relay leads go to the middle box & out to the remote relays. there is a 70' amplified USB cable running from my office to the Arduino in the garage unit. It's all very workable, I'm just new at VB & unsure of what i'm doing, but the attached article does a good job of explaining the interface. Please help!! I know there are many with a great amount of expertise out there... all I ask is that you poin me in the right direction!
    . thank you for your time & patience, I know this is a long read!!

  2. #2
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: VB newbie desperately needs programming help!!

    Which version of VB/VS are you using. There are VB6 statements in your code. If that's right then this should be asked in the appropriate forum section.

  3. #3
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    Re: VB newbie desperately needs programming help!!

    I am using Visual Basic Express 2110. I told you I was a newbie, but had no idea I was that out of whack lol! can you give me some pointers, please? I'm currently taking VB courses every spare moment, & the more I learn, it seems the more I'm lost! I have great respect for those of you who do this every day - gotta be bright obviously! It does seem to me that what I'm after is a relatively (for one such as yourself) easy program - I hope... any assistance would be appreciated more than you could know! I've got a lot of time & cash into it already, and am anxious to see it work!!! thank you for your time... !

  4. #4
    Loquacious User Shaggy Hiker's Avatar
    Join Date
    Aug 02
    Location
    Idaho
    Posts
    20,390

    Re: VB newbie desperately needs programming help!!

    I think you are working on an excellent project, and I encourage you to stick with it. I work on some robot code as a hobby, and am vaguely familiar with the arduino (basically, I know that it exists and that's all). That may not make any difference. As far as I am concerned, the first step should be to get some communication going, as the rest is all gravy. If you can demonstrate that you are able to read and write to the device, you have crossed the biggest technical hurdle, and everything else is the fun (though occasionally frustrating) part of putting your imagination into practice. So, first off, can you say whether or not you have had any communication with the device through code?

    As for the code, you used On Error, which is archaic VB6 error handling. The proper approach in .NET (which is what you are using) is to use a Try....Catch block. You also don't want to be doing any Resume Next, but if you switch to Try...Catch, you won't The equivalent using Try...Catch would be to have an empty Catch block, but that would just be shooting yourself in the foot. If an exception occurs, you want to know about it, even if you can't do anything about it. Therefore, if nothing else, put a messagebox in the Catch block and show the exception message.

    The next thing I note is that you have a variable named SerialPort1 which is bizarrely declared as type Integer. I suspect that you really WANT that to be a serial port. There is a type in .NET for that. Better yet, there are dozens of threads on serial port communication on this forum. Unfortunately, the software has just been changed over, and I can't say whether or not the Search feature is working correctly, yet. The last time I tried it, it was not, but that was more than a week ago. If it isn't working yet, you can be certain that it will be soon.

    One other suggestion would be to look into RadioButtons rather than buttons. I would expect that you will end up with a few of them, and it all comes down to what feels best to you. The RadioButton does what you want as far as giving some feedback, whereas you have to change the text and backcolor of the button to get it to do the same thing. Therefore, the RadioButton may suit you, but I should also note that I often use buttons the way you are using that one (though I like to change the color, too), so it is a matter of personal opinion.
    My usual boring signature: Nothing

  5. #5
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    Re: VB newbie desperately needs programming help!!

    Shaggy Hiker; thank you so much for your response! I'm not quite sure what you mean by success,I am proficient at programming arduino's & have used them for many things. As for the VB code, no success yet communicating with the arduino.I will switch to try catch(& am spending every spare moment at VB courses). I will research the types for serial port - I'm beginning to believe that's where my problem is! I will definitely check the threads on this forum relating to it.(I declared it as integer not knowing any better lol) lastly, I know little about the RadioButtons , but will do some deep research into that as well. Google has become one of my best friends lately... the on error code bit was from the article I came across that I got this idea from; I'm assuming that article is a bit out of date. I imagine I may need further advice, but this really seems like a wonderful forum with competent, knowledgeable people that are more than willing to help! Thank you! I will post an updated code to examine, & let you know when I am able to communicate.

  6. #6
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    Re: VB newbie desperately needs programming help!!

    OK, i think I'm close... the problem I'm having is sending serial outstring to the arduino. I believe it would all work if I could resolve this issue! I have researched it exhaustibly ( to the best of MY limited ability!) I came up with something the author said would work, but it's catching an exception for Rs232(). revised code is below...


    Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Try

    Catch ex As Exception

    End Try

    Dim onstate, outstring As Integer
    onstate = 0
    If Button1.Text = "Pin 6 on" Then
    Button1.Text = "Pin 6 off"
    onstate = 1
    outstring = "!"
    End If
    If Button1.Text = "Pin 6 off" And onstate = 0 Then
    Button1.Text = "Pin 6 on"
    outstring = "$"
    End If

    Dim moRS232 As New Rs232()
    With moRS232
    .Port = 3 '// Uses COM3
    .BaudRate = 300 ' // 300 baud rate
    .DataBit = 8 '// 8 data bits
    .StopBit = Rs232.DataStopBit.StopBit_1 '// 1 Stop bit
    .Parity = Rs232.DataParity.Parity_None '// No Parity
    .Timeout = 500 '// 500 ms of timeout admitted to get all required bytes
    End With
    '// Initializes and Open
    moRS232.Open()
    Try

    Catch ex As Exception

    End Try

    End Sub
    Private Function Rs232() As Object
    Throw New NotImplementedException
    End Function

    End Class

    I did try the RadioButton, saw no real difference, but will likely go back to it because it just seems simpler. I REALLY wanted to figure this out on my own & I hate to ask, but could someone PLEASE tell me how to send serial out? I'm at my wits end here & I want it to work sooo bad! All is not lost, I have learned a GREAT deal... I'm sure I can add the rest of the buttons & get this project off the ground. & I have no intention of stopping the VB.NET courses, I intend to do many more projects! You all have been great on this forum, one of the very best I've had the pleasure of being a part!! Thank you all for your time & expertise.. my expertise is electrical engineering, & I had no idea what programmers went through, I certainly have a new-found appreciation for ya all!

  7. #7
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: VB newbie desperately needs programming help!!

    Well first we need to tidy up the code a bit. The Try/Catch works like this ...
    vb.net Code:
    1. Try
    2.  
    3. 'all the code that might throw an exception
    4.  
    5. Catch ex As Exception
    6.  
    7. 'code to determine what happens if an exception is thrown
    8. 'ex gives the specific Exception of you want to handle different exceptions differently
    9.  
    10. End Try

    Dim moRS232 As New Rs232()
    This doesn't make any sense as RS232() is a custom function not a type.

    vb.net Code:
    1. Dim moRS232 As SerialPort = New SerialPort
    2. With moRS232
    3. '.Port = 3 '// Uses COM3
    4. .PortName = "COM3"

    And I've no idea what ....

    Private Function Rs232() As Object
    Throw New NotImplementedException
    End Function
    ... is supposed to do but it doesn't. It's not a Function to start with (no return value) and does nothing but throw an exception and effectively kill the program.

  8. #8
    Loquacious User Shaggy Hiker's Avatar
    Join Date
    Aug 02
    Location
    Idaho
    Posts
    20,390

    Re: VB newbie desperately needs programming help!!

    I would guess that Rs232() is a function that is supposed to set up and return a SerialPort object. It doesn't do that, as written, and even the prototype is pretty poor, since it returns type Object, but that would be my guess as to what it was supposed to do. I don't do that.

    Here is a class that I think I use to communicate with a different type of brainboard (one I don't use anymore) over a serial port. Much of the class will not be useable, but I left it all in so that you can see how I was writing out certain things and reading in certain things.

    Code:
    Public Class FastSerialManager
        Implements IDisposable
    
        Private WithEvents mSerial As System.IO.Ports.SerialPort
        Private lastData(4096) As Byte
        Private mLastPointer As Integer
        Private mHasData As Boolean
        Private mLocalData(4096) As Byte
        Private mLocalPointer As Integer
    
        Private mDataList As List(Of String)
        Private mResidual As Byte
    
        Private disposedValue As Boolean = False        ' To detect redundant calls
        Private resetFlag As Boolean
    
        Private mFailCount As Integer
    
        Private mAlertCount As Integer
        Private mAlertHolder As Integer
        Private mDoneCount As Integer
    
    
        'Private mCount As Integer
    
        'The timer
        Private myTimer As System.Windows.Forms.Timer
        Private timeCounter As Boolean
        Private myContext As System.Threading.SynchronizationContext
    
    
    #Region "Constructors and Destructors"
    
        Public Sub New()
            mSerial = New System.IO.Ports.SerialPort
            mSerial.BaudRate = 9600
            mSerial.DataBits = 8
            mSerial.StopBits = IO.Ports.StopBits.One
            mSerial.Parity = IO.Ports.Parity.None
            mSerial.PortName = "COM4"
    
            mSerial.WriteTimeout = 500
            mSerial.ReadTimeout = 3000
            mSerial.ReadBufferSize = 4096
            mSerial.ReceivedBytesThreshold = 1
    
            myContext = System.Threading.SynchronizationContext.Current
    
            'Need to do a few things to look for the com ports and decide which one to use.
            mSerial.Open()
            resetFlag = False
    
            'Create the timer.
            myTimer = New System.Windows.Forms.Timer
            mLocalPointer = -1
    
            'Need to tell it where to send time tick messages.
            AddHandler myTimer.Tick, AddressOf TimerEventProcessor
            myTimer.Enabled = False
            myTimer.Interval = 2000
        End Sub
    
        Public Sub New(ByVal nm As String)
            mSerial = New System.IO.Ports.SerialPort
            mSerial.BaudRate = 9600
            mSerial.DataBits = 8
            mSerial.StopBits = IO.Ports.StopBits.One
            mSerial.Parity = IO.Ports.Parity.None
            mSerial.PortName = nm
    
            mSerial.WriteTimeout = 500
            mSerial.ReadTimeout = 500
            mSerial.ReceivedBytesThreshold = 1
            myContext = System.Threading.SynchronizationContext.Current
    
            'Need to do a few things to look for the com ports and decide which one to use.
            mSerial.Open()
    
            'Create the timer.
            myTimer = New System.Windows.Forms.Timer
            mLocalPointer = -1
    
            'Need to tell it where to send time tick messages.
            AddHandler myTimer.Tick, AddressOf TimerEventProcessor
            myTimer.Enabled = False
            myTimer.Interval = 2000
        End Sub
    
        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                mSerial.Dispose()
            End If
            Me.disposedValue = True
            myTimer.Dispose()
        End Sub
    
    #Region " IDisposable Support "
        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
    #End Region
    
    #End Region
    
    #Region "Properties and Events"
    
        Public ReadOnly Property NewData() As Boolean
            Get
                Return mHasData
            End Get
        End Property
    
        Public Event DataReady()
    
        Public Event Alert(ByVal alertVal As Integer)
    
        Public Event Stopped()
    
        Public Event Failed()
    
    
    #End Region
    
    #Region "Public Functions"
    
        Public Sub ReSet()
            mSerial.Dispose()
            mFailCount = 0
            mSerial = New System.IO.Ports.SerialPort
            mSerial.BaudRate = 9600
            mSerial.DataBits = 8
            mSerial.StopBits = IO.Ports.StopBits.One
            mSerial.Parity = IO.Ports.Parity.None
            mSerial.PortName = "COM5"
    
            mSerial.WriteTimeout = 500
            mSerial.ReadTimeout = 3000
            mSerial.ReadBufferSize = 4096
    
            'Need to do a few things to look for the com ports and decide which one to use.
            mSerial.Open()
        End Sub
    
        'Pass in a buffer, and it will be filled. The return is the number of bytes read.
        'The buffer should be sized to 4096.
        Public Function GetData(ByRef buffHolder() As Byte) As Integer
            buffHolder = CType(lastData.Clone(), Byte())
            Array.Clear(lastData, 0, 4096)
        End Function
    
        'This sub mostly is used for calling sound.
        Public Sub SendOutput(ByVal senNo As Byte, ByVal senVal As Byte)
            Dim buf(2) As Byte
    
            'Confirm that the escape char (92) is not included in the arguments.
            If senVal = 92 Then
                senVal += CByte(1)
            End If
            If senNo = 92 Then
                RaiseEvent Failed()
                Return
            End If
    
            buf(0) = 255
            buf(1) = senNo
            buf(2) = senVal
            mSerial.Write(buf, 0, 3)
        End Sub
    
        'This assumes that senNo is a number less than 256. No checking is
        'Done if that is not the case.
        Public Sub ReadSensor(ByVal senNo As Byte, ByVal senVal As Byte)
            Dim buf(2) As Byte
    
            'Confirm that the escape char (92) is not included in the arguments.
            If senVal = 92 Then
                senVal += CByte(1)
            End If
    
            If senNo = 92 Then
                'This should NEVER happen, so just fail it.
                RaiseEvent Failed()
                Return
            End If
    
            buf(0) = 255
            buf(1) = senNo
            buf(2) = senVal
    
            mLastPointer = 0
            mLocalPointer = -1
            mHasData = False
            Array.Clear(mLocalData, 0, 4096)
            Array.Clear(lastData, 0, 4096)
            mSerial.Write(buf, 0, 3)
            myTimer.Enabled = True
            timeCounter = True
        End Sub
    
        Public Sub ClearAlert()
            Dim buf(2) As Byte
    
            buf(0) = 255 'The flag
            buf(1) = 111 'Sensor 111 just clears the alert.
            buf(2) = 0 'This doesn't do anything.
    
            mSerial.Write(buf, 0, 3)
        End Sub
    
        Public Sub WriteMove(ByVal lWhl As Byte, ByVal rWhl As Byte, ByVal dur As Byte)
            Dim buf(2) As Byte
    
            'Check to see that 92 (the escape character) is not one of the values.
            If lWhl = 92 Then
                lWhl += CByte(1)
            End If
            If rWhl = 92 Then
                rWhl += CByte(1)
            End If
            If dur = 92 Then
                dur += CByte(1)
            End If
    
            buf(0) = 255
            buf(1) = 100
            buf(2) = lWhl
    
            mSerial.Write(buf, 0, 3)
    
            buf(0) = 255
            buf(1) = 101
            buf(2) = rWhl
    
            mSerial.Write(buf, 0, 3)
    
            buf(0) = 255
            buf(1) = 102
            buf(2) = dur
    
            mSerial.Write(buf, 0, 3)
    
        End Sub
    
        'A relic to setting addresses for the SRF08. Don't use it.
        Public Sub WriteAddress(ByVal no As Byte)
            Dim buf(2) As Byte
    
            buf(0) = 255
            buf(1) = 10
            buf(2) = no
            mSerial.Write(buf, 0, 3)
        End Sub
    
        Public Sub SendReset()
            resetFlag = True
            mSerial.Write("\0")
            mSerial.Write("W")
            resetFlag = False
        End Sub
    
    #End Region
    
    #Region "Private Functions"
    
        
        Private Sub TimerEventProcessor(ByVal myobject As Object, ByVal myEventArgs As EventArgs)
            If timeCounter Then
                SendReset()
                myTimer.Enabled = False
                RaiseEvent Failed()
                mFailCount += 1
                If mFailCount > 3 Then
                    ReSet()
                End If
            Else
                timeCounter = True 'Set false by data received.
            End If
        End Sub
    
        'This is the way data is read if the timer is not in use (no sensor read).
        Private Sub DataReceivedProcessor(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles mSerial.DataReceived
            Dim inByte As Byte
            Dim cnt As Integer
            Dim buff(4096) As Byte
            Dim x As Integer
            'This is a special case, not a sensor read.
            mFailCount = 0 'ANY bytes coming in means that something is happening.
            timeCounter = False
    
            'If the flag is set, bail out.
            If resetFlag Then
                Return
            End If
    
            cnt = mSerial.Read(buff, 0, 4096)
            For x = 0 To cnt - 1
                inByte = buff(x)
                mLocalPointer += 1
                mLocalData(mLocalPointer) = inByte
                If inByte = 128 Then
                    mAlertCount += 1
                ElseIf inByte = 255 Then
                    mDoneCount += 1
                    mAlertCount = 0
                    If mDoneCount = 3 Then
                        mDoneCount = 0
                        
                        'If there is something in the alert holder, then this
                        'is an alert. Only the alert holder byte matters, so the three 128 bytes
                        'will simply be ignored.
                        If mAlertHolder > 0 Then
                            myContext.Post(AddressOf EventRaiser, mAlertHolder) 'The stop alert.
                            mAlertHolder = 0 'Clear the holder.
                        Else
                            'Need to strip off those final three bytes.
                            mLocalPointer -= 3
                            'Check that this didn't do something truly bizarre.
                            If mLocalPointer < 0 Then
                                mLocalPointer = 0
                                'This should never happen.
                                Windows.Forms.MessageBox.Show("A too short message was found.", "Error")
                            End If
                            lastData = CType(mLocalData.Clone, Byte())
                            mLastPointer = mLocalPointer
                            mHasData = True
                            myTimer.Enabled = False
                            myContext.Post(AddressOf EventRaiser, 255)
                            mLocalPointer = -1
                            Array.Clear(mLocalData, 0, 4096)
                        End If
                    End If
                Else
                    If mAlertCount = 3 Then
                        mAlertCount = 0
                        mAlertHolder = CInt(inByte)
                        'clear these two.
                    End If
                    mAlertCount = 0
                    mDoneCount = 0
                End If
    
            Next
    
        End Sub
    
        Private Sub EventRaiser(ByVal typ As Object)
            Select Case CInt(typ)
                Case 255
                    RaiseEvent DataReady()
                Case 101
                    RaiseEvent Stopped()
                Case Else
                    RaiseEvent Alert(CInt(typ))
            End Select
        End Sub
    
    #End Region
    End Class
    My usual boring signature: Nothing

  9. #9
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    Re: VB newbie desperately needs programming help!!

    I studied both responses, & came up with this code:


    Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Try
    'All the code that might throw an exception
    Catch ex As Exception
    'code to determine what happens if an exception is thrown
    'ex gives the specific Exception of you want to handle different exceptions differently

    End Try
    Dim onstate, outstring
    onstate = 0
    If Button1.Text = "Pin 1 on" Then
    Button1.Text = "Pin 1 off"
    onstate = 1
    outstring = "!"
    End If
    If Button1.Text = "Pin 1 off" And onstate = 0 Then
    Button1.Text = "Pin 1 on"
    outstring = "$"
    End If
    End Sub

    Public Class FastSerialManager
    Implements IDisposable

    Private WithEvents mSerial As System.IO.Ports.SerialPort
    Private lastData(4096) As Byte
    Private mLastPointer As Integer
    Private mHasData As Boolean
    Private mLocalData(4096) As Byte
    Private mLocalPointer As Integer

    Private mDataList As List(Of String)
    Private mResidual As Byte

    Private disposedValue As Boolean = False ' To detect redundant calls
    Private resetFlag As Boolean

    Private mFailCount As Integer

    Private mAlertCount As Integer
    Private mAlertHolder As Integer
    Private mDoneCount As Integer


    'Private mCount As Integer

    'The timer
    Private myTimer As System.Windows.Forms.Timer
    Private timeCounter As Boolean
    Private myContext As System.Threading.SynchronizationContext


    #Region "Constructors and Destructors"

    Public Sub New()
    mSerial = New System.IO.Ports.SerialPort
    mSerial.BaudRate = 9600
    mSerial.DataBits = 8
    mSerial.StopBits = IO.Ports.StopBits.One
    mSerial.Parity = IO.Ports.Parity.None
    mSerial.PortName = "COM4"

    mSerial.WriteTimeout = 500
    mSerial.ReadTimeout = 3000
    mSerial.ReadBufferSize = 4096
    mSerial.ReceivedBytesThreshold = 1

    myContext = System.Threading.SynchronizationContext.Current

    'Need to do a few things to look for the com ports and decide which one to use.
    mSerial.Open()
    resetFlag = False

    'Create the timer.
    myTimer = New System.Windows.Forms.Timer
    mLocalPointer = -1

    'Need to tell it where to send time tick messages.
    AddHandler myTimer.Tick, AddressOf TimerEventProcessor
    myTimer.Enabled = False
    myTimer.Interval = 2000
    End Sub

    Public Sub New(ByVal nm As String)
    mSerial = New System.IO.Ports.SerialPort
    mSerial.BaudRate = 9600
    mSerial.DataBits = 8
    mSerial.StopBits = IO.Ports.StopBits.One
    mSerial.Parity = IO.Ports.Parity.None
    mSerial.PortName = nm

    mSerial.WriteTimeout = 500
    mSerial.ReadTimeout = 500
    mSerial.ReceivedBytesThreshold = 1
    myContext = System.Threading.SynchronizationContext.Current

    'Need to do a few things to look for the com ports and decide which one to use.
    mSerial.Open()

    'Create the timer.
    myTimer = New System.Windows.Forms.Timer
    mLocalPointer = -1

    'Need to tell it where to send time tick messages.
    AddHandler myTimer.Tick, AddressOf TimerEventProcessor
    myTimer.Enabled = False
    myTimer.Interval = 2000
    End Sub

    ' IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
    If Not Me.disposedValue Then
    mSerial.Dispose()
    End If
    Me.disposedValue = True
    myTimer.Dispose()
    End Sub

    #Region " IDisposable Support "
    ' This code added by Visual Basic to correctly implement the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
    ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
    Dispose(True)
    GC.SuppressFinalize(Me)
    End Sub
    #End Region

    #End Region

    #Region "Properties and Events"

    Public ReadOnly Property NewData() As Boolean
    Get
    Return mHasData
    End Get
    End Property

    Public Event DataReady()

    Public Event Alert(ByVal alertVal As Integer)

    Public Event Stopped()

    Public Event Failed()


    #End Region

    #Region "Public Functions"

    Public Sub ReSet()
    mSerial.Dispose()
    mFailCount = 0
    mSerial = New System.IO.Ports.SerialPort
    mSerial.BaudRate = 9600
    mSerial.DataBits = 8
    mSerial.StopBits = IO.Ports.StopBits.One
    mSerial.Parity = IO.Ports.Parity.None
    mSerial.PortName = "COM5"

    mSerial.WriteTimeout = 500
    mSerial.ReadTimeout = 3000
    mSerial.ReadBufferSize = 4096

    'Need to do a few things to look for the com ports and decide which one to use.
    mSerial.Open()
    End Sub

    'Pass in a buffer, and it will be filled. The return is the number of bytes read.
    'The buffer should be sized to 4096.
    Public Function GetData(ByRef buffHolder() As Byte) As Integer
    buffHolder = CType(lastData.Clone(), Byte())
    Array.Clear(lastData, 0, 4096)
    End Function

    'This sub mostly is used for calling sound.
    Public Sub SendOutput(ByVal senNo As Byte, ByVal senVal As Byte)
    Dim buf(2) As Byte

    'Confirm that the escape char (92) is not included in the arguments.
    If senVal = 92 Then
    senVal += CByte(1)
    End If
    If senNo = 92 Then
    RaiseEvent Failed()
    Return
    End If

    buf(0) = 255
    buf(1) = senNo
    buf(2) = senVal
    mSerial.Write(buf, 0, 3)
    End Sub

    'This assumes that senNo is a number less than 256. No checking is
    'Done if that is not the case.
    Public Sub ReadSensor(ByVal senNo As Byte, ByVal senVal As Byte)
    Dim buf(2) As Byte

    'Confirm that the escape char (92) is not included in the arguments.
    If senVal = 92 Then
    senVal += CByte(1)
    End If

    If senNo = 92 Then
    'This should NEVER happen, so just fail it.
    RaiseEvent Failed()
    Return
    End If

    buf(0) = 255
    buf(1) = senNo
    buf(2) = senVal

    mLastPointer = 0
    mLocalPointer = -1
    mHasData = False
    Array.Clear(mLocalData, 0, 4096)
    Array.Clear(lastData, 0, 4096)
    mSerial.Write(buf, 0, 3)
    myTimer.Enabled = True
    timeCounter = True
    End Sub

    Public Sub ClearAlert()
    Dim buf(2) As Byte

    buf(0) = 255 'The flag
    buf(1) = 111 'Sensor 111 just clears the alert.
    buf(2) = 0 'This doesn't do anything.

    mSerial.Write(buf, 0, 3)
    End Sub

    Public Sub WriteMove(ByVal lWhl As Byte, ByVal rWhl As Byte, ByVal dur As Byte)
    Dim buf(2) As Byte

    'Check to see that 92 (the escape character) is not one of the values.
    If lWhl = 92 Then
    lWhl += CByte(1)
    End If
    If rWhl = 92 Then
    rWhl += CByte(1)
    End If
    If dur = 92 Then
    dur += CByte(1)
    End If

    buf(0) = 255
    buf(1) = 100
    buf(2) = lWhl

    mSerial.Write(buf, 0, 3)

    buf(0) = 255
    buf(1) = 101
    buf(2) = rWhl

    mSerial.Write(buf, 0, 3)

    buf(0) = 255
    buf(1) = 102
    buf(2) = dur

    mSerial.Write(buf, 0, 3)

    End Sub

    'A relic to setting addresses for the SRF08. Don't use it.
    Public Sub WriteAddress(ByVal no As Byte)
    Dim buf(2) As Byte

    buf(0) = 255
    buf(1) = 10
    buf(2) = no
    mSerial.Write(buf, 0, 3)
    End Sub

    Public Sub SendReset()
    resetFlag = True
    mSerial.Write("\0")
    mSerial.Write("W")
    resetFlag = False
    End Sub

    #End Region

    #Region "Private Functions"


    Private Sub TimerEventProcessor(ByVal myobject As Object, ByVal myEventArgs As EventArgs)
    If timeCounter Then
    SendReset()
    myTimer.Enabled = False
    RaiseEvent Failed()
    mFailCount += 1
    If mFailCount > 3 Then
    ReSet()
    End If
    Else
    timeCounter = True 'Set false by data received.
    End If
    End Sub

    'This is the way data is read if the timer is not in use (no sensor read).
    Private Sub DataReceivedProcessor(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles mSerial.DataReceived
    Dim inByte As Byte
    Dim cnt As Integer
    Dim buff(4096) As Byte
    Dim x As Integer
    'This is a special case, not a sensor read.
    mFailCount = 0 'ANY bytes coming in means that something is happening.
    timeCounter = False

    'If the flag is set, bail out.
    If resetFlag Then
    Return
    End If

    cnt = mSerial.Read(buff, 0, 4096)
    For x = 0 To cnt - 1
    inByte = buff(x)
    mLocalPointer += 1
    mLocalData(mLocalPointer) = inByte
    If inByte = 128 Then
    mAlertCount += 1
    ElseIf inByte = 255 Then
    mDoneCount += 1
    mAlertCount = 0
    If mDoneCount = 3 Then
    mDoneCount = 0

    'If there is something in the alert holder, then this
    'is an alert. Only the alert holder byte matters, so the three 128 bytes
    'will simply be ignored.
    If mAlertHolder > 0 Then
    myContext.Post(AddressOf EventRaiser, mAlertHolder) 'The stop alert.
    mAlertHolder = 0 'Clear the holder.
    Else
    'Need to strip off those final three bytes.
    mLocalPointer -= 3
    'Check that this didn't do something truly bizarre.
    If mLocalPointer < 0 Then
    mLocalPointer = 0
    'This should never happen.
    Windows.Forms.MessageBox.Show("A too short message was found.", "Error")
    End If
    lastData = CType(mLocalData.Clone, Byte())
    mLastPointer = mLocalPointer
    mHasData = True
    myTimer.Enabled = False
    myContext.Post(AddressOf EventRaiser, 255)
    mLocalPointer = -1
    Array.Clear(mLocalData, 0, 4096)
    End If
    End If
    Else
    If mAlertCount = 3 Then
    mAlertCount = 0
    mAlertHolder = CInt(inByte)
    'clear these two.
    End If
    mAlertCount = 0
    mDoneCount = 0
    End If

    Next

    End Sub

    Private Sub EventRaiser(ByVal typ As Object)
    Select Case CInt(typ)
    Case 255
    RaiseEvent DataReady()
    Case 101
    RaiseEvent Stopped()
    Case Else
    RaiseEvent Alert(CInt(typ))
    End Select
    End Sub

    #End Region
    End Class
    End Class

    It debugged fine, but there was an error: Warning 1 Function 'GetData' doesn't return a value on all code paths. Are you missing a 'Return' statement? C:\Users\dan\documents\visual studio 2010\Projects\WindowsApplication8\WindowsApplication8\Form1.vb 176 9 WindowsApplication8

    It is still not communicating with the arduino - I'm about positive the arduino code is good, I've written dozens of them for different purposes that all worked fine - 2 were even quite complex. Is there something that needs to be fixed yet? I'm a bit perplexed that it debugged with an error showing!

    I did notice one other thing - in one of my earlier attempts, when I clicked the button, the text changed. I have not had that happen since; is that the way it's supposed to work?? I am felling frustrated... it seems as though we are closer than ever - your code looks awesome, but still not doing quite what I want lol

    What is the next logical step here? one thing is for sure, I'm learning vb.net more every day, & that was actually my main goal!! One thing I noticed, the "try catch" didn't come up with anything! I know I'm taking an awful lot of your time, but bear with me here - we're close! please advise...

  10. #10
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: VB newbie desperately needs programming help!!

    The try/catch was a template not a literal copy and paste. You need to insert the relevant sections of code into it where it says that's where the code goes!

    A function must return a value to the calling code eg.

    x = DoStuff(y)

    calls

    Function DoStuff(byVal input as Int16) As Int16
    Dim stuff As Int16 = input * 13231
    Return stuff
    End Function

    which with input = y does some math and returns stuff making x = stuff

    If it has no return value then it's a Sub not a Function and must be declared so.

  11. #11
    Loquacious User Shaggy Hiker's Avatar
    Join Date
    Aug 02
    Location
    Idaho
    Posts
    20,390

    Re: VB newbie desperately needs programming help!!

    The Try...Catch won't come up with anything the way you have it in the button click, because you don't do anything in the Catch portion. At the very least, you should be showing a messagebox with ex.Message in it.

    Also, in the Try portion that you showed, all you have is a comment about what code is there. What code IS there? After all, you appear to have copied in my class, but I don't see you doing anything with it. You don't show that you create an instance of the class, or call any of the methods. There is also lots of code that you left in there that won't do you any good, such as the creation of the byte strings that I was sending in ReadSensor, WriteMove, WriteAddress. All that stuff is largely worthless to you except possibly as an example for one way to make methods for sendind certain things out the serial port.

    GetData has a flaw. It is written as a function which returns an integer, except that I didn't return anything. The function works, it just doesn't need to be a function. Instead, it should be a sub. I expect that I was intending to return the number of bytes of data that were copied, then decided against it and didn't change the function to a sub. It's interesting that I didn't deal with the warning, but I haven't worked with that bit of the code for years.

    If you haven't gotten to the point where you have learned about classes in VB, much of that code may make no sense to you. For instance, the events (which aren't all that well implemented, frankly), the structure of the code, and so forth. It certainly won't work right for you, as is, since it was designed to work with an entirely different brainboard (OOPic) communicating via a Bluetooth chip (which doesn't really matter, since it acts as any other serial port). The key to take from that is how to set up a SerialPort object, and how to work with one.
    My usual boring signature: Nothing

  12. #12
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    Re: VB newbie desperately needs programming help!!

    OK, thanks guys... I see several of my mistakes now. For one thing, I was half asleep when I posted - the baud rate for the arduino must be 300, & my com port is com3... DUH! I obviously wasn't watching what I was doing & apologize for wasting your time lol. I understand the points you've made above also... will rework & experiment b4 I re-post. got a few pressing matters in real time here also, so it will likely be a couple of days. thanks for the continued support.

  13. #13
    Loquacious User Shaggy Hiker's Avatar
    Join Date
    Aug 02
    Location
    Idaho
    Posts
    20,390

    Re: VB newbie desperately needs programming help!!

    Ouch!! A baud rate maximum of 300? I guess you are only talking about moving a few bytes at a time, but that sure seems low.
    My usual boring signature: Nothing

  14. #14
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    Re: VB newbie desperately needs programming help!!

    I know it's painfully slow, but it is just a micro-processor... most loops run fast enough to not notice with the applications they use. I'll be working on this tonight!

  15. #15
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    Re: VB newbie desperately needs programming help!!

    OK, I've looked it over very carefully, & removed the sections that you said I don't need - also removed the get data function. It looks like there may be other things I won't need, but it looks like it should be ok... be sure & correct me if I'm wrong, please! It looks like I needed to name the serial port mSerial, so I did. I'm a bit stuck now, however, because I need to integrate my code portion with the part from you that I revised, & I'm really not sure how to go about it. I really would like to do it on my own, because I know there's no better way to learn... what I would like is some kind of direction to proceed; please give me an Idea of what I need to do! also, is everything in your code ok now that I've messed with it? & lastly, was I right in naming the serial port eSerial? I know I'm asking a lot, & you already have a lot of time in this for me... you have no idea how excited I am that someone is willing to help me with this, especially since I keep making blunders!! I am still working on VB.NET from 2 different online sources - I find that it doesn't come easily to me, it's profoundly more complex than I had expected & I hold a real admiration for experts such as yourself! Sotra one of those things the more you learn, the more you realize how little you know... thank you all for everything you've done for me - this is a fantastic forum! I will end by posting the revised code from you, then the code I need to integrate:


    Public Class Form1
    Public Class FastSerialManager
    Implements IDisposable

    Private WithEvents mSerial As System.IO.Ports.SerialPort
    Private lastData(4096) As Byte
    Private mLastPointer As Integer
    Private mHasData As Boolean
    Private mLocalData(4096) As Byte
    Private mLocalPointer As Integer

    Private mDataList As List(Of String)
    Private mResidual As Byte

    Private disposedValue As Boolean = False ' To detect redundant calls
    Private resetFlag As Boolean

    Private mFailCount As Integer

    Private mAlertCount As Integer
    Private mAlertHolder As Integer
    Private mDoneCount As Integer


    'Private mCount As Integer

    'The timer
    Private myTimer As System.Windows.Forms.Timer
    Private timeCounter As Boolean
    Private myContext As System.Threading.SynchronizationContext


    #Region "Constructors and Destructors"

    Public Sub New()
    mSerial = New System.IO.Ports.SerialPort
    mSerial.BaudRate = 300
    mSerial.DataBits = 8
    mSerial.StopBits = IO.Ports.StopBits.One
    mSerial.Parity = IO.Ports.Parity.None
    mSerial.PortName = "COM3"

    mSerial.WriteTimeout = 500
    mSerial.ReadTimeout = 3000
    mSerial.ReadBufferSize = 4096
    mSerial.ReceivedBytesThreshold = 1

    myContext = System.Threading.SynchronizationContext.Current

    'Need to do a few things to look for the com ports and decide which one to use.
    mSerial.Open()
    resetFlag = False

    'Create the timer.
    myTimer = New System.Windows.Forms.Timer
    mLocalPointer = -1

    'Need to tell it where to send time tick messages.
    AddHandler myTimer.Tick, AddressOf TimerEventProcessor
    myTimer.Enabled = False
    myTimer.Interval = 2000
    End Sub

    Public Sub New(ByVal nm As String)
    mSerial = New System.IO.Ports.SerialPort
    mSerial.BaudRate = 300
    mSerial.DataBits = 8
    mSerial.StopBits = IO.Ports.StopBits.One
    mSerial.Parity = IO.Ports.Parity.None
    mSerial.PortName = nm

    mSerial.WriteTimeout = 500
    mSerial.ReadTimeout = 500
    mSerial.ReceivedBytesThreshold = 1
    myContext = System.Threading.SynchronizationContext.Current

    'Need to do a few things to look for the com ports and decide which one to use.
    mSerial.Open()

    'Create the timer.
    myTimer = New System.Windows.Forms.Timer
    mLocalPointer = -1

    'Need to tell it where to send time tick messages.
    AddHandler myTimer.Tick, AddressOf TimerEventProcessor
    myTimer.Enabled = False
    myTimer.Interval = 2000
    End Sub

    ' IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
    If Not Me.disposedValue Then
    mSerial.Dispose()
    End If
    Me.disposedValue = True
    myTimer.Dispose()
    End Sub

    #Region " IDisposable Support "
    ' This code added by Visual Basic to correctly implement the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
    ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
    Dispose(True)
    GC.SuppressFinalize(Me)
    End Sub
    #End Region

    #End Region

    #Region "Properties and Events"

    Public ReadOnly Property NewData() As Boolean
    Get
    Return mHasData
    End Get
    End Property

    Public Event DataReady()

    Public Event Alert(ByVal alertVal As Integer)

    Public Event Stopped()

    Public Event Failed()


    #End Region

    #Region "Public Functions"

    Public Sub ReSet()
    mSerial.Dispose()
    mFailCount = 0
    mSerial = New System.IO.Ports.SerialPort
    mSerial.BaudRate = 300
    mSerial.DataBits = 8
    mSerial.StopBits = IO.Ports.StopBits.One
    mSerial.Parity = IO.Ports.Parity.None
    mSerial.PortName = "COM3"

    mSerial.WriteTimeout = 500
    mSerial.ReadTimeout = 3000
    mSerial.ReadBufferSize = 4096

    'Need to do a few things to look for the com ports and decide which one to use.
    mSerial.Open()
    End Sub

    'This sub mostly is used for calling sound.
    Public Sub SendOutput(ByVal senNo As Byte, ByVal senVal As Byte)
    Dim buf(2) As Byte

    'Confirm that the escape char (92) is not included in the arguments.
    If senVal = 92 Then
    senVal += CByte(1)
    End If
    If senNo = 92 Then
    RaiseEvent Failed()
    Return
    End If

    buf(0) = 255
    buf(1) = senNo
    buf(2) = senVal
    mSerial.Write(buf, 0, 3)
    End Sub


    Public Sub ClearAlert()
    Dim buf(2) As Byte

    buf(0) = 255 'The flag
    buf(1) = 111 'Sensor 111 just clears the alert.
    buf(2) = 0 'This doesn't do anything.

    mSerial.Write(buf, 0, 3)
    End Sub



    Public Sub SendReset()
    resetFlag = True
    mSerial.Write("\0")
    mSerial.Write("W")
    resetFlag = False
    End Sub

    #End Region

    #Region "Private Functions"


    Private Sub TimerEventProcessor(ByVal myobject As Object, ByVal myEventArgs As EventArgs)
    If timeCounter Then
    SendReset()
    myTimer.Enabled = False
    RaiseEvent Failed()
    mFailCount += 1
    If mFailCount > 3 Then
    ReSet()
    End If
    Else
    timeCounter = True 'Set false by data received.
    End If
    End Sub

    'This is the way data is read if the timer is not in use (no sensor read).
    Private Sub DataReceivedProcessor(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles mSerial.DataReceived
    Dim inByte As Byte
    Dim cnt As Integer
    Dim buff(4096) As Byte
    Dim x As Integer
    'This is a special case, not a sensor read.
    mFailCount = 0 'ANY bytes coming in means that something is happening.
    timeCounter = False

    'If the flag is set, bail out.
    If resetFlag Then
    Return
    End If

    cnt = mSerial.Read(buff, 0, 4096)
    For x = 0 To cnt - 1
    inByte = buff(x)
    mLocalPointer += 1
    mLocalData(mLocalPointer) = inByte
    If inByte = 128 Then
    mAlertCount += 1
    ElseIf inByte = 255 Then
    mDoneCount += 1
    mAlertCount = 0
    If mDoneCount = 3 Then
    mDoneCount = 0

    'If there is something in the alert holder, then this
    'is an alert. Only the alert holder byte matters, so the three 128 bytes
    'will simply be ignored.
    If mAlertHolder > 0 Then
    myContext.Post(AddressOf EventRaiser, mAlertHolder) 'The stop alert.
    mAlertHolder = 0 'Clear the holder.
    Else
    'Need to strip off those final three bytes.
    mLocalPointer -= 3
    'Check that this didn't do something truly bizarre.
    If mLocalPointer < 0 Then
    mLocalPointer = 0
    'This should never happen.
    Windows.Forms.MessageBox.Show("A too short message was found.", "Error")
    End If
    lastData = CType(mLocalData.Clone, Byte())
    mLastPointer = mLocalPointer
    mHasData = True
    myTimer.Enabled = False
    myContext.Post(AddressOf EventRaiser, 255)
    mLocalPointer = -1
    Array.Clear(mLocalData, 0, 4096)
    End If
    End If
    Else
    If mAlertCount = 3 Then
    mAlertCount = 0
    mAlertHolder = CInt(inByte)
    'clear these two.
    End If
    mAlertCount = 0
    mDoneCount = 0
    End If

    Next

    End Sub

    Private Sub EventRaiser(ByVal typ As Object)
    Select Case CInt(typ)
    Case 255
    RaiseEvent DataReady()
    Case 101
    RaiseEvent Stopped()
    Case Else
    RaiseEvent Alert(CInt(typ))
    End Select
    End Sub

    #End Region

    End Class
    End Class


    And the code I need to add:


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    * Dim onstate, outstring
    * onstate = 0
    * If Button1.Text = "Pin 1 on" Then
    * Button1.Text = "Pin 1 off"
    * onstate = 1
    * outstring = "!"
    * End If
    * If Button1.Text = "Pin 1 off" And onstate = 0 Then
    * Button1.Text = "Pin 1 on"
    * outstring = "$"
    * End If
    * End Sub

    I did figure out the Try - catch with a message box, just wasn't quite sure where that should go either - sorry! My code portion came from the attachment under the pic of my hardware, & it seems to be a pretty good article - explains the interface between VB.NET & the arduino, because of the slow baud rate of the arduino, it makes the VB do most of the work & leaves a small loop for the arduino. Any questions, ask away, I'll be watching all day for the next several days. Thanks again!

  16. #16
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: VB newbie desperately needs programming help!!

    If you double click on Button1 in the design window it will automatically provide a casing for the Click event code.

  17. #17
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    Re: VB newbie desperately needs programming help!!

    Hey, Shaggy hiker, if your around, I could use your input! the last couple of days I've spent a lot of time studying, & realize I still have some things wrong; Whats more, I stumbled across a current, step by step guide for building code for serial I/O, & interfacing with micro-processors. since we have this started, I'd rather work with you on what we have going, but I now have a much better understanding of what the heck I'm doing lol! I think I can finally see the light at the end of the tunnel... getting really excited! Anyone else that has suggestions or input are more than welcome also of course; this is an awesome forum with too many experts in this field to count, I'm glad to be here! thank you all.

  18. #18
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    Re: VB newbie desperately needs programming help!!

    RESOLVED!! I feel a need to post my resolution for 2 reasons; First & foremost, to thank all involved in helping me along my journey, and just as important, I,ve found a really sipmle solution for those of you looking for this answer. There is an organization called Firmata.org that developed a protocol for this expressed purpose; Firmata is a protocol built into arduino's version UNO & newer that is specifically meant to interface with VB.NET. go to Firmata.org & download the Firmata.dll, place it in your library with the Arduino environment. In VB, bring up the toolbox, right click, browse to where the Firmata.dll is, & it can be added to the toolbox. Drag & drop onto your project, & Firmata will show up on the status bar where the serial port would normally show up. This AUTOMATICALLY enables the protocol to a comport - it's so simple, it's unbelievable!there are some more steps, & basic knowledge is required in VB.NET, but I easily used the info from Firmata.org & a bit more research, & wa-la, it works like a gem! there are some limitations which i will briefly go into, & one VERY important thing; Enter the Arduino environment, go to files/examples/Firmata/Standard firmata and load the protocol into the arduino environment - it must be running in the background to interface with VB.NET. Any other questions can be addressed at Firmata.org or with some basic research. for my purpose, it was brilliant; from my host pc in my office, & the arduino & relay banks in my 5 car garage(this can be set up wirelessly, or in my case I used a 50' amplified USB cable) I can open or close all garage doors, control both light banks,the garage furnace, a motion detector with a semi-silent alarm in my office, a 60 gallon air compressor(which I have a bad habit of leaving on), the motion sensor lights on the driveway, the front door light, + I have four unused relays for whatever else I may come up with... the best part of all, when the host PC is shut down, the arduino holds all settings as is, until the next bootup when you may once again click buttons to your hearts content! Limitations: I have read that there are some - most notably, it won't work well with robotics that involve a ping sensor, because the protocol throws off the delicate timing needed for pings to measure distances accurately. One thing I failed to mention is that the remote Arduino must be loaded with Firmata also.(in addition to the environment on the host PC). Although I'm still on a learning curve myself, I will be checking this post in case anyone may have a question I can address. I CAN tell you that it's been a real blast getting this finalized! I did use low voltage relays & wiring to each unit controlled for both cost & safety concerns. (5V relays that can switch 220V at 10A - the relay for the compressor fired a larger, 40 amp relay)

  19. #19
    Loquacious User Shaggy Hiker's Avatar
    Join Date
    Aug 02
    Location
    Idaho
    Posts
    20,390

    Re: VB newbie desperately needs programming help!!

    You managed to post #17 the day I left for a three week hike. Glad you got it resolved.
    My usual boring signature: Nothing

  20. #20
    New Member angleofphase's Avatar
    Join Date
    Aug 12
    Posts
    11

    Re: VB newbie desperately needs programming help!!

    Shaggy Hiker - you were the most instrumental of all in my learning VB.NET! A very special thanks to you for being so patient with me! I know I was a slow learner, but you stuck with me & encouraged me - something I'll never forget; you owed me nothing, but because of your perseverance, I struggled through the VB tutorials & can finally Write code & have the general knowledge to proceed, & believe me, I'm just beginning! I find a great satisfaction in using my new-found talent for amusement, productivity, creativity & enjoyment... also a special thanks to others who have contributed along the way. I don't know how long these posts stay active, but I would like to continue the goodwill of this forum & be of help to others if I'm able... best wishes to you all!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •