I have an arduino uno, with this I want to make a programme that allows me to walk through a menu on a display using a rotary encoder. Now I can't smoothly walk through the menu with the rotary encoder. I have to very quietly walk through the menu one turn at a time, if I turn a bit harder it happens to falter a bit. Also, I often have to press several times to start a programme. I have everything connected as it should be and expect this to be in the programme.
I am at a loss as to what else to do.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ezButton.h>
LiquidCrystal_I2C lcd(0x27, 16, 4);
int menu = 1;
const int RELAY_PIN = 7; // the number of the relay pin
const int RotaryCLK = 2; // CLK pin op de rotary encoder
const int RotaryDT = 3; // DT pin op de rotary encoder
const int RotarySW = 4; // SW (push button) pin op de rotary encoder
ezButton button(RotarySW); // Maak een ezButton-object voor de push-knop van de rotary encoder.
int relayState = LOW; // the current state of the relay
bool relayBlinking = false; // flag to indicate if the relay should blink
void setup() {
lcd.init();
lcd.backlight();
pinMode(RotaryCLK, INPUT_PULLUP);
pinMode(RotaryDT, INPUT_PULLUP);
pinMode(RotarySW, INPUT_PULLUP);
pinMode(RELAY_PIN, OUTPUT); // set Arduino pin to output mode
updateMenu();
Serial.begin(9600); // initialize serial
}
void loop() {
button.loop(); // MUST call the loop() function first
int encoderValue = readEncoder();
if (encoderValue > 0) {
menu++ ;
updateMenu();
delay(25);
} else if (encoderValue < 0) {
menu-= 1;
updateMenu();
delay(25);
}
if (button.isPressed()) {
executeAction();
updateMenu();
delay(2);
}
if (relayBlinking) {
relayBlinking = false; // Stop blinking
digitalWrite(RELAY_PIN, LOW); // Turn the relay off
} else {
relayBlinking = true; // Start or resume blinking
}
}
int readEncoder() {
static int encoderPos = 0;
static int lastEncoderPos = 0;
int encoderValue = 0;
static bool isClockwise = false;
int CLKState = digitalRead(RotaryCLK);
int DTState = digitalRead(RotaryDT);
if (CLKState != lastEncoderPos) {
if (DTState != CLKState) {
// Alleen verhogen als de richting kloks wijzerzin is.
if (isClockwise) {
encoderValue++;
isClockwise = false;
} else {
isClockwise = true;
}
} else {
// Alleen verlagen als de richting tegen de klokwijzers in is.
if (!isClockwise) {
encoderValue--;
isClockwise = true;
} else {
isClockwise = false;
}
}
}
lastEncoderPos = CLKState;
return encoderValue;
}
void updateMenu() {
switch (menu) {
case 0:
menu = 1;
break;
case 1:
lcd.clear();
lcd.print(">Ademhaling 1");
lcd.setCursor(0, 1);
lcd.print(" Ademhaling 2");
lcd.setCursor(0, 2);
break;
case 2:
lcd.clear();
lcd.print(">Ademhaling 2 ");
lcd.setCursor(0, 1);
lcd.print(" Ademhaling 3");
lcd.setCursor(0, 2);
break;
case 3:
lcd.clear();
lcd.print(">Ademhaling 3");
lcd.setCursor(0, 1);
lcd.print(" Ademhaling 4");
lcd.setCursor(0, 2);
break;
case 4:
lcd.clear();
lcd.print(">Ademhaling 4");
lcd.setCursor(0, 1);
break;
}
}
bool exitLoop = false; // Flag to indicate whether to exit the loop
void executeAction() {
switch (menu) {
case 1:
action1();
while (relayBlinking && !exitLoop) { // Check both relayBlinking and exitLoop conditions
digitalWrite(RELAY_PIN, HIGH);
delay(2000);
digitalWrite(RELAY_PIN, LOW);
delay(500);
// Check if the up or down button is pressed to exit the loop
if (!digitalRead(RotaryCLK) || !digitalRead(RotarySW) || !digitalRead(RotaryDT)) {
exitLoop = true; // Set the flag to exit the loop
}
}
// Reset the flag after exiting the loop
exitLoop = false;
break;
case 2:
action2();
while (relayBlinking && !exitLoop) { // Check both relayBlinking and exitLoop conditions
digitalWrite(RELAY_PIN, HIGH);
delay(500);
digitalWrite(RELAY_PIN, LOW);
delay(500);
// Check if the up or down button is pressed to exit the loop
if (!digitalRead(RotaryCLK) || !digitalRead(RotarySW) || !digitalRead(RotaryDT)) {
exitLoop = true; // Set the flag to exit the loop
}
}
// Reset the flag after exiting the loop
exitLoop = false;
break;
case 3:
action3();
while (relayBlinking && !exitLoop) { // Check both relayBlinking and exitLoop conditions
digitalWrite(RELAY_PIN, HIGH);
delay(5000);
digitalWrite(RELAY_PIN, LOW);
delay(1000);
// Check if the up or down button is pressed to exit the loop
if (!digitalRead(RotaryCLK) || !digitalRead(RotarySW) || !digitalRead(RotaryDT)) {
exitLoop = true; // Set the flag to exit the loop
}
}
// Reset the flag after exiting the loop
exitLoop = false;
break;
case 4:
action4();
while (relayBlinking && !exitLoop) { // Check both relayBlinking and exitLoop conditions
digitalWrite(RELAY_PIN, HIGH);
delay(6000);
digitalWrite(RELAY_PIN, LOW);
delay(3000);
// Check if the up or down button is pressed to exit the loop
if (!digitalRead(RotaryCLK) || !digitalRead(RotarySW) || !digitalRead(RotaryDT)) {
exitLoop = true; // Set the flag to exit the loop
}
}
// Reset the flag after exiting the loop
exitLoop = false;
}
}
void action1() {
lcd.clear();
lcd.print("2 SEC AAN");
lcd.setCursor(0, 1);
lcd.print("0.5 SEC UIT");
}
void action2() {
lcd.clear();
lcd.print("0.5 SEC AAN");
lcd.setCursor(0, 1);
lcd.print("0.5 SEC UIT");
}
void action3() {
lcd.clear();
lcd.print("5 SEC AAN");
lcd.setCursor(0, 1);
lcd.print("1 SEC UIT");
}
void action4() {
lcd.clear();
lcd.print("6 SEC AAN");
lcd.setCursor(0, 1);
lcd.print("3 SEC UIT");
}