Interfacing Arduino with C#/.NET
Tags: dotnet, arduino, csharp, programming
Published: 2023-09-25 00:08:56

## Introduction

Hey guys, I'm here with another interesting article on how to interface Arduino with C#/.NET seamlessly using serial communication. There are other ways available but the easier and most stable way is via the Serial protocol. At the end of the _tutorial_, you will be able to interface any Arduino boards with any .NET applications. This includes Console, WPF, WinUI3, .NET MAUI etc., Let's get started.

---

## Prerequisites

Make sure you guys are ready with the below equipment.


- A Laptop/PC with USB Port (not type-c).
- Any Arduino boards. I'm using Arduino UNO.
- .NET 6 or later version installed.
- Arduino IDE.
- Self Interest.

---

## Getting Started

- Verify your .NET installation with the below command

```bash
$ dotnet --list-sdks

#output
#7.0.401 [C:\Program Files\dotnet\sdk]
```
Here it shows that I have .NET7.0.x installed, which is good.

- Connect Arduino board to the PC and verify that the board is detected.

- If everything goes fine. You're ready to write the code.

---

## Programming the Arduino

In this tutorial, we're going to send a string "Hello World" from Arduino to the .NET application. So, we need to write a simple code to make the Arduino log "Hello World" via Serial Communication.

- Open the Arduino IDE and create a new sketch.
- Copy paste the below code.
```cpp
void setup() {
    Serial.begin(9600);
}

void loop() {
    Serial.println("Hello World");
    delay(2000);
}
```
- Upload the sketch to Arduino.
- Done. The Arduino part is over. Now we can get to the real deal. The interface program in .NET/C#.

---

## Interfacing in a .NET Application

For this tutorial, I'm going to create a simple Console Application. But this code is common for any .NET workloads. With some little tweaks, you can integrate the code with any type of .NET Applications.

- Create a .NET Console app.
```bash
$ dotnet new console
```
- We are going to use `System.IO.Ports` NuGet package. This is a core package responsible for serial interfacing.
```bash
$ dotnet add package System.IO.Ports
```

- Now it's time to code. I'm going to use VSCode with the [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) Installed for intellisense. You can use Visual Studio or any editor you want.

Open Program.cs and clear out the code that's already been there. Now import the necessary libraries.
```csharp
using System.IO.Ports;
using System;
```

Now create a class called `Program` with `Main` method in it.
```csharp
public class Program()
{
    public static void Main()
    {     
    }
}
```

Now create another method in the `Program` class called `MainInterface`. This method is called in the `Main` method to reduce the complexity of using `static` methods and properties everywhere.
```csharp
public class Program()
{
    public static void Main()
                => new Program().MainInterface();

    public void MainInterface() 
    {
    }
}
```

Now create a `SerialPort` property called `serialPort` in the `Program` class.
```csharp
private SerialPort serialPort {get; set;}
```

Now copy paste the following code in `MainInterface` method.
```csharp
serialPort = new()
{
    PortName = "COM3",
    BaudRate = 9600
};
```
In this scenario, my Arduino board is connected to "COM3" port, and the baud rate is set to 9600 as we set the same in the Arduino code. You can check the port on which your Arduino is connected in **Device Manager**.

Now, we want to subscribe to event when a data is received via the Serial Communication. This can be achieved by SerialPort's `DataReceived` event handler.

Firstly, create a new `DataReceived` event handler method in the `Program` class.
```csharp
public void SerialDataRecieved(object sender, SerialDataReceivedEventArgs e)
{
    string inData = serialPort.ReadLine();
    Console.WriteLine($"Data Received: {inData}");
}
```

Now reference the event handler method to the `serialPort` property in the `MainInterface` method.
```csharp
serialPort.DataReceived += SerialDataRecieved;
```

Now, Copy paste the below lines in `MainInterface` method to Open the port and start listening.
```csharp
serialPort.Open();
Console.ReadKey();
serialPort.Close();
```

And that's it. In case you lost your track, here is the entire code.

```csharp
using System.IO.Ports;
using System;

public class Program()
{

    private SerialPort serialPort {get; set;}

    public static void Main()
                => new Program().MainInterface();

    public void MainInterface() 
    {
        serialPort = new()
        {
            PortName = "COM3",
            BaudRate = 9600
        };
        serialPort.DataReceived += SerialDataRecieved;
        serialPort.Open();
        Console.ReadKey();
        serialPort.Close();
    }

    public void SerialDataRecieved(object sender, SerialDataReceivedEventArgs e)
    {
        string inData = serialPort.ReadLine();
        Console.WriteLine($"Data Received: {inData}");
    }
}
```

---

## Running / Testing

Make sure you have connected the Arduino board and mentioned the correct **COM Port name** in the C# Code. If everything is fine, you can run the program by using the below command.
```bash
$ dotnet run
```

And if everything goes fine, you can see our "Hello World" gets printed on the console or terminal.


![Console App Logging Data from Arduino](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xg9dpnjo8fa1fez9vxaa.png)

Hooray, we have successfully interfaced Arduino with C#/.NET. You can even send data to the Arduino via the same Serial Communication and handle those in the Arduino code. It's time to make your own .NET app to control Arduino...!


## Conclusion

Hope you guys got basic idea on what is serial communication and how easy it is to interface Arduino with a .NET app. You can interface any component that supports Serial Communication. See you guys in the next blog 👋.

## Reference Links

- `SerialPort` docs can be found [[here](https://learn.microsoft.com/en-us/dotnet/api/system.io.ports?view=dotnet-plat-ext-7.0)].