Sorry... didn't mean to overwhelm you.
Here is a simpler version commented to help. NOTE: This uses the
Windows API so it will not run with the demo version of PB.
Code: Select all
Enumeration
#Window_Main
#Gadget_Panel1
#Gadget_ListIcon
EndEnumeration
#MaxReceiveBuffer = 1024
Global dcb.DCB
Global LF.s : LF = Chr(10)
Global device.s : device.s = ""
Global portsetup.s : portsetup = ""
Procedure.s PortState()
portsetup = " " + Str(dcb\BaudRate) + " , "
portsetup + Str(dcb\ByteSize) + " , "
Select dcb\Parity
Case #NOPARITY
portsetup + " N, "
Case #EVENPARITY
portsetup + " E, "
Case #ODDPARITY
portsetup + " O, "
Case #MARKPARITY
portsetup + " M, "
Case #SPACEPARITY
portsetup + " S, "
EndSelect
Select dcb\StopBits
Case #ONESTOPBIT
portsetup + " 1"
Case #TWOSTOPBITS
portsetup + " 2"
Case #ONE5STOPBITS
portsetup + " 1.5"
EndSelect
EndProcedure
Procedure.s SerialPorts()
For I = 1 To 16 ; look at all 16 ports to see if they exist
device = "COM" + Str(I) + ":"
AddGadgetItem(#Gadget_Panel1, -1, "Checking Port " + Str(I) + " of 16")
LI = ListIconGadget(#Gadget_ListIcon + I, 6, 6, GadgetWidth(#Gadget_Panel1) - 16, GadgetHeight(#Gadget_Panel1) - 36, "Description", 80,#PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines|#LVS_NOSORTHEADER)
AddGadgetColumn(#Gadget_ListIcon + I, 1, "Results", 202)
; Use WinAPI - try to open desired port
hCom = CreateFile_(@device, #GENERIC_READ | #GENERIC_WRITE, 0, #Null, #OPEN_EXISTING, 0, #Null)
If hCom = #INVALID_HANDLE_VALUE
; Failed to open the port
; Use WinAPI to get the error number and report it
dwError.l = GetLastError_()
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Couldn't open the Comm Port")
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Error result: " + Str(dwError))
; Brief delay so user can see the activity, otherwise too fast
Delay(100)
RemoveGadgetItem(#Gadget_Panel1, CountGadgetItems(#Gadget_Panel1)-1)
Else
SetGadgetItemText(#Gadget_Panel1, CountGadgetItems(#Gadget_Panel1)-1, device,0)
AddGadgetItem(#Gadget_ListIcon + I, -1, device + LF + "Found")
fSuccess.l = GetCommState_(hCom, @dcb)
; GetCommState returns a non-zero value upon success, zero if failure
If fSuccess
; Successful
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Retrieved the current Comm State")
; Use a procedure to check out the current port state, values in the DCB structure
PortState()
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + portsetup)
; Set the Data Control Block: baud=115200, 8 Data bits, no parity, 1 stop bit.
dcb\BaudRate = #CBR_115200
dcb\ByteSize = 8;
dcb\Parity = #NOPARITY;
dcb\StopBits = #ONESTOPBIT
; Use the WinAPI to reset the Comm port's state
fSuccess = SetCommState_(hCom, @dcb)
; SetCommState returns zero on failure, a non-zero value upon success
If fSuccess
; Successful
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Reset the Comm State")
; Use the procedure to review the current port state
PortState()
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + portsetup)
Else
; Failure
; Use the WinAPI to get error code and report it
dwError = GetLastError_()
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Couldn't set the Comm State")
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Error result: " + Str(dwError))
EndIf
; Set the Timeouts
ct.COMMTIMEOUTS
ct\ReadIntervalTimeOut = 200 ; in milliseconds
ct\ReadTotalTimeoutConstant = 1
ct\ReadTotalTimeoutMultiplier = 1
ct\WriteTotalTimeoutConstant = 10
ct\WriteTotalTimeoutMultiplier = 1
If fSuccess
; We successfully set the comm port state, now lets set the timeouts for that port
fSuccess = SetCommTimeouts_(hCom,@ct)
If fSuccess
; Successful
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Reset the Comm Timeouts")
Else
; Failure
; Use the WinAPI to get error code and report it
dwError = GetLastError_()
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Couldn't set the Comm Timeouts")
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Error result: " + Str(dwError))
EndIf
EndIf
;We set the state and the timeouts, now set the In/Out buffer lengths
If fSuccess
fSuccess = SetupComm_(hCom,1200,1200)
If fSuccess
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Reset the Comm Buffer Sizes")
Else
dwError = GetLastError_()
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Couldn't set the Comm Buffer Sizes")
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Error result: " + Str(dwError))
EndIf
EndIf
; MessageRequester("Open Comm Port",Msg$,#MB_ICONINFORMATION)
AddGadgetItem(#Gadget_ListIcon + I, -1, "")
; OK, now we are ready to try to communicate with the port
; Lets purge the buffer and then write some data to the Comm Port
; Here I send a modem command that I would expect a reply to....
PurgeComm_(hcom, #PURGE_TXCLEAR|#PURGE_TXCLEAR)
NoOfBytesWritten.l = 0
DataToWrite.s = "ATI3I4I5I6I7I8I9" + Chr(13)
Results = WriteFile_(hCom, @DataToWrite, Len(DataToWrite),@NoOfBytesWritten,0)
; Flush the file buffer immediately to insure writing is complete
FlushFileBuffers_(hcom)
If Results
; Successful
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Successfully wrote " + Str(NoOfBytesWritten) + " bytes")
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + RemoveString(DataToWrite,Chr(13)))
Else
; Failure
; Use the WinAPI to get error code and report it
dwError = GetLastError_()
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Couldn't write data")
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Error result: " + Str(dwError))
EndIf
AddGadgetItem(#Gadget_ListIcon + I, -1, "")
; Now lets try to read some data from the Comm Port
buffer.s = ""
Offset = 0
NoOfBytesReceived.l = 0
DataReadFromPort.l = AllocateMemory(#MaxReceiveBuffer)
Repeat
Results = ReadFile_(hCom, DataReadFromPort + Offset, 256, @NoOfBytesReceived, 0)
If Results
; Successfully read something
If NoOfBytesReceived > 0
; put it in my processing buffer
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Successfully read "+ Str(NoOfBytesReceived) + " bytes")
Offset + NoOfBytesReceived
buffer + PeekS(DataReadFromPort, NoOfBytesReceived)
EndIf
ElseIf Results = 0
; Failed to read anything
; Use the WinAPI to get error code and report it
dwError = GetLastError_()
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Couldn't receive data")
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Error result: " + Str(dwError))
EndIf
Until NoOfBytesReceived = 0 Or Offset > #MaxReceiveBuffer
FlushFileBuffers_(hCom)
; Now lets interpret what we read from the port
; First, I will take out some unwanted lines
buffer = RemoveString(buffer,"OK") ; I don't want the OK reply. You may.
buffer = RemoveString(buffer,Chr(10)+Chr(13)) ; Remove LF & CR, you may want them.
buffer = RemoveString(buffer,Chr(10)) ; Remove just a LF, you may want them.
If Len(buffer) > 0
; OK, show me what I read from the port
AddGadgetItem(#Gadget_ListIcon + I, -1, "")
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Data read")
For k = 1 To 8
temp$ = StringField(buffer, k, Chr(13))
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + temp$)
Next
EndIf
Else
AddGadgetItem(#Gadget_ListIcon + I, -1, "" + LF + "Couldn't get the Comm State" + Chr(10) + "Error result: " + Str(fSuccess))
EndIf
; Finally, close the port
CloseHandle_(hCom)
EndIf
Next
EndProcedure
; Open main window
If OpenWindow(#Window_Main, 0, 0, 311, 430, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Serial Port Information")
CreateGadgetList(WindowID())
; Set up a way to see the results of querying the serial ports
PanelGadget(#Gadget_Panel1, 4, 30, WindowWidth() - 8, WindowHeight() - 34)
; Call the procedure to get the Serial Port statistics,
; Look at all 16, try to read and write to each one found.
SerialPorts()
; Processing loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow ; Window close box clicked
Quit = #True
EndSelect
Until Quit
EndIf
End