In this project, we will learn how to identify faults in a single-phase line, and additionally, we will send the fault notification to a mobile number as a SMS. In this project, we will use the PIC16F73 microcontroller and SIM module as GSM modules. We’ll also know why we need single-phase fault protection and how we can do this. So let’s start Single Phase fault analysis with GSM.
⚠️ Disclaimer ⚠️
Working with electricity involves serious risk. Ensure you have the necessary skills and take proper safety precautions before attempting any electrical projects. Proceed at your own risk — the author assumes no responsibility for any damage, injury, or issues resulting from the use or misuse of the information provided.
All content on this website is original and protected by copyright. Please do not copy or reproduce content without permission. While most of the resources shared here are open-source and freely accessible for your learning and benefit, your respect for our intellectual effort is appreciated.
If you find our tutorials helpful, consider supporting us by purchasing related materials or sharing our work — it helps keep the content flowing.
Need help or have questions? Leave a comment below — the author is always happy to assist!
Table of Contents
Faults in single phase line:
The main fault in a single-phase line is line voltage. Either the line voltage goes too high or too low is not suitable for our home appliances. Most of us have a power line rated 220V but in some countries, it may be different. Whatever it is, too high or too low voltage is not good for appliances. Also, spikes in the power line are not acceptable. A single spike may damage our appliance. That is why we must pay attention to line voltage to provide protection.

Another protection we can keep is high current protection. Most of the houses have circuit breakers and fuses. These two devices can give short circuit protection. Besides, we can add high current protection. When a load or a set of loads is taking extra current than its rated current, we can trip that load for a while. If this same case happens, again and again, we can trip permanently.
Voltage and Current Sensing:
Voltage sensing:
To sense line voltage and current, we need some kind of device which can convert or transform the ratio. Most of the control circuits work around the 5V range. So if we want to sense some kind of parameters, we have to convert that parameter into a voltage range of 5V. Here in our project, we need to sense the line voltage and load current. As the line voltage is 220V AC, we can not sense this range directly with our sensing device (here PIC16F73 micro-controller). So we will use a transformer, formally known as the potential transformer.

A simple transformer with a ratio of 220:12 can be used as our potential transformer. Then this transformer will convert the 220V into 12V range. And one more step will make it suitable for our micro-controller.
Current Sensing:
Similarly to sense current we need another type of transformer called Current Transformer (CT) which converts high rated current into the small rated current.
To know more about the current transformer please check this.

As we can not sense any current rather than voltage, so we need to convert the secondary small current into voltage bypassing that current through a burden resistor.

The calculation is very simple, V=IR. Using this simple equation, we can easily find the line current.
You can check these current transformers (CTs) at amazon.com :
PIC16F73 micro-controller:
PIC16F73 is a very common 8bit microcontroller with a 28pin package with 22 I/O. 6 channel 8bit ADC (AN0-AN5) makes it easy to sense voltages. A general feature can be found in this image:

Each MCU has various special features. We need to use whatever we need for a purpose. Here in this project, we need an ADC feature for sensing voltage and current. We will also need another feature later which we’ll discuss later on.
Analog to Digital Converter:
Analog to Digital Converter is a kind of converter which converts the analog voltage into digital data. You can find more about ADC here. PIC16F73’s ADC features are found here.


Here we have some kind of registers to command the ADC for a specific process. This will be discussed later.
This far we have seen the sensing techniques. After taking the input readings we can process our data and make a decision on what to do next.
Load Control Device:
To turn the load on/off keeping the control device isolated we can use Relays.
Inside mechanism of a relay A commercial relay
Relay can provide isolated switching and is easy to use too. So for our project, we’ll use the relay as the electromechanical switch.
Communicating (GSM) Device:
Another part of our project is to notify the fault condition via SMS. For this purpose, we will use a GSM module. Any GSM module can be used, here we used SIM300 based GSM module. You can use any GSM module.
Here are some GSM modules that you can collect from amazon.com.
GSM module works through UART communication protocol. And supports ‘AT’ commands. You can read SIM300 AT command set here and SIM800L AT Command set here. Both modules have similar AT command set to communicate with them. The simple communication technique between micro-controller and GSM module is:

The communication(UART) works at multiple baud rates but in most cases, the default baud rate is 9600. So you can set your baud rate at 9600. Another key point is, the SIM module has a lower logic level (3.3V). On the other hand, MCU has a logic level of 5V. This may create a problem with the GSM module’s Rx pin. That is why you will need to use a voltage divider like this:
When the MCU transmitting at a 5V logic level, this voltage divider will lower the voltage to a 3.3V level. As we are not receiving any SMS from the GSM module in this project so we do not need to use the Tx pin of the GSM module. But if we need to use it, we can use this connection directly. Because MCU can accept logic levels from 2.5V. Anyway, for this project, we will not need any further connections so don’t worry.
Block Diagram:
Here is our project block diagram. The main input line (AC220V) which we will monitor with a CT and PT then will be switched via relay to load. The micro-controller gets the reading of current and voltage from CT and PT correspondingly and decides when to turn the relay on/off with the help of a relay driver. The information is displayed on LCD which is a common 16X2 LCD display. A GSM module is here for sending SMS. And finally, we need a power supply to power the devices up. For the microcontroller we need 5V but for the relay, we need 12V.
Circuit diagram:
Here is the complete circuit diagram of our project Single-phase Fault Analysis.
Here you can see different components including transformers, LCD, micro-controller, and other associated devices.
Connection summery:
As mentioned earlier to sense line voltage and load current we’ll need two transformers named PT and CT. Starting from the source, we have TR1 as a power transformer which is providing 12V AC and after that, a bridge diode and a capacitor(C1) is making it unregulated DC12V. This 12V(UG) is supplied to the relay and the voltage regulator IC(U3) LM7805CV. A capacitor C2 is added just after the voltage regulator to make it more smooth. The regulated 5V DC supply is supplied to the micro-controller(PIC16F73) and LCD display. The GSM module is supplied separately in this project.
Sensing:
Now, PT (220:12) is connected parallel to the supply, and CT and relay(RL1) are connected in series with the line and the load(L1) via a switch. [Note: In practice, we’ve to use several lamps and switches]. Diode D1 and capacitor C3 are connected with the relay coil which is driven by a transistor Q2(BC547) which is our relay driver in this project. D1 is used to remove the back emf generated by the relay coil and the capacitor C3 stabilizes the coil’s magnetic flux.
After PT, diode D2 rectifies the voltage, and resistor R3 is used as a shunt resistor to eliminate noise and helps flowing minimum current through the diode D2. Then this voltage is divided with the help of the R5 and R6 voltage divider resistor. A ceramic capacitor C4 is used here to remove noise. This voltage is then supplied to RA0(AN0) of the micro-controller.
R4 is working as the burden resistor of our CT which is converting the current into voltage from CT secondary winding. This voltage is then supplied to RA1(AN1) of the micro-controller.
Using the ADC module of MCU line voltage and current are then calculated.
Other parts:
The Display (LCD) needs 4 data pins and 2 control pins to work properly which are connected to the MCU (RB0 to RB5). A resistor (usually 2.7K) needs to use in real hardware in between VEE and GND to set the LCD contrast.
GSM module(U2) is connected in a common GND line and the Tx pin of MCU is connected to the Rx pin of the GSM module through two resistors ( logic level reducer) R8 and R9. The Tx pin is the pin of the UART module of our micro-controller.
And finally, we will add a buzzer as an audio alarming system which is driven with the help of a transistor Q1. Both of the transistors (Q2 and Q1) are biased through 10K resistors.
The Vpp/MCLR pin of the microcontroller is connected to a 5V supply ( through a 10K resistor in hardware). An 8MHz crystal is used in real hardware which is not shown in the circuit diagram.
Flow chart:
mikroC Code:
/******************************************************************************* * Program for, "1Ph fault analysis and senging sms through GSM" * * Program Written by_ Engr. Mithun K. Das * * MCU:PIC16F73B; X-Tal: 8MHz * * Date:27-08-2016 * *******************************************************************************/ // LCD module connections sbit LCD_RS at RB5_bit; sbit LCD_EN at RB4_bit; sbit LCD_D4 at RB3_bit; sbit LCD_D5 at RB2_bit; sbit LCD_D6 at RB1_bit; sbit LCD_D7 at RB0_bit; sbit LCD_RS_Direction at TRISB5_bit; sbit LCD_EN_Direction at TRISB4_bit; sbit LCD_D4_Direction at TRISB3_bit; sbit LCD_D5_Direction at TRISB2_bit; sbit LCD_D6_Direction at TRISB1_bit; sbit LCD_D7_Direction at TRISB0_bit; // End LCD module connections void Lcd_COut(char row, char col, const char *cptr) { char chr = 0; //first, it is used as empty string Lcd_Out(row, col, &chr); //nothing to write but set position. for ( ; chr = *cptr ; ++cptr ) Lcd_Chr_CP(chr); //out in loop } void UART_Write_CText(const char *cptr) { char chr; for ( ; chr = *cptr ; ++cptr ) UART1_Write(chr); } unsigned int voltage=0,current=0; char volt[]="V:000V "; void Get_Voltage(void) { unsigned int temp0=0; unsigned int maxpoint0=0; unsigned int k=0; ADCON0 = 0b00000001;// AN0 selected for(k=0;k<1000;k++) { if(temp0 = ADC_Read(0),temp0>maxpoint0) { maxpoint0 = temp0; } } maxpoint0 = abs(ceil(maxpoint0)); voltage = maxpoint0*3.477;// (5/255)*11.00*0.707*220/9*cal_factor; volt[2] = (voltage/100) +48; volt[3] = (voltage/10)%10 +48; volt[4] = voltage%10 +48; Lcd_Out(1,1, volt); Delay_ms(20); maxpoint0 = 0; } char curr[]="I:0.00A"; void Get_Current(void) { //char message4[] = "0.000A"; unsigned int temp1=0; unsigned int maxpoint1=0; int kk=0; ADCON0 = 0b00000101;// AN1 selected for(kk=0;kk<3000;kk++) { if(temp1 = ADC_Read(1),temp1>maxpoint1) { maxpoint1 = temp1; } } current = maxpoint1*0.340;// get the load current curr[2] = current/100+48; curr[3] = '.'; curr[4] = (current/10)%10 +48; curr[5] = (current/1)%10 +48; Lcd_Out(1,9,curr); Delay_ms(20); maxpoint1 = 0; } void Send_SMS_Int(void) { UART1_Write_Text("AT\r\n"); Delay_ms(200); UART1_Write_Text("AT+cmgf=1\r\n"); Delay_ms(200); UART1_Write_Text("AT+cmgs="); UART1_Write((char)'"'); UART1_Write_Text("xxxxxxx"); //add your mobile number here UART1_Write((char)'"'); UART1_Write((char)13); UART1_Write((char)10); Delay_ms(2000); } #define Relay RC4_bit #define Buzzer RC5_bit unsigned int cnt_ol=0,trip_cnt=0; bit permanent_trip,sms_cnt; void main() { TRISA = 0xFF;//all input TRISC = 0x00;//all output ADCON1 = 0x00;//all analog in Relay = 0; Buzzer = 1; Lcd_Init();//int LCD Lcd_Cmd(_LCD_CLEAR); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_COut(1,1,"1 Phase Fault"); Lcd_COut(2,1,"Analysis, GSM"); UART1_Init(9600); Delay_ms(50); Buzzer = 0; Delay_ms(2000); Lcd_Cmd(_LCD_CLEAR); UART_Write_CText("AT\r\n");Delay_ms(100); UART_Write_CText("AT\r\n");Delay_ms(100); UART_Write_CText("AT\r\n");Delay_ms(100);//send AT command permanent_trip=0; sms_cnt=1; while(1) { OERR_bit = 0;// clear Overrun Error bit FERR_bit = 0;//clear Farming Error bit UART_Write_CText("AT\r\n"); if(permanent_trip==0) { Get_Voltage(void); Get_Current(void); if(voltage>180 && voltage<240)// voltage is in between { if(current<75)//not overloaded { Relay = 1; Lcd_COut(2,1,"Normal Condition"); Delay_ms(50); sms_cnt = 1;//reset mask } else { cnt_ol++; if(cnt_ol>5) { Relay = 0;//trip trip_cnt++; cnt_ol = 0;//clear cnt Lcd_COut(2,1,"Tripped,Overload"); Buzzer = 1; Delay_ms(2000); Lcd_Cmd(_LCD_CLEAR); Buzzer = 0; Lcd_COut(1,1,"Sending SMS_"); Send_SMS_Int(void); UART_Write_CText("System is Tripped due to overload."); Delay_ms(300); UART1_Write((char)26); Delay_ms(300); Lcd_COut(2,1,"SMS Sent_"); Delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); cnt_ol = 0; } } } else { Relay = 0; if(voltage<=180)Lcd_COut(2,1,"Low Voltage"); if(voltage>=240)Lcd_COut(2,1,"High Voltage"); Delay_ms(1000); trip_cnt++; Lcd_COut(2,1,"Tripped, V_Error"); Buzzer = 1; Delay_ms(2000); Buzzer = 0; Lcd_Cmd(_LCD_CLEAR); Lcd_COut(1,1,"Sending SMS_"); Send_SMS_Int(void); UART_Write_CText("System is Tripped due to Voltage error."); Delay_ms(300); UART1_Write((char)26); Delay_ms(300); Lcd_COut(2,1,"SMS Sent_"); Delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); } } else { Lcd_Cmd(_LCD_CLEAR); Lcd_COut(1,1,"Permanently"); Lcd_COut(2,1,"Tripped"); Delay_ms(3000); if(sms_cnt) { Lcd_Cmd(_LCD_CLEAR); Lcd_COut(1,1,"Sending SMS_"); Send_SMS_Int(void); Buzzer = 1; UART_Write_CText("System is Permanently Tripped."); Delay_ms(300); UART1_Write((char)26); Delay_ms(300); sms_cnt = 0; Lcd_COut(2,1,"SMS Sent_"); Delay_ms(1000); Buzzer = 0; Lcd_Cmd(_LCD_CLEAR); } } if(trip_cnt>5) { permanent_trip = 1; } else { permanent_trip = 0; } }//while(1) }//void main
Download the mikroC project file from here.
Code Explanation:
Code is easy and written in a simple way so that you can understand easily.
// LCD module connections sbit LCD_RS at RB5_bit; sbit LCD_EN at RB4_bit; sbit LCD_D4 at RB3_bit; sbit LCD_D5 at RB2_bit; sbit LCD_D6 at RB1_bit; sbit LCD_D7 at RB0_bit; sbit LCD_RS_Direction at TRISB5_bit; sbit LCD_EN_Direction at TRISB4_bit; sbit LCD_D4_Direction at TRISB3_bit; sbit LCD_D5_Direction at TRISB2_bit; sbit LCD_D6_Direction at TRISB1_bit; sbit LCD_D7_Direction at TRISB0_bit; // End LCD module connections
This part of the code is to set up the LCD connection with the micro-controller. The rest of the process is done by the mikroC LCD library.
void Lcd_COut(char row, char col, const char *cptr) { char chr = 0; //first, it is used as empty string Lcd_Out(row, col, &chr); //nothing to write but set position. for ( ; chr = *cptr ; ++cptr ) Lcd_Chr_CP(chr); //out in loop }
This sub-function is used to reduce RAM consumption for LCD functions. This way we can add more texts in the LCD function.
void UART_Write_CText(const char *cptr) { char chr; for ( ; chr = *cptr ; ++cptr ) UART1_Write(chr); }
This part is also reducing RAM consumption when using the UART function. It also helps to add more texts in the UART function.
unsigned int voltage=0,current=0; char volt[]="V:000V "; void Get_Voltage(void) { unsigned int temp0=0; unsigned int maxpoint0=0; unsigned int k=0; ADCON0 = 0b00000001;// AN0 selected for(k=0;k<1000;k++) { if(temp0 = ADC_Read(0),temp0>maxpoint0) { maxpoint0 = temp0; } } maxpoint0 = abs(ceil(maxpoint0)); voltage = maxpoint0*3.477;// (5/255)*11.00*0.707*220/9*cal_factor; volt[2] = (voltage/100) +48; volt[3] = (voltage/10)%10 +48; volt[4] = voltage%10 +48; Lcd_Out(1,1, volt); Delay_ms(20); maxpoint0 = 0; }
In this sub-function, we are calculating the line voltage. As we are taking a reading of the AC signal directly so we need to find the peak point of each pulse. We are taking 1000 samples and comparing if it is higher than the previous one. Once we find the previous one is greater or equal to the recent one, then that previous one will be the peak reading.

You can read the AC voltage measurement technique to know more about this.
From that peak reading, we can easily calculate the line voltage by taking the RMS voltage equation in our calculation.
In this sub-function, we are displaying the reading on our LCD. As LCD works in ASCII so we have to convert the decimal value into ASCII value.
char curr[]="I:0.00A"; void Get_Current(void) { //char message4[] = "0.000A"; unsigned int temp1=0; unsigned int maxpoint1=0; int kk=0; ADCON0 = 0b00000101;// AN1 selected for(kk=0;kk<3000;kk++) { if(temp1 = ADC_Read(1),temp1>maxpoint1) { maxpoint1 = temp1; } } current = maxpoint1*0.340;// get the load current curr[2] = current/100+48; curr[3] = '.'; curr[4] = (current/10)%10 +48; curr[5] = (current/1)%10 +48; Lcd_Out(1,9,curr); Delay_ms(20); maxpoint1 = 0; }
In this sun function, we are calculating the load current. This one is using a similar technique to the voltage reading.
void Send_SMS_Int(void) { UART1_Write_Text("AT\r\n"); Delay_ms(200); UART1_Write_Text("AT+cmgf=1\r\n"); Delay_ms(200); UART1_Write_Text("AT+cmgs="); UART1_Write((char)'"'); UART1_Write_Text("xxxxxxx"); //add your mobile number here UART1_Write((char)'"'); UART1_Write((char)13); UART1_Write((char)10); Delay_ms(2000); }
In this part, we have kept a sub-function to send SMS. It initializes the GSM module to send a text as SMS to the given number. Whenever we need to send an SMS, we can call this function then print our text and send the end command.
#define Relay RC4_bit #define Buzzer RC5_bit unsigned int cnt_ol=0,trip_cnt=0; bit permanent_trip,sms_cnt;
This is for simple pin declaration and some variable declaration.
TRISA = 0xFF;//all input TRISC = 0x00;//all output ADCON1 = 0x00;//all analog in Relay = 0; Buzzer = 1; Lcd_Init();//int LCD Lcd_Cmd(_LCD_CLEAR); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_COut(1,1,"1 Phase Fault"); Lcd_COut(2,1,"Analysis, GSM"); UART1_Init(9600); Delay_ms(50); Buzzer = 0; Delay_ms(2000); Lcd_Cmd(_LCD_CLEAR); UART_Write_CText("AT\r\n");Delay_ms(100); UART_Write_CText("AT\r\n");Delay_ms(100); UART_Write_CText("AT\r\n");Delay_ms(100);//send AT command permanent_trip=0; sms_cnt=1;
This is for initialization of input/outputs, ADC settings, LCD initialization, UART initialization, etc. Here we named our project on LCD and sent 3 ‘AT’ commands to our GSM module to establish UART communication.
OERR_bit = 0;// clear Overrun Error bit FERR_bit = 0;//clear Farming Error bit UART_Write_CText("AT\r\n");
OERR and FERR are cleared and the ‘AT’ command is sent periodically to maintain UART communication between the MCU and GSM module.
if(permanent_trip==0) { Get_Voltage(void); Get_Current(void); if(voltage>180 && voltage<240)// voltage is in between { if(current<75)//not overloaded { Relay = 1; Lcd_COut(2,1,"Normal Condition"); Delay_ms(50); sms_cnt = 1;//reset mask } else { cnt_ol++; if(cnt_ol>5) { Relay = 0;//trip trip_cnt++; cnt_ol = 0;//clear cnt Lcd_COut(2,1,"Tripped,Overload"); Buzzer = 1; Delay_ms(2000); Lcd_Cmd(_LCD_CLEAR); Buzzer = 0; Lcd_COut(1,1,"Sending SMS_"); Send_SMS_Int(void); UART_Write_CText("System is Tripped due to overload."); Delay_ms(300); UART1_Write((char)26); Delay_ms(300); Lcd_COut(2,1,"SMS Sent_"); Delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); cnt_ol = 0; } } } else { Relay = 0; if(voltage<=180)Lcd_COut(2,1,"Low Voltage"); if(voltage>=240)Lcd_COut(2,1,"High Voltage"); Delay_ms(1000); trip_cnt++; Lcd_COut(2,1,"Tripped, V_Error"); Buzzer = 1; Delay_ms(2000); Buzzer = 0; Lcd_Cmd(_LCD_CLEAR); Lcd_COut(1,1,"Sending SMS_"); Send_SMS_Int(void); UART_Write_CText("System is Tripped due to Voltage error."); Delay_ms(300); UART1_Write((char)26); Delay_ms(300); Lcd_COut(2,1,"SMS Sent_"); Delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); } } else { Lcd_Cmd(_LCD_CLEAR); Lcd_COut(1,1,"Permanently"); Lcd_COut(2,1,"Tripped"); Delay_ms(3000); if(sms_cnt) { Lcd_Cmd(_LCD_CLEAR); Lcd_COut(1,1,"Sending SMS_"); Send_SMS_Int(void); Buzzer = 1; UART_Write_CText("System is Permanently Tripped."); Delay_ms(300); UART1_Write((char)26); Delay_ms(300); sms_cnt = 0; Lcd_COut(2,1,"SMS Sent_"); Delay_ms(1000); Buzzer = 0; Lcd_Cmd(_LCD_CLEAR); } } if(trip_cnt>5) { permanent_trip = 1; } else { permanent_trip = 0; }
And in this part inside the while(1) loop we are checking if the permanent _trip is over or not. If it is over then the system is tripped permanently and if not the system will check line voltage and current periodically.
Here we used a voltage range of 180 to 240 which is normal for a 220V line for common appliances. For sophisticated appliances, you can narrow this range down as per your wish.
And the current range is 75 is considering 0.75A of current. Over that value system will trip as overload. You can set it as per your requirement.
PCB Design:

As this is an educational project so PCB is designed in that manner. For commercial use, this system will be designed in a commercial way.
Thanks for reading this article. I hope this will help you in your project. For more helpful projects, don’t forget to subscribe. Thanks.
Liked this article? Subscribe to our newsletter:
or,
Visit LabProjectsBD.com for more inspiring projects and tutorials.
Thank you!
Check this out: 5 coolest multimeters you can buTop 5 Digital Multimeters for beginners
3 Comments
enrique · 12/09/2020 at 3:41 pm
Excellent all your work, I am a faithful follower from Colombia, thank you very much for sharing your knowledge, I wish you many successes, I look forward to your next work
FANYOREAL · 18/04/2021 at 9:39 am
PERFECT work, I am a faithful follower from Nigeria, thank you very much for sharing your knowledge, I wish you many successes, I look forward to your next work
MKDas · 18/04/2021 at 10:11 am
It’s my pleasure. Thanks.