Controlling a USB Relay Board from the Mac
I have been playing lately with a USB relay board purchased from EasyDAQ. Their prices are not the cheapest by any means but their email support has been excellent. There are many different relay boards on the market and some of the cheapest appear to be on Ebay from Bulgaria, although I haven’t tried these. All the available boards I’ve seen are based around chipsets from a U.S. company called FTDI Chip. My card (pictured here) is based around the FT232BL chip and full details of this chip are available on FTDI’s website. The board is available with two relay options and I chose the ‘power relays’ with SPDT contacts that can switch up to 10A at 250v AC on the normally open contacts, and up to 7A on the normally closed contacts. It’s a useful relay which can operate most household appliances, and for higher power devices the relay board could operate a higher-rated slave relay.
The relay board can appear as a COM port on a PC. To initialise it each channel must be set as an input or output channel (relays are outputs but the chip also supports inputs, and some relay boards also offer opto-isolated inputs for devices such as burglar alarm sensors), then the relevant bit in a one-byte register is used to switch on or off a relay (16 relay boards of course have two registers, 24 relays have 3, etc). The neat thing about this arrangement is that because each USB board has its own address, the computer can control an almost infinite number of relays. The boards are self-powered from the USB bus but they have provision for an external 5v DC power supply if more than 8 relays will be closed at once.
The internet is flooded with shareware and freeware applications for these relay boards. There are numerous example programs in Visual Basic and C# but all the examples I could find were for Windows PCs. This is a good example of Mac users being at a disadvantage. EasyDAQ assured me that OS/X and Linux already had the drivers built-in but in my experience this isn’t the case. However I downloaded and installed a driver from FTDI’s website and instantly my board appeared in the Mac’s file-system as /dev/cu.usbserial-000012FD (the suffix being the board’s unique address; another board would have a different address). I could operate the relays from a Unix terminal window like this:
echo -e “B\x00″ > /dev/cu.usbserial-000012FD
This command initialises the 8 channels on the board as outputs. It only needs to be sent once when the relay board is first powered up. Having sent that one command, the relays can be switched on and off as shown in this example:
echo -e “C\x1f” > /dev/cu.usbserial-000012FD
This sends the byte 1F to register C, switching on relays 1, 2, 3, 4, & 5 (relays are numbered from 1, starting at the least significant bit). The trouble is, when I attempted to replicate this in an Applescript I couldn’t find a way to send the byte to the board rather than the ASCII characters (i.e. ‘1′ and ‘F’) that described the value of that byte. In the end the solution seems to be to place the actual bytes in a text file and send that file (or rather, its contents) to the board. Note that you need a text editor that can insert non-printing characters into the text file; the Unix vi editor can do this, allowing Ctrl+A as ASCII 1 which will operate relay 1, Ctrl+C as ASCII 3 which operates relays 1 and 2, etc. So my shell script became:
cat /users/chris/Library/scripts/Relay01.txt > /dev/cu.usbserial-000012FD
Looking at this now it’s blindingly obvious but it took me over a day to get to this point with some help from a Mac forum. My Unix days are too long ago. Having achieved this it was another faltering step to learn enough Applescript to encapsulate this shell script. The answer is:
do shell script “cat /users/chris/Library/scripts/Relay01.txt > /dev/cu.usbserial-000012FD”
Having mastered this I could draw all these bits together. The comprehensive rules facility in the OS/X built-in email client allows an Applescript to be executed when certain conditions are satisfied. I wired a mains socket to relay 1 and plugged my Anglepoise desk lamp into it, and created a couple of email rules. Now, when an incoming email arrives from my personal email address with my preset password in the subject line, and a command in the body of the email, the relay is activated.
You can see here photos of a demonstration (my apologies for the poor quality, I struggled to compose the shot to show the email on the Mac’s screen, the relay board, and the desk lamp). I also had difficulty getting the exposure right for the lamp being on and off so please take my word for it that it really does work. The command in bold red text in the email is purely for demonstration purposes. The font and colour are actually irrelevant. Since many mobile devices can send emails this ‘proof of concept’ demonstration shows how an email sent from anywhere can instruct the Mac to control an external device via the relay board. In theory you could switch the heating on when returning from holiday, or control various lights in the house to deter intruders.
Finally I slightly adapted a public-domain Xcode project written by Michael Cohen in Australia for the same relay board to provide an application giving direct control of the relays at the click of a mouse. Its simple user interface is shown here.
on July 29th, 2009 at 10:53 pm
We have also found the EasyDAQ USB relay cards very useful for our automated test suite and have written a Linux server to control multiple boards, if anyone is interested. They are pretty useful boards. However, while we also found initially EasyDAQ were helpful, they have been less than helpful when one of the six boards we purchased developed an intermittent fault very soon after we purchased it. The PIC and oscillator have been replaced and the card is now functioning but we currently find ourselves out of pocket as EasyDAQ still claim there was no fault with the card. Can anyone recommend an alternative supplier of similar USB relay cards? Amplicon are a bit pricy for us.
on August 2nd, 2009 at 3:13 pm
I have just recieved a 8 port usb relay board from http://www.denkovi.com/ . I have been looking for some Linux based programming examples and stumbled on this page. The cost of this unit was $55.00 us.
on August 8th, 2009 at 6:38 am
I mentioned in this post that I couldn’t find a way to send non-printing ASCII characters to the relay board using Applescript. The work-around was to place the characters in a text file (the Unix vi editor allows you to insert non-printing characters into a file) and send this file to the board.
Now, thanks to assistance in the excellent Apple programming forum on macrumors.com I have a simpler solution. Using only Applescript you can use the following command:
set testString to "echo 'C" & (ASCII character (92)) & "x03' > /dev/cu.usbserial-000012FD"do shell script testString
The 03 is a hexadecimal byte that is sent to the board, and will switch on relays 1 and 2. Sending 0B will switch on relays 1, 2, and 4. Sending FF will switch all eight on, and so on. Sending 00 switches them all off.
on May 7th, 2010 at 1:51 pm
I use an Applescript with Serial Bridge to control the same relay board. With SB I can poll the board to get the hex number which indicates what relays are on and off. The script calculates the “position” of the board” and, depending on what relay you want on or off, calculates the new hex number to be sent to the board. Can you poll the board from the terminal? I tried “echo -e “A\x00″ > /dev/cu.usbserial-000012FD” with no success.
on May 7th, 2010 at 7:58 pm
Hi Bob,
I haven’t tried polling my board on port A but if SB can do it I would expect it to work via Terminal too. My Mac has been running iDefrag for the last 6 hours and hasn’t finished yet but when it does I’ll give this a try myself and post another comment here within 24hrs.
Chris
on May 8th, 2010 at 7:22 am
I have now considered this question of polling the board more carefully. Product Datasheet 34 from EasyDAQ states:
This suggests that you can indeed poll the board. I haven’t been able to find any examples of how this is achieved in the Unix shell.
I found a similar question, but sadly no answer, here:
http://www.linuxquestions.org/questions/linux-networking-3/reading-data-from-a-serial-port-262496/
Chris