This page covers everything you need to wire up a Surqo sensor node, configure the firmware constants, and flash the ESP32. The firmware uses WiFiManager for zero-config WiFi setup and derives the node’s identity from its MAC address — no hardcoded credentials or farm IDs are stored in the firmware itself.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ricardomb-tech/surqo/llms.txt
Use this file to discover all available pages before exploring further.
GPIO Pinout
Connect each sensor to the following ESP32 pins. All sensor VCC lines are wired to GPIO25 rather than the 3.3V rail directly, so the firmware can cut power to every sensor before entering deep sleep.| ESP32 GPIO | Sensor | Notes |
|---|---|---|
| GPIO 4 | DHT22 DATA | Air temperature + humidity |
| GPIO 5 | DS18B20 DATA | Soil temperature — requires 10 kΩ pull-up to 3.3V |
| GPIO 25 | Sensor VCC (all sensors) | Set HIGH on wake, LOW before deep sleep to save energy |
| GPIO 32 | Capacitive soil AOUT | ADC1_CH4 |
| GPIO 34 | ML8511 UV OUT | ADC1_CH6 — input only |
| GPIO 35 | Battery voltage divider | ADC1_CH7 — input only |
First-Boot WiFi Setup (WiFiManager)
The Surqo firmware stores no WiFi credentials. On first power-on — or whenever it cannot connect to a previously saved network — it automatically opens a captive portal access point so the farmer can configure WiFi from any phone.Node opens the setup AP
The ESP32 broadcasts a WiFi network named
Surqo-Setup-{CLAIM_CODE} (e.g. Surqo-Setup-A3F2C1). The AP password is defined in secrets.h as AP_PASSWORD.Connect your phone
Join the
Surqo-Setup-XXXXXX network from your phone’s WiFi settings. A captive portal page opens automatically (or navigate to 192.168.4.1 manually).Enter your WiFi credentials
Select your home or farm WiFi network from the list and enter the password. Tap Save.
The portal times out after 180 seconds (
PORTAL_TIMEOUT_S). If no
credentials are entered in time, the node logs the failure to Serial and
enters deep sleep, retrying on the next scheduled wake.Claim Code and Device Pairing
Every Surqo node derives a unique claim code from the last 6 hex digits of its MAC address. This code is the only identifier you need to link a physical node to a farm in the web app.- Derivation example: MAC
a4:cf:12:a3:f2:c1→g_mac = "a4cf12a3f2c1"→claim_code = "A3F2C1" - The claim code is printed to Serial at 115200 baud on every boot, inside the startup banner.
- The node announces itself to the backend via
POST /api/v1/devices/register(sends MAC + firmware version) on each boot after WiFi connects.
- Open the Surqo web app → Devices → Pair Device
- Enter the 6-character claim code shown in the Serial monitor
- Select the farm to associate with this node
- All subsequent MQTT readings are routed to that farm automatically
No
FARM_ID is stored in the firmware. The backend resolves the farm
association from the MAC address after pairing. You can re-pair a node to a
different farm at any time from the web app.config.h Constants
Theconfig.h file defines every tunable parameter for the node. It is safe to version-control — all secrets (MQTT credentials and the portal password) live in secrets.h, which is excluded from git.
config.h
Create secrets.h
Before compiling, copysecrets.example.h to secrets.h and fill in your real credentials:
firmware/surqo_node/secrets.h
Build and Upload (PlatformIO)
Set
SLEEP_MINUTES 1 in config.h during development so the node wakes every
minute. Change it to 15 or 30 before deploying on battery in the field.Operation Cycle
On every wake triggered by the RTC deep sleep timer, the node executes the following sequence and then returns to sleep:Power sensors
GPIO25 is set HIGH, supplying 3.3V to all sensor VCC lines. A 2-second warmup delay (
SENSOR_WARMUP_MS) allows the DHT22 to stabilize.Read all sensors
The firmware reads in this order (before WiFi is enabled, because the radio can interfere with DHT22 timing):
- DHT22 — up to 5 attempts, average of first 3 valid readings
- DS18B20 — 12-bit conversion (~750 ms)
- Capacitive soil — 10 ADC samples averaged (
ADC_SAMPLES = 10) - ML8511 UV — 10 ADC samples averaged
- Battery voltage — 10 ADC samples averaged, multiplied by voltage divider factor 2
Connect WiFi
WiFiManager connects using stored credentials (or opens the captive portal if no credentials are saved).
Register device
A best-effort HTTPS POST to
POST /api/v1/devices/register announces the MAC address and firmware version to the backend.Publish via MQTT TLS
The node connects to HiveMQ Cloud on port 8883 (TLS) and publishes a JSON payload to topic
surqo/devices/{mac}/sensors.HTTP fallback
If MQTT fails (bad credentials, broker unreachable, TLS error), the firmware falls back to
POST /api/v1/devices/{mac}/reading over HTTPS.