Language: EN

esp32-net6-websockets

How to connect an ESP32 with NET6 via WebSockets

New entry in the series of entries aimed at seeing ways of communication between an ESP32 and a NET6 application written in C#. This time we see communication via WebSockets.

We have previously seen communication through the serial port, and communication through HTTP requests. We continue in today’s entry to see communication via WebSockets.

NET6 is cross-platform and is available on computers with Windows, Android, Linux, or Mac, as well as on x86/x64 and ARM7 or higher architectures. This means that we can run the same program on different devices, such as desktop computers with Windows or Linux, Android mobiles, or Raspberry Pi.

As we mentioned in the previous entry, and it is not the first time in the blog, although we see one form of communication after another, it does not mean that communication via WebSockets is “better” than communication via HTTP requests. Each communication has its advantages and disadvantages.

In particular, WebSocket communication is interesting when completely bidirectional communication between client and server is needed, and the required data transfer speed is high.

However, it is not all advantages. It also has the negative side that it requires many resources. It also involves a large consumption of ports on the server machine, which requires more complex system solutions. So it may not be recommended in the case that we have many clients making an occasional connection.

Having said that, let’s get started!

ESP32 Code

As in the rest of the entries in the series, I will use an M5 Stick C as the development device. However, any device with WiFi similar to Arduino, such as any model of the ESP32 family, will serve you equally.

And as is customary in our blog entries, for order and cleanliness we will separate the code according to functionality. Thus, in the APIWebSocket.hpp file, we have all the logic associated with the WebSockets.

void InitWebSockets()
{
    webSocket.begin(ApiHost, 81, "/API");
    webSocket.onEvent(webSocketEvent);
    Serial.println("Connected websockets");
}

void SendA()
{
    webSocket.sendTXT("A");
}

void SendB()
{
    webSocket.sendTXT("B");
}

As we can see, we only have a function to initialize communication via WebSockets, and two methods to send ‘A’ and ‘B’. Simple, but sufficient for our example.

On the other hand, our main sketch would be as follows.

void setup()
{
    Serial.begin(115200);

    WIFI_Connect();

    delay(2000);
    InitWebSockets();
}

bool isOn = false;
void Update()
{
    if (M5.BtnA.wasPressed())
    {
        if (isOn == false)
        {
            isOn = true;
            Serial.println("A");
            SendA();
        }
        else if (isOn == true)
        {
            isOn = false;
            Serial.println("B");
            SendB();
        }
    }
}

void loop()
{
    M5.update();
    webSocket.loop();
    delay(10);

    Update();
}

Where, as we can see, in the setup we initiate the WiFi and communication via WebSockets. On the other hand, in loop() we update the WebSocket communication, and call the update() function.

In this update() function, we simply check if the button has been pressed, to alternately send ‘A’ or ‘B’. Of course, in a real example, you would put the necessary logic for your project there. For this example of communication, our A/B is more than enough.

NET6 Code

On the other hand, for communication via WebSockets from NET6, we will use the WebsocketSharp library that we already saw in this post.

As we have done in previous entries, we are going to create an object that simplifies the use of WebSockets in our program. In the case of WebSockets, it is very simple, and could be something like the following.

public class ArduinoWebsocket : WebSocketBehavior
{
    public static string LastRecieved { get; private set; } = "";

    public static event EventHandler DataArrived;

    protected override void OnMessage(MessageEventArgs e)
    {
        LastRecieved = e.Data;
        DataArrived?.Invoke(this, new EventArgs());
    }
}

With this object, making the connection via WebSockets from NET6 to the ESP32 would be as simple as the following.

InitWebSocketServer();

Console.ReadLine();

void InitWebSocketServer()
{
    var web = new WebSocketServer(81);
    web.AddWebSocketService<ArduinoWebsocket>("/API");

    ArduinoWebsocket.DataArrived += DataArrived;
    web.Start();
}

void DataArrived(object sender, EventArgs e)
{
    if (ArduinoWebsocket.LastRecieved == "A")
    {
        Console.WriteLine("A");
    }
    else if (ArduinoWebsocket.LastRecieved == "B")
    {
        Console.WriteLine("B");
    }
}

That’s it! We really see that communication via WebSockets, from the point of view of code, is not complicated at all. In fact, it is very simple to communicate an ESP32 with a NET6 application in C# via WebSockets. In the next entry we will see communication via MQTT. Until next time!

Download the code

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