# How to read AC voltage with arduino

Please let us in the comment zone any suggestions that you think will improve the article!

If you like the article click the follow button  to stay in touch with us!

### I’m not responsable for any accidents!

Now, besides reading ac voltage i will make an acoustic alarm (with a buzzer) if voltage drop bellow any specified value.

As you probably know, arduino can read maximum 5 Volts, so it’s not possible to read directly 230V and for this reason i’ve used a step down transformer from 220V to 12V.

After the transformer, i’ve use a rectifier bridge and a voltage divider, not with  filter (capacitor).

As i said before i want to make not only a reading also an alarm for a specified grid voltage so i need both ac half duty cycles (both positive after the bridge) and if i put a capacitor as a filter those half duty cycles will disappear.

If the voltage drop is small the capacitor will compensate this drop.

Anyway, for ac voltage, because we know that it is an ac voltage ( from the grid)  is necessary only the maximum value. For any other values we can use formulas.

• Average value=peak value x 0.637;
• Effective value(RMS)=peak value x 0.707;

In order to know the effective value (nominal 230V in the european grid) it  is necessary to know the peak value.

A schematically representasion for this project is presented in the image below: The waveforms obtained from the bridge rectifier and after the voltage divider are: The red signal is after the voltage divider(this signal is read by arduino) and the yellow one is after the bridge rectifier.

Because i’ve used a cheap transformer the waveforms are not sine waves as they should be.

From the couple of volts which arduino reads, the program must calculate the grid voltage, with the formula Vgrid=(max/0.230+1.4)*transformer ratio*0.707, where:

• max=the maximum value read by arduino
• 0.230=the voltage divider ratio (this value is made after reading the exact values of resistors R1=3288.4 and R2=983.6)
• 1.4=the voltage drop on two diodes for a half duty cycle on the recftifier bridge (data from the datasheet (i’ve used an old bridge from a pc power supply KBU6M))
• The component (max/0.230+1.4) represents the voltage before bridge, which means the voltage from the secondary of the transfomer.

Transformer ratio i’ve measured in function and i’ve obtained 241.2V on primary  and 13.48V on the secondary, which means a 17.89 ratio.

In the image below i’ve shown every voltage and next will be presented the program used with associated variables of these voltages: And the program is:

int x = 0; // value associated with voltage
float v=0; //voltage after voltage divider
float i=0; //comparison variable
float maxim=0; // maximum variable which is used for rms value
boolean OK=false;
float V=0; // voltage before voltage divider
float Vin=0;// voltage before bridge rectifier
float Vgrid=0; //grid voltage(rms value)
const float y=17.89; //transformer ratio

void setup() {
// initialize serial communications at 250000 bps:
Serial.begin(250000);
}

void loop() {
Serial.println(Vgrid);
if(v<i && OK==false){
maxim=i;// 3.88 represent 230V in the grid
OK=true;
}
else if (v<=0.1){// because not every time voltage drop to zero according to serial monitor
OK=false; //reset for next half duty cycle
}
i=v;
V=maxim/0.230;//0.230 come from the voltage divider resistors R1=3288.4 and R2=983.6
Vin=V+1.4; //adding the bridge rectifier voltage drop
Vgrid=Vin*y*0.707;//voltage grid-RMS value-obtain 230V-229V for a maxim=3.88
}                                   //230V-231V  measured with multimeter

### The alarm.

For setting the alarm we must know that every voltage drop (for example in grid faults are also drops in peak values):  The second image is simultated manually on a MCB (miniature circuit braker) with 50ms for each division (approx 150ms).

These faults can have a variate period so in the program you can choose the period to start the alarm when the peak voltage drops below a specified value (also chosen by the user).

The program for this is:

int x = 0; // value associated with voltage
float v=0; //voltage after voltage divider
float i=0; //comparison variable
float maxim=0; // maximum variable which is used for rms value
boolean OK=false;
boolean OK1=false;
boolean OK2=false;
unsigned long previousMillis=0;
const long interval=350;// voltage drop interval

void setup() {
// initialize serial communications at 250000 bps:
Serial.begin(250000);
pinMode(3, OUTPUT); //buzzer pin
}

void loop() {
Serial.println(maxim);
v=x*5.0/1023.0;// voltage after voltage divider
if(v<i && OK==false){
maxim=i; //for my project 3.88 volts for maxim correspond to 230V in the grid
OK=true; //230V-231V measured with multimeter
else if (v<=0.1){
OK=false;
}
i=v;
unsigned long currentMillis=millis();
if(OK2==false){
digitalWrite(3, HIGH); ///disable buzzer
}
if (maxim<3.60 && OK1== false){ // start counting
previousMillis=currentMillis; //3.60 limit for voltage drop
OK1=true; //3.60=213.4V in the grid obtain with rule of three
}
if (maxim>3.60 && currentMillis-previousMillis<interval){ //reset and wait if
//the voltage drop was
//smaller than period chosen by us
OK1=false;
}
if (maxim<3.60 && OK2==false && currentMillis-previousMillis>=interval){//enable buzzer if voltage
//drop was bigger than
//period chosen by us
OK2=true;
digitalWrite(3, LOW); //enable buzzer
}

}

Finally, i present you all the parts mounted on a PCB (with another bridge rectifier and a 7805 voltage regulator for an arduino pro mini, powered from the same transformer-the pcb file can’t be upload): 