Skip to Content

How to use 4G with the ESP32 PLC

SIM, Arduino IDE settings and two sketches, HTTP and MQTT, for the u-blox LTE-M and NB-IoT board
September 5, 2024 by
How to use 4G with the ESP32 PLC
Boot & Work Corp. S.L, Joan Bello

To use 4G on an ESP32 PLC you need the 4G (M1)-NB1 IoT LTE communication board (u-blox SARA-R412M), a SIM with an LTE-M or NB-IoT data plan and an antenna. In the Arduino IDE, select your ESP32 PLC model and set Tools > Extension module 1 to LTE for LTE-M or NB for NB-IoT. The NB library of the Industrial Shields boards package registers the modem on the network, and its NBClient works with ArduinoHttpClient for HTTP and with PubSubClient for MQTT.

This guide shows how to insert the SIM card, which menu options to choose, and two sketches: an HTTP request and an MQTT client that publishes and subscribes. The syntax of both has been checked, but they have not been compiled or tested on a PLC, so compile and test them on your own ESP32 PLC before you use them. At the end there is a table to find the cause when the PLC does not connect.

  1. Step 1Board and SIM4G board in slot 1, LTE-M or NB-IoT SIM, antenna
  2. Step 2Arduino IDEModel, version v3 and Extension module
  3. Step 3Attachbegin() with PIN and APN, then attachGPRS()
  4. Step 4Send dataHTTP or MQTT over NBClient

Why use 4G on an ESP32 PLC

The ESP32 PLC already has Wi-Fi, Bluetooth and Ethernet. They need a local network. A 4G board lets the PLC send data from places without one: pumping stations, wells, vehicles, railway carriages or machines at a customer site where you cannot use the plant network. LTE-M and NB-IoT are the 4G technologies made for this kind of device: low data volume, low power and good coverage.

A mobile link loses coverage from time to time. Plan for it from the start: keep the data on the PLC while the link is down and send it when it comes back.

Hardware you need

  • An ESP32 PLC with the 4G (M1)-NB1 IoT LTE (u-blox) communication board. On the product page, choose it as communication board 1. The board carries a u-blox SARA-R412M module.
  • A SIM card with a data plan for LTE-M (LTE Cat M1) or NB-IoT. Ask your operator which one it supports in your area and which APN to use.
  • An LTE antenna connected to the 4G board.
  • A computer with the Arduino IDE and the Industrial Shields boards package. See How to install Industrial Shields boards in the Arduino IDE.

Which 4G board? The NB library in the boards package works with the u-blox SARA-R412M and SARA-R422M8S modules: it reads the model of the modem and stops with an error if it is a different one. This guide is for the 4G (M1)-NB1 IoT LTE (u-blox) board. If your PLC has a Quectel or an LTE Cat 4 board, ask our technical team which library to use. The ESP32 PLC 14 can be ordered with 4G integrated: see Sending messages via SMS or Telegram with an ESP32 PLC 14.

Insert the SIM card in the ESP32 PLC

Disconnect the power before you open the cover.

  1. Remove the cover of the Ethernet port. Put a finger in the Ethernet port and push up to lift the cover, or lift it gently from one side with a flat screwdriver.
  2. Insert the SIM card. The SIM slot is above the reset button. Insert the card with the contacts facing up.
  3. Put the cover back. Press it down until it clicks into place.
Front of an ESP32 PLC V3 with the Ethernet port cover in place and a flat screwdriver to lift it
The front of the ESP32 PLC with the cover of the Ethernet port in place.
ESP32 PLC with the Ethernet port cover removed, showing the inside where the SIM card slot sits above the reset button
With the cover removed, the SIM slot is above the reset button.

Configure the Arduino IDE for the 4G board

The 4G board is optional, so you tell the IDE where it is. These options are in the Tools menu:

MenuValueNote
BoardIndustrial Shields ESP32 Boards > ESP32 PLC FamilyInstalled with the boards package
ModelYour model, for example ESP32 PLC 21 IO+It sets the I/O map of the PLC
Versionv3The NB and LTE options exist only for v3. v1 is the legacy version
Extension module 1LTE for LTE-M, or NB for NB-IoTUse Extension module 2 if the board is in slot 2

The option you choose in Extension module decides the radio technology. With LTE, the library sets the modem to LTE Cat M1 (AT+URAT=7). With NB, it sets NB-IoT (AT+URAT=8). If the SIM only works on LTE-M and you choose NB, the PLC never registers. The GPRS option is for the 2G GPRS board, not for the 4G board.

If no module is selected, the sketch does not compile and shows: No NB expansion module has been defined. Please select one in Tools -> Extension module.

The NB library comes with the boards package. Its examples are in File > Examples > NB: NBWebClient, NBSSLWebClient, SendSMS, ReceiveSMS and, under Tools, TestModem, TestGPRS and NBScanNetworks. For the sketches below, also install two libraries from Sketch > Include Library > Manage Libraries:

  • ArduinoHttpClient, for HTTP.
  • PubSubClient, for MQTT.

Example 1: send an HTTP request over 4G

The sketch registers on the mobile network, opens the data connection and sends a GET request to httpbin.org, a public test service that answers with the request it receives. Fill in the PIN and the APN of your SIM. Leave the PIN empty if the SIM has no PIN.

#include <NB.h>
#include <ArduinoHttpClient.h>

// Uncomment once if the modem does not answer: it finds the baud rate and sets it to 38400
// #define MAKE_AUTOBAUD

const char PINNUMBER[] = "";  // SIM PIN, empty if the SIM has no PIN
const char APN[]       = "";  // APN of your operator
const char USERNAME[]  = "";  // only if the operator asks for it
const char PASSWORD[]  = "";

NBClient nbClient;
GPRS gprs;
NB nbAccess;  // NB nbAccess(true); prints every AT command on the serial monitor

const char server[] = "httpbin.org";
const int port = 80;
HttpClient http(nbClient, server, port);

void setup() {
  Serial.begin(115200);
  Serial.println("Starting the 4G web client");

#ifdef MAKE_AUTOBAUD
  if (!nbAccess.autobaud()) {
    Serial.println("Autobaud failed, check the Extension module setting");
    while (true);
  }
  nbAccess.shutdown();
#endif

  // Register on the LTE-M or NB-IoT network and open the data connection
  while (nbAccess.begin(PINNUMBER, APN, USERNAME, PASSWORD) != NB_READY ||
         gprs.attachGPRS() != GPRS_READY) {
    Serial.println("Not connected, retrying");
    delay(1000);
  }
  Serial.println("Connected to the mobile network");

  int err = http.get("/get");
  if (err != 0) {
    Serial.print("Request failed, error ");
    Serial.println(err);
    return;
  }
  int status = http.responseStatusCode();
  String body = http.responseBody();
  Serial.print("HTTP status: ");
  Serial.println(status);
  Serial.println(body);
  http.stop();
}

void loop() {
}

How it works:

  • nbAccess.begin(PIN, APN, USERNAME, PASSWORD) starts the modem, applies the settings and waits until it is registered on the network. It returns NB_READY.
  • gprs.attachGPRS() opens the data connection and returns GPRS_READY. The name comes from the Arduino MKR NB library this one is based on: the connection uses LTE-M or NB-IoT, not 2G.
  • NBClient is a standard Arduino Client, so HttpClient uses it like an Ethernet or Wi-Fi client.
  • http.get() returns 0 when the request is sent. responseStatusCode() gives the HTTP status (200 if all is well) and responseBody() the answer.

Open the serial monitor at 115200 baud. Registration takes at least 24 seconds, because the library resets the modem and restarts its radio, and can take a few minutes the first time, while the modem searches for the network.

Example 2: publish and subscribe with MQTT over 4G

MQTT sends small messages through a broker. It needs little data, so it suits LTE-M and NB-IoT. This sketch connects to a public test broker, publishes a message, subscribes to the same topic and prints every message it receives.

#include <NB.h>
#include <PubSubClient.h>

const char PINNUMBER[] = "";  // SIM PIN, empty if the SIM has no PIN
const char APN[]       = "";  // APN of your operator
const char USERNAME[]  = "";
const char PASSWORD[]  = "";

NBClient nbClient;
GPRS gprs;
NB nbAccess;
PubSubClient mqtt(nbClient);

const char* MQTT_SERVER = "broker.hivemq.com";  // public test broker: no login, no TLS
const int   MQTT_PORT   = 1883;
const char* TOPIC       = "test/esp32plc-4g";
const char* CLIENT_ID   = "esp32plc-4g-0001";   // must be unique on the broker

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message on ");
  Serial.print(topic);
  Serial.print(": ");
  for (unsigned int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void connectNetwork() {
  while (nbAccess.begin(PINNUMBER, APN, USERNAME, PASSWORD) != NB_READY ||
         gprs.attachGPRS() != GPRS_READY) {
    Serial.println("Not connected, retrying");
    delay(1000);
  }
  Serial.println("Connected to the mobile network");
}

void connectMqtt() {
  Serial.print("Connecting to the MQTT broker... ");
  if (mqtt.connect(CLIENT_ID)) {
    Serial.println("connected");
    mqtt.publish(TOPIC, "Hello from the ESP32 PLC over 4G");
    mqtt.subscribe(TOPIC);
  } else {
    Serial.print("failed, state ");
    Serial.println(mqtt.state());
    delay(5000);
  }
}

void setup() {
  Serial.begin(115200);
  connectNetwork();
  mqtt.setServer(MQTT_SERVER, MQTT_PORT);
  mqtt.setCallback(callback);
}

void loop() {
  if (!mqtt.connected()) {
    if (!nbAccess.isAccessAlive()) {
      connectNetwork();  // registration lost: attach again
    }
    connectMqtt();
  }
  mqtt.loop();
}

How it works:

  • connectNetwork() registers on the network and opens the data connection, as in example 1.
  • connectMqtt() makes one connection attempt. If it fails, it prints the error code and waits 5 seconds.
  • In loop(), if MQTT is disconnected, isAccessAlive() checks the registration with AT+CEREG?. If the PLC has lost the network, it attaches again before it reconnects to the broker.
  • mqtt.loop() keeps the connection alive and calls callback() for each message that arrives.

The client ID must be unique on the broker: if two devices use the same one, the broker disconnects the first. broker.hivemq.com is a public test broker without login or encryption, so anyone can read the topic. For a real installation, use your own broker with a user, a password and TLS. See MQTT over TLS with the ESP32 PLC and MQTT security fundamentals.

The delay(5000) and the retry loops block the program. That is fine for a test. In a PLC that also controls outputs, reconnect without blocking, as in non-blocking reconnection on an ESP32 PLC.

LTE-M or NB-IoT: which one to choose

LTE-M (LTE Cat M1)NB-IoT
Extension module optionLTENB
Data rateHundreds of kbit/sTens of kbit/s
Devices that moveYes, it changes cell while connectedBetter for fixed devices
FitsMQTT and HTTP with frequent messages, firmware downloads, vehiclesSmall messages a few times per hour, fixed sites, deep indoor coverage

Both depend on the operator: check that your SIM and your area have the one you choose. The library also sets the Standard Europe operator profile of the modem and LTE bands 3, 8 and 20, which are the usual bands for LTE-M and NB-IoT in Europe. If your operator uses other bands, ask our technical team before you install.

Troubleshooting the 4G connection

What you seeLikely causeWhat to do
Compile error: No NB expansion module has been definedExtension module is set to NoneSet Tools > Extension module 1 (or 2) to LTE or NB
The modem does not answer, begin() returns an error at onceThe modem uses a different baud rateUncomment #define MAKE_AUTOBAUD and upload once. The library tries several baud rates and leaves the modem at 38400. Comment it again afterwards
"Not connected, retrying" without endWrong technology (NB or LTE), wrong APN or PIN, no antenna, no coverage, or the SIM has no LTE-M or NB-IoTCheck the menu option, the APN and the antenna. Run the NBScanNetworks and TestGPRS examples
You need to see what the modem saysCreate the object as NB nbAccess(true);: every AT command and answer goes to the serial monitor
MQTT state -2The TCP connection to the broker failedCheck the server name, the port and the data connection
MQTT state -4 or -3Time-out or connection lost, often weak coverageCheck the antenna and the signal, and keep the data on the PLC until it reconnects
MQTT state 2, 4 or 5The broker rejects the client ID, the user and password, or the accessUse a unique client ID and the credentials of the broker

From a test sketch to remote telemetry

A field installation adds three things to these examples: a buffer for the data while there is no coverage, timestamps, and a server that receives the messages from many PLCs. The railway case below sends energy data over 4G LTE-M and keeps it on board when the train has no coverage. The oil well case shows the same pattern from a remote site, with an ESP32 PLC 21 FLEX and a 4G board. To collect the messages from many PLCs, see the Node-RED MQTT concentrator for ESP32 PLC fleets.

Take it further

A 4G link drops and comes back. See how a real project handles coverage, a simulator where you cut the link and the code that keeps the data.

FAQ about 4G on the ESP32 PLC

Which SIM card do I need for the ESP32 PLC 4G board?

A SIM with a data plan for LTE-M or NB-IoT, from an operator that offers it in your area. Many IoT SIMs include both. A SIM for 2G only does not work with this board, because the library sets the modem to LTE-M or NB-IoT.

Why does the code use a class called GPRS on a 4G board?

The NB library is based on the Arduino MKR NB library, which keeps the name GPRS for the data connection. attachGPRS() opens the data connection over LTE-M or NB-IoT.

Can I use HTTPS or MQTT with TLS over 4G?

Yes. The NB library includes NBSSLClient, with the NBSSLWebClient example. For MQTT with TLS on the ESP32 PLC, see this guide.

Can the 4G board send SMS?

Yes. The library includes the SendSMS and ReceiveSMS examples, in File > Examples > NB.

What happens to the data when the PLC loses coverage?

The examples above do not keep it. In a real project, write each message to the SD card or to memory first and send it when the link returns. See offline-first MQTT data logging with SD buffering.

​Search in our Blog

How to use 4G with the ESP32 PLC
Boot & Work Corp. S.L, Joan Bello September 5, 2024
Share this post
Tags

Looking for your ideal Programmable Logic Controller?

Take a look at this product comparison with other industrial controllers Arduino-based. 

We are comparing inputs, outputs, communications and other features with the ones of the relevant brands.

PLC Comparison