Click here to Skip to main content
15,860,972 members
Articles / Programming Languages / Java

Remote Boot and Power Control a PC Slave

Rate me:
Please Sign up or sign in to vote.
4.93/5 (58 votes)
23 Jul 2014CPOL7 min read 102.2K   109   21
Remotely controlling a PC to turn it on and off from software control on another PC.

Summary

Remotely controlling a PC to turn it on and off from software control on another PC. This is useful in driver and other development testing.

Introduction

I'm working heavily on C# Open Source Operating System (Cosmos). While VMware is great, its even better to test on real hardware. To do this I wanted to make the deployment automatic, but this required some custom work. Booting could be done using PXE, and debugging through a null modem serial cable. But who wants to manually turn on and off the PC for every build?

To solve this problem I needed to find a way to turn the slave PC on and off using software on my main PC. A few alternatives were first considered.

WOL (Wake On LAN)

A magic packet can be sent across the network containing the MAC address of the PC to turn it on. However WOL has no facility to turn off or reset.

USB Power Controllers

Amazon has a bunch of USB and Ethernet based power switches that turn on and off a power socket. PCs can be programmed to restore after a power loss. However these tended to be very expensive, and the lower end ones had horrible comments about quality. These would also not provide perfect control for what I needed.

Custom Solution

I found a blog that discussed several attempts by an end user to do exactly what I was doing by using the lines of a serial port. Its actually more complicated than one would think because isolation is required using at minimum opto couplers. The schematic required some very specific parts however that were hard to come by.

Relay Controllers

I found several ready to go relay controllers for purchase. I evaluated many of them and finally settled on the CanaKit UK1104. It costs $59.95 plus shipping. It supports 4 relays, and also has input sensors which I can use to detect the PC state. This is actually important, because toggling the power switch is used to both turn on and off the PC, so I needed to know if I was about to turn it on, or off.

To use the relays, you also need a +9V or +12V power supply. I have hooked many 12V applications to the computer PSU, but since the device is actually used to turn the PC on, and there are no always on +12V lines on an ATX computer PSU, the additional power supply is needed.

Choosing a Motherboard

Everything else in the PC is standard and many are used parts I got from a computer repair facility. In my case I needed a few specific items on the motherboard:
 

  1. On board Ethernet with PXE boot. Most boards have this.
  2. Serial port, or serial header.
  3. Inexpensive.
  4. On board video

After some evaluation I settled on the Intel D425KT. Its a Mini-ITX board with on board serial, and a second serial available via headers. It has an on board Atom CPU and costs about $50 wholesale, or $60-$75 retail.

Building the PC

First, I built the PC and made sure it worked normally. Next step was to add the relay board and make some custom changes to the wiring. Assembled the PC looks like this.

Image 1

Now lets examine the front panel header of the motherboard. Every motherboard's pin locations are different so its important to look in your manual for proper connections. Wrong connections can short out your board.

Image 2
The connections we are interested in are in green and red. To make the connections easy, find an old case and get the power light and power switch. They will have connectors that can be used to ensure shorts do not occur. Sometimes they wont match exactly but they can be separated and leads can be extracted with a small knife and rearranged.

Image 3
(Note, this is not the D425KT in this photo)

First we need to connect up the power switch to 6 and 8. Cut the power cable and wire it to COM and NO on one of the relays. I used relay 4. COM is ground, and NO is shorted to COM when the relay is on. NC is shorted to COM when the relay is off, but we don't need that in our application. Since it is a switch, there is no polarity and it doesn't matter which one pins 6 and 8 are connected to, so long as one is connected to COM and one to NO. The relays are screw down terminals, so no soldering is required, just a small screwdriver. I also spliced back the original physical switch and connected it directly to the relay to form the splice so I can still manually operate the PC.

Next we need to connect the Power LED. This is a +5 line that is powered when the PC is on. Its used to connect the power light, but since its +5V we can use it to sense if the PC is on or off. To do this cut the power line and attach the +5 line to channel 1 on the controller card. Only the +5 line is used, the ground remains only to the motherboard. On the line, the coloured one is used for positive and the plastic connector is usually marked as well.

Image 4

If  one is not coloured and the other white, they may be red and black instead. Red is always positive, and black is always ground. Less common in these wires is the stripe system because they are smaller.

Image 5

If they are both white, one will have a stripe. The one with the stripe is positive.

I also spliced the light back in this as well so I have a visible indicator as well. To attach to the board which has pins for sensors, I cut off the plastic connector from the hard drive light and used it. Not all the channels are equal and some use different voltage levels. For our use probably any would work (TTL or Schottky), but Schottky is a bit better for our use so I chose channel 1.

Image 6

So after we are done it should look something like this.

Image 7



Or the real life version.

Image 8

Finally since the PC will be booted over the network and use the serial for debugging, there are important connections on the back as well.

Image 9

Software

Now we are ready to go! The relay controller installs as a USB to serial, which means it can be addressed with a terminal program or very easily with any programming language by using a serial port.

Image 10

The relay controller operates on series of text commands listed in the manual. To test it we can now open a terminal program and issue some commands. This is TeraTerm, a free terminal program.

Image 11

Image 12

First we check the state of Channel 1. Its 0, this means the computer is off.

Then we have to toggle the switch since power switches are push and release. That is we simulate it being pushed and released by turning on the relay and turning it off. In software make sure you delay about 500ms between on and off for the motherboard to recognize the press. Remember, we are simulating a human finger.

Finally we check channel 1 again, and we can see the computer is now on.

One of the other relays could be hooked to the reset pins, but its not needed. To reset the PC, simply turn it off, then back on. To turn it off is the same as it is to turn it on, just "push" the button.

Video 

I have also posted a video of this system in action.

Image 13

Source

The source code used in this video can be extracted easily from the Cosmos project source. Here is the relevant code as used in Cosmos (C# Open Source Operating System)

 

C#
<pre wrap="true">using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO.Ports;
using Cosmos.Build.Common;

namespace Cosmos.Debug.VSDebugEngine.Host {
  public class Slave : Base {
    string mPortName;
    SerialPort mPort;
    Thread mPowerStateThread;

    public Slave(NameValueCollection aParams, bool aUseGDB)
      : base(aParams, aUseGDB) {
      var xPort = mParams[BuildProperties.SlavePortString];
      if (xPort == "None") {
        throw new Exception("No slave port is set.");
      }

      var xParts = xPort.Split(' ');
      mPortName = xParts[1];
    }

    string WaitForPrompt() {
      var xSB = new StringBuilder();
      char xLastChar = ' ';
      char xChar = ' ';
      while (true) {
        xLastChar = xChar;
        xChar = (char)mPort.ReadChar();
        xSB.Append(xChar);
        if (xChar == ':' && xLastChar == ':') {
          break;
        }
      }
      // Remove ::
      xSB.Length = xSB.Length - 2;
      return xSB.ToString();
    }

    void TogglePowerSwitch() {
      Send("REL4.ON");
      Thread.Sleep(500);
      Send("REL4.OFF");
    }

    bool IsOn() {
      var xResult = Send("CH1.GET").Split('\n');
      return xResult[1][0] == '1';
    }

    string Send(string aData) {
      // Dont use writeline, it only sends /n or /r (didnt bother to find out which, we need both)
      mPort.Write(aData + "\r\n");
      return WaitForPrompt();
    }

    void WaitPowerState(bool aOn) {
      int xCount = 0;
      while (IsOn() == !aOn) {
        Thread.Sleep(250);
        xCount++;
        // 5 seconds
        if (xCount == 20) {
          throw new Exception("Slave did not respond to power command.");
        }
      }
    }

    public override void Start() {
      mPort = new SerialPort(mPortName);
      mPort.Open();

      Send("");
      // Set to digital input
      Send("CH1.SETMODE(2)");

      if (IsOn()) {
        TogglePowerSwitch();
        WaitPowerState(false);
        // Small pause for discharge
        Thread.Sleep(1000);
      }

      TogglePowerSwitch();
      // Give PC some time to turn on, else we will detect it as off right away.
      WaitPowerState(true);

      if (OnShutDown != null) {
        mPowerStateThread = new Thread(delegate() {
          while (true) {
            Thread.Sleep(1000);
            if (!IsOn()) {
              mPort.Close();
              OnShutDown(this, EventArgs.Empty);
              break;
            }
          }
        });
        mPowerStateThread.Start();
      }
    }

    public override void Stop() {
      if (mPowerStateThread != null) {
        mPowerStateThread.Abort();
        mPowerStateThread.Join();
      }

      if (IsOn()) {
        TogglePowerSwitch();
        WaitPowerState(false);
      }
      mPort.Close();
    }
  }
} 

 

 

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Cyprus Cyprus
Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

I am a former Microsoft Regional DPE (MEA) covering 85 countries, former Microsoft Regional Director, and 10 Year Microsoft MVP.

I have lived in Bulgaria, Canada, Cyprus, Switzerland, France, Jordan, Russia, Turkey, The Caribbean, and USA.

Creator of Indy, IntraWeb, COSMOS, X#, CrossTalk, and more.

Comments and Discussions

 
GeneralMy vote of 5 Pin
D V L23-Jun-16 6:19
professionalD V L23-Jun-16 6:19 
QuestionVery nice Pin
Mike Hankey7-Sep-13 14:41
mveMike Hankey7-Sep-13 14:41 
QuestionLooks good ... but as for USB Power Controllers... Pin
i0022-May-13 1:23
i0022-May-13 1:23 
AnswerRe: Looks good ... but as for USB Power Controllers... Pin
Chad Z. Hower aka Kudzu22-May-13 2:32
Chad Z. Hower aka Kudzu22-May-13 2:32 
GeneralRe: Looks good ... but as for USB Power Controllers... Pin
i0022-May-13 12:44
i0022-May-13 12:44 
GeneralRe: Looks good ... but as for USB Power Controllers... Pin
Chad Z. Hower aka Kudzu22-May-13 12:46
Chad Z. Hower aka Kudzu22-May-13 12:46 
GeneralRe: Looks good ... but as for USB Power Controllers... Pin
i0022-May-13 15:07
i0022-May-13 15:07 
GeneralRe: Looks good ... but as for USB Power Controllers... Pin
Chad Z. Hower aka Kudzu28-May-13 3:08
Chad Z. Hower aka Kudzu28-May-13 3:08 
GeneralMy vote of 5 Pin
p_a_k29-Jan-13 22:51
p_a_k29-Jan-13 22:51 
GeneralMy vote of 5 Pin
Yusuf Uzun16-Aug-12 0:16
Yusuf Uzun16-Aug-12 0:16 
GeneralMy vote of 5 Pin
Ștefan-Mihai MOGA8-Aug-12 5:45
professionalȘtefan-Mihai MOGA8-Aug-12 5:45 
Generalthats something amazing Pin
Xmen Real 14-Jul-12 18:29
professional Xmen Real 14-Jul-12 18:29 
GeneralRe: thats something amazing Pin
Chad Z. Hower aka Kudzu15-Jul-12 2:33
Chad Z. Hower aka Kudzu15-Jul-12 2:33 
GeneralRe: thats something amazing Pin
Xmen Real 15-Jul-12 2:38
professional Xmen Real 15-Jul-12 2:38 
GeneralMy vote of 4 Pin
Casey Sheridan11-Jul-12 4:40
professionalCasey Sheridan11-Jul-12 4:40 
GeneralA socket application can achieve this Pin
Yajnesh Narayan Behera2-Jul-12 20:50
Yajnesh Narayan Behera2-Jul-12 20:50 
GeneralRe: A socket application can achieve this Pin
Chad Z. Hower aka Kudzu3-Jul-12 4:03
Chad Z. Hower aka Kudzu3-Jul-12 4:03 
GeneralRe: A socket application can achieve this Pin
Yajnesh Narayan Behera3-Jul-12 7:40
Yajnesh Narayan Behera3-Jul-12 7:40 
GeneralMy vote of 5 Pin
Dr Bob2-Jul-12 14:10
Dr Bob2-Jul-12 14:10 
GeneralMy vote of 5 Pin
newton.saber2-Jul-12 4:07
newton.saber2-Jul-12 4:07 
QuestionThat's pretty wild stuff Pin
Sacha Barber1-Jul-12 22:28
Sacha Barber1-Jul-12 22:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.