//To modify the code so that the OLED display reverts to the last output if the encoder switch is not pressed within 5 seconds, you can implement a timer that checks the duration since the last switch press. If 5 seconds pass without a switch press, the display will revert to the last output.
//Here’s how to implement that functionality in your existing code:
//### Modified Code
//```cpp
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Encoder.h>
// OLED display settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Rotary encoder pins
#define ENCODER_PIN_A 2
#define ENCODER_PIN_B 3
#define ENCODER_SWITCH 4
Encoder myEnc(ENCODER_PIN_A, ENCODER_PIN_B);
// Output pins
#define OUTPUT1 5
#define OUTPUT2 6
#define OUTPUT3 7
// MPG status input pin
#define MPG_STATUS_PIN 8
// Variables
int currentOutput = 0;
int lastOutput = 0;
long oldPosition = -999;
unsigned long lastSwitchPressTime = 0;
bool switchPressed = false;
bool lastMpgStatus = HIGH;
unsigned long lastDisplayUpdateTime = 0;
const unsigned long DISPLAY_UPDATE_INTERVAL = 100; // Update display every 100 ms
const unsigned long SWITCH_TIMEOUT = 5000; // 5 seconds timeout
// Pulse counting
int pulseCount = 0; // Counter for pulses
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.display();
delay(2000);
display.clearDisplay();
// Set output pins
pinMode(OUTPUT1, OUTPUT);
pinMode(OUTPUT2, OUTPUT);
pinMode(OUTPUT3, OUTPUT);
// Set encoder switch pin
pinMode(ENCODER_SWITCH, INPUT_PULLUP);
// Set MPG status pin
pinMode(MPG_STATUS_PIN, INPUT_PULLUP);
// Set initial state of output pins
digitalWrite(OUTPUT1, HIGH);
digitalWrite(OUTPUT2, HIGH);
digitalWrite(OUTPUT3, HIGH);
digitalWrite(OUTPUT1, LOW);
delay(300);
digitalWrite(OUTPUT1, HIGH);
// Display initial output
displayOutput(currentOutput);
}
void loop() {
long newPosition = myEnc.read() / 4;
// Update position and pulse counting
if (newPosition != oldPosition) {
oldPosition = newPosition;
// Increment or decrement pulse count based on direction
pulseCount += (newPosition > oldPosition) ? 1 : -1;
// Change selection only after 3 pulses
if (abs(pulseCount) >= 3) {
currentOutput = (currentOutput + (pulseCount > 0 ? 1 : -1)) % 3; // Ensure non-negative output
if (currentOutput < 0) {
currentOutput += 3; // Wrap around
}
displaySelectedOutput(currentOutput);
lastSwitchPressTime = millis(); // Update last switch press time
switchPressed = false;
pulseCount = 0; // Reset pulse count after changing selection
}
}
// Handle encoder switch state
bool encoderSwitchState = digitalRead(ENCODER_SWITCH) == LOW;
if (encoderSwitchState != switchPressed) {
if (encoderSwitchState) {
lastOutput = currentOutput;
setOutputLow(currentOutput);
displayOutput(currentOutput);
lastSwitchPressTime = millis(); // Update last switch press time
}
switchPressed = encoderSwitchState;
} else if (switchPressed && (millis() - lastSwitchPressTime > SWITCH_TIMEOUT)) {
// If 5 seconds have passed since the last switch press, revert to last output
displayOutput(lastOutput);
switchPressed = false; // Reset switch pressed state
}
// Check MPG status pin state and update display based on frequency
unsigned long currentTime = millis();
if (currentTime - lastDisplayUpdateTime >= DISPLAY_UPDATE_INTERVAL) {
bool currentMpgStatus = digitalRead(MPG_STATUS_PIN);
if (currentMpgStatus != lastMpgStatus) {
lastMpgStatus = currentMpgStatus;
displayOutput(currentOutput); // Refresh display to update MPG status
}
lastDisplayUpdateTime = currentTime;
}
}
void setOutputLow(int output) {
// Turn selected output pin LOW and then HIGH with a short delay
digitalWrite(OUTPUT1 + output, LOW);
delay(300);
digitalWrite(OUTPUT1 + output, HIGH);
}
void displayOutput(int output) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(digitalRead(MPG_STATUS_PIN) == LOW ? "JOG Enabled" : "*Disabled");
display.setTextSize(2);
display.setCursor(0, 16);
display.println(outputToString(output));
display.display();
}
void displaySelectedOutput(int output) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(digitalRead(MPG_STATUS_PIN) == LOW ? "JOG Enabled" : "*Disabled");
display.setTextSize(2);
display.setCursor(0, 16);
display.println("Select");
display.setCursor(0, 32);
display.println(outputToString(output));
display.display();
}
String outputToString(int output) {
switch (output) {
case 0: return "x 1";
case 1: return "x 10";
case 2: return "x 100";
default: return "Unknown";
}
}
//```
//
//### Key Changes:
//1. **Timeout Variable**: Introduced a constant `SWITCH_TIMEOUT` set to 5000 milliseconds (5 seconds).
//2. **Last Switch Press Time**: The `lastSwitchPressTime` is updated whenever the switch is pressed or the output is changed.
//3. **Reverting Logic**: Added a check to revert the display to `lastOutput` if 5 seconds have passed since the last switch press.
//
//This implementation ensures that if the switch is not pressed within 5 seconds, the display will revert to show the last output. Adjust the timeout duration or other settings as needed for your specific application!