Page 1 of 1

Serial Port Search

Posted: Thu Dec 14, 2017 6:56 pm
by User_Russian
How to find all serial ports? In Windows, it's easy to do.

Code: Select all

For i=1 To 255
  If OpenSerialPort(0, "COM"+i, 11520, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 255, 255)
    Debug "COM"+i
    CloseSerialPort(0)
  EndIf
Next
How to do it in Linux and MacOS.

Re: Serial Port Search

Posted: Thu Dec 14, 2017 7:32 pm
by Wolfram
On Mac (and I think on Linux too)

Code: Select all

If ExamineDirectory(0,"/dev/","tty.*")
  While NextDirectoryEntry(0)
    If DirectoryEntryType(0) = #PB_DirectoryEntry_File
      Debug DirectoryEntryName(0)
    EndIf
  Wend
  FinishDirectory(0)
EndIf

Re: Serial Port Search

Posted: Thu Dec 14, 2017 9:16 pm
by HeX0R
Windows and Linux, no idea about Mac:

Code: Select all

Global NewList AvailableComs.s()

Procedure GetAvailableComPorts()                                               ;this procedure scans the registry (on win) or dmesg (on linux) to find the connected com ports
	Protected hKey, lpcbName, lpName.s, a$, lType, i, j, Dmesg, Fgrep, Port.s

	CompilerSelect #PB_Compiler_OS
		CompilerCase #PB_OS_Windows
			If RegOpenKeyEx_(#HKEY_LOCAL_MACHINE, "HARDWARE\DEVICEMAP\SERIALCOMM", 0, #KEY_QUERY_VALUE, @hKey) = #ERROR_SUCCESS
				lpName = Space(1024)

				Repeat
					lpcbName = 1024
					If RegEnumValue_(hKey, i, @lpName, @lpcbName, 0, 0, 0, 0) = #ERROR_SUCCESS
						a$ = Left(lpName, lpcbName)
						If a$ = ""
							Break
						EndIf
						lpcbName = 1024
						lType    = 0
						If RegQueryValueEx_(hKey, a$, 0, @lType, @lpName, @lpcbName) = #ERROR_SUCCESS
							AddElement(AvailableComs())
							AvailableComs() = lpName
						EndIf
						i + 1
					Else
						Break
					EndIf
				ForEver
				RegCloseKey_(hKey)
			EndIf
		CompilerCase #PB_OS_Linux
			Dmesg = RunProgram("/bin/dmesg", "", "", #PB_Program_Open | #PB_Program_Read)
			If Dmesg
				Fgrep = RunProgram("/bin/fgrep", "tty", "", #PB_Program_Open | #PB_Program_Connect | #PB_Program_Read, Dmesg)
				If Fgrep
					While ProgramRunning(Fgrep)
						a$ = ReadProgramString(Fgrep)
						i  = FindString(a$, "ttyS", 1)
						If i > 0
							j = FindString(a$, " ", i)
							Port = "/dev/" + Mid(a$, i, j - i)
							hKey = 1
							ForEach AvailableComs()
								If AvailableComs() = Port
									hKey = 0
									Break
								EndIf
							Next
							If hKey
								AddElement(AvailableComs())
								AvailableComs() = Port
							EndIf
						EndIf
					Wend
					CloseProgram(Fgrep)
				EndIf
				CloseProgram(Dmesg)
			EndIf
			
			
		CompilerCase #PB_OS_MacOS
			
			
	CompilerEndSelect

EndProcedure

GetAvailableComPorts()

ForEach AvailableComs()
	Debug AvailableComs()
Next

Advantages:
- Lists also ports currently in use
- Shows also ports not named "COMx", like virtual com ports e.g.

Re: Serial Port Search

Posted: Thu Dec 14, 2017 9:26 pm
by gally
Image

Code: Select all

  #SERIAL_PORTCOM_MIN = 1
  #SERIAL_PORTCOM_MAX = 256
  
  Define.i i, j, iPortCom, iPortBaud
  Define.s sPortCom, sPortBaud = "50;75;110;150;300;600;1200;1800;2400;4800;9600;19200;38400;57600;115200;128000;153600;230400;256000;460800;921600"

  
  For i=#SERIAL_PORTCOM_MIN To #SERIAL_PORTCOM_MAX
    sPortCom = "COM" + Str(i)
    iPortCom = OpenSerialPort(#PB_Any, sPortCom, 9600, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 512)
    If iPortCom And IsSerialPort(iPortCom)
      CloseSerialPort(iPortCom)
      ;
      Debug sPortCom + " : PASS"
      ;
      For j=0 To CountString(sPortBaud, ";")
        iPortCom = OpenSerialPort(#PB_Any, sPortCom, Val(StringField(sPortBaud, j + 1, ";")), #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 512)
        If iPortCom And IsSerialPort(iPortCom)
          CloseSerialPort(iPortCom)
          Debug ">>>>>>>>>>>>>>> " + StringField(sPortBaud, j + 1, ";") + " Baud PASS"
        EndIf
      Next j
      ;  
    EndIf
  Next i

Re: Serial Port Search

Posted: Fri Dec 15, 2017 3:44 pm
by swhite
Hi

The key part in the following code is the RunProgram part. In my case we have programmed the FTDI USB chips with a description so I can determine which piece of equipment is connected to a particular port.

Code: Select all

Procedure.i QueryPorts(*toParam.Param)
   Define ls.i,lcTxt.s,lnUSB.i,lnSec.i
   lnSec = ElapsedMilliseconds() + 30000
   Repeat
      ls.i = RunProgram("/bin/ls","-l /dev/serial/by-id","",#PB_Program_Open | #PB_Program_Read)
      If ls
         While ProgramRunning(ls)
            If AvailableProgramOutput(ls)
               lcTxt = ReadProgramString(ls) 
               WriteToLog(lcTxt)
               If FindString(lcTxt,"_kt_magr_",1)
                  *toParam\Mag\PortName = "/dev"+Mid(lcTxt,FindString(lcTxt,"../tty")+2)
                  lnUSB = lnUSB + 1
               ElseIf FindString(lcTxt,"_kt_lcd_",1)
                  *toParam\LCD\PortName = "/dev"+Mid(lcTxt,FindString(lcTxt,"../tty")+2)
                  lnUSB = lnUSB + 2
               ElseIf FindString(lcTxt,"_kt_mnet_",1)
                  *toParam\Pmp\PortName = "/dev"+Mid(lcTxt,FindString(lcTxt,"../tty")+2)
                  lnUSB = lnUSB + 4
               ElseIf FindString(lcTxt,"_kt_keyb_",1)
                  *toParam\KeyB\PortName = "/dev"+Mid(lcTxt,FindString(lcTxt,"../tty")+2)
                  lnUsb = lnUSB + 8
               EndIf
            EndIf
         Wend
         CloseProgram(ls)
      Else
         WriteToLog("Error: '/bin/ls -l /dev/serial/by-id' did not run")
      EndIf
      Delay(4000)
   Until lnUSB = 15 Or ElapsedMilliseconds() > lnSec
   ProcedureReturn lnUSB

Re: Serial Port Search

Posted: Fri Dec 22, 2017 11:50 am
by ElementE
The Windows registry contains the "device" mapping between the serial port hardware and the assigned COM port numbers.

Code: Select all

Computer\HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
In my case we have programmed the FTDI USB chips with a description so I can determine which piece of equipment is connected to a particular port.
This is important as Windows is known for reassigning COM port numbers!