First Boot and WiFi
What a healthy first boot looks like
- The splash screen appears with the Safi mark and firmware version.
- Below it, the boot report lists any peripheral that failed to initialize. On a complete build the list is empty; on a partial build you will see entries such as
SD (ESP_ERR_TIMEOUT). The device continues without the failed peripheral. - The screen switches to the idle clock, and it stays there while credentials are tried or provisioning runs. The WiFi status screen appears only after WiFi actually connects, and it returns to the idle clock on its own after 10 seconds. Time shows
--:--until WiFi connects and the clock synchronizes. - Once WiFi connects, the status bar gets a WiFi icon and the idle screen shows the device IP address.
Everything the boot decided is also visible later in the dashboard under Settings, and on the serial console if the device is connected over USB.
The three provisioning paths
Safi attempts credentials in a fixed order at every boot:
Path 1: saved credentials
Whatever worked before is stored in the device's encrypted settings flash and tried first. You get this automatically after any successful connection; there is nothing to configure.
Path 2: firmware credentials (for developers)
If you build from source, idf.py menuconfig under Safi Configuration has SAFI_WIFI_SSID and SAFI_WIFI_PASSWORD. These are compiled in as a fallback. The build system reads them from an untracked sdkconfig.local file so credentials never end up in git; see getting started.
Path 3: SoftAP provisioning (no computer needed)
When nothing else works, the device opens a provisioning access point named
Safi-XXXXXX, where the suffix comes from the device's own MAC address
(for example Safi-3C7A1B). Pairing takes about a minute:
- Install the ESP SoftAP Provisioning app (Espressif's official app, iOS and Android). The older ESPTouch app will not work: SmartConfig was removed in ESP-IDF v6 and Safi no longer speaks it.
- Open the app and press the refresh button; your phone lists nearby networks and sees
Safi-XXXXXXas an access point. - Tap it, then enter the provisioning username
safiand the proof of possession (PoP): the 16-character code printed on the device label (on production devices it is derived at the factory from the device's chip identity, not stored anywhere; on a first-boot development device it is printed once on the serial console). - The app now shows the usual WiFi list; pick your home network and enter its password.
- The credentials travel to the device over an encrypted provisioning session (SRP6a plus AES-GCM). A few seconds later Safi saves them and connects; the app confirms.
The PoP is not the WiFi password; it is the per-device code that proves you are holding this physical device. Without it the provisioning app cannot start a session at all, so there is nothing to brute force.
The ESP32-S3 radio does not support 5 GHz networks. The provisioning access point is on 2.4 GHz; the network you then choose in the app must be 2.4 GHz too. If your router broadcasts one name for both bands, this usually just works, but a 5 GHz only network will never be visible to the device. Phone hotspots default to 5 GHz on many models; switch the hotspot to 2.4 GHz ("maximize compatibility" on iPhone).
NFC alternative: if the device was provisioned with an NFC card bound to a WiFi configuration, one tap of that card on the reader sets the credentials and connects, no phone app involved. See NFC cards for how the binding is configured.
Choosing the transport: SoftAP or BLE
The transport is a compile-time choice, SAFI_PROVISIONING_TRANSPORT under Safi Configuration in menuconfig, SoftAP by default. Prebuilt firmware ships with SoftAP. A BLE build behaves identically except that Path 3 pairs over Bluetooth instead of an access point:
- When the provisioning window opens, the device advertises over BLE as
PROV_SafiXXXXXX(the six hex digits of the MAC suffix, for examplePROV_Safi3C7A1B). ThePROV_prefix is deliberate: the provisioning app filters BLE scans by a device name prefix,PROV_by default, so the device shows up without touching any app setting. - Open the ESP SoftAP Provisioning app and select the BLE transport; the scanned device list shows
PROV_SafiXXXXXX. - Tap it. The same username
safiand the same 16-character PoP from the device label apply; the session is the same security 2 setup (SRP6a plus AES-GCM), just carried over BLE. - Pick the WiFi network and enter its password. The credentials travel over BLE; a few seconds later Safi saves them and connects, and the app confirms.
Two practical notes: BLE provisioning needs no access point on the device, which helps when the phone must stay on a network that provides internet (for example a captive-portal hotspot). The provisioning window still alternates with stored-credential retries exactly as it does for SoftAP, and the 2.4 GHz note above applies unchanged to the network you pick.
Retry behavior
If the network drops, Safi retries automatically every 30 seconds. Failed connection attempts also step the radio transmit power down through a fallback ladder, which rescues marginal power supplies; the developer WiFi chapter tells that story.
If Safi ends up in provisioning mode (for example, your router was off during boot), it does not stay stuck there: the device alternates between advertising the Safi-XXXXXX access point (10 minutes by default) and quietly retrying its saved credentials, forever, until one of the two succeeds. A router that comes back an hour later gets rejoined without anyone touching the device.
Reading the diagnostics
Connected over USB, the serial console (115200 baud) narrates every attempt, including a scan of visible networks after each failure:
WIFI_MANAGER: Trying built-in WiFi credentials
WIFI_MANAGER: Retry connecting to WiFi... (1/5, reason=201)
WIFI_MANAGER: AP 'HomeNet': ch=6 rssi=-58 auth=WPA2
WIFI_MANAGER: Target SSID 'MyNet' not visible on 2.4 GHz (5 GHz-only network?)
The reason codes and what to do about each are in troubleshooting.