Здравствуете подскажите пожалуйста где я ошибся? Никак не могу запустить из меню в Режим работы Нажимаю кнопку видно что срабатывает но тут же обратно в меню лезет! Код (C++): #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <Bounce.h> #define autoOFF 10 // кол-во секунд через которое выключается подсветка дисплея при бездействии LiquidCrystal_I2C lcd(0x20, 16, 2); // установка I2C адреса LCD в 0x27, а также указываем что 16 символов, 2 строки //int pos = 0; // текущая позиция (0 - установка, 1 - работа) int interval = 0; unsigned long currentTime; unsigned long TimeLCDOff; int m = 0; // переменная для экранов меню int p1 = 0; int p2 = 0; int p3 = 0; #define BL 3 #define plusPin 6 #define minusPin 10 #define upPin 8 #define downPin 7 #define EterPin 12 #define ledPin 13 boolean buttonPlusWas = true; boolean buttonMinusWas = true; boolean buttonUpWas = true; boolean buttonDownWas = true; boolean buttonEterWas = true; boolean working = false; //boolean ledEnabled = false; void setup() { pinMode(plusPin, INPUT); pinMode(minusPin, INPUT); pinMode(upPin, INPUT); pinMode(downPin, INPUT); pinMode(EterPin, INPUT); pinMode(BL, OUTPUT); pinMode(ledPin, OUTPUT); lcd.init(); // инициализация LCD lcd.backlight(); // включаем подсветку for (int i = 0; i <= 255; i++) { analogWrite(BL, i); delay(5); } delay (500); } void loop() { boolean buttonPlusIs = digitalRead(plusPin); boolean buttonMinusIs = digitalRead(minusPin); boolean buttonUpIs = digitalRead(upPin); boolean buttonDownIs = digitalRead(downPin); boolean buttonEterIs = digitalRead(EterPin); //================================================ if (working == false) { if (buttonEterWas && !buttonEterIs) { delay(10); buttonEterIs = digitalRead(upPin); if (!buttonEterIs && m == 0) { lcd.backlight(); TimeLCDOff = currentTime; working = true; } } //Обработка нажатия кнопки меню if (buttonPlusWas && !buttonPlusIs) { delay(10); buttonPlusIs = digitalRead(plusPin); if (!buttonPlusIs) { lcd.backlight(); TimeLCDOff = currentTime; m++; if (m > 3) { m = 0; } delay(100); lcd.clear(); menu(); } } //Обработка нажатия кнопки назад if (buttonMinusWas && !buttonMinusIs) { delay(10); buttonMinusIs = digitalRead(minusPin); if (!buttonMinusIs) { lcd.backlight(); TimeLCDOff = currentTime; m--; if (m < 0) { m = 3; } delay(100); lcd.clear(); menu(); } } // Обработка нажатия для параметра p1 + if (buttonUpWas && !buttonUpIs) { delay(10); buttonUpIs = digitalRead(upPin); if (!buttonUpIs && m == 1) { lcd.backlight(); TimeLCDOff = currentTime; p1++; if (p1 > 100) { p1 = 0; } delay (100); lcd.setCursor(5, 1);//очистка предыдущего параметра lcd.print(" "); menu(); } } // Обработка нажатия для параметра p1 - if (buttonDownWas && !buttonDownIs) { delay(10); buttonDownIs = digitalRead(downPin); if (!buttonDownIs && m == 1) { lcd.backlight(); TimeLCDOff = currentTime; p1--; if (p1 < 0) { p1 = 100; } delay (100); lcd.setCursor(5, 1);//очистка предыдущего параметра lcd.print(" "); menu(); } } // Обработка нажатия для параметра р2 + if (buttonUpWas && !buttonUpIs) { delay(10); buttonUpIs = digitalRead(upPin); if (!buttonUpIs && m == 2) { lcd.backlight(); TimeLCDOff = currentTime; p2++; if (p2 > 10) { p2 = 0; } delay (100); lcd.setCursor(5, 1);//очистка предыдущего параметра lcd.print(" "); menu(); } } // Обработка нажатия для параметра р2 - if (buttonDownWas && !buttonDownIs) { delay(10); buttonDownIs = digitalRead(downPin); if (!buttonDownIs && m == 2) { lcd.backlight(); TimeLCDOff = currentTime; p2--; if (p2 < 0) { p2 = 10; } delay (100); lcd.setCursor(5, 1); lcd.print(" "); menu(); } } // Обработка нажатия для параметра р3 + if (buttonUpWas && !buttonUpIs) { delay(10); buttonUpIs = digitalRead(upPin); if (!buttonUpIs && m == 3) { lcd.backlight(); TimeLCDOff = currentTime; // ledEnabled = !ledEnabled; // digitalWrite(ledPin, ledEnabled); // p3 = ledEnabled; menu(); } } // Обработка нажатия для параметра р3 - if (buttonDownWas && !buttonDownIs) { delay(10); buttonDownIs = digitalRead(downPin); if (!buttonDownIs && m == 3) { lcd.backlight(); TimeLCDOff = currentTime; menu(); } } } //======================================================================= currentTime = millis(); // считываем время, прошедшее с момента запуска программы if (working == true) { show_work(); digitalWrite(ledPin, HIGH); // моргнем встроенным LED delay(100); digitalWrite(ledPin, LOW); //================================================== if (buttonEterWas && !buttonEterIs) { delay(10); buttonEterIs = digitalRead(upPin); if (!buttonEterIs && working == true )//&& m == 0 { lcd.backlight(); // включаем подсветку TimeLCDOff = currentTime; // в TimeLCDOff записываем новое значение m = 0; working = false; // прерываем режим "работа" menu(); // если были в рабочем режиме, то прерываем } } } if (currentTime >= (TimeLCDOff + (autoOFF * 1000))) { lcd.noBacklight(); } buttonUpWas = buttonUpIs; buttonDownWas = buttonDownIs; buttonPlusWas = buttonPlusIs; buttonMinusWas = buttonMinusIs; buttonEterWas = buttonEterIs; //end loop } //================================================================== void menu() { working = false; if (m == 0) { lcd.setCursor(0, 0); lcd.print( "Main Menu" ); } else if (m == 1) { lcd.setCursor(0, 0); lcd.print( "Parametr-1" ); lcd.setCursor(0, 1); lcd.print( "P1 = " ); lcd.print(p1); } else if (m == 2) { lcd.setCursor(0, 0); lcd.print( "Parametr-2" ); lcd.setCursor(0, 1); lcd.print( "P2 = " ); lcd.print(p2); } else if (m == 3) { lcd.setCursor(0, 0); lcd.print( "LED Control" ); lcd.setCursor(0, 1); lcd.print( "LED = " ); lcd.print(p3); } } void show_work() { lcd.clear(); lcd.setCursor(1, 0); lcd.print("work"); // lcd.setCursor(4, 1); //lcd.print("L=setup R=start"); // m = 0; working = true; }
Попытался заменить кнопку входа в меню заработал но мне надо чтоб и режим меню и режим работы были с одной кнопки.
я лично не понимаю вашей логики boolean buttonEterIs = digitalRead(EterPin); объявили её как кнопку ентер хорошо но дальше buttonEterIs = digitalRead(upPin); уже в эту переменную записываете значение с другой кнопки...
Уважаемый lerik2703 Если вам не трудно подскажите пожалуйста как в этом примере выполнить длинное нажатие кнопки То есть короткое нажатие значение переменной изменяется на единицу а при нажатии и удерживании нужно что бы переменная начала быстро менять значение. Помогите пожалуйста!
Что то не получается найти. Примерно понимаю что нужно завести еще один таймер и по нему следить сколько времени нажата кнопка но вот подавление дребезга сбивает с толку единица прибавляться после отпускания кнопки. Буду очень признателен если поможете!
как вариант могу вам предложить библиотеку Bounce2 https://github.com/thomasfredericks/Bounce2 смотрите пример retrigger
Да но хотелось бы без использования библиотек Да и на будущее был бы пример. Я уже пытался использовать Bounce Но без нее остальной код лучше работает поэтому она сейчас закомментирована. используются только три библиотеки с ними код дружит хорошо. #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <EEPROM.h>
После нажатия заполняется переменная с милисекундами с флагом "пока не залипло". Пока кнопка нажата переменная сравнивается с миллис + сколько там надо, при превышении устанавливается флаг "наконецто залипло" и понеслось быстрое нажатие. Если не понятно как это написать на С, я помогу, но чуть позже.
Спасибо! То есть в моем случае после этих строк? if(buttonPlusWas &&!buttonPlusIs) { delay(10); buttonPlusIs = digitalRead(plusPin); Вставляем flagTime = millis(); if (flagTime >=buttonPlusIs+1000) Или я не правильно вас понял?
Код (C++): #define BUTTON_PIN 2 void setup() { Serial.begin(115200); pinMode(BUTTON_PIN, INPUT_PULLUP); // подключаем кнопку через внутренний резистор } void loop() { static int s = 0; s = isButtonStatus(s, BUTTON_PIN, false); Serial.println(s) ; } int isButtonStatus(int n , int pin, bool sign ) { const int longTimeClick = 500 ; const int bounce_interval_millis = 10; static bool Click_One = false; static bool button_state = false; // флаг предыдущего состояния кнопки static bool button_newState; static unsigned long previous_millis; // переменная обработки временного интервала static unsigned long lastSwitchTime ; if ((millis() - previous_millis) >= bounce_interval_millis) { button_newState = !digitalRead(pin); if ( !Click_One and button_newState ) { previous_millis = millis(); Click_One = !Click_One; } else if (button_state != button_newState) button_state = button_newState; if (!button_newState and Click_One) { Click_One = button_newState; button_state = button_newState; n = ((sign) ? (++n) : (--n)); } } if (button_state) { lastSwitchTime = previous_millis; if ((millis() - lastSwitchTime) >= longTimeClick) { //delay(100);//???? n = ((sign) ? (++n) : (--n)); } } return n; } попробуйте такой вариант я постарался более универсальней функцию сделать
Не получилось Код (C++): if (buttonUpWas && !buttonUpIs) { flagTime = millis(); if (flagTime >= buttonPlusIs + 1000) { if (!buttonUpIs && m == 1) { lcd.backlight(); TimeLCDOff = currentTime; p1++; if (p1 > 100) { p1 = 0; } delay (100); lcd.setCursor(5, 1);//очистка предыдущего параметра lcd.print(" "); menu(); } } delay(10); buttonUpIs = digitalRead(upPin); if (!buttonUpIs && m == 1) { lcd.backlight(); TimeLCDOff = currentTime; p1++; if (p1 > 100) { p1 = 0; } delay (100); lcd.setCursor(5, 1);//очистка предыдущего параметра lcd.print(" "); menu(); } }
Да!! Здесь мне точно разбираться на полгода! Почему то при загрузке несколько секунд стоит ноль а потом переменная начинает сама расти как только нажму кнопку останавливается отпущу снова растет.
Что то я не правильно пишу у меня получается только в течении секунды после отпускания кнопки переменная сама увеличивается успевает на на 3 единицы прибавиться
ну да особенности подключения кнопки)))забыл указать это сразу ,кстати ,последний параметр это какое действие нужно выполнить прибавить или отнять.
Одна кнопка прибавляет вторая наоборот. Спасибо вам но навряд ли у меня получиться применить ваш код не дорос я еще чтоб в нем разобраться полностью Я попытаюсь что либо попроще если не получиться оставлю все как есть или на полку кину до лучших времен!