VB 2005 and BS2 -- why won't the signal stop after I close connection?
tbare
Posts: 13
Here's a pretty basic question with probably a very easy answer.
I'm using the BoE - USB version
End goal: capture impressions from a press. The press will close a circuit each time there's an impression.
Currently, I'm simulating my press w/ one BS2 with the following code:
When I click "Stop," however, the counter in my program stops, but the red light keeps blinking telling me that the BoE is still sending the signal to the app. How do i tell the BS2 to stop running the code OR tell it to stop sending the info to through to the USB port?
Any help would be greatly appreciated - my more complex app is crashing when i hit stop if i keep sending a signal to the computer (impressions are still occurring), even if I 'Close' the connection...
I'm stuck.
TIA!
I'm using the BoE - USB version
End goal: capture impressions from a press. The press will close a circuit each time there's an impression.
Currently, I'm simulating my press w/ one BS2 with the following code:
' {$STAMP BS2} ' {$PBASIC 2.5} Flash: 'subroutine labeled Flash DEBUG "*" HIGH 1 'turn on PAUSE 20 LOW 1 'turn off PAUSE 313 'wait 1/3 second GOTO Flash 'go back to the rest of the programand the second BS2 is capturing it that signal like so:
' {$STAMP BS2} ' {$PBASIC 2.5} btnwrk VAR Byte Btn PIN 0 Main: BUTTON Btn, 1, 255, 20, btnwrk, 0, No_Press : DEBUG "*" 'send * to output for each impression No_Press: GOTO Main 'Start back at the beginningI've got a simple VB .NET app that i'm using for testing:
Imports System Imports System.IO.Ports.SerialPort Imports System.IO.Ports Imports System.Threading Public Class Form1 Delegate Sub SetTextCallback(ByVal [text] As String) 'to change the text of Pause button w/o errors Public WithEvents COMPort As New System.IO.Ports.SerialPort Public Counter As Integer = 0 Public PortAvailable As Boolean = False Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim ports As String() = GetPortNames() ' Check each available COM port for specified port Dim port As String For Each port In ports If port = "COM5" Then COMPort.PortName = "COM5" COMPort.BaudRate = 2400 COMPort.DataBits = 8 COMPort.Parity = IO.Ports.Parity.None COMPort.StopBits = IO.Ports.StopBits.One PortAvailable = True End If Next port If PortAvailable Then Else MsgBox("COM5 not available") End End If End Sub Private Sub SerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles COMPort.DataReceived Counter += 1 Call updateText(Counter) If Counter Mod 200 = 0 Then COMPort.Close() COMPort.Open() End If End Sub Private Sub updateText(ByVal [Text] As String) If Me.lblComOut.InvokeRequired Then Dim d As New SetTextCallback(AddressOf updateText) Me.Invoke(d, New Object() {[Text]}) Else Me.lblComOut.Text = [Text] End If End Sub Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click If COMPort.IsOpen = False Then COMPort.Open() End If End Sub Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click If COMPort.IsOpen = True Then COMPort.Close() End If End Sub End ClassCurrently, when I start the program up, I have to click start to start receiving the signal - perfect.
When I click "Stop," however, the counter in my program stops, but the red light keeps blinking telling me that the BoE is still sending the signal to the app. How do i tell the BS2 to stop running the code OR tell it to stop sending the info to through to the USB port?
Any help would be greatly appreciated - my more complex app is crashing when i hit stop if i keep sending a signal to the computer (impressions are still occurring), even if I 'Close' the connection...
I'm stuck.
TIA!
Comments
Otherwise send a message to STAMP2 when you click the Stop button. Stamp 2 will need to look for the message and turn off/on accordingly.
additionally, if i do just "turn off the stamp," when i turn it back on, it goes right back to what it was doing. The only way to get it to stop is to unplug the usb cable, and plug it back in.
what is the code to turn off / on the stamp? that is more or less what i'm looking for.
Jeff T.
As a complete self-proclaimed rookie, and being under a relative time-crunch, how would i do something like the following:
IF SERIN ... [DEC 1]
loop and output for each impression -- probably use similar BUTTON code that i currently have
UNTIL SERIN [DEC 2]
basically, once it receives a 1, look for button presses until it receives a 2, then wait for the next 1...
Any push in the right direction (or flat out code) would be greatly appreciated... they're wanting this thing done as quick as possible (and they asked the new guy whom they knew had no experience with EEPROMs to do it..)
EDIT:
forgot to mention that i've looked at the Nuts & Volts chapter on Serin & Serout dmystified, as well as several other pages, but am running out of time on this.. I am trying to learn, promise!
The VB logic needs to resend 0x30 (anything other than 0x31) if the acknowledge character is not received within some period of time (timeout). Once "!" is received then proceed to close the port. The STAMP does not handle parallel tasks. It could be working on something else when the VB app sends the stop command.
When you open the port, send 0x31 until the "!" is received.
Notice the PBasic logic is echoing the command. That's because you're listening for the Data_ Received event which is executing on a secondary thread. When you see a "!" the next byte is the last command. I'd roll up a listener (delegate) in the button close/open event and fire off an event when the "!" is received. You can also save the state of which button was pressed, then when you see the "!", read the state and handle.
You could poll the serial port over using the SerialPort.DataReceived event. Polling will be a little easier.
[Edit]: This is .NET source I used for testing cross platform serial port communication. It uses a timer to poll the serial port because Mono (on Linux) does not implement the DataReceived event. It's C# though.
I'm guessing that you're closing the port after 200 DataReceived events to clear the receive buffer? You're asking for trouble. Also there is not guarantee that impression count = DataReceived count. Consider reading the buffer and making a decision on the data received.
Thanks again for all the help! again, being a rookie in a new game is always difficult.
Anyway, the .NET and PBasic code provided has what you need to complete the project. Did you, by chance, run the code?
If I run into anything else, I'll post back.
again, the help is MUCH appreciated!
EDIT - I got pulled onto a more pressing project -- i haven't been working on this non-stop since my last post.. just throwin' that out there...
here's my stop code, though:
and here's my BASIC stamp:
Any thoughts as to what may causing this, and a good solution to bypass it w/out a msgbox? I've tried a thread.sleep(4000), but it doesn't help... I'm sure i could do a loop for a few seconds, but that seems like a bad work-around.
Thanks!
I'm guessing you're having a problem understanding multi-threaded applications. It's hard to tell with out seeing all your code.
Change the baud to 2400 max (16780) and remove the DEC formatter from [DEC result].
and the stamp:
Everything is working as expected now, except the stop - I'll look more into the multi-threading, as i agree that this is probably where i'm having my issues.
like i said, the counter works as expected, just closing the connection doesn't... if I comment out the "COMPort.Close()" line, it works fine, still... but wouldn't that be bad form to leave the connection open like that? seems like a bad idea. I'd much rather open and close the connection for each use.
As far as 2010, i'm pretty sure we have a copy i can use for testing under our ActionPack. I'll check. and converting from C# to VB.NET isn't an issue...
Thanks again for all your help.
1) Counter is counting the number of DataReceived events not the number of impressions from a press!
2) You're receiving data but not reading the data, just plopping it on the screen.
3) The DataReceived handler is operating on a secondary thread while the btnStop_Click handler is invoked for the primary thread.
Clicking the Stop button invokes a write to the serial port from the primary thread. The primary is put to sleep for 5ms but DataReceived handler is not asleep!
for example
Dim Port_Closing As Boolean=True
When you open the port:-
Port_Closing=False
In you Data Received event:-
If Not Port_Closing Then
****Do your receiving here****
End If
And when you close the port:
Port_Closing=True
add a short delay here to allow time for everything to finish
Jeff T.
2) This is my test app - I don't actually care "what" the information is during the DataRecieved handler - but if there is data recieved, i'm counting it as an impression, adding 1 to a variable, then every 250, writing it out to a database, with a final count written out when the stop button is pushed. - the data doesn't have to be perfect, but it needs to be closer than what they're getting now (which isn't counting any waste at all...)
3) -- let's focus on this one, as it appears to be the bulk of the issue. I'm not very familiar with threading, so my question is how do you know that it's on a secondary thread? Any thoughts on how I would resolve this mistake?
I tried your suggestion w/ the PortClosing boolean, but it still locks, even with a 5 second sleep after i set the boolean to true and before i attempt to close the port.
i'm sure it's still the multi-threading issue - i just don't know how to resolve it.
Thanks.
Remember to assign the COMPort.DataReceived delegate to SerialPort_DataReceived when the Open button is clicked.