Here is the code: (I had to break this up so I don't exceed the maximum characters)
/*
Arduino Software for lab power supply.
Wireing guide:
**Wiring for 16x2 LCD:**
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
**Wiring for buttons:**
* RS button to pin 6 (as a digital input) -- Switches from reading read current/voltage values to setting those values, and Vice Versa.
* setVI button to pin 7 (as a digital input) -- Switches to the 'set' mode and flips from setting the voltage to setting the current.
* UP button to pin 8 (as a digital input) -- Increments the voltage or current up when in the 'set' mode.
* DOWN button to pin 9 (as a digital input) -- Increments the voltage or current up when in the 'set' mode.
**Analog inputs/outputs:**
*A0 -- Measures a potential of a resistor divider that can output a voltage of 0-5V based on the 0-30V output this PSW capable of.
*A1 -- Measures the current flow through a resistor to measure current. (Some reason there seems to be a pulldown resistor on this pin, so the voltage does not float.)
*Vout -- This will be later implemented if I get a DAC, for the increased resolution. (1024 is just not enough in my opinion. At least 12 bits)
*Aout -- This will be later implemented if I get a DAC, for the increased resolution. (1024 is just not enough in my opinion. At least 12 bits)
*/
int UP = 0; // These are the 2 buttons used to incrementally
int DOWN = 0; // step up or down the voltage on the output
int RS = 0; // These 2 buttons tell the LCD to either read out the voltage on the analog pins. (I plan to change this so it reads from a 14 bit ADC and writes
int setVI = 0; // the voltage output through a 14 (or 16 bit) bit ADC. I need 3 significant digits, or at least 0.1% accuracy.
int dudd = 0; // this dudd (dummy variable) is just here to prove that digitaslreading pin 7 works very weird! Any help on this?
int preRS = 1; // Anything with a "Pre" before it is simply what said integer/variable on the last loop. I use these to prevent a parasitic
int presetVI = 1; // oscillation of states that they control, so when a button is pressed, it will not jump between 2 states every cycle.
int preUP = 0;
int preDOWN = 0;
float Aset = 0.00; // I need these to be "floated" so I can set the exact value of these to 3 significant digits.
float Vset = 0.00; // Aset and Vset define what the output voltage *should* be, and are defined with the UP/DOWN buttons.
int VIselection = 1;// this variable will invert when Aset button is pressed. Similar to the IVselect, this number will also invert
int READorSET = 1; // Bset button is pressed. This allows the mode to be changed from SET mode or the READ output mode, thus allowing
// one to compare the output voltage and current to the set value, as well as set the output voltage and current.
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);// initialize the library with the numbers of the interface pins
void setup() {
//-------------------------// I tried making diagnosting this thing easier by making all the important data availible in the serial monitor.
lcd.begin(16, 2);
Serial.begin(9600);
Serial.print("INPUTS RS: READorSET: setVI & dudd: VIselection:");
Serial.println("");
}
void loop() {
float V = (30.00*analogRead(A0))/1024.00; //These are what I use to read the voltage output of my power supply. I will have a voltage divider on the output,
float A = (15.000*analogRead(A1))/1024.000; //to limit the voltage range from 0-30V to 0-5V. Same concept goes for the current measurement.
int dudd = digitalRead(7);//
RS = digitalRead(6);//RS stands for "Read/set"
setVI = digitalRead(7);//VI is stands for "Current/Voltage set"
UP = digitalRead(8);//UP is simply a button used to set voltage & current
DOWN = digitalRead(9);//DOWN is simply a button used to set voltage & current
if(presetVI == LOW && setVI == HIGH){VIselection = -VIselection;}
if(preRS == LOW && RS == HIGH){READorSET = -READorSET;}
Serial.print("\t "); // prints an inital space.
Serial.print(RS); // prints the RS reading. It should be '1' when pin 7 is HIGH.
Serial.print("\t ");
Serial.print(READorSET); // prints the READorSET reading. This should only change when the RS button is pressed.
Serial.print("\t ");
Serial.print(setVI); // prints the setVI reading. It should be '1' when pin 7 is HIGH.
Serial.print("\t");
Serial.print(dudd); // prints the setVI reading. It should be '1' when pin 7 is HIGH.
Serial.print("\t "); //
Serial.println(VIselection); // prints the VIselection reading. This should only change when the setVI button is pressed.
//if(presetVI == LOW && setVI == HIGH && READorSET == 1) {READorSET = -READorSET; VIselect = -VIselect;}
// This line of code just makes so that when I need to go from the voltage read screen to
// the set mode, I can just press the VIselect button. It just makes things more intuitive, but could be
// causeing the error, so I nulled it. I also nulled it out another portion that will keep the voltage or
// current setting the same when using the VI buttton to select the set mode. (otherwise it has to be
// double pressed to return to, say, the current setting, if that is where you left off.)
if(UP == HIGH && DOWN == LOW && VIselection == -1){if(Aset <= 10.00) {Aset += 0.05;}}
if(DOWN == HIGH && UP == LOW && VIselection == -1){if(Aset >= 0.10) {Aset -= 0.05;}}
if(UP == HIGH && DOWN == LOW && VIselection == 1) {if(Vset <= 30.00) {Vset += 0.05;}}
if(DOWN == HIGH && UP == LOW && VIselection == 1) {if(Vset >= 0.05) {Vset -= 0.05;}}
//============================================================================================================//
if (READorSET == 1){ //this is the defualy screen, and shows the output voltage and current.
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("VOLTAGE:");
lcd.setCursor(0, 1);
lcd.print("CURRENT:");
lcd.setCursor(10, 0);
lcd.print(V);
lcd.setCursor(15, 0);
lcd.print("V");
lcd.setCursor(10, 1);
lcd.print(A);
lcd.setCursor(15, 1);
lcd.print("A");
}
if (READorSET == -1){ // This is the portion of the code allowing me to set the current and voltage
lcd.clear(); // using the up/down butons.
if (VIselection == -1){
lcd.setCursor(0, 0);
lcd.print(" SET CURRENT:");
lcd.setCursor(5, 1);
lcd.print(Aset);
lcd.print("A ");
}
if(VIselection == 1){
lcd.setCursor(0, 0);
lcd.print(" SET VOLTAGE:");
lcd.setCursor(5, 1);
lcd.print(Vset);
lcd.print("V ");
}
}
//============================================================================================================//
presetVI = setVI; // At the end of each loop, the current variable settings that were used are set equal
preRS = RS; // to the 'pre' versions of the code. This allowes me to basicaly measure the when
// the button is initally pressed, and/or released. Using this method with the delay()
// function, however, is a bit buggy, but I did have it working well enough before. If you
// tap the button too quickly. You almost have to hold it for a split second. If you
// know a better, simpler way of doing this, please tell me, thank you.
delay(80); // The delay helps stabilize the reading on the LCD, but if it is too large, than the
// refresh rate suffers, and the buttons respond slower. However, setting too low will
// cause the reading on the display to change so rapidly, it is illegable.
}