-
[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
;)
-
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.
-
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
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
LiamC
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?
-
1 Attachment(s)
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.
-
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)?
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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.
-
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
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
Quote:
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
Mc_VB
I edited the code sample to account for the CRLF
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
Mc_VB
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 !
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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
-
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 !
-
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.
-
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 !
-
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).
-
1 Attachment(s)
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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:
Attachment 105181
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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 :)
-
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
-
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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 :)
-
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 !
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
LiamC
...
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.
- Open the port
- Send a command that causes the object to move
- When it stops you take a picture - I am assuming that there is some data received that indicates stop
- 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?
-
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
Quote:
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
Mc_VB
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..
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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.
- Open the port
- Send a command that causes the object to move
- When it stops you take a picture - I am assuming that there is some data received that indicates stop
- 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 !!!
-
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)
-
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).
-
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 ?
-
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?
-
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
LiamC
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?
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
LiamC
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?
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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 !
-
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
Mc_VB
Do you have handshaking enabled and implemented for the serial port.
Did the documentation specify any? If so it should be. Good catch!
-
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.
Quote:
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
Mc_VB
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 !
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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.
-
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
LiamC
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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).
-
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 ?
-
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
-
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 :)
-
1 Attachment(s)
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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:
Attachment 105447
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.
-
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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
-
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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 ?
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
LiamC
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?
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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:
Quote:
" 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."
Quote:
"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
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.
-
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?
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Can you post your code for the slimmed down version?
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
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.
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
dbasnett
Can you post your code for the slimmed down version?
By slimmed down you mean without a Loop for the 50 positions ?
-
Re: SerialPort VB.NET : Write/buffer/timing and Data Received Event (VS2010 and VS200
Quote:
Originally Posted by
LiamC
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?