In 2025 I bought an ODROID H4 Ultra. It was a bit of an experiment.
Could this tiny board be a hassle-free replacement for the Supermicro
server boards I’ve grown to love? Turns out the answer is absolutely yes
for a homelab. With 8-cores and 4 SATA ports, it’s quite capable for NAS
duty and the like.
The ODROID H4 Ultra
Problem: No BMC
There was one key component missing that every server board has: a BMC/IPMI
device. A BMC is a system on your motherboard that let’s you do things
regardless of whether an operating system is actually running. You can
load the BMC’s web UI and see the console, you can use something like ipmitool to issue a hard
reset from another computer, and on and on. It’s quite handy as you can
stick your server in a garage, or attic, or basement, or wherever you
want it and control it as if you had physical access.
But the ODROID doesn’t have a BMC. This is no surprise. No boards of
this size do (that I’m aware of). But! As I mentioned, a BMC is just a
system on your motherboard. So if we have an extra system, then we can
replicate a BMC.
The ODROID H4 Ultra’s I/O Expansion GPIO (EXT_HEAD1) Map
In this case, there are 5 pins that will help us to replicate a
BMC/IPMI experience. Pins 6, 8, and 10 can connect to any USB-to-TTL
cable and allow remote console access. Pins 17 and 19 can be used to
wire up an actual physical power button. But we want remote access. So
we need something that can simulate a physical button press.
Solution Component 1:
An Optocoupler Relay
An optocoupler 3.3V relay is the essential component to this whole
solution. It is the thing that effectively “pushes the button.” The term
“optocoupler relay” essentially means “a device capable of receiving a
digital signal from device A and relaying it to device B in the form of
a 3.3V signal.”
Optocoupler 3V/3.3V Relay
If you look at the right side of that device, you’ll see the 3.3V
relayed signal side. This is what will connect to pins 17 and 19 on the
ODROID.
Solution
Component 2: An USB-to-TTL Serial Adapter Cable
The other thing we’ll need to monitor the ODROID during a reboot is a
USB-To-TTL
Serial Adapter Cable. You’ll find lots of options on sites like
Amazon. I’d take the size of the USB casing into consideration. I
originally bought a Waveshare cable, which worked, but the casing was so
big it blocked the other USB ports. Ensure the cable you get has GND
(ground), RXD (receive), and TXD (transmit) wiring. You find cables with
more than that, but unless you have a use for them I’d keep it
simple.
DTech USB-to-TTL Serial Adapter Cable
Solution Component 3: Jumper
Wires
The simplest components needed are jumper wires. Any brand will do. I
recommend buying a pack that comes with male-male, female-female, and
male-female ends. Aside from this project, these are just handy to have
around and frequently useful for a wide variety of things.
Jumper wires
Solution
Component 4: A Signal-Sending 2nd Computer
You can use any computer for this step as long as it has 3 pins: a
3.3V header, a ground header, and a programmable header. I happen to
have a Raspberry Pi 5 that sits next to the ODROID, so its GPIO
absolutely perfect.
So with the components in hand, all we need to do is connect the
right pins and headers with jumper wires. Here’s the logical mapping of
wiring necessary between devices.
Wires into ODROID H4 Ultra EXT_HEAD1
Wires from Rpi5 GPIO to Optocoupler
Power On!
Ok, let’s see it in action. First, we connect to the ODROID’s console
courtesy of our newly installed USB-to-TTL cable. I’m using picocom, but any serial
application will do. Another common one is cu.
doas picocom -b 115200 /dev/ttyUSB0
Now as we keep an eye on the console, we use a script to power on the
ODROID.
Split tmux screen: ODROID console showing BIOS (top) and RPi’s shell
(bottom).
A few seconds later we see the OS’s boot loader. Success!
It works! Like this, we can power the ODROID on or off, or hard reset
it if it happens to get stuck. We’ve replicated the most important
aspects of a BMC/IPMI interface.
The code behind the shell
script
I used the “pinctrl” package to talk to the RPi’s GPIO pins. There
are other ways, but I found this to be quite simple.
Script to automate button presses.
#!/usr/bin/env zsh
# ensuring we're running as root
if [[ "$EUID" -ne 0 ]]; then
echo "Run this script as root"
exit 1
fi
# ensure pinctrl is installed
if ! command -v pinctrl > /dev/null ; then
echo "Install pinctrl to use this script."
exit 1
fi
# Specify GPIO pin used for signal
gpio_signal_pin=17
# Specify which pinctrl options simulate press and release
button_press_signal_option="dh"
button_release_signal_option="dl"
# by default, simulate a 0.5 second button press
button_press_duration=0.5
button_press_description="quick"
# simulate a long-press/hard-reset if --long arg supplied
if [[ ! -z "${1}" ]] && [[ "${1}" == "--long" ]]; then
button_press_duration=7.0
button_press_description="long"
fi
echo "Simulating a ${button_press_duration} second ${button_press_description} button press ..."
echo " sending button press"
pinctrl set ${gpio_signal_pin} op ${button_press_signal_option}
echo " holding"
sleep ${button_press_duration}
echo " sending button release"
pinctrl set ${gpio_signal_pin} op ${button_release_signal_option}
echo "Button released. Sequence complete."
Or, if you want to skip the script, the manual equivalent from the
command line is …
doas pinctrl set 17 op dh
doas pinctrl set 17 op dl
Note: if you only issued the first command with “dh” it would be the
equivalent of pressing and holding the button and never letting go. So
don’t forget the second command!
And that’s it. We now have a fully remote-controllable ODROID with a
little help from an RPi and an optocoupler.
A Note on What Didn’t Work
In my first attempt, I used a Waveshare USB-to-TTL
device and attempted to make use of the RTS, GND, and VCC pins to issue
a reset.
Waveshare USB TO TTL Converter
This kind of worked, but there was a big problem. Plugging in the
USB, or connecting to the UART console would trigger the RTS pin and
that resulted in button presses I didn’t want. It turns out, if you want
to do this, you need a device with a DTR pin, which doesn’t trigger when
the devices is activated. With these limitations, I opted for the
optocoupler approach, which has the added benefit of fully segregating
UART/serial from button presses.