Typically the WiFi credentials and other per device settings are hardcoded for each project and if those settings change, you will need to reprogram every device with the updated credentials. For smaller one off projects that seems acceptable, but there is an even easier way: Juerd Waalboer’s ESP-WiFiSettings.
With this library, if the ESP32 can create a captive WiFi portal on startup if it fails to connect to a WiFi Access Point. The key feature I love about it is secret credentials never need to touch the software (being instead stored in the SPIFFS on the ESP32).
From my testing an ESP32 configured with a Static IP address will connect to WiFi faster (yielding longer battery life for battery powered sensors). I slightly modified Juerd’s implementation to connect with a known IP, Gateway, and Netmask, if provided.
main.cpp:
#include <Arduino.h>
#include "meas.h" //NOLINT(build/include_subdir)
#include <SPIFFS.h>
#include <WiFiSettings.h>
Meas meas;
void setup() {
// put your setup code here, to run once:
meas = Meas();
String greeting = meas.get_hello() + "\n";
printf("%s", greeting.c_str());
SPIFFS.begin(true); // On first run, will format after failing to mount
//To reset stored credentials, run SPIFFS.format()
//SPIFFS.format();
// Use stored credentials to connect to your WiFi access point.
// If no credentials are stored or if the access point is out of reach,
// an access point will be started with a captive portal to configure WiFi.
WiFiSettings.connect(true, 30);
//WiFiSettings.portal();
printf("Wifi Connect done %lu\n", millis());
printf("Serial: %d\n", sn);
printf("MQTT Host:%s:%d\n", host.c_str(), port);
}
void loop() {
// put your main code here, to run repeatedly:
printf("Mag: %d, time: %lu\n", meas.get_hall(), millis());
delay(1000);
}
The platform.ini file has been updated to point to my GitHub fork of ESP-WiFiSettings that supports Static IP, but you can easily include the original ESP-WiFiSettings.
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:ezsbc]
platform = espressif32
board = esp-wrover-kit
framework = arduino
monitor_speed = 115200
build_flags = -DCORE_DEBUG_LEVEL=5
lib_deps =
;ESP-WiFiSettings
; KeyOpt/ESP-WiFiSettings.git allows Static IP selection
https://github.com/KeyOpt/ESP-WiFiSettings.git#master
With that library, the ESP32 will create a local hotspot that you can connect to and configure for your WiFi network which is shown here.
Continuous Integration
Setting up this project with Continuous Integration means that each time we perform a commit, all of the tests that we designed previously will be run.
And for each one of those tests, we can click on it and get a full console log showing exactly what was processed (and what went wrong):
[0KRunning with gitlab-runner 13.3.0-rc1 (669fc507)
[0;m[0K on docker-auto-scale ed2dce3a
[0;msection_start:1598319418:prepare_executor
[0K[0K[36;1mPreparing the "docker+machine" executor[0;m
[0;m[0KUsing Docker executor with image python:latest ...
[0;m[0KPulling docker image python:latest ...
[0;m[0KUsing docker image sha256:79cc46abd78d048923350e8fb4af6cd47177d36606f8834a8e770b7eaf7e4452 for python:latest ...
[0;msection_end:1598319449:prepare_executor
[0Ksection_start:1598319449:prepare_script
[0K[0K[36;1mPreparing environment[0;m
[0;mRunning on runner-ed2dce3a-project-20446038-concurrent-0 via runner-ed2dce3a-srm-1598319353-74fae3f9...
section_end:1598319454:prepare_script
[0Ksection_start:1598319454:get_sources
[0K[0K[36;1mGetting source from Git repository[0;m
[0;m[32;1m$ eval "$CI_PRE_CLONE_SCRIPT"[0;m
[32;1mFetching changes with git depth set to 50...[0;m
Initialized empty Git repository in /builds/KeyOpt/esp32-sensor/.git/
[32;1mCreated fresh repository.[0;m
[32;1mChecking out 380ffb51 as wifi_captive_portal...[0;m
[32;1mSkipping Git submodules setup[0;m
section_end:1598319456:get_sources
[0Ksection_start:1598319456:download_artifacts
[0K[0K[36;1mDownloading artifacts[0;m
[0;m[32;1mDownloading artifacts for cpplint (701658283)...[0;m
Downloading artifacts from coordinator... ok [0;m id[0;m=701658283 responseStatus[0;m=200 OK token[0;m=aap4s6sn
[32;1mDownloading artifacts for flawfinder (701658284)...[0;m
Downloading artifacts from coordinator... ok [0;m id[0;m=701658284 responseStatus[0;m=200 OK token[0;m=y9CCe75_
[32;1mDownloading artifacts for cppcheck (701658286)...[0;m
Downloading artifacts from coordinator... ok [0;m id[0;m=701658286 responseStatus[0;m=200 OK token[0;m=fs8SM6ED
section_end:1598319457:download_artifacts
[0Ksection_start:1598319457:step_script
[0K[0K[36;1mExecuting "step_script" stage of the job script[0;m
[0;m[32;1m$ pip install -U platformio[0;m
Collecting platformio
Downloading platformio-4.3.4.tar.gz (190 kB)
Collecting bottle<0.13
Downloading bottle-0.12.18-py3-none-any.whl (89 kB)
Collecting click<8,>=5
Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting colorama
Downloading colorama-0.4.3-py2.py3-none-any.whl (15 kB)
Collecting pyserial!=3.3,<4,>=3
Downloading pyserial-3.4-py2.py3-none-any.whl (193 kB)
Collecting requests<3,>=2.4.0
Downloading requests-2.24.0-py2.py3-none-any.whl (61 kB)
Collecting semantic_version<3,>=2.8.1
Downloading semantic_version-2.8.5-py2.py3-none-any.whl (15 kB)
Collecting tabulate<1,>=0.8.3
Downloading tabulate-0.8.7-py3-none-any.whl (24 kB)
Collecting pyelftools<1,>=0.25
Downloading pyelftools-0.26-py2.py3-none-any.whl (136 kB)
Collecting marshmallow>=2
Downloading marshmallow-3.7.1-py2.py3-none-any.whl (45 kB)
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1
Downloading urllib3-1.25.10-py2.py3-none-any.whl (127 kB)
Collecting idna<3,>=2.5
Downloading idna-2.10-py2.py3-none-any.whl (58 kB)
Collecting certifi>=2017.4.17
Downloading certifi-2020.6.20-py2.py3-none-any.whl (156 kB)
Collecting chardet<4,>=3.0.2
Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB)
Building wheels for collected packages: platformio
Building wheel for platformio (setup.py): started
Building wheel for platformio (setup.py): finished with status 'done'
Created wheel for platformio: filename=platformio-4.3.4-py3-none-any.whl size=294313 sha256=aeace2d62cbb2b9a30ae916384366aebbd3e40280aa218ddcbc3030e5adc919b
Stored in directory: /root/.cache/pip/wheels/22/76/4e/8451b93142686519520b707538b8ced937c1b7a3e79f369ef5
Successfully built platformio
Installing collected packages: bottle, click, colorama, pyserial, urllib3, idna, certifi, chardet, requests, semantic-version, tabulate, pyelftools, marshmallow, platformio
Successfully installed bottle-0.12.18 certifi-2020.6.20 chardet-3.0.4 click-7.1.2 colorama-0.4.3 idna-2.10 marshmallow-3.7.1 platformio-4.3.4 pyelftools-0.26 pyserial-3.4 requests-2.24.0 semantic-version-2.8.5 tabulate-0.8.7 urllib3-1.25.10
[32;1m$ platformio run -e ezsbc[0;m
********************************************************************************
If you like PlatformIO, please:
- follow us on Twitter to stay up-to-date on the latest project news > https://twitter.com/PlatformIO_Org
- star it on GitHub > https://github.com/platformio/platformio
- try PlatformIO IDE for embedded development > https://platformio.org/platformio-ide
********************************************************************************
Processing ezsbc (platform: espressif32; board: esp-wrover-kit; framework: arduino)
--------------------------------------------------------------------------------
PlatformManager: Installing espressif32
Downloading...
Unpacking...
espressif32 @ 1.12.4 has been successfully installed!
The platform 'espressif32' has been successfully installed!
The rest of packages will be installed automatically depending on your build environment.
PackageManager: Installing toolchain-xtensa32 @ ~2.50200.0
Downloading...
Unpacking...
toolchain-xtensa32 @ 2.50200.80 has been successfully installed!
PackageManager: Installing framework-arduinoespressif32 @ ~3.10004.191002
Downloading...
Unpacking...
framework-arduinoespressif32 @ 3.10004.200129 has been successfully installed!
PackageManager: Installing tool-esptoolpy @ ~1.20600.0
Downloading...
Unpacking...
tool-esptoolpy @ 1.20600.0 has been successfully installed!
CorePackageManager: Installing tool-scons @ ~3.30102.0
Downloading...
Unpacking...
tool-scons @ 3.30102.0 has been successfully installed!
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp-wrover-kit.html
PLATFORM: Espressif 32 1.12.4 > Espressif ESP-WROVER-KIT
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (ftdi) On-board (ftdi) External (esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
- framework-arduinoespressif32 3.10004.200129 (1.0.4)
- tool-esptoolpy 1.20600.0 (2.6.0)
- toolchain-xtensa32 2.50200.80 (5.2.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
LibraryManager: Installing ESP-WiFiSettings
git version 2.20.1
Cloning into '/builds/KeyOpt/esp32-sensor/.pio/libdeps/ezsbc/_tmp_installing-btwywnhv-package'...
ESP-WiFiSettings @ ab6d62e has been successfully installed!
Found 28 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <ESP-WiFiSettings> 3.3.1 #ab6d62e
| |-- <DNSServer> 1.1.0
| | |-- <WiFi> 1.0
| |-- <SPIFFS> 1.0
| | |-- <FS> 1.0
| |-- <WebServer> 1.0
| | |-- <WiFi> 1.0
| | |-- <FS> 1.0
| |-- <WiFi> 1.0
|-- <measurements>
|-- <SPIFFS> 1.0
| |-- <FS> 1.0
Building in release mode
Compiling .pio/build/ezsbc/src/main.cpp.o
Generating partitions .pio/build/ezsbc/partitions.bin
Compiling .pio/build/ezsbc/lib789/WiFi/ETH.cpp.o
Compiling .pio/build/ezsbc/lib789/WiFi/WiFi.cpp.o
Compiling .pio/build/ezsbc/lib789/WiFi/WiFiAP.cpp.o
Compiling .pio/build/ezsbc/lib789/WiFi/WiFiClient.cpp.o
Compiling .pio/build/ezsbc/lib789/WiFi/WiFiGeneric.cpp.o
Compiling .pio/build/ezsbc/lib789/WiFi/WiFiMulti.cpp.o
Compiling .pio/build/ezsbc/lib789/WiFi/WiFiSTA.cpp.o
Compiling .pio/build/ezsbc/lib789/WiFi/WiFiScan.cpp.o
Compiling .pio/build/ezsbc/lib789/WiFi/WiFiServer.cpp.o
Compiling .pio/build/ezsbc/lib789/WiFi/WiFiUdp.cpp.o
Archiving .pio/build/ezsbc/lib789/libWiFi.a
Indexing .pio/build/ezsbc/lib789/libWiFi.a
Compiling .pio/build/ezsbc/lib43b/DNSServer/DNSServer.cpp.o
Archiving .pio/build/ezsbc/lib43b/libDNSServer.a
Indexing .pio/build/ezsbc/lib43b/libDNSServer.a
Compiling .pio/build/ezsbc/lib790/FS/FS.cpp.o
Compiling .pio/build/ezsbc/lib790/FS/vfs_api.cpp.o
Archiving .pio/build/ezsbc/lib790/libFS.a
Indexing .pio/build/ezsbc/lib790/libFS.a
Compiling .pio/build/ezsbc/lib117/SPIFFS/SPIFFS.cpp.o
Archiving .pio/build/ezsbc/lib117/libSPIFFS.a
Indexing .pio/build/ezsbc/lib117/libSPIFFS.a
Compiling .pio/build/ezsbc/lib5f9/WebServer/Parsing.cpp.o
Compiling .pio/build/ezsbc/lib5f9/WebServer/WebServer.cpp.o
Compiling .pio/build/ezsbc/lib5f9/WebServer/detail/mimetable.cpp.o
Archiving .pio/build/ezsbc/lib5f9/libWebServer.a
Indexing .pio/build/ezsbc/lib5f9/libWebServer.a
Compiling .pio/build/ezsbc/lib807/ESP-WiFiSettings/WiFiSettings.cpp.o
Archiving .pio/build/ezsbc/lib807/libESP-WiFiSettings.a
Indexing .pio/build/ezsbc/lib807/libESP-WiFiSettings.a
Compiling .pio/build/ezsbc/libf4c/measurements/meas.cpp.o
Archiving .pio/build/ezsbc/libf4c/libmeasurements.a
Indexing .pio/build/ezsbc/libf4c/libmeasurements.a
Archiving .pio/build/ezsbc/libFrameworkArduinoVariant.a
Indexing .pio/build/ezsbc/libFrameworkArduinoVariant.a
Compiling .pio/build/ezsbc/FrameworkArduino/Esp.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/FunctionalInterrupt.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/HardwareSerial.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/IPAddress.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/IPv6Address.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/MD5Builder.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/Print.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/Stream.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/StreamString.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/WMath.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/WString.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/base64.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/cbuf.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-adc.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-bt.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-cpu.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-dac.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-gpio.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-i2c.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-ledc.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-matrix.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-misc.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-psram.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-rmt.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-sigmadelta.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-spi.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-time.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-timer.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-touch.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/esp32-hal-uart.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/libb64/cdecode.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/libb64/cencode.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/main.cpp.o
Compiling .pio/build/ezsbc/FrameworkArduino/stdlib_noniso.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/wiring_pulse.c.o
Compiling .pio/build/ezsbc/FrameworkArduino/wiring_shift.c.o
Archiving .pio/build/ezsbc/libFrameworkArduino.a
Indexing .pio/build/ezsbc/libFrameworkArduino.a
Linking .pio/build/ezsbc/firmware.elf
Building .pio/build/ezsbc/firmware.bin
esptool.py v2.6
Retrieving maximum program size .pio/build/ezsbc/firmware.elf
Checking size .pio/build/ezsbc/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [= ] 12.3% (used 40392 bytes from 327680 bytes)
Flash: [====== ] 60.2% (used 789004 bytes from 1310720 bytes)
========================= [SUCCESS] Took 46.90 seconds =========================
[32;1m$ mv .pio/build/ezsbc/firmware.bin firmware_ezsbc.bin[0;m
section_end:1598319513:step_script
[0Ksection_start:1598319513:upload_artifacts_on_success
[0K[0K[36;1mUploading artifacts for successful job[0;m
[0;m[32;1mUploading artifacts...[0;m
firmware_ezsbc.bin: found 1 matching files and directories[0;m
Uploading artifacts as "archive" to coordinator... ok[0;m id[0;m=701658287 responseStatus[0;m=201 Created token[0;m=BssDteFq
section_end:1598319515:upload_artifacts_on_success
[0K[32;1mJob succeeded
My main.cpp includes prompts for a MQTT server and port, which will be discussed in the next post.
The source code for this post can be found here.