Sketch to compare voltages for series parallel capacitor switching circuit

I am trying to create a simple program that will switch mosfets based on voltages read from A0 and A1, I have tried multiple times to get it to switch at the right points but there is something wrong, its switching too early, I think, im having trouble at the second half of the cycle where the capacitor needs to discharge to about half the supply voltage. I have tried several different ways with different approaches and i cant get it to work.
This is my code:

 int CHARGE1pin = 2;         // capacitor 1 in parallel
int CHARGE2pin = 3;         // capacitor 2 in parallel
int DISpin = 4;         // capacitors in series
int VCCPin = A0;   // Voltage sensor 'S'
int CAPpin = A1;   // Voltage sensor 'S'


int VCC = 0;
int CAPvolt = 0;


void setup () {
                          
 pinMode(CHARGE1pin, OUTPUT);                  // mosfet
 pinMode(CHARGE2pin, OUTPUT);                  // mosfet
 pinMode(DISpin, OUTPUT);                  // mosfet
}


void loop () {

  VCC = analogRead(VCCPin);  // read input voltage 
  CAPvolt = analogRead(CAPpin);  // read cap voltage
  int difference = VCC - CAPvolt;
if (difference > 10)
  {
    digitalWrite(DISpin,  LOW);  // discharge mosfet Off
  digitalWrite(CHARGE1pin, HIGH);  // charge mosfet ON
  digitalWrite(CHARGE2pin,  HIGH);  // charge mosfet ON
   }
  else {
  digitalWrite(CHARGE1pin, LOW);  // charge mosfet ON
  digitalWrite(CHARGE2pin,  LOW);  // charge mosfet ON
  digitalWrite(DISpin,  HIGH);  // discharge mosfet ON
  
  int diff = CAPvolt - VCC / 2;
  while (diff > 300)
 {
 delayMicroseconds(100);

 }
 
}
}

I want to switch on pins 2 and 3 until capvolt reaches supply voltage VCC, then turn off 2 and 3 and turn on the discharge mosfet until capvolt gets down to 1/2 VCC, and then start the charging cycle again, Im using a divider that is equal (and below 5v) for both input pins, the hardware part of the circuit is isolated via optocouplers and working fine.

forgot to include circuit diagram which might make this easier to understand, mosfet gates are driven by opto isolators powered by individual 9v batteries.

1 Like

diff does not change, so that either never happens or gets stuck.

You have to recalculate diff for basing while() on it.

Which also means getting the current values of the other variables set by analogRead().

Try coding it in the IPO model. Every loop, measure some stuff, decide what to do, and set the outputs accordianly.

No while statements, just if.

Oh, and welcome to the forum.

a7

I looked at ipo but i didn't understand what the code was doing at all.
I re wrote the code will this re calculate diff until the value is met?

void loop () {

  VCC = analogRead(VCCPin);  // read input voltage 
  CAPvolt = analogRead(CAPpin);  // read cap voltage
  int difference = VCC - CAPvolt;
if (difference > 10)
  {
    digitalWrite(DISpin,  LOW);  // discharge mosfet Off
  digitalWrite(CHARGE1pin, HIGH);  // charge mosfet ON
  digitalWrite(CHARGE2pin,  HIGH);  // charge mosfet ON
   }
  else {
  digitalWrite(CHARGE1pin, LOW);  // charge mosfet Off
  digitalWrite(CHARGE2pin,  LOW);  // charge mosfet Off
  digitalWrite(DISpin,  HIGH);  // discharge mosfet ON
  int diff = CAPvolt - VCC / 2;
  if (diff > 100)
 {
 VCC = analogRead(VCCPin);  // read input voltage 
  CAPvolt = analogRead(CAPpin);  // read cap voltage
 }

Thankyou

I'm looking through the tiny window here, I can look better later.

But I can say

Introduce a global variable to mean charging or not charging.

bool charging = false;

The your loop looks like (pseudo code)

// Input
...measure all the values from the system


// Process
if charging
    decide whether to stop charging based on latest readings you took
    if yes
        charging = false;

else (not charging)
    decide whether to start charging again based on the input
    if yes
        charging = true


// Output
...set outputs depending on if you are charging or not.

a7

I see, will read into it, im very bad at programming, everything takes me 10x as long as it should, I'm not sure why some thing that should be so simple is causing me such hassle.
I tried the code that I posted before and it does the same thing as all the other iterations I have tried, Im only getting 0.2v of discharge before the cycle starts again as i can see in the waveform of the voltage across the capacitor on the scope, Is there something wrong with the maths? I tried putting " int diff = CAPvolt - (VCC / 2);" but it seemed to make no difference.

Because those variables don't change until/unless you assign new results from analogRead(ing) again…

I can make it no simpler than the IPO sketch of a sketch, so to speak, I provided.

L8R

a7

Am i not reading again to compare here?

Leaving aside the code, what are you trying to achieve here? Are you trying to reduce the voltage by switching the capacitors?

No one has raised an eyebrow about the circuit yet ?
[UPDATE] Glad to see that jhaine questions the circuit as well.

When the power is turned on, and all the mosfets are off, then both C1 and C2 will charge to VCC/2 via a reverse current through Q3. That is not nice.

When Q1 and Q2 are turned on, then C1 and C2 are both charged to VCC. So far so good.

However, when Q1 and Q2 are turned off and Q3 (in the middle) is turned on, then the capacitors C1 and C2 create a voltage doubler. This higher voltage lifts the voltage of C3, which will be charged, causing a negative current through the load.

In other words: There is no normal discharge. There is some discharge into C3. If that capacitor is very large, then it can be called a "discharge".

the caps will charge through the mosfet body diode, the ratings are not exceeded no problem there at all, they will handle that nicely.

Thats why I have a blocking diode to protect my bench top psu. potential divider across the capacitor not the supply to measure the voltage at that point, for reference in the next cycle.
The capacitor is infact very large, 0.1F.
The negative current across the load is what designed the circuit to do.

Its a charge pump to create alternating power across a load.

"alternating" between quotes :wink:

The positive current through the load charges the capacitors parallel.
The negative current discharges the capacitors in series. Is that half of the positive current ? I'm still a little confused :face_with_spiral_eyes:

sorry could you rephrase that?

Twice the voltage is half the current when it comes to charge pumps with capacitors.

twice the voltage across a load is always twice the current, a capacitor in series with another will have half the capacity in farads if that's what you mean? how does this help me tho?

I'm not sure what efficiency you are hoping for, but if you charge a capacitor through a switch exactly the amount of energy stored in the capacitor is dissipated in the switch. You can see this if you assume the switch has a small resistance and calculate the energy dissipated in charging, which comes out to be the same even as the resistance tends to zero.

Maybe. Hard to say with no context.

Please post a complete sketch that compiles and runs, whether or not it does what you want.

a7

int CHARGE1pin = 2;         // capacitor 1 in parallel
int CHARGE2pin = 3;         // capacitor 2 in parallel
int DISpin = 4;         // capacitors in series
int VCCPin = A0;   // Voltage sensor 'S'
int CAPpin = A1;   // Voltage sensor 'S'


int VCC = 0;
int CAPvolt = 0;


void setup () {
                          
 pinMode(CHARGE1pin, OUTPUT);                  // mosfet
 pinMode(CHARGE2pin, OUTPUT);                  // mosfet
 pinMode(DISpin, OUTPUT);                  // mosfet
}

void loop () {

  VCC = analogRead(VCCPin);  // read input voltage 
  CAPvolt = analogRead(CAPpin);  // read cap voltage
  int difference = VCC - CAPvolt;
if (difference > 10)
  {
    digitalWrite(DISpin,  LOW);  // discharge mosfet Off
  digitalWrite(CHARGE1pin, HIGH);  // charge mosfet ON
  digitalWrite(CHARGE2pin,  HIGH);  // charge mosfet ON
   }
  else {
  digitalWrite(CHARGE1pin, LOW);  // charge mosfet Off
  digitalWrite(CHARGE2pin,  LOW);  // charge mosfet Off
  digitalWrite(DISpin,  HIGH);  // discharge mosfet ON
  int diff = CAPvolt - (VCC / 2);
  if (diff < 100)
 {
 VCC = analogRead(VCCPin);  // read input voltage 
  CAPvolt = analogRead(CAPpin);  // read cap voltage
 }
 
 }
}

Im always charging and discharging through the load which has a very high resistance compared to the mosfet, so the energy dissipated in the switch is negligible.