Не меняется переменная
- Войдите на сайт для отправки комментариев
Сб, 17/08/2019 - 21:03
День (вечер-ночь-утро) добрый уважаемое сообщество!
Делаю мини-комп на велик (с кучей всего)
Теперь собственно вопрос.
- при зажатии клавиши переменная режима (mode) скачет туда-сюда
- не изменяется переменная меню экрана (screen), кнопки точно рабочие)
#include <GyverTimer.h>
GTimer_ms blinc;
GTimer_ms stopl;
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS1302, 3, 9, 4);
#include <GyverButton.h>
GButton butt_r(10); //кнопка право
GButton butt_l(11); //кнопка лево
GButton butt_c(12); //кнопка центр
GButton butt_s(A2); //кнопка stop
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include <EEPROM.h>
unsigned long lastturn, time_press; //переменные хранения времени
float SPEED; //переменная хранения скорости в виде десятичной дроби
float DIST; //переменная хранения расстояния в виде десятичной дроби
float w_length = 2.060; //длина окружности колеса в метрах
byte light = 0; //режим работы габаритов
int screen = 0; //режим работы дисплея
bool mode = 0; //режим работы кнопок
bool alarm = 0; // сигнализация
void setup() {
// настройки пинов
pinMode(5, OUTPUT); //свет середина
pinMode(6, OUTPUT); //свет право
pinMode(7, OUTPUT); //свет центр
pinMode(8, OUTPUT); //свет лево
pinMode(13, OUTPUT); //свет лево контрол
pinMode(A0, OUTPUT); //свет центр контрол
pinMode(A1, OUTPUT); //свет право контрол
pinMode(A3, OUTPUT); //зуммер
time.begin();
lcd.init();
lcd.init();
lcd.backlight();
blinc.setInterval(777);
stopl.setInterval(7777);
Serial.begin(9600); //открыть порт
attachInterrupt(0, sens, RISING); //подключить прерывание на 2 пин при повышении сигнала
//--------------
DIST = (float)EEPROM.read(0) / 10.0; //вспоминаем пройденное расстояние при запуске системы (деление на 10 нужно для сохранения десятых долей расстояния, см. запись)
}
void sens() {
if (millis() - lastturn > 80) { //защита от случайных измерений (основано на том, что велосипед не будет ехать быстрее 120 кмч)
SPEED = w_length / ((float)(millis() - lastturn) / 1000) * 3.6; //расчет скорости, км/ч
lastturn = millis(); //запомнить время последнего оборота
DIST = DIST + w_length / 1000; //прибавляем длину колеса к дистанции при каждом обороте оного
}
}
void loop() {
// отработка кнопок
Serial.print(screen);
Serial.println(mode);
butt_l.tick();
butt_c.tick();
butt_r.tick();
butt_s.tick();
if (butt_l.isClick() && mode == 0) light = 1;
if (butt_l.isClick() && mode == 1) {screen--;}
if (butt_r.isClick() && mode == 0) light = 2;
if (butt_r.isClick() && mode == 1) {screen++;}
if (butt_c.isClick() && mode == 0) light = 3;
if (butt_c.isDouble() && mode == 0) light = 4;
if (butt_c.isHold()) mode = !mode;
if (butt_s.isPress()) light = 5;
if (butt_s.isRelease()) light = 0;
// отработка кнопок
// отработка габаритов
switch (light) {
case 0: off();
break;
case 1: left();
break;
case 2: right();
break;
case 3: stop_1();
break;
case 4: stop_2();
break;
}
// отработка экрана
switch (screen) {
case 0: def();
break;
case 1: date();
break;
case 2: max_s();
break;
case 3: max_d();
break;
case 4: alrm();
break;
}
}
// функции габаритов
void off() {
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (7, 0);
digitalWrite (8, 0);
digitalWrite (A0, 0);
digitalWrite (A1, 0);
digitalWrite (13, 0);
}
void left() {
digitalWrite (8, 1);
digitalWrite (7, 1);
digitalWrite (13, 1);
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (A0, 0);
digitalWrite (A1, 0);
if (blinc.isReady()) {
digitalWrite (8, !digitalRead(8));
}
if (butt_l.isDouble()) light = 0;
}
void right() {
digitalWrite (6, 1);
digitalWrite (7, 1);
digitalWrite (A1, 1);
digitalWrite (5, 0);;
digitalWrite (8, 0);
digitalWrite (A0, 0);
digitalWrite (13, 0);
if (blinc.isReady()) {
digitalWrite (6, !digitalRead(6));
}
if (butt_r.isDouble()) light = 0;
}
void stop_1() {
digitalWrite (8, 1);
digitalWrite (6, 1);
digitalWrite (5, 0);
digitalWrite (7, 1);
digitalWrite (A0, 1);
digitalWrite (A1, 0);
digitalWrite (13, 0);
if (butt_c.isTriple()) light = 0;
}
void stop_2() {
digitalWrite (5, 0);
digitalWrite (7, 0);
digitalWrite (A1, 0);
digitalWrite (13, 0);
if (blinc.isReady()) {
digitalWrite (8, !digitalRead(8));
digitalWrite (6, !digitalRead(6));
digitalWrite (A0, !digitalRead(A0));
}
if (butt_c.isTriple()) light = 0;
}
// функции экрана
void def() {
lcd.setCursor(2, 1);
lcd.print(time.gettime("H:i:s D"));
}
void date() {
lcd.setCursor(3, 0);
lcd.print(time.gettime("d-m-Y"));
lcd.setCursor(2, 1);
lcd.print(time.gettime("H:i:s D"));
}
void max_s() {
lcd.setCursor(3, 0);
lcd.print("MAX SPEED");
}
void max_d() {
lcd.setCursor(3, 0);
lcd.print("MAX DIST");
}
void alrm() {
lcd.setCursor(3, 0);
lcd.print("ALARM");
lcd.setCursor(2, 1);
lcd.print(alarm);
if (butt_c.isClick()) alarm = !alarm;
}
Да хрен его знает, что там в библиотеке гайвера накручено.
но с той же библиотекой переменная (light), отвечающая за габаритку, работает нормально
но с той же библиотекой переменная (light), отвечающая за габаритку, работает нормально
Darrel , даже не надейтесь, копаться в коде Гайвера тут считается за западло,
при зажатии клавиши переменная режима (mode) скачет туда-сюда
Типа нажал и держишь и она срабатывает то нажата, то не нажата. Такое поведение?
но с той же библиотекой переменная (light), отвечающая за габаритку, работает нормально
Мне кажется, что проблемя все-таки у меня в коде. какая-то глупая ошибка новичка.
при зажатии клавиши переменная режима (mode) скачет туда-сюда
Типа нажал и держишь и она срабатывает то нажата, то не нажата. Такое поведение?
нет, при удерживании переменная менятся 0-1, а когда отпускаю, остается в последнем значении
А как должна?
А как должна?
Поменятся один раз.
при зажатии клавиши переменная режима (mode) скачет туда-сюда
Типа нажал и держишь и она срабатывает то нажата, то не нажата. Такое поведение?
нет, при удерживании переменная менятся 0-1, а когда отпускаю, остается в последнем значении
Я о том и говорю. Это хреновая реализация программного подавления дребезга контактов в библиотеке.
Возьмите для кнопок титановый велосипед с нашего форума. Проблемы уйдут.
при зажатии клавиши переменная режима (mode) скачет туда-сюда
Типа нажал и держишь и она срабатывает то нажата, то не нажата. Такое поведение?
нет, при удерживании переменная менятся 0-1, а когда отпускаю, остается в последнем значении
Я о том и говорю. Это хреновая реализация программного подавления дребезга контактов в библиотеке.
Но ведь все остальное работает как часы!
Но ведь все остальное работает как часы!
Меньше надо бузову слушать.
Возьмите для кнопок титановый велосипед с нашего форума. Проблемы уйдут.
Я новичек, очень громоздкий код. На три кнопки, на каждой минимум два варианта нажатия, на одной четыре.
Но ведь все остальное работает как часы!
Меньше надо бузову слушать.
БГ и Аквариум, это все что я могу себе позволить)
Возьмите для кнопок титановый велосипед с нашего форума. Проблемы уйдут.
Чисто ради научного интереса, привесил на одну кнопку "титановый велосипед"
Все так же дохлый штиль и дохлая чайка на дохлом горизонте.
Хоть бы код приводили что и как делается....
какая-то глупая ошибка новичка.
Так и есть. Ошибка новичка проявилась в выборе библиотеки.
Я новичек, очень громоздкий код.
А кто ж его такой написал? Пиши короче и компактнее.
Но ведь все остальное работает как часы!
Ну, раз так, то тебе остётся только одно - https://community.alexgyver.ru
Только там тебе могут помочь.
Кстати, ТС запостил это же на ардуино.юа, и получил ответ
Гайвер?!
В сад! Все в сад!
https://www.youtube.com/watch?v=ix1YNPgWjKk
Парень, не сомневайся, тоже самое тебе скажут и на амперке. Единственное место, где тебе могут помочь - это https://community.alexgyver.ru
Ну значит переменную отвечающую за номер кнопки надо сразу обнулять после использования.
Хоть бы код приводили что и как делается....
#include <GyverTimer.h> GTimer_ms blinc; GTimer_ms stopl; #include <iarduino_RTC.h> iarduino_RTC time(RTC_DS1302, 3, 9, 4); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // класс титановый велосипед для тактовой кнопки. // фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick), нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени. class BUTTON { public: //================================================================ static const byte bounce_ = 50; // длительность отслеживания дребезга. static const byte doubleclick_ = 200; // длительность отслеживания двойного клика. static const unsigned long timer_ = 5000; // длительность отслеживания неактивности. static const unsigned int retention_ = 2000; // длительность отслеживания нажатия и удержания. //================================================================ boolean click_down; boolean click_up; boolean doubleclick; boolean timer; boolean retention; //================================= unsigned long m; boolean p; boolean b; boolean dc; byte c; boolean t; boolean r; //================================= byte _pb; //================================= BUTTON(byte pb) { _pb = pb; pinMode(_pb, INPUT_PULLUP); digitalWrite(_pb, 1); //==== click_down = 0; click_up = 0; doubleclick = 0; timer = 0; retention = 0; //==== m = millis(); p = digitalRead(_pb); b = 0; dc = 0; c = 0; t = 0; r = 0; //==== } void read() { //======================================================= unsigned long nm = millis(); boolean np = digitalRead(_pb); //================= boolean nb = 0; boolean ndc = 0; boolean nt = 0; boolean nr = 0; //================ click_down = 0; click_up = 0; doubleclick = 0; timer = 0; retention = 0; //================= if (np != p) {p = np; m = nm; } //======================================================= if (nm - m > bounce_) {nb = 1;} if (nm - m > doubleclick_) {ndc = 1;} if (ndc != dc) {dc = ndc; if (dc == 1) {c = 0;}} if (nb != b) {b = nb; if (p == 0 && b == 0) {click_down = 1; ++c; if (c == 2) {c = 0; doubleclick = 1;} } if (p == 1 && b == 1) {click_up = 1;} } //======================================================= if (nm - m > timer_) {nt = 1;} if (nt != t) {t = nt; if (p == 1 && t == 1) {timer = 1;} } //======================================================= if (nm - m > retention_) {nr = 1;} if (nr != r) {r = nr; if (p == 0 && r == 1) {retention = 1;} } //======================================================= } }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BUTTON butt_r(10); BUTTON butt_l(11); BUTTON butt_c(12); BUTTON butt_s(A2); #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 20, 4); #include <EEPROM.h> unsigned long lastturn, time_press; //переменные хранения времени float SPEED; //переменная хранения скорости в виде десятичной дроби float DIST; //переменная хранения расстояния в виде десятичной дроби float w_length = 2.060; //длина окружности колеса в метрах byte light = 0; //режим работы габаритов int screen = 0; //режим работы дисплея bool mode = 0; //режим работы кнопок bool alarm = 0; // сигнализация void setup() { // настройки пинов pinMode(5, OUTPUT); //свет середина pinMode(6, OUTPUT); //свет право pinMode(7, OUTPUT); //свет центр pinMode(8, OUTPUT); //свет лево pinMode(13, OUTPUT); //свет лево контрол pinMode(A0, OUTPUT); //свет центр контрол pinMode(A1, OUTPUT); //свет право контрол pinMode(A3, OUTPUT); //зуммер time.begin(); lcd.init(); lcd.init(); lcd.backlight(); blinc.setInterval(777); stopl.setInterval(7777); Serial.begin(9600); //открыть порт attachInterrupt(0, sens, RISING); //подключить прерывание на 2 пин при повышении сигнала //-------------- DIST = (float)EEPROM.read(0) / 10.0; //вспоминаем пройденное расстояние при запуске системы } void sens() { if (millis() - lastturn > 80) { //защита от случайных измерений SPEED = w_length / ((float)(millis() - lastturn) / 1000) * 3.6; //расчет скорости, км/ч lastturn = millis(); //запомнить время последнего оборота DIST = DIST + w_length / 1000; //прибавляем длину колеса к дистанции при каждом обороте оного } } void loop() { // отработка кнопок Serial.print(screen); Serial.println(mode); if (butt_l.click_down && mode == 0) {light = 1;} if (butt_l.click_down && mode == 1) {screen--;} if (butt_r.click_down && mode == 0) {light = 2;} if (butt_r.click_down && mode == 1) {screen++;} if (butt_c.click_down && mode == 0) {light = 3;} if (butt_c.doubleclick && mode == 0) {light = 4;} if (butt_c.retention) {mode = !mode;} if (butt_s.click_down) {light = 5;} if (butt_s.click_up) {light = 0;} // отработка габаритов switch (light) { case 0: off(); break; case 1: left(); break; case 2: right(); break; case 3: stop_1(); break; case 4: stop_2(); break; } // отработка экрана switch (screen) { case 0: def(); break; case 1: date(); break; case 2: max_s(); break; case 3: max_d(); break; case 4: alrm(); break; } } // функции габаритов void off() { digitalWrite (5, 0); digitalWrite (6, 0); digitalWrite (7, 0); digitalWrite (8, 0); digitalWrite (A0, 0); digitalWrite (A1, 0); digitalWrite (13, 0); } void left() { digitalWrite (8, 1); digitalWrite (7, 1); digitalWrite (13, 1); digitalWrite (5, 0); digitalWrite (6, 0); digitalWrite (A0, 0); digitalWrite (A1, 0); if (blinc.isReady()) { digitalWrite (8, !digitalRead(8)); } if (butt_l.doubleclick) light = 0; } void right() { digitalWrite (6, 1); digitalWrite (7, 1); digitalWrite (A1, 1); digitalWrite (5, 0);; digitalWrite (8, 0); digitalWrite (A0, 0); digitalWrite (13, 0); if (blinc.isReady()) { digitalWrite (6, !digitalRead(6)); } if (butt_r.doubleclick) light = 0; } void stop_1() { digitalWrite (8, 1); digitalWrite (6, 1); digitalWrite (5, 0); digitalWrite (7, 1); digitalWrite (A0, 1); digitalWrite (A1, 0); digitalWrite (13, 0); if (butt_c.timer) light = 0; } void stop_2() { digitalWrite (5, 0); digitalWrite (7, 0); digitalWrite (A1, 0); digitalWrite (13, 0); if (blinc.isReady()) { digitalWrite (8, !digitalRead(8)); digitalWrite (6, !digitalRead(6)); digitalWrite (A0, !digitalRead(A0)); } if (butt_c.timer) light = 0; } // функции экрана void def() { lcd.setCursor(2, 1); lcd.print(time.gettime("H:i:s D")); } void date() { lcd.setCursor(3, 0); lcd.print(time.gettime("d-m-Y")); lcd.setCursor(2, 1); lcd.print(time.gettime("H:i:s D")); } void max_s() { lcd.setCursor(3, 0); lcd.print("MAX SPEED"); } void max_d() { lcd.setCursor(3, 0); lcd.print("MAX DIST"); } void alrm() { lcd.setCursor(3, 0); lcd.print("ALARM"); lcd.setCursor(2, 1); lcd.print(alarm); if (butt_c.click_down) alarm = !alarm; }может я что-то упускаю, но теперь вообще перестали работать все кнопки.
Я уже убрал библиотеку Гайвера.
button.read надо в вначало loop вставить для каждой кнопки. И если screen вдруг станет больше 4 что будет?
Все работает, спасибо большое всем за помощь.
Еще два вопроса:
- Как реализовать тройное нажатие кнопки?
- Как сделать чтобы кнопка реагиравала конкретно на клик (нажал-отпустил) и на холд раздельно?
#include <GyverTimer.h> GTimer_ms blinc; GTimer_ms stopl; #include <iarduino_RTC.h> iarduino_RTC time(RTC_DS1302, 3, 9, 4); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // класс титановый велосипед для тактовой кнопки. // фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick), нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени. class BUTTON { public: //================================================================ static const byte bounce_ = 50; // длительность отслеживания дребезга. static const byte doubleclick_ = 200; // длительность отслеживания двойного клика. static const unsigned long timer_ = 5000; // длительность отслеживания неактивности. static const unsigned int retention_ = 2000; // длительность отслеживания нажатия и удержания. //================================================================ boolean click_down; boolean click_up; boolean doubleclick; boolean timer; boolean retention; //================================= unsigned long m; boolean p; boolean b; boolean dc; byte c; boolean t; boolean r; //================================= byte _pb; //================================= BUTTON(byte pb) { _pb = pb; pinMode(_pb, INPUT_PULLUP); digitalWrite(_pb, 1); //==== click_down = 0; click_up = 0; doubleclick = 0; timer = 0; retention = 0; //==== m = millis(); p = digitalRead(_pb); b = 0; dc = 0; c = 0; t = 0; r = 0; //==== } void read() { //======================================================= unsigned long nm = millis(); boolean np = digitalRead(_pb); //================= boolean nb = 0; boolean ndc = 0; boolean nt = 0; boolean nr = 0; //================ click_down = 0; click_up = 0; doubleclick = 0; timer = 0; retention = 0; //================= if (np != p) {p = np; m = nm; } //======================================================= if (nm - m > bounce_) {nb = 1;} if (nm - m > doubleclick_) {ndc = 1;} if (ndc != dc) {dc = ndc; if (dc == 1) {c = 0;}} if (nb != b) {b = nb; if (p == 0 && b == 0) {click_down = 1; ++c; if (c == 2) {c = 0; doubleclick = 1;} } if (p == 1 && b == 1) {click_up = 1;} } //======================================================= if (nm - m > timer_) {nt = 1;} if (nt != t) {t = nt; if (p == 1 && t == 1) {timer = 1;} } //======================================================= if (nm - m > retention_) {nr = 1;} if (nr != r) {r = nr; if (p == 0 && r == 1) {retention = 1;} } //======================================================= } }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BUTTON butt_r(10); BUTTON butt_l(11); BUTTON butt_c(12); BUTTON butt_s(A2); #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 20, 4); #include <EEPROM.h> unsigned long lastturn, time_press; //переменные хранения времени float SPEED; //переменная хранения скорости в виде десятичной дроби float DIST; //переменная хранения расстояния в виде десятичной дроби float w_length = 2.060; //длина окружности колеса в метрах byte light = 0; //режим работы габаритов int screen = 0; //режим работы дисплея bool mode = 0; //режим работы кнопок bool alarm = 0; // сигнализация void setup() { // настройки пинов pinMode(5, OUTPUT); //свет середина pinMode(6, OUTPUT); //свет право pinMode(7, OUTPUT); //свет центр pinMode(8, OUTPUT); //свет лево pinMode(13, OUTPUT); //свет лево контрол pinMode(A0, OUTPUT); //свет центр контрол pinMode(A1, OUTPUT); //свет право контрол pinMode(A3, OUTPUT); //зуммер time.begin(); lcd.init(); lcd.init(); lcd.backlight(); blinc.setInterval(777); stopl.setInterval(7777); Serial.begin(9600); //открыть порт attachInterrupt(0, sens, RISING); //подключить прерывание на 2 пин при повышении сигнала //-------------- DIST = (float)EEPROM.read(0) / 10.0; //вспоминаем пройденное расстояние при запуске системы } void sens() { if (millis() - lastturn > 80) { //защита от случайных измерений SPEED = w_length / ((float)(millis() - lastturn) / 1000) * 3.6; //расчет скорости, км/ч lastturn = millis(); //запомнить время последнего оборота DIST = DIST + w_length / 1000; //прибавляем длину колеса к дистанции при каждом обороте оного } } void loop() { // отработка кнопок butt_r.read(); butt_l.read(); butt_c.read(); butt_s.read(); Serial.print(screen); Serial.println(mode); if (butt_l.click_down && mode == 0) {light = 1;} if (butt_l.click_down && mode == 1) {screen--;} if (butt_r.click_down && mode == 0) {light = 2;} if (butt_r.click_down && mode == 1) {screen++;} if (butt_c.click_down && mode == 0) {light = 3;} if (butt_c.doubleclick && mode == 0) {light = 4;} if (butt_c.retention) {mode = !mode;} if (butt_s.click_down) {light = 5;} if (butt_s.click_up) {light = 0;} // отработка габаритов switch (light) { case 0: off(); break; case 1: left(); break; case 2: right(); break; case 3: stop_1(); break; case 4: stop_2(); break; } // отработка экрана switch (screen) { case 0: def(); break; case 1: date(); break; case 2: max_s(); break; case 3: max_d(); break; case 4: alrm(); break; } } // функции габаритов void off() { digitalWrite (5, 0); digitalWrite (6, 0); digitalWrite (7, 0); digitalWrite (8, 0); digitalWrite (A0, 0); digitalWrite (A1, 0); digitalWrite (13, 0); } void left() { digitalWrite (8, 1); digitalWrite (7, 1); digitalWrite (13, 1); digitalWrite (5, 0); digitalWrite (6, 0); digitalWrite (A0, 0); digitalWrite (A1, 0); if (blinc.isReady()) { digitalWrite (8, !digitalRead(8)); } if (butt_l.doubleclick) light = 0; } void right() { digitalWrite (6, 1); digitalWrite (7, 1); digitalWrite (A1, 1); digitalWrite (5, 0);; digitalWrite (8, 0); digitalWrite (A0, 0); digitalWrite (13, 0); if (blinc.isReady()) { digitalWrite (6, !digitalRead(6)); } if (butt_r.doubleclick) light = 0; } void stop_1() { digitalWrite (8, 1); digitalWrite (6, 1); digitalWrite (5, 0); digitalWrite (7, 1); digitalWrite (A0, 1); digitalWrite (A1, 0); digitalWrite (13, 0); if (butt_c.timer) light = 0; } void stop_2() { digitalWrite (5, 0); digitalWrite (7, 0); digitalWrite (A1, 0); digitalWrite (13, 0); if (blinc.isReady()) { digitalWrite (8, !digitalRead(8)); digitalWrite (6, !digitalRead(6)); digitalWrite (A0, !digitalRead(A0)); } if (butt_c.timer) light = 0; } // функции экрана void def() { lcd.setCursor(2, 1); lcd.print(time.gettime("H:i:s D")); } void date() { lcd.setCursor(3, 0); lcd.print(time.gettime("d-m-Y")); lcd.setCursor(2, 1); lcd.print(time.gettime("H:i:s D")); } void max_s() { lcd.setCursor(3, 0); lcd.print("MAX SPEED"); } void max_d() { lcd.setCursor(3, 0); lcd.print("MAX DIST"); } void alrm() { lcd.setCursor(3, 0); lcd.print("ALARM"); lcd.setCursor(2, 1); lcd.print(alarm); if (butt_c.click_down) alarm = !alarm; }А в соседнем форуме ТС написал
Т.е. таки выбросил гивера-то :)
А в соседнем форуме ТС написал
Т.е. таки выбросил гивера-то :)
Я умею признавать свои ошибки)
Может будут еще советы по оптимизации кода?
Я умею признавать свои ошибки)
Возможно, но каким-то своим, особым образом.
Ибо в посте #21 читаем
Я уже убрал библиотеку Гайвера.
А через 17 минут в посте #23 вдруг видим
Наступает когнитивный диссонанс :(
Может будут еще советы по оптимизации кода?
Да, пожалуй, нет :(
Я убрал
<GyverButton.h>,которая отвечала за кнопки.Сейчас избавляюсь от
<GyverTimer.h>ТС, держи обработчик кнопок. Конструктор+функции+пример использования
Целых 255 вариантов нажатия.
Реализовывал кодовый замок на одной кнопке с этой библиотекой
class multiKey//создадим класс кнопок {public://общие функции и переменные //конструктор класса multiKey(byte pin,byte state,byte val); byte read();//функция обработчика нажатий private://личные переменные и функции класса //локальные переменные обьекта номер пина/тип сигнала/количество кликов byte _pin,_state,_val; uint32_t start_press;//переменная времени нажатия кнопки uint32_t pressTime;//переменная длительности нажатия кнопки uint32_t double_press;//переменная времени между нажатиями boolean pressFlag;//переменная флага нажатия byte press_one;//переменная количества нажатий //переменные состояния/временного состояния/нажатия кнопки byte num,_num,button; }; //Функция чтения кнопки byte multiKey::read(){ !_state?button=digitalRead(_pin):button=!digitalRead(_pin);//в зависимости от того, что в конструкторе настраиваем кнопку if(!button){num=0;}//если кнопка отпущена, выдаем результат 0 if(button&&!pressFlag)//если кнопка нажата и флаг опущен {pressTime=millis()-start_press;//считаем время нажатия кнопки if(pressTime>=1500){//если длительность нажатия больше 1,5 сек pressFlag=1;//поднимаем флаг num=255;//значение кнопки long pressTime=0;//сбрасываем длительность нажатия } } if(!button){//если кнопка отпущена start_press=millis();//сбрасываем время нажатия pressFlag=0;//опускаем флаг } if(!button&&!pressFlag){//если кнопка и флаг отпущены if(pressTime>50&&pressTime<1500)//а время нажатия больше 50мс, но меньше 1,5сек {press_one++;//увеличиваем счетчик количества нажатий if(press_one>_val)press_one=_val;//ограничиваем значение счетчика pressTime=0;//сбрасываем длительность нажатия double_press=millis();//запускаем таймер ожидания следующего нажатия }} if(press_one){//если было короткое нажатие if(millis()-double_press>=300){//ждем 0,3сек pressTime=0;//сбрасываем длительность нажатия num=press_one;//значение кнопки приравниваем к количеству нажатий press_one=0;//сбрасываем количество нажатий }} _num=num;//для одиночного вывода результата, используем временную переменную num=0;//обнудяем основную переменную значения кнопки return _num;//возвращаем значение кнопки } //функция конструктора класса /*в конструкторе указываем: номер пина тип сигнала (лог0/лог1) максимальное количество отслеживаемых кликов*/ multiKey::multiKey(byte pin,byte state,byte val) {_pin = pin;//передаем внутренней переменной номер пина //!state?_state=2:_state=0;//в зависимости от выбранного типа сигнала меняем значение переменной _state=state; _val=val;//передаем внутренней переменной количество кликов pinMode(pin,_state);//конфигурируем пин согласно типа сигнала } boolean led1,led2; multiKey myBtn(9,0,2);//вот так создаём кнопку(пин,отслеживаемый уровень,максимальное количество кликов) void setup(){ pinMode(11,1); pinMode(13,1); } void loop(){ byte btn_state=myBtn.read();//а вот так читаем кнопку switch(btn_state){ case 0:break; case 1: led1=!led1;digitalWrite(11,led1);break; case 2: led2=!led2;digitalWrite(13,led2);break; } }Немного привел код в удобочитаемый вид (для меня).
class multiKey { // создадим класс кнопок public: // общие функции и переменные multiKey(byte pin, byte state, byte val); // конструктор класса byte read(); // функция обработчика нажатий private: // личные переменные и функции класса byte _pin, _state, _val; // локальные переменные обьекта номер пина/тип сигнала/количество кликов uint32_t start_press; // переменная времени нажатия кнопки uint32_t pressTime; // переменная длительности нажатия кнопки uint32_t double_press; // переменная времени между нажатиями boolean pressFlag; // переменная флага нажатия byte press_one; // переменная количества нажатий byte num, _num,button; // переменные состояния/временного состояния/нажатия кнопки }; //Функция чтения кнопки byte multiKey::read(){ !_state?button = digitalRead(_pin):button = !digitalRead(_pin); // в зависимости от того, что в конструкторе настраиваем кнопку if(!button) { // если кнопка отпущена num = 0; // выдаем результат 0 } if(button && !pressFlag) { // если кнопка нажата и флаг опущен pressTime = millis() - start_press; // считаем время нажатия кнопки if(pressTime >= 1500) { // если длительность нажатия больше 1,5 сек pressFlag = 1; // поднимаем флаг num = 255; // значение кнопки long pressTime = 0; // сбрасываем длительность нажатия } } if(!button){ // если кнопка отпущена start_press = millis(); // сбрасываем время нажатия pressFlag = 0; // опускаем флаг } if(!button && !pressFlag) { // если кнопка и флаг отпущены if(pressTime > 50 && pressTime < 1500) { // а время нажатия больше 50мс, но меньше 1,5сек press_one++; // увеличиваем счетчик количества нажатий if(press_one > _val) { press_one = _val; // ограничиваем значение счетчика } pressTime = 0; // сбрасываем длительность нажатия double_press = millis(); // запускаем таймер ожидания следующего нажатия } } if(press_one){ // если было короткое нажатие if (millis() - double_press >= 300) { // ждем 0,3сек pressTime = 0; // сбрасываем длительность нажатия num = press_one; // значение кнопки приравниваем к количеству нажатий press_one = 0; // сбрасываем количество нажатий } } _num = num; // для одиночного вывода результата, используем временную переменную num = 0; // обнуляем основную переменную значения кнопки return _num; // возвращаем значение кнопки } //функция конструктора класса /* в конструкторе указываем: 1. номер пина 2. тип сигнала (лог0/лог1) 3. максимальное количество отслеживаемых кликов */ multiKey::multiKey(byte pin,byte state,byte val) { _pin = pin; // передаем внутренней переменной номер пина //!state?_state=2:_state=0; // в зависимости от выбранного типа сигнала меняем значение переменной _state = state; _val = val; // передаем внутренней переменной количество кликов pinMode(pin,_state); // конфигурируем пин согласно типа сигнала } //================================ /* Описание класса окончено. Далее идет пример использования. */ boolean led1, led2; /* Как я понял - флаги управления светодиодами. Одно нажатие - меняем состояние первого светодиода, если же произошло двойное нажатие - меняем состояние второго светодиода. */ multiKey myBtn(9, 0, 2); // вот так создаём кнопку("пин", "отслеживаемый уровень", "максимальное количество кликов") void setup(){ pinMode(11,1); pinMode(13,1); } void loop(){ byte btn_state = myBtn.read(); // а вот так читаем кнопку switch (btn_state) { case 0: break; // Если кнопка НЕ нажата - ничего не делаем (???) case 1: led1 = !led1; // Если нажали один раз - меняем состояние первого диода digitalWrite(11, led1); break; case 2: led2 = !led2; // Если было двойное нажатие - меняем состояние второго диода digitalWrite(13,led2); break; } }Вопрос возник - в строке 30 дублирование условия строки 19, их может объеденить? Или в этом имеется какой-то "тайный смысл"? :-)
Еще строку 18 конвертните в длинную запись из короткой, не могу сообразить что там происходит...
Да , безусловно строки 19 и 30 можно написать как одну. Но все дело в том, что как таковая функция у меня уже давно удалена и все оформлено в виде библиотеки. То что тут представлено скомпоновано из разных файлов и проверено только на правильность компиляции.
А в строке 30 идёт тренарная операция по проверке состояния кнопки. Если в конструкторе указано , что при срабатывании сигнал кнопки лог1 то одно переменная принимает одно значение, если лог0 то противоположное. Это позволяет сконфигурировать кнопки при их обьявлении на разные рабочие уровни сигналов, не меняя остальной код.
Наверное речь про 18 строку, а не 30ю.
Ещё вопрос - значение 255 означает долгое нажатие, как я понимаю? Или я не прав? Как длинное нажатие обозначается?
Да, долгое нажатие 255
Понятно. Данная библиотека будет работать с триггером Шмитта? (SN74HC14N)
А при чем тут библиотека ?
Для пояснения:
Библиотека обрабатывает нажатия по принципу, одно нажатие одно событие. Т.е. если у нас просто короткое нажатие, то оно так и отрабатывает, если длинное, то после проверки времени функция возвращает результат, сбрасывает флаги и ждёт, когда отпустят кнопку, возвращает при этом результат false. При мультикликах считает время после последнего клика и возвращает количество нажатий в тот момент, когда проходит время отведенное на задержку между кликами.
Как использовать совместно с триггером Шмитта, это уже вопрос реализации самого триггера и схемы его подключения
Собственно вопрос про триггер в том, что SN74HC14N - инвертирующий триггер. То есть низкий уровень на входе дает высокий уровень на выходе. Вот я о чем.
Ну вроде есть же в конструкторе объекта выбор логического уровня, для отслеживания сигнала
А вот теперь все сложилось в одну единую цепочку! Большое спасибо.
К чему вам этот триггер или у вас не кнопка, а что то другое ?