Как остановить цикл "Выбор позиции в меню". ENKODER_OLED_MENU
- Войдите на сайт для отправки комментариев
Чт, 09/03/2017 - 13:47
Коплектующие:
1. Энкодер с кнопкой от автомагнитоллы
2. OLED дисплей модуль 0.96" I2C 128x64
3. Arduino Nano
В нижеприведенном коде при вызове энкодером функции
void Menu()
курсор бегает по кругу, не могу остановить.
#include <OLED_I2C.h>
OLED myOLED(SDA, SCL, 1);
extern uint8_t SmallFont[];
volatile int encoderPin1 = 2;
volatile int encoderPin2 = 3;
volatile int MSB ;
volatile int LSB ;
volatile int encoded = 0 ;
volatile int lastEncoded = 0;
volatile int sum ;
volatile int i = 0;
volatile int a = 0;
volatile int b = 0;
volatile int c = 0;
volatile int encoderValue = 0;
void setup(){
Serial.begin (9600);
myOLED.begin();
myOLED.clrScr();
myOLED.setFont(SmallFont);
pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);
pinMode(4, INPUT); // Kнопка "Mеню"
pinMode(13, OUTPUT);
digitalWrite(encoderPin1, HIGH);
digitalWrite(encoderPin2, HIGH);
digitalWrite(4, HIGH);
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
}
void loop(){
MainScreen();
if(!digitalRead(4)){
delay(200);Menu();
}
if(c==1){
c=0;Serial.println(encoderValue);
}
}
void updateEncoder(){
MSB = digitalRead(encoderPin1);
LSB = digitalRead(encoderPin2);
encoded = (MSB << 1) |LSB;
sum = (lastEncoded << 2) | encoded;
if(encoded==0b0000){
if(a==0){
encoderValue = encoderValue+i; c=1; a=1; b=0;
}
}
if(encoded==0b0011){
if(b==0){
encoderValue = encoderValue+i; c=1; b=1; a=0;
}
}
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011){
digitalWrite(13, HIGH);
i=1;
}
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000){
digitalWrite(13, LOW);
i=-1;
}
lastEncoded = encoded;
}
void MainScreen() {
myOLED.clrScr();
myOLED.print("MainScreen", CENTER, 20);
myOLED.printNumI(encoderValue, CENTER, 40);
myOLED.update();
}
void Menu(){
byte menuPos = 1;
for (i=0; i<=500; i++){
//***************************** Выбор позиции в меню ***********************
if(!encoded --){
menuPos = menuPos + 1;
}
if(menuPos > 4){
menuPos = 1;
}
if(!encoded ++){
menuPos = menuPos - 1;
}
if(menuPos < 1){
menuPos = 4;
}
switch(menuPos){
//*************** устанавливаем курсор согласно позиции в меню ***************
case 1:
myOLED.clrScr();
myOLED.print(">", 0, 0);
myOLED.print("Alarm", 10, 0);
myOLED.print("Time", 10, 10);
myOLED.print("Setting", 10, 20);
myOLED.print("back", 10, 40);
if (menuPos == 1 && !digitalRead(4)) MenuSetAlarm();
break;
case 2:
myOLED.clrScr();
myOLED.print(">", 0, 10);
myOLED.print("Alarm", 10, 0);
myOLED.print("Time", 10, 10);
myOLED.print("Setting", 10, 20);
myOLED.print("back", 10, 40);
if (menuPos == 2 && !digitalRead(4)) MenuSetTime();
break;
case 3:
myOLED.clrScr();
myOLED.print(">", 0, 20);
myOLED.print("Alarm", 10, 0);
myOLED.print("Time", 10, 10);
myOLED.print("Setting", 10, 20);
myOLED.print("back", 10, 40);
if (menuPos == 3 && !digitalRead(4)) MenuSetting();
break;
case 4:
myOLED.clrScr();
myOLED.print(">", 0, 40);
myOLED.print("Alarm", 10, 0);
myOLED.print("Time", 10, 10);
myOLED.print("Setting", 10, 20);
myOLED.print("back", 10, 40);
}
myOLED.update();
if (!digitalRead(4) && menuPos == 4){break;}
}
delay (150);
}
void MenuSetTime(){
for (i=0; i<=500; i++){
myOLED.clrScr();
myOLED.print("MenuSetTime", CENTER, 20);
myOLED.update();
if(!digitalRead(4)){break;}
}
}
void MenuSetAlarm(){
for (i=0; i<=500; i++){
myOLED.clrScr();
myOLED.print("MenuSetAlarm", CENTER, 20);
myOLED.update();
if(!digitalRead(4)){break;}
}
}
void MenuSetting(){
for (i=0; i<=500; i++){
myOLED.clrScr();
myOLED.print("MenuSetting", CENTER, 20);
myOLED.update();
if(!digitalRead(4)){break;}
}
}
Сама функция энкодера отрабатывает отлично, кстати взято из этого форума благо добрым людям.
Тут уважаемый один форумчанин объяснил на пальцах цитирую:
меню с энкодером это тоже самое что и меню с кнопками, просто когда энкодер вращается в лево присваиваем какой нибудь bool left=true, когда вправо bool right=true. Когда он не двигается все ЛОЖЬ. это будет аналогично нажатию на кнопки left и rigtht.
конец цитаты.
Но я так и не смог понять как это правильно оформить в коде.
Прошу Вас, может кто знает.
Как при однократном такте поворота ручки энкодера, в лево или в право, курсор в коде переходил на одну позицию.
Пожайлуста поправте меня в коде!
я делаю так
val = encoded;
if(val > val_old)
{
.......
val_old = val;
}
Помедленней я записываю!
Поясните - что, куда, в место чего, в какой строке и функции?
Спасибо разобрался.
Тема закрыта!