C/Python library — transparently control LEGO SPIKE Prime devices via Raspberry Pi Build HAT.
libspikehat is a shared library that directly implements the Raspberry Pi Build HAT serial protocol.
Both C and Python applications can control the same devices through the same library —
C apps link against it directly, Python apps use it via ctypes.
┌───────────────┐ ┌─────────────────────┐
│ C app │ │ Python app │
└──────┬────────┘ └──────────┬───────────┘
│ │ ctypes
└────────────┬──────────────┘
┌─────▼──────────────────────┐
│ libspikehat.so │
│ (Build HAT protocol impl) │
└─────┬──────────────────────┘
│ UART /dev/serial0 (115200 baud)
┌─────▼──────────────────────┐
│ Build HAT │
└────────────────────────────┘
| Device | Constant | Features |
|---|---|---|
| SPIKE Prime M Angular Motor | SPIKEHAT_DEVICE_MOTOR_M |
PWM, speed control, position readout |
| SPIKE Prime L Angular Motor | SPIKEHAT_DEVICE_MOTOR_L |
Same as above |
| SPIKE Prime Color Sensor | SPIKEHAT_DEVICE_COLOR |
HSV value readout |
| SPIKE Prime Distance Sensor | SPIKEHAT_DEVICE_DISTANCE |
Distance (mm) readout |
| SPIKE Prime Force Sensor | SPIKEHAT_DEVICE_FORCE |
Force (N) and pressed state readout |
- Raspberry Pi 4
- Raspberry Pi Build HAT
- Raspberry Pi OS Bookworm (64-bit) — see warning below
sudo apt install python3-build-hat(for firmware loading)gcc,cmake >= 3.15
Warning: OS version (as of May 2026)
As of May 2026, the latest Raspberry Pi OS is Trixie, but
python3-build-hatand the Build HAT firmware have only been verified on Bookworm.python3-build-hatis not available on Trixie, and this library will not work there. When using Raspberry Pi 4 + Build HAT, please use Bookworm (Debian 12).
git clone https://github.com/kuboaki/libspikehat.git
cd libspikehat
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j4Build outputs:
build/libspikehat.so— shared librarybuild/test_motor— C sample (motor)build/test_sensor— C sample (sensor)
The Build HAT firmware is managed by python3-build-hat.
Before using this library for the first time, follow these steps.
Install python3-build-hat:
sudo apt install python3-build-hatLoad the firmware onto the Build HAT (only needed once):
python3 -c "from buildhat import Motor"This step is not required on subsequent runs.
#include "spikehat.h"
int main(void) {
spikehat_t *hat = spikehat_open("/dev/serial0");
// Port configuration (A=0, B=1, C=2, D=3)
spikehat_port_config(hat, 0, SPIKEHAT_DEVICE_MOTOR_M);
spikehat_port_config(hat, 3, SPIKEHAT_DEVICE_DISTANCE);
sleep(1);
// Motor: run at speed 5 for 2 seconds, then reverse at speed -3
spikehat_motor_run_for_seconds(hat, 0, 2.0f, 5);
// reverse
spikehat_motor_run_for_seconds(hat, 0, 2.0f, -3);
// Distance sensor readout
int mm;
if (spikehat_distance_read(hat, 3, &mm) == 0)
printf("Distance: %d mm\n", mm);
spikehat_close(hat);
return 0;
}Compile:
gcc myapp.c -I/path/to/libspikehat/include \
-L/path/to/libspikehat/build -lspikehat -lpthread \
-Wl,-rpath,/path/to/libspikehat/build -o myappimport sys
sys.path.insert(0, '/path/to/libspikehat/python')
from spikehat import SpikeHat, DEVICE_MOTOR_M, DEVICE_DISTANCE
with SpikeHat() as hat:
hat.port_config(0, DEVICE_MOTOR_M)
hat.port_config(3, DEVICE_DISTANCE)
# Motor: run at speed 5 for 2 seconds, then reverse at speed -3
hat.motor_run_for_seconds(0, 2.0, 5)
# reverse
hat.motor_run_for_seconds(0, 2.0, -3)
print(f"Distance: {hat.distance_read(3)} mm")| Function | Description |
|---|---|
spikehat_open(device) |
Open the Build HAT. device is typically "/dev/serial0" |
spikehat_close(hat) |
Stop all devices and close |
spikehat_port_config(hat, port, type) |
Assign and initialize a device type on a port |
| Function | Description |
|---|---|
spikehat_motor_pwm(hat, port, power) |
Direct PWM control (-1.0 to +1.0) |
spikehat_motor_start(hat, port, speed) |
Start rotating at given speed (-100 to +100) |
spikehat_motor_run_for_seconds(hat, port, sec, speed) |
Run for specified seconds |
spikehat_motor_run_for_degrees(hat, port, deg, speed) |
Run for specified degrees (negative speed = reverse) |
spikehat_motor_stop(hat, port) |
Stop (coast) |
spikehat_motor_coast(hat, port) |
Coast to stop |
spikehat_motor_get_speed(hat, port, *speed) |
Get current speed |
spikehat_motor_get_position(hat, port, *degrees) |
Get current position (degrees) |
Note: The seconds parameter of spikehat_motor_run_for_seconds specifies the
duration of the constant-speed phase only. Including the built-in
acceleration/deceleration ramp, the motor may keep moving for a few seconds
(roughly 2-5 seconds longer, depending on speed) after the specified time
before it fully settles.
| Function | Description |
|---|---|
spikehat_distance_read(hat, port, *mm) |
Get distance in millimeters |
spikehat_color_read_hsv(hat, port, *h, *s, *v) |
Get color as HSV |
spikehat_color_read_rgb(hat, port, *r, *g, *b) |
Get color as RGB (0–255 each) |
spikehat_force_read(hat, port, *force, *pressed) |
Get force (N) and pressed state |
spikehat_force_is_pressed(hat, port, *pressed) |
Get pressed state only |
spikehat_force_get_force(hat, port, *force) |
Get force (N) only |
The SPIKE Prime Force Sensor raw value range is 0〜100 (not 0〜1024).
The conversion to Newtons is: force_N = raw_value / 10.0
force: 0〜10 Npressed: 1 when touched (may be 1 even when force=0)
libspikehat/
├── include/spikehat.h Public API header
├── src/
│ ├── serial.c/h UART communication
│ ├── protocol.c/h Build HAT text protocol
│ ├── spikehat.c Initialization, reader thread, port management
│ ├── motor.c Motor control implementation
│ └── sensor.c Sensor readout implementation
├── python/spikehat.py Python ctypes bindings
├── examples/
│ ├── test_motor.c/.py Motor sample
│ └── test_sensor.c/.py Sensor sample
└── CMakeLists.txt
Communication with the Build HAT uses a text protocol over /dev/serial0 (115200 baud, 8N1).
For protocol details, refer to docs/protocol.md in the
raspberrypi/buildhat repository.
MIT License