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.
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.
/*
* 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");
}
}
}