#include <LiquidCrystal_I2C.h>
// Define LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Change the address if needed
// Define button pins
const int menuButtonPin = 2;
const int upButtonPin = 3;
const int downButtonPin = 4;
// Define analog output pins
const int voltagePin = 9;
const int currentPin = 10;
// Define voltage and current limits
const float maxVoltage = 56.0;
const float maxCurrent = 35.0;
float setVoltage = 0.0;
float setCurrent = 0.0;
// Define menu states
enum MenuState {
VOLTAGE,
CURRENT
};
MenuState currentMenuState = VOLTAGE;
void setup() {
// Initialize LCD
lcd.begin(16, 2);
// Initialize buttons
pinMode(menuButtonPin, INPUT_PULLUP);
pinMode(upButtonPin, INPUT_PULLUP);
pinMode(downButtonPin, INPUT_PULLUP);
// Set initial values
analogWrite(voltagePin, 0);
analogWrite(currentPin, 0);
// Display initial values on LCD
updateLCD();
}
void loop() {
// Check buttons
if (digitalRead(menuButtonPin) == LOW) {
// Change menu state when the menu button is pressed
if (currentMenuState == VOLTAGE) {
currentMenuState = CURRENT;
} else {
currentMenuState = VOLTAGE;
}
delay(200); // debounce
updateLCD();
}
if (digitalRead(upButtonPin) == LOW) {
// Increase voltage or current based on the menu state
if (currentMenuState == VOLTAGE) {
setVoltage = constrain(setVoltage + 1.0, 0.0, maxVoltage);
analogWrite(voltagePin, map(setVoltage, 0, maxVoltage, 0, 255));
} else {
setCurrent = constrain(setCurrent + 1.0, 0.0, maxCurrent);
analogWrite(currentPin, map(setCurrent, 0, maxCurrent, 0, 255));
}
delay(200); // debounce
updateLCD();
}
if (digitalRead(downButtonPin) == LOW) {
// Decrease voltage or current based on the menu state
if (currentMenuState == VOLTAGE) {
setVoltage = constrain(setVoltage - 1.0, 0.0, maxVoltage);
analogWrite(voltagePin, map(setVoltage, 0, maxVoltage, 0, 255));
} else {
setCurrent = constrain(setCurrent - 1.0, 0.0, maxCurrent);
analogWrite(currentPin, map(setCurrent, 0, maxCurrent, 0, 255));
}
delay(200); // debounce
updateLCD();
}
}
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
if (currentMenuState == VOLTAGE) {
lcd.print("Voltage: ");
lcd.print(setVoltage);
lcd.print(" V");
} else {
lcd.print("Current: ");
lcd.print(setCurrent);
lcd.print(" A");
}
lcd.setCursor(0, 1);
lcd.print("Use Menu to switch");
// Display voltage bar, battery icon, and status graph in row 3
lcd.setCursor(0, 2);
displayVoltageBar();
lcd.print(" ");
displayBatteryIcon();
lcd.print(" ");
displayStatusGraph();
}
void displayVoltageBar() {
int barLength = map(setVoltage, 0, maxVoltage, 0, 16);
for (int i = 0; i < barLength; ++i) {
lcd.write(255); // Display a block character to represent the voltage bar
}
}
void displayBatteryIcon() {
lcd.write(6); // Display a custom character representing a battery icon
}
void displayStatusGraph() {
// Display a simple status graph based on the current value
int graphLength = map(setCurrent, 0, maxCurrent, 0, 16);
for (int i = 0; i < graphLength; ++i) {
lcd.write(7); // Display a custom character representing a graph
}
}