Monday, 28 November 2011

Using the parallel port

Initially the plan for the tank was a NetDuino, but as we are not experts with microcontrollers, it seems like simply sending commands to the NetDuino via USB is not a common use. The USB is more suitable to load programs, not communication. It can definitely be done, but does not seem simple.

The new plan

This made us turn to more basic methods and I discovered the parallel port!
We found an old laptop in the garage that has 1x USB port and 1x parallel port.
So instead of using a small lightweight NetDuino, we plan on using a full blown computer!

The setup will (hopefully) include a Sinatra/Rails webapp running which will control the parallel port, and therefore control the motors for movement, firing, etc.
This webapp should be mobile browser friendly and with the help of a PCMCIA wifi card that has the ability to be put into master mode, the tank should broadcast its own wifi network so there is no reliance on being close to a router (for field tests).
The web interface should also provide a video stream from the webcam(s) so hypothetically you could control it without line of sight.

I did a simple test to see how easy using the parallel port from Ruby was and documented it over at my blog here:

It worked well, and because we intend on using Ruby on the server side it should be quite easy to setup control via a web page :)

Using /dev/port

The method I documented takes advantage of the /dev/port special file.
This provides a map of every IO port on the system and requires privileged access.
The address of the parallel port is pretty standard and google will generally suffice, but you can discover the address of this port by searching through /proc/ioport.

As mentioned in my blog post, there are 8 data pins, and using /dev/port makes turning these pins on and off really easy.
All you have to do is open the file for writing, seek to the address of the parallel port and write 1 byte (8 bits) where each bit corresponds to a pin. If you want to change the state of the port, you simply seek back and overwrite it again.

Here is my example script.

This method requires root access by default and can be dangerous if other parts of the file are tampered with, so linux provides another way of access the IO ports.

Using /dev/parport0

This method uses the Linux IOCTL mechanism.
I'm no expert with this stuff, but I have a much better understanding of how this works now than when I was just using /dev/port.
This method is similar, but there is a permissions system in place that requires the process that wants access to the parallel port to request it from the OS first.

First you need to open /dev/parport0 as a file for writing as usual, then you need issue an IOCTL to claim that port. Once you can claimed it for use, you can then issue other IOCTL commands for reading and writing and once your done, you need to issue an IOCTL to release it back to the OS again.

This is a bit more complicated that the last method, but it seems like the proper way to do it. IOCTL is a very Linux / C thing, but luckily the Ruby IO library contains a basic implementation.

Here is my example script.

As you can probably see, the IOCTL commands are just constants which I needed to look up to find. I found another Ruby example which is much more complete here.


Post a Comment