Функция нескончаемо инкременирует значение при нажатие на кнопку
- Войдите на сайт для отправки комментариев
Чт, 05/02/2015 - 02:57
Здравствуйте, сделал вот по этому примеру, но при нажатии на любую из двух кнопок происходит бесконечный цикл, как его ограничить - нахожусь в прострации:) Подскажите, почему функция click1() так работает и как можно это исправить.
Можно например так сделать
unsigned long eventTime = 0; int regim = 1; int flag = 0; void setup() { pinMode(4, OUTPUT); pinMode(5, OUTPUT); } void loop() { if(digitalRead(8) == HIGH && flag == 0) { flag = 1; eventTime = millis(); } if(digitalRead(8) == HIGH && flag == 1 && millis()-eventTime > 3000) regim = 0; if(digitalRead(8) == LOW && flag == 1) { flag = 0; if(millis()-eventTime < 3000) regim++; if(regim > 3) regim = 1; } switch(regim) { case 0: digitalWrite(4, HIGH); digitalWrite(5, HIGH); break; case 1: digitalWrite(4, LOW); digitalWrite(5, LOW); break; case 2: digitalWrite(4, HIGH); digitalWrite(5, LOW); break; case 3: digitalWrite(5, HIGH); digitalWrite(4, LOW); break; } }
кнопки которые выполняют либо увеличение на 1 либо на 5, но это циклично, и не пойму в чем проблема, подскажите, пожалуйста. Скетч
// DS отвечает за поток битов(данные). На Схеме 595 пин 14 #define DATA_PIN 4 //STCP отвечает за так называемое защелкивание. Когда мы все свои биты передали, посылаем сигнал, что окончили передачу. На Схеме 595 пин 12 #define LATCH_PIN 3 // SHCP отвечает за ШИМ. Когда 1 из данных забирается бит, 0 пропускается.Синхронизация потока. На Схеме 595 пин 11 #define CLOCK_PIN 2 const int digitPins[3] = { 52,51,50}; //Массив пинов. Выбрал произвольные кониакты у меня Мега int8_t Disp[3]={ 0};// задается тип int8_t чтобы к нам ничего, кроме набора бит не попало. int Value = 120; int i = 0; int flag = 0;//0 - не нажата ни одна, 1 - нажата одна int regim ; unsigned long previousMillis = 0;//отсечка unsigned long time; int TimePush = 2000; byte segments[10] = { //Массив из 10 значений B11000000, //0 B11111001, //1 B10100100, //2 B10110000, //3 B10011001, //4 B10010010, //5 B10000010, //6 B11111000, //7 B10000000, //8 B10010000 //9 Бинарное значение цифры в моем подключении индикатора и сдвигового регистра, когда q1->a,..q7->g,q0->DP }; void setup() { Serial.begin(115200); for(byte j=0;j<3;j++)pinMode(digitPins[j],OUTPUT); //цикл - назначаем всем режим выход из нашего массива пинов pinMode(DATA_PIN, OUTPUT); pinMode(CLOCK_PIN, OUTPUT); pinMode(LATCH_PIN, OUTPUT); } // Моя функция для работы с индикатором и сдвиговым регистром 74НС595 void printInd() { //цифровые выходы из массива в 0 (LOW) - отключаем используем цикл for(byte d=0; d<3; d++) digitalWrite(digitPins[d], LOW); //Для начала записи в 74HC595 нужно подать 0 на STCP (открыть) digitalWrite(LATCH_PIN, LOW); // с данными выпускаем поток битов на DS синхроннированные с SHCP shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, segments[Disp[i]]); // А теперь когда последний бит числа передали закрываем digitalWrite(LATCH_PIN, HIGH); //на индикатор подаем 5V смотреть в DATASHEET вашего индикатора!!! digitalWrite(digitPins[i], HIGH); //delayMicroseconds(300); //Частота ирцания и собственно она же яркость индикатора:) //delay(1000);// проследить появление i++; if(i > 2) i=0; } void click1() { int VRes = analogRead(0); // значение с аналог пина if(flag == 0 && VRes<300 && VRes>0) // нажата ли кнопка 1 + { previousMillis= millis(); // когда нажата flag = 1; // состояние что нажата Serial.println("IF 1"); } if(flag == 1 && VRes<300 && VRes>0 && ((millis()-previousMillis) > TimePush)){ regim=1; Serial.println("IF 2"); }// выполняем первый режим работы прибавление 5 ед. if(VRes > 1000 && flag ==1) { flag = 0; //кнопка отжата Serial.println("IF 3"); if(millis()-previousMillis<TimePush) { regim = 2; Serial.println("IF 4"); } //прибавление единицы } //Два других режима по аналогии // if(flag == 0 && VRes > 250 && VRes < 530) // нажата ли кнопка 2 - // { // Serial.println("IF 5"); // previousMillis = millis(); // когда нажата // flag = 1; // состояние что нажата // } // if(flag == 1 && VRes > 250 && VRes < 530 && millis()-previousMillis > TimePush){ // Serial.println("IF 6"); // regim=3;// третий режим - отнимаем 5 ед. // } // if(VRes > 1000 && flag ==1) // { // Serial.println("IF 7"); // flag=0; //кнопка отжата // if(millis()-previousMillis<TimePush) // { // Serial.println("IF 8"); // regim=4; //отнимаем единицы // } // } switch(regim) { case 1: Value+=5; break; case 2: Value++; break; case 3: Value-=5; break; case 4: Value--; break; } } void loop() { click1(); Serial.println(Value); //Выводим значение отсрочки срабатывания таймера на дисплей Disp[0] = (Value/100)%10; //сотни Disp[1] = (Value/10)%10; //десятки Disp[2] = Value%10; //единицы printInd(); //Функция для отображения на индикаторе }
Ну как минимум, пример Вы взяли для цифровых конопок да еще и с реализацией длительного нажатия. А сами используете аналоговые кнопки и задержка вроде как не нужна. flag у Вас один а кнопок две, соответственно значение флага будет "какое попало".
Ну а вообще надо regim еще обнулять именно из-за него у Вас цакикливание в +=5
А по хорошему, на простых примерах сделать свои кнопки, научится ими управлять, а потом уже запихивать в компот.
Кнопки отдельно тестировались, и было тоже самое, полный скетч - для полноты картины.
Ну как минимум, пример Вы взяли для цифровых конопок да еще и с реализацией длительного нажатия. А сами используете аналоговые кнопки и задержка вроде как не нужна. flag у Вас один а кнопок две, соответственно значение флага будет "какое попало".
Ну а вообще надо regim еще обнулять именно из-за него у Вас цакикливание в +=5
О таком изменении речь?
Кнопки отдельно тестировались, и было тоже самое, полный скетч - для полноты картины.
Выходит, результата не получили, но дальше пошли. Три самых почитаемых российских святых - авось, небось и как нибудь((((
Кнопки отдельно тестировались, и было тоже самое, полный скетч - для полноты картины.
Выходит, результата не получили, но дальше пошли. Три самых почитаемых российских святых - авось, небось и как нибудь((((
Дело в том, что есть 7 ми сегмент и значения на нем зависят от этих кнопок, поэтому не совсем понимаю о чем вы скетч итак только основное здесь имеет. И кнопки вызвали крайнее недоумение.
Ну если в двух словах то у Вас click1() выполняется постоянно, при этом regim всегда имеет какое-то значение от 1 до 4, а значит switch case будет срабатывать на каждом цикле, отсюда и Ваша зацикленность. Если уверенны, что кнопки работают правильно то надо после каждого case перед break писать regim=0 Тогда на следующем цикле мы не попадём в case, а попадём туда тоьлко когда действительно нужно т.е. при нажатиях на кнопки.
Ну если в двух словах то у Вас click1() выполняется постоянно, при этом regim всегда имеет какое-то значение от 1 до 4, а значит switch case будет срабатывать на каждом цикле, отсюда и Ваша зацикленность. Если уверенны, что кнопки работают правильно то надо после каждого case перед break писать regim=0 Тогда на следующем цикле мы не попадём в case, а попадём туда тоьлко когда действительно нужно т.е. при нажатиях на кнопки.
Действительно, как же не догадался, спасибо огромное, помогло!! Светлая голова.
Теперь нужно разобраться почему при действии +5 срабатывает счетчик без конца
+ единица работает отлично!!
- единица не хочет
((millis()-previousMillis) > TimePush
Вот это Вам зачем? Вам надо длинные и короткие нажатия на кнопку?
Нажал первую кнопку в лог выкинуло
IF 1
IF 3
IF 4
и + 5 к значению
Нажал вторую кнопку в лог выкинуло
IF 5
IF 7
IF 8
и + 5 к значению
Хотя по case иное:((
((millis()-previousMillis) > TimePush
Вот это Вам зачем? Вам надо длинные и короткие нажатия на кнопку?
Да, именно. Краткое нажатие прибавляет(/ отнимает) единицу. А с задержкой в 2 сек прибавляет(/ отнимает) 5 единиц
Ну тогда, как Вам уже советовали надо с кнопками разобраться, они у Вас неправильно реализованы.
Вот, например, тут. Заходим в условие меняем флаг один раз сверяем время и всё больше мы в это условие не попадём так как флаг сменили, а значит и не отработаем длинное нажатие.
Хотя судя по < оно тут вообще непонять зачем. В общем кнопки надо делать
добавил в условия &®im ==0
теперь всё как надо но 5 ки не могу поймать по времени, то есть если передержать то счетчик "летит"
Ну тогда, как Вам уже советовали надо с кнопками разобраться, они у Вас неправильно реализованы.
Вот, например, тут. Заходим в условие меняем флаг один раз сверяем время и всё больше мы в это условие не попадём так как флаг сменили, а значит и не отработаем длинное нажатие.
Хотя судя по < оно тут вообще непонять зачем. В общем кнопки надо делать
Не совсем понимаю, посмотрите последний, пожалуйста
В целом вам надо конкретизировать понятия - короткое и длинное нажатие. Можем принять - короткое это от 1сек до 2сек, а длинное от 3сек до 5сек. Тогда можно что то реализовать. Если нижний предел короткого не ограничивать, как прога узнает что наступило длинное? Алгоритм - нажали, начали считать время, если отпустили и время в первом диапазоне - короткое, во вторм - длинное.
В целом вам надо конкретизировать понятия - короткое и длинное нажатие. Можем принять - короткое это от 1сек до 2сек, а длинное от 3сек до 5сек. Тогда можно что то реализовать. Если нижний предел короткого не ограничивать, как прога узнает что наступило длинное? Алгоритм - нажали, начали считать время, если отпустили и время в первом диапазоне - короткое, во вторм - длинное.
Так вроде же IF 1 - это кнопка нажата, IF 2 - если 2 сек была нажата, IF 3-4 - если мы её отпустили раньше 2 секунд
А если флаг = 0
то 5 + 1 срабатывает
Чувствую надо поспать:(
Зачем вот это условие при отжатии кнопки?
if
(millis()-previousMillis<TimePush&®im ==0)
Зачем вот это условие при отжатии кнопки?
if
(millis()-previousMillis<TimePush&®im ==0)
Нажатие менее 2 сек и выполняется case 2: Value++;
if(regim==0) достаточно. Если оно 0 то это короткое нажатие, т.к. если бы это было длинное нажатие то regim уже был бы 1
if(regim==0) достаточно. Если оно 0 то это короткое нажатие, т.к. если бы это было длинное нажатие то regim уже был бы 1
Тогда без всяких нажатий пойдет цикл) Или большими бросками будет считать. Думаю что тут что то с флагами, но сам не могу понять
Куда он пойдет? Если перед ним еще одно условие с флагом и значением... Никуда оно не пойдет.
На это обратите пожалуйста внимание, как ограничить прибавления в след 5 ке. Например жму две секунды и не успеваю отжать как уже 5 +1 получилось
Куда он пойдет? Если перед ним еще одно условие с флагом и значением... Никуда оно не пойдет.
Проверил, без нажатия, если оставил regim==0 или вместе с flag==1 при нажатии летит значение
Сделайте так примерно
Сделайте так примерно
Идеально!!!!! Очень благодарен, что помогли!!! А то я уже паниковать начинал, пойду теперь посплю, дело сделано. Приобрел для себя неоценимый опыт.
Добавил еще защиту и разделил переменные flag
Теперь как Швейцарские часы работает))