Constant Current DC Load Part 3

Posted on 13/05/2016 by Adam

Below is the code for the early version of my arduino constant current load – it is worth noting this isn’t a working version as yet.


#include "LCD5110_Graph.h" // Available from http://www.rinkydinkelectronics.com/library.php?id=47
LCD5110 myGLCD(13,11,10,8,9); // Setup Nokia 5110 Screen SCLK/CLK=13, DIN/MOSI/DATA=11, DC/CS=10, RST=8 Chip Select/CE/SCE=9,

int GoPin = 2; //Go Button must be connected to interrupt pin
int IVPin = 3; //IV Button must be connected to interrupt pin
int DwnPin = 4;
int UpPin = 5;
int fetPin = 6; //Mosfet Gate Pin
int v1Pin = A6; //Voltage at positive end of shunt resistor
int v2Pin = A7; //Voltage at negative end of shunt resistor
int pulseWidth = 0;

volatile boolean go = true;
volatile byte GoState = LOW;
volatile byte IVState = LOW;
volatile int menu = 0;
volatile int buttonUpState = 1;
volatile int buttonDwnState = 1;

float shunt = 0.47; //Your shunt resistor value - for best results measure value.
float actualCurrent = 0.0; //Calculated current
float voltage1 = 0.0;
float voltage2 = 0.0;
float maxVolt = 15.638; //Using a voltage divider calculator enter maximum safe voltage of your divider.
volatile float targetCurrent = 1.0; //Default current
volatile float dropoutVoltage = 1.0; //Default dropout voltage

extern uint8_t SmallFont[]; //Get external display font for display

void setup() {
pinMode(GoPin, INPUT_PULLUP);
pinMode(IVPin, INPUT_PULLUP);
pinMode(UpPin, INPUT_PULLUP);
pinMode(DwnPin, INPUT_PULLUP);
pinMode(fetPin, OUTPUT);

attachInterrupt(0, stoprun, LOW);

myGLCD.InitLCD(70); //initialize LCD with contrast of 75 (default is 70)
myGLCD.setFont(SmallFont); //Set default font size. tinyFont 4x6, smallFont 6x8, mediumNumber 12x16, bigNumbers 14x24
myGLCD.clrScr();
myGLCD.print("AdamWelch.Uk",CENTER,24); //Print branding
myGLCD.update();
delay(1000);
myGLCD.clrScr();

}

void loop() {

voltage1 = analogRead(v1Pin) * maxVolt / 1024.0;

if (GoState == HIGH && voltage1 > dropoutVoltage) {
constantCurrent();
}
else if (GoState == HIGH && voltage1 < dropoutVoltage) {
GoState = LOW;
}
else if (GoState == LOW) {
pulseWidth = 0;
analogWrite(fetPin, pulseWidth);
attachInterrupt(1, menuChange, LOW);

if (IVState == LOW) {
menu0();
}
else if (IVState == HIGH) {
menu1();
}
}
}

void stoprun() {
GoState = !GoState;
}

void menuChange() {
IVState = !IVState;
}

void constantCurrent() {
voltage2 = analogRead(v2Pin) * maxVolt / 1024.0;
actualCurrent = (voltage1 - voltage2) / shunt;

if (actualCurrent < targetCurrent) {
pulseWidth++;
if (pulseWidth > 80) pulseWidth = 80; // Pulse width limited to ensure mosfet doesn't go fully on.
}
else if (actualCurrent > targetCurrent) {
pulseWidth--;
if (pulseWidth < 0) pulseWidth = 0;
}

analogWrite(fetPin, pulseWidth);

myGLCD.clrScr();
myGLCD.print("Voltage(v)",LEFT,0);
myGLCD.print("Current(a)",LEFT,24);
myGLCD.printNumF(voltage1, 1,LEFT,12);
myGLCD.printNumF(actualCurrent, 1,LEFT,36);
myGLCD.print("Up",RIGHT,0);
myGLCD.print("Dn",RIGHT,14);
myGLCD.print("IV",RIGHT,28);
myGLCD.print("Stop",RIGHT,40);
myGLCD.update();
}

void menu0() {

myGLCD.clrScr();
myGLCD.print("Voltage(v)",LEFT,0);
myGLCD.printNumF(dropoutVoltage, 1,LEFT,12);
myGLCD.print("Current(A)",LEFT,24);
myGLCD.printNumF(targetCurrent, 1,LEFT,36);
myGLCD.drawLine(0,44,20,44);
myGLCD.print("Up",RIGHT,0);
myGLCD.print("Dn",RIGHT,14);
myGLCD.print("IV",RIGHT,28);
myGLCD.print("Go",RIGHT,40);
myGLCD.update();

if (digitalRead(UpPin) == 0) {
targetCurrent = targetCurrent + 0.1;
if (targetCurrent > 5.0) targetCurrent = 5.0;
delay(20);
}
else if (digitalRead(DwnPin) == 0) {
targetCurrent = targetCurrent - 0.1;
if (targetCurrent < 0.1) targetCurrent = 0.1;
delay(20);
}

myGLCD.update();
detachInterrupt(1, menuChange, LOW);
}

void menu1() {

myGLCD.clrScr();
myGLCD.print("Voltage(v)",LEFT,0);
myGLCD.print("Current(a)",LEFT,24);
myGLCD.printNumF(dropoutVoltage, 1,LEFT,12);
myGLCD.drawLine(0,20,20,20);
myGLCD.printNumF(targetCurrent, 1,LEFT,36);
myGLCD.print("Up",RIGHT,0);
myGLCD.print("Dn",RIGHT,14);
myGLCD.print("IV",RIGHT,28);
myGLCD.print("Go",RIGHT,40);

if (digitalRead(UpPin) == 0) {
dropoutVoltage = dropoutVoltage + 0.1;
if (dropoutVoltage > 15.0) dropoutVoltage = 15.0;
delay(20);
}
else if (digitalRead(DwnPin) == 0) {
dropoutVoltage = dropoutVoltage - 0.1;
if (dropoutVoltage < 0.0) dropoutVoltage = 0.0;
delay(20);
}

myGLCD.update();
detachInterrupt(1, menuChange, LOW);
}

#include "LCD5110_Graph.h" // Available from http://www.rinkydinkelectronics.com/library.php?id=47
LCD5110 myGLCD(13,11,10,8,9); // Setup Nokia 5110 Screen SCLK/CLK=13, DIN/MOSI/DATA=11, DC/CS=10, RST=8 Chip Select/CE/SCE=9,

int GoPin = 2; //Go Button must be connected to interrupt pin
int IVPin = 3; //IV Button must be connected to interrupt pin
int DwnPin = 4;
int UpPin = 5;
int fetPin = 6; //Mosfet Gate Pin
int v1Pin = A6; //Voltage at positive end of shunt resistor
int v2Pin = A7; //Voltage at negative end of shunt resistor
int pulseWidth = 0;

volatile boolean go = true;
volatile byte GoState = LOW;
volatile byte IVState = LOW;
volatile int menu = 0;
volatile int buttonUpState = 1;
volatile int buttonDwnState = 1;

float shunt = 0.47; //Your shunt resistor value - for best results measure value.
float actualCurrent = 0.0; //Calculated current
float voltage1 = 0.0;
float voltage2 = 0.0;
float maxVolt = 15.638; //Using a voltage divider calculator enter maximum safe voltage of your divider.
volatile float targetCurrent = 1.0; //Default current
volatile float dropoutVoltage = 1.0; //Default dropout voltage

extern uint8_t SmallFont[]; //Get external display font for display

void setup() {
pinMode(GoPin, INPUT_PULLUP);
pinMode(IVPin, INPUT_PULLUP);
pinMode(UpPin, INPUT_PULLUP);
pinMode(DwnPin, INPUT_PULLUP);
pinMode(fetPin, OUTPUT);

attachInterrupt(0, stoprun, LOW);

myGLCD.InitLCD(70); //initialize LCD with contrast of 75 (default is 70)
myGLCD.setFont(SmallFont); //Set default font size. tinyFont 4x6, smallFont 6x8, mediumNumber 12x16, bigNumbers 14x24
myGLCD.clrScr();
myGLCD.print("AdamWelch.Uk",CENTER,24); //Print branding
myGLCD.update();
delay(1000);
myGLCD.clrScr();

}

void loop() {

voltage1 = analogRead(v1Pin) * maxVolt / 1024.0;

if (GoState == HIGH && voltage1 > dropoutVoltage) {
constantCurrent();
}
else if (GoState == HIGH && voltage1 < dropoutVoltage) {
GoState = LOW;
}
else if (GoState == LOW) {
pulseWidth = 0;
analogWrite(fetPin, pulseWidth);
attachInterrupt(1, menuChange, LOW);

if (IVState == LOW) {
menu0();
}
else if (IVState == HIGH) {
menu1();
}
}
}

void stoprun() {
GoState = !GoState;
}

void menuChange() {
IVState = !IVState;
}

void constantCurrent() {
voltage2 = analogRead(v2Pin) * maxVolt / 1024.0;
actualCurrent = (voltage1 - voltage2) / shunt;

if (actualCurrent < targetCurrent) {
pulseWidth++;
if (pulseWidth > 80) pulseWidth = 80; // Pulse width limited to ensure mosfet doesn't go fully on.
}
else if (actualCurrent > targetCurrent) {
pulseWidth--;
if (pulseWidth < 0) pulseWidth = 0;
}

analogWrite(fetPin, pulseWidth);

myGLCD.clrScr();
myGLCD.print("Voltage(v)",LEFT,0);
myGLCD.print("Current(a)",LEFT,24);
myGLCD.printNumF(voltage1, 1,LEFT,12);
myGLCD.printNumF(actualCurrent, 1,LEFT,36);
myGLCD.print("Up",RIGHT,0);
myGLCD.print("Dn",RIGHT,14);
myGLCD.print("IV",RIGHT,28);
myGLCD.print("Stop",RIGHT,40);
myGLCD.update();
}

void menu0() {

myGLCD.clrScr();
myGLCD.print("Voltage(v)",LEFT,0);
myGLCD.printNumF(dropoutVoltage, 1,LEFT,12);
myGLCD.print("Current(A)",LEFT,24);
myGLCD.printNumF(targetCurrent, 1,LEFT,36);
myGLCD.drawLine(0,44,20,44);
myGLCD.print("Up",RIGHT,0);
myGLCD.print("Dn",RIGHT,14);
myGLCD.print("IV",RIGHT,28);
myGLCD.print("Go",RIGHT,40);
myGLCD.update();

if (digitalRead(UpPin) == 0) {
targetCurrent = targetCurrent + 0.1;
if (targetCurrent > 5.0) targetCurrent = 5.0;
delay(20);
}
else if (digitalRead(DwnPin) == 0) {
targetCurrent = targetCurrent - 0.1;
if (targetCurrent < 0.1) targetCurrent = 0.1;
delay(20);
}

myGLCD.update();
detachInterrupt(1, menuChange, LOW);
}

void menu1() {

myGLCD.clrScr();
myGLCD.print("Voltage(v)",LEFT,0);
myGLCD.print("Current(a)",LEFT,24);
myGLCD.printNumF(dropoutVoltage, 1,LEFT,12);
myGLCD.drawLine(0,20,20,20);
myGLCD.printNumF(targetCurrent, 1,LEFT,36);
myGLCD.print("Up",RIGHT,0);
myGLCD.print("Dn",RIGHT,14);
myGLCD.print("IV",RIGHT,28);
myGLCD.print("Go",RIGHT,40);

if (digitalRead(UpPin) == 0) {
dropoutVoltage = dropoutVoltage + 0.1;
if (dropoutVoltage > 15.0) dropoutVoltage = 15.0;
delay(20);
}
else if (digitalRead(DwnPin) == 0) {
dropoutVoltage = dropoutVoltage - 0.1;
if (dropoutVoltage < 0.0) dropoutVoltage = 0.0;
delay(20);
}

myGLCD.update();
detachInterrupt(1, menuChange, LOW);
}

What Others Are Saying

  1. Stas 01/03/2017 at 13:47

    Why did you posted twice the code?)

Leave a Reply

Your email address will not be published. Required fields are marked *