Дребезг кнопки на аналоговом входе

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

Подключаю несколько кнопок на аналоговый вход (не хватает пинов). Работает. Нужно, чтобы кнопка могла работать в нескольких режимах. Вроде работает, но дребезг замучал.  Как в этой ситуации его победить

  a = analogRead(0);
  delay(15);

  if (a>250 && a<350) 
  {    
    regim++;   
    flag=1; 
    if(regim > 3)
      regim=1;
  } 
  if(regim == 1)  {
    Serial.println("fffffffffff");
    digitalWrite(led, LOW); 
  }
  if(regim == 2)  {
    Serial.println("nnnnnnnnnnn");
    digitalWrite(led, HIGH);  
  }
  if(regim ==3)  {
    Serial.println("ccccccccccc");
    unsigned long currentMillis = millis();

    if(currentMillis - previousMillis > interval) {
      previousMillis = currentMillis; 
      if (ledState == LOW)
        ledState = HIGH;
      else
        ledState = LOW;
      digitalWrite(led, ledState);
    }
  }

 

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

Вот обнуление флага

if (a>950 && ( regim == 1 || regim == 2 || regim == 3) )  flag=0;

 

toly
Offline
Зарегистрирован: 17.05.2014

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

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

Вначале нужно научится бороться с дребезгом обычной кнопки. Если умеете - покажите как бы вы делали для обычной кнопки (на цифровом входе), если не умеете, то читайте прикрепленную тему Работа с кнопками. В помощь новичку.

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

Чаще всего через библу Bounce

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

Если одна кнопка, то так и всегда гуд( пример взял в теме Работа с кнопками)

int regim=1; 
 int flag=0; 

 void setup()   
 { 
    pinMode(10,OUTPUT);    
 pinMode(9,OUTPUT);    
       
 } 

 void loop() 

 { 
       
     if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата   
     // и перемення flag равна 0 , то ... 
     { 
       regim++;   
       flag=1; 
         
        //это нужно для того что бы с каждым нажатием кнопки 
        //происходило только одно действие 
        // плюс защита от "дребезга"  100% 
          
        if(regim>4)//ограничим количество режимов 
        { 
          regim=1;//так как мы используем только одну кнопку, 
                    // то переключать режимы будем циклично 
        } 
       
     } 
       
      if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата 
     //и переменная flag равна - 1 ,то ... 
     { 
          
        flag=0;//обнуляем переменную "knopka" 
     } 
      
       
       
    if(regim==1)//первый режим 
    { 
      digitalWrite(9,LOW);//выключаем все светодиоды 
      digitalWrite(10,LOW); 
        
        
      //здесь может быть любое ваше действие 
    } 
    if(regim==2)//второй режим 
    { 
      digitalWrite(10,HIGH);//включае красный светодиод 
      digitalWrite(9,LOW); 
        
      //здесь может быть любое ваше действие 
    } 
      
    if(regim==3)//третий режим 
    { 
        
      digitalWrite(9,HIGH);//включае зеленый светодиод 
      digitalWrite(10,LOW); 
        
        
      //здесь может быть любое ваше действие 
    } 
      
    if(regim==4)//четвертый режим 
    { 
        
      digitalWrite(9,HIGH);//включаем светодиоды одновременно 
      digitalWrite(10,HIGH); 
      //здесь может быть любое ваше действие 
    } 
      
 } 

 

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

Ну тогда у вас есть два варианта:

1. Искать библиотеку типа Bounce но с поддержкой аналоговых (сомневаюсь, хотя может быть и существует)
2. Все таки разобратся, как самому, без библиотеки давить дребезг цифровый кнопок. Благо ничего сверх-сложного в этом нет. Пара строчек, только "понять идею" (если не понятно в той теме, так в инете нагуглить можно статьи по этому поводу. Все  - для новичков).

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

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

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

 

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

>Если одна кнопка, то так и всегда гуд( пример взял в теме Работа с кнопками)

Честно говоря, я не вижу где-тут "защита от дребезга" (хотя в комментах это и написано. Но коменты - явно расходятся с кодом. Скажем написанно "обнуляем переменную knopka", в коде flag=0). Так что, скорее всего, это кнопка у вас "не дребезжит".

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

Самый тупой вариант это сделать: воткнуть, скажем delay(50) после того как детектировали что кнопка нажата.

 

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

Вообщем смотрите, вот как бы мы ловили нажатие цифровой кнопки, подтянутой к питанию (именно "нажатие", а не удержание)

void loop(){
  static byte prevButtonState=false; // состояние кнопки при прошлом проходе loop
   byte buttonState=!digitalRead(PIN_NO); // читаем текущие состояние кнопки

  if(!prevButtonState && buttonState){ // была не нажата, стала нажата
     Serial.println("Button Pressed");
  }

  prevButtonState=buttonState;
}

Так же обратите внимание, что у меня разделены "котлеты и мухи". Чтение кнопки  и логика определения что произошло с кнопкой. Только одно чтение digitalRead(). Сама "логика обработки" кнопки - ничерта не знает о том как мы ее читали. Она смотрит только на переменную buttonState. Которая имеет значения true если кнопка в данный момент удерживается.

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

Теперь, добавим "антидребезг". Вначале самым "тупым способом".

void loop(){
  static byte prevButtonState=false; // состояние кнопки при прошлом проходе loop
   byte buttonState=!digitalRead(PIN_NO); // читаем текущие состояние кнопки

  if(!prevButtonState && buttonState){ // была не нажата, стала нажата
     Serial.println("Button Pressed");
    delay(100); // ждем пока дребезги оттребезжат
  }

  prevButtonState=buttonState;
}

То есть после того как мы словили нажатие кнопки, мы просто останавливаем контроллер на 100ms. В результате все лишние нажатия - он просто "прощелкает клювом".

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

Спасибо, щщщщас попробую

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

Но delay() - в большинстве случаев не приемлим в боевых скетчей. Именно из-за того, что полностью останавливает скетч (мало ли что нам еще нужно в этот момент делать?)

Поэтому используем millis(). Идея, в чем-то родственна тому, что вы использовали в стартовом скетче для мигания светодиодом без delay()

1. Запоминаем момент когда кнопка была нажата.
2. Все "анализы нажатий" делаем только если с момента нажатия прошло достаточно времени (больше 100ms)

 

void loop(){
  static byte prevButtonState=false; // состояние кнопки при прошлом проходе loop
   byte buttonState=!digitalRead(PIN_NO); // читаем текущие состояние кнопки

  unsigned long buttonPressTime=0;// тут будем хранить время нажатия кнопки

  if(!prevButtonState && buttonState && (millis()-buttonPressTime>100)){ // была не нажата, стала нажата и с прошлого нажатия прошло 100ms
     Serial.println("Button Pressed");

     buttonPressTime=millis(); // запомнили когда у нас была нажата кнопка
  }

  prevButtonState=buttonState;
}

Пока ход рассуждений понятен?

 

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

Ну, вот... а теперь мы можем попробовать перейти на работу с аналоговыми. Так как у нас нет никаких digitalRead в if-фах. То всю логику "ловли нажатия" и "антидребезга" - мы не трогаем. Она не зависит от типа кнопки. Единстевенная строка которая потребует нашего внимания, это само чтение текущего состояни, кнопки

 boolean buttonState=!digitalRead(PIN_NO); // читаем текущие состояние кнопки

Нам нужно переделать ее таким образом, что-бы читался аналоговых вход. И buttonState, по прежнему принимал true, если кнопка сейчас нажата.

int analogVal=analogRead(PIN_NO_A); // читаем аналоговый вход

boolean buttonState; // нажата или не нажата кнопка 
if(analogVal>250 && analogVal<350){
   buttonState=true;
} else  {
   buttonState=false;
}

Или чуток короче (разница - в синтаксисе, сут - таже самая)

int analogVal=analogRead(PIN_NO_A); // читаем аналоговый вход
boolean buttonState=(analogVal>250 && analogVal<350); // нажата или не нажата кнопка 

P.S. я поменял тип переменных buttonState и prevButtonState с byte, на boolean. Сточки зрения "работоспособности" - это без разницы, но так человеком легче читается. Более явно видно, что в переменных могут быть только true/false (1/0)

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

Да, спасибо

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

Ох, строка 5-ть, с ошибкой....

 unsigned long buttonPressTime=0;// тут будем хранить время нажатия кнопки

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

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

Либо добавить ключевое слово static (как мы делали это для prevButtonState)

static unsigned long buttonPressTime=0;// тут будем хранить время нажатия кнопки

P.S. Писал все из "головы на ходу", в компиляторе не проверял. Сугубо для "объяснить идею".

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

Вот так работает, спасибо за помощь

a = analogRead(0);
  if (a>250 && a<350)
  { 
    if(  (millis()-buttonPressTime>250)){
      regim++; 
      if(regim > 3)
        regim=1;
      buttonState=true;
      buttonPressTime=millis();
    }    
  else  {
    buttonState=false;
  }
  }

 

Alexus-12
Offline
Зарегистрирован: 28.03.2014

leshak пишет:

Ну, вот... а теперь мы можем попробовать перейти на работу с аналоговыми. Так как у нас нет никаких digitalRead в if-фах. То всю логику "ловли нажатия" и "антидребезга" - мы не трогаем. Она не зависит от типа кнопки. Единстевенная строка которая потребует нашего внимания, это само чтение текущего состояни, кнопки

 boolean buttonState=!digitalRead(PIN_NO); // читаем текущие состояние кнопки

Нам нужно переделать ее таким образом, что-бы читался аналоговых вход. И buttonState, по прежнему принимал true, если кнопка сейчас нажата.

int analogVal=analogRead(PIN_NO_A); // читаем аналоговый вход

boolean buttonState; // нажата или не нажата кнопка 
if(analogVal>250 && analogVal<350){
   buttonState=true;
} else  {
   buttonState=false;
}

Или чуток короче (разница - в синтаксисе, сут - таже самая)

int analogVal=analogRead(PIN_NO_A); // читаем аналоговый вход
boolean buttonState=(analogVal>250 && analogVal<350); // нажата или не нажата кнопка 

P.S. я поменял тип переменных buttonState и prevButtonState с byte, на boolean. Сточки зрения "работоспособности" - это без разницы, но так человеком легче читается. Более явно видно, что в переменных могут быть только true/false (1/0)

А можно полный вариант этого алгоритма выложить ? С цифровой кнопкой вроде все понятно, а с аналоговыми никак не могу понять.

X-Dron
Offline
Зарегистрирован: 24.01.2015

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

    #include <AnalogKey5.h>

    #define LED_PIN     9
    #define POT_PIN     A1

    AnalogKey5 AKeys(10, 144, 329, 505, 742, 10);
    
    void setup() {
      pinMode(LED_PIN, OUTPUT);
    }

    void loop()
    {
      AKeys.Refresh(analogRead(POT_PIN));
      digitalWrite(LED_PIN, AKeys.Key1());
   }

AnalogKey5 это класс обработчика 5-ти кнопок на аналоговом входе. Числа при создании класса - это средние значения АЦП для каждой из кнопок. Последнее - половина  ширины зоны для каждой кнопки. Для первой кнопки зона в данном примере 0...20, для второй 134...154.

Если значение АЦП находится в этой зоне в течение 50мс, то считается, что кнопка нажата. Выход из зоны так же снимает значение нажатия клавиши через 50мс. Времена антидребезга жестко зашиты в библиотеке. Меняются изменением ccp-файла. В методе void AnalogKey5::Refresh(int aValue) находите 50 и ставите нужное значение.

Библиотека  здесь

https://github.com/X-Dron/X-Dron_lib/archive/master.zip

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

ошибся, пардон

X-Dron
Offline
Зарегистрирован: 24.01.2015

проверил, все там есть

Это информация о только что скачанном архиве, с сервера. Время создание локальной копии на компе

https://yadi.sk/i/9TRd12o-fG4Gx

Вот содержимое архива

https://yadi.sk/i/3yMBssfvfG4Jg

Изменен 24-го февраля.

Alexus-12
Offline
Зарегистрирован: 28.03.2014

X-Dron пишет:

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

    #include <AnalogKey5.h>

    #define LED_PIN     9
    #define POT_PIN     A1

    AnalogKey5 AKeys(10, 144, 329, 505, 742, 10);
    
    void setup() {
      pinMode(LED_PIN, OUTPUT);
    }

    void loop()
    {
      AKeys.Refresh(analogRead(POT_PIN));
      digitalWrite(LED_PIN, AKeys.Key1());
   }

Вроде все понятно, кроме вот этой строки

digitalWrite(LED_PIN, AKeys.Key1());

Я так понимаю она должна подавать на выходной пин такой же потенциал, как берётся со входного пина и соответственно светодиод будет гореть ярче или тусклее? Что значит Key1?

Как мне прописать другое действие, например вывод в сериал порт определенных фраз в зависимости от того, какая кнопка нажата?

Извиняюсь за тупые вопросы, но мой уровень не очень высокий во всех этих классах и т.п.

inspiritus
Offline
Зарегистрирован: 17.12.2012

У Вас что памяти для программы слишком много? 

Повесьте ёмкость и не морочьтесь.

 

Alexus-12
Offline
Зарегистрирован: 28.03.2014

inspiritus пишет:

У Вас что памяти для программы слишком много? 

Повесьте ёмкость и не морочьтесь.

Можно по-подробнее - куда и какую? Видимо Вы пытались вставить схему, но её не видно.

inspiritus
Offline
Зарегистрирован: 17.12.2012

Пытался. 

http://vrtp.ru/index.php?showtopic=20766

там... В середине первой простыни. Я делаю проще, 0.1мкФ от кнопки на землю , правда для цифровом входе. Однако зависит от Вашей работы на аналоговом порте. Куда и как подвешено, куда замыкается, одна кнопка , или несколько?

X-Dron
Offline
Зарегистрирован: 24.01.2015

1. Аналоговые входы A0-A5 могут быть быть использованы как обыкновенные дискретные. Для их считывания используются адреса пинов 14-19. Например, pinMode(14, INPUT); digitalWrite(14, LOW); для A0
2. Класс AnalogKey5 писался как альтернатива "стандартному решению" для такого устройства
http://www.droboticsonline.com/media/catalog/product/cache/1/image/5e06319eda06f020e43594a9c230972d/a/r/arduinolcdkeypadforstore3.jpg
с такой схемой подключения
http://chingachgook.net/wp-content/uploads/2014/06/Keypad.jpg
Здесь на один аналоговый вход вешаются 5 кнопок. Нажатие каждой соответствует своему уровню напряжения на A0. Что соответствует первому посту темы
3. Относительно п2. AKeys.Key1() это метод, который возвращает булевое значение "клавиши". Нажата/отпущена. digitalWrite(LED_PIN, AKeys.Key1()); зажигает лампочку, если кнопка надата
4. Памяти для простейших "проектов" чаще всего за глаза.

X-Dron
Offline
Зарегистрирован: 24.01.2015

1. Аналоговые входы A0-A5 могут быть быть использованы как обыкновенные дискретные. Для их считывания используются адреса пинов 14-19. Например, pinMode(14, INPUT); digitalWrite(14, LOW); для A0
2. Класс AnalogKey5 писался как альтернатива "стандартному решению" для такого устройства
http://www.droboticsonline.com/media/catalog/product/cache/1/image/5e06319eda06f020e43594a9c230972d/a/r/arduinolcdkeypadforstore3.jpg
с такой схемой подключения
http://chingachgook.net/wp-content/uploads/2014/06/Keypad.jpg
Здесь на один аналоговый вход вешаются 5 кнопок. Нажатие каждой соответствует своему уровню напряжения на A0. Что соответствует первому посту темы

vvadim пишет:

Подключаю несколько кнопок на аналоговый вход (не хватает пинов). Работает.

3. Относительно п2. AKeys.Key1() это метод, который возвращает булевое значение "клавиши". Нажата/отпущена. digitalWrite(LED_PIN, AKeys.Key1()); зажигает лампочку, если кнопка нажата. Для клавиши 2 AKeys.Key2()... для пятой AKeys.Key5()
4. Памяти для простейших "проектов" чаще всего за глаза.

С изменением режима немного по позже

X-Dron
Offline
Зарегистрирован: 24.01.2015
#include <AnalogKey5.h>
#define LED_PIN     9
#define POT_PIN     A1

AnalogKey5 AKeys(10, 144, 329, 505, 742, 10);
boolean Key2_Old;
byte mode=0;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
   AKeys.Refresh(analogRead(POT_PIN));
   digitalWrite(LED_PIN, AKeys.Key1());

   if (AKeys.Key2() && !Key2_Old) mode = (++mode)%3;
   Serial.print("Mode: ");
   Serial.println(mode);
   Key2_Old = AKeys.Key2();
}

По нажатию второй клавиши на аналоговом вводе меняется режим от 0 до 2 и выводится на терминал.

 

Alexus-12
Offline
Зарегистрирован: 28.03.2014

inspiritus пишет:

там... В середине первой простыни. Я делаю проще, 0.1мкФ от кнопки на землю , правда для цифровом входе. Однако зависит от Вашей работы на аналоговом порте. Куда и как подвешено, куда замыкается, одна кнопка , или несколько?

Схема подключения по типу такой. 4 кнопки на один порт.

http://chingachgook.net/wp-content/uploads/2014/06/Keypad.jpg

Про аппаратное устранение дребезга на цифровом порту я в курсе. Как сделать тоже самое на аналоговом порту, если такое возможно?

X-Dron пишет:

3. Относительно п2. AKeys.Key1() это метод, который возвращает булевое значение "клавиши". Нажата/отпущена. digitalWrite(LED_PIN, AKeys.Key1()); зажигает лампочку, если кнопка надата

Как оно распознает какая именно кнопка из пяти нажата? Булево возвращает либо да, либо нет. А как распознать что именно нажато в этом примере?

X-Dron
Offline
Зарегистрирован: 24.01.2015

Alexus-12 пишет:

Как оно распознает какая именно кнопка из пяти нажата? Булево возвращает либо да, либо нет. А как распознать что именно нажато в этом примере?

Читайте 18й пост.

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

AnalogKey5 AKeys(10, 144, 329, 505, 742, 10);

Потом делаем обновление внутренних переменных, делая расчет с новым входным значением входного аналогового сигнала

AKeys.Refresh(analogRead(POT_PIN));

А потом запрашивать нажато/ненажато

AKeys.Key1();
...
AKeys.Key5();

Или Вам непонятно как из int значения получается boolean?
Элементарный пример - операторы сравнения. :)

boolean bv = Value > 150;

digitalWrite(LED_PIN, AKeys.Key1());
эквивалентна такой записи

if (AKeys.Key1()) {
   digitalWrite(LED_PIN, HIGH);
   }else{
   digitalWrite(LED_PIN, LOW);
}

кто там боролся за краткость кода?
 

inspiritus
Offline
Зарегистрирован: 17.12.2012

Да повесьте порт на землю кондеем. Впрос не в этом. Сотворите компаратор , чтобы ловил все кнопки формированием уровня ( например нуля). Повесьте на прерывание. Прерывание сделайте FALLING. Внутри прерывания добавьте задержку, сформируйте флаг и остальное обрабатывайте в основном цикле. ОНО будет ловить дребезг , фактически триггер.

Не забудьте. На входе в прерывание  запрещайте прерывания , на выходе разрешайте. 

Alexus-12
Offline
Зарегистрирован: 28.03.2014

X-Dron пишет:

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

Сделал вот так, ничего не изменилось, дребезг остался. Что не так?

#include <AnalogKey5.h>
#define BUTTON 14 // Пин, к которому подключены кнопки (А0)
AnalogKey5 AKeys(912, 836, 509, 179, 1100, 10);

void setup()
{
Serial.begin(9600);
  pinMode(BUTTON,INPUT);
}

void loop()
{
  AKeys.Refresh(analogRead(BUTTON));
  if (AKeys.Key1()) Serial.println ("Button 1 pressed");
}

 

X-Dron
Offline
Зарегистрирован: 24.01.2015

Интересно, как Вы по этому коду узнали что есть дребезг?
"Button 1 pressed" выводится все время, пока клавиша нажата.
Правильнее все-же так
 

#include <AnalogKey5.h>
#define BUTTON A0 // Пин, к которому подключены кнопки (А0)
AnalogKey5 AKeys(912, 836, 509, 179, 1100, 10);
 
void setup()
{
Serial.begin(9600);
}
 
void loop()
{
  AKeys.Refresh(analogRead(BUTTON));
  if (AKeys.Key1()) Serial.println ("Button 1 pressed");
}

А если все-таки нужен фронт нажатия клавиши, то так.
 

#include <AnalogKey5.h>
#define BUTTON A0 // Пин, к которому подключены кнопки (А0)
AnalogKey5 AKeys(912, 836, 509, 179, 1100, 10);
boolean Key1_Old;
 
void setup()
{
Serial.begin(9600);
}
 
void loop()
{
  AKeys.Refresh(analogRead(BUTTON));
  if (AKeys.Key1() && !Key1_Old) Serial.println ("Button 1 pressed (UP front)");
  Key1_Old = AKeys.Key1();
}

 

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

проверил библиотеку X-Dron - всё нормально работает, автор молодца
буду использовать

 

Alexus-12
Offline
Зарегистрирован: 28.03.2014

X-Dron пишет:

А если все-таки нужен фронт нажатия клавиши, то так.
 

#include <AnalogKey5.h>
#define BUTTON A0 // Пин, к которому подключены кнопки (А0)
AnalogKey5 AKeys(912, 836, 509, 179, 1100, 10);
boolean Key1_Old;
 
void setup()
{
Serial.begin(9600);
}
 
void loop()
{
  AKeys.Refresh(analogRead(BUTTON));
  if (AKeys.Key1() && !Key1_Old) Serial.println ("Button 1 pressed (UP front)");
  Key1_Old = AKeys.Key1();
}

Вот это заработало как надо. Сколько кнопку не держи, а все равно только один раз в порт печать идет.

Если кнопок несколько то для каждой нужна переменная boolean Key_Old как я понял.

Спасибо. Но если честно я все равно не понял как оно работает :) Буду использовать как есть.

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

почитай в его библе файл AnalogKey5.срр там всё расписано

Alexus-12
Offline
Зарегистрирован: 28.03.2014

Да я читал. Но это выше моего понимания :)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

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

deftvk
Offline
Зарегистрирован: 27.05.2016

Alexus-12 пишет:

Извиняюсь за тупые вопросы, но мой уровень не очень высокий во всех этих классах и т.п.

Конечно лучше самому разобраться и понять механизм работы без библиотек - обратите внимание, как происходит борьба с дребезгом и погрешностью АЦП путем битового сдвига в статье - http://codius.ru/articles/221#a18

mastiff
Offline
Зарегистрирован: 09.11.2013

#define BUTTON A0 // Пин, к которому подключены кнопки (А0)

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

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

С дребезгом на на аналоговом входе я борюсь так

/* AnalogBounce.ino
#1
кнопка1 -> A0 (Analog_pin) 0 нажата /1 нет
*/
// #1
const int Analog_pin = 0; // вывод кнопки
int Analog_new,Analog;// значение на кнопке без дребезга (новое и старое)
const int delta = 5;
bool bounce = 0; // антидребезговый флаг

void setup() {
  Serial.begin(9600);
  // #1
  Analog_new = analogRead(Analog_pin);
}

void loop() {
  // #1
  static uint32_t past_1 = 0 ;
  Analog_new = analogRead(Analog_pin);
  if (!bounce &&  (Analog+delta < Analog_new  ||  Analog-delta > Analog_new)) { // если прошел фронт изм на выводн
    bounce = 1;                                 // выставить флаг
    past_1 = millis();                          // сделать временую засветку
  }
  else if ( bounce &&( millis() - past_1) >= 40 ) { // если прошло антидребезговое время
    bounce = 0;                            // то снять фл
    Analog = Analog_new;           // прочитать реальное значение на выводе
    Serial.println(Analog);// сюда можно воткнуть обработчик события
  }
}

 

deftvk
Offline
Зарегистрирован: 27.05.2016

mastiff пишет:

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

Настолько больше, что нельзя на один пин замкнуть?

Alexej79
Offline
Зарегистрирован: 14.03.2017

Приветствую. Заинтересовался тоже темой подключения пяти кнопок к одному аналоговому порту. У меня возник вопрос как можно определить по аналоговому значению какая кнопка нажата и присвоить соответственное значение переменной?

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

void Tasten() {
  x=analogRead(button);// считать данные с кнопок
  if((x<1010)&&(flag==0)){// если кнопка нажата и флаг равен нулю то 
   flag=1;//флаг переключить в 1
   delay(100);// сделать паузу пока устоканится дребезг
   x=analogRead(button);// считать устойчивый сигнал с кнопок
    if(x<335)a=1;// присвоить соответствуещее значение
    if((x>336)&&(x<500))a=2;
    if((x>501)&&(x<560))a=3;
    if((x>561)&&(x<620))a=4;
    if((x>621)&&(x<700))a=5;
    Serial.println(x);
 }
 if((x>1010)&&(flag==1))flag=0;
}

Буду очень признателен за советы опытных программистов.

deftvk
Offline
Зарегистрирован: 27.05.2016

Посмотрите статью http://codius.ru/articles/221 - там много конструкций кода.

Alexej79
Offline
Зарегистрирован: 14.03.2017

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

deftvk
Offline
Зарегистрирован: 27.05.2016

Так, а код из сотого абзаца вас чем не устраивает?

Alexej79
Offline
Зарегистрирован: 14.03.2017

deftvk пишет:

Так, а код из сотого абзаца вас чем не устраивает?


Что за сотый абзац?

deftvk
Offline
Зарегистрирован: 27.05.2016

Alexej79 пишет:
Что за сотый абзац?

http://codius.ru/articles/221#a100

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

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

Вы хотите такой подход?http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-novichku?page=21#comment-269244

 

Alexej79
Offline
Зарегистрирован: 14.03.2017

Читал я эту тему, там очень сложно пока для меня.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Чего там сложного. Подключили аналоговую клавиатуру . Залили скетч и посмотрели как он работает. убедились в работе, по отправке нужного сообщения в сериал, по нажатию кнопки. Ну а дальше уже прописали, что вам надо сделать по нажатию кнопки.  Для чего я пишу эти библиотеки. Для того что бы если надо я банально вставлю в нужную программу и все.