Sitemap
Medialesson

We help our customers design, architect, develop and operate modern, intelligent, beautiful and usable apps on any platform powered by the Cloud, IoT and AI.

Raspberry Build HAT: Controlling LEGO Engines with .NET

5 min readAug 19, 2025

--

Press enter or click to view image in full size

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 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.

  1. 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.

2. Update system packages

sudo apt update && sudo apt full-upgrade -y
sudo reboot

3. Enable I2C (required by the Build HAT)

sudo raspi-config
# Interface Options -> I2C -> Enable
sudo reboot

4. 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.

5. 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):

dotnet new console -n BuildHatControl

Add the NuGet package and replace Program.cs with the following minimal example. The package name is Iot.Device.Bindings.

Get BEN ABT’s stories in your inbox

Join Medium for free to get updates from this writer.

Configure now your project to run on the Raspberry Pi and Arm64

<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Iot.Device.Bindings" Version="4.0.1" />
</ItemGroup>

<PropertyGroup Label="Build">
<RuntimeIdentifiers>linux-arm64</RuntimeIdentifiers>
<PublishReadyToRun>false</PublishReadyToRun>
<PublishReadyToRunShowWarnings>false</PublishReadyToRunShowWarnings>
<PublishTrimmed>false</PublishTrimmed>
</PropertyGroup>
</Project>

Replace Program.cs with the following:

using System;
using System.Device.I2c;
using System.Threading;
using Iot.Device.BuildHat;

// First, connect to your Build HAT

// the serial port to use, in our case serial0
Brick brick = new Brick("/dev/serial0");

// the sensor port is the port where the motor is connected, in this case, we use Port A
string sensorPort = "0";

// now, we need to send commands to the motor

// first, we send a power limit: this means we want to define the limit of the motor's power
brick.SendRawCommand($"port {sensorPort} ; plimit 1\r");

// 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.
brick.SendRawCommand($"port {sensorPort} ; bias 0\r");

// now we can start the engine:
double speed = 0.70; // this means. 70%

brick.SendRawCommand($"port {sensorPort} ; pwm ; set {speed.ToString(CultureInfo.InvariantCulture)}\r");
Console.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:

dotnet 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-arm instead 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):

scp 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:

chmod +x /home/pi/buildhat/BuildHatControl
chmod 755 /home/pi/buildhat/BuildHatControl
cd /home/pi/buildhat
./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.BuildHat package 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.BuildHat package 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! 🚀

Author

BEN ABT

Ben is a Principal Software Engineer at Medialesson.de, with a strong focus on .NET and Microsoft Azure. In his professional role, he designs and builds highly scalable platforms for hybrid and cloud-based scenarios. He also advises companies and C-levels on migrating to the sovereign cloud.

He runs myCSharp.de, the largest and most active German-speaking C# community forum, actively contributes to both his own and external open-source projects, and regularly shares his knowledge through his blog, at community events, conferences, and as a writer for technical magazines.

--

Ben is Chief Engineering Officer and Principal Software Engineer at Medialesson.de, with a strong focus on .NET and Microsoft Azure.

See more from me

Medialesson
Medialesson

Published in Medialesson

We help our customers design, architect, develop and operate modern, intelligent, beautiful and usable apps on any platform powered by the Cloud, IoT and AI.