Как программно ограничить число нажатий кнопки?

poty

★★★★★★✩
19 Фев 2020
2,958
886
Я не очень внимательно читал ветку по мере появления в ней новых сообщений. Скажу, что эта ветка ничему не учит, и в следующий раз будет только сбивать других людей с пути истинного.
Начать с постановки задачи: ограничить число нажатий кнопки невозможно, это - механическое действие. Фактически ТС вообще не представлял себе задачу в начале обсуждения. В результате - уродливый код с кучей ненужных переменных и обработок, выполняющийся более-менее осмысленно только по причине delay (иначе serial был бы забит одинаковыми сообщениями). Добавить что-то нужное в него будет второй титанической задачей.
Лучше бы подсказали ТС как переформулировать задание, было бы гораздо информативнее для последующих этим путём новичков.
 

VictorArx

★★✩✩✩✩✩
22 Мар 2021
463
79
Пожалуйста. Рад что у Вас всё получилось как Вы хотели.

А касательно скетча, я бы всё-таки советовал использовать библиотеку gyver-button хотя бы чтобы защититься от дребезга контактов. Тогда и задержку в 21\26 строчках не надо использовать.
Первый скетч я сделал именно с библиотекой gyver-button и всё получилось, хотя мне было кое что не понятно. Этот скеч сделал по своему, конечно по дилетански, но работает. Я ведь только учусь, и что для многих програмистов элементарно, для меня пока тёмный лес.
 

VictorArx

★★✩✩✩✩✩
22 Мар 2021
463
79
Может Вас она и ни чему не учит, а меня многому научила. Мне помогали и с помощью отдельных участников форума я сделал то, что хотел. Кстати я не знаю многих терминов, что такое TC ?
 
Изменено:

VictorArx

★★✩✩✩✩✩
22 Мар 2021
463
79
Вот мой первый скетч.

C++:
int led = 11;         //  Номер Pin к которому подключен диод
   //  Переменная в которой хранится уровень яркости (От 0 до 254)
     //  Номер Pin к которому подключена кнопка 
#include "GyverButton.h"

#define BTN1 2                // кнопка подключена сюда (PIN --- КНОПКА --- GND)
#define BTN2 3        // кнопка подключена сюда (PIN --- КНОПКА --- GND)

GButton butt1(BTN1);
GButton butt2(BTN2);

uint8_t value = 0 ;
 
void setup()  {
 
   Serial.begin(9600);
 
   pinMode(led, OUTPUT); // Порт 11 (led) будет работать как Выход.
 
 }

void loop()  { // Этот цикл будет выполняться бесконечное количество раз.
 

butt1.tick();  // обязательная функция отработки. Должна постоянно опрашиваться
  butt2.tick();
 if (butt1.isClick() && value < 5)
   {
  value ++;
  
  }
 

 if (butt2.isClick() &&value != 0  )
  
 
 {
   value--;
 
 }
 
  switch (value) {
    case 0:    // your hand is on the sensor
      Serial.println("dark");
    
  
 analogWrite(led,0);     
      
    break;
    case 1:    // your hand is close to the sensor
   Serial.println("bright");   
 
analogWrite(led,50 );     
      
    break;
  
   case 2:    // your hand is a few inches from the sensor
      Serial.println("medium");
    
  analogWrite(led,100 ); 
      
       break;
    case 3:    // your hand is nowhere near the sensor
      
      Serial.println("dim");
 
analogWrite(led, 150);     
      
      break;
 
 
 case 4:    // your hand is nowhere near the sensor
      
      Serial.println("pim");
 
analogWrite(led,255);     
        
 break;
  
   }
 
   }
 

bort707

★★★★★★✩
21 Сен 2020
2,864
850
@VictorArx, вам уже советовали выравнивать код Ctrl+T перед выкладыванием? А вы снова выложили кривой неоформленный код...

. я тоже слегка поразился, что можно обсуждать две страницы в этой теме.... программа по сути из одной строки...
Все, что с самого начала надо было сделать - это правильно сформулировать задачу, а именно:

"Кнопка должна менять яркость, пока яркость не достигнет установленного предела".

Из этого логично вытекает этот код:
C++:
if (butt1.isClick() && value < VAL_MAX)   value ++;
и все
 

xof

★✩✩✩✩✩✩
24 Окт 2020
123
44
Это форумный жаргон - ТопикСтартер (тот кто начал тему).

@poty, да, с одной стороны Вы правы. Код написан неправильно, можно было всё сделать по другому, но Виктор совсем новичок судя по всему, и закидывать его сразу что вот тут не так, вот там не так, тут надо использовать таймеры на миллис, там флаги, тут вынести в отдельные методы, создать структуры и погрузимся в ООП, скорее только оттолкнёт его от этого дела.

Уверен что он сам дойдёт до всего когда будет нужно (перейдёт с delay на millis когда поймёт что код останавливается, а ему этого не надо и т.д. и т.п.).
Ну это сугубо моё ИМХО. Сколько людей, сколько мнений.

p.s. Ctrl+T конечно использовать нужно почаще для автовыравнивания
 

VictorArx

★★✩✩✩✩✩
22 Мар 2021
463
79
Избыточное цитирование
@VictorArx, вам уже советовали выравнивать код Ctrl+T перед выкладыванием? А вы снова выложили кривой неоформленный код...

. я тоже слегка поразился, что можно обсуждать две страницы в этой теме.... программа по сути из одной строки...
Все, что с самого начала надо было сделать - это правильно сформулировать задачу, а именно:

"Кнопка должна менять яркость, пока яркость не достигнет установленного предела".

Из этого логично вытекает этот код:
C++:
if (butt1.isClick() && value < VAL_MAX)   value ++;
и все
Советовали только </>, насчёт выравнивания не говорили. Учту.
 

bort707

★★★★★★✩
21 Сен 2020
2,864
850
Уверен что он сам дойдёт до всего когда будет нужно (перейдёт с delay на millis когда поймёт что код останавливается, а ему этого не надо и т.д. и т.п.).
о чем вы вообще? - я в этом коде вообще никакой работы со временем не вижу... Какие делей, какие миллис...

Код, кстати. вполне приличный. Вопрос в другом - что тут было обсуждать 2 страницы? - а вся проблема в том, что ТС надо учиться правильно формулировать задачу.
Когда человек не может верно описать алгоритм на родном языке - он и запрограммировать его не сможет, это же связанные вещи. И наоборот - из хорошего четкого описания алгоритма код получается сам собой.
 
  • Лойс +1
Реакции: Юрий Саныч

VictorArx

★★✩✩✩✩✩
22 Мар 2021
463
79
Избыточное цитирование
Это форумный жаргон - ТопикСтартер (тот кто начал тему).

@poty, да, с одной стороны Вы правы. Код написан неправильно, можно было всё сделать по другому, но Виктор совсем новичок судя по всему, и закидывать его сразу что вот тут не так, вот там не так, тут надо использовать таймеры на миллис, там флаги, тут вынести в отдельные методы, создать структуры и погрузимся в ООП, скорее только оттолкнёт его от этого дела.

Уверен что он сам дойдёт до всего когда будет нужно (перейдёт с delay на millis когда поймёт что код останавливается, а ему этого не надо и т.д. и т.п.).
Ну это сугубо моё ИМХО. Сколько людей, сколько мнений.

p.s. Ctrl+T конечно использовать нужно почаще для автовыравнивания
Спасибо за поддержку ! Я уж подумал , что ТС -тупая скотина.Не волнуйся дружище, не оттолкнут меня от этого дела. Мне нравится учиться и я уже в возрасте, не обижаюсь на грамотных людей. посмотреть в иде пример fade - ТАМ ВСЁ ПОКАЗАНО))))) А это где?
 
Изменено:

xof

★✩✩✩✩✩✩
24 Окт 2020
123
44
о чем вы вообще? - я в этом коде вообще никакой работы со временем не вижу... Какие делей, какие миллис...
Я про в принципе о написании более правильного кода, понимании когда что использовать и т.д.

Код, кстати. вполне приличный.
Нууу да... Но как минимум то что мы бегаем в switch независимо от того была нажата кнопка или нет и срём пишем бесконечно в serial и снова и снова дёргаем analogWrite как-то такое. Но зато работает. Как для новичка - отлично, логично и понятно.
 

poty

★★★★★★✩
19 Фев 2020
2,958
886
Код написан неправильно, можно было всё сделать по другому, но Виктор совсем новичок судя по всему, и закидывать его сразу что вот тут не так, вот там не так, тут надо использовать таймеры на миллис, там флаги, тут вынести в отдельные методы, создать структуры и погрузимся в ООП, скорее только оттолкнёт его от этого дела.
По моему, я не говорил ничего про millis, флаги и проч., а уж тем более - про ООП. Хотя вот с самого начала ТС использовал объект Serial, а это - чистое ООП. Я начал с того, что все бросились помогать в задаче, которая не была сформулирована. В результате, первоначальный "заплыв" в неверную сторону и привёл к дурацкому коду, в котором всё подчинено непонятным целям. А как всё это сделать функциональным ТС не знает... Или знает, @VictorArx ? Ведь сейчас, с точки зрения управления чем-либо написанное совсем неприменимо, правильно сказал @xof.
 

VictorArx

★★✩✩✩✩✩
22 Мар 2021
463
79
Избыточное цитирование
По моему, я не говорил ничего про millis, флаги и проч., а уж тем более - про ООП. Хотя вот с самого начала ТС использовал объект Serial, а это - чистое ООП. Я начал с того, что все бросились помогать в задаче, которая не была сформулирована. В результате, первоначальный "заплыв" в неверную сторону и привёл к дурацкому коду, в котором всё подчинено непонятным целям. А как всё это сделать функциональным ТС не знает... Или знает, @VictorArx ? Ведь сейчас, с точки зрения управления чем-либо написанное совсем неприменимо, правильно сказал @xof.
Не совсем понял о чём речь, то есть совсем не понял. Я знаю другой код для яркости светодиода без всякого switch . Но я хотел попробовать именно этот оператор, принцип работы. Теперь в этом коде буду заменять делей на миллис. Сам попробую разобраться, а то вы ещё переругаетесь из за меня.
 

poty

★★★★★★✩
19 Фев 2020
2,958
886
я хотел попробовать именно этот оператор, принцип работы. Теперь в этом коде буду заменять делей на миллис.
специально посмотрел: желание попробовать switch у Вас возникло только в посту №22. Заменять delay на millis просто так - бессмысленно. Определитесь с задачей, удалите нафиг switch и перейдите на обычные массивы. А вообще - пример, что получился - это типичный "объект, который может находится в одном из нескольких состояний". И ООП здесь ложится просто идеально!

посмотреть в иде пример fade
В среде IDE в меню Файл есть строчка Примеры. Там - 01. Basics, затем - Fade.
 

VictorArx

★★✩✩✩✩✩
22 Мар 2021
463
79
C++:
int led = 11;         //  Номер Pin к которому подключен диод
int brightness = 0;   //  Переменная в которой хранится уровень яркости (От 0 до 300)
int buttonPlus = 2;   //  Номер Pin к которому подключена кнопка
int buttonMinus = 4;


void setup()  {

  Serial.begin(9600);
  pinMode(buttonPlus, INPUT);

  pinMode(buttonMinus, INPUT);

  pinMode(led, OUTPUT); // Порт 11 (led) будет работать как Выход.}
}
void loop()  { // Этот цикл будет выполняться бесконечное количество раз.

  if (digitalRead(buttonPlus) == HIGH && brightness < 256) {
    brightness  += 5 ;
    delay(300);
  }
  if (digitalRead(buttonMinus) == HIGH && brightness > 0 ) {
    brightness  -= 5 ; Вот ещё сам придумал.

    delay(300);

  }

  switch (brightness) {



    case 0:    // your hand is on the sensor
      Serial.println("dark");


      analogWrite(led, brightness );



      break;
    case 5:    // your hand is close to the sensor


      analogWrite(led, brightness );

      Serial.println("bright");
      break;
    case 10:    // your hand is a few inches from the sensor
      Serial.println("medium");


      analogWrite(led, brightness);



      break;
    case 15:    // your hand is nowhere near the sensor

      Serial.println("dim");

      analogWrite(led, brightness);


      break;


    case 20:    // your hand is nowhere near the sensor

      Serial.println("pim");

      analogWrite(led, brightness);


      break;

    case 25:    // your hand is nowhere near the sensor

      Serial.println("pim");

      analogWrite(led, brightness);


      break;

  }

}
Ещё сам придумал
 

poty

★★★★★★✩
19 Фев 2020
2,958
886
Работать не будет. brightness подвёл. Внутри switch он имеет значение от 0 до 25 с шагом 5, а наверху - ограничение от 0 до 255 с тем же шагом 5.
 

VictorArx

★★✩✩✩✩✩
22 Мар 2021
463
79
Читал все возмущённые отклики по поводу моего кода. Действительно зачем изобретать велосипед, с свичами, кейсами, если всё умещается в две строчки кода .Brightness+=5; brightness- =5; . Справедливо если это конечная цель проекта. Если нет, то начинается вторая часть маралезонского балета. Пишем вторую переменную, рисуем кейс и подключаем потенциометр. Пишем код , чтобы потенциометр управлял тоже яркостью этого светодиода. Нужно, чтобы один и тот же светик регулировался кнопками и потенцем. Для чего нужно потом объясню. Код нарисую сам или с вашей помощью. Нужно просто добавить к полученному ранее коду.
 

poty

★★★★★★✩
19 Фев 2020
2,958
886
Снова метод решения задачи идёт впереди её формулировки...
switch попробовали? Зачем продолжать решать задачу через одно место?
Ладно, умолкаю. Смысла нет.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Кнопка не выдает значение яркости. только нажатие или отпускания. Допустим, у вас 2 кнопки , одна на + , вторая на -. 5 Градаций яркости от 0 до максимума. Тут все ок. Нажатие кнопки четко определено 1 на пине.
Берем потенциометр, он будет выдавать значение от 0 до 1023, причем значение будет колебаться. Уже придумали как понять надо ли регулировать яркость от потенциометра или нет ? Как отличить крутили его или он дребезжит? А то, что например с максимальной яркости до нуля она мгновенно опустит яркость нормально ?
 

xof

★✩✩✩✩✩✩
24 Окт 2020
123
44
Так, как её решить кроме switch? Я не знаю по другому. Меня на эту мысль натолкнул пост, где написано, как объеденить два скетча.
Если брать за основу то что Вы уже написали, я бы предложил как-то так чтобы ясно было как можно по другому (не проверял, писал на коленке, но думаю принцип понятен. Правда ближе к конечному результату о котором мы не в курсе это всё сильно может измениться):
C++:
void loop() {

  button1.tick();
  button2.tick();

  if (button1.isClick() && bright < 256)
  {
    bright++;
    changeBright();
  }
  if (button2.isClick() && bright > 0)
  {
    bright--;
    changeBright();
  }
  /*
    и т.д. по типу
    если значение потенциометра изменилось на что-то что не дребезг, то мапим значение с потенциометра и записываем в bright
    и вызываем метод changeBright()
  */
}

void changeBright()
{
  Serial.print("changing bright to ");
  Serial.println(bright);
  analogWrite(led, bright);
}
 
Изменено:

poty

★★★★★★✩
19 Фев 2020
2,958
886
Так, как её решить кроме switch? Я не знаю по другому. Меня на эту мысль натолкнул пост, где написано, как объеденить два скетча.
Вы сначала сформулируйте четкую задачу:
  • описание объекта;
  • сколько состояний, что определяет нахождение в определённом состоянии?
  • алгоритм перехода между состояниями;
  • методы воздействия, какой алгоритм применяется для каждого метода воздействия?
 

VictorArx

★★✩✩✩✩✩
22 Мар 2021
463
79
Избыточное цитирование
Вы сначала сформулируйте четкую задачу:
  • описание объекта;
  • сколько состояний, что определяет нахождение в определённом состоянии?
  • алгоритм перехода между состояниями;
  • методы воздействия, какой алгоритм применяется для каждого метода воздействия?
Хорошо, уговорили. Пишу чисто теоретически чё надо. Я уже писал в одном из постов, что у меня серва на 360 градусов без ограничителя и крутится неуправляемая через две кнопки. Если подключаю через потенциометр то можно остановить её и регулировать. Прочитав у вас на форуме, как объединить два скетча решил попробовать через switch. Задумка такая . Если я подключаю серву через потенц могу её остановить. Вот и решил через потенц её остановить, а кнопками управлять.
 

poty

★★★★★★✩
19 Фев 2020
2,958
886
Остаётся понять, что значит: "остановить через потенциометр"?
Потом, насколько я знаю, такой вид сервопривода не имеет четко выраженных состояний, то есть подача некоторого потенциала заставит ее непрерывно двигаться в заданном направлении и определить точное местоположение в целом получается невозможно.
Что хотите от привода-то? Может проще обратную связь прикрутить?