Go Down

Topic: OPC-UA - (ESP8266, ESP32, Arduino + Ethernet) (Read 8942 times) previous topic - next topic

martinius96

Nov 22, 2019, 08:48 pm Last Edit: Feb 04, 2020, 08:52 pm by martinius96
I introduced OPC-UA architecture in more detail in the last published article. Today, I would like to extend the original article to include information and insights in the actual implementation. The implementation includes standard client -> server communication, using various types of clients.

As for servers, they work on standard HTTP protocol 80, they differ mainly in operating modes, and they can operate on an existing LAN network as STATION, or they can broadcast their own encrypted WiFi network - AP mode - under WPA / WPA2 - PSK (Only applies to ESP8266 and ESP32).

To demonstrate such an OPC-UA architecture, I have chosen up to three platforms that can be combined into this architecture. These are the WiFi chips ESP8266 and ESP32, which provide WiFi connectivity and for Ethernet representative Arduino with the most famous Ethernet modules Wiznet W5100, W5500.

In my own implementation, I tried to create a full-fledged OPC-UA sensor system. The webserver receives data from the client - the ADC value of the converter, and distributes this data to other clients, so called. Subscribers who ask for this information by appropriate request. The system is very interesting as it can be implemented also in sensory networks, automation.

All data in the system is accessible in real time. The data is not stored, running on the webserver in its RAM memory. Webserver is also used for human interaction, as it is possible to connect to it from the browser, while it is possible to browse the data or control outputs via HTML page and its elements. The HTML page can also incorporate a simple SCADA visualization with the possibility of control through this visualization.

In implementation I used simple examples for HTTP webserver for each microprocessor architecture. I later extended the examples for the expected "requirements" (their form) to specific GET subpages. By implementing for all platforms, I managed to build a simple communication network that is multiplatform. I.e. If the Arduino webserver is equipped with an Ethernet shield, we can use the ESP8266 or ESP32 development boards as clients, as well as vice versa with a webserver on ESP platforms.

A simple block diagram represents the proposed architecture:


Server queries:
  • URL Function
    • / (Root) Overview of recent data + automatic refresh of data on the page
    • /data/?sensor_data=NUMBER Pass data to GET using NUMBER method (Publisher)
    • /get_data/ Request data from a server (Subscriber) from the server -> value NUMBER

    Web server types:
    • Type Function
    • AP Broadcasts its own SSID network under WPA / WPA2 (can also be unsecured without a password), processes DHCP, static IP
    • STATION Connects to an existing WiFi / LAN network. It can have a dynamic IP, mDNS can be used for a domain name


    Client types:
    • Type Function
    • Publish_Client sends data from ADC converter to server, prints received server response - acknowledges received data sent
    • Publish_Client_UDP sends data from ADC converter to server, skip server response (process it, do not write received response, do not work with it)
    • Subscriber_Client performs an HTTP request to the server - the server responds with a received value from the (Publish) client, for example, the value can be a temperature. It is possible to work with the value, use it further (ventilation, boiler switching, relay)

    Implementation issues:
    The easiest implementation was to build the OPC-UA webserver for ESP8266. Directly in the examples for this platform is mentioned and pre-implemented also receiving the GET request for the page with the given parameter.

    The ESP32 platform is little different in terms of software. There is another library header file, with server functions almost identical. Implementation on the ESP32 platform is somewhat different as it has no function for the expected parameter, as is the case with ESP8266. It can only accept the hard-coded parameter in the source code.

    The hardest implementation was programming the web server for Arduino with Ethernet shield W5100 or W5500 module respectively. Each module uses a different library header file, for Wiznet W5100 it is Ethernet.h and for W5500 it is Ethernet2.h. The implementations for the webserver do not contain download parameters, they are able to download only the whole received string - request from client in style:
    GET /data/?sensor_data=NUMBER. This address needs to be split, for example with the C function strok (), or substring with the String object with appropriate terminators.

    Then verify the individual depth and text of the URL, the received parameter and, last but not least, the value that the webserver should take. Arduino is considerably limited in terms of speed and memory. When using Arduina Uno, only 2kB of available RAM is available. ESP32 has 500kB of RAM and ESP8266 of about 96kB. The Arduino program with Ethernet module is quite specific, but it is possible to program a webserver equivalent to those used for ESP8266 or ESP32, as well as receive HTTP requests from these microcontrollers.

    More about project you can see at: https://arduino.php5.sk/opc-ua-esp8266.php?lang=en

OPC-UA (Two ESP8266 and Windows Client communication)
https://www.youtube.com/watch?v=pxey3PC_u8s
Arduino and website programmer

martinius96

One source code for OPC-UA webserver and OPC-UA client (both ESP8266 - NodeMCU) without XML (SOAP) parser - only example data transfer.
POST HTTP request with SOAP (XML) payload.
SOURCE CODES WITH XML (SOAP) PARSER AND ADVANCED SOURCE CODES ARE PAID! IF YOU WANT TO BUY PROJECT, CONTACT ME AT: martinius96@gmail.com

OPC-UA Webserver source code:
Code: [Select]

//ESP8266 (NodeMCU) - OPC-UA webserver - EXAMPLE IMPLEMENTATION
//Author: Martin Chlebovec (martinius96)
//Web: https://arduino.php5.sk?lang=en
//Donate for more: https://paypal.me/chlebovec
//E-mail contact: martinius96@gmail.com

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
const char* ssid = "WIFI_NAME";
const char* password =  "WIFI_PASSWORD";

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Waiting to connect...");
  }
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  server.on("/body", handleBody);
  server.begin();
  Serial.println("Server listening");

}

void loop() {
  server.handleClient();
}

void handleBody() {
  if (server.hasArg("plain") == false) {
    server.send(200, "text/plain", "Body not received");
    return;
  }
  String message = "Body received:\n";
  message += server.arg("plain");
  message += "\n";
  server.send(200, "text/plain", message);
  Serial.println(message);
}

OPC-UA Client source code:
Code: [Select]

//ESP8266 (NodeMCU) - OPC-UA Client with XML (SOAP) datas
//Author: Martin Chlebovec (martinius96)
//Web: https://arduino.php5.sk
//Donate: https://paypal.me/chlebovec
//E-mail: martinius96@gmail.com

#include <ESP8266WiFi.h>
const char * ssid = "WIFI_NAME";
const char * password = "WIFI_PASSWORD";
const char * host = "192.168.1.19"; //IP address of OPC-UA webserver --> second NodeMCU
const int httpPort = 80; //http port
WiFiClient client;
void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi uspesne pripojene");
  Serial.println("IP adresa: ");
  Serial.println(WiFi.localIP());
  Serial.println("Ready");
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
  }
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  client.stop();
  String mac = WiFi.macAddress();
  String data = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
  data += "<ServiceRequest>\n";
  data += "<ID_BOARD>" + mac + "</ID_BOARD>\n";
  data += "<BME280_VALUE_PRESSURE>1013.48</BME280_VALUE_PRESSURE>\n";
  data += "<BME280_VALUE_TEMPERATURE>-20.34</BME280_VALUE_TEMPERATURE>\n";
  data += "<BME280_VALUE_HUMIDITY>48.55</BME280_VALUE_HUMIDITY>\n";
  data += "</ServiceRequest>\n";
  String url = "/body";
  if (client.connect(host, httpPort)) {
    client.println("POST " + url + " HTTP/1.0");
    client.println("Host: " + (String)host);
    client.println("User-Agent: ESP8266");
    client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded;");
    client.print("Content-Length: ");
    client.println(data.length());
    client.println();
    client.println(data);
    while (client.connected()) {
      String line = client.readStringUntil('\n');
      if (line == "\r") {
        break;
      }
    }
    String line = client.readStringUntil('\n');
  } else {
    Serial.println("Problem connecting to webserver");
  }
  delay(5000);
}
Arduino and website programmer

Go Up