Ограничить количество нажатий на кнопку.

Gorky
Offline
Зарегистрирован: 08.01.2018

Подскажите пожалуйста, как ограничить количество нажатий на кнопку. Например 5 раз нажали и больше ардуинка на нее не реагирует до перезапуска.
 

// Circuit settings
#define  IR_PIN  3
#define BTN_PIN 8


// Frequency calculations
// carrier frequency: f = 56000 Hz
// wave period:   T = 1/f = 17.86 µs
// half cycle period: T/2 = 8.93 µs

// assuming carrier_interval_delay + instructions_delay = T/2
#define CARRIER_INTERVAL  4   // adjusted experimentally


// MilesTag definitions
// carrier off space: 600 µs
// header pulse: 2400 µs
// bit0 pulse: 600 µs
// bit1 pulse: 1200 µs

#define MLT_SPACE_INTERVAL  600

// header cycle count: 2400 / 17.86 = 134.3
#define MLT_HEADER_CYCLES 128   // adjusted experimentally

// bit0 cycle count: 600 / 17.86 = 33.6
#define MLT_BIT0_CYCLES   32    // adjusted experimentally

// bit1 cycle count: 1200 / 17.86 = 67.2
#define MLT_BIT1_CYCLES   64    // adjusted experimentally


void setup() {

  pinMode(IR_PIN, OUTPUT);
  pinMode(BTN_PIN, INPUT);

  digitalWrite(BTN_PIN, HIGH);

  Serial.begin(9600);
  Serial.println("Ready...");
}


void loop() {

  boolean btnPressed = digitalRead(BTN_PIN) == LOW;
  if ( btnPressed ) {
    fire();
    delay(200);
  }

  delay(10);
}

void fire() {
  Serial.println("Fire!");

  sendHeader();
  sendByte(0x83);
  sendByte(0x05);
  sendByte(0xE8);
}

void sendHeader() {
  sendPulse(MLT_HEADER_CYCLES);
  delayMicroseconds(MLT_SPACE_INTERVAL);
}

void sendByte(byte x) {
  for(int i=0; i<8; i++) {
    if (x & 0x80) {
      sendPulse(MLT_BIT1_CYCLES);
    } else {
      sendPulse(MLT_BIT0_CYCLES);
    }
    x = x << 1;
    delayMicroseconds(MLT_SPACE_INTERVAL);
  }
}

void sendPulse(int cycles) {
  for (int i=0; i<cycles; i++ ) {
    digitalWrite(IR_PIN, HIGH);
    delayMicroseconds(CARRIER_INTERVAL);
    digitalWrite(IR_PIN, LOW);
    delayMicroseconds(CARRIER_INTERVAL);
  }
}

 

rygoravich
Offline
Зарегистрирован: 04.05.2016

Добавить счетчик нажатий :) .

Например:



void loop() {

  int btnCounter = 0;

  boolean btnPressed = digitalRead(BTN_PIN) == LOW;
  if ( btnPressed && btnCounter < 5) {
    fire();
    btnCounter++;
    delay(200);
  }

  delay(10);
}

 

Gorky
Offline
Зарегистрирован: 08.01.2018

Не выходит  ( 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

rygoravich пишет:

void loop() {

  int btnCounter = 0;

  boolean btnPressed = digitalRead(BTN_PIN) == LOW;
  if ( btnPressed && btnCounter < 5) {
    fire();
    btnCounter++;
    delay(200);
  }

  delay(10);
}

Я бы слово static в начало третьей строки добавил.

Gorky
Offline
Зарегистрирован: 08.01.2018

Великолепно, спасибо большое все работает. Последний вопрос откуда взять значения для вывода на сигментный дисплей склько осталось нажатий.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Вычитаете из максимально разрешенного количества нажатий значение переменной btnCounter

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Gorky пишет:

Великолепно

та хренли великолепного? Мужики, я с Вас офигеваю.

- Памагите!
- дали кусок кода, вставил - не заработало
- Памагите!
- подсказали как поправить
- Великолепно!
потребовалось "из пяти два вычесть"
- Памагите!

Блин, где вытаскивание печёнки на тему, "а что в это коде написано?" и "что означает волшебное слово статик, которое всё разрулило?" Ни хрена ведь ведь не понял, вставил чужой код как мартышка и тут же

Gorky пишет:

Последний вопрос

Ни хрена ведь не последний, потому что понимать что-то ты даже не пытаешься. А вставлять чужие коды не понимая ... через час потребуется что-то ещё. И снова будет "памагите!"

Учитесь же, мужики, ну чего как обезьяны, правда?

Gorky
Offline
Зарегистрирован: 08.01.2018

Я прекрасно понимаю что это так и выглядит, но с програмированием у меня проблемма. Когда то давно в школе в старших классах увлекался. И насчет всего что подсказывали я уже начился и все сообразил). Вычитать из макс значения и отображать на дисплее не проблема. Тут проблема глобальней, дело в том что ограниченное число нажатий будет динамичным, оно будет програмироваться при помощи кнопки. Спросил тупо потому что мб что то другое подсказали бы.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Gorky пишет:

Тут проблема глобальней, дело в том что ограниченное число нажатий будет динамичным, оно будет програмироваться при помощи кнопки. 

Нет тут проблемы. Просто добавляете в программу ещё одну переменную (например btnMaxCounter), в которой будет храниться макс. число нажатий. Значение этой переменной по ходу программы можно "програмировать при помощи кнопки".

Для отображения на дисплее - из переменной с макс. числом нажатий нужно вычесть переменную с текущим числом нажатий: val = btnMaxCounter - btnCounter

Также в условии if будем проверять не btnCounter < 5, а btnCounter < btnMaxCounter

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Какой ауенно полезный код....

BuonanotteMasha
BuonanotteMasha аватар
Offline
Зарегистрирован: 02.01.2018

У меня такой вопрос. Допустим имеется две кнопки и число(int, byte или другого целого типа). Нужен простой алгоритм чтобы задействуя эти кнопки можно было увеличивать число на 1,10,100. Думаю одной кнопкой такое не возможно, поэтому предлагая на двух. 

Думаю организовать счетчик нажатий или чтото типа. Чтобы одна увеличивала число, а другая задавала предел(1,10...)

rygoravich
Offline
Зарегистрирован: 04.05.2016

Необязательно две кнопки. Нажал и отпустил - увеличился счетчик. Нажал и подержал более, например, двух секунд не отпуская (время по вкусу) - увеличился предел.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А Вы никогда видели устройств в которых нажмёшь на кнопку, онс сначала медленно что-то увеличивает, потом быстрее, потом ещё быстрее. Вот и Вам так надо. Первые раз 5 на 1, потом раз пять на 10, потом, если всё ещё не отпусакют)  уже на сто. Всё одной кнопкой делается и человеку такой подход понятен.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Не, предлагаю минимум 4 кнопки, чо уж мелочиться: на одну нажимаем - увеличиваем на 1, на другую - уменьшаем на 1, на третью - увеличиваем на 5, на четвёртую - уменьшаем на пять, ну и далее по списку :) :) :)

Gorky
Offline
Зарегистрирован: 08.01.2018

Если кнопка при включении зажата (>2сек) то выполнить код1, если нет то код2. Но у меня всегда срабатывает если зажата >2сек. Есть всего 1 кнопка. Как задать что бы именно при включении, допустим в первые 3 сек работало условие. ?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Gorky пишет:

Если кнопка при включении зажата (>2сек) то выполнить код1, если нет то код2. Но у меня всегда срабатывает если зажата >2сек. Есть всего 1 кнопка. Как задать что бы именно при включении, допустим в первые 3 сек работало условие. ?

Ну, а я что говорил?

Тот вопрос был НЕ последний. И не будет последнего пока ты кричишь "Великолепно", когда что-то непонятное волшебным образом заработало. Если не разобрался, то ничего великолепного нет. А желания разбираться за тобою замечено не было :(

Gorky
Offline
Зарегистрирован: 08.01.2018

Меня не интересует как прописать условие, какой код впихнуть в него. Я не могу понять как ограничить время работы условия. 
Зачем тогда форумы? 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Gorky пишет:

Зачем тогда форумы? 

А сам-то как думаешь? Неужели, люди собрались на форуме исключительно для того, чтобы рассказывать тебе как посчитать нажатия, как вычесть количество нажатий из максимального и как "ограничить время работы условия"? Вот именно для этого тут люди собрались и больше им заняться решительно нечем? Когда же они все так тебе задолжать-то успели?

Форума для общения по интересам! Люди с общими интересами общаются потому, что им интересно общаться.

Я тебе уже говорил, учись, а не задавай тупые вопросы по каждому чиху. Тогда с тобой будет интересно общаться и люди будут это делать. Пока же от тебя слышно только "памагите" по нескольку раз на дню. Ты ведь ни разу не спросил "что почитать?", и ни разу не спросил "как работает?" то, чтебе подсказали. Вбил как мартышка - заработало и "великолепно", можно следующий тупой вопрос задавать. Причём, вопросы то действительно тривиальные, которые может освоить любой школьник, которому не лень просто почитать какую-нибудь книжку. Ты, думаешь, кому-то интересно отвечать на тупые вопросы? Ты правда так думаешь?

Gorky
Offline
Зарегистрирован: 08.01.2018

Что почитать (я весь день читаю), как работает понимаю, я не знаю синтаксис (если я правильно выразился)

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Синтаксис? Причём тут синтаксис, если ты задаёшь вопросы про совершенно тривиальные алгоритимческие действия, которых не можешь придумать сам! Синтаксис ту не при делах вовсе.

Впрочем, мне пофиг чего ты не знаешь, я уже говорил, это место общения по интересам, а с тобой неинтересно (пока).

Не хочешь слушать, что тебе советуют - не слушай, мы все свободные люди.

BuonanotteMasha
BuonanotteMasha аватар
Offline
Зарегистрирован: 02.01.2018

ЕвгенийП пишет:

А Вы никогда видели устройств в которых нажмёшь на кнопку, онс сначала медленно что-то увеличивает, потом быстрее, потом ещё быстрее. Вот и Вам так надо. Первые раз 5 на 1, потом раз пять на 10, потом, если всё ещё не отпусакют)  уже на сто. Всё одной кнопкой делается и человеку такой подход понятен.

Что ж, подумаю над этим. Позже прикреплю код

BuonanotteMasha
BuonanotteMasha аватар
Offline
Зарегистрирован: 02.01.2018

Вполне рабочий код, воспользовался советом ЕвгенийП и rygoravich, им отдельное спасибо. Теперь также соглашусь что для этого одной кнопки вполне достаточно.

Отлаживал на LCD 4 строки, поскольку не избавился от паразитной delay

#include <Wire.h> // библиотека для управления устройствами по I2C 
#include <LiquidCrystal_I2C.h> // подключаем библиотеку для LCD 1602

LiquidCrystal_I2C lcd(0x3f,20,4); // присваиваем имя lcd для дисплея 20х4

unsigned long time_Pressed;  // Переменные для работы со временем;
unsigned long timeNow;
byte i = 0; // мое число

enum bottonVariants { // Определения для работы с кнопкой;
        BOTTON_CLICK,							
	BOTTON_SHORT,
	BOTTON_LONG,
	BOTTON_NOT,
};
bottonVariants botton = BOTTON_NOT;

void setup() {
  lcd.begin();
  lcd.backlight(); 

  lcd.setCursor(1, 1);
  lcd.print("PROGRAM V1.0");
  
  delay(1000);
  lcd.clear();
  
  pinMode(9, INPUT);	 //пин для кнопки
  digitalWrite(9, HIGH); //подключаем подтягивающий резистор
  
}

void loop() {
  
    if (digitalRead(9) == 0) {	 // Стандартная проверка с антидребезгом;
	delay(50);		 // Ждем для устранения дребезга;
			
	if (digitalRead(9) == 0) {	// Проверяем еще раз;
	    time_Pressed = millis();	// Запоминаем время нажатия кнопки;
            
	    lcd.clear();
            lcd.print("+1");
            delay(200);		 
            botton = BOTTON_CLICK; // однократное нажатие
            
	    while (digitalRead(9) == 0) {		        // Ждем отпускания кнопки;
	       timeNow = millis();				// И засекаем время;
		    if (timeNow - time_Pressed > 1000 && timeNow - time_Pressed < 2000) {	
                    // Было долгое нажатие кнопки - больше 2 с.
                       lcd.clear();				 
		       lcd.print("+10");
		       delay(200);
                       botton = BOTTON_SHORT;   
	            }
	            else if (timeNow - time_Pressed >2000) {	
                    // Было короткое нажатие - менее 2 с но более 1 с.
                       lcd.clear();				
		       lcd.print("+100");
		       delay(200);
                       botton = BOTTON_LONG;  
		    }
	    }
	 }
     }
     
     switch (botton) {	// Здесь выбираем что менять;
			
        case BOTTON_CLICK:			// При одиночном нажатии,

        i++;
        lcd.setCursor(0, 1); lcd.print(i);
	botton = BOTTON_NOT;
	break;
			
	case BOTTON_SHORT:			// При коротком нажатии;
			
        i+=10;
        lcd.setCursor(0, 1); lcd.print(i);
	botton = BOTTON_NOT;
	break;

        case BOTTON_LONG:			// При долгом нажатии,

        i+=100;
        lcd.setCursor(0, 1); lcd.print(i);
	botton = BOTTON_NOT;
	break;
			
	case BOTTON_NOT:
	break;
    }
}

 

BuonanotteMasha
BuonanotteMasha аватар
Offline
Зарегистрирован: 02.01.2018

Можете мне подсказать еще с одним моментом. Если я в свой код добавлю еще одно число i1(тоже целого типа) и задействую еще одну кнопку (пин 8). И захочу например по нажатию на эту кнопку выбирать число над которым собираюсь производить операции(+1,10...) кнопкой(на 9 пине). Тут я думаю одним if не обойдется поскольку хочу мониторить эти два числа на дисплее и чтобы изменение одного никак не отражалось на другом

Выложен код

#include <Wire.h> // библиотека для управления устройствами по I2C 
#include <LiquidCrystal_I2C.h> // подключаем библиотеку для LCD 1602

LiquidCrystal_I2C lcd(0x3f,20,4); // присваиваем имя lcd для дисплея 20х4

unsigned long time_Pressed;  // Переменные для работы со временем;
unsigned long timeNow;
byte i = 0; // мое число  0-255
byte i1 = 0; // мое число 0-255

enum bottonVariants { // Определения для работы с кнопкой;
        BOTTON_CLICK,							
	BOTTON_SHORT,
        BOTTON_NOLONG,
	BOTTON_LONG,
	BOTTON_NOT,
};
bottonVariants botton = BOTTON_NOT;

void setup() {
  lcd.begin();
  lcd.backlight(); 

  lcd.setCursor(1, 1);
  lcd.print("PROGRAM V1.0");
  
  delay(1000);
  lcd.clear();
  pinMode(8, INPUT);	 //пин для кнопки выбора числа
  digitalWrite(9, HIGH); //подключаем подтягивающий резистор
  pinMode(9, INPUT);	 //пин для кнопки операций над числом
  digitalWrite(9, HIGH); //подключаем подтягивающий резистор
  
}

void loop() {
    /////////////////////////////////
    lcd.setCursor(0, 1); lcd.print(i);
    lcd.setCursor(0, 2); lcd.print(i1);
    /////////////////////////////////
            
    if (digitalRead(9) == 0) {	 // Стандартная проверка с антидребезгом;
	delay(50);		 // Ждем для устранения дребезга;
			
	if (digitalRead(9) == 0) {	// Проверяем еще раз;
	    time_Pressed = millis();	// Запоминаем время нажатия кнопки;
            
	    lcd.clear();
            lcd.print("+1");
            delay(200);		 
            botton = BOTTON_CLICK; // однократное нажатие
            
	    while (digitalRead(9) == 0) {		        // Ждем отпускания кнопки;
	       timeNow = millis();				// И засекаем время;
		    if (timeNow - time_Pressed > 1000 && timeNow - time_Pressed < 1500) {	
                    // Было короткое нажатие - менее 1.5 с но более 1 с.
                       lcd.clear();				 
		       lcd.print("+10");
		       delay(200);
                       botton = BOTTON_SHORT;   
	            }
	            else if (timeNow - time_Pressed > 1500 && timeNow - time_Pressed < 2500) {	
                    // Было недолгое нажатие кнопки - менее 2.5 с но более 1.5 с.
                       lcd.clear();				
		       lcd.print("+50");
		       delay(200);
                       botton = BOTTON_NOLONG;  
		    }
	            else if (timeNow - time_Pressed >2500) {	
                    // Было долгое нажатие кнопки - больше 2.5 с.
                       lcd.clear();				
		       lcd.print("+100");
		       delay(200);
                       botton = BOTTON_LONG;  
		    }
	    }
	 }
     }
     
     switch (botton) {	// Здесь выбираем что менять;
			
        case BOTTON_CLICK:			// При одиночном нажатии,
        i++;
        //lcd.setCursor(0, 1); lcd.print(i);
	botton = BOTTON_NOT;
	break;
			
	case BOTTON_SHORT:			// При коротком нажатии;			
        i+=10;
        //lcd.setCursor(0, 1); lcd.print(i);
	botton = BOTTON_NOT;
	break;

        case BOTTON_NOLONG:			// При недолгом нажатии,
        i+=50;
        //lcd.setCursor(0, 1); lcd.print(i);
	botton = BOTTON_NOT;
	break;

        case BOTTON_LONG:			// При долгом нажатии,
        i+=100;
        //lcd.setCursor(0, 1); lcd.print(i);
	botton = BOTTON_NOT;
	break;
			
	case BOTTON_NOT:
        lcd.setCursor(0, 1); lcd.print(i);
	break;
    }
   
}

 

BuonanotteMasha
BuonanotteMasha аватар
Offline
Зарегистрирован: 02.01.2018

Временно сократил  код чтобы не мозолил глаза, может кто нибудь сталкивался с подобным. Как сделать чтобы по нажатию кнопки на 8 пине в переменную chislo записывалось первое chislo_One, затем по повторному нажатию второе chislo_Two, затем снова chislo_One ...

 

.

byte chislo_One = 0; //  число 0-255
byte chislo_Two = 0; //  число 0-255
byte chislo; // результат выбора

enum bottonVariants { // Определения для работы с кнопкой;
        BOTTON_CLICK,							
	BOTTON_NOT,
};
bottonVariants botton = BOTTON_NOT;

void setup() {

  pinMode(8, INPUT);	 //пин для кнопки выбора числа
  digitalWrite(9, HIGH); //подключаем подтягивающий резистор
  pinMode(9, INPUT);	 //пин для кнопки операций над числом
  digitalWrite(9, HIGH); //подключаем подтягивающий резистор
  
}

void loop() {
    
    
    if (digitalRead(8) == 0) {	 // Стандартная проверка с антидребезгом;
	delay(50);		 // Ждем для устранения дребезга;
    if (digitalRead(8) == 0) {	// Проверяем еще раз;
        // этой кнопкой нужно выбрать из chislo_One и chislo_Two
        // chislo - буфер для хранения числа chislo_One или chislo_Two
        // chislo = присвоить переменной  выбранное	 
	 }
     }
     
    if (digitalRead(9) == 0) {	 // Стандартная проверка с антидребезгом;
	delay(50);		 // Ждем для устранения дребезга;
			
	if (digitalRead(9) == 0) {	// Проверяем еще раз
          botton = BOTTON_CLICK; // однократное нажатие
          // редактирование числа
	 }
     }
     
     switch (botton) {	// Здесь выбираем что менять;
			
        case BOTTON_CLICK:			// При одиночном нажатии,
        chislo++;
	botton = BOTTON_NOT;
	break;
			
	case BOTTON_NOT:
        // код вывода на ЖК
	break;
    }
   
}

 

vk007
Offline
Зарегистрирован: 16.06.2015

BuonanotteMasha пишет:

Как сделать чтобы по нажатию кнопки на 8 пине в переменную chislo записывалось первое chislo_One, затем по повторному нажатию второе chislo_Two, затем снова chislo_One ...

Завести флаг, который бы инвертировался при каждом нажатии кнопки, и если флаг в одном состоянии, то в chislo пишем chislo_One, если в другом - то chislo_Two.

-----

Зачем вы задаете один и тот же вопрос в разных темах? Их же все-равно читают одни и те же люди.