Skip to Content

ESP32 Bluetooth, BLE and Wi-Fi: specs and PLC examples

Datasheet figures, the radio inside the ESP32 PLC and two Arduino examples: a Wi-Fi scan and a BLE write from a phone
May 10, 2019 by
ESP32 Bluetooth, BLE and Wi-Fi: specs and PLC examples
Serzh Ohanyan

Complete guide: Choosing an industrial controller

The ESP32 is a 32-bit microcontroller from Espressif with 2.4 GHz Wi-Fi (802.11 b/g/n, up to 150 Mbps) and Bluetooth v4.2 (Classic BR/EDR and Bluetooth LE) on the same chip, 520 KB of SRAM and up to 240 MHz. In an Industrial Shields ESP32 PLC the radio is built in, so the controller that reads the inputs can also send data over Wi-Fi or exchange values with a phone over BLE, with no external module. You program both radios in the Arduino IDE with the WiFi and BLE libraries of the ESP32 core.

This guide gives the datasheet figures that matter in a PLC project, shows how the radio fits in the ESP32 PLC, and includes two Arduino examples: a Wi-Fi scan and a BLE write from a phone. The last section covers the older approach: an ESP32 board connected to an M-Duino or an Ardbox over a serial line.

ESP32 Wi-Fi and Bluetooth specifications

These figures come from the ESP32 Series Datasheet (version 5.3):

FeatureESP32 chip
CPUXtensa LX6, single or dual core, 32-bit, up to 240 MHz
Memory448 KB ROM, 520 KB SRAM, 16 KB SRAM in the RTC
Wi-Fi802.11 b/g/n, 2.4 GHz only, up to 150 Mbps with 802.11n
Wi-Fi modesStation, SoftAP (access point) and promiscuous, at the same time
Bluetoothv4.2 BR/EDR (Classic) and Bluetooth LE
Bluetooth radio+9 dBm transmit power, -94 dBm Bluetooth LE sensitivity
Peripherals34 GPIOs, 12-bit ADC with up to 18 channels, two 8-bit DACs, 10 touch sensors, 4 SPI, 2 I2S, 2 I2C, 3 UART, TWAI (CAN 2.0), LED PWM with up to 16 channels
SecuritySecure boot, flash encryption, 1024-bit OTP (up to 768 bits for the user), hardware AES, SHA-2, RSA and a random number generator

Two limits matter in an industrial project. The radio works only in the 2.4 GHz band, so it cannot join a 5 GHz network. And Wi-Fi and Bluetooth share the same radio and antenna: when both are on, the chip shares the airtime between them (coexistence), and each one gets less throughput.

The ESP32 inside an industrial PLC

The ESP32 PLC family of Industrial Shields puts the ESP32 in a DIN rail controller with industrial inputs and outputs. The radio needs no extra hardware. According to the product sheets of the ESP32 PLC 14 and 21:

ItemESP32 PLC
ProcessorESP32 dual core, up to 240 MHz, 16 MB flash, 520 KB SRAM
WirelessWi-Fi 2.4 GHz and Bluetooth LE, built in
WiredEthernet 10/100 Mbit, RS-485 and I2C; the ESP32 PLC 21 adds RS-232 and SPI
ModelsESP32 PLC 14, 19R, 21, 38AR, 38R, 42, 57R and 58
OptionsThe FLEX versions of the ESP32 PLC 14 and 21 take one board: LoRa, 4G LTE-M/NB-IoT or CAN. The 14 FLEX also offers an RTC board
Power and mounting12 to 24 Vdc, DIN rail, IP20, inside a cabinet
ProgrammingArduino IDE with the Industrial Shields ESP32 boards package

Typical uses of the radio in a machine or a plant: send values to an MQTT broker or a database over Wi-Fi when there is no network cable, give a technician a phone screen over BLE to read values and change settings, or keep Ethernet for the plant network and use Wi-Fi as a service link.

The M-Duino and the Ardbox use an Arduino Mega and an Arduino Leonardo, which have no radio. On those PLCs an external ESP32 board can add Wi-Fi or Bluetooth, as shown at the end of this guide.

How to program the ESP32 radio in the Arduino IDE

  1. Install the Industrial Shields boards in the Arduino IDE and select the ESP32 PLC family and your model.
  2. Include the library you need: WiFi.h for Wi-Fi, BLEDevice.h for Bluetooth LE, or BluetoothSerial.h for a Bluetooth Classic serial link.
  3. Open the serial monitor at 115200 baud to read the output of the examples below.

The Industrial Shields ESP32 package (version 2.7.1) is based on version 2 of the ESP32 Arduino core. In that version, getValue() of a BLE characteristic returns a std::string. In version 3 of the core it returns an Arduino String.

Example 1: scan the Wi-Fi networks

Before you install a PLC in a cabinet, check which networks it can see and how strong they are. This sketch lists the networks every 5 seconds with their RSSI (received signal strength, in dBm) and channel:

// Wi-Fi scan on an Industrial Shields ESP32 PLC
// Lists the 2.4 GHz networks the PLC can see, with signal strength and channel

#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);      // station mode: the PLC joins networks, it does not create one
  WiFi.disconnect();        // make sure it is not connected to an access point
  delay(100);
  Serial.println("Scan ready");
}

void loop() {
  unsigned long start = millis();
  int n = WiFi.scanNetworks();          // blocking scan, about 2 to 3 s
  Serial.print("Scan time (ms): ");
  Serial.println(millis() - start);

  if (n <= 0) {
    Serial.println("No networks found");
  } else {
    Serial.print(n);
    Serial.println(" networks found");
    for (int i = 0; i < n; i++) {
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print("  RSSI ");
      Serial.print(WiFi.RSSI(i));       // dBm, closer to 0 is stronger
      Serial.print(" dBm  channel ");
      Serial.print(WiFi.channel(i));
      Serial.println(WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? "  open" : "  encrypted");
    }
  }
  WiFi.scanDelete();                    // free the memory of the results
  Serial.println();
  delay(5000);
}

The RSSI is negative, and a value closer to 0 means a stronger signal. A metal cabinet weakens the signal, so run the scan with the cabinet door closed.

Example 2: receive data from a phone over BLE

Bluetooth LE organises data in services and characteristics, each one identified by a 128-bit UUID. This sketch creates one service with one characteristic. When a phone writes to it, the PLC prints the text on the serial monitor:

// BLE write on an Industrial Shields ESP32 PLC
// A phone writes text to a characteristic and the PLC prints it on the serial monitor
// Based on the BLE_write example of the ESP32 Arduino core (Neil Kolban, Evandro Copercini)

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

// Generate your own UUIDs (for example with uuidgen on Linux)
#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5b9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class WriteCallbacks : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {
    std::string value = pCharacteristic->getValue();   // String in ESP32 core 3.x
    if (value.length() > 0) {
      Serial.print("Received: ");
      Serial.println(value.c_str());
    }
  }
};

void setup() {
  Serial.begin(115200);
  Serial.println("1. Install a BLE scanner app on your phone");
  Serial.println("2. Scan and connect to ESP32-PLC");
  Serial.println("3. Write text to the custom characteristic");

  BLEDevice::init("ESP32-PLC");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
      CHARACTERISTIC_UUID,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE);

  pCharacteristic->setCallbacks(new WriteCallbacks());
  pCharacteristic->setValue("Hello from the PLC");
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}

void loop() {
  delay(2000);
}

To test it:

  1. Install a BLE scanner app on your phone, such as nRF Connect.
  2. Scan for devices and connect to ESP32-PLC.
  3. Open the custom service, write a text to the characteristic and send it.
  4. The serial monitor shows Received: followed by your text.

In a real project, map each command to an action in the program and check its value before you act on it. Keep emergency stops and other safety functions on wired circuits, not on a wireless link.

Both sketches compile without warnings in the sketch code with the Industrial Shields ESP32 package 2.7.1 for the ESP32 PLC 21 (compiler test of the sketch only, not a full build in the Arduino IDE). We have not run them on a PLC for this post.

Wi-Fi or BLE on an M-Duino or an Ardbox with an external ESP32

An M-Duino or an Ardbox can get wireless data from an ESP32 development board over a TTL serial line. The ESP32 board runs its own program, for example the Wi-Fi scan above with Serial2 instead of Serial, and the PLC reads what it receives.

M-Duino (Arduino Mega)

Connect TX2 of the ESP32 board to RX1 of the PLC and RX2 to TX1, plus a common GND. The ESP32 sends on Serial2 and the PLC receives on Serial1:

// M-Duino: print on the USB serial port what the ESP32 board sends to Serial1
void setup() {
  Serial.begin(19200);     // USB, serial monitor
  Serial1.begin(19200);    // TTL serial from the ESP32 board
}

void loop() {
  if (Serial1.available()) {
    Serial.print((char)Serial1.read());
  }
}

Ardbox (Arduino Leonardo)

Pins 0 and 1 of the Ardbox are used by the RS-232 port, so this example uses a software serial port on the MISO (RX) and MOSI (TX) pins:

// Ardbox: software serial on MISO (RX) and MOSI (TX), so pins 0 and 1 stay free for RS-232
#include <SoftwareSerial.h>

SoftwareSerial espSerial(MISO, MOSI);   // RX, TX

void setup() {
  Serial.begin(19200);      // USB, serial monitor
  espSerial.begin(19200);   // TTL serial from the ESP32 board
}

void loop() {
  if (espSerial.available()) {
    Serial.print((char)espSerial.read());
  }
}
Wiring diagram: a power supply at 7 to 12 V feeds an ESP32 development board, whose TX2 and RX2 pins go to the MISO and MOSI pins of an Ardbox PLC on a DIN rail, with a common GND
Test wiring: an ESP32 board powered at 7 to 12 V, with TX2 and RX2 to the MISO and MOSI pins of an Ardbox and a common GND.

Check the logic levels. The GPIOs of the ESP32 work at 3.3 V and are not 5 V tolerant, while the serial pins of the M-Duino and the Ardbox work at 5 V. Put a level shifter between the PLC TX and the ESP32 RX. Both programs compile and link with the Industrial Shields AVR package 1.2.1 for the M-Duino 21+ and the Ardbox Relay; they have not been tested on hardware for this post.

This setup is good for tests. In a machine, a controller with the radio inside, such as the ESP32 PLC, avoids loose boards and extra wiring in the cabinet.

FAQ about ESP32 Wi-Fi and Bluetooth

Does the ESP32 support 5 GHz Wi-Fi?

No. The radio of the ESP32 works only in the 2.4 GHz band, with 802.11 b/g/n. Check that the access point offers a 2.4 GHz network.

Can the ESP32 use Wi-Fi and Bluetooth at the same time?

Yes. Both share one radio and one antenna, and the chip divides the airtime between them. It works, but each link is slower than when it runs alone.

What is the difference between Bluetooth Classic and BLE on the ESP32?

Bluetooth Classic (BR/EDR) gives a continuous serial link, with the BluetoothSerial library. Bluetooth LE uses services and characteristics, uses less power and works with the apps of current phones. The ESP32 PLC product sheets list Bluetooth LE.

Which Industrial Shields PLCs have Wi-Fi and Bluetooth built in?

The ESP32 PLC family, from the ESP32 PLC 14 to the ESP32 PLC 58. The M-Duino and the Ardbox have no radio of their own.

Can I control the PLC outputs from a phone?

Yes, over BLE. The PLC Solution Library has an example of an ESP32 PLC controlled from a mobile app. Keep safety functions wired.

Take it further

Wireless on the ESP32 PLC in practice: a Wi-Fi gate system, control from a phone over BLE and a reconnection routine for factory Wi-Fi.

​Search in our Blog

ESP32 Bluetooth, BLE and Wi-Fi: specs and PLC examples
Serzh Ohanyan May 10, 2019
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