The ESP32 is a powerful WiFi module from the creators of the successful ESP8266 low-cost WiFi module, Espressif. The creators has released the ESP-IDF (Iot Development Framework) which is a FreeRTOS based core for the module that you can plug your own code and modules into.
The ESP32 module is a dual protocol hybrid with WiFi + Bluetooth + Ethernet with a 240Mhz dual core 600DMIPS CPU, 520KB RAM and 16MB flash, yet it uses very low power. All in all a much more powerful module as to what is needed for a uNabto integration – but this just leaves more space to the application.
Lots of different boards are out there, Espressif has released some, but we settled on the evaluation board from Olimex (ESP32-EVB) which has a good formfactor, good available interfaces, and even contains two 250VAC relays so it can be used for real applications out of the box (for example to remotely turn an appliance on/off). Also the hardware is open source, so you can download the pcb files and adjust it to match your own application.
The github repository for our project located here:
Experienced ESP32 developers might just need to read the readme file. But if you haven’t worked with ESP32, we advise you to read further on.
The Olimex ESP32-EVB Board and what you need
You can buy the board here: https://www.olimex.com/Products/IoT/ESP32-EVB/open-source-hardware
- ESP32-WROOM32 module
- Built-in programmer for Arduino and ESP-IDF
- WiFi, BLE connectivity
- Ethernet 100Mb interface
- MicroSD card
- Two relays 10A/250VAC with LED status
- CAN interface
- IR received and transmitter from 5 meter distance
- LiPo charger for stand alone operation during power breaks with 4 status LEDs
- UEXT connector to connect UEXT modules
- GPIO 40 pin connector with all ESP32 ports
- Dimensions: (75 x 75)mm ~ (2.95 x 2.95)
The board can be powered using an USB cable, so that is the only extra thing you need extra and you’re up and running. The USB is also the programming interface via a USB to serial builtin adapter.
What software you’ll need
The ESP32 contains two cores. An Arduino core and an ESP-IDF (IoT Development Framework) core. We have done many Arduino integrations so our idea was to do this specific integration via the ESP-IDF. So start by following the setup guide here:
Start by installing the toolchain for your operating system.
How the Nabto platform works
So far, so good. But how does the Nabto platform actually work? The drawing below gives a brief overview. Your ESP32 module represents the Device running the uNabto server. As soon as it connects to the internet it identifies itself at the Nabto Basestation, using its unique ID. If a Client wants to connect to the ESP32 module, a connect request with the ID is sent to the Basestation, and a direct connection to the device is established. A client can be a native app or use an abstraction framework like our Heat Control Ionic starter app used in this demo.
The above description is from helicopter perspective. The basestation is actually not a single instance but multiple clusters of basestations located in different datacenters around the world located based on the ip-geo-location of the device. The basestations have access to a distributed database telling potential clients that want to connect to a device, which basestation the client need to communicate with. Basestations are actually a manager-node that manages multiple worker-nodes. But to you as a developer all this is hidden, you just need to put the device-id and key on the device (if it’s a new system integrate to the Nabto integration adapter) and you have a world wide accessible device.
The uNabto Platform Adapter integration
The uNabto server is divided into two layers:
- The actual uNabto framework (uNabto SDK)
- The uNabto Platform Adapter abstraction layer between the framework and the Native Platform
Hence, we only need to implement the uNabto Platform Adapter, in order to port the uNabto device code to the ESP32 module.
Implementing the Platform Adapter
The Platform Adapter acts as link between the generic uNabto framework and the ESP-IDF core. The adapter is divided into single files, as suggested in the Nabto documentation (TEN023 Nabto device SDK guide, section 12), and the files can be found in the “porting” directory:
- unabto_config.h: Basic uNabto configuration
- unabto_platform_types.h: Define all necessary uNabto types
- unabto_platform.h: Platform specific ad-hoc functions
- network_adapter.c: Init, close, read and write functionality for network data
- time_adapter.c: Time functions
- dns_adapter.c: DNS resolving
- random_adapter.c: Random generator
If you are interested in how the platform adapter is implemented in detail, check the adapter files in the src directory of the library on GitHub. Since the ESP-IDF is based upon BSD sockets the integration is fairly easy. The logging adapter of uNabto has been tied to the “printf” command that writes to the serial interface.
Using the code
Just follow the instructions in the readme file of the github directory.
The github repository can be found here: github.com/nabto/unabto-esp32
You just need to clone the github repository:
~$ git clone --recursive https://github.com/nabto/unabto-esp32.git Cloning into 'unabto-esp32'... remote: Counting objects: 80, done. remote: Compressing objects: 100% (57/57), done. remote: Total 80 (delta 30), reused 60 (delta 17), pack-reused 0 Unpacking objects: 100% (80/80), done. Submodule 'components/unabto' (firstname.lastname@example.org:nabto/unabto.git) registered for path 'components/unabto' Cloning into '/Users/carstengregersen/unabto-esp32/components/unabto'... Submodule path 'components/unabto': checked out 'e60857eb0effea22f418f972c7bfec6153595f20'
Enter into the unabto-esp32 directory and type:
cd unabto-esp32/ make menuconfig
You will enter into the ESP-IDF configuration editor.
Remember to adjust the serial flasher to match the configuration of the specific USB-serial port driver you installed!!!
After this go into the “Custom configuration” menu:
You should now enter the WiFi access point SSID and password that the module should locally attach to. Also enter the Nabto-Id and key that you retrieve from the AppMyProduct portal (Signup -> Specify a product (f.x. mytestproduct) -> Generate Licenses -> Retrieve key).
After this, compile the project (make), flash the firmware (make flash) and lastly monitor the log (make monitor).
make make flash make monitor
You should see something like
0:00:00:114 main.c(172) Connecting to nabtotest1 00:00:00:117 main.c(74) Main task: waiting for connection to the wifi network... 00:00:02:486 main.c(76) connected! 00:00:02:487 main.c(82) IP Address: 192.168.0.103 00:00:02:490 main.c(83) Subnet mask: 255.255.255.0 00:00:02:495 main.c(84) Gateway: 192.168.0.1 00:00:02:499 unabto_common_main.c(121) Device id: 'uqhtktt3.smtth.appmyproduct.com' 00:00:02:506 unabto_common_main.c(122) Program Release 4.1.1 00:00:02:513 unabto_app_adapter.c(690) Application event framework using SYNC model 00:00:02:519 unabto_context.c(55) SECURE ATTACH: 1, DATA: 1 00:00:02:524 unabto_context.c(63) NONCE_SIZE: 32, CLEAR_TEXT: 0 00:00:02:531 unabto_common_main.c(200) Nabto was successfully initialized 00:00:02:537 unabto_application.c(71) In demo_init 00:00:02:541 unabto_application.c(92) Before fp_mem_init 00:00:02:546 unabto_application.c(95) Before acl_ae_init 00:00:02:555 unabto_context.c(55) SECURE ATTACH: 1, DATA: 1 00:00:02:556 unabto_context.c(63) NONCE_SIZE: 32, CLEAR_TEXT: 00:00:02:565 unabto_attach.c(804) State change from IDLE to WAIT_DNS 00:00:02:568 unabto_attach.c(805) Resolving DNS for uqhtktt3.smtth.appmyproduct.com 00:00:02:585 unabto_attach.c(818) DNS error (returned by application) 00:00:02:587 unabto_attach.c(819) State change from WAIT_DNS to IDLE 00:00:04:595 unabto_context.c(55) SECURE ATTACH: 1, DATA: 1 00:00:04:596 unabto_context.c(63) NONCE_SIZE: 32, CLEAR_TEXT: 0 00:00:04:599 unabto_attach.c(804) State change from IDLE to WAIT_DNS 00:00:04:602 unabto_attach.c(805) Resolving DNS for uqhtktt3.smtth.appmyproduct.com 00:00:04:615 unabto_attach.c(824) Resolved DNS for uqhtktt3.smtth.appmyproduct.com to: 00:00:04:617 unabto_attach.c(830) <span class="Apple-converted-space"> </span>Controller ip: 220.127.116.11 00:00:04:622 unabto_attach.c(836) State change from WAIT_DNS to WAIT_BS 00:00:04:686 unabto_attach.c(487) State change from WAIT_BS to WAIT_GSP 00:00:04:686 unabto_attach.c(488) GSP address: 18.104.22.168:5565 00:00:04:695 unabto_attach.c(275) ########U_INVITE with LARGE nonce sent, version: - URL: - 00:00:04:750 unabto_attach.c(591) State change from WAIT_GSP to ATTACHED
The last line is indicating success:
State change from WAIT_GSP to ATTACHED
This tells that the device now is attached to a GSP (Group ServerPeer – which could be considered a basestation worker node).
Now download the Heatcontrol demo app. Pair it with the ESP32-EVB board and now you can remote access the board. NOTE: The ACL list is currently stored in RAM not stored in EEPROM, i.e. a reboot will reset the Access Control List.
Please contact our email@example.com if you have any questions or need any help with integration.