OSX, PB & USB-RS232 serial ports: SOLVED

Mac OSX specific forum
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

OSX, PB & USB-RS232 serial ports: SOLVED

Post by dhouston »

I am ready to port my application, which is working under Windows & Linux, to OSX. It interfaces with an embedded device via RS232. I have code working under both Windows and Linux that automatically enumerates all of the serial ports on the system. Under OSX I will have to interface with USB-RS232 adapters and am hoping that someone here has a little experience with this.

It looks like my Linux code to enumerate the ports will be useless.

Code: Select all

Procedure EnumSerialPorts()                              ;enumerate serial ports 
  #O_RDONLY   = 0
  #O_WRONLY   = 1
  #O_RDWR      = 2
  #O_NOCTTY   = $100
  #O_NONBLOCK = $800
  #TIOCMGET   = $5415
  #TIOCMSET   = $5418
  #SET_DTR    = %000000000010    ;$002
  #CLR_DTR    = %111111111101    ;~#SET_DTR
  Protected dev.s,LineIn.s,found.s
  Protected ps,dmesg,fgrep,tee,i,t,s,u,c
  NewList Comports.s()
  ps=RunProgram("/bin/ps", "-A","",#PB_Program_Open|#PB_Program_Read)
  fgrep=RunProgram("/bin/fgrep", "SerialTest","",#PB_Program_Open|#PB_Program_Connect|#PB_Program_Read,ps)
  tee = RunProgram("/usr/bin/tee","PID.txt",AppPath,#PB_Program_Open|#PB_Program_Connect|#PB_Program_Read,fgrep)
  While ProgramRunning(tee)
    Pid=StringField(Trim(ReadProgramString(tee)),1," ")
  Wend 
  WaitProgram(tee)
  CloseProgram(ps):CloseProgram(tee)
  ;-----enum ports & write tty.txt-----
  DeleteFile(AppPath+"tty.txt")
  dmesg = RunProgram("/bin/dmesg","","",#PB_Program_Open|#PB_Program_Read)
  fgrep = RunProgram("/bin/fgrep","tty","",#PB_Program_Open|#PB_Program_Connect|#PB_Program_Read,Dmesg)
  tee = RunProgram("/usr/bin/tee","tty.txt",AppPath,#PB_Program_Open|#PB_Program_Connect|#PB_Program_Read,Fgrep)
  WaitProgram(tee)
  CloseProgram(Dmesg):CloseProgram(Fgrep):CloseProgram(Tee)
  ;-----parse tty.txt-----
  ports=""
  If ReadFile(0,AppPath+"tty.txt")    
    While Eof(0) = 0 
      LineIn=ReadString(0)+" "
      t=FindString(LineIn,"tty",1)                    ;Tibbo uses vspdN
      If t>0
        s=FindString(LineIn," ",t)
        dev=Trim(Mid(LineIn,t,s-t))     
        If Right(dev,1)=":":dev=Left(dev,Len(dev)-1):EndIf
        If Not IsNumeric(Mid(dev,4,1))
          c=CountString(LineIn,"tty")
          If c=1      
            ;RunProgram("stty","-F /dev/"+dev+" 19200 cread -echo -icanon","")
            ;fd=open_("/dev/"+dev,#O_NONBLOCK|#O_NOCTTY|#O_RDWR,0)  
            fd=OpenSerialPort(#PB_Any,"/dev/"+dev,19200,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,1024,1024)        
            If fd<>0 
              AddElement(ComPorts())
              ComPorts()="/dev/"+dev
              close_(fd)
            EndIf             
          ElseIf (c=2) 
            s=Val(Mid(dev,5,2))                                               ;first index
            t=FindString(LineIn,"tty",t+Len(dev))                   ;find second tty?xx
            c=Val(Mid(LineIn,t+4,2))                                       ;second index
            If (c>s)
              For i=s To c
                dev=Left(dev,4)+Str(i)       
                ;RunProgram("stty","-F /dev/"+dev+" 19200 cread -echo -icanon","")
                ;fd=open_("/dev/"+dev,#O_NONBLOCK|#O_NOCTTY|#O_RDWR,0)  
                fd=OpenSerialPort(#PB_Any,"/dev/"+dev,19200,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,1024,1024)
                If fd<>0
                  AddElement(ComPorts())
                  ComPorts()="/dev/"+dev
                  close_(fd)
                EndIf                 
              Next
            ElseIf FindString(LineIn,"-",1)>0
              MessageRequester("Serial Port Enumeration","Unexpected dmesg format - Copy tty.txt to roZetta author"+#CRLF$+LineIn)
            EndIf
          Else
            MessageRequester("Serial Port Enumeration","Unexpected dmesg format - Copy tty.txt to roZetta author"+#CRLF$+LineIn)
          EndIf  
        EndIf
      EndIf
    Wend
    CloseFile(0)
  EndIf 
  SortList(ComPorts(),0)
  ForEach ComPorts()
    If FindString(ports,ComPorts(),1)=0   ;avoid duplicates
      If Len(ports):ports+",":EndIf
      ports+ComPorts()
    EndIf
  Next
;Debug ports  
  OpenPreferences(AppPath+"serial.prf"):PreferenceGroup("port")
    WritePreferenceString("found",ports)
  ClosePreferences()  
EndProcedure
I still have to dig a couple of USB-RS232 adapters out of my parts bin and plug them in to my Mac Mini. How does OSX report their presence?
Last edited by dhouston on Fri Oct 08, 2010 7:51 pm, edited 1 time in total.
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Re: OSX, PB & USB-RS232 serial ports

Post by dhouston »

OK, installing the driver for an FTDI USB-RS232 adapter gave me enough info that I understand the serial adapter under OSX. I doubt I'll be able to automatically enumerate the ports as dmesg and fgrep seem to be missing but users can edit the app's .prf file to add any such ports.

Now, if I can resolve the PanelGadget issue (along with other cosmetic issues) I'll feel very good about PB & OSX.
aaron
Enthusiast
Enthusiast
Posts: 267
Joined: Mon Apr 19, 2004 3:04 am
Location: Canada
Contact:

Re: OSX, PB & USB-RS232 serial ports

Post by aaron »

All of your serial ports will show up as /dev/tty.* I think (but can't guarantee) that most usb to serial devices will show up at /dev/tty.usbserial.*

Rather than dmesg and fgrep, you can use the purebasic built in file system commands to grab the directory listing from /dev, throw away any entries that aren't tty. and you should be most of the way there.
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Re: OSX, PB & USB-RS232 serial ports

Post by dhouston »

aaron wrote:All of your serial ports will show up as /dev/tty.* I think (but can't guarantee) that most usb to serial devices will show up at /dev/tty.usbserial.*
Actually. my first generation FTDI (which is the only one I've tried so far) uses...
  • /dev/cu.usbserial-USAxxxxx
where xxxxx is a serial number. The FTDI documentation shows other possible variations.

I have the drivers for the Prolific PL2303 chipset but their documentation does not offer any details on how it is listed in /dev/ so I'll have to find one of mine and try it.
aaron wrote:Rather than dmesg and fgrep, you can use the purebasic built in file system commands to grab the directory listing from /dev, throw away any entries that aren't tty. and you should be most of the way there.
I hope you are right but fear it may prove too complex without knowing the specifics of each manufacturer's method. I'll probably just require users to edit a preference file. It's likely to be simpler than Linux where many multiport PCI cards have far different methods for identification. I expect the number of USB-Serial adapters to be minimal under OSX. This is one area where Windows is simpler to handle with all being listed as COMn.
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Re: OSX, PB & USB-RS232 serial ports

Post by dhouston »

Ahh! The FTDI adapter is also listed as "tty.usbserial-USA632H8" so, if the Prolific adapter uses a similar method, it might be simple to automatically enumerate them after all. I've installed the Prolific driver but still have to locate the adapter(s).

In case anyone else needs inexpensive USB-Serial adapters...
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Re: OSX, PB & USB-RS232 serial ports

Post by dhouston »

I've had a chance to test this and...

Code: Select all

If ExamineDirectory(0,"/dev/","tty.u*")
  While NextDirectoryEntry(0)
    If DirectoryEntryType(0) = #PB_DirectoryEntry_File
      MessageRequester("/dev/filename", DirectoryEntryName(0))
    EndIf
  Wend
  FinishDirectory(0)
EndIf
finds the three USB-Serial adapters I have connected. I will be modifying my Linux procedure accordingly as this is much simpler.
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Re: OSX, PB & USB-RS232 serial ports

Post by dhouston »

The code snippet below finds all the serial ports on my Intel mini but fails on my PPC iMac. I suspect I need to search a different directory(?) and/or use different search patterns. So far, I haven't figured out how to find, let alone view the contents, of /dev.

Code: Select all

  OpenPreferences(AppPath+"user.prf"):PreferenceGroup("user")
    ports = ReadPreferenceString("ports","NONE")    
    dirs = ReadPreferenceString("dirs","")    ; dirs = /dev
    patterns = ReadPreferenceString("patterns","")   ;patterns = tty.u*
  ClosePreferences()
  If ports="NONE"
    ports=""
    Protected i,j,dir.s,pattern.s
    NewList Comports.s()
    For i=1 To CountString(dirs,",")+1
      dir=StringField(dirs,i,",")
      For j=1 To CountString(patterns,",")+1
        pattern=StringField(patterns,j,",")
        If ExamineDirectory(0,dir,pattern)
          ;MessageRequester(dir,pattern)
          While NextDirectoryEntry(0)
            If DirectoryEntryType(0) = #PB_DirectoryEntry_File
              AddElement(ComPorts())
              ComPorts()=dir+"/"+DirectoryEntryName(0)              
            EndIf
          Wend
          FinishDirectory(0)
        EndIf  
      Next j
    Next i  
    SortList(ComPorts(),0)
    ForEach ComPorts()
      If FindString(ports,ComPorts(),1)=0               ;avoid duplicates
        If Len(ports):ports+",":EndIf
        ports+ComPorts()
      EndIf
    Next    
    ;MessageRequester("ports",ports)
  EndIf
EndProcedure
http://davehouston.org
Mac Mini (Intel) 10.6.8 - iMac G4 (PPC) 10.4.11
Dell Dimension 2400 W98SE,W2K,XP,Vista,W7,Debian,Ubuntu,Kubuntu,Xubuntu,Fedora,Mandriva,Mint
(on swappable HDDs)
Vizio VTAB1008 - Android 3.1
MK808 miniAndroidPC (Android 4.1)
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Re: OSX, PB & USB-RS232 serial ports

Post by dhouston »

I had overlooked the need for drivers. Both of my test serial-USB adapters (one FTDI based, one Prolific based) showed up in System Profiler but I guess it took the installation of the drivers to actually create the /dev entries.
http://davehouston.org
Mac Mini (Intel) 10.6.8 - iMac G4 (PPC) 10.4.11
Dell Dimension 2400 W98SE,W2K,XP,Vista,W7,Debian,Ubuntu,Kubuntu,Xubuntu,Fedora,Mandriva,Mint
(on swappable HDDs)
Vizio VTAB1008 - Android 3.1
MK808 miniAndroidPC (Android 4.1)
Post Reply