pommel
October 15, 2023, 4:00pm
1
I am trying to build a 2 Item Menu controlled by a Rotary Encoder, a Button and displayed by an OLED.
So far so good. But when i add a Variable in the Second Menu "//Display & SerialMonitor" it is not changing the "menuVal". I am stuck in what ever Menu i am at the start. Which is also odd. It changes the "menuVal" each time i reset the Arduino.
I have no clue why it is doing that. As long as i am not printing any Values i am fine.
Thx!!
//RotaryEncoder
#define inputCLK 2
#define inputDT 5
int aState;
int aLastState;
//TimerFunktion
int counter = 30;
//CountDownFunktion
int countDown = 30;
//RotaryEncoderSwitch
#define inputSW 4
int sw; //SwitchValue
//Button
#define button 7
int buttonVal = 1;
int menuVal = 1;
int buttonPeriod = 100;
//SerialPrint intervall
int serialPrintPeriod = 1000;
//Screen
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//Heater
int relayPin = 6; //relayPin Pin
int HeaterButton = 4000; // Length of the HeaterControllerButton necessary to be HIGH
//millis
unsigned long timeOld;
void setup() {
Serial.begin(9600);
pinMode(inputCLK, INPUT);
pinMode(inputDT, INPUT);
pinMode(inputSW, INPUT_PULLUP); //SwitchPin
pinMode(relayPin, OUTPUT); //relayPin
digitalWrite(relayPin, HIGH); //relayPin
pinMode(button, INPUT); //ButtonPin
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
aLastState = digitalRead(inputCLK);
}
void loop() {
//buttonRead
if (millis() - timeOld >= serialPrintPeriod) {
buttonVal = digitalRead(button);
Serial.print("buttonVal ");
Serial.println(buttonVal);
Serial.print("menuVal ");
Serial.println(menuVal);
Serial.print("counter ");
Serial.println(counter);
Serial.print("CountDown ");
Serial.println(countDown);
timeOld = millis();
}
//buttonVal
if (buttonVal == 1) {
menuVal = menuVal + 1;
}
//menuVal
if (menuVal >= 3) {
menuVal = 1;
}
//Menu1+2
if (menuVal == 1) {
//Display & SerialMonitor
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.print("Timer - ");
display.print(counter);
display.println(" Minutes");
display.display();
//Rotary
aState = digitalRead(inputCLK);
if (aState != aLastState) {
if (digitalRead(inputDT) != aState) {
counter = counter - 5;
} else {
counter = counter + 5;
}
}
aLastState = aState;
//Timer Funktion
sw = digitalRead(inputSW);
if (sw == 0) {
Serial.println(counter * 60ul * 1000ul);
digitalWrite(relayPin, LOW);
delay(HeaterButton);
digitalWrite(relayPin, HIGH);
delay(counter * 60ul * 1000ul);
digitalWrite(relayPin, LOW);
delay(HeaterButton);
digitalWrite(relayPin, HIGH);
}
} else {
//Display & SerialMonitor
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.println("CountDown ");
display.print(countDown);
display.println("CountDown ");
display.display();
}
}
J-M-L
October 15, 2023, 5:07pm
2
how did you wire this button?
blh64
October 15, 2023, 5:57pm
3
You only read your button state once every second - way too slow. You should be reading it every time through loop() and debouncing it.
But then, every time through loop(), this happens:
so imagine this scenario. You press the button, it reads HIGH. buttonVal is now HIGH so you increment menuVal. Next time through loop(), it is not time to read the button but it is still HIGH so you increment menuVal again. This happens very rapidly until you get to 3 and then resets back to 1. Repeat.
Your logic needs a bit of re-work.
pommel
October 15, 2023, 6:33pm
4
to pin 7. the other side is "plus" and "negativ" + 1k ohm Resistor.
Please post a schematic. Written descriptions are always more ambiguous than a drawing. Hand drawn, photographed and posted is fine.
pommel
October 16, 2023, 7:38am
7
i debounced the button in my code.
now it works!
//RotaryEncoder
#define inputCLK 2
#define inputDT 5
int aState;
int aLastState;
//TimerFunktion
int counter = 30;
//CountDownFunktion
int countDown = 30;
//RotaryEncoderSwitch
#define inputSW 4
int sw; //SwitchValue
//Button
#define button 7
int buttonVal;
int lastButtonVal = 0;
int menuVal = 1;
int buttonPeriod = 100;
//SerialPrint intervall
int serialPrintPeriod = 1000;
//Screen
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//Heater
int relayPin = 6; //relayPin Pin
int HeaterButton = 4000; // Length of the HeaterControllerButton necessary to be HIGH
//millis
unsigned long timeOld;
void setup() {
Serial.begin(9600);
pinMode(inputCLK, INPUT);
pinMode(inputDT, INPUT);
pinMode(inputSW, INPUT_PULLUP); //SwitchPin
pinMode(relayPin, OUTPUT); //relayPin
digitalWrite(relayPin, HIGH); //relayPin
pinMode(button, INPUT); //ButtonPin
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
aLastState = digitalRead(inputCLK);
}
void loop() {
//Serial.Print
if (millis() - timeOld >= serialPrintPeriod) {
Serial.print("buttonVal ");
Serial.println(buttonVal);
Serial.print("menuVal ");
Serial.println(menuVal);
Serial.print("counter ");
Serial.println(counter);
Serial.print("CountDown ");
Serial.println(countDown);
timeOld = millis();
}
//Buttonfunktion
buttonVal = digitalRead(button);
if (lastButtonVal == 0 && buttonVal == 1) {
menuVal++;
if(menuVal >= 3){
menuVal = 1;
}
}
lastButtonVal = buttonVal;
delay(100);
//Menu1+2
if (menuVal == 1) {
//Display & SerialMonitor
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.print("Timer - ");
display.print(counter);
display.println(" Minutes");
display.display();
//Rotary
aState = digitalRead(inputCLK);
if (aState != aLastState) {
if (digitalRead(inputDT) != aState) {
counter = counter - 5;
} else {
counter = counter + 5;
}
}
aLastState = aState;
//Timer Funktion
sw = digitalRead(inputSW);
if (sw == 0) {
Serial.println(counter * 60ul * 1000ul);
digitalWrite(relayPin, LOW);
delay(HeaterButton);
digitalWrite(relayPin, HIGH);
delay(counter * 60ul * 1000ul);
digitalWrite(relayPin, LOW);
delay(HeaterButton);
digitalWrite(relayPin, HIGH);
}
} else {
//Display & SerialMonitor
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.print("CountDown ");
display.println(countDown);
display.display();
}
}
thx everyone
J-M-L
October 16, 2023, 7:58am
8
I would suggest to use libraries for the encoder and the buttons, it will make your coding easier for example with:
1 Like
blh64
October 17, 2023, 11:54am
9
An easier way to wire up your button is to connect one corner to your pin and the other corner to ground and then make the pin an INPUT_PULLUP. No need for external resistors or connecting it to power.
If you do have a 4 leg button like your image suggests, it is always best to use the diagonal corners for connection points. That way, you can rotate the button 90 degrees and it will still work fine. No chance or the wrong orientation.
1 Like
system
Closed
April 14, 2024, 11:54am
10
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.