Работа с кнопками. В помощь новичку.

demon969
Offline
Зарегистрирован: 24.04.2012

Спокойнее.

Вот как написал создатель поста

digitalWrite(13,!digitalRead(13));
       flag=1;
        //это нужно для того что бы с каждым нажатием кнопки
        //происходило только одно действие
        // плюс защита от "дребезга"  100%

Я про переменную flag вообще то имел ввиду в последнем посте своем.

maksim
Offline
Зарегистрирован: 12.02.2012

Я спокоен, вы поконкретнее вопросы задавайте, а не один и тот же вопрос.

flag-  это флаг, к устранению дребезга тоже имеет косвенное отношение, я бы даже сказал - никакого.

У автора 100%ного антидребезга последний отсутствует по причине этого куска:

if(digitalRead(swich)==LOW)
  { 
    analogWrite(ledPin, led);
    delay(30); 
  }

а именно - по причине задержки.

Илья73
Offline
Зарегистрирован: 06.09.2013

Помогите разобраться.Все работает вроде нормально, но не до конца :)

Есть кнопка и светодиод.При нажатии на кнопку загорается светодиод на 10 пине и начинает работать сенсор света на реле, реле на 8 пине.Кнопка и сенсор считывается аналоговыми входами.При повторном нажатии на кнопку светодиод гаснет, и отключается сенсор света – не реагирует.

 Таким образом имеем простой выключатель сенсора света с индикацией на светодиод.Но проблема в том что когда темно и реле HIGH (включено) нажатием на кнопку реле не отключается. А отключается только когда станет светло.

Или я не в том направлении двигаюсь?

#define ePin 10  // желый светодиод
 int knop=0;     //кнопка
 int x =0;       
 int sensor=0;   // свето сенсор
 #define rPin 8  // реле 
void setup()
 {
  pinMode(ePin,1);
  pinMode(rPin,1); 
 }
void loop()
{
  sensor=analogRead(1);
  knop = analogRead(0);
  if(knop>675&&knop<690&&x==0)
  {  
    digitalWrite(10,!digitalRead(10));
    x=1;
  }
    if(knop<675&&x==1)
  {
     x=0; 
  }
   if(sensor<500&&digitalRead(10)==1)digitalWrite(8,1);
   else if (sensor>550)digitalWrite(8,0);
   delay(10);
}

 

maksim
Offline
Зарегистрирован: 12.02.2012
   if(sensor<500||digitalRead(10)==1)digitalWrite(8,1);
   else if (sensor>550||digitalRead(10)==0)digitalWrite(8,0);

 

Илья73
Offline
Зарегистрирован: 06.09.2013

maksim спасибо. Но к сожалению при таком варианте при нажатии кнопки включается светодиод и реле вместе, и при повторном нажатии ни как не реагирует вообще(

 

maksim
Offline
Зарегистрирован: 12.02.2012

Так вы опишите алгоритм работы - что хотите.

Илья73
Offline
Зарегистрирован: 06.09.2013

Нажали кнопку  - включили сенсор. О  том что активен сенсор сигнализирует светодиод.

Нажали кнопку еще раз - отключили сенсор. Диод погас.

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

А хотелось бы что бы отрубалось как "рубильником"

maksim
Offline
Зарегистрирован: 12.02.2012
if(digitalRead(10)==1)
{
  if(sensor<500)digitalWrite(8,1);
  else if (sensor>550)digitalWrite(8,0);
}
else digitalWrite(8,0);

 

Илья73
Offline
Зарегистрирован: 06.09.2013

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

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

maksim
Offline
Зарегистрирован: 12.02.2012

Что у вас за реле? Модуль реле с инвертированным входом? О таких вещах надо писать в первую очередь.

if(digitalRead(10)==1)
{
  if(sensor<500)digitalWrite(8,1);
  else if (sensor>550)digitalWrite(8,0);
}
else digitalWrite(8,1);

 

Илья73
Offline
Зарегистрирован: 06.09.2013

модуль с тремя ногами (реле, диод, транзистор с резистором и светодиод)...., сейчас поставлю вместо реле светик.

Поставил светодиод, реагирует точно так же как и реле.

Вставил ваш код, поставил реле обратно. При загрузке просто включилось реле и кнопка глючить стала  :) значит не инвертирован

maksim
Offline
Зарегистрирован: 12.02.2012

Тогда с примером из #144 поста все должно работать, если на 10 выводе логический 0 то и на 8 выводе будет тоже 0.

Илья73
Offline
Зарегистрирован: 06.09.2013

Кстати вот так все работает отлично!

Но!  тогда отсутствует переход от (зуммерения) Логики вообще не могу понять - почему?

#define ePin 10  // желый светодиод
 int knop=0;     //кнопка
 int x =0;       
 int sensor=0;   // свето сенсор
 #define rPin 8  // реле 
void setup()
 {
  pinMode(ePin,1);
  pinMode(rPin,1); 
 }
void loop()
{
  sensor=analogRead(1);
  knop = analogRead(0);
  if(knop>675&&knop<690&&x==0)
  {  
    digitalWrite(10,!digitalRead(10));
    x=1;
  }
    if(knop<675&&x==1)
  {
     x=0; 
  }
    if(sensor<500&&digitalRead(10)==1)digitalWrite(8,1);
    else  digitalWrite(8,0);

   delay(10);
}

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

Не стабильно работает... Буду искать другой подход.

Илья73
Offline
Зарегистрирован: 06.09.2013

Максим, все заработало правильно как в посте 144. Сегодня все разобрал и собрал заново. Или проводки на макетке не контачили  или мой мозг к вечеру перегрелся. Скорее второе )

Спасибо)

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

По поводу аналоговых кнопок награфоманил в блоге

Леший в мире Ардуины: Читаем аналоговые кнопки. Часть 1

Раздел "железная составляющая" - в принципе описывает то же самое что и nestandart в сообщении #1 . Причем, как мне кажется у него более внятно "разжеванно". Но может и мое кто-нибудь поймет :).

Остальное - альтернатива подходу приведенному maksim в сообщении #5 .

Главное отличие - я старался "спрятать" различие в работе с цифровыми и "аналоговыми кнопками". Что-бы базовые примеры из стартового поста было попроще адаптировать под аналоговые кнопки. Или "смешивать" в одном скетче аналоговые и цифровые кнопки.

Ну и, с таким подходом, мне кажется можно будет и одновременное нажатие нескольких кнопок ловить.  Просто намерять какое значение дает комбинация и объявить ее "еще одним псевдо-цифровым пином".

 

vvadim
Offline
Зарегистрирован: 23.05.2012

Интересно и доходчиво. Уверен что многим пригодится. Жду библиотеку по кнопкам!

jane Jack
Offline
Зарегистрирован: 08.10.2013

Здрасти всем. На днях приобрел атот чудо контролер и пока пытаюсь разобраться с языком. помогите пожалуста прикрутить кнопочку к моему железу

#define led 12


// переменная, которая будет содержать символ, полученный через последовательный порт
int ricevuto = ' '; 

void setup() {
   Serial.begin(9600);     // открывает последовательный порт на скорости 9600 бит / с
   pinMode(led, OUTPUT);  // определяет pin на которой подключен led как выход
  }

void loop() {
   if (Serial.available() > 0) { // если последовательный буфер содержит данные
      ricevuto = Serial.read(); // присваиваем переменной значение из буфера последовательного порта
      switch (ricevuto){  
         case '0':
            digitalWrite(led,LOW); // если я получаю 0 выключить светодиод led
            Serial.print(0);
            break;
         case '1':
            digitalWrite(led,HIGH); // если я получаю 1 включить светодиод led
            Serial.print(1);
            break;
        
       }}}

и вот эта кнопочка:

#define led 12

void setup() 
{

pinMode(12,OUTPUT);//конфигурируем пин как выход ( к нему подключен светодиод)
digitalWrite(31,HIGH);//включаем внутренний pull-up резистор
}

void loop() 
{
  
  
    digitalWrite(12,!digitalRead(31));//устанавливаем значение выхода 12 противоположное 
   //входу 31 . Т.е. когда на входе LOW (есть сигнал) на выходу устанавливаем HIGH
 
  
 
}

Все исходники и моя пока в черновом варианте красяфка" окно интерфейса" лежат в архиве здесь:http://yadi.sk/d/u4-U-r0dAg5Yz

Monsel
Offline
Зарегистрирован: 27.10.2013

leshak пишет:
По поводу аналоговых кнопок награфоманил в блоге

Леший в мире Ардуины: Читаем аналоговые кнопки. Часть 1

Раздел "железная составляющая" - в принципе описывает то же самое что и nestandart в сообщении #1 . Причем, как мне кажется у него более внятно "разжеванно". Но может и мое кто-нибудь поймет :).

Остальное - альтернатива подходу приведенному maksim в сообщении #5 .

помогите понять синтаксическую конструкцию выражения (вложенный if ) из вашей программы:

//ищем максимум/минимум

    if(val<min if="" min="val;" val="">max)max=val;
    
    // добавляем замер к среднему
Андрей01
Offline
Зарегистрирован: 04.11.2013
#include <Servo.h>

Servo servo_gor;// создаём объект для контроля сервы

int val;//
void setup()  
{  
   servo_gor.attach(9);// подключаем серву к пину 9      
   pinMode(10, INPUT);   //объявляем 10 пин как вход    
}
void loop()                       
{
   val = digitalRead(10);    // узнаём состояние кнопки
  if(val)                    // тоже самое что (val == HIGN)  // если 10 пин замкнут
     {
     servo_gor.writeMicroseconds(2000);
   delay(2000);
 servo_gor.writeMicroseconds(2150);
   delay(2000);
     }               // делаем какуюто каманду
  if(!val)                   // тоже что и val==LOW           // если 10 пин не замкнут
     {
     servo_gor.writeMicroseconds(2188);
   delay(1500);
     servo_gor.writeMicroseconds(2000);
   delay(2000);
   }               // делаем другую каманду
}

Доброго времени суток, подскажите правильно ли я написал програмку? У меня не ругается на программу а вот в железе смогу пока сделать чють попоже, ориентие конец недели. А так надо управлять программным кодом при нажатии или отпускании кнопки (кнопок).

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

maksim пишет:

Одно из решений "аналоговой клавиатуры", которое можно подредактировать и под вашу схему:

#define NUM_KEYS 5
int  adc_key_val[NUM_KEYS] = {30, 150, 360, 535, 760};

void setup()
{
  Serial.begin(9600);
}

void loop() 
{
  int key = get_key(A0);
  if(key) Serial.println(key, DEC);
}

int get_key(int key_pin)
{
  int input = analogRead(key_pin);
  int k;
  for(k = 0; k < NUM_KEYS; k++) 
    if(input < adc_key_val[k]) 
      return k + 1;     
  return 0;
}

данный код написан под эту схему

как видите количество кнопок задается параметром NUM_KEYS,
а "диапазоны" акуратненько "лежат" в массиве adc_key_val[].

 

Уважаемый Максим. Я собрал схему. запустл Ваш скетч и скетч из примера на analogRead, и видно, что значения без нажатия кнопок скачут вверх от 0 до 1023 и обратно от 1023 до 0 с разным шагом. Так и должно быть?

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

Так быть не должно. При отпущеных кнопках на входе будет 1023. Ищите ошибку в сборке. Обратите особое внимание на R2.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

nestandart пишет:

Так быть не должно. При отпущеных кнопках на входе будет 1023. Ищите ошибку в сборке. Обратите особое внимание на R2.

 

пересмотрю схему.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

ingener.solovyev пишет:

nestandart пишет:

Так быть не должно. При отпущеных кнопках на входе будет 1023. Ищите ошибку в сборке. Обратите особое внимание на R2.

 

пересмотрю схему.

 

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

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

Впишите  delay(100);  в строку 12.

Можно и кондер. 0.1 - 10мкф между входом и землей.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

nestandart пишет:

Впишите  delay(100);  в строку 12.

Можно и кондер. 0.1 - 10мкф между входом и землей.

входом вы называете сигнальный провод на A0?

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

Да. Проще говоря поставьте кондер между +5  и GND.

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

Правла с кондером вы получите некоторую энерциальность в работе ( зависит от емкости кондера). Если это не критично то ставьте кондер.

maksim
Offline
Зарегистрирован: 12.02.2012

Не ставьте конденсатор - так вы только сделаете хуже. Вы и ловите эти "соседние кнопки" только по той причине что на линии не мгновенно устанавливается нужное напряжение.

byte get_key(int key_pin)
{
  if(analogRead(key_pin) < adc_key_val[NUM_KEYS-1])
  {
    byte k[3];
    for(byte i = 0; i < 3; i++)
    {
      delay(10);
      k[i] = 0;
      for(byte j = 0; j < NUM_KEYS; j++)
      { 
        if(analogRead(key_pin) < adc_key_val[j]) 
        {
          k[i] = j + 1;
          break;
        }
      }
    }
    if((k[0] > 0) && (k[0] == k[1]) && (k[0] == k[2]) && (k[1] == k[2])) return k[0];
  }
  return 0;
}

 

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

maksim пишет:

Не ставьте конденсатор - так вы только сделаете хуже. Вы и ловите эти "соседние кнопки" только по той причине что на линии не мгновенно устанавливается нужное напряжение.

byte get_key(int key_pin)
{
  if(analogRead(key_pin) < adc_key_val[NUM_KEYS-1])
  {
    byte k[3];
    for(byte i = 0; i < 3; i++)
    {
      delay(10);
      k[i] = 0;
      for(byte j = 0; j < NUM_KEYS; j++)
      { 
        if(analogRead(key_pin) < adc_key_val[j]) 
        {
          k[i] = j + 1;
          break;
        }
      }
    }
    if((k[0] > 0) && (k[0] == k[1]) && (k[0] == k[2]) && (k[1] == k[2])) return k[0];
  }
  return 0;
}

 

 

Я Вам благодарен, но могли бы Вы, мне, недалекому человеку, сказать куда вставить эту часть кода?

maksim
Offline
Зарегистрирован: 12.02.2012
#define NUM_KEYS 5
int  adc_key_val[NUM_KEYS] = {30, 150, 360, 535, 760};

void setup()
{
  Serial.begin(9600);
}

void loop() 
{
  int key = get_key(A0);
  if(key) Serial.println(key, DEC);
}

byte get_key(int key_pin)
{
  if(analogRead(key_pin) < adc_key_val[NUM_KEYS-1])
  {
    byte k[3];
    for(byte i = 0; i < 3; i++)
    {
      delay(10);
      k[i] = 0;
      for(byte j = 0; j < NUM_KEYS; j++)
      { 
        if(analogRead(key_pin) < adc_key_val[j]) 
        {
          k[i] = j + 1;
          break;
        }
      }
    }
    if((k[0] > 0) && (k[0] == k[1]) && (k[0] == k[2]) && (k[1] == k[2])) return k[0];
  }
  return 0;
}

 

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

maksim пишет:

#define NUM_KEYS 5
int  adc_key_val[NUM_KEYS] = {30, 150, 360, 535, 760};

void setup()
{
  Serial.begin(9600);
}

void loop() 
{
  int key = get_key(A0);
  if(key) Serial.println(key, DEC);
}

byte get_key(int key_pin)
{
  if(analogRead(key_pin) < adc_key_val[NUM_KEYS-1])
  {
    byte k[3];
    for(byte i = 0; i < 3; i++)
    {
      delay(10);
      k[i] = 0;
      for(byte j = 0; j < NUM_KEYS; j++)
      { 
        if(analogRead(key_pin) < adc_key_val[j]) 
        {
          k[i] = j + 1;
          break;
        }
      }
    }
    if((k[0] > 0) && (k[0] == k[1]) && (k[0] == k[2]) && (k[1] == k[2])) return k[0];
  }
  return 0;
}

 

 

Максим, а могли бы Вы на этом примере показать, как упаковать это чудо в отдельную библиотеку?

Пример с сайта  (Morse) не совсем понятен для данного случая. 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

максим, и у меня просьба - прокомментируйте свой код, что-то непонятно как оно работает (ну я тут недавно в C++ ...)

kaznachej
Offline
Зарегистрирован: 21.01.2012

Здравствуйте, форумчане! Помогите с моей проблемкой.

Нужно при кратковременном нажатии кнопки "+" (или "-") увеличивать (уменьшать) число на единицу. При удержании этой кнопки нужно увеличивать (уменьшать) число на единицу в полсекунды. При удержании дольше 5 сек, добавлять (или отнимать) десятки с такой же частотой, А при удержании дольше 10 сек увеличивать (уменьшать) сотни этого числа раз в полсекунды.

Вот часть моего кода для обработки кнопок:

if (digitalRead(pin_plus)==HIGH&&flag_plus==0){        //
    n_ust++; lcd.clear(); flag_plus=1; }               // обрабатываем кнопку          
    if (digitalRead(pin_plus)==LOW&&flag_plus==1){     // +
    flag_plus=0;}                                      // количества витков
    
    if (digitalRead(pin_plus)==HIGH){
      if ((millis()-previousMillis)>100){
       previousMillis=millis();
       n_ust++; lcd.clear();
      } 
    }
                  
    
    
    if (digitalRead(pin_min)==HIGH&&flag_min==0){           //
    n_ust--; lcd.clear(); flag_min=1;}                      // обрабатываем кнопку          
    if (digitalRead(pin_min)==LOW&&flag_min==1){            // -
    flag_min=0;}                                            // количества витков
    
    if (digitalRead(pin_min)==HIGH){
      if ((millis()-previousMillis)>100){
       previousMillis=millis();
       n_ust--; lcd.clear();
      } 
    }

нужная переменная n_ust.

vvadim
Offline
Зарегистрирован: 23.05.2012

Попробовал  так

  if (buttonLeftState==HIGH) {
    currentMillis = millis();
    if(currentMillis - previousMillis < 5000) {
      previousMillis = currentMillis; 
      val-= 1;
      if(val <= 0) {
        val = 0;
      }
    }
    else if(currentMillis - previousMillis > 5000) {
      previousMillis = currentMillis; 
      val-= 10;
      if(val <= 0) {
        val = 0;
      }
    }
  }

отнимает только по единице. Как заставить десятки отнимать?

kaznachej
Offline
Зарегистрирован: 21.01.2012

Решил свою проблему. Толькопривязку взял не ко времени, а к числу. Вот моя программа для намоточного станка, может кому будет нужна\полезна:

/*
//////////////////////////////////////// 
///Счетчик витков намоточного станка.///
////////////////////////////////////////
Отображает на ЖК (8 символов, 2 строки) дисплее заданное и 
реальное количество витков.
При достижении заданного количества витков, выдает цифровой 
сигнал на клемму OUT и сигнализирует звуком.
Счетчик имеет 4 кнопки управления: сброс; +; -; прог.
В режиме счета кнопки + и - не работают, кнопка сброс - 
сбрасывает в 0 реальные показания витков, кнопка прог - 
переводит счетчик в режим установки заданного количества витков.
В этом режиме кнопки + и - увеличиват или уменьшают это значение,
кнопка сброс - сбрасывает устанавливаемые показания в 0,
кнопка прог - возвращает устройство в режим счета. При этом 
происходит запоминание заданного количества витков в
энергонезависимой памяти устройства
  

  
  Схема подключения:
 * LCD RS пин к цифр. выходу 11
 * LCD Enable пин к цифр. выходу 10
 * LCD R/W к Общему
 * LCD VO пин (пин 3) к ШИМ-выходу 9
 * LCD D4 пин к цифр. выходу 8
 * LCD D5 пин к цифр. выходу 5
 * LCD D6 пин к цифр. выходу 7
 * LCD D7 пин к цифр. выходу 6

 зуммер пин 12
 контраст пин 9
 кнопка сброс пин 14
 кнопка + пин 15
 кнопка - пин 16
 кнопка прог пин 17
 вых синг пин 18
 ик излучатель пин 19
 ик приемник пин 4

 */

 #include <EEPROM.h>
 #include <LiquidCrystal.h>

LiquidCrystal lcd(11, 10, 8, 5, 7, 6);

word n_real=0;
word n_ust=0;

int pin_res=14;
int pin_plus=15;
int pin_min=16;
int pin_prog=17;

int pin_Zum=12;
int pin_signal=18;
int pin_ik_out=19;
int pin_ik_in=4;

boolean flag_res=0;
boolean flag_plus=0;
boolean flag_min=0;
boolean flag_prog=0;

boolean flag_schet=0;

boolean regim=0;

long previousMillis=0;

word prew_n_ust=0;

long i=0;



void setup() {
  
  pinMode(9, OUTPUT); 
  analogWrite(9, 70);           // устанавливаем ШИМ выход контрастности 
  lcd.begin(8, 2);              // устанавливаем кол-во столбцов и строк
  

pinMode(pin_res, INPUT);
pinMode(pin_plus, INPUT);
pinMode(pin_min, INPUT);
pinMode(pin_prog, INPUT);

pinMode(pin_signal, OUTPUT);
pinMode(pin_ik_out, OUTPUT);
pinMode(pin_ik_in, INPUT);

 tone(pin_Zum, 2000, 70);
 delay(150);
 tone(pin_Zum, 3000, 85);
 delay(150);
 tone(pin_Zum, 4000, 100);

 n_ust=word(EEPROM.read(0), EEPROM.read(1));
}

void loop() {
  
  if (digitalRead(pin_prog)==HIGH&&flag_prog==0){              // меняем режимы:
    regim=!regim; flag_prog=1; lcd.clear();}                   // программирования (при 1) и  
  if (digitalRead(pin_prog)==LOW&&flag_prog==1){               // счета (при 0)
   flag_prog=0;}
  
  
  if (regim==0){                        // считаем витки
  
    if (digitalRead(pin_res)==HIGH&&flag_res==0){          //
    delay(50); n_real=0; flag_res=1; lcd.clear();}         // обрабатываем кнопку          
    if (digitalRead(pin_res)==LOW&&flag_res==1){           // сброс
    flag_res=0;}                                           // реального количества витков
    
    digitalWrite(pin_ik_out, HIGH);                      // включаем ИК излучатель
                                                         //
    if (digitalRead(pin_ik_in)==LOW&&flag_schet==0){     // ведем счет
    n_real++;              flag_schet=1;}                // витков          
    if (digitalRead(pin_ik_in)==HIGH&&flag_schet==1){    // 
    flag_schet=0;}                                       // 
    
    if (n_real==n_ust){                           // при достижении
                                                  // заданного количества
      lcd.clear();                                // витков
      digitalWrite(pin_signal, HIGH);             // сбрасываем счетчик,
      delay(50);                                  // выдаем выходной сигнал, 
      digitalWrite(pin_signal, LOW);              // пикаем
      if (n_real!=0)tone(pin_Zum, 2000, 300);     // и
      n_real=0;                                   //
      delay(100); }                               // ждем переезда
    
    lcd.setCursor(0, 0);               // выводим на дисплей
    lcd.print(n_real);                 // показания счетчика
    lcd.setCursor(0, 1);               // и заданного 
    lcd.print(n_ust);                  // количества витков
    
  }
  
  
  if (regim==1){                    // настраиваем количество витков
    
 //   n_real=0;
 int pause=250;
    
    digitalWrite(pin_ik_out, LOW);               // выключаем ИК излучатель
    
    if (digitalRead(pin_res)==HIGH&&flag_res==0){           //
    n_ust=0; lcd.clear(); flag_res=1;}                     // обрабатываем кнопку          
    if (digitalRead(pin_res)==LOW&&flag_res==1){           // сброс
    flag_res=0;}                                           // заданного количества витков
    
    if (digitalRead(pin_plus)==HIGH&&flag_plus==0){        //
     lcd.clear(); flag_plus=1; prew_n_ust=n_ust;}          // обрабатываем кнопку          
    if (digitalRead(pin_plus)==LOW&&flag_plus==1){         // +
    flag_plus=0;}                                          // количества витков
    
    if (digitalRead(pin_plus)==HIGH){
      if (((n_ust-prew_n_ust)<15)&&((millis()-previousMillis)>pause)){
        n_ust++; previousMillis=millis(); lcd.clear();}
      else if (((n_ust-prew_n_ust)<220)&&((millis()-previousMillis)>pause)){
        n_ust=n_ust+10; previousMillis=millis(); lcd.clear();}
      else if (((n_ust-prew_n_ust)<2620)&&((millis()-previousMillis)>pause)){
        n_ust=n_ust+100; previousMillis=millis(); lcd.clear();}
      else if (((n_ust-prew_n_ust)<65500)&&((millis()-previousMillis)>pause)){
        n_ust=n_ust+1000; previousMillis=millis(); lcd.clear();} 
    }
                  
                  
  if (digitalRead(pin_min)==HIGH&&flag_min==0){         //
  lcd.clear(); flag_min=1; prew_n_ust=n_ust;}           // обрабатываем кнопку          
  if (digitalRead(pin_min)==LOW&&flag_min==1){          // -
  flag_min=0;}                                          // количества витков
    
  if (digitalRead(pin_min)==HIGH){
    if (((prew_n_ust-n_ust)<15)&&((millis()-previousMillis)>pause)){
      n_ust--; previousMillis=millis(); lcd.clear();}
    else if (((prew_n_ust-n_ust)<220)&&((millis()-previousMillis)>pause)){
      n_ust=n_ust-10; previousMillis=millis(); lcd.clear();}
    else if (((prew_n_ust-n_ust)<2620)&&((millis()-previousMillis)>pause)){
      n_ust=n_ust-100; previousMillis=millis(); lcd.clear();}
    else if (((prew_n_ust-n_ust)<65500)&&((millis()-previousMillis)>pause)){
      n_ust=n_ust-1000; previousMillis=millis(); lcd.clear();} 
   }
    
    EEPROM.write(0, highByte(n_ust));      // записываем значение в память
    EEPROM.write(1, lowByte(n_ust));       //
    
    lcd.setCursor(0, 0);               // выводим на дисплей
    lcd.print(n_real);                 // показания счетчика
    lcd.setCursor(0, 1);               // и заданного 
    lcd.print(n_ust);                  // количества витков
    lcd.setCursor(7, 1);               // выводим букву Р 
    lcd.print("P");                    // в режиме программирования
  }
  
  
}  // конец loop

 

 

vvadim
Offline
Зарегистрирован: 23.05.2012

Попробовал сделать привязку к числу. Работает. Только мне не совсем удобно.

 Нужен такой алгоритм: 

- нажимаю или удерживаю до 5 сек - +- единицы 

- удерживаю более 5 сек -  +- десятки

- отпускаю (таймер обнулился) и опять нажимаю - +- единицы 


if (buttonRightState==HIGH ) {
  currentMillis = millis();
  if((currentMillis - previousMillis) < 5000) {
    val +=  1;
    if(val >= 1000) {
      val = 1000;
    }
  }
  else if((currentMillis - previousMillis) > 5000) {
    val += 10;
    if(val >= 1000) {
      val = 1000;
    }
  }
}
if (buttonRightState==LOW ) {
  previousMillis = currentMillis;
}

Десятки после 5 сек не хотят прибавляться    

step962
Offline
Зарегистрирован: 23.05.2011

Чтобы заработало, как задумано, необходимо анализировать не только СОСТОЯНИЯ, но и СОБЫТИЯ.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Объясните, как эти кнопки работают:

maksim
Offline
Зарегистрирован: 12.02.2012

Это матричная клавиатура, погуглите. Только вот использовать ее для 4-х кнопок неразумно.

demon969
Offline
Зарегистрирован: 24.04.2012

 

 

Возможно ли отследить одновременное нажатие двух кнопок, при выше приведенной схеме?

Клапауций
Offline
Зарегистрирован: 10.02.2013

demon969 пишет:

Возможно ли отследить одновременное нажатие двух кнопок, при выше приведенной схеме?

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

Kish
Offline
Зарегистрирован: 18.01.2014

Приветствую.

Тоже начал работать с тактовой кнопкой. Воспользовался библиотекой Bounce версии 2. Вот код:

#define BUTTON_ENTER 13
Bounce buttonEnter = Bounce();

void setup()
{
  pinMode(BUTTON_ENTER, INPUT);
  buttonEnter.attach(BUTTON_ENTER);
  buttonEnter.interval(5);
}

void loop()
{
  switch(mainMenu)
  {
    case(1):

    break;

    case(2):

    break;

    case(3):
    display_lcd(0,0,"Ololo");
    delay (1000);
    lcd.clear();
    mainMenu = 0;
    break;

  default:
     if (buttonEnter.update())
    {
      if (buttonEnter.read() == HIGH) {
         mainMenu = 3;
       }
    }
    break;
  }
}

Подключил, как видите по коду, к 13 пину, на котором сидит и светодиод, расположенный по дефолту на плате Ардуино Уно. Кнопка подключена по этой схеме: http://arduino.ru/tutorials/button через резистор на 10 кОм. При нажатии на кнопку, светодиод, который расположен на плате загорается сразу, а вот надпись на экране появляется, примерно, через 2 секунды удержания кнопки. Хотелось бы, чтобы надпись появлялась быстрее. Что я делаю не так?

Спасибо.

codex
Offline
Зарегистрирован: 26.01.2014

Уважаемые форума!

По коду: если светло - на выходах 22 и 23 LOW and HIGH соответственно, темно - наоборот. 

Есть такая проблема, как к этому коду прикрутить две кнопки (в моём случае это концевики) так, чтобы при нажатии одной из кнопок на двух этих выходах одновременно  появилисть либо LOW, либо HIGH (уровень не  принципиален), но есть маленькое но!!! допустим одна из кнопок (Up) будет нажата (концевик), при условии - светло, как заставить при этом работать программу если условие поменяется на - темно ?

int analogPin = 0; // здесь фоторезистор
int loadPin_22 = 22; // здесь нагрузка
int loadPin_23 = 23; // здесь нагрузка
int val = 0; // переменная для хранения значения входного напряжения
int button_1 = 42; // номер входа кнопка Up
int button_2 = 43; // номер входа кнопка Down

 void setup()
{
  pinMode(analogPin, INPUT);
  pinMode(button_1, INPUT);
  pinMode(button_2, INPUT);
  pinMode(loadPin_22, OUTPUT);
  pinMode(loadPin_23, OUTPUT);
  digitalWrite(loadPin_22, LOW);
  digitalWrite(loadPin_23, LOW);
}
 
 void loop(){
   val = analogRead(analogPin); // считываем значение с фоторезистора
   static uint32_t millis_prev, millis_off; //2 переменные для хранения меток времени
     if (val <= 400) // тут подбираем под освещенность
       {
         if(millis()-millis_prev >= 5000) // проверяем что уровень держится >= 5 cек.
       {
        digitalWrite(loadPin_22, HIGH);
        digitalWrite(loadPin_23, LOW);
        millis_off = millis();
       } 
}
     else
  {
        millis_prev = millis();
        if(millis()-millis_off >= 5000)
       {
        digitalWrite(loadPin_22, LOW);  
        digitalWrite(loadPin_23, HIGH); 
       } 
}
}

P.S. Искренне прошу помощи, в поиск не посылать, много переварил, но воз так и стоит.

С ув. codex

chaytan
Offline
Зарегистрирован: 02.02.2012

nestandart пишет:

 Достаточно немного изменить включение резисторов и кнопки можно будет отслеживать и две и три и все сразу.

а об этом способе можно немного поподробнее.

в настоящий момент в реализуемом проэкте востребована такая возможность.

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

Способ считывания нескольких кнопок (нажатых комбинаций) описан в первом посте.

chaytan
Offline
Зарегистрирован: 02.02.2012

nestandart пишет:

Способ считывания нескольких кнопок (нажатых комбинаций) описан в первом посте.

интерес представляет способ максимально возможного уменьшения кол-ва проводов от кнопок...

 

Клапауций
Offline
Зарегистрирован: 10.02.2013

chaytan пишет:

интерес представляет способ максимально возможного уменьшения кол-ва проводов от кнопок...

менее двух проводов никак не получается - многие пробовали, но упёрлись в жестокую реальность.

но, впечатляет, что к аналоговому пину можно подключить 1024 кнопки - лешак явил сию истину народу, была большая радость.

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

В первом посте представлен способ подключения двух кнопок к пину АЦП по двум проводам.

1024 это вы конечно загнули.

Учитывая погрешности измерений и "Шум в эфире" не больше 100 кнопок.

Клапауций
Offline
Зарегистрирован: 10.02.2013

nestandart пишет:

В первом посте представлен способ подключения двух кнопок к пину АЦП по двум проводам.

ок - наблюдаю ступенчатый резистор на три положения.

почему это настойчиво называется "способом увеличения количества кнопок по одному проводу" - не ясно.

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

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

Можно конечно и потенциометр подключить. Но он неудобен тем что для того чтобы установить его в какое либо положение нужно проскакать по предыдущим.

 

>>почему это настойчиво называется "способом увеличения количества кнопок по одному проводу" - не ясно.<<

По форме это именно увеличение количества кнопок.

По содержанию - потенциометр.