Fault detection system(3 phase) of transmission system

#using-arduino i am working in 3 phase fault detection project.
code is compiling and upload successfully on Arduino but
during hardware implement it is not displaying anything except "detecting fault---"
either you create fault (like: phase to neutral) or No fault condition.
(It does not run the main loop of code)
please help me to resolve this issue

#include <SoftwareSerial.h>
#include <ArduinoJson.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
SoftwareSerial nodemcu(9, 10);
int mVperAmp = 100;
float I1 = 0.00;
float I2 = 0.00;
float I3 = 0.00;
int FT = 1;
int MAP = 0;
double pickup_current = 0.55;
double fault_current = 0;
double Voltage1 = 0;
double Voltage2 = 0;
double Voltage3 = 0;
double Voltage4 = 0;
double VRMS1 = 0;
double VRMS2 = 0;
double VRMS3 = 0;
double VRMS4 = 0;
double AmpsRMS1 = 0;
double AmpsRMS2 = 0;
double AmpsRMS3 = 0;
double AmpsRMS4 = 0;
void setup() {
  pinMode(7, OUTPUT);
  pinMode(6, INPUT);
  lcd.begin(16, 2);
  Serial.begin(9600);
  Serial.begin(9600);
  nodemcu.begin(115200);
  delay(1000);
  Serial.println("Program started");
  lcd.print("  TRANSMISSION ");
  lcd.setCursor(0, 1);
  lcd.print("      LINE     ");
  delay(800);
  lcd.clear();
  lcd.print("FAULT DECTECTION");
  lcd.setCursor(0, 1);
  lcd.print("     SYSTEM");
  delay(800);
}

void loop() {
  Voltage1 = getVPP1();
  VRMS1 = (Voltage1 / 2.0) * 0.707;
  AmpsRMS1 = (VRMS1 * 1000) / mVperAmp;
  Serial.print(AmpsRMS1);
  Serial.println(" Neutral RMS");
  Voltage2 = getVPP2();
  VRMS2 = (Voltage2 / 2.0) * 0.707;
  AmpsRMS2 = (VRMS2 * 1000) / mVperAmp;
  Serial.print(AmpsRMS2);
  Serial.println(" Red RMS");
  Voltage3 = getVPP3();
  VRMS3 = (Voltage3 / 2.0) * 0.707;
  AmpsRMS3 = (VRMS3 * 1000) / mVperAmp;
  AmpsRMS3 = (AmpsRMS3 + (AmpsRMS3 * (0.40)));
  Serial.print(AmpsRMS3);
  Serial.println(" Green RMS");
  Voltage4 = getVPP4();
  VRMS4 = (Voltage4 / 2.0) * 0.707;
  AmpsRMS4 = (VRMS4 * 1000) / mVperAmp;
  Serial.print(AmpsRMS4);
  Serial.println(" Blue RMS");
  if (((AmpsRMS2 > pickup_current) && (AmpsRMS1 >= 0.37)) || ((AmpsRMS3 > pickup_current) && (AmpsRMS1 >= 0.37)) || ((AmpsRMS4 > pickup_current) && (AmpsRMS1 >= 0.37)) || ((AmpsRMS2 > pickup_current) && (AmpsRMS3 > pickup_current)) || ((AmpsRMS3 > pickup_current) && (AmpsRMS4 > pickup_current)) || ((AmpsRMS4 > pickup_current) && (AmpsRMS2 > pickup_current))) {
    lcd.clear();
    digitalWrite(7, HIGH);
    while (digitalRead(6) == LOW) {
      Serial.print(AmpsRMS1);
      Serial.println(" Neutral RMS");
      Serial.print(AmpsRMS2);
      Serial.println(" RED RMS");
      Serial.print(AmpsRMS3);
      Serial.println(" GREEN RMS");
      Serial.print(AmpsRMS4);
      Serial.println(" BLUE RMS");
      lcd.clear();
      if ((AmpsRMS2 > pickup_current) && (AmpsRMS3 > pickup_current) && (AmpsRMS4 > pickup_current) && (AmpsRMS1 < 0.40)) {
        tone(13, 1000);
        lcd.print("Three Phase");
        lcd.setCursor(0, 1);
        lcd.print("fault");
        FT = 2;
      } else if ((AmpsRMS2 > pickup_current) || (AmpsRMS3 > pickup_current) || (AmpsRMS4 > pickup_current)) {
        if ((AmpsRMS2 > pickup_current) && (AmpsRMS3 > pickup_current) || (AmpsRMS3 > pickup_current) && (AmpsRMS4 > pickup_current) || (AmpsRMS4 > pickup_current) && (AmpsRMS2 > pickup_current)) {
          tone(13, 1000);
          if (AmpsRMS1 >= 0.38) {
            lcd.clear();
            lcd.print("Double line to");
            lcd.setCursor(0, 1);
            lcd.print("Ground fault");
            FT = 3;
          } else {
            lcd.print("line to line");
            lcd.setCursor(0, 1);
            lcd.print("fault");
            FT = 4;
          }
        } else {
          tone(13, 1000);
          lcd.print("Single line to");
          lcd.setCursor(0, 1);
          lcd.print("Ground fault");
          FT = 5;
        }
      }
      delay(1000);
      lcd.clear();

      if ((AmpsRMS2 > pickup_current) && (AmpsRMS1 >= 0.37)) {
        fault_current = AmpsRMS2;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("RED");
        lcd.setCursor(0, 1);
        lcd.print("GROUND");
      }
      if ((AmpsRMS3 > pickup_current) && (AmpsRMS1 >= 0.37)) {
        fault_current = AmpsRMS3;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("GREEN");
        lcd.setCursor(0, 1);
        lcd.print("GROUND");
      }
      if ((AmpsRMS4 > pickup_current) && (AmpsRMS1 >= 0.37)) {
        fault_current = AmpsRMS4;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("BLUE");
        lcd.setCursor(0, 1);
        lcd.print("GROUND");
      }
      if ((AmpsRMS2 > pickup_current) && (AmpsRMS3 > pickup_current)) {
        fault_current = AmpsRMS3;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("RED");
        lcd.setCursor(0, 1);
        lcd.print("GREEN");

      } else if ((AmpsRMS3 > pickup_current) && (AmpsRMS4 > pickup_current)) {
        fault_current = AmpsRMS3;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("GREEN");
        lcd.setCursor(0, 1);
        lcd.print("BLUE");

      } else if ((AmpsRMS4 > pickup_current) && (AmpsRMS2 > pickup_current)) {
        fault_current = AmpsRMS2;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("BLUE");
        lcd.setCursor(0, 1);
        lcd.print("RED");
      }

      if (fault_current >= 1.10) {
        MAP = 2;
        lcd.setCursor(8, 0);
        lcd.print("2 KM");
        lcd.setCursor(8, 1);
        lcd.print("2 KM");
        if ((AmpsRMS2 > pickup_current) && (AmpsRMS3 > pickup_current) && (AmpsRMS4 > pickup_current)) {
          delay(1500);
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("BLUE");
          lcd.setCursor(8, 0);
          lcd.print("2 KM");
        }
      }
      if ((fault_current >= 0.83) && (fault_current < 1.10)) {
        MAP = 4;
        lcd.setCursor(8, 0);
        lcd.print("4 KM");
        lcd.setCursor(8, 1);
        lcd.print("4 KM");
        if ((AmpsRMS2 > pickup_current) && (AmpsRMS3 > pickup_current) && (AmpsRMS4 > pickup_current)) {
          delay(1500);
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("BLUE");
          lcd.setCursor(8, 0);
          lcd.print("4 KM");
        }
      }
      if ((fault_current >= 0.72) && (fault_current < 0.83)) {
        MAP = 6;
        lcd.setCursor(8, 0);
        lcd.print("6 KM");
        lcd.setCursor(8, 1);
        lcd.print("6 KM");
        if ((AmpsRMS2 > pickup_current) && (AmpsRMS3 > pickup_current) && (AmpsRMS4 > pickup_current)) {
          delay(1500);
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("BLUE");
          lcd.setCursor(8, 0);
          lcd.print("6 KM");
        }
      }
      if ((fault_current >= pickup_current) && (fault_current < 0.72)) {
        MAP = 8;
        lcd.setCursor(8, 0);
        lcd.print("8 KM");
        lcd.setCursor(8, 1);
        lcd.print("8 KM");
        if ((AmpsRMS2 > pickup_current) && (AmpsRMS3 > pickup_current) && (AmpsRMS4 > pickup_current)) {
          delay(1500);
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("BLUE");
          lcd.setCursor(8, 0);
          lcd.print("8 KM");
        }
      }
      delay(1000);
    }
  } else {
    digitalWrite(7, LOW);
    noTone(13);
    lcd.clear();
    lcd.print("    NO FAULT    ");
    FT = 1;
  }
}
void sendStatus() {
  StaticJsonBuffer<1000> jsonBuffer;
  JsonObject& data = jsonBuffer.createObject();
  I1 = AmpsRMS1;
  I2 = AmpsRMS2;
  I3 = AmpsRMS3;
  data["FT"] = FT;
  data["MAP"] = MAP;
  data["I1"] = I1;
  data["I2"] = I2;
  data["I3"] = I3;
  data.printTo(nodemcu);
  jsonBuffer.clear();
}
float getVPP1() {
  lcd.clear();
  lcd.print("FAULT DETECTING");
  lcd.setCursor(0, 1);
  lcd.print("----------");
  float result1;
  int readValue1;        //value read from the sensor
  int maxValue1 = 0;     // store max value here
  int minValue1 = 1024;  // store min value here

  uint32_t start_time = millis();
  while ((millis() - start_time) < 1000)  //sample for 1 Sec
  {
    readValue1 = analogRead(A0);
    // see if you have a new maxValue
    if (readValue1 > maxValue1) {
      /*record the maximum sensor value*/
      maxValue1 = readValue1;
    }
    if (readValue1 < minValue1) {
      /*record the minimum sensor value*/
      minValue1 = readValue1;
    }
  }

  // Subtract min from max
  result1 = ((maxValue1 - minValue1) * 5.0) / 1024.0;

  return result1;
}
float getVPP2() {
  lcd.setCursor(0, 1);
  lcd.print("------------");
  float result2;
  int readValue2;        //value read from the sensor
  int maxValue2 = 0;     // store max value here
  int minValue2 = 1024;  // store min value here

  uint32_t start_time = millis();
  while ((millis() - start_time) < 1000)  //sample for 1 Sec
  {
    readValue2 = analogRead(A1);
    // see if you have a new maxValue
    if (readValue2 > maxValue2) {
      /*record the maximum sensor value*/
      maxValue2 = readValue2;
    }
    if (readValue2 < minValue2) {
      /*record the minimum sensor value*/
      minValue2 = readValue2;
    }
  }

  // Subtract min from max
  result2 = ((maxValue2 - minValue2) * 5.0) / 1024.0;

  return result2;
}

float getVPP3() {
  lcd.setCursor(0, 1);
  lcd.print("--------------");
  float result3;
  int readValue3;        //value read from the sensor
  int maxValue3 = 0;     // store max value here
  int minValue3 = 1024;  // store min value here

  uint32_t start_time = millis();
  while ((millis() - start_time) < 1000)  //sample for 1 Sec
  {
    readValue3 = analogRead(A2);
    // see if you have a new maxValue
    if (readValue3 > maxValue3) {
      /*record the maximum sensor value*/
      maxValue3 = readValue3;
    }
    if (readValue3 < minValue3) {
      /*record the minimum sensor value*/
      minValue3 = readValue3;
    }
  }

  // Subtract min from max
  result3 = ((maxValue3 - minValue3) * 5.0) / 1024.0;

  return result3;
}
float getVPP4() {
  lcd.setCursor(0, 1);
  lcd.print("----------------");
  float result4;
  int readValue4;        //value read from the sensor
  int maxValue4 = 0;     // store max value here
  int minValue4 = 1024;  // store min value here

  uint32_t start_time = millis();
  while ((millis() - start_time) < 1000)  //sample for 1 Sec
  {
    readValue4 = analogRead(A3);
    // see if you have a new maxValue
    if (readValue4 > maxValue4) {
      /*record the maximum sensor value*/
      maxValue4 = readValue4;
    }
    if (readValue4 < minValue4) {
      /*record the minimum sensor value*/
      minValue4 = readValue4;
    }
  }

  // Subtract min from max
  result4 = ((maxValue4 - minValue4) * 5.0) / 1024.0;

  return result4;
}

1 Like

Hello shusil

All below mentioned calls of the delay() function will block the desired and needed realtime behaiviour of a fault detection system.

Line  33:   delay(1000);
	Line  38:   delay(800);
	Line  43:   delay(800);
	Line 110:       delay(1000);
	Line 169:           delay(1500);
	Line 184:           delay(1500);
	Line 199:           delay(1500);
	Line 214:           delay(1500);
	Line 222:       delay(1000);

Additional I have checked the code a little.
This sketch seems to have grown organically through nested and dupilcate function calls.
This leads to spaghetti code and nodes in the logic that are functionally undesirable.

What to do.
There are two options.
Debug, using multiple Serial.println()'s to see what happens under different conditions. Nodes can be solved this way, but new ones can also be created in the process.
The second option is to rearrange the sketch. Based on the IPO model, structure the desired function of the sketch into basic functions. Take a sheet of paper and a pencil and draw a programme structure to identify the required functions, e.g. button, timer and display functions. All these functions can be coded and tested separately. To complete the project, you also need to design a control structure that uses events to call the above functions. In this way keep in mind to design objects and related services thus handle input/output actions.
That is all that needs to be done. Try them out.

Have a nice day and enjoy coding in C++.

@paulpaulson
Thank you for you reply
But i am new to coding ..
Help me out .. what to do..?
I have tested this code stimulation software (proteus 8) is was running perfectly so i implemented it on hardware..

Do you have experience with programming in C++?

The task can easily be realised with an object.
A structured array contains all information, such as pin addresses for the I/O devices, as well as the information for the timing.
A single service takes care of this information and initiates the intended action.
The structured array makes the sketch scalable until all I/O pins are used up without having to adapt the code for the service.
It is cool stuff, isn´t it?

Assuming you meant "FAULT DETECTING", not "detecting fault--", and taking you literally, I offer the loop() function above and ask if that print statement fails to operate.

Or does it flood the serial monitor with that line it prints?

a7

@paulpaulson no i don't having coding experience.
I belong to EEE branch
I get code from youtuber ..

Just for fun while I wait for my beach buddy to text she's rolling towards me, I showed ChatGPT one of your four functions which all seemed to do the same thing and asked it to

Please rewrite the function. Remove the appended digits on the variable names, and introduce an argument that tells the function which analog pin to read.

The below plausible (untested) result was issued. BTW ChatGPT had produced a nice and accurate analysis of your original function.

float getVPP(int pin) {

  lcd.clear();
  lcd.print("FAULT DETECTING");
  lcd.setCursor(0, 1);
  lcd.print("----------");

  float result;
  int readValue;        //value read from the sensor
  int maxValue = 0;     // store max value here
  int minValue = 1024;  // store min value here

  uint32_t start_time = millis();
  while ((millis() - start_time) < 1000)  //sample for 1 Sec
  {
    readValue = analogRead(pin);
    // see if you have a new maxValue
    if (readValue > maxValue) {
      /*record the maximum sensor value*/
      maxValue = readValue;
    }
    if (readValue < minValue) {
      /*record the minimum sensor value*/
      minValue = readValue;
    }
  }

  // Subtract min from max
  result = ((maxValue - minValue) * 5.0) / 1024.0;

  return result;
}

Now if there are remain real differences between the four functions, you can handle them inside the one function that works for all the measuring.

a7

@alto777 Thanks for your concern..

can you give give more details regarding the application?
what equipment are you monitoring?
what voltage? current ?
upload a schematic showing the wiring?
could you monitor the current? e.g. using a clamp?

@horace

As per circut diagram..
3 phase is step down to 12 v
Then it is connected in series with acs712 current sensor for current measurement..
4 channel relay module to trip circuit during fault
During any fault..
Here aurdino is program to detect any line(R,Y,B) vs ground fault
Line to line fault .
(But i am excluding nodemcu and gps code for online monitoring code)
Each 2km is assumed to having 10ohms resistance..
It will display fault km distance..

So you are measuring the 12 volt current instead of the original 3-phase mains current. What does this tell you? Are you looking for faults in the Arduino/relay circuit?

The circuit with those transformers make no sense at all - you seem to be just shorting out the secondaries - unless the diagram is wrong ?
I’m not sure about your method of working out “voltages” by seeking the peak values and how that compares with a fault condition .
Power transmission lines are not just resistive , you need to look at protection systems . Distance protection usually models the lines impedance , so if voltage and currents match that then there is no fault in the line , the fault is elsewhere - protected by some other device.

The proposed is already covered using proprietory equipment which is certified for use on mains/mains equipment.
Things like phase failure/under/over voltage .....circuit breakers and rcbo's.......on and on....pretty much off-the-shelf gear I might add.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.