Constant Current DC Load Part 6

Posted on 26/06/2016 by Adam

This version of the code is working – it does however need improving. The analog value readings are a little off.

#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 = A7;  //Voltage of input
int v2Pin = A2;  //Voltage at mosfet source pin
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 = 1.0; //Your shunt resistor value - for best results measure value.
float actualCurrent = 0.0;  //Calculated current
float voltage1 = 0.0;
float refVolt = 4.9; //Actual USB Voltage
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() {
  actualCurrent = analogRead(v2Pin) * RefVolt / 1024.0;
  
  if (actualCurrent < targetCurrent) {
     pulseWidth++;
     if (pulseWidth > 200) pulseWidth = 200;  // 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);
}

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);
}


What Others Are Saying

  1. Dan Johnston 10/08/2016 at 18:50

    Thanks Adam for making these Arduino videos AND sharing your code. Some of the projects on YT will not share their code, and that is their right, but those projects are useless to me. I have been trying to learn how to use the Arduino for over a year, and my brain just will not get the code stuff. I love electronics and projects like this, but I could never program like this, so I could not make this project without help with the code.
    I have several good books that I am reading on programing, maybe one day I will understand more.
    Again Thanks

Leave a Reply

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