Code: Select all
EnableExplicit
#COMMaxPorts = 30
Enumeration #PB_Event_FirstCustomValue
#ComThread_Started
#ComThread_ByteReceived
#ComThread_LineReceived
#ComThread_Finished
EndEnumeration
Enumeration
#ComText
#ComCombo
#ConnectButton
#SendText
#SendString
#SendButton
#ReceiveText
#ReceiveEdit
EndEnumeration
Structure ThreadParameterStructure
Thread.i
Semaphore.i
Com$
Com.i
Receive$
Exit.i
EndStructure
Global NewList COMUsablePorts.s()
Procedure COMGetAvailablePorts()
Protected NewList COMPortNameList.s()
Protected i.i, Directory.i, Com.i
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
For i = 1 To #COMMaxPorts
AddElement(COMPortNameList())
COMPortNameList() = "COM" + Str(i)
Next i
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Directory = ExamineDirectory(#PB_Any, "/dev", "ttyUSB*")
If Directory
While NextDirectoryEntry(Directory)
AddElement(COMPortNameList())
COMPortNameList() = "/dev/" + DirectoryEntryName(Directory)
Wend
FinishDirectory(Directory)
EndIf
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Directory = ExamineDirectory(#PB_Any, "/dev", "tty.usbserial*")
If Directory
While NextDirectoryEntry(Directory)
AddElement(COMPortNameList())
COMPortNameList() = "/dev/" + DirectoryEntryName(Directory)
Wend
FinishDirectory(Directory)
EndIf
CompilerEndIf
ForEach COMPortNameList()
Com = OpenSerialPort(#PB_Any, COMPortNameList(), 9600, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1, 1)
If Com
AddElement(COMUsablePorts())
COMUsablePorts() = COMPortNameList()
CloseSerialPort(Com)
EndIf
Next
FreeList(COMPortNameList())
EndProcedure
Procedure ComThread(*Parameter.ThreadParameterStructure)
Protected Byte.a, ReceivedBytes.i
PostEvent(#ComThread_Started)
*Parameter\Com = OpenSerialPort(#PB_Any, *Parameter\Com$, 9600, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
If *Parameter\Com
WriteSerialPortString(*Parameter\Com, #CR$ + #CR$ + #CR$)
Repeat
If AvailableSerialPortInput(*Parameter\Com)
If ReadSerialPortData(*Parameter\Com, @Byte, 1) = 1
ReceivedBytes + 1
PostEvent(#ComThread_ByteReceived, 0, 0, 0, ReceivedBytes)
If Byte = #CR
PostEvent(#ComThread_LineReceived)
WaitSemaphore(*Parameter\Semaphore)
Else
*Parameter\Receive$ + Chr(Byte)
EndIf
EndIf
Else
Delay(10)
EndIf
Until *Parameter\Exit
CloseSerialPort(*Parameter\Com)
EndIf
PostEvent(#ComThread_Finished)
EndProcedure
Define.i Event, Exit
Define ThreadParameter.ThreadParameterStructure
COMGetAvailablePorts()
OpenWindow(0, 0, 0, 400, 300, "Serialport", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
TextGadget(#ComText, 10, 10, 50, 20, "Port")
ComboBoxGadget(#ComCombo, 70, 10, 100, 20)
ForEach COMUsablePorts()
AddGadgetItem(#COMCombo, -1, COMUsablePorts())
Next
SetGadgetState(#ComCombo, 0)
ButtonGadget(#ConnectButton, 180, 10, 80, 20, "Connect")
TextGadget(#SendText, 10, 40, 50, 20, "Send")
StringGadget(#SendString, 70, 40, 200, 20, "")
ButtonGadget(#SendButton, 280, 40, 80, 20, "Send")
DisableGadget(#SendString, #True)
DisableGadget(#SendButton, #True)
TextGadget(#ReceiveText, 10, 70, 50, 20, "Receive")
EditorGadget(#ReceiveEdit, 70, 70, 200, 100, #PB_Editor_ReadOnly)
DisableGadget(#ReceiveEdit, #True)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(100)
AddStatusBarField(100)
StatusBarText(0, 0, "Disconnected", #PB_StatusBar_Center)
ThreadParameter\Semaphore = CreateSemaphore()
Repeat
Event = WaitWindowEvent()
Select Event
Case #ComThread_Started
SetGadgetText(#ConnectButton, "Disconnect")
DisableGadget(#ComCombo, #True)
StatusBarText(0, 0, "Connected", #PB_StatusBar_Center)
DisableGadget(#SendString, #False)
DisableGadget(#SendButton, #False)
DisableGadget(#ReceiveEdit, #False)
Case #ComThread_ByteReceived
StatusBarText(0, 1, Str(EventData()), #PB_StatusBar_Center)
Case #ComThread_LineReceived
AddGadgetItem(#ReceiveText, -1, ThreadParameter\Receive$)
ThreadParameter\Receive$ = ""
SignalSemaphore(ThreadParameter\Semaphore)
Case #ComThread_Finished
SetGadgetText(#ConnectButton, "Connect")
DisableGadget(#ComCombo, #False)
StatusBarText(0, 0, "Disconnected", #PB_StatusBar_Center)
DisableGadget(#SendString, #True)
DisableGadget(#SendButton, #True)
DisableGadget(#ReceiveEdit, #True)
Case #PB_Event_Gadget
Select EventGadget()
Case #ConnectButton
If GetGadgetText(#ConnectButton) = "Connect"
StatusBarText(0, 1, "")
ThreadParameter\Com$ = GetGadgetText(#ComCombo)
ThreadParameter\Exit = #False
ThreadParameter\Thread = CreateThread(@ComThread(), @ThreadParameter)
Else
ThreadParameter\Exit = #True
EndIf
Case #SendButton
WriteSerialPortString(ThreadParameter\Com, GetGadgetText(#SendString))
EndSelect
Case #PB_Event_CloseWindow
Exit = #True
EndSelect
Until Exit
If IsThread(ThreadParameter\Thread)
ThreadParameter\Exit = #True
If WaitThread(ThreadParameter\Thread, 3000) = 0
KillThread(ThreadParameter\Thread)
EndIf
EndIf
FreeSemaphore(ThreadParameter\Semaphore)