Digital Control for Laboratory Power Supply Using Arduino

arduino_duemilanove_board

Figure 1. Arduino Duemilanove Board for Power Supply’s Digital Control

Digital System for Display and Control

As the second part of the first article Adjustable 1-30V Laboratory Power Supply, the digital control and display for our power supply will be presented here. The microcontroller used in the circuit is ATMEGA 328, a member of Atmel’s AVR microcontroller family. We use Arduino Duemilanove board to ease the development, and you can see the board  in the Figure 1. If you don’t want to use Arduino board then you can make your own microcontroller board based on Arduino system configuration at arduino-duemilanove-schematic.pdf (you can omit many parts which is not needed for this design). Here is the circuit’s schematic diagram employing the Arduino board:

Power Suply Digital Control

Figure 2. Shcematic Diagram of The Digital Control Circuit

The Control and Display Circuit Design

The main features of the power supply are the adjustable output  voltage level and the adjustable current limiter. We need a control interface to set the parameters, and a display to monitor the real value of the controlled parameter.  At the schematic diagram we can see the control interface consists of three key switches and one potentiometer. The key switches is read by digital input pin of the micro controller board, and the potentiometer is read by the analog input of the board. The potentiometer position can be used to adjust the voltage or current level, even to select multiple option of menu items, unlimited usage can be applied. The key switches has no debounching capacitors, so we have to provide the debounching mechanism in the software. This controller communicate to the switching regulator circuit using PWM signal (P.1 and P.2) to adjust the voltage and current setting, and read the analog voltages (A3 and A4) from current sensor and voltage sensor from switching regulator board to monitor the actual voltage and current. The potentiometer labelled as contrast is not part of the user interface since it should be set  only one to adjust the readability of the LCD monitor.

The Program Source Code (The Firmware)

The source code for the arduino system is shown below, how the code works and how to tweak this firmware will be presented in the next update, coming soon!


#include <LiquidCrystal.h>
#include <stdlib.h>

LiquidCrystal lcd(2,3,4,5,6,7);
int voltagePin = A3;
int currentPin = A4;
int pwmCurrentPin = 10;
int pwmVoltagePin = 9;
int potPin = A5;
int key1Pin = 8;
int key2Pin = 12;
int key3Pin = 11;
int prevk1=1;
int prevk2=1;
int prevk3=1;
int currk1=1;
int currk2=1;
int currk3=1;
float voltageRef = 0;
float currentRef = 0;

float readVoltage()
{
float total=0;
for(int n=0;n<100;n++)
{
float temp = (float) analogRead(voltagePin);
temp = 1.1 * temp/1024 * 30;
total = total + temp;
delay(1);
}
return total/100;
}

float readCurrent()
{
float total=0;
for(int n=0;n<100;n++)
{
float temp = (float) analogRead(currentPin);
temp = temp/1024 * 5;
temp = (temp-2.51)*25*0.185;
total = total + temp;
delay(1);
}
return total/100;
}

float readPot()
{
float temp = (float) analogRead(potPin);
temp = temp/1024;
return temp;
}

void showCurrentSet(float value)
{
char txt[6];
dtostrf(value,4,1,txt);
lcd.setCursor(11,0);
lcd.print(txt);
}

void showVoltageSet(float value)
{
char txt[6];
dtostrf(value,5,1,txt);
lcd.setCursor(4,0);
lcd.print(txt);
}

void showVoltageAct(float value)
{
char txt[6];
dtostrf(value,5,1,txt);
lcd.setCursor(4,1);
lcd.print(txt);
}

void showCurrentAct(float value)
{
char txt[6];
dtostrf(value,4,1,txt);
lcd.setCursor(11,1);
lcd.print(txt);
}

void setup()
{
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print(“SET:00.00V 0.00A”);
lcd.setCursor(0,1);
lcd.print(“ACT:00.00V 0.00A”);
pinMode(key1Pin, INPUT_PULLUP);
pinMode(key2Pin, INPUT_PULLUP);
pinMode(key3Pin, INPUT_PULLUP);
pinMode(pwmVoltagePin, OUTPUT);
analogWrite(pwmVoltagePin, 0);
pinMode(pwmCurrentPin, OUTPUT);
currentRef = 0.5;
analogWrite(pwmCurrentPin,128 + (currentRef*12.7));
}

void loop()
{
int tempk1 = digitalRead(key1Pin);
int tempk2 = digitalRead(key2Pin);
int tempk3 = digitalRead(key3Pin);
int count = 0;
while (count < 10)
{
currk1 = digitalRead(key1Pin);
currk2 = digitalRead(key2Pin);
currk3 = digitalRead(key3Pin);
if(tempk1 != currk1)
{
tempk1 = currk1;
count = 0;
}
if(tempk2 != currk2)
{
tempk2 = currk2;
count = 0;
}
if(tempk3 != currk3)
{
tempk3 = currk3;
count = 0;
}
count++;
}

if((currk1==0)&&(prevk1==1))
{
currentRef = currentRef + 0.5;
if(currentRef>3) currentRef=3;
showCurrentSet(currentRef);
analogWrite(pwmCurrentPin,128 + (currentRef*11));
}

if((currk2==0)&&(prevk2==1))
{
currentRef = currentRef – 0.5;
if(currentRef<0.5) currentRef=0.5;
showCurrentSet(currentRef);
analogWrite(pwmCurrentPin,128 + (currentRef*12.7));
}

if((currk3==0)&&(prevk3==1))
{
}

prevk1=currk1;
prevk2=currk2;
prevk3=currk3;

showVoltageAct(readVoltage());
showCurrentAct(readCurrent());
showCurrentSet(currentRef);
showVoltageSet(readPot()*30);
analogWrite(pwmVoltagePin, 0.91*readPot()*255);
}

See the software in action, in our Youtube channel below:

4 Comments on Digital Control for Laboratory Power Supply Using Arduino

  1. Hi.
    Was building my PWM regulator with Arduino and got stuck with current limiting. Implemented a Hall effect sensor in the circuit and do not know how to code the Arduino to work with it. I’d like to limit the current when it reaches the set level. Can you explain your code because as far as I can see it is exactly what I need. Many thanks,
    Roman.

  2. Hi I really like this design, good work on the design! I will be getting my components today in the mail as I plan to build this but was wondering if you had finished with the additional firmware and tweeks? And also do you have a couple more reference photos of inside the case? Ive already constructed the actual case itself, but would love to see more of the inside components. And also I have a real nice transformer that came out of a big sound bar, it has 3 output voltages; the center looks to be 24 volts (Two 12 volt lines and center tap), and has an 8.7V winding, and an 18.8V winding as well. Im hoping to make the 8.7 winding the logic supply for the Atmega, and maybe stepping down the 18.8 to maybe 12V??? Maybe use it as a fixed 12V output with a regulator or through the Atmega???? Not sure I am pretty new into electronics, but have been studying my ass off on circuits and such I really love it. Also any thoughts of maybe an ethernet connection as well? I have a nice little shield I bought off ebay for next to nothing I could maybe incorporate into the supply as well, well thank you for the excellent head start on this and hope to hear any additional input, and or ideas you have and code tweeks because Ill sure need all the help I can get!!! Lol, ttyl and thanks again!!

  3. Forgot to mention in last comment.The arduino ice was used to compile and the chip used is an atmega 328 p-pu.

  4. I tried twice on putting this together. I plan to use a ATX power supply with a LM317 to control the 12volt rail thuss making it a 12volt adjustable supply. Anyway, the 1602 LCD I have uses different lettering on the pins. For a example on your diagram it says L+ and L- but my LCD doesn’t have that. It has A and K. Also doesn’t it need a voltage load for anything to show up on the LCD? I ask because I haven’t tried putting a load on it.

Leave a comment

Your email address will not be published.

*



four + 9 =