USB-C Wi-Fi/BLE Sensor Design

I’ll add a separate control-panel schematic block for the boric acid slurry measurement system, using terminal headers/generic blocks for the PLC, SMPS, SSRs, relays, pumps, alarm, and RS‑485 sensor wiring. I’ll keep the existing design intact unless you explicitly ask me to replace it.
Added the Boric Acid Slurry control-panel schematic as a separate subsystem without removing the existing sensor-node design.
Completed:
  • 220 VAC input and 220 VAC → 24 VDC SMPS.
  • PLC input block with X0 Start, X1 Stop, X2 Temp 40 °C, X3 Temp 43 °C using +24 V source-input logic.
  • PLC output block with Y0–Y3 sink-output logic for SSRs/relays, P-101, P-102, V-1, and alarm.
  • RS-485 RDA/RDB terminal for turbidity sensor.
  • Wire-color notes documented in the project file: Boric Acid Slurry Automatic Measurement System — Control Panel Wiring.
Electrical review for the new control-panel wiring returned no matching ERC errors/warnings. Note: final SSR/relay/contact ratings should be checked against real pump current, inrush, enclosure, fusing, and local electrical safety requirements before panel build.
Add protection devices
Add field terminals
Check load ratings
Run full review
Create control BOM

Refine this doc
Ask about this doc
Firmware Starter — ESP32-C3-WROOM-02-N4
Platform & Toolchain
  • MCU/module: ESP32-C3-WROOM-02-N4
  • Framework: Arduino on PlatformIO
  • Sensor: Sensirion SHT40-AD1B-R3, I2C address 0x44
  • USB programming/debug: native ESP32-C3 USB Serial/JTAG on IO18/IO19
Pin Mapping

Table


FunctionGPIO / PinConnected ToDirectionNotes
I2C_SDAGPIO4U4 SDA, R_SDA 4.7 kΩ pull-upBidirectionalSHT40 data line
I2C_SCLGPIO5U4 SCL, R_SCL 4.7 kΩ pull-upOutputSHT40 clock line
STATUS_LEDGPIO10R_LED then LED1OutputActive high LED
USB_D_NGPIO18J1 DN1/DN2 through ESD D1USBNative USB D-
USB_D_PGPIO19J1 DP1/DP2 through ESD D1USBNative USB D+
ESP_BOOT_IO9GPIO9Boot button to GND, 10 kΩ pull-upInput/strapHold BOOT while resetting to enter download mode
ESP_ENENReset button, 10 kΩ pull-up, 1 µF to GNDResetPull low to reset
platformio.ini

Ini


[env:esp32-c3-devkitm-1]
platform = espressif32
board = esp32-c3-devkitm-1
framework = arduino
monitor_speed = 115200
upload_speed = 460800
build_flags =
    -D ARDUINO_USB_MODE=1
    -D ARDUINO_USB_CDC_ON_BOOT=1
lib_deps =
    adafruit/Adafruit SHT4x Library@^1.0.5
    h2zero/NimBLE-Arduino@^1.4.2
Complete Firmware Source — src/main.cpp

Cpp


#include <Arduino.h>
#include <Wire.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <Adafruit_SHT4x.h>
#include <NimBLEDevice.h>

// Pin definitions from schematic
#define I2C_SDA_PIN      4
#define I2C_SCL_PIN      5
#define STATUS_LED_PIN   10
#define BOOT_BUTTON_PIN  9

// SHT40 default I2C address is 0x44. The Adafruit driver handles this internally.
#define SENSOR_READ_INTERVAL_MS 10000UL
#define WIFI_RETRY_INTERVAL_MS  30000UL

const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const char* HTTP_ENDPOINT = "http://example.local/environment";

Adafruit_SHT4x sht4;
unsigned long lastSensorRead = 0;
unsigned long lastWifiAttempt = 0;
bool sensorReady = false;

NimBLEServer* bleServer = nullptr;
NimBLECharacteristic* envCharacteristic = nullptr;

static void setStatusLed(bool on) {
  digitalWrite(STATUS_LED_PIN, on ? HIGH : LOW);
}

static void initI2CAndSensor() {
  Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN, 400000);

  sensorReady = sht4.begin(&Wire);
  if (!sensorReady) {
    Serial.println("ERROR: SHT40 not found on I2C address 0x44");
    return;
  }

  sht4.setPrecision(SHT4X_HIGH_PRECISION);
  sht4.setHeater(SHT4X_NO_HEATER);  // Keep heater off for low-power normal operation.
  Serial.println("SHT40 initialized");
}

static void initWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.setSleep(true);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  lastWifiAttempt = millis();
  Serial.print("Connecting to WiFi");
}

static void maintainWiFi() {
  if (WiFi.status() == WL_CONNECTED) {
    return;
  }

  unsigned long now = millis();
  if (now - lastWifiAttempt >= WIFI_RETRY_INTERVAL_MS) {
    Serial.println("Retrying WiFi connection");
    WiFi.disconnect(true);
    delay(50);
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    lastWifiAttempt = now;
  }
}

static void initBLE() {
  NimBLEDevice::init("EnvNode-C3");
  NimBLEDevice::setPower(ESP_PWR_LVL_N0);  // Conservative BLE TX power for consumer node.

  bleServer = NimBLEDevice::createServer();
  NimBLEService* service = bleServer->createService("181A");  // Environmental Sensing service

  envCharacteristic = service->createCharacteristic(
      "2A6E",  // Temperature characteristic UUID
      NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

  envCharacteristic->setValue("0.00 C, 0.00 %RH");
  service->start();

  NimBLEAdvertising* adv = NimBLEDevice::getAdvertising();
  adv->addServiceUUID("181A");
  adv->setScanResponse(true);
  adv->start();

  Serial.println("BLE environmental service advertising");
}

static bool readSHT40(float& temperatureC, float& humidityPercent) {
  if (!sensorReady) {
    return false;
  }

  sensors_event_t humidity;
  sensors_event_t temp;
  bool ok = sht4.getEvent(&humidity, &temp);
  if (!ok) {
    Serial.println("ERROR: SHT40 read failed");
    return false;
  }

  temperatureC = temp.temperature;
  humidityPercent = humidity.relative_humidity;
  return true;
}

static void publishWiFi(float temperatureC, float humidityPercent) {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi not connected; skipping HTTP publish");
    return;
  }

  HTTPClient http;
  http.begin(HTTP_ENDPOINT);
  http.addHeader("Content-Type", "application/json");

  String payload = "{\"temperature_c\":" + String(temperatureC, 2) +
                   ",\"humidity_percent\":" + String(humidityPercent, 2) + "}";

  int code = http.POST(payload);
  Serial.printf("HTTP POST %d: %s\n", code, payload.c_str());
  http.end();
}

static void publishBLE(float temperatureC, float humidityPercent) {
  if (envCharacteristic == nullptr) {
    return;
  }

  char payload[48];
  snprintf(payload, sizeof(payload), "%.2f C, %.2f %%RH", temperatureC, humidityPercent);
  envCharacteristic->setValue((uint8_t*)payload, strlen(payload));
  envCharacteristic->notify();
}

void setup() {
  pinMode(STATUS_LED_PIN, OUTPUT);
  pinMode(BOOT_BUTTON_PIN, INPUT_PULLUP);
  setStatusLed(false);

  Serial.begin(115200);
  delay(500);
  Serial.println("USB-C WiFi/BLE Environmental Sensor Node booting");

  initI2CAndSensor();
  initBLE();
  initWiFi();
}

void loop() {
  maintainWiFi();

  unsigned long now = millis();
  if (now - lastSensorRead >= SENSOR_READ_INTERVAL_MS) {
    lastSensorRead = now;

    float temperatureC = 0.0f;
    float humidityPercent = 0.0f;
    if (readSHT40(temperatureC, humidityPercent)) {
      setStatusLed(true);
      Serial.printf("T=%.2f C, RH=%.2f %%\n", temperatureC, humidityPercent);
      publishBLE(temperatureC, humidityPercent);
      publishWiFi(temperatureC, humidityPercent);
      delay(25);
      setStatusLed(false);
    } else {
      for (int i = 0; i < 3; ++i) {
        setStatusLed(true);
        delay(80);
        setStatusLed(false);
        delay(80);
      }
    }
  }

  delay(10);
}
Build, Flash, and Monitor

Bash


pio run
pio run -t upload
pio device monitor
Bootloader Entry
  1. Hold SW_BOOT.
  2. Press and release SW_RESET.
  3. Release SW_BOOT.
  4. Run pio run -t upload.
Low-Power Notes
  • Keep the SHT40 heater disabled for normal environmental monitoring.
  • Increase SENSOR_READ_INTERVAL_MS to reduce Wi-Fi activity.
  • For production battery-derived variants, use deep sleep and wake periodically; this USB-C version keeps USB/Wi-Fi services active by default.
  • Platform & Toolchain

  • Pin Mapping

  • `platformio.ini`

  • Complete Firmware Source — `src/main.cpp`

  • Build, Flash, and Monitor

  • Bootloader Entry

  • Low-Power Notes

Documents

  • Firmware Starter — ESP32-C3-WROOM-02-N4

  • Project Specification — USB-C WiFi BLE Environmental Sensor Node

  • Boric Acid Slurry Automatic Measurement System — Control Panel Wiring

Assets

No assets added.

USB-C WiFi BLE Environmental Sensor Node b4cb

USB-C WiFi BLE Environmental Sensor Node b4cb thumbnail
Low-power consumer temperature and humidity sensor node using USB-C 5 V input, protected power path, ESP32 Wi-Fi/BLE connectivity, and a digital T/RH sensor.

Properties

USB-C 5 V sink; default Type-C current, compatible with 0.5 A to 3 A sources; protected by OVP/UVLO/OCP/reverse-current input stage and regulated 3.3 V rail.

USB-C power/programming, boot/reset buttons, status LED

2.4 GHz Wi-Fi 802.11 b/g/n plus Bluetooth Low Energy 5.x

Consumer environmental sensing / IoT

Digital temperature/relative humidity sensor on I2C; low-power ESP32-class module with native USB; protected USB-C VBUS path; 3.3 V regulator sized for Wi-Fi transmit current.

5

V

Pricing & Availability

Distributor

Qty 1

Arrow

$14.64–$18.56

Digi-Key

$7.18

HQonline

$10.40

LCSC

$45.30–$45.66

Mouser

$62.90

TME

$73.22

Verical

$64.34–$89.99

Controls