modCOMM - Written by: David M. Hitchner (1 Viewer)

ions

Access User
Local time
Today, 12:43
Joined
May 23, 2004
Messages
785
Access Expert,

I am trying to use David Hitchner's very good code to read data from a scale connected to a COM port.

I downloaded the sample code from
http://www.thescarms.com/vbasic/CommIO.aspx

The download contains a .BAS file, a VBP and a VBW file along with sample code in a txt file.

1) My first question is what are .BAS, VBP and VBW files. When I opened the .BAS file in a text editor it's vba code. I just pasted that code into a module so I am not sure what the .BAS suffix is for. Also I am not sure what the VBP and VBW files are for.

2) When I run David's Code everything runs without errors but I can never read data from the scale. **Note there is another locked down program (I cant' see the source code) on the machine that does capture the data from the scale.

strData is always "" and udtCommStat.cbInQue in the procedure commRead is always 0 in my case.

I believe I have the parameters correct "baud=9600 parity=E data=7 stop=2".

Why am I not capturing data from the scale?

Thank you.
 

mbaker0720

New member
Local time
Today, 14:43
Joined
Jun 20, 2012
Messages
3
Thanks for responding David. When I said I was having the same problem I was really refering to the second part of IONS question. I found some VBA code that is supposed to work in Excel to make API calls to read and write to the serial ports. I got this code and brought it into Access 2010 and it seems to work fine when I write to the serial ports;however, when I attempt to read I get nothing. In tracing the code I have found that then function CommRead seems to not function correctly. I read somewhere that you are the one who originally wrote this code so I searched for your name and landed on this website. The code that IONS is talking about appears to be the same code that I am using (except that mine is VBA and his is VB) the problem is the same...

strData always comes back as "" and udtCommStat.cbInQue in the procedure commRead is always 0.

As a result I am having a great deal of dificulty reading the weight on the connected scale into my Access database.

Here is the code. I am sure this is old code and am sure you have better things to do than look at it again. So, I would like to Thank You up front for any time you spend on this.

'-------------------------------------------------------------------------------
' CommRead - Read serial port input buffer.
'
' Parameters:
' intPortID - Port ID used when port was opened.
' strData - Data buffer.
' lngSize - Maximum number of bytes to be read.
'
' Returns:
' Error Code - 0 = No Error.
'-------------------------------------------------------------------------------
Public Function CommRead(intPortID As Integer, strData As String, _
lngSize As Long) As Long

Dim lngStatus As Long
Dim lngRdSize As Long, lngBytesRead As Long
Dim lngRdStatus As Long, strRdBuffer As String * 1024
Dim lngErrorFlags As Long, udtCommStat As COMSTAT

On Error GoTo Routine_Error

strData = ""
lngBytesRead = 0
DoEvents

' Clear any previous errors and get current status.
lngStatus = ClearCommError(udtPorts(intPortID).lngHandle, lngErrorFlags, _
udtCommStat)

If lngStatus = 0 Then
lngBytesRead = -1
lngStatus = SetCommError("CommRead (ClearCommError)")
GoTo Routine_Exit
End If

If udtCommStat.cbInQue > 0 Then
If udtCommStat.cbInQue > lngSize Then
lngRdSize = udtCommStat.cbInQue
Else
lngRdSize = lngSize
End If
Else
lngRdSize = 0
End If

If lngRdSize Then
lngRdStatus = ReadFile(udtPorts(intPortID).lngHandle, strRdBuffer, _
lngRdSize, lngBytesRead, udtCommOverlap)

If lngRdStatus = 0 Then
lngStatus = GetLastError
If lngStatus = ERROR_IO_PENDING Then
' Wait for read to complete.
' This function will timeout according to the
' COMMTIMEOUTS.ReadTotalTimeoutConstant variable.
' Every time it times out, check for port errors.

' Loop until operation is complete.
While GetOverlappedResult(udtPorts(intPortID).lngHandle, _
udtCommOverlap, lngBytesRead, True) = 0

lngStatus = GetLastError

If lngStatus <> ERROR_IO_INCOMPLETE Then
lngBytesRead = -1
lngStatus = SetCommErrorEx( _
"CommRead (GetOverlappedResult)", _
udtPorts(intPortID).lngHandle)
GoTo Routine_Exit
End If
Wend
Else
' Some other error occurred.
lngBytesRead = -1
lngStatus = SetCommErrorEx("CommRead (ReadFile)", _
udtPorts(intPortID).lngHandle)
GoTo Routine_Exit

End If
End If

strData = Left$(strRdBuffer, lngBytesRead)
End If

Routine_Exit:
CommRead = lngBytesRead
Exit Function

Routine_Error:
lngBytesRead = -1
lngStatus = Err.Number
With udtCommError
.lngErrorCode = lngStatus
.strFunction = "CommRead"
.strErrorMessage = Err.Description
End With
Resume Routine_Exit
End Function
 

ions

Access User
Local time
Today, 12:43
Joined
May 23, 2004
Messages
785
I got the code to read my port using the below code along with David Hitchner's library in my Access Application.

Code:
Option Compare Database
Option Explicit

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)


Public Function ReadScale()

On Error GoTo PROC_ERR

    Dim intPortID As Integer ' Ex. 1, 2, 3, 4 for COM1 - COM4
    Dim lngStatus As Long
    Dim strError  As String
    Dim strData   As String
    Dim sngStart As Single
    Dim intPollComResult As Integer '0 Timed Out, 1 Success, 2 Error
    
    intPortID = 1
    
    ' Initialize Communications
    lngStatus = CommOpen(intPortID, "COM" & CStr(intPortID), _
        "baud=9600 parity=E data=7 stop=2")
    
    If lngStatus <> 0 Then
        ' Handle error.
        lngStatus = CommGetError(strError)
        MsgBox "COM Error: " & strError
    End If
    

    ' Set modem control lines.
    lngStatus = CommSetLine(intPortID, LINE_RTS, True)
    lngStatus = CommSetLine(intPortID, LINE_DTR, True)
    
    'Write to Com Port
    lngStatus = CommWrite(intPortID, "P")
    
    If lngStatus <> 1 Then
        lngStatus = CommGetError(strError)
        MsgBox "COM Error: " & strError
        GoTo PROC_EXIT
    End If

    
    '*** Poll the Com Port.
    
    sngStart = Timer
    
    ' Infinite Loop with Exit Do
    Do
        
        ' Read maximum of 64 bytes from serial port.
        lngStatus = CommRead(intPortID, strData, 64)
        
        Select Case lngStatus
        
        Case 0 'No data was returned
        
            'Keep Trying to Poll the Com port.
            
        Case Is > 0  'Data was returned
        
            'Success
            intPollComResult = 1
            Exit Do

        
        Case Is < 0 ' Error occured
        
            intPollComResult = 2
            Exit Do
            
        End Select
        
        
        If Format(Timer - sngStart, "Fixed") < 4 Then
                
                Call Sleep(25)
            
        Else
            
            'Timed Out
            intPollComResult = 0
            Exit Do
        End If
        
    Loop

    
    'Com Poll Result.
    Select Case intPollComResult
    
    Case 0 'Timed Out
    
        Call MsgBox("The operation timed out!", vbOKOnly + vbExclamation + _
                  vbDefaultButton1, "WMS")
                  
    Case 1 ' Process data.
        
        
        MsgBox strData
    
    Case 2 ' Handle error.
        
        
        lngStatus = CommGetError(strError)
        MsgBox "COM Error: " & strError
    
    End Select


PROC_EXIT:
    
     ' Reset modem control lines.
    lngStatus = CommSetLine(intPortID, LINE_RTS, False)
    lngStatus = CommSetLine(intPortID, LINE_DTR, False)

    ' Close communications.
    Call CommClose(intPortID)
    
    Exit Function

PROC_ERR:
    MsgBox Err.Number, Err.Description, "modScale.ReadScale"
    Resume PROC_EXIT
    Resume

End Function
 

DemonDNF

Registered User.
Local time
Today, 15:43
Joined
Jan 31, 2014
Messages
77
SOLVED! Go to post #12 if you don't feel like reading this.

I'm also having problems receiving a file using modCOMM. The barcode scanning app on my android phone sends a fixed 150 bytes. I can receive these using the Receive File feature on the Bluetooth icon so I know the connection is good.

1. Is it possible to receive more than 64 bytes using modCOMM? Or is it limitted to that due to some Windows constraint? I saw in the module that the buffers are 1024 (assuming these are I/O buffers and not used for something else).

2. Is it possible to receive from COM ports higher than 4? I know how to override the USB port in Windows, but it would be nice if I could use whatever the laptop choses (in my case it varies from COM12-18 depending on which socket).

Thanks!

Robert
 
Last edited:

DemonDNF

Registered User.
Local time
Today, 15:43
Joined
Jan 31, 2014
Messages
77
SOLVED! Go to post #12 if you don't feel like reading this.

I've been fiddling with modCOMM since yesterday so today I moved on to MScomm32.ocx from here:
http://support.microsoft.com/kb/194922

I made a new form with TEXT1, added MScomm32.ocx and tweaked sample code without any of my other "stuff". Code so far:

Code:
      Private Sub Form_Load()
         With MSComm1
            .CommPort = 2
            .Handshaking = 2 - comRTS
            .RThreshold = 1
            .RTSEnable = True
            .Settings = "9600,n,8,1"
            .SThreshold = 1
            .PortOpen = True
            ' Leave all other settings as default values.
         End With
         Text1.Caption = ""
      End Sub
 
      Private Sub Form_Unload(Cancel As Integer)
         MSComm1.PortOpen = False
      End Sub
 
      Private Sub MSComm1_OnComm()
         Dim InBuff As String
         Select Case MSComm1.CommEvent
         ' Handle each event or error by placing
         ' code below each case statement.
         ' This template is found in the Example
         ' section of the OnComm event Help topic
         ' in VB Help.
         ' Errors
            Case comEventBreak   ' A Break was received.
            Case comEventCDTO    ' CD (RLSD) Timeout.
            Case comEventCTSTO   ' CTS Timeout.
            Case comEventDSRTO   ' DSR Timeout.
            Case comEventFrame   ' Framing Error.
            Case comEventOverrun ' Data Lost.
            Case comEventRxOver  ' Receive buffer overflow.
            Case comEventRxParity   ' Parity Error.
            Case comEventTxFull  ' Transmit buffer full.
            Case comEventDCB     ' Unexpected error retrieving DCB]
         ' Events
            Case comEvCD   ' Change in the CD line.
            Case comEvCTS  ' Change in the CTS line.
            Case comEvDSR  ' Change in the DSR line.
            Case comEvRing ' Change in the Ring Indicator.
            Case comEvReceive ' Received RThreshold # of chars.
               InBuff = MSComm1.Input
               Call HandleInput(InBuff)
            Case comEvSend ' There are SThreshold number of
                           ' characters in the transmit buffer.
            Case comEvEOF  ' An EOF character was found in the
                           ' input stream.
         End Select
      End Sub
 
      Sub HandleInput(InBuff As String)
         ' This is where you will process your input. This
         ' includes trapping characters, parsing strings,
         ' separating data fields, etc. For this case, you
         ' are simply going to display the data in the TextBox.
'         Text1.SelStart = Len(Text1.Text)
         Text1.Caption = Text1.Caption & InBuff
      End Sub

Same thing, the form just sits there but I can still manually receive files using the Bluetooth icon on the task bar.

Personally, I prefer this logic a lot more than modCOMM, it seems much leaner. I'm pretty sure I'm sticking on handshaking. I have no idea how to find out what the Bluetooth icon tells my phone during communication.

Robert


EDIT: Just a bit more info, I can confirm I am on COM2 at 9600,8,N,1. The intention is to just keep on appending bytes received to TEXT1 for now to keep things simple, and to confirm if the record length changes using MScomm32 instead of Bluetooth exe.

Oh yeah, I don't have a OnComm event when I look at MScomm32 Properties in Access 2002? <-- This is normal, another thread explains why.
 
Last edited:

DemonDNF

Registered User.
Local time
Today, 15:43
Joined
Jan 31, 2014
Messages
77
SOLVED! Go to post #12 if you don't feel like reading this.

After finding this:
http://www.access-programmers.co.uk/forums/showthread.php?t=143399

My code is now down to this:

Code:
Option Compare Database
Option Explicit
Private Sub Form_Load()
   With MSComm1
     .CommPort = 2
'     .Handshaking = 2 - comRTS
'     .Handshaking = comXOnXoff
'     .Handshaking = comNone
'     .Handshaking = comRTSXOnXOff
     .Handshaking = comRTS
     .RThreshold = 1
     .RTSEnable = True
     .Settings = "9600,n,8,1"
     .SThreshold = 1
     .PortOpen = True
     .InputLen = 30000
     .InputMode = comInputModeText
  End With
  Text1.Caption = ""
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
  MSComm1.PortOpen = False
End Sub
 
Private Sub MSComm1_OnComm()
  Text1.Caption = Text1.Caption & MSComm1.Input
End Sub

I tried all the combinations I could think of and same thing, nothing showing up on the form.

Robert

EDIT: I just can't figure out what triggers ONCOMM event if it's not listed in the MScomm32 Properties. Does it have to do with me having Access 2002?
 
Last edited:

DemonDNF

Registered User.
Local time
Today, 15:43
Joined
Jan 31, 2014
Messages
77
SOLVED! Go to post #12 if you don't feel like reading this.

I think I figured out what's wrong. I'm missing a whole lot of "stuff" going on in the background to manage a bluetooth communication. That little Bluetooth icon on the task bar does a whole lot more than just listen on a COM port.

Got up this morning and started googling bluetooth protocol and followed a trail that led me to what goes on in the background of my phone:
http://developer.android.com/refere...ateRfcommSocketToServiceRecord(java.util.UUID)

There has to be a "sniffer" component running first, then an exchange of MAC addresses, determining which device may connect (pairing), the list goes on.

I haven't found an example of someone having been through this using Access yet. I realized last night that all the examples I was finding so far were people using real RS232 communication. The bluetooth dongle data may come out over the COM port, but it's the handshaking going on in the background that is unknown.

I searched last night for a free COM port monitor to see the data actually being exchanged. Google is literally flooded with HHD "free" monitor over a multitude of different web sites names. I tried it once, none of the features worked to monitor this COM port. It's basically a demo screen of buttons and windows to entice you to buy the software - uninstall.

The other free serial monitors I found could not listen while the port was in use. My plan was to receive a file manually using the Bluetooth icon and then replicate the data sent from the laptop.

Don't really know what to do at this point. So close yet so far.

Robert
 
Last edited:

DemonDNF

Registered User.
Local time
Today, 15:43
Joined
Jan 31, 2014
Messages
77
SOLVED! Go to post #12 if you don't feel like reading this.

I noticed something in Device Manager. COM2 is listed as a Standard Serial over Bluetooth Link.

To me that would mean that the PC-side is standard serial communication and the device takes care of the bluetooth handling. I checked the properties and there's a bunch of entries for Details: BTHENUM, BTHMODEM and a bunch of other stuff.

So it "appears" as if the bluetooth guts are there and enumeration should be taken care of. Unless I'm supposed to feed it the proper parameters. I'm a COBOL programmer so what do I know.

Stumped at this point.

Robert
 
Last edited:

DemonDNF

Registered User.
Local time
Today, 15:43
Joined
Jan 31, 2014
Messages
77
SOLVED!

Turns out it was the app. I tried another one that mentionned bluetooth and SPP and it worked on the first shot.



Now I know why that first app was feature rich and without ads. That payware SDK was for more than customizing the app to your liking, it probably was so you could override the protocol to standard windows SPP. It wouldn't even show up on Hyperterminal.

Too bad the scan window on this app is tiny. I'm going to have to find a payware app with full screen like the first one, but this time with bluetooth and SPP in the description.

Robert
 

DemonDNF

Registered User.
Local time
Today, 15:43
Joined
Jan 31, 2014
Messages
77
In case it helps someone. This is my code to trap incoming data from my android phone via bluetooth over SPP using COM2:

Code:
Option Compare Database
Option Explicit
 
Private Sub Form_Load()
  MSComm1.PortOpen = True                           ' Open port
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
  MSComm1.PortOpen = False                          ' Close port
End Sub
 
Private Sub MSComm1_OnComm()
  lblLight.BackColor = 65280                        ' Turn ON Green indicator
  Text1.Caption = Text1.Caption & MSComm1.Input     ' Append input data
End Sub

Yes, that's all there is to it. Just set the MScomm properties in Access properly, then just turn the port ON, trap the bytes, turn the port OFF. No need for anything else except MScomm32.OCX hidden on your form somewhere.



For those that don't know where MScomm32.OCX comes from:

1. Open form in Design view.
2. Click MORE CONTROLS (hammer & wrench icon) in TOOLBOX.
3. Hover mouse over down arrow.
4. Click on Microsoft Communications Control (I have version 6.0).
5. Left click a small box on your form to create the control.
6. Change the properties of that control as needed.

And that's it.

Robert


EDIT: Look at post #8 for more detailed code to trap a certain length of bytes, or use a counter in OnComm to signal reception of a complete record.

Also, I have since increased the input and output buffers to 1024, just to be safe.
 
Last edited:

DemonDNF

Registered User.
Local time
Today, 15:43
Joined
Jan 31, 2014
Messages
77
When you reboot the next day and nothing works, make sure to check this: LOL



The ports had been rearranged by windows. You want to read the OUTGOING port from your Access form, not INCOMING - that will only cost you hours of frustration. It is read outgoing from phone.

So in this case I had to change to COM3 in the MScomm32 activeX.


While I'm at it, this is what my Device Manager looks like:




One last thing that can cause frustration. I am using the TEC-IT barcode app; make sure to read the instructions for whatever app you select. For this one, the app had to be started BEFORE adding the phone to the bluetooth devices on the laptop or else the connection would fail.

Robert
 

DemonDNF

Registered User.
Local time
Today, 15:43
Joined
Jan 31, 2014
Messages
77
I guess I might as well show this panel:



I'm pretty sure you want an app that uses Serial Port Profile, enable it. The first app I had tried did not have this feature.

And that's likely why it received a file manually in Bluetooth (RFCOMM), but not in MScomm32 (SPP). The protocol layers are explained here:
https://developer.bluetooth.org/TechnologyOverview/Pages/SPP.aspx

Robert
 

nickryles

New member
Local time
Today, 20:43
Joined
Dec 8, 2020
Messages
3
Hi,
I'm a real novice at this but our sailing club appears to be using modCOMM routine to communicate with some lights in our race starting sequence.
Recently I've got this error message in one of the fucntions used to open the port. Any familiar with the code that could tell me what might be the problem?

Nick
 

Attachments

  • Capture.PNG
    Capture.PNG
    6.2 KB · Views: 194

Cornellihus

New member
Local time
Today, 20:43
Joined
Jun 14, 2022
Messages
3
Hi,
I'm a real novice at this but our sailing club appears to be using modCOMM routine to communicate with some lights in our race starting sequence.
Recently I've got this error message in one of the fucntions used to open the port. Any familiar with the code that could tell me what might be the problem?

Nick
Hii nick
Any solutions!!
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 14:43
Joined
Feb 28, 2001
Messages
27,146
@Cornellihus - please note that the dates on these posts are quite old.

As to the error posted in #16, that may be due to an incorrect port name. You would need to get into your system's DEVICE MANAGER to find the name of any serial ports.
 

Cornellihus

New member
Local time
Today, 20:43
Joined
Jun 14, 2022
Messages
3
@Cornellihus - please note that the dates on these posts are quite old.

As to the error posted in #16, that may be due to an incorrect port name. You would need to get into your system's DEVICE MANAGER to find the name of any serial ports.
Thank you it helped me a lot
one more question please can you tell me where's the problem
Screenshot (62).png
 

sonic8

AWF VIP
Local time
Today, 21:43
Joined
Oct 27, 2015
Messages
998
please can you tell me where's the problem
The problem is that the second argument in the declaration of the CommSetLine procedure is declared ByRef and it's data type is incompatible to the data type of the variable or constant LINE_RTS.
 

Users who are viewing this thread

Top Bottom