I'd prefer to do this using my Mac server. I'm happy to buy one of the
USB/RS-232 dongle converters if it'll do the trick.
Has anyone here used Ruby to program raw serial port communication on a
Mac (under OS X), using a converter to control something with RS-232?
If so, what USB/Serial converter did you use, how well did it work, and
can I see some of your code?
If this is going to be a big uphill battle, perhaps I'll introduce a
second house server running Windows into the mix; I just hate to waste
the energy of a box sitting in the server closet doing nothing but
poking an RS-232 port a couple times a day.
All advice appreciated.
1. ruby-serialport - a library for accessing serial ports with Ruby -
compiles and works just fine under Linux and OS X (it's a Ruby
extension). Includes a little sample program as well. Find it here:
2. USB serial port adapter - these work great with OS X (PPC and Intel
- they have a universal driver) - you can get a 1 or 4 serial port
model - we've used both, no problems:
3. Serial port server - if you need distance between your Mac and your
serial port gear, then moving up to a serial port server makes sense -
these put serial data on your TCP network - you can get wired or
wireless Ethernet versions - again, we use these and they work great
(note, there are several companies that make these, we've only tried
the Vlink and NPort from Moxa):
Whether the serial data is on a physical serial cable or a TCP network,
you deal with the remote device the same - the only difference being
how you connect to it.
Hope that helps!
That's fantastic...I had no idea such things existed. Can you show me a
small sample of how you connect to it using the ruby-serialport library
under OS X? How do you open the 'com' port via an IP address, and
(assuming I get the 4-port version) specify which port to use?
USB Serial Adapter:
You'll need the ruby-serialport library compiled and installed on OS X.
Then you'll need a KeySpan USB serial adapter. There are other
companies that make USB serial adapters but thus far, only KeySpan
seems to provide a universal driver. A driver for OS X is required no
matter which USB serial port adapter you use. If you're still using
PPC Macs, then there are several choices, but if you're on Intel Macs,
KeySpan is your best bet.
Code for USB Serial Adapter:
(NOTE: this isn't production-level code, just a sample - thus no error
# require the ruby-serialport library
# create the KeySpan single serial port USB adpater
port = SerialPort.new("/dev/tty.KeySerial1")
# KeySpan's driver also provides this sort of device name as well -
# this is needed when you're using
# more than one (like if you use their 4-serial port model)
#port = SerialPort.new("/dev/tty.USA19H7d2P1.1")
# if you use the 4-serial port USB adapter, your TTY's might look
# like this:
# /dev/tty.USA49W7d2P1.1 - 1st serial port
# /dev/tty.USA49W7d2P2.2 - 2nd serial port
# /dev/tty.USA49W7d2P3.3 - 3rd serial port
# /dev/tty.USA49W7d2P4.4 - 4th serial port
# these are documented and you can see them via Terminal, just go
# to /dev and do 'ls'
# configure the serial port
port.baud = 9600
port.data_bits = 8
port.stop_bits = 1
port.parity = SerialPort::NONE
port.flow_control = SeralPort::NONE
port.read_timeout = 0
# BTW: the stuff below here is the same if you use the USB or TCP
# approach - only the means of connecting to the serial port changes
# - the sending & receiving of data stays the same!
# all the functionality / methods of the standard Ruby IO class is
# available via ruby-serialport use IO::putc to send a single 'a'
# use IO::getc to read a single byte from the serial port
# of course you can put this in a loop and keep reading until
# something causes you to exit the loop
x = port.getc
# send a bunch of single characters
# why am I using putc and getc? for us, we're dealing with instruments
# and we need to send / receive single characters at a time - you have
# to watch out for calls like IO::readlines, as it's looking for a
# separator, which might not be there - depends on what you're
# communicating with at the other end of the serial port.
TCP Serial Server:
Just about any TCP-based serial port server should work. Most have 3
1. Virtual COM port - typically Windows only - used if you have an
existing app that communicates via COM port
2. Paired - you can tie two of the serial servers together - makes a
really long virtual serial port
3. TCP - this is what you want - you communicate over sockets to the
NOTE: you can 1, 2, 4, 8, 16 or 32 serial-port serial servers - just
depends on your needs.
In TCP mode, you can setup the serial servers two ways: (1) TCP Server
or (2) TCP Client.
I find it easier to setup the serial servers as TCP Servers, each
serial port is accessible as a separate TCP port.
So if your serial server's IP address is 192.168.123.110, then serial
port #1 might be on port 4001 while serial port #2 might be on port
You setup the baud and all of that stuff for the serial port on the
serial server itself - most have a web and telnet interface.
Code for TCP Serial Server:
# using TCP, need Ruby's standard Socket library
# connect via TCP to serial port #1
port = TCPSocket.new('192.168.123.110', '4001')
# now just use Ruby::IO methods
x = port.getc
# again, the Ruby::IO methods that work best for you and your
# needs might be different than ours
Hope that helps. It's really pretty simple - just decide which
hardware works best for you and that decides which connection method
you need to use (ruby-serialport or TCP). Once the connection to the
serial port is done, the sending & receiving of data is the same and
it's just plain ol'Ruby::IO methods.
Very helpful, thanks again!