Comm32 Logo
Home Button  Buy Button 

Topic:   Troubles with the CommEvent = comEvEvtChar

By: Jay ZebrykPosted on: Apr 2 2020 at 04:10:03 PM
I am trying to create a hybrid version of a OnComm Event with in-line code.

Can do either the above fine, but not the hybrid.

In all cases, the code is looking for a ASCII 10 Line Feed termination character.

For the In-Line version, this works: (Grabs the whole string received upto the LF character.)

SComm1.CommPort = 5
SComm1.Settings = "9600,N,8,1"
SComm1.PortOpen = True

---------
Function Receive() As String

Do
Buffer = Buffer & SComm1.Input ' Adds to Buffer each Loop
If InStr(Buffer, vbLf) Then ' Looks for LF Inside String
Exit Do ' If found, jumps out.
End If
Wait 10 ' Wait About 1mS Per Character @9600BPS
Loop

Buffer = Replace(Buffer, vbLf, "") ' Removes the Line Feed character
Receive = Buffer ' Stuffs the Buffer into the Receive Return
Debug.Print Receive

End Function
---------

For the OnComm version this also works fine: (Triggers nicely on the LF character.)

SComm1.CommPort = 5
SComm1.Settings = "9600,N,8,1"
SComm1.PortOpen = True
SComm1.RThreshold = 1
SComm1.EvtCharEnable = True
SComm1.EvtChar = 10

---------
Private Sub SComm1_OnComm()
Receive = SComm1.Input
Receive = Replace(Receive, vbLf, "")
Debug.Print Receive
End Sub
---------

Having troubles combining the above to waiting for a LF termination character without testing
each character incoming to the input buffer.

SComm1.CommPort = 5
SComm1.Settings = "9600,N,8,1"
SComm1.PortOpen = True
SComm1.RThreshold = 1
SComm1.EvtCharEnable = True
SComm1.EvtChar = 10

---------
Function Receive() As String

Do
If SComm1.CommEvent = comEvEvtChar Then
Exit Do
End If
Wait 10
Loop

Receive = SComm1.Input

End Function
---------

The above just hangs.
Have tried a number of iterations of the above without success.

Note: All of the above run in little isolated test apps created just for debugging this.

By: Jay ZebrykPosted on: Apr 3 2020 at 11:31:43 AM
Up-Date
Doing more experimentation, with lots of Debug.Print statements, I have concluded the EvtChar function is broken, or, more likely, I have really missed something big.
Observations:
1. Although the CommEvent fires, with EvtCharEnable = True, it does so regardless of changing the EvtChar to anything.
2. Setting RThreshold = 1, the CommEvent never fires even with the correct EvtChar.
3. Debug.Print comEvEvtChar produces (8) which would be next in order after the EOF event # 7?

FYI, I also have USB-Serial SPY diagnostic running so I can see what is actually being sent and received.
The (2) USB-Serial Modules are both FTDI "genuine" devices.

I am trying to work this backwards to some known good condition but am stalled.
I would be very interested in an example of how to check/test this out.
Is SComm1.CommEvent = comEvEvtChar valid, or does the comEvtChar have a numeric code to be used instead?

Thanks!

By: Jay ZebrykPosted on: Apr 3 2020 at 11:34:25 AM
TYPO!
2. Setting RThreshold = 1, the CommEvent never fires even with the correct EvtChar.
Should have been RThreshold = 0
(According to the manual, this should work.)

By: Jay ZebrykPosted on: Apr 7 2020 at 05:14:54 PM
Considering that I need to immediately process the response to a Polled transmission in a tight loop, might disabling SComm1.OverlappedIO feature allow the EvtChar feature to function properly?

By: GuestPosted on: Apr 8 2020 at 02:54:05 AM
You said your first 2 methods work. So why the third Hybrid method? Don't either of the first 2 work for you?

When do you call that receive() function in your hybrid code? If it's your intention to start the application and immediately call that receive() function and wait for your evtChar then I'm afraid your code can't work. It will just go into a never ending loop and hang your application.

You need to remember that VB6 is single threaded. Everything is in the same single thread. If you go into a never ending loop then you have, in effect, hung your application. The CommEvent variable is in your application thread and because you've hung the thread the variable can not change and therefore you'll loop forever waiting for a variable to change that can never change.

Please explain the reason for your Hybrid code? What are you trying to acheive?

By: SupportPosted on: Apr 8 2020 at 03:25:03 AM
You mention 3 different approaches that you've named "In Line", "On Comm" and "Hybrid"

First your InLine approach. Looping in your Receive() function is bad code. It loops forever and can only exit the loop if data arrives. If no data arrives the application hangs forever. An application should never assume that the serial port will receive data.

Periodically (frequently) calling an 'UnLooped' Receive() function - for example on a timer - would be better.

Your OnComm event also isn't working as you expect. Because you're using RThreshold=1 you will get OnComm events as soon as 'ANY' character arrives. So this is not actually triggering on LF. It's triggering on ANY. Not what you want either.

Your 'Hybrid' code is isn't working either. The Receive() function is a never ending loop waiting for the CommEvent value to change. But in such a dead loop no variabe in your code can change (The thread is hung inside the loop) that even prevents the Commevent variable changing so it'll never change. I can't comment on that approach further.

The correct approach is nearer your OnComm.

SComm1.CommPort = 5
SComm1.Settings = "9600,N,8,1"
SComm1.PortOpen = True
SComm1.RThreshold = 0
'Set rThreshold to zero. We DO NOT want rx events
We only want evtChar events
SComm1.EvtCharEnable = True
SComm1.EvtChar = 10

---------
Private Sub SComm1_OnComm()
Receive = SComm1.Input
Receive = Replace(Receive, vbLf, "")
Debug.Print Receive
End Sub
---------

Now the OnComm event should fire but only when the evtChar arrives in the RX buffer.

If it's not firing then I'd need to go check our source code and run a few tests on different hardware to see if it's hardware specific. I'll do that today if I can and get back to you.

In the meantime though just use your OnComm event (rThreashold=1 and evtChar event disabled). manually checking your data for LF is not bad code. Somebody somewhere has to look at each character so doing it in your code is not slowing down the application and by doing it yourself you know you're not going to be surprised if it turns out that any specific hardware is not capable of triggering all events.

By: IanSPosted on: Apr 8 2020 at 03:51:06 AM
I'd just use the standard functions. We know they work in all version of SComm and with all types of serial port.


' Declare a local buffer at the very top of the
' module. Somewhere to store our rx data
Dim MyBuffer As String


SComm1.CommPort = 5
SComm1.Settings = "9600,N,8,1"
SComm1.PortOpen = True
SComm1.RThreshold = 1
SComm1.InputLen = 1 ' Only one char per .Input/Read
MyBuffer = ""

Private Sub SComm1_OnComm()
Dim ch As Char

If CommEvent = comEvReceive Then

Do While SComm1.InbufferCount > 0
ch = SComm1.Input ' Will only get one char because InputLen is 1
if ch = vbLF Then
' We have LF. Assume that MyBuffer contains the string up to LF

Exit Sub ' and do whatever you want with MyBuffer.
End If

' If we get here then ch was not LF. So append it to MyBuffer and loop round

MyBuffer = MyBuffer & ch
Loop

' Don't hang round. Lets exit as soon as possible.
' More OnComm events may come till we get LF.
End If

End Sub ' End of OnComm event


By: IanSPosted on: Apr 8 2020 at 03:52:13 AM
Sorry. Wanted to say that I didn't actually run the above code. I just typed it from my head so please double check everything for typos

By: SupportPosted on: Apr 8 2020 at 09:35:42 AM
OK. I tested this with uGreen USB Serial adapter (FT232R Chipset (FTDI))

The following code works fine.

SComm1.CommPort = 5
SComm1.Settings = "9600,n,8,1"
SComm1.Handshaking = 0
SComm1.SThreshold = 0
SComm1.RThreshold = 0 '// 0 We do not want any comEvReceive events
SComm1.InputLen = 0 '// 0 = When we call SComm1.Input we'll get ALL of the data from the buffer

SComm1.EvtChar = 10
SComm1.EvtCharEnable = True

'// Transmit "Hello World" followed by CRLF to the port
'// As soon as LF is received Hello World appears in the textbox

Private Sub SComm1_OnComm()

 If SComm1.CommEvent = comEvEvtChar Then

  Textbox1.Text = Textbox.Text & SComm1.Read

 End If

End Sub



Reply - add a comment to this topic.

You may enter letters, numbers and standard punctuation only. HTML and other scripts/tags will be rejected.

Topic:- Troubles with the CommEvent = comEvEvtChar


Enter the numbers.

Your name here is optional