Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[HELP] PROTEUS 8 PROFESSIONAL: APFC

Status
Not open for further replies.

magicxrps

Newbie
Joined
Mar 29, 2023
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
32
Hi everyone,

I am simulating an automatic power factor correction system using Arduino Nano in Proteus 8 Professional. In this regard, why is it that the system shows "Simulation is not running in real time due to excessive CPU load"? Shown below is the circuit as well as the error message.

Circuit.png
Issue.png
 

The cpu (central processing unit, your computer)...
is bogged down by a multitude of calculations.

* Close non-essential programs while running Proteus.

* Simplify your own schematic to make it easier for the simulator to model. Right now it has a great many inductors, switches, relays. Can you prove your concept by using fewer components?

* Can you use a simpler model of the micro-controller? A simpler model of the display?

As you make progress toward proving your concept, then try to discover how to streamline the simulator's ability to run your schematic, and gradually restore components with the intent to achieve a workable project.
 

Bradtherad is right, simplify the circuit, consider making the resistors digital instead of analogue. Does it matter if the simulation is not running in real time?
 

Hello everyone.

I am simulating an automatic power factor correction system using Arduino Nano on Proteus 8 Professional. Upon simulating, the circuit measures something even though that there is no connected load yet. What I have noticed is that there is an error on my voltage comparator and zero-crossing detection portion of the system (composed of op-amps and an XOR gate). Shown below are the snippets of the whole circuit and the zoomed-in ZCD. Can anyone help me to figure this out?

Circuit.png
ZCD.png
 

Hard to guess without sufficient details. Do you have the source code, or only the binary compiled file ? In the first case, run the code in Debug mode and add break points at keyoints of the code - e.g before value being issued to the LCD.
 

Hard to guess without sufficient details. Do you have the source code, or only the binary compiled file ? In the first case, run the code in Debug mode and add break points at keyoints of the code - e.g before value being issued to the LCD.
Hi Sir, here is my Arduino code:

C++:
#include <math.h>
#include <LiquidCrystal.h>
float Power_Factor, load_voltage, load_current, real_power, angle_rad, total_capacitance, Q_reqd, New_PF, I_secondary;
float peak_voltage = 0;
float peak_current = 0;
int f = 60;
float vSensor = A0;
float iSensor = A1;
unsigned long time_diff;
const int XOR = 0;
const int capacitor_pin[] = {1, 2, 3, 4, 5, 6, 7};
const int RS = 13;
const int E = 12;
const int D4 = 11;
const int D5 = 10;
const int D6 = 9;
const int D7 = 8;
LiquidCrystal LCD(RS, E, D4, D5, D6, D7);
void setup() {
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  LCD.begin(20, 4);
  LCD.setCursor(0,0);
  LCD.print(F("AUTOMATIC"));
  delay(50);
  LCD.setCursor(0,1);
  LCD.print(F("POWER FACTOR"));
  delay(50);
  LCD.setCursor(0,2);
  LCD.print(F("CORRECTION"));
  delay(50);
  LCD.setCursor(0,3);
  LCD.print(F("SYSTEM"));
  unsigned long initialization_time = millis();
  while (millis() - initialization_time < 2000){
  }
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(0, INPUT);
  for (int i = 0; i < 7; i++) {
    pinMode(capacitor_pin[i], OUTPUT);
    digitalWrite(capacitor_pin[i], LOW);
  }
  time_diff = 0;
}
void CapacitorCombinations(int j) {
  static unsigned long CapComb_time = 0;
  if(millis() - CapComb_time >= 450){
    CapComb_time = millis();
    String base_2 = String(j, BIN);
    while (base_2.length() < 7) {
      base_2 = "0" + base_2;
    }
    for (int k = 0; k < 7; k++){
      if (base_2.charAt(k) == '1') {
        digitalWrite(capacitor_pin[k], HIGH);
      }   
      else {
      digitalWrite(capacitor_pin[k], LOW);
      }
    }
  }
}
void ComputePF() {
  static unsigned long PF_time = 0;
  if(millis() - PF_time >= 300){
    PF_time = millis();
    time_diff = pulseIn(XOR, HIGH);
    angle_rad = 2*PI*f*time_diff;
    Power_Factor = cos(angle_rad);
  }
}
float ReqdCapacitance(float PF, float V, float I) {
  static unsigned long ReqdCap_time = 0;
  if(millis() - ReqdCap_time >= 350){
    ReqdCap_time = millis();
    float C_reqd, X_c, P;
    C_reqd = 0;
    P = V*I*PF;
    Q_reqd = P*(tan(PF)-tan(0.96));
    X_c = (V*V)/Q_reqd;
    C_reqd = 1/(2*PI*f*X_c);
  return C_reqd;
  }
}
float CapacitorActivation(float Cap_Reqd) {
  static unsigned long ActivateCap_time = 0;
  if(millis() - ActivateCap_time >= 400){
    ActivateCap_time = millis();
    float capacitor_bank[7] = {1e-6, 2e-6, 4e-6, 8e-6, 16e-6, 32e-6, 64e-6};
    int cap_combination = 0;
    total_capacitance = 0;
    for (int l = 0; l < 128; l++){
      total_capacitance = 0;
      for (int m = 0; m < 7; m++){
        if (l & (1 << m)){
          total_capacitance += capacitor_bank[m];
        } 
      }
      if (total_capacitance >= Cap_Reqd){
        cap_combination = l;
        break;
      }
    }
    return cap_combination;
  }
}
float CorrectedPF(float PF, float V, float I) {
  static unsigned long CorrectedPF_time = 0;
  if(millis() - CorrectedPF_time >= 500){
    CorrectedPF_time = millis();
    float P, C_reactance, C_reactive_pow, L_reactive_pow, Q_new, theta_new;
    P = V*I*PF;
    C_reactance = 1/(2*PI*f*total_capacitance);
    C_reactive_pow = (V*V)/C_reactance;
    L_reactive_pow = (V*I)*sin(acos(PF));
    Q_new = L_reactive_pow - C_reactive_pow;
    theta_new = atan(Q_new/P);
    New_PF = cos(theta_new);
    return New_PF;
  }
}
void DisplayNoLoad()  {
  static unsigned long NoLoad_time = 0;
  if(millis() - NoLoad_time >= 100){
    NoLoad_time = millis();
    LCD.clear();
    LCD.setCursor(0,1);
    LCD.print(F("NO LOAD"));
    LCD.setCursor(0,2);
    LCD.print(F("CONNECTED"));
  }
}
void DisplayInitialParameters() {
  static unsigned long InitialParameters_time = 0;
  if(millis() - InitialParameters_time >= 300){
    InitialParameters_time = millis();
    LCD.clear();
    LCD.setCursor(0,0);
    LCD.print(F("PF: "));
    LCD.print(Power_Factor, 2);
    LCD.setCursor(0,1);
    LCD.print(F("VOLTAGE: "));
    LCD.print(load_voltage);
    LCD.print(F("V"));
    LCD.setCursor(0,2);
    LCD.print(F("CURRENT: "));
    LCD.print(load_current, 2);
    LCD.print(F("A"));
    LCD.setCursor(0,3);
    LCD.print(F("POWER: "));
    LCD.print(real_power);
    LCD.print(F("W"));
  }
}
void DisplayCorrectedPF() {
  static unsigned long FinalParameters_time = 0;
  if(millis() - FinalParameters_time >= 600){
    FinalParameters_time = millis();
    LCD.clear();
    LCD.setCursor(0,0);
    LCD.print(F("Required Qc: "));
    LCD.print(Q_reqd, 2);
    LCD.print(F("VAR"));
    LCD.setCursor(0,1);
    LCD.print(F("Required C: "));
    LCD.print(total_capacitance, 2);
    LCD.print(F("C"));
    LCD.setCursor(0,2);
    LCD.print(F("Corrected PF: "));
    LCD.print(New_PF, 2);
  }
}
void DisplayNoCorrectionNeeded()  {
  static unsigned long NoCorrection_time = 0;
  if(millis() - NoCorrection_time >= 700){
    NoCorrection_time = millis();
    LCD.clear();
    LCD.setCursor(0,0);
    LCD.print(F("PF: "));;
    LCD.print(Power_Factor, 2);
    LCD.setCursor(0,1);
    LCD.print(F("NO"));
    LCD.setCursor(0,2);
    LCD.print(F("CORRECTION"));
    LCD.setCursor(0,3);
    LCD.print(F("NEEDED"));
  } 
}
float ReadVoltage()  {
  static unsigned long peak_voltage_time = 0;
  if(millis() - peak_voltage_time >= 100){
    peak_voltage = analogRead(A0)*(5.0/1023.0);
    if(peak_voltage < 0 || peak_voltage > 5){
      return -1.0;
    }
    peak_voltage_time = millis();
    return peak_voltage;
  }
  return -1.0;
}
float ReadCurrent()  {
  static unsigned long peak_current_time = 0;
  if(millis() - peak_current_time >= 100){
    peak_current = analogRead(A1)*(5.0/1023.0);
    if(peak_current < 0 || peak_current > 5){
      return -1.0;
    }
    peak_current_time = millis();
    return peak_current;
  }
  return -1.0;
}
void ComputeLoadCurrent() {
  static unsigned long LoadCurrent_time = 0;
  if(millis() - LoadCurrent_time >= 200){
    LoadCurrent_time = millis();
    float Vrms_current, V_Rburden;
    if (peak_current > 0 || peak_current < 5){
      Vrms_current = peak_current/sqrt(2);
      V_Rburden = Vrms_current + 1.4;
      I_secondary = V_Rburden/5.0;
      load_current = I_secondary*(20/1);
    }
    else{
      return;
    }
  }
}
void ComputeLoadVoltage() {
  static unsigned long LoadVoltage_time = 0;
  if(millis() - LoadVoltage_time >= 200){
    LoadVoltage_time = millis();
    float Vrms_voltage, V_drop;
    if (peak_voltage > 0 || peak_voltage < 5){
      Vrms_voltage = peak_voltage/sqrt(2.0);
      V_drop = 1.4 + (I_secondary)*1000.0;
      load_voltage = (Vrms_voltage + V_drop)*(230.0/5.0);
    }
    else{
      return;
    }
  }
}
void ComputeRealPower() {
  static unsigned long RealPower_time = 0;
  if(millis() - RealPower_time >= 250){
    RealPower_time = millis();
    real_power = load_voltage*load_current*Power_Factor;
  }
}
void loop() {
  ReadCurrent();
  delay(500);
  ReadVoltage();
  delay(500);
  ComputeLoadCurrent();
  delay(500);
  ComputeLoadVoltage();
  delay(500);
  while(load_current <= 0.1){
    DisplayNoLoad();
    delay(500);
  }
  if(load_current > 0){
    ComputePF();
    delay(500);
    ComputeRealPower();
    delay(500);
    DisplayInitialParameters();
    delay(500);
    if (Power_Factor < 0.96){
      float Required_Capacitance = ReqdCapacitance(Power_Factor, load_voltage, load_current);
      delay(500);
      int Activate_Capacitor = CapacitorActivation(Required_Capacitance);
      delay(500);
      CapacitorCombinations(Activate_Capacitor);
      delay(500);
      CorrectedPF(Power_Factor, load_voltage, load_current);
      delay(500);
      DisplayCorrectedPF();
      delay(500);
    }
    else {
      DisplayNoCorrectionNeeded();
      delay(500);
    }
  }
}
 

Hard to guess without sufficient details. Do you have the source code, or only the binary compiled file ? In the first case, run the code in Debug mode and add break points at keyoints of the code - e.g before value being issued to the LCD.
Hi Sir, here is my Arduino code:

Are you expecting others to do this for you?
 

Hi,

Generally the shown solution has a lot of issues.
Hardware:
* current measurement via CT, burden, rectifier, C ... gives in now way a reliable value for RMS current
* using zero cross method also XOR also provides poor information on real mains current
* the comparators will see negative voltages up to -0.7 V which is beyond specified operation condition
* supplying a comparator with a 1k series resistor is no good idea, and missing a bypass capacitor makes it worse.
* there are more issues
Software:
* your method to measure voltage and current is not properly timed ... it just does a couple of samples
* measurement of "peak" values to get RMS information is the most error prone method.
* doing float operations on each incoming ADC value is not wrong, but just wastes processing power
* there are more issues.

If you are interested in good quality ... and by the same time reduced hardware effort:
* feed the V and I signals with 3 Rs and 2Cs to the ADC (one RC as high pass to enable DC offset, one RC as noise filter low pass, and a R for DC offset)
(Get rid of all the comparators, XOR, rectifiers, big capacitors...)
* Use a timing controlled ADConversion (interrupt) to get accurate and reliable informations of RMS current, RMS voltage, phase shift, power factor, true power .....
(I'm quite sure even the code becomes smaller)

There are a lot of discussions here in this forum ... and even more in the internet. All the information is freely available.

I can only recommend .... but it still is your decision.

Klaus
 

1.
Your op amps have single-ended power supply (positive polarity and 0V gnd). Is the LM358 model capable of rail-to-rail output voltage? Or does output stay 2V above supply rail?

Remember op amps should have bipolar supply in order for output to range down to 0V.

----------------------------------------------

2.
Your high voltage mains AC goes to a ground icon appearing identical to your low voltage DC circuitry. It's not necessarily an electrical error however it can lead the reader to wonder if there is a path for undesired current somewhere.
Your design is unconventional although the concept deserves a try, therefore it pays to make troubleshooting as easy as possible.
 

Hi,

I just realized that you "mistreat" OPAMPs as comparators. While this may work with a LM358 (I did not check all I/O parameters) this may cause trouble with other OPAMPs.
I recommend to use a comparator when you want a comparator function
(and use an OPAMP when you want an OPAMP function.)
There´s a good reason why they design OPAMPs and comparators differently.

Klaus
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top