Page 2 of 3 FirstFirst 123 LastLast
Results 41 to 80 of 102

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

  1. #41

    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 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.
    I'm not sure I need another thread either. What I do need is a Grab_image function that is going to be stopped while the motion is not finished and that fires when the motion is finished (status=1). In the BCKGND DoWork, can we have another WaitHandle (there is already DataAvailable.WaitOne() ) ? Grab_Image would need to have a Grab_Image.WaitOne() at the start of the function (signaled by the "check_return_string" part) and would need a Send_Command.Set() at the end to specify the Loop of SerialPort.Write() to resume.

  2. #42

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

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

    Here is some of the work I did this morning, haven't test it yet with the controller (not in the lab room):

    Code:
    Option Strict On
    
    ' All the imports are not usueful yet, but I need them afterwards
    
    Imports System
    Imports System.ComponentModel
    Imports System.Threading
    Imports System.IO
    Imports System.IO.Ports
    Imports System.Windows.Forms
    Imports System.Data
    Imports System.Text
    
    
    Public Class SerialPortwBv2
    
        Public strX, strY As String
    
        Public Posx0, Posx1, Posx2, Posx3, Posx4, Posx5, Posx6, Posx7, Posx8, Posx9, Posx10, Posx11, Posx12, Posx13 As String
        Public Posx14, Posx15, Posx16, Posx17, Posx18, Posx19, Posx20, Posx21, Posx22, Posx23, Posx24, Posx25, Posx26 As String
        Public Posx27, Posx28, Posx29, Posx30, Posx31, Posx32, Posx33, Posx34, Posx35, Posx36, Posx37, Posx38 As String
        Public Posx39, Posx40, Posx41, Posx42, Posx43, Posx44, Posx45, Posx46, Posx47, Posx48, Posx49 As String
    
        Public Posy0, Posy1, Posy2, Posy3, Posy4, Posy5, Posy6, Posy7, Posy8, Posy9, Posy10, Posy11, Posy12, Posy13 As String
        Public Posy14, Posy15, Posy16, Posy17, Posy18, Posy19, Posy20, Posy21, Posy22, Posy23, Posy24, Posy25, Posy26 As String
        Public Posy27, Posy28, Posy29, Posy30, Posy31, Posy32, Posy33, Posy34, Posy35, Posy36, Posy37, Posy38 As String
        Public Posy39, Posy40, Posy41, Posy42, Posy43, Posy44, Posy45, Posy46, Posy47, Posy48, Posy49 As String
    
    
        Private Sub Form1_Shown(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Shown
            '
            'Port setup and open
            '
            Dim p() As String = IO.Ports.SerialPort.GetPortNames 'Array p contains ports visible to the system
    
            'Settings here
            With SerialPort1
                .PortName = "COM1"
                .Encoding = System.Text.Encoding.GetEncoding(28591)
                '.DtrEnable = True
                '.RtsEnable = True 		>>>>>>>>> As pointed out by Mc_VB, maybe this should be enabled / setup ?
                .Parity = IO.Ports.Parity.None
                .StopBits = IO.Ports.StopBits.One
                .DataBits = 8
                .BaudRate = 19200
    
            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
    
    
            rtb_ONOFF.BackColor = Color.DarkGreen
    
        End Sub
    
    
    
        Dim sc As Threading.Thread
    
        Private Sub btnSendMultiple_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSendMultiple.Click
    
            btnSendMultiple.Enabled = False
    
            sc = New Threading.Thread(AddressOf SendCmds)
    
            sc.IsBackground = True
            sc.Start()
    
        End Sub
    
    
        Dim cmdDone As New Threading.AutoResetEvent(True)
        Dim SendCommand As New Threading.AutoResetEvent(False)
    
    
        Private Sub SendCmds()
    
            ' Positions (49 : x and y) 
            'X Values:
            Posx0 = "000"
            Posx1 = "020"
            Posx2 = "015"
            Posx3 = Posx2
            Posx4 = Posx2
            Posx5 = Posx2
            Posx6 = Posx2
    
            Posx7 = "010"
            Posx8 = Posx7
            Posx9 = Posx7
            Posx10 = Posx7
            Posx11 = Posx7
            Posx12 = Posx7
            Posx13 = Posx7
    
            Posx14 = "005"
            Posx15 = Posx14
            Posx16 = Posx14
            Posx17 = Posx14
            Posx18 = Posx14
            Posx19 = Posx14
            Posx20 = Posx14
    
            Posx21 = "000"
            Posx22 = Posx21
            Posx23 = Posx21
            Posx24 = Posx21
            Posx25 = Posx21
            Posx26 = Posx21
            Posx27 = Posx21
            Posx28 = Posx21
            Posx29 = Posx21
    
            Posx30 = "-05"
            Posx31 = Posx30
            Posx32 = Posx30
            Posx33 = Posx30
            Posx34 = Posx30
            Posx35 = Posx30
            Posx36 = Posx30
    
            Posx37 = "-10"
            Posx38 = Posx37
            Posx39 = Posx37
            Posx40 = Posx37
            Posx41 = Posx37
            Posx42 = Posx37
            Posx43 = Posx37
    
            Posx44 = "-15"
            Posx45 = Posx44
            Posx46 = Posx44
            Posx47 = Posx44
            Posx48 = Posx44
    
            Posx49 = "-20"
    
            'Y Values:
            Posy0 = "000"
            Posy1 = Posy0
            Posy4 = Posy0
            Posy10 = Posy0
            Posy17 = Posy0
            Posy25 = Posy0
            Posy33 = Posy0
            Posy40 = Posy0
            Posy46 = Posy0
            Posy49 = Posy0
    
            Posy3 = "-05"
            Posy11 = Posy3
            Posy16 = Posy3
            Posy26 = Posy3
            Posy32 = Posy3
            Posy41 = Posy3
            Posy45 = Posy3
    
            Posy2 = "-10"
            Posy12 = Posy2
            Posy15 = Posy2
            Posy27 = Posy2
            Posy31 = Posy2
            Posy42 = Posy2
            Posy44 = Posy2
    
            Posy13 = "-15"
            Posy14 = Posy13
            Posy28 = Posy13
            Posy30 = Posy13
            Posy43 = Posy13
    
            Posy29 = "-20"
    
            Posy5 = "005"
            Posy9 = Posy5
            Posy18 = Posy5
            Posy24 = Posy5
            Posy34 = Posy5
            Posy39 = Posy5
            Posy47 = Posy5
    
            Posy6 = "010"
            Posy8 = Posy6
            Posy19 = Posy6
            Posy23 = Posy6
            Posy35 = Posy6
            Posy38 = Posy6
            Posy48 = Posy6
    
            Posy7 = "015"
            Posy20 = Posy7
            Posy22 = Posy7
            Posy36 = Posy7
            Posy37 = Posy7
    
            Posy21 = "020"
    
    
            ' Position Table definition:
            Dim PosArray(,) As String =
                {{Posx0, Posy0}, {Posx1, Posy1}, {Posx2, Posy2}, {Posx3, Posy3}, {Posx4, Posy4}, {Posx5, Posy5}, {Posx6, Posy6}, {Posx7, Posy7}, {Posx8, Posy8}, {Posx9, Posy9},
                {Posx10, Posy10}, {Posx11, Posy11}, {Posx12, Posy12}, {Posx13, Posy13}, {Posx14, Posy14}, {Posx15, Posy15}, {Posx16, Posy16},
                {Posx17, Posy17}, {Posx18, Posy18}, {Posx19, Posy19}, {Posx20, Posy20}, {Posx21, Posy21}, {Posx22, Posy22}, {Posx23, Posy23}, {Posx24, Posy24},
                {Posx25, Posy25}, {Posx26, Posy26}, {Posx27, Posy27}, {Posx28, Posy28}, {Posx29, Posy29}, {Posx30, Posy30}, {Posx31, Posy31}, {Posx32, Posy32},
                {Posx33, Posy33}, {Posx34, Posy34}, {Posx35, Posy35}, {Posx36, Posy36}, {Posx37, Posy37}, {Posx38, Posy38}, {Posx39, Posy39}, {Posx40, Posy40},
                {Posx41, Posy41}, {Posx42, Posy42}, {Posx43, Posy43}, {Posx44, Posy44}, {Posx45, Posy45}, {Posx46, Posy46}, {Posx47, Posy47}, {Posx48, Posy48}, {Posx49, Posy49}}
    
    
            ' DataTable in DataSet:
            Dim row As DataRow
            Dim i As Integer
    
            ' From POS 1 to 49:
            For i = 1 To 49
    
                ' Filling DataTable:
                row = dTable1.NewRow()
                row("dTKey") = i
                row("dTColPosX") = PosArray(i, 0)
                row("dTColPosY") = PosArray(i, 1)
    
                dTable1.Rows.Add(row)
    
            Next i
    
            ' Filling DataGridView for display:
            DataGridView1.DataSource = dTable1
    
            DataGridView1.Columns(0).DataPropertyName = dTable1.Columns(0).ColumnName
            DataGridView1.Columns(1).DataPropertyName = dTable1.Columns(1).ColumnName
            DataGridView1.Columns(2).DataPropertyName = dTable1.Columns(2).ColumnName
            'DataGridView1.Columns(3).DataPropertyName = dTable1.Columns(3).ColumnName
            'DataGridView1.Columns(4).DataPropertyName = dTable1.Columns(4).ColumnName
            'DataGridView1.Columns(5).DataPropertyName = dTable1.Columns(5).ColumnName
            'DataGridView1.Columns(6).DataPropertyName = dTable1.Columns(6).ColumnName
    
    
            For Each RROOWW As DataRow In dTable1.Rows
    
                'coordinates (Column "X" and Column "Y") for each index (RROOWW):
                strX = CStr(RROOWW("dTColPosX"))
                strY = CStr(RROOWW("dTColPosY")) 'Conversion object to string
    
                'Append Positions to the rest of the commands:
                Dim line_1, line_2, line_3, line_4, line_5 As String
                Dim line_A, line_B, line_C As String
    
                ' Commands definition to send to the controller:
                line_1 = "1TP?;2TP?;WT500;"
                line_2 = "1PA"
                line_3 = "2PA"
                line_4 = "1WS;2WS;WT500;"
                line_5 = "1TP?;2TP?;1MD?;2MD?;WT2000;"
    
                ' String concat:
                line_2 = line_2 & strX & ";"
                line_3 = line_3 & strY & ";"
    
                ' Final command lines to send to the controller (total number of lines to be tested...):
                line_A = line_1 & line_2 & line_3 & line_4 & line_5
                'line_B = line_3
                'line_C = line_4 & line_5
    
                'Dim cmds As New List(Of String)
    
                'cmds.Add(line_A)
                'cmds.Add(line_B)
                'cmds.Add(line_C)
    
                Try
    
                    If isopen.WaitOne(0) AndAlso SerialPort1.IsOpen Then
    
                        'For Each c As String In cmds
    
                        cmdDone.WaitOne()
                        SerialPort1.Write(line_A & vbCrLf)
    
                        'Next
    
                        'Me.Invoke(Sub() btnSendMultiple.Enabled = True) : now that we have a big loop, no need to enable the button again
    
                    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()
    
                ' HERE THE WAITHANDLE SETCOMMAND should be waiting for a signal from the Grab_Image part
                ' to go to the next position:
    
                SendCommand.WaitOne()
    
                Thread.Sleep(5000)
    
            Next RROOWW
    
    
    
        End Sub
    
    
        Private Sub btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click
    
    
            'close port
            isopen.WaitOne()
            SerialPort1.Close()
            rtb_ONOFF.BackColor = Color.Red
    
        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(ByVal sender As Object, ByVal 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 ' byte code for LF char
    
        Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal 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 ?
                    'If 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
    
            ' >>>>>>>> WE CAN CALL THE GRAB_IMAGE FUNCTION HERE OR JUST PASTE THE CODE , RIGHT ?
    
            'emulate function GRAB_IMAGE:
            MsgBox("test de timing apres check_string a l'emplacement de GRAB_IMAGE", MsgBoxStyle.OkOnly, "TEST TIMING")
    
            ' Signals the SendCommand WaitHandle to resume the loop:
            SendCommand.Set()
    
        End Sub
    
    
        Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    
            'This code run on UI ??? I thought RunWorkerCompleted ran on the UI...
    		
            Dim s As String = DirectCast(e.UserState, String) 'get message
            RichTextBox1.AppendText(s & Environment.NewLine)
    
        End Sub
    
    
        Private Sub SerialPort1_ErrorReceived(ByVal sender As Object, _
        ByVal e As IO.Ports.SerialErrorReceivedEventArgs) Handles SerialPort1.ErrorReceived
    
            Debug.WriteLine("ER " & e.EventType.ToString)
    
        End Sub
    
    
        Private Sub SerialPort1_PinChanged(ByVal sender As Object, _
        ByVal e As IO.Ports.SerialPinChangedEventArgs) Handles SerialPort1.PinChanged
    
            Debug.WriteLine("PC " & e.EventType.ToString)
    
        End Sub
    
    
    
    End Class
    The loop is implemented with the positions in the dataTable defined at the start.
    Last edited by LiamC; Oct 2nd, 2013 at 06:10 AM.

  3. #43
    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 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 !
    I would set the serial port to RequestToSend handshaking. Also turn on DTR.
    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

  4. #44

    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 would set the serial port to RequestToSend handshaking. Also turn on DTR.
    Ok, I will try these parameters.

    First, I'm going to test the code with the loop and WaitHandles, plus see how many lines/commands the controller prefers (one line = no list, as done in the code provided, several lines populating a list and list passed to the controller).

  5. #45

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

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

    OK back from the first tests downstairs

    There were a few hick-ups, but I managed to get something close to the actions I wanted:

    * From the code posted in #42:

    - I got rid of the SendCommand WaitHandle for the moment, I haven't managed to use it properly (I think with FALSE in AutoResetEvent it cannot reach the part where I SET() it...But just a guess)
    - With a big uncontrolled loop (position after position without anything in-between) the controller gets too much data and it hangs (somekind of bufferoverflow I guess...)
    - RTS/DTR/Handhsaking did not change the behaviour of the controller from what I saw
    - I put a MsgBox at the end of the big loop, just before NEXT ROW to halt the process and this got rid of the crashing and went through the 49 positions smoothly
    - I kept the "only one string" to SerialPort.Write() with string concatenation and it did work perfectly

    NOW:

    - This is not solid VB programing to put a MSGBOX to have the formal mode and halt the process, it was just to check if it went through the positions and kept updating the richtextbox: it did
    - Where to put some WaitHandles (I'm a bit lost after looking at that code and how it goes from one thread to another, or the way it triggers events) so I have something smooth that waits at the end of every axis motion ?
    - Is it the most practical way to put the GRAB_IMAGE at the end of the BackgroundWorker DoWork if we need to set a waithandle to go back to the SENDCOMMAND part ?
    Last edited by LiamC; Oct 2nd, 2013 at 08:53 AM.

  6. #46
    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

    Keep the DTR and handshaking, especially since it did not cause a bad reaction.

    The code in #42 was a huge step. If I were doing this I would have taken smaller steps, get one entire sequence(move, stop, take picture) working and then added another.

    In the backgroundworker I would have watched for a command response that indicated that the motion had stopped and taken the picture, then set the autoreset for the next command sequence. This requires that the commands being sent end with a command that causes the response I am looking for(motion stopped).

    You have added so much code that it is hard for me to follow, especially since I don't have the equipment, and I am not familiar with the controller. Based on what you have said in this thread I think I would send one command at a time, not send multiple commands per line, at least until I got it working.
    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. #47

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

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

    double post...edited
    Last edited by LiamC; Oct 2nd, 2013 at 09:32 AM.

  8. #48

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

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

    Thanks for the input again,

    I do agree it's a big step, but there aren't that many intermediate in-situ steps to take:

    The first small step you describe (without any loop) is actually working: one entire sequence then wait/take picture.
    I have the response from the controller to the ProgressChanged event (updating the RTB) : it is displaying the "1" for motion status DONE. At every step, so it is working fine.
    The huge chunk of code at the start is only there to define 50 positions, nothing else in it. Then there is a dataTable to store all the positions.
    When the dataTable is set, I'm trying to loop in it, row after row.
    I send only one string line containing the commands and the controller reacts correctly and sends back the answers to the questions I've asked him.

    To my typical string of commands, the controller answers :

    Code:
    0.000            ' what is your X position = 1TP?
    0.000            ' what is your Y position = 2TP?
    1                  ' Has axis X stopped its motion = 1MD?
    1                  ' Has Axis Y stopped its motion = 2MD?
    20.000          ' What is your actual X position now (after motion)?
    0.000           ' What is your actual Y position now (after motion) ?
    I can put the 1MD? command at the end and check for last chars to get the motion status done, that is not a problem now the answers are always the same

  9. #49

    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
    Keep the DTR and handshaking, especially since it did not cause a bad reaction.

    The code in #42 was a huge step. If I were doing this I would have taken smaller steps, get one entire sequence(move, stop, take picture) working and then added another.

    In the backgroundworker I would have watched for a command response that indicated that the motion had stopped and taken the picture, then set the autoreset for the next command sequence. This requires that the commands being sent end with a command that causes the response I am looking for(motion stopped).

    You have added so much code that it is hard for me to follow, especially since I don't have the equipment, and I am not familiar with the controller. Based on what you have said in this thread I think I would send one command at a time, not send multiple commands per line, at least until I got it working.
    Hi,

    I've taken some of your advice and tested some smaller scale things:

    1. One command per line only and have them Added in the list as you did => The controller hangs after the first 3 commands or so. It seems it doesn't like the multiple "vbCr"...
    2. I've ended the line of commands with the motion status command to be able to check the string: works well
    Here is a capture:
    Name:  ScreenCap_1st_Run.JPG
Views: 5168
Size:  65.7 KB

    The red zone is the RTB where the return string is displayed.
    The blue zone is the answer to the motion status question (placed at the end of the string commands)
    The green zone is a Lbl updated after the checking of the string displaying this message if it found the "1" in the string 2 char from the end.

  10. #50
    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

    Does this, "the controller hangs after the first 3 commands or so. It seems it doesn't like the multiple "vbCr"..." mean there is still a problem?

    I can' tell if you are making progress or not.
    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. #51

    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
    Does this, "the controller hangs after the first 3 commands or so. It seems it doesn't like the multiple "vbCr"..." mean there is still a problem?

    I can' tell if you are making progress or not.
    When I choose to write only one command per line and then do the cmds.Add(string) to the list, yes there obviously is an issue between this method and the controller.

    I'm making progress yes. First because the reading of bytes+motion WITH my 50 times LOOP is running correctly. That is already a huge step from what I had. I'm still unsure the RTB displays everything correctly when it begins to stack-up. I will have to check this later. Secondly, the way the return string is verified and then we're still able to move on to the next position is also a step up.

    I'm checking the return string in the ProgressChanged part of the BCKGND Worker, don't know if it's good or not. But in the DoWork, all the chars of the string are not yet appended to the RTB (the variable you named "s") and it's only when it's displayed in the RTB that it is complete. I can then proceed to put it in my "IF" condition:

    Code:
    If s.substring(s.Length-2,1) ="1" Then
    
    updateLabelText("MOTION STATUS HAS BEEN VERIFIED = 1")
    
    cmdDone.Set()
    
    Else
    'motion is not complete
    
    updateLabelText("Motion not complete")
    
    End If

  12. #52
    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

    I don't understand what this, "When I choose to write only one command per line and then do the cmds.Add(string) to the list, yes there obviously is an issue between this method and the controller." means. I thought you were adding the commands to the list and then sending the list of commands, one at a time, to 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

  13. #53

    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 don't understand what this, "When I choose to write only one command per line and then do the cmds.Add(string) to the list, yes there obviously is an issue between this method and the controller." means. I thought you were adding the commands to the list and then sending the list of commands, one at a time, to the controller.

    Yes sorry, that's what I meant. The controller doesn't like this, it hangs after the first 2 or 3 lines. Whereas when I pass it all the commands in one line (without a list so to speak), it answers perfectly with the return string we were waiting for.

    For the moment, I'm going with the working method for a single movement and I'm trying to implement the loop, and it causes a lot of troubles...

    1. I don't think ProgressChanged of the BCKGND Worker is the right place to check the return string (that's what I'm doing now)
    I'm doing this to avoid a string length error:

    Code:
    'inside the ProgressChanged:
    Dim s As String=DirectCast(e.userState,String)                                                                       'regather the message from the DoWork: that's your code which is working fine
    RichTextBox1.AppendText(s & Environment.NewLine)                                                              'display the return string in the RTB: that is working fine when I'm NOT using a loop
    
    s1=RichTextBox.Text
    
    If s1.substring(s1.length-2,1) ="1" Then
    
    'Motion complete
    
    etc.
    Here I went for this as I do not have enough char arrived from the controller if I use "s" (ie: I get s.Length-2 < 0 errors)

    But I don't think it's a good method: how and where would you tackle the check string problem ?
    Last edited by LiamC; Oct 3rd, 2013 at 09:44 AM.

  14. #54
    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
    Yes sorry, that's what I meant. The controller doesn't like this, it hangs after the first 2 or 3 lines. Whereas when I pass it all the commands in one line (without a list so to speak), it answers perfectly with the return string we were waiting for.
    Is there anything in the documentation about sending commands one at a time? What does hang mean? Any two or three commands or specific sequences?
    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. #55

    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
    Is there anything in the documentation about sending commands one at a time?
    Nothing about sending one command nor about the delay. but some useful information:

    " Remember that commands must be terminated with a carriage-return (ASCII 13 decimal). Until a terminator is received, characters are simply kept in contiguous buffer space without evaluation."


    "To prevent buffer overflow when data is transferred to the ESP301
    controller input buffer, a CTS/RTS hardware handshake protocol is
    implemented. The host terminal can control transmission of characters
    from the ESP301 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."


    Quote Originally Posted by dbasnett View Post
    What does hang mean? Any two or three commands or specific sequences?
    Hang means that it stops responding and that i doesn't process the next command.
    After the first 2 or the first three commands, it stops responding. The following commands which both happen to be the motion commands (first 2 are the positions questions).

    I've edit my previous post aswell.
    Last edited by LiamC; Oct 3rd, 2013 at 09:37 AM.

  16. #56
    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 you get responses to the position commands?

    Does every command have a response?

    What is the longest amount of time between a command being sent and a response?

    And keeping the goal in mind, how long does it take to capture the image?

    The autoresetevent as an overload that is a timeout in ms. In the WaitOne add 10000 (10 seconds) i.e. cmdDone.WaitOne(10000) and see what happens. http://msdn.microsoft.com/en-us/library/cc189907.aspx

    Did you leave DTR=TRUE and HandShaking=RTS/CTS?
    Last edited by dbasnett; Oct 3rd, 2013 at 09:52 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

  17. #57
    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

    Can you post your code for the slimmed down version?
    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

  18. #58

    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 you get responses to the position commands?

    Does every command have a response?
    NO. The MOVE commands and the WAIT commands (resp. 1PA/2PA and WS/WT500 for example) do not trigger a response from the controller.
    But for all the commands that actually trigger a response, I do have an incoming response with a single position (ie. no loop).

    What is the longest amount of time between a command being sent and a response?
    Between the commands that require the longest amount of time: going from 1PA0 (start) to 1PA20 (first position on the X axis). It takes approx. 5 sec to do +20 on the X axis and approx. 7sec to do +20 on the Y axis. Those are the steps that require the longest amount of time.

    And keeping the goal in mind, how long does it take to capture the image?
    It takes rather long. Because there are user actuated buttons and a processing function. I'd say around 1min total.

    The autoresetevent as an overload that is a timeout in ms. In the WaitOne add 10000 (10 seconds) i.e. cmdDone.WaitOne(10000) and see what happens.
    Ok, I'm going to watch the effect on this param.

    Did you leave DTR=TRUE and HandShaking=RTS/CTS?
    I left it on enabled for DTR yes, and handshaking on RequestToSend. Do I have an access to CTS options ?
    I answered in the quote.
    Last edited by LiamC; Oct 3rd, 2013 at 09:59 AM.

  19. #59

    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
    Can you post your code for the slimmed down version?
    By slimmed down you mean without a Loop for the 50 positions ?

  20. #60
    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
    By slimmed down you mean without a Loop for the 50 positions ?
    Generally when I have a problem I try to make the simplest test case that shows the problem. If it takes a loop with 50 then so be it, though I would prefer less.

    The code I provided made assumed that every command caused a response, but since it doesn't...

    edit: Can you explain the format of the commands?
    Last edited by dbasnett; Oct 3rd, 2013 at 10:22 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

  21. #61

    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
    Generally when I have a problem I try to make the simplest test case that shows the problem. If it takes a loop with 50 then so be it, though I would prefer less.

    The code I provided made assumed that every command caused a response, but since it doesn't...

    edit: Can you explain the format of the commands?
    I removed the loop and got back to what I had. I hope I did not left too many errors with my loop removal.
    The code is thus intended for one unique position, here X=20,Y=10.

    The commands are explained in comments in the code.

    Thank you again !

    Here is the code which is mainly yours in the end. I added : just a bunch of commands and a string verification + a label update to check I was in the right place of the IF condition during the string verification:

    Code:
    Option Strict On
    
    ' All the imports are not usueful yet, but I need them afterwards
    
    Imports System
    Imports System.Threading
    Imports System.IO
    Imports System.IO.Ports
    
    
    Public Class SerialPortwBv2
    
    
        Private Sub Form1_Shown(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Shown
            '
            'Port setup and open
            '
            Dim p() As String = IO.Ports.SerialPort.GetPortNames 'Array p contains ports visible to the system
    
            'Settings here
            With SerialPort1
                .PortName = "COM1"
                .Encoding = System.Text.Encoding.GetEncoding(28591)
                .DtrEnable = True
                .RtsEnable = True 		'>>>>>>>>> As pointed out by Mc_VB, maybe this should be enabled /setup ?
                .Parity = IO.Ports.Parity.None
                .StopBits = IO.Ports.StopBits.One
                .DataBits = 8
                .BaudRate = 19200
    
            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
    
    		' coloured indicator for the serialport connection
            rtb_ONOFF.BackColor = Color.DarkGreen
    
        End Sub
    
    
    
        Dim sc As Threading.Thread
    
        Private Sub btnSendMultiple_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSendMultiple.Click
    
            btnSendMultiple.Enabled = False
    
            sc = New Threading.Thread(AddressOf SendCmds)
    
            sc.IsBackground = True
            sc.Start()
    
        End Sub
    
    
        Dim cmdDone As New Threading.AutoResetEvent(True)
    
    
        Private Sub SendCmds()
    
            
                ' Command definition
                line_1 = "1TP?;2TP?;WT500;" 				' What is the X Position ? ; What is the Y Position ? ; Wait 500ms
                line_2 = "1PA20;"							' GoTo 20 on axis X ; 
                line_3 = "2PA10;"							' GoTo 10 on axis Y ;
                line_4 = "1WS;2WS;WT500;"					' Wait for Axis X to stop ; Wait for axis Y to stop ; Wait 500ms
                line_5 = "1TP?;2TP?;1MD?;2MD?;WT2000;"		' Position X ? ; Position Y ? ; Has axis X stopped ? ; Has axis Y stopped ? ; Wait 2 secs
    
               
                ' Final command lines to send to the controller (total number of lines to be tested...):
                line_A = line_1 & line_2 & line_3 & line_4 & line_5
                
    
                Try
    
                    If isopen.WaitOne(0) AndAlso SerialPort1.IsOpen Then
    
    
                        cmdDone.WaitOne()
                        SerialPort1.Write(line_A & 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 btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click
    
            'close port
            isopen.WaitOne()
            SerialPort1.Close()
    		
            rtb_ONOFF.BackColor = Color.Red
    
        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(ByVal sender As Object, ByVal 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 ' byte code for LF char
    
        Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal 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 ?
                    'If 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(ByVal sender As Object, ByVal 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)
    
    		
    		' RETURN STRING VERIFICATION:
    		' 4 and 2 char from the END we SHOULD FIND a "1" meaning both axis motion status are = 1, ie: STOPPED.
    		
    		
    		
    		'If I use "s" instead of "s1" it has to few chars at the beginning so I get an error with the Length minus 2 or 4 chars:
    		
    		Dim s1 As String
    		s1=RichTextBox1.Text
    		
    		If s1.substring(s1.Length-2,1)="1" AndAlso s1.substring(s1.Length-4,1)="1" Then
    		
    		'motion complete:
    		updateText("MOTION STATUS HAS BEEN VERIFIED=1")
    	
    		'I Don't think it's the right place to set the WaitHandle, but it made sense to put it only after the string is verified:
    		'I GUESS THE LINK TO THE GRAB_IMAGE WILL BE HERE
    		cmdDone.Set()
    	
    		Else
    		
    		'motion NOT complete:
    		updateText("MOTION NOT COMPLETE")
    		
    		End If
    		
    	
    	End Sub
    
    	
    	Delegate Sub SetTextCallback(ByVal [text] As String)
    
    
        Public Sub updateText(ByVal [text] As String)
    
            If Me.Label1.InvokeRequired Then
    
                Dim x As New SetTextCallback(AddressOf updateText)
    
                Me.Invoke(x, New Object() {(text)})
    
            Else
                Me.Label1.Text &= [text] & vbCrLf
            End If
    
        End Sub
    	
    	
        Private Sub SerialPort1_ErrorReceived(ByVal sender As Object, _
        ByVal e As IO.Ports.SerialErrorReceivedEventArgs) Handles SerialPort1.ErrorReceived
    
            Debug.WriteLine("ER " & e.EventType.ToString)
    
        End Sub
    
    
        Private Sub SerialPort1_PinChanged(ByVal sender As Object, _
        ByVal e As IO.Ports.SerialPinChangedEventArgs) Handles SerialPort1.PinChanged
    
            Debug.WriteLine("PC " & e.EventType.ToString)
    
        End Sub
    
    
    
    End Class

  22. #62
    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

    Many posts ago we resolved the issues with serialport communications. (One thing, you still do not have handshaking set.)

    What we are left with is the protocol of the controller. Some things confuse me.

    Does the controller execute one command at a time. i.e. If you tell it to move is the next command delayed until it completes the movement?

    What is the purpose of the wait commands? It seems like they are for writing programs on the controller and serve no purpose if you are doing remote control.

    Let me ask this again. Is the purpose of this application to move the device to a certain location and then take an image? Is there anything else?
    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

  23. #63

    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
    Many posts ago we resolved the issues with serialport communications. (One thing, you still do not have handshaking set.)
    And I thank you for that big step !

    What we are left with is the protocol of the controller.

    Some things confuse me.

    ME too, I hope this controller has no random behaviour because there are some issue with timings.

    Does the controller execute one command at a time. i.e. If you tell it to move is the next command delayed until it completes the movement?
    No. That's the purpose of "1WS;" for example, ie: wait for axis 1 to stop before next command. Or if I write "1PA20;2PA10;" the motion of both axis is almost started at the same time, not sequential at all.

    What is the purpose of the wait commands? It seems like they are for writing programs on the controller and serve no purpose if you are doing remote control.

    If I don't put a wait 500ms, the next couple of commands are processed too quickly and when I ask the position for example, the axis has not reach its destination.

    Let me ask this again. Is the purpose of this application to move the device to a certain location and then take an image? Is there anything else?

    Yes it the sole purpose. Move to position N, grab a frame, process this frame, move to position N+1, etc...
    Answered in between the quotes.
    Last edited by LiamC; Oct 3rd, 2013 at 02:26 PM.

  24. #64
    Addicted Member
    Join Date
    Nov 2011
    Posts
    223

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

    Hi Liam, there are a couple of things I don't understand and I am hoping you will enlighten me.


    The following code snippet builds the final command string if I understand correctly.

    ' Command definition
    line_1 = "1TP?;2TP?;WT500;" ' What is the X Position ? ; What is the Y Position ? ; Wait 500ms
    line_2 = "1PA20;" ' GoTo 20 on axis X ;
    line_3 = "2PA10;" ' GoTo 10 on axis Y ;
    line_4 = "1WS;2WS;WT500;" ' Wait for Axis X to stop ; Wait for axis Y to stop ; Wait 500ms
    line_5 = "1TP?;2TP?;1MD?;2MD?;WT2000;" ' Position X ? ; Position Y ? ; Has axis X stopped ? ; Has axis Y stopped ? ; Wait 2 secs


    ' Final command lines to send to the controller (total number of lines to be tested...):
    line_A = line_1 & line_2 & line_3 & line_4 & line_5
    1TP?,2TP?,1MD? and 2MD? are all commands that will respond yet I don't see where the response is being handled, are they used somewhere in a decision loop? In a loop x 50 there would be 300 such responses.

    If the above is in a loop 1TP? and 2TP? are requested twice in succession, would this be necessary?

    The command line has a ~3 second total delay which means any commands that follow cannot be processed for 3 seconds, so for 3 seconds the buffer fills unless the flow control is working correctly. This comment is more of a "thinking out loud" moment, it is something I could see as being potential problem. Are all the delays needed.

    Do you have a sequence of operation, I see it like this, would this be right?

    1./ transmit next move (1PAnn;2PAnn <CR>) //transmit command

    2./ loop until the move is done (1MD?;2MD? <CR>) //transmit command, no timer needed just keep sending until true is received

    3./ process response (true/false) //receive response

    4./ false goto #2

    5./ check position (1TP?;2TP <CR>) //transmit command

    6./ if position is correct aquire image //receive response

    7./ if not completed goto #1

    I wrote this before I realized the question about the time delays had been asked but I have left it as is. I saw where you were using delays to wait for a response, using the above sequence would this not eliminate the need for the timers?

  25. #65

    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
    Hi Liam, there are a couple of things I don't understand and I am hoping you will enlighten me.


    The following code snippet builds the final command string if I understand correctly.



    1TP?,2TP?,1MD? and 2MD? are all commands that will respond yet I don't see where the response is being handled, are they used somewhere in a decision loop? In a loop x 50 there would be 300 such responses.
    I check 1md and 2md responses. for the moment tp? are just displayed so i can check the accuracy of the motion.

    If the above is in a loop 1TP? and 2TP? are requested twice in succession, would this be necessary?
    one before motion, the other after the motion, bringing the start and destination position of the motion resp. But of course in a loop, there's one too many.

    The command line has a ~3 second total delay which means any commands that follow cannot be processed for 3 seconds, so for 3 seconds the buffer fills unless the flow control is working correctly. This comment is more of a "thinking out loud" moment, it is something I could see as being potential problem. Are all the delays needed?
    good question and one of the dark area for me...

    Do you have a sequence of operation, I see it like this, would this be right?

    1./ transmit next move (1PAnn;2PAnn <CR>) //transmit command

    2./ loop until the move is done (1MD?;2MD? <CR>) //transmit command, no timer needed just keep sending until true is received

    3./ process response (true/false) //receive response

    4./ false goto #2

    5./ check position (1TP?;2TP <CR>) //transmit command

    6./ if position is correct aquire image //receive response

    7./ if not completed goto #1

    I wrote this before I realized the question about the time delays had been asked but I have left it as is. I saw where you were using delays to wait for a response, using the above sequence would this not eliminate the need for the timers?

    Well, I like ur way of thinking in the command sequence, maybe it's more solid with the controller behaviour/results that way.I did not try it yet
    answers before I hit the sack !

  26. #66
    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

    Thinking out loud... Maybe the answer is to build a class that is the controller, or at least mimics the behavior. This class would have only a couple of commands(methods), like Stop and Move. It would mimic the behavior that McVb suggested and be in control of the SerialPort totally.
    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. #67

    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
    Thinking out loud... Maybe the answer is to build a class that is the controller, or at least mimics the behavior. This class would have only a couple of commands(methods), like Stop and Move. It would mimic the behavior that McVb suggested and be in control of the SerialPort totally.
    It seems a good idea, to go along the actions of the controller with several methods. Just that a class construction seems a tad out of my reach in terms of coding capacity atmo, even if it's maybe not that difficult to understand in the end...

    The only tweak I would see with the sequence Mc_vb proposed is with the position checking. The axis move with an accurate position of 3 digits after the decimal (20.000). And we have an acceptance on this position, ie: 19.996 is allright for example (difference <0.005). Otherwise the order of commands seems perfect.

  28. #68

    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,

    I'm doing just what mc_VB proposed right now (and for the last 2 days of last week). I've sequenced it with buttons for the user to click: each method has its own button (move, verify motion stop, verify position, grab image) and I just disable/enable the buttons for the user atmo.

    I just have a practical VB/.NET question here :

    - I'd like to update a control of the UI outside the UI , but not just the text (for exemple the background colour of a ritchtextbox, or sthg else). I managed to do it with the text by creating a function named updateText, using a Delegate sub and an InvokeRequired on the text zone. I'd like to find an example of passing other input parameters than just text from outside de UI which created the control.

    To put it in the context of my application:

    In the Data Received event I either check for a "1" char at the end of a string which length is < 3 (just asked for both "MD?" commands, answer is "11" or "00" or "10" / "01", so strictly inferior to 3 characters) or I get the position from a longer string (answer is maybe "15.000<Cr>-5.000" which is always > 3 char long).

    - In the first case I would like to put a visual mark on the UI , fro example the back colour of a rtb to GREEN, with the "OK" mention in it (for the text part I found a way)
    - In the second case, I'd like to pass the positions (after parsing) from the DataReceived Event to the UI thread to compare them with the expected positions


    What's the quickest method and best approach to these two tasks ? (I used the background worker and the progresschanged event before, but maybe we should do something more appropriate)



    Thx !

    [EDITED] I kinda answered my questions this morning But would still like to see your inputs on this if possible.

    With:

    Code:
    Me.Invoke( New Eventhandler(AddressOf DoPOSITIONUpdate))
    Placed in the Datareceived


    and the sub declaration:

    Code:
    Public Sub DoPOSITIONUpdate (ByVal sender As Object, ByVal e As System.EventArgs)
    
    txtRETURNS.text= AnalyzedString
    
     '  parsing...
    txtPOSX.text = ParsedPart1
    txtPOSY.text = ParsedPart2
    
    ' Comparing strings...
    
    if ABS(ParsedPart1 - XexpectedValue) < 0.006 AndAlso ABS(ParsedPart2 - YexpectedValue) < 0.006 then
    
    ' position is ok
    
    else
    
    'error
    
    End Sub
    Last edited by LiamC; Oct 7th, 2013 at 04:17 AM.

  29. #69
    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

    The reason I didn't put an Invoke in the DataReceived was because only one SerialPort event can fire at a time. For this app it probably won't make a difference.
    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. #70

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

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

    OK, thanks for the technical explanation dbasnett !

    1. And what's the difference between Encoding.Getchars() and Encoding.GetString() methods ? (further down in the code, you used a bytes[ ] to Array of Char conversion with GetChars() )

    2. I'm removing the part where the code checks for a LineFeed and cuts the bytes sequence at this point to get a string. I'm doing this because I now send only two commands, get the result, analyse the response and go to next step (as hinted by mc_VB).
    Thus, I need the entire response now and to not cut the array at the first LF found (as we did before). Is it better to provide the length of the bytes Array in GetChars() along the array and the start index ? Or can we just give the GetChars() method the bytes array as a single argument ?

  31. #71
    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
    OK, thanks for the technical explanation dbasnett !

    1. And what's the difference between Encoding.Getchars() and Encoding.GetString() methods ? (further down in the code, you used a bytes[ ] to Array of Char conversion with GetChars() )

    2. I'm removing the part where the code checks for a LineFeed and cuts the bytes sequence at this point to get a string. I'm doing this because I now send only two commands, get the result, analyse the response and go to next step (as hinted by mc_VB).
    Thus, I need the entire response now and to not cut the array at the first LF found (as we did before). Is it better to provide the length of the bytes Array in GetChars() along the array and the start index ? Or can we just give the GetChars() method the bytes array as a single argument ?
    1. GetChars is slightly faster in some cases. You can use either one for this.

    2. If you are expecting multiple responses why not leave the code as is and add each response to a list of string. When the count of the list matches the desired amount, two in this case, process the list and then clear it. On the other hand if you know exactly what the string length will be every time you could do it your way.
    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. #72

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

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

    Ha, nice catch on the 2nd answer, I prefer your way !

    Because I don't know exactly the length...And this is why: this stupid controler responds "20.000" for a position, "0.000" for another position and "-15.000" for a third one. Resulting in 3 different lengths of string...
    This afternoon I was trying to parse the two combined answers at specific chars positions: find the first "CR" char, cut the first string. Then, find the first "LF" char, that is where the second position string should be starting, and cut when the second "CR" is found.
    I don't know how to optimize this without going your way with the 2 counts in a list.

  33. #73
    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 long as you know the order one list should suffice.
    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. #74

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

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

    Yes, one list with two items that I add, each being a response of the controler.

    (Here I'm at home atmo) I just recall that the SerialPort.Read() was done by counting bytes to read and then putting these bytes in a list (and added with dataByts.AddRange(b) ).This would later be converted with GetChars() to a string.
    Is there another way I can separate the 2 incoming commands responses other than look for a Cr/Lf within the bytes "stream" because I can only see this as the way to go ?
    Last edited by LiamC; Oct 7th, 2013 at 01:51 PM.

  35. #75
    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

    I am lost. Didn't you have the code working were each response was already a separate string? If you send one of your two commands, get the response and store it in a List(Of String), then the second, and store it in the list what else do you need?
    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. #76

    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 am lost. Didn't you have the code working were each response was already a separate string? If you send one of your two commands, get the response and store it in a List(Of String), then the second, and store it in the list what else do you need?
    Again I typed a fast message from home and it wasn't very clear, my apologies.

    I separated the methods, ie: each method is in the click event of a button for the user of the optical experiment. But one method contains several commands: "1MD?;2MD?;" or "1PA10;2PA-5;" for example.
    So in my earlier message what I meant was that I was getting 2 responses, one for each command contained in the method.

    Now I'm separating the commands, ie: one serialport.write() for each command that triggers a response (SerialPort.Write("1MD?;") and Serialport.Write("2MD?;") later, for example).
    With this, I can still use the "LF" separator as a way to parse the command response from the message sent back by the controler and then populate a list as you said.
    I then will wait for the list.count to be >1 (wait for the second message, am I correct ?) to go further and compare both list(0) and list(1) with the positions we were waiting for.
    These positions are stored in a datatable.

    Is it clearer ?

  37. #77
    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

    Yes it is.
    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

  38. #78

    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
    Yes it is.
    Does it seem like a correct way to work on ?

    I will have access to the controller and cameras this afternoon and will do some tests of what I've written in VB.

  39. #79
    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

    With your mc_vb approach and this, yes.
    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

  40. #80

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    144

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

    In the case were we would only use one serialport.write to avoid 2 iterations of serialdata received event, how would you parse a string like this one:

    Code:
    response = 20.000{CR}{LF}0.000{CR}{LF}
    knowing that the number of useful characters (positions) can change the next time a response is triggered by a user click on the "verify position" button ?

Page 2 of 3 FirstFirst 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