// Test for Discord channel.
// This is not working code ?
// Code from 4:08 AM
//
// A different rotary encoder might be used ?
// Wokwi has only one type of rotary encoder.
// CLK = A
// DT = B
// Arduino Variable Power Station Code
// Components: Motor Driver, 0.91" I2C OLED Display, Rotary Encoder
// Voltage increments by 0.05V, click switches between Amps and Volts, double-click locks the selection with a lock symbol
#include <Wire.h>
#include <U8glib.h>
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);
const int encoderPinA = 2;
const int encoderPinB = 3;
const int encoderSwitch = 4;
const int motorPWM = 5;
float voltage = 0.0;
float current = 0.0;
bool isLocked = false;
bool selectingVoltage = true;
bool lastButtonState = HIGH;
unsigned long lastButtonPress = 0;
unsigned long lastButtonRelease = 0;
bool singleClickDetected = false;
bool encoderMoved = false;
unsigned long lastUpdate = 0;
const int updateInterval = 2; // Further slow down loop execution
void setup() {
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(encoderSwitch, INPUT_PULLUP);
pinMode(motorPWM, OUTPUT);
attachInterrupt(digitalPinToInterrupt(encoderPinA), onEncoderMove, CHANGE);
}
void loop() {
if (millis() - lastUpdate > updateInterval) {
handleButtonPress();
if (encoderMoved && !isLocked) {
updateValues();
encoderMoved = false;
}
displayValues();
analogWrite(motorPWM, (int)(voltage * 51)); // Scale 0-5V to 0-255
lastUpdate = millis();
delay(50); // Added wait function to slow down loop execution
}
}
void handleButtonPress() {
bool buttonState = digitalRead(encoderSwitch);
if (buttonState == LOW && lastButtonState == HIGH) {
lastButtonPress = millis();
} else if (buttonState == HIGH && lastButtonState == LOW) {
lastButtonRelease = millis();
if (lastButtonRelease - lastButtonPress < 300) {
if (singleClickDetected && (millis() - lastButtonPress) < 600) {
isLocked = !isLocked; // Double-click: Lock/Unlock
singleClickDetected = false;
} else {
singleClickDetected = true;
}
}
}
if (singleClickDetected && (millis() - lastButtonPress) > 600) {
selectingVoltage = !selectingVoltage; // Single click: Switch selection
singleClickDetected = false;
}
lastButtonState = buttonState;
}
void onEncoderMove() {
encoderMoved = true;
}
void updateValues() {
int increment = digitalRead(encoderPinB) ? 2 : -2; // Increased sensitivity
if (selectingVoltage) {
voltage = constrain(voltage + increment * 0.05, 0.0, 5.0);
} else {
current = constrain(current + increment * 0.01, 0.0, 2.0);
}
}
void displayValues() {
u8g.firstPage();
do {
u8g.setFont(u8g_font_ncenB08r);
u8g.setPrintPos(0, 12);
if (selectingVoltage) u8g.print('>');
u8g.print("V: "); u8g.print(voltage, 2);
u8g.setPrintPos(0, 28);
if (!selectingVoltage) u8g.print('>');
u8g.print("A: "); u8g.print(current, 2);
if (isLocked) {
// Draw pixel art lock symbol on the right side of the screen
u8g.drawFrame(114, 2, 10, 12); // Lock body
u8g.drawBox(116, 0, 6, 4); // Lock shackle
}
} while (u8g.nextPage());
}Motor