How to build a cheap USB on off relay
Summary
This is a step by step guide on how to build a cheap USB relay (around $3) that can turn the USB port power on and off from software.Basic idea
The idea came from the famous lava lamp alert system where you can switch a power socket on and off. I thought it sounded like a fun project but $40 was a bit too much considering I was just playing around. So I decided that I would try to build the USB relay as cheap as possible where I could turn the power of an USB port on and off by software.That way you can be alerted by your favorite USB toy when your server is running out of diskspace, if your build server says the build is broken or whatever you decide.
Limitations
Since the USB data signal is used to communicate with the serial port this project will only run on dumb USB toys that does not require any data signals but will just run when they get some power.First try failed
First attempt was to dig deep into windows registry and see if it was possible to disable a USB port. But, alas, that is not possible. Apparently the USB ports are always on in order to power the devices that will be connected. So I decided to go for hardware instead.Tools
- Soldering iron
- Wire cutter
Required parts
- USB Serial port adapter
- IRF9540N Power MOSFET P-Channel 23A 100V
- USB extension cable
Description on how to build it
So I had to do it by hardware and I chose to use a USB to serial port since they are very cheap. You can buy one for $2 on ebay including an extension cable and free delivery. The MOSFET I used cost around $1. It is fairly easy to build since there is only three parts to connect. The basic idea is to send a signal to the serial port which will trigger the MOSFET.
The diagram below shows how to connect the three parts:
So let's get started!
Step by step guide
Step 1
Cut the serial cable around 15 cm from the serial adapter and find the ground and +5V wires. The +5V wire is usually red while the ground will be black. Solder some extra wires on ground and +5V and connect the four wires again.Step 2
Solder a wire to pin 3 of the serial cableStep 3
Connect the wire from pin3 to the left leg of the MSOSFET called GateStep 4
Connect the +5V wire from step 1 to the middle leg of the MOSFET called DrainStep 5
Connect a wire from the right leg of the MOSFET called Source.Step 6
Cut the USB extension cable and throw away the male part. Now connect the +5V of the female part to the wire from step 5. Connect the ground leg of the USB to the ground wire from step 1.Testing the USB relay
You should now have a working USB relay. To test it first connect the male USB to your computer. You should get a "found new hardware" and the driver should be downloaded automatically:
Now connect your favorite USB toy.
Then download Realterm or some similar software that can change the pins of a serial port. Select the correct port in the port tab:
Finally go to the pins tab and click on the "set break" and "clear break":
You should now see your USB toy turn on and off.
Source code for java
import gnu.io.CommPort; import gnu.io.CommPortIdentifier; import gnu.io.SerialPort; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; //http://yengal-marumugam.blogspot.dk/2012/04/serial-port-manipulation-in-java.html //http://www.cloudhopper.com/opensource/rxtx/ //http://rxtx.qbang.org/wiki/index.php/Download#x64_Binaries /** * Connects to a serial port and turns the USB power on or off * * @author theis.borg * */ public class USBOnOffSwitch { public static boolean keepRunning = true; public static boolean off = true; SerialPort serialPort; static String detectedPort = ""; /** * the main program that receives user input and a thread that communicates with the COM port * * @param args */ public static void main(String[] args) { new USBOnOffSwitch(); } /** * detects all ports and uses the last detected serial port */ static void detectPorts() { java.util.EnumerationportEnum = CommPortIdentifier.getPortIdentifiers(); while (portEnum.hasMoreElements()) { CommPortIdentifier portIdentifier = portEnum.nextElement(); if (portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL) { detectedPort = portIdentifier.getName(); } System.out.println("Found port: " + portIdentifier.getName() + " - " + getPortTypeName(portIdentifier.getPortType())); } if (detectedPort.equals("")) { System.out.println("No serial ports found"); System.exit(0); } } /** * writes the type of a COM port * * @param portType * @return */ static String getPortTypeName(int portType) { switch (portType) { case CommPortIdentifier.PORT_I2C: return "I2C"; case CommPortIdentifier.PORT_PARALLEL: return "Parallel"; case CommPortIdentifier.PORT_RAW: return "Raw"; case CommPortIdentifier.PORT_RS485: return "RS485"; case CommPortIdentifier.PORT_SERIAL: return "Serial"; default: return "unknown type"; } } /** * Starts a thread that handles communication to the COM port and receives * user input in order to turn the USB power on or off */ public USBOnOffSwitch() { detectPorts(); // if you have multiple COM ports on your computer you may wish to connect to a specific one, i.e. connect("COM5"); connect(detectedPort); Thread portThread = new Thread(new Runnable() { public void run() { while (keepRunning) { if (off) { serialPort.sendBreak(500); // off }else{ try { Thread.sleep(500); } catch (InterruptedException e) { } } } serialPort.close(); System.out.println("Thread stopped"); } }); portThread.start(); while (keepRunning) { try { System.out.println("Enter something (ON, OFF, STOP): "); BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in)); String s = bufferRead.readLine(); if (s.equalsIgnoreCase("ON")) { off = false; } if (s.equalsIgnoreCase("OFF")) { off = true; } if (s.equalsIgnoreCase("STOP")) { keepRunning = false; } System.out.println(s); } catch (IOException e) { e.printStackTrace(); } } System.out.println("USB on off stopped"); } /** * Connects to the specified serial COM port * * @param portName */ void connect(String portName) { try { CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); if (portIdentifier.isCurrentlyOwned()) { System.out.println("Error: Port is currently in use"); } else { CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000); if (commPort instanceof SerialPort) { serialPort = (SerialPort) commPort; serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } else { System.out.println("Error: Only serial ports are handled by this example."); } } } catch (Exception e) { System.out.println("Error: could not connect to port."); System.exit(0); } } }