
In this beginner-friendly guide, you’ll learn how to control LEGO motors connected to a Raspberry Pi via the official Raspberry Pi Build HAT – using a simple, pure .NET application. We’ll use the Iot.Device.BuildHat NuGet package, which provides a friendly .NET API for the Build HAT. No Python required. We’ll also publish the app as a self-contained .NET 9 binary for linux-arm64 so you do not need to install .NET on the Raspberry Pi. This approach is easy to set up, reliable, and a great starting point for your own robotics projects.
Hardware
To get started with controlling LEGO engines using the Raspberry Pi and .NET, you’ll need the following hardware components:
- Raspberry Pi, this sample uses a Raspberry Pi 4 B , but its should also work with the Pi 5
- It’s recommended to cool your Raspberry Pi , especially when using it for extended periods.
- A Raspberry Pi Build HAT Module
- A compatible LEGO motor (e.g., LEGO Vestas 10268 )
Raspberry Configuration
We’ll prepare the Raspberry Pi for I2C (required by the Build HAT). You do not need to install .NET on the Pi because we’ll publish a self-contained binary for linux-arm64.
- Flash Raspberry Pi OS
- Use Raspberry Pi Imager to install a recent Raspberry Pi OS (64-bit recommended).
- Enable SSH, set a hostname, and Wi‑Fi if you prefer headless setup.
- Update system packages
1sudo apt update && sudo apt full-upgrade -y
2sudo reboot
- Enable I2C (required by the Build HAT)
1sudo raspi-config
2# Interface Options -> I2C -> Enable
3sudo reboot
- No .NET runtime needed on the Pi
We’ll build and publish a self-contained .NET 9 linux-arm64 binary on your development machine (Windows, macOS, or Linux) and just copy the single file to the Pi.
- Attach the Build HAT and motor
- Power off the Pi.
- Seat the Build HAT on the Pi’s GPIO header.
- Connect your LEGO motor to port A on the HAT.
- If needed, connect external power to the HAT.
- Power on the Pi again.
.NET Code
This section covers the .NET code needed to control the LEGO motors via the Build HAT.
Step 1: Create the .NET 9 console app (on your dev machine)
Create a new .NET 9 console app (on the Pi or locally and copy over):
1dotnet new console -n BuildHatControl
Add the NuGet package and replace Program.cs with the following minimal example. The package name is Iot.Device.Bindings
.
Configure now your project to run on the Raspberry Pi and Arm64
1<Project Sdk="Microsoft.NET.Sdk.Web">
2 <PropertyGroup>
3 <OutputType>Exe</OutputType>
4 <TargetFramework>net9.0</TargetFramework>
5 <ImplicitUsings>enable</ImplicitUsings>
6 <Nullable>enable</Nullable>
7 </PropertyGroup>
8
9 <ItemGroup>
10 <PackageReference Include="Iot.Device.Bindings" Version="4.0.1" />
11 </ItemGroup>
12
13 <PropertyGroup Label="Build">
14 <RuntimeIdentifiers>linux-arm64</RuntimeIdentifiers>
15 <PublishReadyToRun>false</PublishReadyToRun>
16 <PublishReadyToRunShowWarnings>false</PublishReadyToRunShowWarnings>
17 <PublishTrimmed>false</PublishTrimmed>
18 </PropertyGroup>
19</Project>
Replace Program.cs with the following:
1using System;
2using System.Device.I2c;
3using System.Threading;
4using Iot.Device.BuildHat;
5
6// First, connect to your Build HAT
7
8// the serial port to use, in our case serial0
9Brick brick = new Brick("/dev/serial0");
10
11// the sensor port is the port where the motor is connected, in this case, we use Port A
12string sensorPort = "0";
13
14// now, we need to send commands to the motor
15
16// first, we send a power limit: this means we want to define the limit of the motor's power
17brick.SendRawCommand($"port {sensorPort} ; plimit 1\r");
18
19// second, we send the bias: Motor commands are amplified by 0.1 upwards or, in the case of negative commands, attenuated by 0.1. This can be helpful, for example, if the motor tends to “stick” in one direction or reacts unevenly.
20brick.SendRawCommand($"port {sensorPort} ; bias 0\r");
21
22// now we can start the engine:
23double speed = 0.70; // this means. 70%
24
25brick.SendRawCommand($"port {sensorPort} ; pwm ; set {speed.ToString(CultureInfo.InvariantCulture)}\r");
26Console.WriteLine("Engine started, wroooooom!");
Step 2: Publish a self-contained linux-arm64 binary
From the BuildHatControl folder on your dev machine, publish for the Raspberry Pi as a single-file, self-contained binary:
1dotnet publish -c Release -r linux-arm64 --self-contained true -p:PublishSingleFile=true
The output will be in bin/Release/net9.0/linux-arm64/publish/ and include a single executable named BuildHatControl, your project name.
Notes:
- linux-arm64 assumes you run 64‑bit Raspberry Pi OS. If you’re on 32‑bit OS, use
-r linux-arminstead and rebuild (also adjust your profile file!).
Step 3: Copy to the Raspberry Pi and run
Copy the published file to the Pi (replace pi@raspberrypi and the path as needed):
1scp bin/Release/net9.0/linux-arm64/publish/BuildHatControl pi@raspberrypi:/home/pi/buildhat/BuildHatControl
You can also use a UI app like WinSCP.
SSH into the Pi, make it executable, and run:
1chmod +x /home/pi/buildhat/BuildHatControl
2chmod 755 /home/pi/buildhat/BuildHatControl
3cd /home/pi/buildhat
4./BuildHatControl
You should see the motor spin!
How it works (in short)
- The Build HAT exposes ports (A–D) for LEGO motors/sensors and communicates with the Pi over I2C.
- The
Iot.Device.BuildHatpackage wraps that protocol in a friendly .NET API. - Everything stays in C#, making integration with other .NET components straightforward.
Beyond hobby?
If you’re moving beyond hobby projects and care about reliability, read the follow-up on unit testing with the Raspberry Pi Build HAT: Raspberry Build HAT: Unit Testing Strategies with .NET
Conclusion
You’ve built a beginner‑friendly, pure .NET setup that controls LEGO motors with the Raspberry Pi Build HAT:
- The Raspberry Pi handles hardware access; the Build HAT speaks to LEGO motors.
- The
Iot.Device.BuildHatpackage provides a reliable control surface. - Your .NET code orchestrates actions, integrates with other systems, and provides structure.
From here you can extend this sample with sensors, ramping/acceleration profiles, or position control – and wrap it in richer .NET services, Web APIs or UI apps. Have fun building! 🚀

Comments