Arduino + OLED + Encoder Simple Menu System

Easy way to control variables with one rotary encoder and OLED display.

Mar 14, 2018

104013 views

26 respects

Components and supplies

1

Rotary Encoder with Push-Button

1

OLED Expansion

1

Arduino UNO

1

Breadboard (generic)

1

Jumper wires (generic)

Project description

Code

Arduino IDE Codes

arduino

This code requires some additional libraries

Comments

Only logged in users can leave comments

Anonymous user

2 years ago

Hi Yılmaz Yurdakul!! It's a nice project you developed here. I copied your code and uploaded to arduino, same wired up, to try to understand how rotary encoders work. But when it start running, the little arrow for determining in which item you are starts changing continuously and never stops. It's like you were pressing the button from rotary a couple times per second, the whole time. Then, if I leave it pressed, it stops and the increment functionality works on the item I stay. After I stop pressing, it continues changing and changing position through items the whole time. I'm quite a newbie in this arduino-programming world, and I tried to find the "error" (in my case it is one in your code) intensively, but without success. Could you have any idea what it could be or where should I dig in. Thanks in advance and pretty cool project!! Alt

yilmazyurdakul

2 years ago

Thank you for your attention and sorry for late reply. Your problem is about debounce. That mean phisical faults about pressing. You can solve this problem with millis function but i use simple delay after digitalRead button. That mean arduino will read the button, after reading it will wait about 50 ms. This delay (about 50 - 150 ms) enough for releasing your finger. void loop() { clk = digitalRead(4); ledControl(); menuCheck(); staticMenu(); display.clearDisplay(); ------ delay(50); ----------> Magic happens here :D }

Anonymous user

2 years ago

i have same problem delay doesn't work

MarcusAurelius

2 years ago

I had same problem. You must give one resistor betwen pins (SW and +5V) on encoder. I gived 100k resistor and now is all OK You can try other resistor if you want.

Anonymous user

2 years ago

hello i tried to do the same thing but it doesn't work i have compilation problems at line 37 please help mister Yilmaz

yilmazyurdakul

2 years ago

Hmm sounds strange. can you explain that or can you send images? Did you find your oled displays i2c address?

yilmazyurdakul

2 years ago

Hello. I guess this is phisical problem or you may miss pull up resistors for encoder

Anonymous user

2 years ago

hi thanks for getting back, i fixed that problem but now i have another problem wich is the arrow keeps movin i tried with the delay to remove debouce but didni' work , the arrow always on the move

Anonymous user

2 years ago

i fixed that but i have huge white thing covering the screen

Anonymous user

2 years ago

Thanks for sharing this sketch. I was looking for a general purpose simple menu to use for my future projects and from what you show in this project I was able to produce something which meets all my requirements :-) i.e. cheap components, simple to implement and easy to wire up https://github.com/alanesq/BasicOLEDMenu It works on esp8266, esp32 and Arduino although I don't think the basic Arduino Uno is really up to it, I have to disable DEBUG (i.e. serial) otherwise it runs out of memory and the display stops working.

Anonymous user

2 years ago

Hello, I know this is a little old. But I found this menu you made and I really like its simplicity. But I can't figure out how to make it so that the set values (valA, valB, valC) don't get reset back to zero when the menu wraps back around. This menu system would be much more useful if the values ONLY change when the user turns the dial, regardless of where the cursor (carrot) is in the menu system. Any chance you could provide an example of how to modify your code to behave this way? Thanks either way for a cool menu.

Anonymous user

2 years ago

I am planning a 4 x KY-040 rotary encoder setup to interface with X-Plane to vary time-of-day, visibility , turbulence and strength of rain during the flight. One encoder no problem, but how to wire up all 4 so as be economical with wiring is causing me headaches. Any tips?

yilmazyurdakul

2 years ago

Hi everyone! I updated the code. It works better and easier to modify. If you have any problem or find something better please write here.

Anonymous user

2 years ago

Hello all I am trying to remake the menu that I will use buttons instead of the encoder. Unfortunately, the down button works for me, but I cannot change the value (buttons 6 and 7) Can anybody help me? ( I am quite a beginner with Arduino ) #include <Wire.h> #include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> #define OLED_ADDR 0x3C Adafruit_SSD1306 display(-1); int encoder0Pos = 0; const int buttonPin5 = 5; // const int buttonPin6 = 6; //left const int buttonPin7 = 7; // Righy int valA; int valB; int valC; byte clk; byte menuCount = 1; byte dir = 0; bool runState = false; void setup() { pinMode(11, OUTPUT); pinMode(9, OUTPUT); pinMode(10, OUTPUT); Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); display.display(); display.clearDisplay(); } void loop() { clk = digitalRead(5); ledControl(); menuCheck(); staticMenu(); display.clearDisplay(); delay(50); } void staticMenu() { display.setTextSize(2); display.setTextColor(WHITE); //--------------------------------- display.setTextSize(1); display.setCursor(10, 0); display.println("Value A:"); display.setCursor(60, 0); display.println(valA); display.setCursor(10, 7); display.println("Value B:"); display.setCursor(60, 7); display.println(valB); display.setCursor(10, 14); display.println("Value C:"); display.setCursor(60, 14); display.println(valC); display.setCursor(10, 21); display.println("Start:"); display.setCursor(45, 21); if (encoder0Pos > 5 && menuCount == 4) { display.println("Run!"); runState = true; } else { display.println("Idle"); runState = false; } display.setCursor(1, (menuCount * 7)-7); display.println(">"); display.display(); } void ledControl() { if (runState == true) { analogWrite(11, valA); analogWrite(9, valB); analogWrite(10, valC); } } void menuCheck() { if (clk == HIGH && menuCount < 5) { menuCount++; encoder0Pos = 0; delay(10); } if (clk == HIGH && menuCount >= 5) { menuCount = 1; delay(10); } if (menuCount == 1) { valA = encoder0Pos; } if (menuCount == 2) { valB = encoder0Pos; } if (menuCount == 3) { valC = encoder0Pos; } } void doEncoder() { if (digitalRead(buttonPin6) == HIGH) { encoder0Pos = encoder0Pos - 1; delay(10); } if (digitalRead(buttonPin7) == HIGH ) { encoder0Pos = encoder0Pos + 1; delay(10); } }

Anonymous user

2 years ago

Could be used with a button setup instead of an encoder?

yilmazyurdakul

2 years ago

Yes. you have to assign functions for each button to increase or decrease count. All menu follows this count. You can implement it by changing encoder section

Anonymous user

2 years ago

Hello everyone! Thanks a lot to Yılmaz Yurdakul for this code ^^ To whoever still struggling to make this code work after trying everything written above, you may have inverted some pins (most likely CLK and SW) so here's what worked for me: (you have to put it before the setup function) #define encoder0PinA 2 //CLK #define encoder0PinB 3 //DT #define encoderButton 4 // SW hope it helps :)

Anonymous user

2 years ago

Good

Anonymous user

2 years ago

bonjour je pourrais avoir le Cheema et les bibliothèque ?

matou173

3 years ago

bonjour je pourrais avoir le Cheema et les bibliothèque ?

Anonymous user

3 years ago

Hello all I am trying to remake the menu that I will use buttons instead of the encoder. Unfortunately, the down button works for me, but I cannot change the value (buttons 6 and 7) Can anybody help me? ( I am quite a beginner with Arduino ) #include <Wire.h> #include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> #define OLED_ADDR 0x3C Adafruit_SSD1306 display(-1); int encoder0Pos = 0; const int buttonPin5 = 5; // const int buttonPin6 = 6; //left const int buttonPin7 = 7; // Righy int valA; int valB; int valC; byte clk; byte menuCount = 1; byte dir = 0; bool runState = false; void setup() { pinMode(11, OUTPUT); pinMode(9, OUTPUT); pinMode(10, OUTPUT); Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); display.display(); display.clearDisplay(); } void loop() { clk = digitalRead(5); ledControl(); menuCheck(); staticMenu(); display.clearDisplay(); delay(50); } void staticMenu() { display.setTextSize(2); display.setTextColor(WHITE); //--------------------------------- display.setTextSize(1); display.setCursor(10, 0); display.println("Value A:"); display.setCursor(60, 0); display.println(valA); display.setCursor(10, 7); display.println("Value B:"); display.setCursor(60, 7); display.println(valB); display.setCursor(10, 14); display.println("Value C:"); display.setCursor(60, 14); display.println(valC); display.setCursor(10, 21); display.println("Start:"); display.setCursor(45, 21); if (encoder0Pos > 5 && menuCount == 4) { display.println("Run!"); runState = true; } else { display.println("Idle"); runState = false; } display.setCursor(1, (menuCount * 7)-7); display.println(">"); display.display(); } void ledControl() { if (runState == true) { analogWrite(11, valA); analogWrite(9, valB); analogWrite(10, valC); } } void menuCheck() { if (clk == HIGH && menuCount < 5) { menuCount++; encoder0Pos = 0; delay(10); } if (clk == HIGH && menuCount >= 5) { menuCount = 1; delay(10); } if (menuCount == 1) { valA = encoder0Pos; } if (menuCount == 2) { valB = encoder0Pos; } if (menuCount == 3) { valC = encoder0Pos; } } void doEncoder() { if (digitalRead(buttonPin6) == HIGH) { encoder0Pos = encoder0Pos - 1; delay(10); } if (digitalRead(buttonPin7) == HIGH ) { encoder0Pos = encoder0Pos + 1; delay(10); } }

Anonymous user

3 years ago

Hello everyone! Thanks a lot to Yılmaz Yurdakul for this code ^^ To whoever still struggling to make this code work after trying everything written above, you may have inverted some pins (most likely CLK and SW) so here's what worked for me: (you have to put it before the setup function) #define encoder0PinA 2 //CLK #define encoder0PinB 3 //DT #define encoderButton 4 // SW hope it helps :)

Anonymous user

4 years ago

Good

Anonymous user

4 years ago

I am planning a 4 x KY-040 rotary encoder setup to interface with X-Plane to vary time-of-day, visibility , turbulence and strength of rain during the flight. One encoder no problem, but how to wire up all 4 so as be economical with wiring is causing me headaches. Any tips?

Anonymous user

4 years ago

Could be used with a button setup instead of an encoder?

yilmazyurdakul

2 years ago

Yes. you have to assign functions for each button to increase or decrease count. All menu follows this count. You can implement it by changing encoder section

Anonymous user

4 years ago

Thanks for sharing this sketch. I was looking for a general purpose simple menu to use for my future projects and from what you show in this project I was able to produce something which meets all my requirements :-) i.e. cheap components, simple to implement and easy to wire up https://github.com/alanesq/BasicOLEDMenu It works on esp8266, esp32 and Arduino although I don't think the basic Arduino Uno is really up to it, I have to disable DEBUG (i.e. serial) otherwise it runs out of memory and the display stops working.

Anonymous user

4 years ago

Hello, I know this is a little old. But I found this menu you made and I really like its simplicity. But I can't figure out how to make it so that the set values (valA, valB, valC) don't get reset back to zero when the menu wraps back around. This menu system would be much more useful if the values ONLY change when the user turns the dial, regardless of where the cursor (carrot) is in the menu system. Any chance you could provide an example of how to modify your code to behave this way? Thanks either way for a cool menu.

bitfogav

6 years ago

Great project, But I also had some issues getting the Encoder to work, my Encoder doesn't have any external pull-up resistors connected to the lines so I enabled the internal pull-ups on the Arduino. My Oled also showed the same issue as user "alt" in the comments. I added the following lines in the setup routine: pinMode(encoder0PinA, INPUT); digitalWrite(encoder0PinA, HIGH); // turn on pull-up resistor pinMode(encoder0PinB, INPUT); digitalWrite(encoder0PinB, HIGH); // turn on pull-up resistor As for the encoder button, I added this line of code before the void setup: #define encoderButton 4 added this to the void setup routine: pinMode(encoderButton, INPUT); digitalWrite(encoderButton, HIGH); // turn on pull-up resistor and changed the main void loop from: clk = digitalRead(4); to clk = digitalRead(encoderButton); All now works perfectly :)

yilmazyurdakul

6 years ago

Hi everyone! I updated the code. It works better and easier to modify. If you have any problem or find something better please write here.

Anonymous user

6 years ago

hello i tried to do the same thing but it doesn't work i have compilation problems at line 37 please help mister Yilmaz

Anonymous user

2 years ago

hi thanks for getting back, i fixed that problem but now i have another problem wich is the arrow keeps movin i tried with the delay to remove debouce but didni' work , the arrow always on the move

Anonymous user

2 years ago

i fixed that but i have huge white thing covering the screen

yilmazyurdakul

2 years ago

Hmm sounds strange. can you explain that or can you send images? Did you find your oled displays i2c address?

yilmazyurdakul

2 years ago

Hello. I guess this is phisical problem or you may miss pull up resistors for encoder

Anonymous user

7 years ago

Hi Yılmaz Yurdakul!! It's a nice project you developed here. I copied your code and uploaded to arduino, same wired up, to try to understand how rotary encoders work. But when it start running, the little arrow for determining in which item you are starts changing continuously and never stops. It's like you were pressing the button from rotary a couple times per second, the whole time. Then, if I leave it pressed, it stops and the increment functionality works on the item I stay. After I stop pressing, it continues changing and changing position through items the whole time. I'm quite a newbie in this arduino-programming world, and I tried to find the "error" (in my case it is one in your code) intensively, but without success. Could you have any idea what it could be or where should I dig in. Thanks in advance and pretty cool project!! Alt

Anonymous user

2 years ago

i have same problem delay doesn't work

Anonymous user

2 years ago

I had same problem. You must give one resistor betwen pins (SW and +5V) on encoder. I gived 100k resistor and now is all OK You can try other resistor if you want.

yilmazyurdakul

2 years ago

Thank you for your attention and sorry for late reply. Your problem is about debounce. That mean phisical faults about pressing. You can solve this problem with millis function but i use simple delay after digitalRead button. That mean arduino will read the button, after reading it will wait about 50 ms. This delay (about 50 - 150 ms) enough for releasing your finger. void loop() { clk = digitalRead(4); ledControl(); menuCheck(); staticMenu(); display.clearDisplay(); ------ delay(50); ----------> Magic happens here :D }

yilmazyurdakul

5 Followers

8 Projects

26

39