//To modify the code so that if the previous state is `OUTPUT2` or `OUTPUT1`, it does not change the output states when the `Z_MINUS_PIN` goes low, we can add a conditional check for those states. Here's the updated code:
#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
// Z minus input pin
#define Z_MINUS_PIN 9
// Variables
int currentOutput = 0;
int lastOutput = 0;
long oldPosition = -999;
unsigned long lastSwitchPressTime = 0;
bool switchPressed = false;
bool lastMpgStatus = HIGH;
bool lastZMinusState = HIGH; // Last state of the Z minus input
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 Z minus input pin
pinMode(Z_MINUS_PIN, INPUT_PULLUP); // Assuming pull-up resistor
// Set initial state of output pins
digitalWrite(OUTPUT1, HIGH);
digitalWrite(OUTPUT2, HIGH);
digitalWrite(OUTPUT3, HIGH);
// Turn selected output pin LOW and then HIGH with a short delay
digitalWrite(OUTPUT1, LOW);
delay(300);
digitalWrite(OUTPUT1, HIGH);
// Display initial output
displayOutput(currentOutput);
}
void loop() {
long newPosition = myEnc.read() / 4;
// Update position and display if the encoder position changes
if (newPosition != oldPosition) {
oldPosition = newPosition;
currentOutput = (newPosition % 3 + 3) % 3; // Ensure non-negative output
displaySelectedOutput(currentOutput);
lastSwitchPressTime = millis();
switchPressed = false;
}
// Handle encoder switch state
bool encoderSwitchState = digitalRead(ENCODER_SWITCH) == LOW;
if (encoderSwitchState != switchPressed) {
if (encoderSwitchState) {
lastOutput = currentOutput;
setOutputLow(currentOutput);
displayOutput(currentOutput);
}
switchPressed = encoderSwitchState;
} else if (switchPressed && (millis() - lastSwitchPressTime > 1000)) {
displayOutput(lastOutput);
switchPressed = false;
}
// Check MPG status pin state and update display if it changes
bool currentMpgStatus = digitalRead(MPG_STATUS_PIN);
if (currentMpgStatus != lastMpgStatus) {
lastMpgStatus = currentMpgStatus;
displayOutput(currentOutput); // Refresh display to update MPG status
}
// Check Z minus input state
bool currentZMinusState = digitalRead(Z_MINUS_PIN);
if (currentZMinusState != lastZMinusState) {
lastZMinusState = currentZMinusState;
if (currentZMinusState == LOW) { // Z minus input goes low
// Momentarily set OUTPUT2 low
digitalWrite(OUTPUT2, LOW);
delay(300); // Keep it low for 300 milliseconds
digitalWrite(OUTPUT2, HIGH);
// Only change output if lastOutput is neither OUTPUT1 nor OUTPUT2
if (lastOutput == 2) { // If the last output was OUTPUT3 (index 2)
lastOutput = currentOutput; // Save the current state
currentOutput = 1; // Change to output 2 (index 1)
displayOutput(currentOutput);
}
} else { // Z minus input goes high
// Momentarily set previous output low only if it is OUTPUT1 or OUTPUT2
if (lastOutput == 0 || lastOutput == 1) {
digitalWrite(OUTPUT1 + lastOutput, LOW);
delay(300); // Keep it low for 300 milliseconds
digitalWrite(OUTPUT1 + lastOutput, HIGH);
}
currentOutput = lastOutput; // Restore previous state
displayOutput(currentOutput);
}
}
}
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. **Conditional Check for Output States:**
// - In the `loop()` function, when handling the low state of `Z_MINUS_PIN`, it now checks if `lastOutput` is `0` (OUTPUT1) or `1` (OUTPUT2). If it is, it does not change the output state.
// - When `Z_MINUS_PIN` goes high, it sets the previous output low momentarily only if `lastOutput` is `0` or `1`.
//### Behavior:
//- If the previous state is `OUTPUT1` or `OUTPUT2`, the output state will not change when `Z_MINUS_PIN` goes low.
//- When `Z_MINUS_PIN` goes high, the previous output will only be set low if it was `OUTPUT1` or `OUTPUT2`.
//This code should meet your requirements as specified. Make sure to test it with your hardware setup!