Page 1 of 3 123 LastLast
Results 1 to 40 of 102

Thread: [RESOLVED] SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS2008)

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Resolved [RESOLVED] SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS2008)

    Hi everybody,

    I’m presently coding an application in VB.NET (VS 2010 Express on the laptop) with different parts/functions. I have to tell that I’m not an expert in neither VB or .Net But I’ve been busy on that issue for some time now.

    I’m trying to achieve the following:

    - Send commands (string) to a Newport controller through RS232 (which in turn, drives a 2 axis-motor to rotate an item placed on these axis). For example the command to move the axis n°1 to the position “20 degrees” will look like : “1PA20” (ie: axis1-Position Absolute-20°)
    - Once one movement of these 2 axis is finished, the controller sends back an answer to the first command string (ie: position, state of the motor, state of the movement: finished or running)
    - After verifying the state of the rotating axis (it has a “1” at the end of the return string when it has stopped), I’m running an image processing thread (backgroundworker for the image Processing and UI thread for the Serialport stuff) which acquires images from CCDs cameras and processes them.

    - The sequence detailed above happens 50 times (ie: 50 positions coordinates for the 2 axis, and the respective 50 images acquisitions after each and every position).

    Now, that the context is explained, here is the problem:

    For the moment I’m using ReadExisting() which maybe isn’t the best answer to my subject. From time to time, I’m having a timing issue with the Data Received Event of the Serialport class: he seems to fire too quickly and during acquisition of let’s say position n°6, the axis rotates to position n°7 (even though the thread is not the same). As it does it faster than usual, I thought of a buffer issue with some remaining data in it. For the process to run a bit smoothly with my actual buggy setup, I have set the “ReceivedBytesThreshold” to 34, although the length of the string is closer to 70 char total (as they also are negative positions, the length of the string sent to the controller isn’t quite the same for the 50 cases, “1PA-10” being one char longer than “1PA20”). When this parameter is set to the exact length of the string (let’s say 70), the DataReceived event doesn’t fire.

    The problem only occurs when I’m in a For Loop and going through the whole moving axis+process one after the other. The serialport part doesn’t produce an awkward behavior when used as a standalone vb program: I can send a 120 char long string and the movement is perfect and the answers in return in the richtextbox are as expected.

    My questions:

    1. Is this an OutBuffer issue?
    2. Could DiscardOutBuffer + Breakstate (just after writing to the port or someplace else) bring a stable solution?
    3. Should I use something not based on the DataReceived Event? Like maybe WriteLine() + ReadLine() with a vbCr as newline and try to stop the writing as soon as the vbCr is found? How to time the checking of the returned chars in that case ? (I would still need to read the last 2 char of the controller’s answer for each step).

    Thank you for reading it

  2. #2
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Is the image being sent via RS232 also? Do you have a link for the documentation? Is the data being set to/from the controller always ASCII? I would not change the ReceivedBytesThreshold from the default.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    HI, thank you for your interest in my problem

    - The image is acquired with another library and dealt on another thread and has no link with the COM part except that it must follow after the end of a movement from the axis.
    - The default for ReceivedBytesThreshold is 1 and the Newport controller fires wayyyyyy too quickly (at 19200bds) when this is set to "1". Let me clarify the situation a bit:

    I send a sequence of commands in one string to the axis controller, something along the lines of "1TP?;1PA10;1WS;WT500...." containing approx. 70-80 char (always string so they can be processed by the controller). With ReadExisting(), if I leave the ReceivedByteThreshold set to 1, roughly one third of the sequence is processed and the DataReceivedEvent already fires from the next part of the string,etc.

    Now the solution may be to leave out the DataReceived Event + ReadExisting altogether and use the combo WriteLine/ReadLine, as I always have ONE string (length may vary) to send and ONE string to process. I will do some tests today and tomorrow to see what parameters could suit me.

    I have the vb codes

  4. #4
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by LiamC View Post
    HI, thank you for your interest in my problem

    - The image is acquired with another library and dealt on another thread and has no link with the COM part except that it must follow after the end of a movement from the axis.
    - The default for ReceivedBytesThreshold is 1 and the Newport controller fires wayyyyyy too quickly (at 19200bds) when this is set to "1". Let me clarify the situation a bit:

    I send a sequence of commands in one string to the axis controller, something along the lines of "1TP?;1PA10;1WS;WT500...." containing approx. 70-80 char (always string so they can be processed by the controller). With ReadExisting(), if I leave the ReceivedByteThreshold set to 1, roughly one third of the sequence is processed and the DataReceivedEvent already fires from the next part of the string,etc.

    Now the solution may be to leave out the DataReceived Event + ReadExisting altogether and use the combo WriteLine/ReadLine, as I always have ONE string (length may vary) to send and ONE string to process. I will do some tests today and tomorrow to see what parameters could suit me.

    I have the vb codes
    The problem is not a byte threshold of 1. I run at speeds much faster than 19,200 and do not have a problem. Without knowing exactly what the protocol is I can't guess what the problem is and how you want to handle the messages being returned. Do you have a link for the documentation?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Oh yes, sorry did not answer that part. I will provide some code of course. From what I've seen during testing (the controller gets too much information, or too quickly), the way I handled readexisting may be at fault, and the timings and pause management surely are.
    Attached Files Attached Files

  6. #6
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Do the messages you receive from the controller end in carriage return (CR - ASCII 13)?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  7. #7

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by dbasnett View Post
    Do the messages you receive from the controller end in carriage return (CR - ASCII 13)?
    I think so yes, I have to check the char positionned 2 from the end of the return string to get the status of the motion.

  8. #8
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Here is some code to try that replaces the datareceived event handler, background worker do work and progress changed. This code will receive the bytes from the controller and display the messages in a richtextbox. Hopefully it shows how to approach this problem.

    Code:
        Dim dataByts As New List(Of Byte)
        Dim dataLock As New Object
        Dim dataAvailable As New Threading.AutoResetEvent(False)
    
        Private Sub SerialPort1_DataReceived(sender As Object, _
                                             e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            Dim br As Integer = SerialPort1.BytesToRead '# of bytes to read
            If br > 0 Then
                Dim b(br - 1) As Byte 'create buffer to read the data
                Try
                    br = SerialPort1.Read(b, 0, b.Length) 'read the bytes, note non-blocking
                    If br < b.Length Then 'adjust length if required
                        Array.Resize(b, br)
                    End If
                    'add bytes just read to list
                    Threading.Monitor.Enter(dataLock)
                    dataByts.AddRange(b)
                    Threading.Monitor.Exit(dataLock)
                    dataAvailable.Set()
                Catch ex As Exception
                    'exception handling
                End Try
            End If
        End Sub
    
        Const LF As Byte = 10
    
        Private Sub BackgroundWorker1_DoWork(sender As Object, _
                                             e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            Do
                If BackgroundWorker1.CancellationPending Then Exit Do
                Dim idxLF As Integer = dataByts.IndexOf(LF)  'get the index of the LF
                If idxLF >= 0 Then 'do we have a LF
                    'yes, get the message from controller
                    Dim s As String
                    Threading.Monitor.Enter(dataLock)
                    s = System.Text.Encoding.GetEncoding(28591).GetChars(dataByts.ToArray, 0, idxLF - 1)
                    dataByts.RemoveRange(0, idxLF + 1) 'remove the message from the buffer
                    Threading.Monitor.Exit(dataLock)
                    BackgroundWorker1.ReportProgress(1, s)
                Else
                    'wait for more data
                    dataAvailable.WaitOne()
                End If
            Loop
        End Sub
    
        Private Sub BackgroundWorker1_ProgressChanged(sender As Object, _
                                                      e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
            'this code run on UI
            Dim s As String = DirectCast(e.UserState, String) 'get message
            RichTextBox1.AppendText(s & Environment.NewLine)
        End Sub
    Note that if this runs for long periods of time the length of the richtextbox.text string will start to affect the performance of the application.
    Last edited by dbasnett; Sep 26th, 2013 at 07:59 AM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  9. #9
    Addicted Member
    Join Date
    Nov 2011
    Posts
    223

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    I have to check the char positionned 2 from the end of the return string to get the status of the motion.

    That seems to go along with the Newport manual I Googled http://assets.newport.com/webDocumen...ages/14293.pdf


    NOTE
    A controller command (or a sequence of commands) has to be terminated with a carriage return character. However, responses from the controller are always terminated by a carriage return/line feed combination. This setting may not be changed. If the IEEE interface is used, the IEEE controller has to be configured to terminate the input (read) function when it senses the line feed character.

  10. #10
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by Mc_VB View Post
    That seems to go along with the Newport manual I Googled http://assets.newport.com/webDocumen...ages/14293.pdf
    I edited the code sample to account for the CRLF
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  11. #11

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by Mc_VB View Post
    That seems to go along with the Newport manual I Googled http://assets.newport.com/webDocumen...ages/14293.pdf
    Yep that's the same series I'm working on. I have a 2 axis ESP301 to work on, so now we're sure of the CrLf ! Thanks guys , so reactive and helpful !

  12. #12

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by dbasnett View Post
    I edited the code sample to account for the CRLF
    Thanks a million dbass !

    I will have a hard look on what magic you've produced there and try to understand all the parts.

    Cheers, will let you know how it goes

  13. #13

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Hi dbasnett and everyone,

    Maybe I have not been precise enough in my explanation of the problem; sorry if this is the case. So I should detail it better before I write my questions on the things I tried to understand in your code.
    here is roughly what I'm trying to set up atmo:

    - Definition of the 50 positions the axis should go through
    - FOR LOOP { SendCoordinates (xi,yi) to controller = Serialport.Write
    - The axis move upon command (takes from 10 to 20 sec), during that time nothing else should happen. Only the movement of the axis.
    - The axis have reached their position, we check this with the return string from the controller (2char from the string end: “0” =movement running, “1” = movement over)
    - Start of the background worker after we've checked the axis have stopped
    - Start of the image acquisition at specified position i. During that time the axis should not move at all, and that’s the biggest issue I have right now with my method: threads/timing/buffering.
    - The main VB form keep updates of the progress of the BCKGND Worker (the progress of the image processing) while being locked (the user cannot click on other buttons while acquisition is in progress) : for the moment I have UI thread locked and the BCKGND Worker running the image process here.
    - End of the acquisition and processing. We quit the BCKGND Worker and we have to move to another position, so back to SendCoordinates()
    - END OF LOOP

    Hope it makes it clearer if it was needed.

    Now here is my input on your code after a first look:

    - BytesToRead counts the bytes in the receive buffer, which are the bytes that have been sent BACK FROM the controller, right? You use this to populate a list of bytes and control the size. That’s a good way for me to do things right, but I would need this to control what’s left in the buffer SENDING DATA TO the controller (BytesToWrite I guess, or am I misunderstanding the way the 2 buffers work?). This is because the return string is always the same size and we just have to check if the “1” is there 2 from the end (=movement stopped). On the opposite, the outgoing string (in Serialport.write) is not the same size depending on the position and we don’t want the controller to get more data than the ONE string we just sent him: that is the crucial thing. I have to send the next string of commands ONLY WHEN the acquisition of the image is over in the BCKGND worker.

    - Threading.AutoresetEvent : allows threads to communicate by signaling as I’ve read it on MSDN, but I don’t quite get how Set() and WaitOne() are linked together in the code here. When Set() is called, what does it trigger ?
    - Same applies to Monitor.Enter and Exit: what exactly is its role ?
    - I got the converting part of the bytes list to an array of char and the reseting of the list afterwards, but why is it in the BCKGND thread?

    Again thanks for the new info and way of handling things, much much appreciated !

  14. #14
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Now here is my input on your code after a first look:

    - BytesToRead counts the bytes in the receive buffer, which are the bytes that have been sent BACK FROM the controller, right? You use this to populate a list of bytes and control the size.

    I think yes. The only thing the receive event handler does is read all the bytes available and place them into a buffer. If the controller sends a message it might cause more than one receive event to be fired. The receive event handler sets the AutoResetEvent to indicate that some data was received.

    That’s a good way for me to do things right, but I would need this to control what’s left in the buffer SENDING DATA TO the controller (BytesToWrite I guess, or am I misunderstanding the way the 2 buffers work?). This is because the return string is always the same size and we just have to check if the “1” is there 2 from the end (=movement stopped).

    When you have received a complete message it is up to you to process it accordingly. Did the code I supplied show complete messages?

    On the opposite, the outgoing string (in Serialport.write) is not the same size depending on the position and we don’t want the controller to get more data than the ONE string we just sent him: that is the crucial thing. I have to send the next string of commands ONLY WHEN the acquisition of the image is over in the BCKGND worker.

    The controller should receive what you send it without delay unless there is some form of flow control defined in the protocol.

    - Threading.AutoresetEvent : allows threads to communicate by signaling as I’ve read it on MSDN, but I don’t quite get how Set() and WaitOne() are linked together in the code here. When Set() is called, what does it trigger ?

    The WaitOne blocks until it is set. Once it is set it executes the code that follows. It resets back to blocking mode for the next time it is executed.

    If you receive a message in two parts, or more, the receive event handler would set the AutoresetEvent after reading the first part. The WaitOne would unblock and see that it didn't have a complete message and end up back at the WaitOne, blocking again. After reading the second part the receive event handler would set the AutoresetEvent again. The WaitOne would unblock and see that it had a complete message and process it and then eventually block again.

    - Same applies to Monitor.Enter and Exit: what exactly is its role ?

    They are locking mechanisms that ensure that only one thread is manipulating the buffer at a time.

    - I got the converting part of the bytes list to an array of char and the reseting of the list afterwards, but why is it in the BCKGND thread?

    It was an example.


    In your first post you indicated that you were new at this. Choosing the SerialPort as a beginner project is a tough choice.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  15. #15

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    HI,
    Thank you for the quick answers once again !

    I haven't been testing your code right away by copying it in the rest of my VB, I wanted to understand the parts first. And see what you were doing and how
    I'm now trying to organize it my way (but keeping your approach obv.) in a new larger VB.

    The main changes are going to be:

    - Put all your sequence in the UI thread (from the start to the verification of the return string at the end)
    - Test if it displays the string in the richtextbox as wanted
    - Then implement the BCKGND worker after this step is complete
    - Test if the two tasks are rightly timed one after the other and that the axis do not move while the bckgnd thread is running.

    A few questions come to mind right now:

    - The DataReceived event fires as soon as the serialport has "enough" data (amount we can't really control as I understand it right now ?). In your code, this "random" process is treated with the WaitOne command: it will Loop until the IndexOf part finds a Cr character, then it will encode the whole sequence of bytes to string and display it in the rtb. Am I correct ?

    - Following this, what would be the better option "to stop" the UI thread (and keep it stopped while the BCKGND worker is running) and start the BCKGND worker once an entire message has been found ?

    - And the way to restart it in the Loop where it left (position i) ? As you’ve maybe seen in my first code, the only way I found at the time was to have a formal message pop up to have a pause on the UI thread, and a “next” button in it. The button was then later enabled when the BCKGND worker had finished. The result is close to what I really want (the user to choose to click on next when he sees a visual signal that BCKGND worker has finished, and invite him to go to the next phase of positioning). But the way it is done seems rather amateur…

    Thank you for sharing your knowledge on this rather deep subject as you mentionned above !

  16. #16
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Step 1: Take the code I provided and add enough code to see if it works. That would be open the serial port, configure / start the backgroundworker, send a command or two, and see if the richtextbox has the commands you expect.

    Step 2: From what I can tell you want to move the camera and when it stops take a picture, and then repeat this some number of times. Is that correct?

    The DataReceived event fires if it has data(how much data is hard to tell, and debugging influences the results), and another SerialPort event is not active. The backgroundworker is 'paused'(.WaitOne) waiting for the DataReceived event to tell it to look for a LF(.Set).
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  17. #17

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by dbasnett View Post
    Step 1: Take the code I provided and add enough code to see if it works. That would be open the serial port, configure / start the backgroundworker, send a command or two, and see if the richtextbox has the commands you expect.

    Step 2: From what I can tell you want to move the camera and when it stops take a picture, and then repeat this some number of times. Is that correct?

    The DataReceived event fires if it has data(how much data is hard to tell, and debugging influences the results), and another SerialPort event is not active. The backgroundworker is 'paused'(.WaitOne) waiting for the DataReceived event to tell it to look for a LF(.Set).
    Step1: totally agree with you and that's what I'm doing when I have time on this. The open/configure are already 100% functionnal, have to start the BCK somewhere and add the part where I serialport.write the commands to the controller
    Step2: It is the object getting illimunated that is moving with the controller commands, but it's roughly the same in the VB/Serialport context if it was the camera And yes, I want to move the object, grab a frame from the camera, move the object again...

    (EDIT) Here is the sketch of the experiment:

    Name:  sketch_context.jpg
Views: 14996
Size:  63.8 KB
    Last edited by LiamC; Sep 26th, 2013 at 10:06 AM. Reason: additional info

  18. #18

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by dbasnett View Post
    Step 1: Take the code I provided and add enough code to see if it works. That would be open the serial port, configure / start the backgroundworker, send a command or two, and see if the richtextbox has the commands you expect.

    Step 2: From what I can tell you want to move the camera and when it stops take a picture, and then repeat this some number of times. Is that correct?

    The DataReceived event fires if it has data(how much data is hard to tell, and debugging influences the results), and another SerialPort event is not active. The backgroundworker is 'paused'(.WaitOne) waiting for the DataReceived event to tell it to look for a LF(.Set).
    Ok, I took some time to work on this a bit:

    1. I put the start of the BCKGND Worker at the end of the DATARECEIVED Event, is this the right way to go ?
    2. RTB is created on the UI thread (windows form object) and thus trying to append text in the BCK ProgressChanged causes interthread exception. How can I avoid this ? InvokeRequired as a guess or just Me.RTb... ? (I'll try these options later)
    3. WaitOne is presently in the BCKG thread. Does it have to be on another thread as the dataAvailable.Set command ?
    4. ReportProgress is usually passed with an INT % as parameter. Here it is written with 2 params and no %, what is the meaning of the syntax used in your code ?

    Thanks
    Last edited by LiamC; Sep 27th, 2013 at 04:43 AM.

  19. #19
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    There is a link in my signature for the Documentation.

    Try this.

    Create a new form with three buttons, one richtextbox, one backgroundworker, and one serialport. Keep the default names for the controls / components. Then copy and paste this code. The form shown event opens the serial port so make changes to reflect your settings for the serial port.

    Code:
    'Create a new project with three buttons and one richtextbox, take the default names.  
    'Copy and paste this code to the project.
    'The shown event opens the port specified.  
    'Make sure you change the settings to match  yours.  
    'Button1 sends data to the port.  
    
    Option Strict On
    Public Class Form1
    
        Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
            '
            'port setup and open - modify to fit your needs
            '
            Dim p() As String = IO.Ports.SerialPort.GetPortNames 'array p contains ports visible to system
    
            'your settings here
            With SerialPort1
                .PortName = "COM27" '<<<<<<<<<<<<<<<<<YOUR PORT<<<<<<<<<<<<<<<<<<<<<<<<
                .Encoding = System.Text.Encoding.GetEncoding(28591)
                .DtrEnable = True
                .RtsEnable = True
                'etc
            End With
    
            Try
                SerialPort1.Open()
                isopen.Set()
                BackgroundWorker1.WorkerReportsProgress = True
                BackgroundWorker1.WorkerSupportsCancellation = True
                BackgroundWorker1.RunWorkerAsync()
            Catch ex As Exception
                RichTextBox1.AppendText(ex.Message & Environment.NewLine)
            End Try
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'send data
            Try
                If isopen.WaitOne(0) AndAlso SerialPort1.IsOpen Then
                    SerialPort1.Write("YOURCOMMAND" & vbCrLf)
                End If
            Catch ex As TimeoutException
                MessageBox.Show(ex.Message)
    
            Catch ex As InvalidOperationException
                MessageBox.Show(ex.Message)
    
            Catch ex As UnauthorizedAccessException
                MessageBox.Show(ex.Message)
    
            End Try
            isopen.Set()
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            'close port
            isopen.WaitOne()
            SerialPort1.Close()
        End Sub
    
        Dim sc As Threading.Thread
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            Button3.Enabled = False
            sc = New Threading.Thread(AddressOf SendCmds)
            sc.IsBackground = True
            sc.Start()
        End Sub
    
        Dim cmdDone As New Threading.AutoResetEvent(False)
    
        Private Sub SendCmds()
            Dim cmds As New List(Of String)
            cmds.Add("yourcmd1" & vbCrLf)
            cmds.Add("yourcmd2" & vbCrLf)
            cmds.Add("yourcmd3" & vbCrLf)
            For Each c As String In cmds
                cmdDone.WaitOne()
                SerialPort1.Write(c)
            Next
            Me.Invoke(Sub() Button3.Enabled = True)
        End Sub
    
        Dim isopen As New Threading.AutoResetEvent(False)
    
        Dim dataByts As New List(Of Byte)
        Dim dataLock As New Object
        Dim dataAvailable As New Threading.AutoResetEvent(False)
    
        Private Sub SerialPort1_DataReceived(sender As Object, _
                                             e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            Dim br As Integer = SerialPort1.BytesToRead '# of bytes to read
            If br > 0 Then
                Dim b(br - 1) As Byte 'create buffer to read the data
                Try
                    br = SerialPort1.Read(b, 0, b.Length) 'read the bytes, note non-blocking
                    If br < b.Length Then 'adjust length if required
                        Array.Resize(b, br)
                    End If
                    'add bytes just read to list
                    Threading.Monitor.Enter(dataLock)
                    dataByts.AddRange(b)
                    Threading.Monitor.Exit(dataLock)
                    dataAvailable.Set()
                Catch ex As Exception
                    'exception handling
                End Try
            End If
        End Sub
    
        Const LF As Byte = 10 'responses end with vbCrLf
    
        Private Sub BackgroundWorker1_DoWork(sender As Object, _
                                             e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            Do
                If BackgroundWorker1.CancellationPending Then Exit Do
                Dim idxLF As Integer = dataByts.IndexOf(LF)  'get the index of the LF
                If idxLF >= 0 Then 'do we have a LF
                    'yes, get the message from controller
                    Dim s As String
                    Threading.Monitor.Enter(dataLock)
                    s = System.Text.Encoding.GetEncoding(28591).GetChars(dataByts.ToArray, 0, idxLF - 1)
                    dataByts.RemoveRange(0, idxLF + 1) 'remove the message from the buffer
                    Threading.Monitor.Exit(dataLock)
                    BackgroundWorker1.ReportProgress(1, s)
    
                    cmdDone.Set() '<<<<<<<<<<<<<<<
                Else
                    'wait for more data
                    dataAvailable.WaitOne()
                End If
            Loop
        End Sub
    
        Private Sub BackgroundWorker1_ProgressChanged(sender As Object, _
                                                      e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
            'this code run on UI
            Dim s As String = DirectCast(e.UserState, String) 'get message
            RichTextBox1.AppendText(s & Environment.NewLine)
        End Sub
    
        Private Sub SerialPort1_ErrorReceived(sender As Object, _
                                              e As IO.Ports.SerialErrorReceivedEventArgs) Handles SerialPort1.ErrorReceived
    
            Debug.WriteLine("ER " & e.EventType.ToString)
        End Sub
    
        Private Sub SerialPort1_PinChanged(sender As Object, _
                                           e As IO.Ports.SerialPinChangedEventArgs) Handles SerialPort1.PinChanged
    
            Debug.WriteLine("PC " & e.EventType.ToString)
        End Sub
    End Class
    Last edited by dbasnett; Sep 30th, 2013 at 10:51 AM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  20. #20

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Back again !

    I tested your code (I did change the names but changed the functions called aswell , so it went like a charm ^^) and it returned the string I wanted. So a big thank you for your method !
    I could achieve this with my first program (the one before implementing the big Loop) but with a so-so method obviously...

    So for a single command to the controller, the code you provided works very well.

    I will have to quickly understand the way all things are linked together to implement more than one "send command" and to link it with the grab image part afterwards.
    Last edited by LiamC; Sep 27th, 2013 at 08:52 AM.

  21. #21
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Good luck.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  22. #22

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by dbasnett View Post
    Good luck.
    Thank you. I will have a first look at this today and see how it starts/goes. I will probably have questions once I hit a wall

  23. #23

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Hi again,

    I've been through some work and I think I've correctly analyzed (maybe not 100% understood) your code. I've also sequenced my needs. For both points, I have global questions.

    After reading your code several time, I think I see this:

    Form.Shown
    LOAD SETTINGS
    OPEN COM PORT
    CALLS THE BCKGND WORKER: GoTo « DoWork ».

    BackgroundWorker.DoWork
    CHECKS IF A “CR” CHAR IS IN THE RETURN STRING
    IF NO / IF YES: FIRST RUN = NO -> DataAvailable.WaitOne()
    WaitOne here means the BCKGND WORKER will stay like this as long as there is no “SET”, i.e. as long as we don’t click on the “SEND” button which contains the “SET” for the WaitHandle. So, the BACKGND WORKER runs “empty” indefinitely if we don’t click on “SEND”.

    Send.Click
    CLICK ON SEND:
    SerialPort.Write() -> TRIGGERS THE DATA RECEIVED.

    DataReceived Event
    READ THE BYTES IN THE BUFFER
    PUTS THE BYTES IN AN ARRAY AND POPULATES A LIST
    SETS THE WAITHANDLE INTO THE SIGNALED STATE: DataAvailable.Set()
    DataAvailable.Set() -> TRIGGERS ACTION ON THE BCKGND WORKER as it releases the handle from his HALTED STATE. The “Do…Loop” in the BCKGND WORKER resumes.

    Back to the BCKGND WORKER:
    The “DO…LOOP” loop: orders the received bytes by checking if the CR is there in the list and by parsing the string at its found “EndOfLine” index.
    IF YES (i.e. there is enough data in the buffer as it contains a “CR” byte-code): CONVERTS THE BYTES INTO A STRING OF CHAR.
    REPORTS THE PROGRESS TO THE BCKGND WORKER
    ReportProgress() -> TRIGGERS PROGRESSCHANGED.

    BackgroundWorker.ProgressChanged
    HAS THE FINAL STRING in INPUT PARAMETER (e.UserState)
    APPENDS THE STRING TO THE RICHTEXTBOX (DISPLAY).

    QUESTION:
    1. Is this correct or close to ?


    As the other point is concerned, it's the analysis of the sequence needs in this program:

    SEND COMMAND is the first action (step1).
    RETURN & READ STRING (step2) is triggered by step1 (BackGroundWorker + Data Received).
    CHECK RETURN STRING (step3) waits on a WaitHandle that step2 SIGNALS.
    ACQUIRE IMAGE (step4) waits on a WaitHandle that step3 SIGNALS.
    For the next position:
    SEND COMMAND waits on a WaitHandle that step4 SIGNALS. ETC. (49 times)

    The difference in these tasks is that SEND COMMAND needs to run the first time without waiting.

    QUESTIONS:

    2. I guess step1 should be started in the SIGNALED STATE (=AutoResetEvent (True)) if I want to have a loop around SerialPort.Write() ?

    3. Are the Waithandles the best way to have all these other tasks working separately and at the right time, the way you did with the first 2 (to return the string in the TxtBox) ?


    Thank you for your input !
    Last edited by LiamC; Sep 30th, 2013 at 07:44 AM.

  24. #24
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by LiamC View Post
    ...
    QUESTION:
    1. Is this correct or close to ?

    2. I guess step1 should be started in the SIGNALED STATE (=AutoResetEvent (True)) if I want to have a loop around SerialPort.Write() ?

    3. Are the Waithandles the best way to have all these other tasks working separately and at the right time, the way you did with the first 2 (to return the string in the TxtBox) ?...
    Your analysis seems correct, but then your question 2 confuses me. The autoreset event indicates data was received.

    Question 3: as good as any IMHO.

    This is what I think you/system is trying to do.


    1. Open the port
    2. Send a command that causes the object to move
    3. When it stops you take a picture - I am assuming that there is some data received that indicates stop
    4. Repeat 2-3 some number of times


    Can you, with minimal changes to the code I provided, send one move, take a picture, and then stop?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  25. #25
    Addicted Member
    Join Date
    Nov 2011
    Posts
    223

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Hi, it looks like the receiving part is in good shape but there are a couple of things from the manual that might be helpful with regard to sending.

    1. All commands are terminated with CR eg: 1PA20<CR>

    2. Multiple commands are separated with a semi-colon and terminated with a CR

    In a similar fashion, multiple commands can be issued on a single command line by separating the commands by a semi-colon . For example, 3MO; 3PA10.0; 3WS; 3MF is a valid command line.
    Once an axis has been commanded to a position further commands can be sent to verify its state. For example 1MD?<CR> is "read motion done status" and responds with a 1 or 0 to indicate true or false respectively, 1TP<CR> is "read actual position" and responds with actual position in predefined units.

  26. #26
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by Mc_VB View Post
    Hi, it looks like the receiving part is in good shape but there are a couple of things from the manual that might be helpful with regard to sending.

    1. All commands are terminated with CR eg: 1PA20<CR>

    2. Multiple commands are separated with a semi-colon and terminated with a CR



    Once an axis has been commanded to a position further commands can be sent to verify its state. For example 1MD?<CR> is "read motion done status" and responds with a 1 or 0 to indicate true or false respectively, 1TP<CR> is "read actual position" and responds with actual position in predefined units.
    Commands to the controller are terminated with CR, commands from the controller are terminated with CRLF. FWIW. I modified the code in post #19 to show a simplified version of how multiple commands could be sent..
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  27. #27

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by dbasnett View Post
    Your analysis seems correct, but then your question 2 confuses me. The autoreset event indicates data was received.

    Question 3: as good as any IMHO.

    This is what I think you/system is trying to do.


    1. Open the port
    2. Send a command that causes the object to move
    3. When it stops you take a picture - I am assuming that there is some data received that indicates stop
    4. Repeat 2-3 some number of times


    Can you, with minimal changes to the code I provided, send one move, take a picture, and then stop?
    Hi dbasnett,

    The grab image function is already done and working (it was working with my earlier buggy serialport code). So I can move the object and grab a frame yes.
    As there is no Loop implemented yet, it grabs a frame and stops without going back to the serialport part again. For your information it's a Matrox Imaging module that is implemented for the processing.
    But the frame grabbing isn't problematic at all, we can just put a fake task to simulate this call to the grab function, as long as it's in the right place and called at the right time obv.

    And the question 2. is confusing myself aswell as it was so badly explained/written. What I wanted to say is : you implemented the dataAvailable waithandle with a "FALSE" input parameter so it starts non-signaled (AutoResetEvent(False)). This way when there is a WaitOne() command, it will wait until a Set() is passed to the waithandle, right ? If I set a waithandle to "TRUE" initially, will it cruise through the WaitOne() instead of being in the waiting queue ? And the intended question was: how do I put a WaitOne (or similar) before SerialPort.Write() in order to pause the write sequence until the grabbing is complete BUT not at the the first loop iteration (position 1 will be reached before any grabbing is done at the start, obviously) ?

    @Mc_VB : yes, I've sent some commands this way:

    Code:
    1TP?;2TP?;1PA20;WT500;2PA10;WT500;1MD?;2MD?;"CR"
    Litteraly: what is the axis n°1 position ?; what is the axis n°2 position ?; Wait 500ms; Go to +20 on axis 1; Go to +10 on axis 2;Wait 500ms; Has axis 1 stopped its movement ?; Has axis 2 stopped its movement ? Return char

    This is roughly the command sequence I send for every position. I append the position "20" and "10" respectively to axis 1 and 2 ("1PA" is in the loop command and I append 20 for example by calling the variable "PosX", which =20 for axis 1 @position number 1). All the positions are in a dataTable ( 50 positions PosX and PosY). I loop with a "For Each row" etc..That part is "working" in my old code, the problem was that the axis could move too quickly after a stop as I wasn't controlling the pause and timings (ReadExisting and so on were the problems). The command to the newport controller itself seems about right.

    @dbasnett: I'm looking at your added code in #19 right now.

    If I understand correctly after a quick first reading:

    - The first step is to click on button1 to send the first command through the first SerialPort.Write()
    - Then we click on button3 which starts a new thread pointing to the function SendCmds. There is a waithandle on halted state and if it is signaled this function is sending several commands with the second SerialPort.Write()
    - I don't really get what's after the "NEXT": isn't there supposed to be sthg after "SUB" ?

    Code:
    Me.Invoke(Sub() Button3.Enabled = True)
    -> VS2008 underlines it. VS2010 Express doesn't. So I guess it's a version thing...

    - We set the waithandle to signaled with cmdDone.Set() at the end of the BackroundWorker. That means, right after a COMPLETE command has been found (Lf byte-code has been found). It frees the waithandle of the sendcommand thread, which in turn writes to the controller.
    Is this correct ?

    Thank to both of you for your view on this !!!
    Last edited by LiamC; Oct 1st, 2013 at 04:27 AM.

  28. #28

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Back from the lab,

    dbasnett, the update of your code works well. It sends the multiple commands to the controler that I've included:
    Code:
    cmds.Add("1TP?;2TP?;WT500;" & vbCrLf)
    cmds.Add("1PA10?;2PA05?;" & vbCrLf)
    cmds.Add("1WS;2WS;WT500;" & vbCrLf)
    cmds.Add("1MD?;2MD?;WT1000;" & vbCrLf)
    It displays the position asked with "TP" and then goes to x=+10 and y=+05 absolute positions with "PA"
    The strange thing is, it doesn't display the 2 "1" for the "MD" commands in the richtextbox (motion done status). Could it be the serialport DataReceived Event didn't fire ? (I started the program several times and tested it)

  29. #29
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    So you know, I don't have the equipment you have. I have a serialport with a loopback plug which I use for testing. What I send, I receive. In order to test the received code I needed to send a LF. I don't think you need to terminate your commands with CRLF, just CR. Don't know if it will make a difference.

    I don't remember which .Net framework runs with VB2008. The serialport had some bugs in frameworks before 4.0. VB 2010 use 4.0, so if you have that use it.

    Do I think that the serial port DataReceived Event is not firing, no. Is it possible, maybe, but I wouldn't pursue this line of thought until I had ruled out everything else. I haven't seen the event not fire.

    Have you tried just sending the commands one at a time? In button 1 change the command to

    SerialPort1.Write("1MD?" & vbCr)

    Remember the code I provided is to help you, it is not the answer. Button 1 was just a test to send one command. Button 3 was for sending multiple commands using a thread. The SendCmds sub runs on a thread that isn't on the UI so to turn Button 3 back on I took the shortcut UI delegate method, Me.Invoke(Sub() Button3.Enabled = True). Change that line to

    Code:
            Dim foo As New but3ondel(AddressOf turnBut3On)
            Me.Invoke(foo)
    and add this

    Code:
        Delegate Sub but3ondel()
    
        Private Sub turnBut3On()
            Button3.Enabled = True
        End Sub
    I found an error with the code I provided, this statement

    Dim cmdDone As New Threading.AutoResetEvent(False) , should be

    Dim cmdDone As New Threading.AutoResetEvent(True).
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  30. #30

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Re dbasnett,

    I do of course understand you don't have the same hardware at your disposal. the part with the commands written was there to illustrate that several REAL commands to the controller did work and your code achieved its goal in-situ.

    I'm going to test command after command and see how it goes with the hardware (and see if it answers to "MD?").

    I will install VS2010 Express on the machine that will have the hardware plugged into at the end (it has VS2008 right now). As I'm constantly going from and to the lab, I'm using the laptop which has VS2010 express/ 4.0 Framework on it. That's it for the VS version explanation

    Thanks for the answer on the delegate, I had figured out its role but now it's perfectly clear with the function and segmentation you wrote.

    I think I understood the difference with the starting status of the waithandle, but what does it change here within this code ?
    Is the cmdDone As New Threading.AutoResetEvent(True) there to go through the WaitOne() at the first iteration ?

  31. #31
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Is the cmdDone As New Threading.AutoResetEvent(True) there to go through the WaitOne() at the first iteration ? Yes. Without it set to True it will not send a command, and therefore the code that sets it will never run.

    Does every command you send return a response from the controller?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  32. #32

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Hi again dbasnett, thanks for the celerity of your inputs

    For one single command it works nicely, they all work, be it move an axis or ask the controller for a status or position.

    I've just tested a few runs, it seems it runs exactly as I want when there are only 3 times "cmds.Add" (=3 strings in the list). And I don't know why it doesn't display everything when I have 6 or 7 times "Add". It hangs after displaying the 2 positions (asked with 1TP? and 2 TP?).

    With a clear example, this works like a charm (several tests) :

    Code:
    cmds.Add("1TP?;2TP?;WT500;1PA10;" &vbCr)
    cmds.Add("2PA05;" &vbCr)
    cmds.Add("1WS;2WS;WT500;1MD?;2MD?;1TP?;2TP?;WT1000;" &vbCr)
    This displays the positions and moves the axis but doesn't return the "1" motion done status neither the second set of "arrival" positions:

    Code:
    cmds.Add("1TP?;2TP?;WT500;" &vbCr)
    cmds.Add("1PA10;" &vbCr)
    cmds.Add("2PA05;" &vbCr)
    cmds.Add("1WS;2WS;WT500;" &vbCr)
    cmds("1MD?;2MD?;1TP?;2TP?;WT1000;" &vbCr)
    vbCr or vbCrLf does bring the same result, ie. they both work.

    I've removed the button1 and its click handle, and put the actions of button3 between try catch as u did it with the single command in button1.

    I saw the difference between TRUE and FALSE in the AutoResetEvent parameter. With FALSE it indeed hanged before writing anything, and with TRUE it went through the cmdDone.WaitOne().

    As I see the architecture of the threading and my needs, I think I have to create a thread for the grab_image "function" and have a waitOne and Set at the right places. For the moment, as I understand the running of the threads, I need to have a waitOne at the BEGINNING of the Grab_Image function so it waits for a signal to continue its course. The Set() that is going to activate the "tollbarrier" of the Grab_Image WaitHandle is going to be placed at the end of the "check return string from controller" part, ie. we need to wait for the string to be checked before starting the image processing.
    Last edited by LiamC; Oct 1st, 2013 at 10:37 AM.

  33. #33
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by LiamC View Post
    Hi again dbasnett, thanks for the celerity of your inputs

    For one single command it works nicely, they all work, be it move an axis or ask the controller for a status or position.

    I've just tested a few runs, it seems it runs exactly as I want when there are only 3 times "cmds.Add" (=3 strings in the list). And I don't know why it doesn't display everything when I have 6 or 7 times "Add". It hangs after displaying the 2 positions (asked with 1TP? and 2 TP?).

    With a clear example, this works like a charm (several tests) :

    Code:
    cmds.Add("1TP?;2TP?;WT500;1PA10;" &vbCr)
    cmds.Add("2PA05;" &vbCr)
    cmds.Add("1WS;2WS;WT500;1MD?;2MD?;1TP?;2TP?;WT1000;" &vbCr)
    This displays the positions and moves the axis but doesn't return the "1" motion done status neither the second set of "arrival" positions:

    Code:
    cmds.Add("1TP?;2TP?;WT500;" &vbCr)
    cmds.Add("1PA10;" &vbCr)
    cmds.Add("2PA05;" &vbCr)
    cmds.Add("1WS;2WS;WT500;" &vbCr)
    cmds("1MD?;2MD?;1TP?;2TP?;WT1000;" &vbCr)
    vbCr or vbCrLf does bring the same result, ie. they both work.

    I've removed the button1 and its click handle, and put the actions of button3 between try catch as u did it with the single command in button1.

    I saw the difference between TRUE and FALSE in the AutoResetEvent parameter. With FALSE it indeed hanged before writing anything, and with TRUE it went through the cmdDone.WaitOne().

    As I see the architecture of the threading and my needs, I think I have to create a thread for the grab_image "function" and have a waitOne and Set at the right places. For the moment, as I understand the running of the threads, I need to have a waitOne at the BEGINNING of the Grab_Image function so it waits for a signal to continue its course. The Set() that is going to activate the "tollbarrier" of the Grab_Image WaitHandle is going to be placed at the end of the "check return string from controller" part, ie. we need to wait for the string to be checked before starting the image processing.
    If the code works sending one command at a time, but not if you combine commands into a single string separated by ;, the problem may be with the controller.

    Here is an alternative SendCmds
    Code:
        Private Sub SendCmds()
            Dim cmds As New List(Of String)
            Dim cmdlist1() As String = {"1TP?", "2TP?", "WT500", "1PA10"}
    
            Dim cmdList2() As String = {"1WS", "2WS", "WT500", "1MD", "2MD", "1TP", "2TP", "WT1000"}
    
            cmds.AddRange(cmdlist1)
            cmds.AddRange(cmdList2)
    
            For Each c As String In cmds
                cmdDone.WaitOne()
                SerialPort1.Write(c & vbCr)
            Next
            'Me.Invoke(Sub() Button3.Enabled = True)
            Dim foo As New but3ondel(AddressOf turnBut3On)
            Me.Invoke(foo)
        End Sub
    Do you need another thread for taking the picture? It doesn't sound like it, but I can't be certain. It seems that with what you have you know in the existing backgroundworker that the motion has stopped, so just take the picture and then continue on.

    Where are you?(country) Is this for work?
    Last edited by dbasnett; Oct 1st, 2013 at 11:32 AM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  34. #34

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by dbasnett View Post
    If the code works sending one command at a time, but not if you combine commands into a single string separated by ;, the problem may be with the controller.

    Here is an alternative SendCmds
    Code:
        Private Sub SendCmds()
            Dim cmds As New List(Of String)
            Dim cmdlist1() As String = {"1TP?", "2TP?", "WT500", "1PA10"}
    
            Dim cmdList2() As String = {"1WS", "2WS", "WT500", "1MD", "2MD", "1TP", "2TP", "WT1000"}
    
            cmds.AddRange(cmdlist1)
            cmds.AddRange(cmdList2)
    
            For Each c As String In cmds
                cmdDone.WaitOne()
                SerialPort1.Write(c & vbCr)
            Next
            'Me.Invoke(Sub() Button3.Enabled = True)
            Dim foo As New but3ondel(AddressOf turnBut3On)
            Me.Invoke(foo)
        End Sub
    Do you need another thread for taking the picture? It doesn't sound like it, but I can't be certain. It seems that with what you have you know in the existing backgroundworker that the motion has stopped, so just take the picture and then continue on.

    Where are you?(country) Is this for work?
    I'll begin with the end: I live In France but have an Irish father and what about yourself? Its for a uni lab, so yeah its for "work".

    The commands appended in one string is what I was doing In my former VB, and it did work well. I passer the parameter the same way you did, just a string argument to serialport.write(). And the controller answered everytime. It was once the serialport.write() was In the loop that the problems appeared.

  35. #35
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by LiamC View Post
    I'll begin with the end: I live In France but have an Irish father and what about yourself? Its for a uni lab, so yeah its for "work".

    The commands appended in one string is what I was doing In my former VB, and it did work well. I passer the parameter the same way you did, just a string argument to serialport.write(). And the controller answered everytime. It was once the serialport.write() was In the loop that the problems appeared.
    I was just curious because it seemed like there was a time lag. I live in the central USA, Missouri. Does each command you send have an identifiable response?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  36. #36

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by dbasnett View Post
    I was just curious because it seemed like there was a time lag. I live in the central USA, Missouri. Does each command you send have an identifiable response?
    Yeah I noticed the hour of your answers were only during my afternoons so roughly it meant somewhere in the USA

    The wait commands do not provoke answers, neither do the motion commands. On the contrary, motion status and position status do.

    Cheers !
    Last edited by LiamC; Oct 2nd, 2013 at 01:55 AM.

  37. #37
    Addicted Member
    Join Date
    Nov 2011
    Posts
    223

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Do you have handshaking enabled and implemented for the serial port.

  38. #38
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by Mc_VB View Post
    Do you have handshaking enabled and implemented for the serial port.
    Did the documentation specify any? If so it should be. Good catch!
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  39. #39
    Addicted Member
    Join Date
    Nov 2011
    Posts
    223

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    This is the note from the Newport manual,I am not familiar enough with hardware handshaking to be able to implement it perhaps you can.

    COMMUNICATION PROTOCOL
    The RS-232C interface must be properly configured on both devices communicating. A correct setting is one that matches all parameters (baud rate, number of data bits, number of stop bits, parity type and handshake type) for both devices.
    NOTE
    The ESP RS-232C configuration is fixed at 8 data bits, no parity, and 1 stop bit (Baud rate factory default = 19200) - can not be changed by user.
    To prevent buffer overflow when data is transferred to the ESP controller input buffer, a CTS/RTS hardware handshake protocol is implemented. The host terminal can control transmission of characters from the ESP by enabling the Request To Send (RTS) signal once the controller’s Clear To Send (CTS) signal is ready. Before sending any further characters, the ESP will wait for a CTS from the host.
    As soon as its command buffer is full, the controller de-asserts CTS. Then, as memory becomes available because the controller reads and executes commands in its buffer, it re-asserts the CTS signal to the host terminal.

  40. #40

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

    Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200

    Quote Originally Posted by Mc_VB View Post
    This is the note from the Newport manual,I am not familiar enough with hardware handshaking to be able to implement it perhaps you can.
    I did check the settings in the manual, but as far as handshaking is concerned I'm not sure how to handle it with VB.NET. I did find the handshake parameter on the serialport object. The available options are: NONE, XOnXOff, RequestToSend and RequestToSendXOnXOff. After reading the paragraph Mc_VB pasted here, I think we should have a look around the "RTS" signal and how to set it up between VB and the ESP301 controller.

    Parity, StopBits, BaudRate, and all are configured properly. If the COM port is connected at let's say 9600bds (instead of 19200) it doesn't get the commands at all. I've done all these small tests (apart from handshaking) at the start.

    Thanks for bringing the point Mc_VB !
    Last edited by LiamC; Oct 2nd, 2013 at 02:03 AM.

Page 1 of 3 123 LastLast

Tags for this Thread

Posting Permissions

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



Click Here to Expand Forum to Full Width