USB C WiFi BLE Sensor Node
Design Notes — USB-C WiFi BLE Environmental Node
Firmware Starter — ESP32-C3-WROOM-02-N4
Board Bring-Up Plan — USB-C WiFi BLE Environmental Node
Technical Construction File — USB-C WiFi BLE Environmental Node
Table
| Function | GPIO | Schematic net | Direction | Notes |
|---|---|---|---|---|
| I2C SDA | 0 | I2C_SDA | bidirectional | SHT40 SDA, 4.7 kΩ pull-up |
| I2C SCL | 1 | I2C_SCL | output | SHT40 SCL, 4.7 kΩ pull-up |
| Status LED | 3 | LED_STATUS_GPIO | output | Through R14=1 kΩ to D3 |
| eFuse fault | 4 | EFUSE_FLT | input | U1 FLT open-drain, 100 kΩ pull-up |
| Buck power-good | 5 | BUCK_PGOOD | input | U2 PG open-drain, 100 kΩ pull-up |
| BOOT button | 9 | ESP_BOOT | input at reset | 10 kΩ pull-up; SW1 pulls low |
| USB D− | 18 | USB_DN | USB | Native USB Serial/JTAG |
| USB D+ | 19 | USB_DP | USB | Native USB Serial/JTAG |
| UART RX | 20 | UART_RX | input | Recovery test point TP8 |
| UART TX | 21 | UART_TX | output | Recovery test point TP7 |
platformio.iniIni
[env:esp32-c3-env-node] platform = espressif32 board = esp32-c3-devkitm-1 framework = arduino monitor_speed = 115200 upload_speed = 921600 build_flags = -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1 lib_deps = adafruit/Adafruit SHT4x Library@^1.0.5 adafruit/Adafruit BusIO@^1.16.1
Cpp
#include <Arduino.h> #include <Wire.h> #include <WiFi.h> #include <Adafruit_SHT4x.h> #define I2C_SDA_PIN 0 #define I2C_SCL_PIN 1 #define STATUS_LED_PIN 3 #define EFUSE_FLT_PIN 4 #define BUCK_PGOOD_PIN 5 #define BOOT_BUTTON_PIN 9 #define UART_RX_PIN 20 #define UART_TX_PIN 21 #define SENSOR_ADDR 0x44 #define SENSOR_PERIOD_MS 5000 #define WIFI_RETRY_LIMIT 20 const char* WIFI_SSID = "YOUR_SSID"; const char* WIFI_PASSWORD = "YOUR_PASSWORD"; Adafruit_SHT4x sht4; unsigned long lastSensorReadMs = 0; void initStatusPins() { pinMode(STATUS_LED_PIN, OUTPUT); digitalWrite(STATUS_LED_PIN, LOW); pinMode(EFUSE_FLT_PIN, INPUT_PULLUP); pinMode(BUCK_PGOOD_PIN, INPUT_PULLUP); pinMode(BOOT_BUTTON_PIN, INPUT_PULLUP); } void initRecoveryUart() { Serial1.begin(115200, SERIAL_8N1, UART_RX_PIN, UART_TX_PIN); Serial1.println("ESP32-C3 environmental node recovery UART online"); } bool initSensor() { Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN, 400000); if (!sht4.begin(&Wire)) { Serial.println("SHT40 not detected at 0x44"); return false; } sht4.setPrecision(SHT4X_HIGH_PRECISION); sht4.setHeater(SHT4X_NO_HEATER); Serial.println("SHT40 initialized"); return true; } void connectWiFi() { WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("Connecting to WiFi"); int retries = 0; while (WiFi.status() != WL_CONNECTED && retries < WIFI_RETRY_LIMIT) { digitalWrite(STATUS_LED_PIN, !digitalRead(STATUS_LED_PIN)); delay(500); Serial.print('.'); retries++; } if (WiFi.status() == WL_CONNECTED) { digitalWrite(STATUS_LED_PIN, HIGH); Serial.printf("\nWiFi connected, IP=%s\n", WiFi.localIP().toString().c_str()); } else { digitalWrite(STATUS_LED_PIN, LOW); Serial.println("\nWiFi not connected; continuing offline"); } } bool powerPathHealthy() { bool efuseOk = digitalRead(EFUSE_FLT_PIN) == HIGH; bool buckOk = digitalRead(BUCK_PGOOD_PIN) == HIGH; if (!efuseOk) Serial.println("WARN: eFuse fault asserted"); if (!buckOk) Serial.println("WARN: 3V3 buck power-good is low"); return efuseOk && buckOk; } void readAndReportSensor() { sensors_event_t humidity, temp; if (!sht4.getEvent(&humidity, &temp)) { Serial.println("ERROR: SHT40 read failed"); return; } Serial.printf("T=%.2f C, RH=%.2f %%\n", temp.temperature, humidity.relative_humidity); Serial1.printf("T=%.2f C, RH=%.2f %%\n", temp.temperature, humidity.relative_humidity); if (WiFi.status() == WL_CONNECTED) { // Placeholder for production data path: publish MQTT or HTTP POST here. // Keep this non-blocking in production firmware. } } void setup() { Serial.begin(115200); delay(500); Serial.println("USB-C WiFi/BLE Environmental Node starting"); initStatusPins(); initRecoveryUart(); powerPathHealthy(); if (!initSensor()) { for (int i = 0; i < 10; i++) { digitalWrite(STATUS_LED_PIN, !digitalRead(STATUS_LED_PIN)); delay(100); } } connectWiFi(); } void loop() { if (WiFi.status() != WL_CONNECTED) { digitalWrite(STATUS_LED_PIN, LOW); connectWiFi(); } unsigned long now = millis(); if (now - lastSensorReadMs >= SENSOR_PERIOD_MS) { lastSensorReadMs = now; powerPathHealthy(); readAndReportSensor(); } delay(10); }
Bash
pio run pio run -t upload pio device monitor -b 115200
Platform & Toolchain
Pin Mapping
`platformio.ini`
Complete Starter Firmware
Build & Flash