Presentation

rPiKVM is a small interface board for the Raspberry Pi (or any other SBC with GPIOs) that makes it possible to control a standard ATX motherboard remotely (power-on, reset, serial access). It stemed from the need to be able to power on and control a consumer-grade computer remotely without the availability of OOB Management or IPMI. I document here what I came up with, for others to use and abuse. Enjoy! It’s all documented after the usual:

Disclaimer

The information and methods described herein are provided “AS-IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. Use the concepts, examples and information at your own risk. There may be errors and inaccuracies, that could be damaging to your devices. Proceed with caution, and although it is highly unlikely that accidents will happen because of following advice or procedures described in this document, the author does not take any responsibility for any damage claimed to be caused by doing so.

Design goals

My design goals were relatively simple:

  • KISS design
  • Inexpensive
  • Power drain as low as possible - No external power required
  • Can be built “by hand” and straightforward to use
  • Small form factor

Schematic

Here’s the schematic of the design:

schematic

Schematic explanation

The design is quite self-explanatory. As usual, I kept the whole design very modular, working in “banks”: 2 input banks, 2 output banks, plus one RS232 interface, each of which can be omitted in the final device without affecting functionality. The output banks consist of a classic darlington optocoupler (TIL198) which interfaces between the 3.3V-level GPIO output of the SBC and the ATX switch header. Typically, one opto will control power and the other reset. The input banks also consist of the same darlington optos, only inverted: the input is on the ATX side and the output is connected to the SBC GPIOs. The purpose of this arrangement is to be able to monitor for instance the LED states from the SBC.

Each of these opto-coupled input/output banks provide full galvanic isolation, making interfacing GPIOs with random voltages (within the TIL198 capabilities) safe. The reason for using polarized optocouplers (which require a little prepwork, see below) instead of e.g. analog switches which wouldn’t care about polarity is to keep costs low and provide galvanic isolation.

Finally, an ubiquitous MAX3232 provides the necessary RS232 voltage conversion: SBCs’ UARTs typically operate at LVTTL levels (0-3V); whereas RS232 voltage levels are completely different and would immediately fry the SBC without proper adaptation.

The circuit can either be entirely powered from the SBC (in which case it is not necessary to connect pin 1 (+5V) on the headers), or it can back power the SBC from e.g. the host computer. To that extent, it is possible to tap (using a T-tap) into the ATX 5VSB (5V Stand-By), which, on ATX2.x-compliant power supplies, can provide at least 2A. Pin 1 on both the PC and PI headers is a convenience to achieve this. 5V is not used anywhere on the design, only the 3.3V rail is required for the operation of the MAX3232. If the MAX3232 is not used, then it is not necessary to provide this voltage either.

Note on resistor values

The schematic does not mention the values of the resistors, that’s because there is no definitive answer. Typically, ATX motherboards will provide +5V with an onboard current limiter for the LED outputs, while the SBC GPIOs will typically be 3.3V. For proper biasing, the forward current of the TIL198 LED input should be over 2mA, with a typical forward drop voltage of 1.2V. For 3.3V GPIOs, a 1kΩ resistor will work just fine. For the ATX LED outputs, the calculation is a little trickier as it depends if you connect the case LEDs or not on the CASE header. 1kΩ is known to work without the case LEDs connected, it may also work with.

Pull-up resistors

There is no pull-up resistors on the design, it was deemed unnecessary as most SBCs will provide internal pullups. For the proper operation of the input banks (to interface with LED outputs), pullups should be enabled on the designated GPIO.

Layout

Here’s a simple two-sided, hand-routed layout that fits on 30x38mm PCB.

board

Resistors are mounted vertically for obvious space reasons, two 2.8mm mount holes are provided. 3 testpoints allow measuring 5V and 3.3V voltages as needed.

Note: the ATX pin headers for switches and LEDs are polarized. The polarity of the LED outputs is usually provided, but the polarity of the switches most often is not. While the optocoupler should endure a reverse polarity connection, it is recommended to check polarity with e.g. a multimeter before assembly.

The silkscreen makes it very clear which pin is the positive and negative side.

The PC header is meant to connect to the adequate ATX pin headers, while the CASE header is provided to connect in parallel the case buttons and/or LEDs.

Final words

I’m successfully using this device to interface a NanoPi NEO with an MSI motherboard, it enables me to control power and reset and monitor the power and HDD LEDs status, while accessing the motherboard serial port via Minicom: it works very nicely and turns out to be very cheap.

Using libgpiod, turning on power can be as simple as:

gpioset -m time -s 1 gpiochip0 0=1
gpioset gpiochip0 0=0

if the opto trigger for power is connected to gpio 0:0.

Reading LED status can be achieved with:

gpioget -l -B pull-up 0 2

if the opto output is connected to gpio 0:2.