esp32-net6-serial

How to connect an ESP32 with NET6 via serial port

  • 5 min

We are launching a series of posts aimed at exploring the different ways to connect an ESP32 to a computer through an application made in NET6, written in C#.

Let’s remember that NET6 is cross-platform and, therefore, is available on computers with Windows, Android, Linux, or Mac, as well as on x86/x64 and ARM7 or higher architectures.

This means we can run the same program, for example, on our desktop computer with Windows or Linux, on our Android mobile, or on our Raspberry Pi. All without needing to make any changes to the code.

And we start the series by looking at one of the simplest forms of communication: using a serial port (or UART).

ESP32 Code

For this series of posts, I’m going to use an M5 Stick C device, which has a built-in screen and accelerometer, because I find it very useful for developing the content. But any Arduino-like device with WiFi, such as any model from the ESP32 family, will work for us.

In the Github repo, I leave you the complete examples, with the ESP32 code and the NET code. You have the link at the end of the post. Here we will only comment on the relevant parts. In the repo, you have four examples:

  • 00_Timer
  • 01_Button
  • 02_Accelerometer
  • 03_Receive

In the first three examples, the ESP32 sends data to the NET6 application. The first example is the simplest and simply sends the commands on a timer. In the second, when we press a button. In the third, we send the command depending on whether the device is vertical or lying down, using the accelerometer of the M5 Stick C.

If we look, for example, at the code for the accelerometer case, the sending part is done in the Update() function,

void Update()
{
  if(isOn == false && GetIsTumbado() == false)
  {
    isOn = true;
    Serial.println("A");
  }
  else if(isOn == true && GetIsTumbado() == true)
  {
    isOn = false;
    Serial.println("B");
  }
}
Copied!

We see that we simply use Serial.println(…) to send the data to the NET6 application, where I’m basically using the accelerometer to detect when the device is lying down or standing up.

It’s that simple. The other two examples have a similar Update(…) function, with small variations depending on the particular case. But the serial communication part is basically just as simple.

In the fourth example, ‘Receive’, the ESP32 receives data sent from the application. In this case, the ‘Update()’ function would be as follows,

void Update()
{
  if (Serial.available())
  {
    auto content = Serial.readStringUntil(‘\n’);
    if(content == "A") isOn = true;
    if(content == "B") isOn = false;

    Render();
  }
}
Copied!

Where we simply check if there is pending data to receive, using the newline separator ‘\n’. Then we read the content and would perform the appropriate actions. In the example, we simply change the screen to red or green, depending on the value received.

NET6 Code

On the other hand, moving to the NET6 side, we create a simple console application. Next, we add the System.IO.Port assembly.

To maintain a minimum of cleanliness, we encapsulate the program logic associated with the serial port in an independent object. I leave you a basic structure in the ArduinoPort.cs file. You can reuse it in your project, or modify it according to your needs.

With this, the code for sending from NET6 to the ESP32 would be as follows,

ArduinoPort arduinoPort = new ArduinoPort();
arduinoPort.DataArrived += ArduinoPort_DataArrived;

// USB port example on Windows
arduinoPort.Open("COM4", 115200);

// USB port example on Linux
//arduinoPort.Open("/dev/ttyUSB0", 115200);

Console.ReadLine();

void ArduinoPort_DataArrived(object? sender, EventArgs? e)
{
  var lastRecieved = arduinoPort.LastRecieved;
  Console.WriteLine(lastRecieved);
}
Copied!

We compile the code and run it, whether on a Windows computer, a Raspberry Pi, or any other available platform. We only need to keep in mind that we must replace the COMx or ttyUSBx port with the name of the port on our device.

Now, with the device connected via USB, when we lay the device down, we see that the ‘A’s and ‘B’s received are displayed in the console application. With this, we would perform the appropriate actions. In the same way, we could send ‘A’ and ‘B’ or any other information, as we have already seen in the numerous blog posts about serial ports.

In the case of wanting the NET6 application to send information to the ESP32, which would correspond to the example 03_Receive.ino, we can use the function ‘arduinoPort.Write(…);

For example, with the following code we would alternately send ‘A’ and ‘B’ every two seconds, so the screen connected to the ESP32 would change from green to red.

var isOn = false;
var timer = Observable.Interval(TimeSpan.FromSeconds(2))
  .Subscribe(async _ =>
  {
    var message = isOn ? "A" : "B";
    isOn = !isOn;
    
    arduinoPort.Write(message);
    Console.WriteLine(message);
  });
Copied!

This is how simply we could communicate an ESP32 with a NET6 application written in C#. In the next post of the series, we will move on to wireless communication via WiFi, seeing how to use HTTP requests.

Download the Code

All the code from this post is available for download on Github. github-full