LinkUp ESP32
 
linkuplogo
LinkUp
linkuplogo

 

An ESP32 Based Coprocessor System

Motivation

Simple microcontrollers are widely used in embedded systems for IoT and robotic applications. There is a growing need to connect these systems to the Internet in order to transmit the data collected by sensors to a remote control system or to receive commands for connected actuators. A direct connection of the microcontroller with the Internet via Ethernet or WLAN, or creating a local access point is often impossible because no such communication hardware is available on the chip. To overcome this problem, a coprocessor can be added to perform these communication tasks.

Data exchange between the microcontroller and the coprocessor should be as simple as possible, as the microcontroller usually has modest resources. The easiest way is to consider the coprocessor as a special type of sensor that receives commands via a standard protocol to perform the communication task. The coprocessor may return information the the microcontroller by the same was. Common protocols for data exchange with sensors are I²C, SPI and UART.

The general concept is shown here (using an Arduino or micro:bit as master, not both at the same time):

linkup5

 

Note:
The ESP32 and not the ESP8266 is used here, since the latter cannot be configured as an I²C slave. There are WLAN add-on boards with the ESP8266 on the market which communicate via a serial interface (UART). However, since the UART interface on the microcontroller is often used for runtime debugging, the connection of the coprocessor via I²C is preferrable. In addition, the ESP32 is much more powerful than the ESP8266, which is especially noticeable when used as a web server.

The LinkUp overcomes the limitations of small microcontroller systems in memory and WLan communication. It opens a wide door to the outside world and applications in the following areas are easy built because the details of the code running on the coprocessor are completely hidden to the application developer.

  • HTTP/HTTPS GET and POST requests (used for most cloud appllications)
  • Web server exposed via a Wlan router
  • Running a local Wlan hotspot for TCP communicaion
  • MQTT publisher and subscriber for typical IoT applications
  • NTP clock synchronization

 

Linkup Manager

After flashing the ESP32 with MicroPython, the program LinkupManager.py is started. It runs an I²C slave at address 0x77 and waits for commands in string format received from an I²C master. The command processor performs the requested action and reports the results back to the master. Typically the master is a small microcontroller with little memory (micro:bit, Arduino, etc.) and only a few lines of command code is necessary to perfom quite complicate actions on the ESP coprocessor. The master program can be written in any programming language (typically MicroPython, C/C++, JavaScript, etc.) or in a visual programming environment (Scratch, Blockly, etc.). The programmer is completely isolated from the code of the LinkupManager and only concerned with the interface API, which is restricted to string exchange.

The ESP32 can be installed on any development board, for example as LOLIN32, Huzzah32 Feather, ESP32-WROOM, ESP32MiniKit Wemos, etc. Because of the small dimensions, the latter is preferred here.

The communication between the master (Arduino, micro:bit) and the slave (ESP32) is based on a simple user definied protocol. The master sends a integer command ID and a string argument and waits eventually for a single string reply. If more than one value is passed, the values are packed into a single string by using a separator ('"?", ":" or "\1").


Linkup Interface Protocol


Description

ID
(int)

Arguments
(string)

Return value
 (string)

Blocking
(wait for task done)

Login to an access point (disconnect, if already connected)

1

ssid;password

IP address attributed by the access point, empty if login failed

Yes

Create access point

9

ssid;password

empty

Yes

Perform HTTP GET request

2

url/?key=value;...

Response (content only)

Yes

Perform HTTP POST request

3

url?key=value;...

Response
(content only)

Yes

Perform HTTP DELETE request

4

url

empty

Yes

Start Web server

5

empty

address?filename?params

No

Request deep sleep

6

empty

empty

No

Request reboot

7

empty

empty

No

Receive text

8

line<wait>line<wait>...
empty_line

empty

Yes (line per line)

Create MQTT client

10

host\0port\0
user\0password\0\keepalive
keepalive = "0": disabled
keepalive = "1": enabled

empty

Yes

Disconnect from MQTT broker

11

empty

empty

No

Publish MQTT topic

12

topic\0payload\0retain\0qos
qos: "0", "1", "2"
retain = "False", "True"

"True", if successful
"False", if failed

Yes

Subscribe MQTT topic

13

topic\qos
qos: "0", "1", "2"

"True", if successful
"False", if failed

Yes

Request  MQTT message
from Fifo queue

14

empty

topic\1message
empty, if no message in queue

Yes

Perform MQTT ping

15

empty

"True", if successful
"False", if failed

Yes

Set MQTT last will

16

topic\0payload\0retain\0qos
qos: "0", "1", "2"
retain = "False", "True"

True", if successful
"False", if failed

Yes

Connect MQTT broker

17

"True" if clean session; else "False"

True", if successful
"False", if failed

Yes

Get time from NTP server

18

empty or server URL
if empty: pool.ntp.org

yyyy:mm:dd:hh:mm:ss:ww
empty, if failed

Yes

Get version info

19

empty

Version of Linkup firmware

Yes

The protocol is easily implemented for different programming environments on the master. Libraries are available written in MicroPython for the micro:bit and in written in C/C++ for the Arduino. See the right side bar for the API definitions. The source of the LinkUpManager and the libraries are part of the LinkUp distribution.

 

Web Server

Command option 5 starts a Web server that replies to HTTP GET requests on port 80. The command differs from others because in this mode the ESP32 remains in an endless loop and does not respond any more to other commands (with the exception of a terminate-server command). To set the ESP32 to normal mode, the reset button must be clicked (or a terminate-server command is issued).

The URL of the client's GET request is extracted and transmitted from the ESP32 to the I²C master (Arduino, micro:bit) in the form clientIP?filename?(key1=value1,key2=value2,... e.g. for a request with the URL

http://clientIP/index.html?lamp1=on,lamp2=off

"clientIP?index.html?lamp1=on,lamp2=off"

The Arduino or micro:bit register a callback function onRequest() that receives the three part of the URL. It processes this information and returns a appropriate string that is sent back to the ESP32 and assembled into the HTTP reponse. For the programmer of the Arduino or micro:bit only the callback function is of his concern since the internals are fully transparent, More information can be found in the sample programs.

The Web server is useful in robotics applications so that a rover can communicate with its environment, for example to be controlled remotely with a smartphone and to transfer state information. This eliminates the need to develop a dedicated mobile app, and the user interface is determined solely by the design of the Web page. Simple knowledge of HTML and possibly JavaScript is sufficient.

linkup12
linkup13

 

Installation of the LinkUp coprocessor firmware

A standalone flash utility for Windows and Mac is part of the Linkup distribution. A flash option for the ESP32 coprocessor is also included in the TigerJython IDE. Since the standard MicroPython firmware does not support I²C slaves, the LoBo version of MicroPython developed by Boris Lovosevic is used.