Blinking LED Circuit Design
WiFi.h onlyTable
| Function | GPIO/Pin | Connected To | Direction | Notes |
|---|---|---|---|---|
| Current ADC input | GPIO34 (D34) | ADC_CT from SCT-013 front-end (J2, R3, R4, D3, D6) | Input | ADC1 channel, safe while WiFi is active |
| Voltage ADC input | GPIO36 (VP) | ADC_V from ZMPT101B front-end (U3, R5, R6, R7, D7, D8) | Input | ADC1 channel, safe while WiFi is active |
| Status LED | GPIO25 (D25) | R8 -> D2 | Output | Active high |
| Isolated output drive | GPIO26 (D26) | R9 -> U4 LED input | Output | Drives PC817 LED |
| Reset button | EN | SW1 to GND | Hardware only | Not software-controlled |
platformio.iniIni
[env:esp32dev] platform = espressif32 board = esp32dev framework = arduino monitor_speed = 115200 upload_speed = 921600 build_flags = -DCORE_DEBUG_LEVEL=3
src/main.cppCpp
#include <Arduino.h> #include <WiFi.h> static constexpr int PIN_ADC_CURRENT = 34; // U1:D34 static constexpr int PIN_ADC_VOLTAGE = 36; // U1:VP static constexpr int PIN_STATUS_LED = 25; // U1:D25 static constexpr int PIN_OPTO_OUT = 26; // U1:D26 static constexpr uint32_t SERIAL_BAUD = 115200; static constexpr uint32_t SAMPLE_PERIOD_MS = 1000; static constexpr uint8_t ADC_BITS = 12; static constexpr float ADC_VREF = 3.3f; static constexpr float ADC_MAX_COUNT = 4095.0f; static constexpr float CT_BIAS_VOLTAGE = 1.65f; static constexpr float ZMPT_DIVIDER_RATIO = (10.0f / (27.0f + 10.0f)); const char* WIFI_SSID = "YOUR_WIFI_SSID"; const char* WIFI_PASS = "YOUR_WIFI_PASSWORD"; unsigned long lastSampleMs = 0; unsigned long lastWifiRetryMs = 0; static float adcCountsToVoltage(int counts) { return (static_cast<float>(counts) * ADC_VREF) / ADC_MAX_COUNT; } static float readCurrentChannelVoltage(void) { int raw = analogRead(PIN_ADC_CURRENT); float voltage = adcCountsToVoltage(raw); return voltage - CT_BIAS_VOLTAGE; } static float readVoltageChannelAtAdc(void) { int raw = analogRead(PIN_ADC_VOLTAGE); return adcCountsToVoltage(raw); } static float estimateZmptModuleOutput(float adcVoltage) { return adcVoltage / ZMPT_DIVIDER_RATIO; } static void setOptoOutput(bool enabled) { digitalWrite(PIN_OPTO_OUT, enabled ? HIGH : LOW); } static void initWifi(void) { WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASS); unsigned long startMs = millis(); while (WiFi.status() != WL_CONNECTED && (millis() - startMs) < 10000UL) { delay(250); Serial.print('.'); } Serial.println(); if (WiFi.status() == WL_CONNECTED) { Serial.print("WiFi connected, IP: "); Serial.println(WiFi.localIP()); } else { Serial.println("WiFi not connected; continuing in offline logging mode."); } } void setup() { Serial.begin(SERIAL_BAUD); delay(200); Serial.println("ESP32 energy monitor starting..."); pinMode(PIN_STATUS_LED, OUTPUT); pinMode(PIN_OPTO_OUT, OUTPUT); digitalWrite(PIN_STATUS_LED, LOW); digitalWrite(PIN_OPTO_OUT, LOW); analogReadResolution(ADC_BITS); analogSetPinAttenuation(PIN_ADC_CURRENT, ADC_11db); analogSetPinAttenuation(PIN_ADC_VOLTAGE, ADC_11db); initWifi(); } void loop() { unsigned long now = millis(); if (WiFi.status() != WL_CONNECTED && (now - lastWifiRetryMs) >= 30000UL) { lastWifiRetryMs = now; Serial.println("Retrying WiFi connection..."); WiFi.disconnect(true, true); delay(100); initWifi(); } if ((now - lastSampleMs) >= SAMPLE_PERIOD_MS) { lastSampleMs = now; float ctAcComponent = readCurrentChannelVoltage(); float adcVoltage = readVoltageChannelAtAdc(); float zmptModuleOutput = estimateZmptModuleOutput(adcVoltage); Serial.print("CT centered voltage (V): "); Serial.print(ctAcComponent, 4); Serial.print(" | Voltage ADC (V): "); Serial.print(adcVoltage, 4); Serial.print(" | Estimated ZMPT OUT (V): "); Serial.println(zmptModuleOutput, 4); bool telemetryActive = (WiFi.status() == WL_CONNECTED); digitalWrite(PIN_STATUS_LED, telemetryActive ? HIGH : !digitalRead(PIN_STATUS_LED)); setOptoOutput(telemetryActive); } }
pio runpio run -t uploadpio device monitor -b 115200SW1 reset button tied to ENGPIO34 and GPIO36/VP are ADC1 inputs, so they remain usable while WiFi is active.R5/R6 before the ESP32 ADC; calibrate the final mains-voltage conversion in software.GPIO26 drives the PC817 LED through R9; set it HIGH to energize the optocoupler.Platform & Toolchain
Pin Mapping
Dependencies & Project Setup
`platformio.ini`
Complete Firmware Source
`src/main.cpp`
Build & Flash Instructions
Bring-Up Notes