помогите немного с кодом для кнопочной клавиатуры

Тема в разделе "Arduino & Shields", создана пользователем ZelGer, 8 май 2015.

  1. ZelGer

    ZelGer Нерд

    Есть самодельная клавиатура по типу

    zzxa.png там всего 13 кнопок, как их "читать" по типу "Эксперимент №8 Мерзкое пианино" и что бы можно было убрать дребезг
     
  2. vvr

    vvr Инженерище

    библиотека ClickButton
     
  3. DrProg

    DrProg Вечный нерд

    Как програмно подавить дребезг написано в "Кнопочный переключатель", как аппаратно - в "Перетягивание каната". Вообще учебные материалы очень грамотно сделаны, отвечают на кучу вопросов с нуля.
     
  4. ZelGer

    ZelGer Нерд

    не как программно убрать дребезг я знаю но не буду же я на все 13 кнопок расписывать
     
  5. ZelGer

    ZelGer Нерд

    можно ссылочку?
     
  6. X-Dron

    X-Dron Гик

    Можно сделать так:
    Код (Text):
        #include <DI.h>        
        #define KEYS 13  // количество кнопок
        int buttonPins[KEYS] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
     
        DI Keys[KEYS];  //создание массива из класса DI - дискретный вход
     
        void setup()
        {
          for (int key_c = 0; key_c < KEYS; key_c++) {
            Keys[key_c].Init(buttonPins[key_c], 10); //инициализация дискретных входов класса DI, антидребезг 10мс
          }
        }
     
        void loop()
        {
          for (int key_c = 0; key_c < KEYS; key_c++) {
            Keys[key_c].DI_Refresh(); //Обновляем входов
          }
    //    Keys[0].DI_Read() - обработанная кнопка на пине 2
    //    ...
    //    Keys[13].DI_Read() - обработанная кнопка на пине 14 (A0)
        }
    понадобится эта библиотека.
    https://yadi.sk/d/hGQy8xu1fZNks
    класс DI считывает входы клавиш и фильтрует дребезг. Кнопки должны быть подключены как здесь:
    http://wiki.amperka.ru/конспект-arduino:миксер

    Когда-то делал http://wiki.amperka.ru/конспект-arduino:кнопочные-ковбои по данной схеме с вылизанными багами типа нажатия до сигнала. Вот полный код последней версии
    Код (Text):
        #include <DI.h>        
        #include <Timer_P.h>
        #define BUZZER_PIN  11  // пин с пищалкой
        #define PLAYER_COUNT 2  // количество игроков-ковбоев
        int buttonPins[PLAYER_COUNT] = {2, 3};
        int ledPins[PLAYER_COUNT] = {7, 8};
        boolean Tour, Win[PLAYER_COUNT];
     
        DI Keys[PLAYER_COUNT];  //создание массива из класса DI - дискретный вход
        Timer_P KeyTimers[PLAYER_COUNT], LedTimers[PLAYER_COUNT], StartDelayTimer; //создание экземпляров таймеров
     
        void setup()
        {
          pinMode(BUZZER_PIN, OUTPUT);
          Tour = false;    // инициализация цикла игры
          for (int player = 0; player < PLAYER_COUNT; player++) {
            pinMode(ledPins[player], OUTPUT); //инициализация выходов на светодиоды
            Keys[player].Init(buttonPins[player], 10); //инициализация дискретных входов класса DI, антидребезг 10мс
          }
        }
     
        void loop()
        {
          if (StartDelayTimer.Timer((!Tour), false, 2, random(3000, 8000))) // если тур игры не запущен, то через промежуток 3..8 секунд
          {
            Tour = true;                    //запускаем тур
            tone(BUZZER_PIN, 3000, 250);    //даем сигнал
          }
          for (int player = 0; player < PLAYER_COUNT; player++)
          {
            Keys[player].DI_Refresh();      //Обновляем входа
            Win[player] = KeyTimers[player].Timer(Keys[player].DI_Read(), !Tour, 0, 1); //Определяем победителя
            //Формируется импульс длительностью до 1мс по нажатию клавиш.
            if (Win[player])  //Если победитель есть
            {
              Tour = false;    //то тур завершился
              tone(BUZZER_PIN, 4000, 1500); //даем сигнал
            }
            digitalWrite(ledPins[player], LedTimers[player].Timer(Win[player], false, 1, 1500)); //обновляем светодиоды
          }
        }
     
     
     
  7. DrProg

    DrProg Вечный нерд

    Вообще смотря что требуется от кнопок, если факт нажатия, как в Пианино, то дребезг давить не нужно вообще. Если переключатель вкл потом выкл то нужно, для этого можно сделать функцию и крутить ее по всем кнопкам в цикле, расписывать каждую не надо.
     
  8. ZelGer

    ZelGer Нерд



    А как с этой библиотекой работать

    например мне надо что бы при нажатии кнопки на пине 14 переменная "wind" менялась сама на себя по типу wind = !wind какая комманда для этого нужна
     
  9. X-Dron

    X-Dron Гик

    Я же написал
    Keys[0].DI_Read() - обработанная кнопка на пине 2
    ...
    Keys[13].DI_Read() - обработанная кнопка на пине 14 (A0)
    считайте, что Keys[0].DI_Read() эквивалентно digitalRead(2), но уже обработано антидребезком;
    Дальше все одинаково. Или Вам полный алгоритм написать?
     
  10. DrProg

    DrProg Вечный нерд

    wind = !digitalRead(13)? !wind : wind

    а если в цикле то одной строкой все пины
     
  11. vvr

    vvr Инженерище

    подобная запись большинство посетителей форума повергнет в ступор:D
    здесь проф. программистов раз - два и обчёлся:)
     
  12. ZelGer

    ZelGer Нерд


    Ну я вот так
    Код (Text):
    if(Keys[13].DI_Read() == HIGH)
    {
      wind = !wind;
    }

    просто немного не понимаю
     
  13. ZelGer

    ZelGer Нерд

    вот тут вы правы я немного в ступоре
     
  14. X-Dron

    X-Dron Гик

    Это работать не будет никогда.:).
    В случае с подтягивающим резистором при отпущенной кнопке wind будет сохранять свое предыдущее состояние. При нажатой кнопке wind каждый проход цикла loop() будет менять свое состояние на противоположное. И когда отпускаете, то с равной вероятностью может оказаться и 0 и 1. Кроме того не сделано антидребезга.
    Можете проверить
    Код (Text):
    const int buttonPin = 3;    // the number of the pushbutton pin
    const int ledPin =  13;      // the number of the LED pin

    // variables will change:
    int wind = 0;    

    void setup() {
      pinMode(ledPin, OUTPUT);  
      pinMode(buttonPin, INPUT_PULLUP);
    }

    void loop(){
        wind = !digitalRead(buttonPin)? !wind : wind;
        digitalWrite(ledPin, wind);
    }
    А вот так будет работать.
    Код (Text):
        #include <DI.h>      
        #define KEYS 13  // количество кнопок
        const int ledPin =  13;
        int buttonPins[KEYS] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
        boolean Keys[KEYS],Keys_Old[KEYS];
        boolean wind;
        DI KeysDI[KEYS];  //создание массива из класса DI - дискретный вход
        void setup()
        {
          for (int key_c = 0; key_c < KEYS; key_c++) KeysDI[key_c].Init(buttonPins[key_c], 10); //инициализация дискретных входов класса DI, антидребезг 10мс
          pinMode(ledPin, OUTPUT);
        }
        void loop()
        {
          for (int key_c = 0; key_c < KEYS; key_c++) {
            KeysDI[key_c].DI_Refresh(); //Обновляем входов
            Keys[key_c]=KeysDI[key_c].DI_Read();
          }
       
          if (Keys[1] && !Keys_Old[1]) wind = !wind;
          digitalWrite(ledPin, wind);
    //    Keys[0].DI_Read() - обработанная кнопка на пине 2
    //    ...
    //    Keys[13].DI_Read() - обработанная кнопка на пине 14 (A0)

          for (int key_c = 0; key_c < KEYS; key_c++) Keys_Old[key_c] = Keys[key_c];
        }
    Заготовка определения фронтов сделана под все 14 клавиш. смена wind повешана на кнопку на пине 3.
    Можно было бы обойтись без Keys[KEYS] и везде использовать KeysDI[...].DI_Read(). Но это из разряда религиозных войн. Выделить больше памяти, по при этом ускорить выполнение программы не делая вызовов методов, или не выделять дополнительную память, но тогда программа будет несколько медленнее.
     
    Последнее редактирование: 9 май 2015
  15. DrProg

    DrProg Вечный нерд

    Антидребезг можно сделать RC цепью и инвертрующим триггером. Но все зависит от задачи, например сам факт нажатия в антидребезге не нуждается.
     
  16. ZelGer

    ZelGer Нерд



    ну вообщем вот код он почему то не работает

    Код (Text):
    #include <OLED_I2C.h>

        #include <DI.h>      
        #define KEYS 13  // количество кнопок

    OLED  myOLED(SDA, SCL, 8);
    extern uint8_t Win1[];
    extern uint8_t Win2[];
    extern uint8_t Win3[];
    extern uint8_t BigNumbers[];

        int buttonPins[KEYS] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};

        DI Keys[KEYS];  //создание массива из класса DI - дискретный вход
        boolean Keys[KEYS],Keys_Old[KEYS];

    boolean wind = LOW;
    boolean z = LOW;


    void setup()
    {




            for (int key_c = 0; key_c < KEYS; key_c++) {
            Keys[key_c].Init(buttonPins[key_c], 10); //инициализация дискретных входов класса DI, антидребезг 10мс
          }







      myOLED.begin();
      Serial.begin(9600);
    }

    void loop()
    {

          for (int key_c = 0; key_c < KEYS; key_c++) {
            Keys[key_c].DI_Refresh(); //Обновляем входов
          }
    //    Keys[0].DI_Read() - обработанная кнопка на пине 2

    //Keys[13].DI_Read();

    if (Keys[1] && !Keys_Old[1]) wind = !wind;





    if(z == LOW)
    {
    myOLED.clrScr();
    myOLED.drawBitmap(0, 0, Win1, 128, 64);
    myOLED.update();
    delay(4000);

    z = HIGH;
      myOLED.clrScr();
      myOLED.drawBitmap(0, 0, Win2, 128, 64);
      myOLED.update();
    }
    Serial.println();

      if(wind == 0)
      {
        myOLED.clrScr();
        myOLED.drawBitmap(0, 0, Win2, 128, 64);
        myOLED.update();
      }

        if(wind == 1)
      {
        myOLED.clrScr();
        myOLED.drawBitmap(0, 0, Win3, 128, 64);
        myOLED.update();
      }





      }
     
  17. ZelGer

    ZelGer Нерд

    там еще 3 файла с массивом для картинок
     
  18. X-Dron

    X-Dron Гик

    Скетч не то чтобы работать, он компилироваться не должен.
    Две переменные разного типа с одним именем в двух соседних строчках.
    DI Keys[KEYS]; //создание массива из класса DI - дискретный вход
    boolean Keys[KEYS],Keys_Old[KEYS];
    Возьмите за основу последний предложенный скетч
     
  19. ZelGer

    ZelGer Нерд

    хорошо я взял за основу тот код оно заработало но в каком месте поменять цифры что бы изменился пин кнопки
     
  20. X-Dron

    X-Dron Гик

    Мне 3-й раз повторить????
    Читайте внимательно.