Install and use Microsoft Dot NET 9 with the Raspberry Pi

In this post we’ll look at how to install and use Microsoft Dot NET 9 with the Raspberry Pi, and get started with using C# and .NET with your IoT Projects.

On November 12th 2024 the .NET Team released .NET 9 at Dot NET Conf 2024.

.NET 9 is the continued cross platform development framework from Microsoft.

What you’ll need

I’ll be using a Raspberry Pi 4… It’s important to note that .NET 9 will only work on an AMR32v7 processor or above… So that’s a Raspberry Pi 2 and upwards…

However, there are possibly some issues running .NET on Older Pi’s, so for now, I’d recommend the Pi3B+ and above!

Unfortunately this rules out the original Pi Zero and Pi Zero W as they have V6 processors. But the Pi Zero 2W will work just fine!

Installation

Sadly, there’s still no apt install for .NET 9 on 32bit OS’s, so to install and use Microsoft Dot NET 9 with the Raspberry Pi would normally involve quite a few manual steps… However, I’ve created a single line install script to make the whole process a breeze!

On your Pi, just run the following command;

wget -O - https://raw.githubusercontent.com/pjgpetecodes/dotnet9pi/main/install.sh | sudo bash
Installing .NET 9 on a Raspberry Pi 4
Installing .NET 9 on a Raspberry Pi 4

This runs the install script as root, so obviously take your own precautions here…. But, if you want to see what’s inside, feel free to click the expandable section below…

Click here to see the contents of the install.sh file
View this gist on GitHub
install.sh

Reboot Time!

At this point you’ll need to reboot your pi for the changes to take effect. This is because we’ve made changes to the .bashrc file. Specifically, we’ve added an environment variable to the .basrc file that tells the system where to find the .NET runtime. This variable won’t be loaded until after we restart our session.

If you don’t reboot, when you try to run your application for the first time, you may receive the following warning;

A fatal error occurred. The required library libhostfxr.so could not be found.

So go ahead and reboot with;

sudo reboot

Note: If you’re feeling brave, you can try simply restarting your bash session instead with;

exec bash

Hello World!

First, let’s create our first “Hello World” .NET 9 Console Application.

Let’s create a simple Console Application using;

dotnet new console -o console1
Create a Console Application

Next we can enter the new project directory with;

cd console1

We can run our new application with;

dotnet run
Run the Hello World Console Application

As of 10th October 2023!

Note: As of 10th October 2023, the Pi 5 isn’t supported by the .NET IoT libraries.

There is a pull request to update the libraries in progress here;

https://github.com/dotnet/iot/pull/2145

If you have Pi4 or below, then feel free to carry on though!

Controlling GPIO using .NET 9

Now let’s get to making stuff really happen.

Connect up the following circuit to your Pi;

Raspberry Pi Circuit
Raspberry Pi LED Circuit

Using a 220 Ohm resistor helps to limit the current sunk by the pi into the LED.

We’re using the Board Numbering Scheme, which is shown by the numbers closest to the pins here…

Raspberry Pi GPIO

So we have one side of the LED connected to the GND pin 6, then we have the other side of the LED connected to a resistor. With the resistor connected to pin 10.

Finally one side of the button connected to GND pin 25 with the other side connected to pin 26.

Add the Dot Net GPIO Nuget package with;

dotnet add package System.Device.Gpio
Add GPIO NugeT Package
Add Dot Net GPIO Library
Using a Raspberry Pi 3A+?
Click here to workaround issues with the GPIO Nuget Package…

If you’re using a Raspberry Pi 3A+, there’s currently an incompatibility with the Raspberry Pi 3A+ which has a different BCM Controller Chip.

Thanks to Eoin Ward over on GitHub for pointing this out…

This causes the following error to be displayed when you try to control the Pi GPIO;

Unhandled exception. System.PlatformNotSupportedException

You can work around this issue by replacing the following line;

GpioController controller = new GpioController(PinNumberingScheme.Board);

With;

var assembly = typeof(GpioDriver).Assembly;
var driverType = assembly.GetType("System.Device.Gpio.Drivers.RaspberryPi3LinuxDriver");
var ctor = driverType.GetConstructor(new Type[]{});
var driver = ctor.Invoke(null) as GpioDriver;
ctl = new GpioController(PinNumberingScheme.Board, driver);

Open the Program.cs file using;

nano Program.cs

Replace the existing code with the following;

using System;
using System.Device.Gpio;
using System.Threading;

namespace console1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            GpioController controller = new GpioController(PinNumberingScheme.Board);

            var pin = 10;
            var lightTime = 300;

            controller.OpenPin(pin, PinMode.Output);

            try
            {
                while(true)
                {
                    controller.Write(pin, PinValue.High);
                    Thread.Sleep(lightTime);
                    controller.Write(pin, PinValue.Low);
                    Thread.Sleep(lightTime);
                }
            }
            finally
            {
                controller.ClosePin(pin);
            }
        }
    }
}
Replace Console Code with LED Flashing Code
GPIO Code

Save and exit nano using ctrl+x and hitting the “y” key when prompted.

Now we can run the code and we should see the LED flashing with;

dotnet run
LED FLashing Animation
Flashing LED

Reading GPIO Pins

Now that we’ve got a flashing LED, the next step is to read the status of the button and control the LED.

Stop the code from running using ctrl+c.

Open the Program.cs file again using;

nano Program.cs

Replace the existing code with;

using System;
using System.Device.Gpio;

namespace rpitest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            
            GpioController controller = new GpioController(PinNumberingScheme.Board);
            var pin = 10;
            var buttonPin = 26;
            
            controller.OpenPin(pin, PinMode.Output);
            controller.OpenPin(buttonPin, PinMode.InputPullUp);            

            try
            {
                while (true)
                {
                    if (controller.Read(buttonPin) == false)
                    {
                        controller.Write(pin, PinValue.High);
                    }
                    else
                    {
                        controller.Write(pin, PinValue.Low);
                    }
                }
            }
            finally
            {
                controller.ClosePin(pin);
                controller.ClosePin(buttonPin);
            }
        }
    }
}

Save and exit nano using ctrl+x and once again hitting “y” to the prompt.

Run the code again using;

dotnet run

Pressing the button should now light up the LED.

Button Flashing LED Animation
Push Button flashes LED

More code and examples in the GitHub repo

You can find the code above, and some more examples in the GitHub repo here;

https://github.com/pjgpetecodes/dotnet9pi

Continue with the .NET Core 3.1 examples:

I have previously created a series of posts on working with .NET Core 3.1 and the Raspberry Pi… You can follow along with those from this point as the code is compatible;

Receiving IoT Hub Messages

That’s all for now…

I hope this has been useful… Do get in touch if you need any more information!