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