How to run an OPC UA server on ESP32?

In an earlier post, i have briefly mentioned about OPC UA and what it is being used for. Thanks to open source projects and developers, it is possible to build an industrial communication network without any cost except the hardware.

If you want to download and use immediately then please move on this post. But if you are ok with building things from source then proceed 🙂 .

On this post, i will explain how i have compiled an OPC UA Server and make it run on ESP32 embedded development board. You can find the source here, or if you are interested in a ready to use one then please contact me over here. There are also other platforms that you can port the OPC UA server code but i chose ESP32, because of its dynamic development environment, called esp-idf and it has a built-in Wi-Fi.

OPC UA server function has been developed by using open62541 open source C stack, which lets you compile embedded servers as small as 100 kB.

Here are the steps to compile OPC UA Server on ESP32;

1 – Get the latest esp-idf:

  • git clone --recursive https://github.com/espressif/esp-idf.git
  • cd esp-idf
  • On Windows: install.bat
  • On Linux: install.sh
  • Windows: export.bat
  • Linux: source export.sh

2 – Get the opcua-esp32 under esp-idf examples:

  • cd examples
  • git clone https://github.com/cmbahadir/opcua-esp32.git
  • cd opcua-esp32
  • (python) idf.py build

3 – Plug the ESP32 development board you are using. I have used ESP32-EVB so if are also using it you will be able to control the on board relays without making any changes in the code.

4 – Configure the ESP32 with “menuconfig” command.

  • (python) idf.py menuconfig

Navigate to “Connection Configuration” to set the type of connection (Wi-Fi or Ethernet), Wi-Fi SSID, password and static IP configuration. Currently static IP can only be set for ethernet.

ESP-IDF menuconfig

You can see the config options you can set for your OPC UA server under “Connection Configuration” as;

OPCUA-ESP32 Connection Configuration

5 – Flash the build to the board.

  • (python) idf.py flash

6 – Run monitor to check if the board got IP and started the OPC UA Server. This is required if you have not set an IP address to ESP32 board via DHCP or not connecting over ethernet with a static IP address.

  • (python) idf.py monitor

7 – Run an OPC UA Client to connect to the server. I have been using UAExpert from Unified Automation.

After connecting properly, you will be able to browse/subscribe/control GPIO 32 (Relay-1 on ESP32-EVB) and GPIO 33 (Relay-2 on ESP32-EVB).

You can set the GPIO’s from “components/open62541lib/model.h”;

  • #define BLINK_GPIO 2
  • #define DHT22_GPIO 4
  • #define RELAY_0_GPIO 32
  • #define RELAY_1_GPIO 33

DHT22 temperature sensor and led blink gpio’s are not functional but can be used after few modifications.

So, now you got the cheapest opc ua server in your hand. It can even work on battery, which i haven’t tried yet. Enjoy controlling devices around, over an industrial grade communication…

If you are interested in a ready to use one, please contact me over here.

Useful Links and references:

23 thoughts on “How to run an OPC UA server on ESP32?

  1. Thanks, this is very good tutorial. Have you ever try to connect to this ESP32 OPC UA Server using PLC S7-1500 OPC UA client??

    Like

    1. Hello Tran,

      Thank you very much for your feedback.

      Yes, i have tried to connect over an OPC Client working on S7-1500 and it worked. But, it depends on your network configuration. For instance if there is a DHCP server with specified MAC Addresses
      ESP32 will not be able to get an IP Address, so OPC UA server will not start.

      If you try and could not connect please let me know by openning an issue in github. https://github.com/cmbahadir/opcua-esp32/issues

      Like

    2. every step was done successfully in my pc , but when i am adding the source ip adress to uaexport , ther is nothing showing, why my server is not at started even i am done with monitor step too

      Like

  2. Hello
    while trying to work on OPC UA, encountered the following error on idf.py build command,
    ‘idf.py’ is not recognized as an internal or external command,
    operable program or batch file

    Can you help me out what am i doing wrong ?

    Like

  3. Hello !
    Thanks for this great tutorial. One question : Do you think its possible to use this on a Lilygo T-Call 1.3 ESP ?
    It´s an ESP32 with GSM on board. I am trying to send an analog value from the ESP32 to WinCC via OPC UA.

    Like

    1. Hello Jens,

      Thank you for the positive feedback.

      I expect it to be compiled and flashed successfully on Lilygo T-Call board and connect over Wi-Fi. But ofcourse you need to configure the analog or digital peripherals according to your setup with Lilygo. And if you want to use OPC UA over GSM, it won’t work, to be honest i do not know if its even possible. 🙂

      Like

  4. Hello

    This is a Great tutorial and Very helpful to new user.
    I am now planning is to create an OPC UA server and I think i can do it with the help of this tutorial.
    My project including below.
    1) Want to read multiple sensors analog values and want to send the sensors data to the UaExpert client.
    2) Want to update the sensor values in every second.
    I want to confirm, do I need any additional board to read the sensor value?
    If I want to change the port number where do I need to change?

    Thank you for any kind of help.

    Regards,
    Rony

    Like

    1. Hello,

      I will try to answer your questions, but it is not possible to say that its going to work or not without calculating the required resources of your setup.

      —- Want to read multiple sensors analog values and want to send the sensors data to the UaExpert client.
      —- Want to update the sensor values in every second.
      Well actually it depends on the type of sensors and server board you are using. There are many examples for analog read and other protocols(I2C, SPI etc.) for ESP32. You can directly assign them as a data source in open62541.

      Analog read depends on two things one is the sampling rate and other is the quantization so depending on the desired specs of your setup, i guess ESP32 is pretty capable in terms of meeting your needs.

      —- Do I need any additional board to read the sensor value?
      So my opinion is, you should not need an extra board if its just a standard(commonly used) sensor.

      —- If I want to change the port number where do I need to change?
      Currently its not possible to change the port number(default 4840) without making the change and compiling the opcua-esp32 code. That would be a nice feature request maybe you should open it as an issue here;
      https://github.com/cmbahadir/opcua-esp32

      Like

  5. Hello, firstly thanks for your great tutorial.
    I have just thought about a model that ESP32 lay a role as OPC UA Client, it will get data from PLC- by using Modbus TCP or S7-protocol, and it will write those data to OPCUA Server. I think it help PLCs which don’t allow OPCUA protocol can put data to cloud. Do you think this model is possible and have practical applications ?
    Thank you a lot.

    Liked by 1 person

    1. I guess you mean OPC UA server acting as a gateway not a client, which on the other side communicates with field devices over ModBus etc.

      Well, this sounded me like an OPCUA gateway that you can find many in the market.

      Like this one from Matrikon:
      https://www.matrikonopc.com/data-connectivity-devices/gateway/ua-modbus-gateway.aspx

      This is not something new and i am not in a position to say if there is a high demand or not. 🙂

      What i can say is that most of the PLCs have built-in OPC UA support.

      Like

    1. Hello Kato,

      Thanks for your feedback.

      The stack i have used is; https://github.com/open62541/open62541.

      I am not really familiar with platformio but i am pretty sure that it could be possible to compile it with few small hacks.

      There is a long but useful thread here about compiling open62541 on embedded platforms here;

      https://github.com/open62541/open62541/pull/2511#issuecomment-772479638

      A question raised there could get you some answers. 🙂

      Like

  6. Hey,
    thanks for this awesome tutorial. I’m having trouble flashing to the esp32.

    log shows:
    cc1: some warnings being treated as errors
    make[3]: *** [esp-idf/open62541lib/CMakeFiles/__idf_open62541lib.dir/build.make:82: esp-idf/open62541lib/CMakeFiles/__idf_open62541lib.dir/open62541.c.obj] Fehler 1
    make[2]: *** [CMakeFiles/Makefile2:4806: esp-idf/open62541lib/CMakeFiles/__idf_open62541lib.dir/all] Fehler 2
    make[1]: *** [CMakeFiles/Makefile2:2058: CMakeFiles/flash.dir/rule] Fehler 2
    make: *** [Makefile:261: flash] Fehler 2
    make failed with exit code 2, output of the command is in…

    i can’t figure out the problem. Any ideas on why this is failing?

    Like

      1. Hey @cmbahadir, i fixed this by switching to an install via VSCode. Everything works fine now. Thanks for the answer and for this awesome tutorial.

        My plan is to add a Bosch BME688 Sensor (which uses the “bsec2” library) to your existing project but i’m currently not succeeding in that due to my lacking C skills. What would be your suggested way of managing this task?

        Like

  7. Hi,

    Thank you very much. This is very interesting. Have you planned to make any VS Code/PlatformIO example for making an OPC UA server?

    I have Unexpected Maker FeatherS3 board and Adafuit Ethernet Wing. Would be nice to make an OPC UA server based on this hardware.

    BR, Ilkka

    Like

  8. Thank You very much for this great tutorial, i really appreciate you work. But something I don’t understand, in commons esp32 and Arduino projects we implement the setup and loop functions, but using that way, I can’t see any way to implement a custom code to run alongside the OPC UA server, have one way to do it?
    In my case, I just need a simple client to catch a simple integer and write a value in an analogic port, this is possible?

    Like

  9. Thank you for the tutorial. I am wondering if you are able to point me out how to implement a call function instead of direct GPIO control.
    The context I’m looking into is controlling a stepper motor for example which requires a certain higher-level sequence of controlling the GPIO pins.

    Such as when using Arduino IDE, to control a stepper motor with ESP32, you have to use:

    (After defining stepper control pins)

    #include
    motor.step(steps_per_rev);

    Would appreciate it immensely for the help as I find that OPC is an interesting protocol but kind of lacking in community support for platforms such as ESP32, Arduino etc.

    Like

Leave a comment