In this post we’ll look at how to install and use Microsoft Dot NET 8 with the Raspberry Pi, and get started with using C# and .NET with your IoT Projects.
On November 14th 2023 the .NET Team will release .NET 8 at Dot NET Conf 2023.
.NET 8 is the continued cross platform development framework from Microsoft.
What you’ll need
- A recent Raspberry Pi – Go shopping at the Pi Hut.
- An LED, a 220 Ohm Resistor, a Button and some DuPont Connecting Cables
- You’ll need a SSH Client like PUTtY – Get it here.
- To make things easier, you can;
- Setup a Samba Share, create a folder in your home directory called “share” and share that – Here’s a link to a good guide.
- Use a Code Editor on your machine to edit your files – Use Visual Studio Code!
I’ll be using a Raspberry Pi 5B… It’s important to note that .NET 8 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 8 on 32bit OS’s, so to install and use Microsoft Dot NET 8 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/dotnet8pi/main/install.sh | sudo bash
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
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 8 Console Application.
Let’s create a simple Console Application using;
dotnet new console -o console1
Next we can enter the new project directory with;
cd console1
We can run our new application with;
dotnet run
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 8
Now let’s get to making stuff really happen.
Connect up the following circuit to your Pi;
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…
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
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);
}
}
}
}
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
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.
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/dotnet8pi
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;
That’s all for now…
I hope this has been useful… Do get in touch if you need any more information!