⚠️☠️ HIGH VOLTAGE WARNING – EDUCATIONAL USE ONLY ☠️⚠️

This project involves measurement of voltages up to ±250 V (500 V peak-to-peak) using a 100:1 high-voltage divider.

⚡ These voltage levels are lethal.

Only trained and competent persons familiar with electrical safety, insulation, creepage/clearance, and high-voltage hazards should work with such circuits.

This information is provided strictly for educational purposes.

Arduino UNO Voltage Measurement with 100:1 Divider

This example demonstrates how to measure AC and DC voltages using an Arduino UNO and a 100:1 voltage divider. The system supports:

With a 100:1 divider, the input range becomes ±250 V while keeping the Arduino within the safe 0–5 V ADC range.

Detailed Steps
Arduino Code ✅

/* 
* Arduino UNO with 100:1 Voltage Divider
* Measures AC/DC voltage, calculates peak, RMS, and frequency for AC signals.
* Updated for centerpoint = ADC 512 with signed voltage mapping.
*/

const int voltagePin = A0;      
const float voltageDividerRatio = 100.0;
const float VRef = 5.0;                   
const int maxADCValue = 1023;             
const int adcCenter = 512;
const float fullScaleVolts = 250.0;
const unsigned long interval = 500;

// AC tracking variables
unsigned long lastZeroCrossingTime = 0;
float sumSquaredVoltage = 0;
int sampleCount = 0;
bool polarity = false;
bool zcd = false;
unsigned long previousACmillis = 0;
int zcp = 512;

unsigned long previousMillis = 0;
float frequency = 0;

void setup() {
    Serial.begin(115200);
    Serial.println("Updated ADC Signed Voltage System (512 = 0V)");
}

void loop() {

    int adcValue = analogRead(voltagePin);

    int adcDelta = adcValue - adcCenter;  
    float normalized = float(adcDelta) / float(adcCenter);
    float inputVoltage = normalized * fullScaleVolts;

    unsigned long currentMillis = millis();
    unsigned long currentMicros = micros();

    if (polarity != (adcValue > zcp)) { 
        polarity = adcValue > zcp; 

        if (polarity) {
            zcp = adcCenter - 10; 
            previousACmillis = currentMillis;

            unsigned long period = currentMicros - lastZeroCrossingTime;
            lastZeroCrossingTime = currentMicros;

            if (period > 0) {
                frequency = 1000000.0 / period;
            } else {
                zcp = adcCenter + 10;
            }
            zcd = true;
        }
    }

    if ((currentMillis - previousACmillis) <= interval) {

        sumSquaredVoltage += inputVoltage * inputVoltage;
        sampleCount++;

        if (zcd && polarity) {
            if ((currentMillis - previousMillis) >= interval) {
                previousMillis = currentMillis;

                float rmsVoltage = sqrt(sumSquaredVoltage / sampleCount);
                Serial.print(" RMS Voltage: ");
                Serial.print(rmsVoltage, 2);
                Serial.print(" V, Frequency: ");
                Serial.print(frequency, 2);
                Serial.println(" Hz");

                sumSquaredVoltage = 0;
                sampleCount = 0;
            }
        }
    } 
    else {
        if ((currentMillis - previousMillis) >= interval) {
            previousMillis = currentMillis;
            Serial.print(" DC Voltage: ");
            Serial.print(inputVoltage);
            Serial.println(" V");
        }
    }
}
How It Works