Digitally controlled voltage with feedback.

Thread Starter

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

feedbacks-1_800x482.gif

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() {
  //Power source for adjustable voltage
  digitalWrite(13, HIGH);
  // Reads potentiometer voltage to get a reference number used for intended output voltage
  int reference = analogRead(A1);
  // 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
  int feedback = analogRead(A0);
  // 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
14,263
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?
 

Thread Starter

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
  int reference = analogRead(A1);

  // 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
  int feedback = analogRead(A0);
  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
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.
 

Thread Starter

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:

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.
 

Thread Starter

coinmaster

Joined Dec 24, 2015
502
Oh right time constant, almost forgot about that. It doesn't seem that you can get a good time constant with good filtering. How to solve this? Maybe I have to resort to a full on DAC?
 
Top