In the previous article, we have seen how we can make an analog voltage stabilizer. We have seen that the circuit was pretty complex like a bird’s nest. In this article, we are going to learn how we can use a micro-controller for that purpose and make a smart voltage stabilizer for our own. Let’s start!
Disclaimer:
Handling electricity carries inherent risks. It’s essential to have the appropriate skills to manage it safely. Proceed at your own risk, as the author disclaims responsibility for any misuse, harm, or errors. All content on this website is unique and copyrighted; please avoid unauthorized copying. While most articles are open-source for your benefit, feel free to use the knowledge provided. If you find our resources helpful, consider purchasing available materials to support our work.
For assistance or guidance, leave a comment below; the author is committed to helping. Some articles may contain affiliate links that support the author with a commission at no additional cost to you. Thank you for your understanding and support.
If you have not read the previous article, I’m requesting you to read the previous article first. Then continue this article.
Table of Contents
What is the benefit of using a micro-controller?
Most people have a fear of using a micro-controller for any work. But it is not like that. Until you learn about something, it is fear. But once you learned it, you’ll become a master of that. Anyway, there is no need to use different circuits for different works when you are using a micro-controller. It already has many blocks inside. You just need to code to use those.
One of the most significant benefits of using a micro-controller is you get the freedom to design the circuit. If you write the code properly, you can get lots of flexibility in circuit designing.
Circuit diagram:
Explanation:
The circuit is very simple and using ULN2003A rather than a set of devices as relay driver with transistor, diode, resistors made the circuit cleaner. Each driver section of ULN2003A is configured with darling tone transistors, resistors, and diodes. The ULN2003A driver IC has common and GND pin from those the GND pin is not shown in the diagram. But it is available in real IC. The pin must be connected to GND.
Each driver has necessary components so no need to use any extra components. It makes it easier to use with micro-controllers. In comparison to the cost, it is also economic rather than using separate transistors and other component sets.
The relay switching part:
The relay switching part is not complex at all too.
Here RL1:RL4 are used to select different taps and the RL5 is used to switch the input to inject the mains to the selected tap. Here as the input line is not connected to the transformer tap in the first. So there is no power in the auxiliary winding at the beginning. That is why it can not start the control circuit.
To solve this problem, an X2 type capacitor is used between the input line and the lowest tap (150V here). This will energize the control circuit. Once the control circuit is turned on and relays are switched, the control circuit can be run from the auxiliary power.
Sensing:
It may seem strange to use resistors directly. But it is the best way to sense the mains voltage using a resistor for voltage stabilizer. This way the line voltage sensing is not interrupted for any relay switching or other part of the circuit.
Also as the control circuit is completely away from the user’s touch so it is not a problem to use resistors. The configuration works like a simple voltage divider circuit. To tune, a POT can be used with a 1K resistor in series to fine-tune the measurement.
A simple 100nF capacitor is enough to filter the signal. The rest of the work will be done in coding.
Note: here the 1MΩ resistors are used of 0.5W. You should use the 5band metalflim one like this one:
There is no more part to explain I think. So let’s do the coding.
Coding:
/******************************************************************************* Program for, "Micro-controller based 5 relay voltage stabilizer" Program Written by_ Engr. Mithun K. Das; mithun060@gmail.com MCU:PIC16F676; X-Tal: 4MHz (internal); Complier: mikroC pro for PIC v7.6.0 Date: 19-04-2021 *******************************************************************************/ #define relay1 RC1_bit #define relay2 RC2_bit #define relay3 RC3_bit #define relay4 RC4_bit #define relay5 RC5_bit #define delay_led RA2_bit #define high_led RA1_bit #define low_led RA0_bit unsigned int line_voltage=0,max_point=0,temp=0; int i=0,k=0; void main() { TRISA=0x00;//all output TRISC=0x01;//all out except RC0_bit ANSEL = 0b00010000;//AN4 active CMCON=0x07;//comparator off ADCON1=0x10;//Fosc/8 speed while(1) { //read input voltage line_voltage = 0; max_point=0; temp=0; ADCON0 = 0x11; //AN4 for(i=0;i<5;i++) { for(k=0;k<500;k++) { if(temp=ADC_Read(4),temp>max_point) { max_point = temp; Delay_us(1); } } line_voltage+=max_point*37/100; } line_voltage/=5; //get average value }//while(1) }//void main()
This is the first step of our coding. Here, I’ve done very simple works. First I defined the pins according to the functions.
#define relay1 RC1_bit #define relay2 RC2_bit #define relay3 RC3_bit #define relay4 RC4_bit #define relay5 RC5_bit #define delay_led RA2_bit #define high_led RA1_bit #define low_led RA0_bit
Then in the initialization section:
TRISA=0x00;//all output TRISC=0x01;//all out except RC0_bit ANSEL = 0b00010000;//AN4 active CMCON=0x07;//comparator off ADCON1=0x10;//Fosc/8 speed
Each line is commented so that it becomes easy to understand the code. Now we’ll measure the voltage I mean the AC voltage from our voltage divider circuit. It may become a little complex to understand. I’ll request to read one of my previous article where I explained about AC voltage measurement.
//read input voltage line_voltage = 0; max_point=0; temp=0; ADCON0 = 0x11; //AN4 for(i=0;i<5;i++) { for(k=0;k<500;k++) { if(temp=ADC_Read(4),temp>max_point) { max_point = temp; Delay_us(1); } } line_voltage+=max_point*37/100; } line_voltage/=5; //get average value
Here a peak point finder algorithm is used and taking the peak point data only. Then making an average value from 5 data. More the raw value, more the accuracy. The 37/100 is coming from our ADC calculation.
Here the voltage divider is actually forming like this with respect to our MCU GND pin:
You may think why I’m not putting all the values in the coding and let the MCU calculate the value. Let’s see what happens if I do that.
Calculation in coding:
If I keep the calculation as it is:
Read more:
- Connect to Raspberry Pi from your Laptop/Desktop using VNC Viewer
- How to reduce noise from DC motor
- Interfacing External EEPROM with PIC microcontroller
- Not Enough ROM/RAM error with micro-controllers
- Read ThingSpeak Channel using ESP8266 and Arduino
- Caller ID detection using Arduino
- Simple voltage protector for your appliances
- DC/DC converter using Transistors
- Simple Component Detector using PIC16F877A
- Voltage Stabilizer Circuit with 4 Relays
- 6V Lead-Acid battery charger circuit
- 5 coolest multimeters you can buy
- Top 5 bench power supplies you can buy
- Top 5 handheld oscilloscopes you can try
- Top 5 Digital Multimeters for beginners
- Digital Clock with DS3231 & PIC microcontroller
- Digital Clock with PIC16F676 & Seven Segment Display
- Digital Clock using a PIC microcontroller & RTC DS1307
- How to remove noise/garbage from the HD44780 LCD display
- How to design a voltage stabilizer using a micro-controller from A to Z
- PICKit2 colon Simplified
- Capacitor Power Supply parts calculator
- Solar Charge Controller circuit & working principle of ON/OFF charge controller
- A smart Battery charger circuit design guide
It consumes 81% of ROM and 31% of RAM. But if I simplify it to even: 0.37 then:
Still, 79% is consumed. But If it is simplified in another step:
Result for changes:
WOW!!! It takes only 26%. This is how we can actually use less ROM & RAM and do more coding with a micro-controller. Even we can tune in some steps more to get optimum results.
Now, one very important issue we have to handle. Did you notice we are using a POT of 10KΩ and a 1KΩ resistor in series with our voltage divider? Those are actually in parallel with our 27K resistor. Also, each of these resistors has some tolerance. As a result, we will never get a calculated result from this type of measurement.
That is why we must calibrate the measurement code by testing with line voltage and practical circuit which can be finalized once it is ready for testing. Anyway, I hope it is now clear to you about the voltage reading.
Note: Here we measured a peak point result. But we know that we use the RMS value not the peak value. So we must calculate the RMS value from the peak value. The calculation is easy,
VP = VRMS × √2
Now let’s add more parts of the code but before that, we have to calculate the input vs output voltage relation for transformer taps. I mean in which input voltage which the tap will be selected?
If you check the transformer again:
What do you see? The tap difference is 30V. And the transformer calculation is:
So we can calculate the relation and set when to change the transformer tap. We can use Microsoft Excel for this calculation which will make our job easy.
Input & output voltage chart:
And the equations is:
Here, the yellow marked points are important for us. As you see, when the input voltage is 170V and the in tap is 150 the output voltage is 238, at the same time if we use the in tap 180V then the output is 198V. In this situation, if we switch the relay sharply, the output voltage will be fluctuating from 198V to 238V which is very dangerous for the load. So what’s the solution?
Solution:
In this situation, we have to create a hysteresis in the code. So let’s complete the code.
/******************************************************************************* Program for, "Micro-controller based 5 relay voltage stabilizer" Program Written by_ Engr. Mithun K. Das; mithun060@gmail.com MCU:PIC16F676; X-Tal: 4MHz (internal); Complier: mikroC pro for PIC v7.6.0 Date: 19-04-2021 *******************************************************************************/ #define relay1 RC1_bit #define relay2 RC2_bit #define relay3 RC3_bit #define relay4 RC4_bit #define relay5 RC5_bit #define delay_led RA2_bit #define high_led RA1_bit #define low_led RA0_bit unsigned int line_voltage=0,max_point=0,temp=0; int i=0,k=0; bit gap1,gap2,gap3,gap4,gap5; void main() { TRISA=0x00;//all output TRISC=0x01;//all out except RC0_bit ANSEL = 0b00010000;//AN4 active CMCON=0x07;//comparator off ADCON1=0x10;//Fosc/8 speed top: PORTA = 0x00;//clear port PORTC = 0x00;//clear port delay_led = 1; Delay_ms(180000);//3min delay = 180000; delay_led = 0; while(1) { //read input voltage line_voltage = 0; max_point=0; temp=0; ADCON0 = 0x11; //AN4 for(i=0;i<5;i++) { for(k=0;k<500;k++) { if(temp=ADC_Read(4),temp>max_point) { max_point = temp; Delay_us(1); } } line_voltage+=max_point*37/10; } line_voltage/=5; //get average value if(line_voltage<145 || line_voltage>305) { relay5 = 0; if(line_voltage<145)low_led = 1; else if(line_voltage>305)high_led = 1; Delay_ms(10000);//wait 10sec goto top; } else { if(line_voltage>145 && line_voltage<170) { relay1 = 0;// 150V Tap connected relay2 = 0; relay3 = 0; relay4 = 0; relay5 = 1;//injection on gap1 = 1; gap2 = 0; } else if(line_voltage>=170 && line_voltage<=172) { if(gap1) { relay1 = 0;// 150V Tap connected relay2 = 0; relay3 = 0; relay4 = 0; relay5 = 1;//injection on } if(gap2) { relay1 = 1;// 180V Tap connected relay2 = 0; relay3 = 0; relay4 = 0; relay5 = 1;//injection on } } else if(line_voltage>172 && line_voltage<204) { relay1 = 1;// 180V Tap connected relay2 = 0; relay3 = 0; relay4 = 0; relay5 = 1;//injection on gap2 = 1; gap1 = 0; gap3 = 0; } else if(line_voltage>=204 && line_voltage<=206) { if(gap2) { relay1 = 1;// 180V Tap connected relay2 = 0; relay3 = 0; relay4 = 0; relay5 = 1;//injection on } if(gap3) { relay1 = 0; relay2 = 1;// 210V Tap connected relay3 = 0; relay4 = 0; relay5 = 1;//injection on } } else if(line_voltage>206 && line_voltage<238) { relay1 = 0; relay2 = 1;// 210V Tap connected relay3 = 0; relay4 = 0; relay5 = 1;//injection on gap3 = 1; gap4 = 0; gap2 = 0; } else if(line_voltage>=238 && line_voltage<=240) { if(gap3) { relay1 = 0; relay2 = 1;// 210V Tap connected relay3 = 0; relay4 = 0; relay5 = 1;//injection on } if(gap4) { relay1 = 0; relay2 = 0; relay3 = 1;// 240V Tap connected relay4 = 0; relay5 = 1;//injection on } } else if(line_voltage>240 && line_voltage<270) { relay1 = 0; relay2 = 0; relay3 = 1;// 240V Tap connected relay4 = 0; relay5 = 1;//injection on gap3 = 0; gap4 = 1; gap2 = 0; } else if(line_voltage>=270 && line_voltage<=272) { if(gap4) { relay1 = 0; relay2 = 0; relay3 = 1;// 240V Tap connected relay4 = 0; relay5 = 1;//injection on } if(gap5) { relay1 = 0; relay2 = 0; relay3 = 0; relay4 = 1;//270V Tap connected relay5 = 1;//injection on } } else if(line_voltage>272 && line_voltage<305) { relay1 = 0; relay2 = 0; relay3 = 0; relay4 = 1;// 270V Tap connected relay5 = 1;//injection on gap4 = 0; gap5 = 1; } } }//while(1) }//void main()
So this is our full code. As you see, I’ve changed some calculations. While I was simulating, I found that I’ve to multiply by 10 when reading the line voltage. Once you make ready the hardware, you have to calibrate this constant value (37/10) to match with your reading. You can build your hex file using mikroC Pro for PIC compiler. Alternatively, you can get my generated hex file from here.
In the relay control section, you can see I’m using a bit variable gap1~gap5. These are actually used to create a hysteresis I mentioned earlier. This step must be written carefully.
OK, now we can check if our code works in simulation:
Simulation result:
I’ve simulated this project in proteus. I hope you’ll make it in real life and show me the result.
PCB design:
I’ve designed the PCB in a single layer. Simple layout for this product. You can draw yourself using my layout:
Conclusion:
I’ve described almost all the basics to make a micro-controller-based voltage stabilizer. Now it’s your turn to utilize this knowledge to develop your own voltage stabilizer or related product or project. I hope you enjoyed this article.
I’m professional in designing professional products. If you need any help feel free to contact me. E-mail: mithun060@gmail.com. Thanks.
If this article is helpful to you kindly subscribe to my YouTube channel and here as well. Also share on Facebook, Twitter, and other social media. Thanks.
For Professional Designs or Help:
Check this out: Voltage Stabilizer Circuit with 4 Relays
48 Comments
Joy · 19/04/2021 at 2:28 pm
Sir you are great.I salute you .It is impossible to compare you with any other Bangladeshi programmer.
MKDas · 20/04/2021 at 5:38 am
Thanks.
Asimiyu · 20/04/2021 at 8:59 am
wao! this is what i have been looking for, you are a very great man engr Mithun. How i wish i have money to donate to your company, because any person who value KNOWLEDGE would know the great things you have been doing. Honestly speaking, I am always extremely happy when come to your blog, every hours, i can’t spent a day without visiting here. you have really impacted knowledge to human kinds and may God Almighty Allah will continue increasing you in Knowledge, wisdom, prosperity and uplift you more higher in this life and the hereafter.
However, all project circuits you have been posted here, are working, with crystal cleared!, theories, practical and its computation analyzes.
i will still go through it sir if there is questions.
MKDas · 20/04/2021 at 9:04 am
Thank you.
Inayat · 30/09/2021 at 3:06 pm
If we use this pcb for 50 volt to 220 volt what can be do?
Ur 1st tapping is 150 and I want my 1st loop is 50 volt
MKDas · 30/09/2021 at 3:17 pm
Try to understand the concept of the circuit. Once you understand it, you can make any changes you need.
ROBERT · 23/04/2021 at 9:33 pm
Hello sir, this is a great work, i appreciate ur effort by given out this educative project that may help many in programming experience. I am one of the benefactor this work.
thans for sharing ur ideas to all. Keep the good work going.
MKDas · 24/04/2021 at 5:03 am
Thanks.
Mohamed · 06/05/2021 at 7:08 am
great, but i need circuit to make constant voltage 220v ac however the input change using automatic voltage stabilizer
MKDas · 06/05/2021 at 11:29 am
In that case you can look for Static Voltage Stabilizer.
Flex · 08/05/2021 at 3:43 am
Nice explanations can you do a project on ac current measurement using opamp and current sensor preferably using the type of current sensor one can easily purchase or make thank you
MKDas · 08/05/2021 at 7:39 am
Thanks.
Chandana · 11/05/2021 at 8:15 am
Does ADC input safe from the negative half of the AC signal? I cannot understand can you kindly explain?
MKDas · 11/05/2021 at 9:24 am
Yes no problem. ADC is internally protected.
Chandana · 11/05/2021 at 10:49 am
Many thanks for the reply.
Thank you so much for excellent projects and clear explanations
MKDas · 11/05/2021 at 10:52 am
You are welcome.
RKHam · 14/05/2021 at 3:19 am
Mr. MKDas,
Can you please explain the connection between sampling rate and the AC wave form.
As per my understanding, 20ms takes for a cycle when AC frequency is 50Hz.
I am trying to understand following code
for(k=0;kmax_point)
{
max_point = temp;
Delay_us(1);
}
}
RKHam · 14/05/2021 at 3:22 am
Sorry I missed some parts of the code in my question above
for(k=0;kmax_point)
{
max_point = temp;
Delay_us(1);
}
}
MKDas · 16/05/2021 at 12:39 pm
You missed again. read again please.
MKDas · 16/05/2021 at 12:38 pm
First you made a mistake to read the code. Check again. It is simply a peak point finding algorithm. I’ve explained this in my other articles. You should read that before this one.
Monir · 02/08/2021 at 8:38 pm
Bought the PCB file. Waiting for the print arrives. Then I’ll get the hex file.
MKDas · 02/08/2021 at 9:07 pm
OK.
Selvakumar · 05/09/2021 at 7:57 am
Hello sir I am doing audio related circuit I need microcontroller for display input volt, output volt, brand name, and master, bass, treble, values in lcd display can u help me
MKDas · 06/09/2021 at 12:19 pm
There are some other articles on voltmeters. Kindly read those. It will be helpful I think.
Elektronik Experts · 14/03/2022 at 8:33 pm
Hello MKDas, I can help you for product development on paid basis, send email me back.
MKDas · 15/03/2022 at 1:25 pm
You can send your requirements to labprojectsbd@gmail.com
md . sumon · 18/09/2021 at 1:10 pm
hi im sumon your project is very nice but ..not 100 parcent ! you not use display lcd or seven seg
i want display sys volatage stab c code pls help….
MKDas · 18/09/2021 at 3:30 pm
This is an educative project that helps people making their own. If someone’s requirement is different then it’s not the project’s fault not to be his/her 100%. Read the article, try to understand the mechanism. Read similar articles that uses LCD then combine them into one.
Harish popat · 19/09/2021 at 5:08 pm
For 3 relay 5 step with 30 sec dela
Send contact no
MKDas · 19/09/2021 at 7:41 pm
Did not understand.
ezekiel iyamu · 28/11/2021 at 12:08 pm
I tried this code on both mplab and the mikroc which you recommended but it shows more than 20 different undeclared identifiers…. is something missing here
Lab Projects BD · 28/11/2021 at 1:36 pm
Code is written in MikroC. Try with the latest version.
Md Ariful Islam · 19/06/2022 at 8:33 pm
Osadharon vai..ey code ami kaj korty parchi…
Dario · 17/08/2022 at 5:20 am
The code has many errors, it is a pity that it is not right, I would like you to upload a new post that is more explained, especially in programming.
MKDas · 17/08/2022 at 11:06 am
What error you are having? The code is 100% working and perfect.
Dario · 18/08/2022 at 6:16 am
Excuse me but what is happening to me with the code is that when I copy it in mikroc it does not generate the Hexadecimal file I do not know why that happens, before copying it checks all the mikroc libraries, but it does not copy properly, I would like you to help me With that, thank you very much.
MKDas · 18/08/2022 at 11:58 am
That is the problem with your copy or mikroC. Not code.
Zira · 01/06/2023 at 11:17 pm
Is a great project but when I want to simulate is not working the pic16f676 is not responding
MKDas · 02/06/2023 at 12:13 pm
check the learning tutorials to learn about the settings. Then you can find yourself.
Yuri · 07/12/2022 at 4:27 am
Undeclared identifier ‘ADC_Read’ in expression
error when using Build function to complie
MKDas · 07/12/2022 at 11:54 am
tick mark library , right side.
JatinderBir Singh Chawla · 21/04/2023 at 9:02 pm
Nice , i will surely try this
Md. Moniruzzaman · 30/06/2023 at 7:38 pm
Dear brother,
At first spacial thanks for your help full post, I have read your post ,it is almost good but I have a question, when all relay is stop that time control voltage provide by capacitor, as your discretion , but I think it will generate malfunctioning because 210 voltage tape directly connected to load, if load circuit current flowing that time maximum voltage will be dropped in capacitor 105, 400v. How to solved it ??
MKDas · 02/07/2023 at 7:21 pm
Design is well tested, it will not malfunction if your starting capacitor is good one.
mehranal · 03/10/2023 at 4:47 pm
I programmed your ready code on pic16f676, but it doesn’t work at all, I completed the circuit according to your specifications, but it doesn’t show any reaction, where is the problem?
MKDas · 10/10/2023 at 8:37 pm
fix your crystal settings first then MCLR then try again.
mehanal · 11/10/2023 at 11:54 am
How do I set mclr for Micro 676? There is no specific reference, please help
MKDas · 11/10/2023 at 3:51 pm
There is a tutorial series with PIC MCU. kindly read those step by step. then you can understand this easily. Once you understand this, you’ll get it for lifetime. But if I say it here, you’ll forget that after some time. Thanks