Помогите новичку с кнопками

rodot
Offline
Зарегистрирован: 18.10.2011

Доброго времени суток помогите новичку.

2 кнопки  и 1 светодиод. При нажатий  4 раза на  1-ю кнопку загорается светодиод , но при нажатий 2-й кнопки светодиод гаснет.   

Думаю написать через. switch () { case } . Поправте если не так.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Можно и через switch() {case} , а можно и так.

int knopka=0;

void setup ()

{
  
  pinMode(13,OUTPUT);
   pinMode(2,INPUT);
    pinMode(3,INPUT);
    
}


void loop()

{
  if(digitalRead(2)==HIGH)
  
  {
    knopka++;
    delay(500);
    
  }
   if(knopka>=4)
  
  {
    digitalWrite(13,HIGH);
    
  }
  
  
  if(digitalRead(3)==HIGH&&knopka>=4)
  
  {
    knopka=0;
    
  }
  if(knopka<4)
  
  {
    digitalWrite(13,LOW);
    
  }
  
  
}

 

rodot
Offline
Зарегистрирован: 18.10.2011

Спасибо за пример. Еще вопрос,  как можно организовать счетчик, чтобы считать нажатия кнопки и записывать количество нажатий , чтобы потом можно было это значение использовать в том же  switch() {case} ?

HOCKU
HOCKU аватар
Offline
Зарегистрирован: 25.04.2011
int clicksCounter=0;

void setup() {
  pinMode(2,INPUT);    
}

void loop() {
  if(digitalRead(2)) {
    clicksCounter++;
  }
}

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

rodot
Offline
Зарегистрирован: 18.10.2011

Спасибо, написал по вашему примеру все работает. Еще один вопрос , если знаете пример с описанием как использовать внешнее прерывание attachInterrupt. А то в программе много задержек и сброс немогу корректно сделать.

HOCKU
HOCKU аватар
Offline
Зарегистрирован: 25.04.2011
volatile int clicksCounter=0;
 
void setup() {
  pinMode(2, INPUT);
  attachInterrupt(0, increase, RISING);
}

void loop() {
}

void increase() {
  clicksCounter++;
}

 вот хорошая статья по прерываниям http://arduino.ru/Reference/AttachInterrupt

rodot
Offline
Зарегистрирован: 18.10.2011

Большое спасибо HOCKU, воспользовался примером все заработало , но правда команда на  прерывание срабатывает  только в цикле, подскажите пример, как сделать проще,  чтобы  команда по прерыванию сразу срабатывала .

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

leshak
Offline
Зарегистрирован: 29.09.2011

 Да нет, прерывание срабатывает-то сразу. Это "команда на исполнение" проверяет "сработало ли прерывание" когда "очередь до нее дошла".

Выход вообщем-то только один. Забыть про задержки. Подход должен быть примерно такой:

Например нам нужно все время проверять "нажатие кнопки" (на кнопке висит прерывание которые устанавливает флаг) и при этом мигать светодиодом. Медленно. Раз в секунду. Раньше бы вы в loop делали что-то типа

  1.  Включить светодиод
  2. delay(1000)
  3. Выключить светодиод
  4. Проверить флаг, была-ли сработка прерывания. Если была сделать что-то полезное

Естественно на втором шаге, даже если прерывание сработает, то "ничего не произойдет", пока программа не доберется до шага 4.

Что-бы этого избежать нужно:

  1. Включить светодиод
  2. Запомнить в какую нибудь переменную время когда его нужно будет выключить (текущие время + секунда)
  3. Проверить "текущие время больше времени_выключение?", если да - выключить.
  4. Проверить флаг, была-ли сработка прерывания. Если была то сделать что-то полезное

Ну и крутить пункты 3, 4 в цикле. Все время "проверять по очереди".

Фактически весь скетч должен строиться по принципу: "проверить условие что нужно что-то сделать, если условие не выполняется (не настало время, кнопку никто не нажал) - идти дальше. проверять следующие условие. и так пробегатся по "условиям" раз за разом. как можно быстрей. тогда будет иллюзия одновременности.

Представте себе что вы варите картошку. Вы можете включить таймер на час, ждат пока он зазвенит (и не реагировать ни на что, это будет delay(1 час) ),  выключить картошку.  А можете поставить картошку, запомнить "когда нужно будет выключить", ну и бегать по своим делам, время от времени поглядывая на часы "не пора ли выключить?", посматривать в окно "не идет военком с повесткой?" (прерывание) и т.п.