Issues adding voltage feedback to pwm

Hello, I am trying to get a code working that sets a pwm duty cycle that uses voltage out as the control for the duty cycle.
Since I am trying to control voltage I am trying to make it as fast as possible.

I am just learning and always appreciate tips on things unrelated to my question, if variables arent used in the best way I am all ears to improving that sort of thing too.

I have this code that works well by using a potentiometer to control duty cycle.

#include <avdweb_AnalogReadFast.h>
byte Output = 0;

void setup()
{
 
  pinMode (5,OUTPUT);

TCCR0B = TCCR0B & B11111000 | B00000001; // for PWM frequency of 62500.00 Hz

}
void loop()
{
  Output = (analogReadFast(4)>>2);
  
  analogWrite(5, Output);

When I try and convert it to use feedback from a pair of voltage dividers it stays full throttle.

#include <avdweb_AnalogReadFast.h>
byte Input = 0, Vin = 0,  drain = 0,  Vout  = 0,  Output  = 0;

void setup()
{

  pinMode (5, OUTPUT);

  TCCR0B = TCCR0B & B11111000 | B00000001; // for PWM frequency of 62500.00 Hz

}

void loop()
{
  Input = 20;                                      //this is the value I want to maintain on Vout
  Vin =   (analogReadFast(5)  >> 2);
  drain = (analogReadFast(6) >> 2);
  Vout  = (Vin - drain);

  if (Vout >= Input) Output  = (Output  - 5);
  if (Vout < Input) Output  = (Output  + 3);


  analogWrite(5, Output);


}

Heres a diagram showing where the voltage dividers are in my circuit.

Thanks for any help

PWM is not analog.

It can be filtered to analog but it won't be as fast.

So my code is likely ok, but I need to filter the output of my voltage dividers?

Any suggestions on the best way to do this, and maybe the easiest way too?

Great schematic, just not quite enough. Show what Arduino you are using and what pins are connected to what. Also show the voltages.

1 Like

We would need to see the rest of the schematic. What are you trying to hide?

One version will be 10-35v, the other version will be 10-80v. (different fet, divider resistor, and 7812 regulator replaced with drop in switching regulator).

I plan on switching at 62 khz , but may drop it down to 31khz if testing shows significant difference in fet heat generation.

Hoping to end up with a one size fits most high power PWM that can take various inputs.

The particular use I am struggling with here is to keep the output voltage steady regardless of what the current draw is on the load.

I can now see that trying to use Vin to PWM a load to drag Vin down wont work either (wind turbine dump load)

Hi,
Thanks for the schematic.

What is the load?
Resistive or inductive?

Why do you need the filter C8, C6, C9?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

The polypropylene snubber capacitors are there to absorb the spike in voltage on the drain of the fet when it shuts off.
I was told the diode isnt fast enough and the caps keep everything ok till the diode (D1)"catches"

Hoping to use them for all kinds of loads, resistive, capacitive and inductive.
I will use them for everything they can do without letting the smoke out . (Will find this limit thru testing)

They work great so far, just burnt a 1/4" welding rod at 300 amps with the full weld current running thru the board.

Just trying to get them working as PWM voltage regulators for solar to send excess power to a heating element.

Really going for a one size fits most kind of thing here as I have a 10 year backlog of stuff I want to test.

PWM is a rectangular digital signal that also can be observed at the load as an increasing (ON) and decreasing (OFF) voltage. If you can not measure the voltages fast enough for building an average voltage you should add low pass filters before the analog inputs.

Also consider to measure the flowing current instead of the voltage, using a Hall sensor based or a clamp meter. This way you get only one signal that is easier to filter.

So I googled what an low pass filter was and added one on each voltage divider, now I get useable "voltage" readings from my dividers.
Thanks for that, I was fighting too many issues at the same time to figure that one out.

Did some more work on my code and got it to work, but it refuses to output anything if I comment the serial plotter? I of course want it off to speed things up.

The code also refuses to work if I uncomment the line "if (Vin < 60) (Output = 0); "

Any ideas what I am doing wrong?

#include <avdweb_AnalogReadFast.h>
byte  Vin = 0,  drain = 0,  Vout  = 0,  Input = 0;
short int  Output = 0;

void setup()
{

  Serial.begin(9600);
  delay(2000);
 
  pinMode (5,OUTPUT);

TCCR0B = TCCR0B & B11111000 | B00000001; // for PWM frequency of 62500.00 Hz

}

void loop()
{

 
  Input = (analogReadFast(4)>>2);
  

  Vin =   (analogReadFast(5)  >> 2);
  drain = (analogReadFast(6) >> 2);
  Vout  = (Vin - drain);

  if (Vout >= Input) Output  = (Output  - 5);
  if (Vout < Input) Output  = (Output  + 3);
  
   Output = constrain(Output, 0, 255);
   //if (Vin < 60) (Output = 0);         //this is supposed to keep controller from starting at full throttle when powered up,controller output stays at zero with this uncommented?
  
  analogWrite(5, Output);


  Serial.println("Output:");
  Serial.print(Output);
  Serial.print(" ");

  Serial.print("Vin:");   
  Serial.print(Vin);
  Serial.print(" ");

  Serial.print("Vout:");
  Serial.print(Vout);
  Serial.print(" ");

  Serial.print("Input:");
  Serial.print(Input);
  Serial.print(" ");
  
  
}

This makes your regulator unstable. If the first statement decrements Output then the second statement immediately increments it again. I'd use

  if (vout > Input) ...
  else if (vout < input) ...

Some hysteresis can be added if vout only is changed if the absolute difference becomes > x.

How is Serial Plotter related to your code?
Perhaps the PWM output is changed too frequently without the Serial output and can not work properly?

Got it working with, and without the serial plotter, thanks for the help and ideas.
Its amazing how much faster it runs without the serial plotter.

Looks like a lot of my issues were from having byte values maxing out, then rolling over to 0 or 255.

Hopefully others can use this since there dosent seem to be much like this geared towards the rookie.

I think this could be ideal to shunt excess solar power to a heater by making these changes, will test soon.

if (Vout > Input) Output = (Output - 5); // for voltage regulation on Vout
else if (Vout < Input) Output = (Output + 3)

to

if (Vin > Input) Output = (Output + 5); //for voltage regulation on Vin with shunt on Vout
else if (Vin < Input) Output = (Output - 3)

//Created by Chris Soro

#include <avdweb_AnalogReadFast.h>
byte  Vin = 0,  drain = 0,  Input = 0;
short int  Vout  = 0,  Output = 0;      // these are to keep the values from maxing out and rolling over

void setup()
{

  //Serial.begin(9600);
  delay(2000);            // to allow you be fully plugged in before drawing current and arcing connections
 
  pinMode (5,OUTPUT);

TCCR0B = TCCR0B & B11111000 | B00000001; // for PWM frequency of 62500.00 Hz

}

void loop()
{

 
  Input = (analogReadFast(4)>>2);       // if you need to map input you will probably need to change Input from a byte to a short int, this might slow it down a little

  
  Vin =   (analogReadFast(5)  >> 2);      // these inputs are fed by voltage dividers with low pass filters, this one on positive in
  drain = (analogReadFast(6) >> 2);       // this one on drain of low side fet
  Vout  = (Vin - drain);                                  // this is to exclude the fet voltage drop from Vout measurement
  
  if (Vout > Input) Output  = (Output  - 5);
  else if (Vout < Input) Output  = (Output  + 3);
   
   Output = constrain(Output, 0, 255);

 if (Vin < 60) Output = 0;      // to keep from starting at full throttle
 
  analogWrite(5, Output);

/*
  Serial.println("Output:");
  Serial.print(Output);
  Serial.print(" ");

  Serial.print("Vin:");   
  Serial.print(Vin);
  Serial.print(" ");

  Serial.print("Vout:");
  Serial.print(Vout);
  Serial.print(" ");

  Serial.print("Input:");
  Serial.print(Input);
  Serial.print(" ");
  
  */
}

Try;

Serial.begin(115200);

And change the baud rate in the IDE monitor/plotter.

Can you post your final code?
Can you post your final schematic?
This would finish this thread nicely for anyone wanting to do the same.

Tom... :smiley: :+1: :coffee: :australia:

I still don't understand why you change Output if Vin equals Input. Don't you really want to get a steady voltage?

Good point, I do want a steady voltage, I will edit my post to change it.

This project has been throwing me a lot of curve balls and I have been working crazy hours to get it sorted. Im not firing on all cylinders at 3am... And firing on all cylinders often isnt very impressive...

Code is updated.

its probably not right, but I have a 223 ceramic cap across R8 and another across R9

in between j2.6 and R6/R9 theres a 330 ohm resistor

in between j2.7 and R7/R8 theres a 330 ohm resistor

This hopefully is a 24khz low pass filter, no idea if thats the optimum value, but it seems to work

Where did you update it???
Please do not update OLD posts, it throws a spanner in the flow of the thread, and anybody trying to use this tread to solve their particular problem will be confused.

PLEASE UPDATE CODE AND SCHEMATIC IN A NEW POST!!!

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

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