The Problem: Manual NEC Wire Sizing is Error-Prone

When sizing conductors for a branch circuit or feeder, you must balance two competing constraints: the thermal ampacity limits defined in NEC Table 310.16 and the voltage drop over the physical distance of the run. Relying on mental math or generic apps often leads to missing the small conductor overrides in NEC 240.4(D) or forgetting to apply the 75°C vs 60°C termination rules from NEC 110.14(C).

To eliminate guesswork on the jobsite or at the workbench, we are building a dedicated National Electric Code wire sizing hardware calculator. This tool uses an ESP32 microcontroller to take your load (Amps), distance (Feet), and material (Copper/Aluminum), then outputs the exact minimum AWG required, factoring in both thermal limits and a strict 3% maximum voltage drop.

Direct Answer: For standard residential 120V/240V copper circuits under 100A, the 75°C column of NEC 310.16 is your baseline, but NEC 240.4(D) hard-caps 14 AWG at 15A, 12 AWG at 20A, and 10 AWG at 30A regardless of insulation rating. This calculator hardcodes those overrides to prevent dangerous undersizing.

Parts List & Spec Sheet

This build prioritizes off-the-shelf availability and 5V tolerance for the I2C bus. Do not substitute the ESP32-S3 or ESP32-C3 for this specific code without adjusting the I2C pin definitions, as the default hardware I2C pins differ across SoC variants.

ComponentExact Variant / ModelWhy This Part?
MicrocontrollerESP32-WROOM-32 DevKit V1 (30-pin)Standard 3.3V logic, dual-core, robust Espressif IDF support.
Display1.3' SH1106 I2C OLED (128x64)SH1106 driver handles 128x64 natively; larger than 0.96' for readability in bright panels.
Inputs12mm Tactile Pushbuttons (x3)Large caps, easy to press with gloves on. Internal pull-ups used (no external resistors needed).
Power5V 2A USB-C Wall AdapterPrevents brownouts when the OLED and ESP32 WiFi stack initialize simultaneously.
EnclosureHammond 1593VBU (Ventilated)Fits the DevKit and OLED with room for a 9V battery backup if added later.

Pin Mapping & Wiring Diagram

Wire the buttons between the specified GPIO pins and GND. The code enables the ESP32's internal pull-up resistors, so the buttons read HIGH when open and LOW when pressed.

ComponentPin / LabelESP32 DevKit V1 GPIONotes
SH1106 OLEDSDAGPIO 21Default I2C Data for ESP32-WROOM
SH1106 OLEDSCLGPIO 22Default I2C Clock for ESP32-WROOM
SH1106 OLEDVCC3V3Do NOT use 5V; SH1106 logic is 3.3V
SH1106 OLEDGNDGNDCommon ground
Button 1 (UP)SignalGPIO 25Connect other leg to GND
Button 2 (DOWN)SignalGPIO 26Connect other leg to GND
Button 3 (SELECT)SignalGPIO 27Connect other leg to GND

The Decision Tree: How the Code Calculates AWG

The algorithm doesn't just look up a table; it applies a strict decision path based on NEC rules. Here is the exact logic flow the C++ code executes to terminate on a single, code-compliant AWG pick.

Condition / InputNEC Rule AppliedAction Taken by Algorithm
Load <= 15A (Copper)NEC 240.4(D)(1)Force minimum 14 AWG. Skip thermal lookup.
Load <= 20A (Copper)NEC 240.4(D)(2)Force minimum 12 AWG. Skip thermal lookup.
Load <= 30A (Copper)NEC 240.4(D)(3)Force minimum 10 AWG. Skip thermal lookup.
Load > 30A (Copper)NEC 310.16 (75°C Col)Iterate through AWG array until Ampacity >= Load.
Voltage Drop > 3% of NominalNEC 310.15(B) (Info Note)Bump the selected AWG up one size (lower gauge number) and recalculate VD.
Material = AluminumNEC 310.16 (Al Column)Use Aluminum ampacity array and K=21.2 for VD calc.

Complete ESP32 Arduino Code

This sketch targets the ESP32-WROOM-32 DevKit V1. It requires the Adafruit_GFX and Adafruit_SH110X libraries installed via the Arduino Library Manager. The code includes I2C initialization error handling: if the OLED fails to handshake, it falls back to Serial output so you aren't debugging blind.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>

// --- PIN DEFINITIONS ---
#define SDA_PIN 21
#define SCL_PIN 22
#define BTN_UP 25
#define BTN_DOWN 26
#define BTN_SEL 27

// --- DISPLAY SETUP ---
Adafruit_SH1106G display = Adafruit_SH1106G(128, 64, &Wire, -1);
bool oled_ok = false;

// --- NEC DATA ARRAYS (Copper, 75C Column) ---
// Index 0 = 14 AWG, Index 1 = 12 AWG ... Index 6 = 1 AWG
const int awg_sizes[] = {14, 12, 10, 8, 6, 4, 2, 1};
const int ampacity_75c[] = {20, 25, 35, 50, 65, 85, 115, 130}; // Raw 75C table values
const int circular_mils[] = {4110, 6530, 10380, 16510, 26240, 41740, 66360, 83690};
const int num_awg = 8;

// --- STATE VARIABLES ---
int load_amps = 15;
int distance_ft = 50;
int voltage = 120;
int selected_awg = 0;

void setup() {
  Serial.begin(115200);
  pinMode(BTN_UP, INPUT_PULLUP);
  pinMode(BTN_DOWN, INPUT_PULLUP);
  pinMode(BTN_SEL, INPUT_PULLUP);

  Wire.begin(SDA_PIN, SCL_PIN);
  
  if(!display.begin(0x3C, true)) {
    Serial.println("ERROR: SH1106 I2C Handshake Failed. Check SDA/SCL.");
    oled_ok = false;
  } else {
    oled_ok = true;
    display.clearDisplay();
    display.setTextColor(SH110X_WHITE);
    display.setTextSize(1);
    display.println("NEC Wire Sizer");
    display.println("Initializing...");
    display.display();
  }
  delay(1000);
}

void loop() {
  handleInputs();
  calculateAndDisplay();
  delay(50); // Debounce
}

void handleInputs() {
  if (digitalRead(BTN_UP) == LOW) {
    load_amps += 5;
    if (load_amps > 200) load_amps = 200;
    while(digitalRead(BTN_UP) == LOW) delay(10);
  }
  if (digitalRead(BTN_DOWN) == LOW) {
    load_amps -= 5;
    if (load_amps < 1) load_amps = 1;
    while(digitalRead(BTN_DOWN) == LOW) delay(10);
  }
  if (digitalRead(BTN_SEL) == LOW) {
    distance_ft += 10;
    if (distance_ft > 500) distance_ft = 10;
    while(digitalRead(BTN_SEL) == LOW) delay(10);
  }
}

int calculateAWG(int amps, int dist, int volts) {
  int start_idx = 0;
  
  // NEC 240.4(D) Small Conductor Overrides for Copper
  if (amps <= 15) start_idx = 0;      // 14 AWG
  else if (amps <= 20) start_idx = 1; // 12 AWG
  else if (amps <= 30) start_idx = 2; // 10 AWG
  else {
    // Find base thermal ampacity from 75C column
    for (int i = 3; i < num_awg; i++) {
      if (ampacity_75c[i] >= amps) {
        start_idx = i;
        break;
      }
      if (i == num_awg - 1) start_idx = num_awg - 1; // Max out
    }
  }

  // Voltage Drop Check: VD = (2 * K * I * L) / CM
  // K for Copper = 12.9
  float K = 12.9;
  float max_vd = volts * 0.03; // 3% limit
  
  for (int i = start_idx; i < num_awg; i++) {
    float vd = (2.0 * K * amps * dist) / circular_mils[i];
    if (vd <= max_vd) {
      return awg_sizes[i];
    }
  }
  return awg_sizes[num_awg - 1]; // Return largest available if still failing
}

void calculateAndDisplay() {
  int final_awg = calculateAWG(load_amps, distance_ft, voltage);
  
  if (oled_ok) {
    display.clearDisplay();
    display.setCursor(0,0);
    display.setTextSize(1);
    display.println("=== NEC WIRE SIZER ===");
    display.print("Load: "); display.print(load_amps); display.println("A");
    display.print("Dist: "); display.print(distance_ft); display.println("ft");
    display.print("Volt: "); display.print(voltage); display.println("V");
    display.setTextSize(2);
    display.print("USE: "); display.print(final_awg); display.println(" AWG");
    display.display();
  }
  
  // Always print to Serial for debugging
  Serial.printf("Load: %dA | Dist: %dft | Result: %d AWG\n", load_amps, distance_ft, final_awg);
}

Debugging: I2C Faults and Guru Meditation Errors

When bridging embedded C++ with electrical hardware, things go wrong. If your build fails, do not guess. Follow this diagnostic path.

Exact Error String: Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.

Ranked Causes:

  1. I2C Buffer Overflow / Null Pointer: The display.begin() failed, returning false, but the code attempted to call display.clearDisplay() without checking the oled_ok boolean flag. (The provided code prevents this, but custom modifications often break it).
  2. Pin Conflict: You assigned GPIO 21 or 22 to a button or another peripheral. On the ESP32-WROOM-32, these are hardwired to the primary I2C bus.
  3. Power Brownout: The SH1106 OLED draws up to 20mA. If powered from a weak USB port, the ESP32's brownout detector triggers a reset loop when the display initializes.

The First Three Things to Check When It Fails

  1. Verify I2C Pull-ups: The ESP32 enables internal pull-ups, but long I2C wires (over 12 inches) require external 4.7kΩ pull-up resistors on both SDA and SCL to 3.3V. Measure with a multimeter; you should read ~3.3V at the OLED pins when idle.
  2. Check SDA/SCL Swap: Many cheap OLEDs have mislabeled silkscreen. Swap the SDA and SCL wires at the breadboard. If the Serial monitor suddenly prints the AWG calculation, your display's silkscreen is lying to you.
  3. Measure VCC under Load: Put your multimeter on the OLED's VCC and GND pins. Press the reset button on the ESP32. If the voltage dips below 3.0V during the display.begin() handshake, your power supply is inadequate. Use a dedicated 5V 2A adapter.

Extending and Simplifying the Build

Depending on your workflow, you may want to strip this down or scale it up. Here is how to adapt the project without rewriting the core logic.

How to Simplify (Serial-Only CLI Tool)

If you don't want to wire an OLED and buttons, delete the Adafruit_SH110X includes and the handleInputs() function. Replace the loop with a Serial.parseInt() prompt. This turns the ESP32 into a headless USB dongle that you can plug into a laptop at the panel, querying wire sizes via the Arduino IDE Serial Monitor. It reduces the BOM cost to just the $5 ESP32 board.

How to Extend (Add Aluminum and 3-Phase)

To support aluminum feeders and 3-phase commercial calculations:

  • Add a Material Toggle: Wire a 4th button to GPIO 14. Create a parallel array ampacity_al_75c[] using the Aluminum column from NEC 310.16.
  • Update the VD Formula: For 3-phase, the voltage drop formula changes from 2 * K * I * L to 1.732 * K * I * L. Add a switch statement in the calculateAWG function to select the multiplier based on a new 'Phase' variable.
  • Apply 90°C Derating: If you are sizing for conduit fill derating (NEC 310.15(C)(1)), you must start your lookup in the 90°C column, apply the derating factor, and then verify the final ampacity against the 75°C termination limits. This requires a 2D array in C++ and a secondary validation loop.

By building this dedicated tool, you stop relying on memory and generic charts. You get a jobsite-ready device that enforces the exact National Electric Code wire sizing rules, ensuring your conductors are safe, compliant, and optimized for voltage drop.