Digitally controlled voltage with feedback.

coinmaster

Joined Dec 24, 2015
502
I'm trying to create a digitally controlled voltage which I will end up using for a software controlled voltage divider for a high voltage circuit control around 600v.

For now I am trying to get it to work on 5v.

This is the general idea

I want precise output voltages so I want to negate any non-linearities in the transistor with digital feedback from a voltage sense IC or something.
So basically I'll tell the controller that I want x voltage on the output and if the voltage on the output reads more or less than that voltage then it will self correct.
This is the code I'm using right now
C:
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
pinMode(13,OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
digitalWrite(13, HIGH);
// Reads potentiometer voltage to get a reference number used for intended output voltage
// Takes analogRead value and turns it into the intended voltage reference number
float ReferenceNumber = reference * (5.0 / 1023.0);

// Translation from intended voltage number to analogWrite voltage
float output=ReferenceNumber*(225/5.0);
// output to transistor base
analogWrite(9,output);
// reads the output voltage for feedback control
// If the output voltage is greater or less than the intended voltage then the opto-isolator bias will be adjusted.
if (feedback*(255/1023.0) > output ) {
output = -1 ;}
if (feedback*(255/1023.0) < output ) {
output = +1 ;}

//Prints the output voltage
Serial.println(feedback* (5.0 / 1023.0));
}
I'm using a potentiometer to adjust the reference voltage and then I'm converting the reverence voltage number into analogWrite voltage which is then read by analogRead at the output and the output is adjusted based on whether the output is lower or higher than the reference number.

It works but it is not stable, it fluctuates all over within a volt or more.
Is there some problem in the concept of my code or something?
I only started learning digital electronics and coding a couple days ago.

Moderators note: changed code tags to C

Last edited by a moderator:

Alec_t

Joined Sep 17, 2013
11,817
R9/C1 introduce a considerable delay between the commanded voltage output and the AnalogRead value that you want. I don't see any delay routines to allow for that?

coinmaster

Joined Dec 24, 2015
502
What do you mean? How is my RC filter delaying the output voltage?

Also I changed the code and switched the supply pins on the arduino and this is the result
http://imgur.com/RSRyUwz
The stability is much better but the accuracy is off. Perhaps the ADC does not have a high enough resolution?
This is the code I am now using

C:
int PWMout = 9; // Ouput PWM pin
int output = 255; //Start PWM at 255 as this is zero voltage output, because the circuit is a shunt regulator.
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
pinMode(13, OUTPUT);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(PWMout, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop()
{
digitalWrite(13, HIGH);
// Reads potentiometer voltage to get a reference number used for intended output voltage

// Takes analogRead value and turns it into the intended voltage reference
float ReferenceVoltage = reference * (5.0 / 1023.0);

// reads the feedback output voltage for feedback control
float FeedbackVoltage = feedback * (5.0 / 1023.0);

// If the feedback voltage is greater than the reference then the PWM needs to be increased to increase shunt current.
if (FeedbackVoltage > ReferenceVoltage )
{
output = +1 ;
}

// If the feedback voltage is less than the reference then the PWM needs to be decreased to decrease shunt current.
if (FeedbackVoltage < ReferenceVoltage )
{
output = -1 ;
}

// Check output value and limit maximum and minimum
if (output >= 255)
{
output = 255;
}
if (output <= 0 )
{
output = 0;
}
// Print variables
analogWrite(PWMout, output);
//Prints the voltages
Serial.print("Reference ");
Serial.print(ReferenceVoltage);
Serial.print("/tFeedbackVoltage ");
Serial.print(FeedbackVoltage);
Serial.print("/tPWMout ");
Serial.println(output);
}

Last edited:

dannyf

Joined Sep 13, 2015
2,197
it fluctuates all over within a volt or more.
it is very hard to stablize a mixed signal control loop.

The universal trick is to lower the gain - but it comes with its bag of negativity as well.

dannyf

Joined Sep 13, 2015
2,197
You are doing "on/off" control - may not be the best approach.

I would try this:

1) measure the analog output (middle of R5/R7);
2) if it is great than your desired output, increment output; else decrement output; update pwm duty cycle
3) go back to 1).

You can adjust the stepping of the increments / decrements.

coinmaster

Joined Dec 24, 2015
502
You are doing "on/off" control - may not be the best approach.

I would try this:

1) measure the analog output (middle of R5/R7);
2) if it is great than your desired output, increment output; else decrement output; update pwm duty cycle
3) go back to 1).

You can adjust the stepping of the increments / decrements.
Um, is that not what I am doing now? Check out my last post.

Also I changed it to
C:
  if (FeedbackVoltage > ReferenceVoltage )
{
output++ ;
}

// If the feedback voltage is less than the reference then the PWM needs to be decreased to decrease shunt current.
if (FeedbackVoltage < ReferenceVoltage )
{
output--;
}
and the result is the same, whether I use +1 or ++

The error margin is pretty much eliminated after changing the supply pin and refining the code. The main issue is accuracy http://imgur.com/L3D2Ygz I'm assuming this is a resolution issue? The aruino only has 8 bits ADC.

Last edited:

Alec_t

Joined Sep 17, 2013
11,817
How is my RC filter delaying the output voltage?
The R9/C1 time constant is 100mS, so a voltage change at the Arduino output will not appear across C1, and hence at the 'Voltmeter' node, immediately.

dannyf

Joined Sep 13, 2015
2,197
Code:
[LIST=1]
[*]// If the feedback voltage is greater than the reference then the PWM needs to be increased to increase shunt current.
[*] if (FeedbackVoltage > ReferenceVoltage )
[*] {
[*]    output = +1 ;
[*] }
[*]

[*] // If the feedback voltage is less than the reference then the PWM needs to be decreased to decrease shunt current.
[*] if (FeedbackVoltage < ReferenceVoltage )
[*] {
[*]    output = -1 ;
[*] }
[/LIST]
That's what you wrote.