Помогите, пожалуйста! Не могу подключить кнопку для управления экраном!

Тема в разделе "Arduino & Shields", создана пользователем vanya_drugov, 22 июл 2018.

  1. vanya_drugov

    vanya_drugov Нуб

    Добгого времени суток! Я в ардуино относительно новичок, но какие-то понятия о программировании имею. Помогите, пожалуйста, мне! Я пытаюсь сделать так, чтобы можно было переключать старницы с информацией на дисплее 1602 нажатием кнопки. Пока я смог сделать только так, чтобы при удерживании кнопки открывалась вторая страница, а при отпускании закрывалась, но а если страниц много, то такое не прокатит, хочется, чтобы при единоразовом нажатии открывалась другая страница, и чтобы её закрыть, надо было бы нажать ещё раз.

    Вот скетч с тем, что смог сделать:

    Код (C++):
    #include <TimeLib.h>
    #include <Wire.h> // библиотека для протокола IIC
    #include <LiquidCrystal_I2C.h> // подключаем библиотеку LCD IIC
    LiquidCrystal_I2C lcd(0x27,20,2); // присваиваем имя lcd для дисплея
    #include <DHT.h> // подключаем библиотеку для DHT11
    DHT dht(2, DHT11); // к какому порту подключаем датчик

    const int BUTTON=4;


    // создаем символ градуса и присваиваем имя "gradus"
    byte gradus[8] = {
    0b01100,0b10010,0b10010,0b01100,0b00000,0b00000,0b00000,0b00000
    };

    // создаем русскую букву "П"
    byte P[8] = {
    0b11111,0b10001,0b10001,0b10001,0b10001,0b10001,0b10001,0b00000
    };

    // создаем русскую букву "У"
    byte Y[8] = {
    0b10001,0b10001,0b10001,0b01111,0b00001,0b00001,0b01110,0b00000
    };

    // создаем русскую букву "Л"
    byte L[8] = {
    0b00111,0b01001,0b10001,0b10001,0b10001,0b10001,0b10001,0b00000
    };

    // создаем русскую букву "Ж"
    byte ZH[8] = {
    0b10101,0b10101,0b10101,0b01110,0b10101,0b10101,0b10101,0b00000
    };

    // создаем русскую букву "Ь"
    byte znak[8] = {
    0b10000,0b10000,0b10000,0b11110,0b10001,0b10001,0b11110,0b00000
    };

    byte YA[8] = {
    0b01111,
    0b10001,
    0b10001,
    0b01111,
    0b00101,
    0b01001,
    0b10001,
    0b00000
    };

    void setup() {
    pinMode (BUTTON, INPUT);

    Serial.begin(9600); // запуск последовательного порта
    lcd.init(); // инициализация LCD дисплея
    lcd.backlight(); // включение подсветки дисплея

    lcd.createChar(1, gradus);
    lcd.createChar(2, P);
    lcd.createChar(3, Y);
    lcd.createChar(4, L);
    lcd.createChar(5, ZH);
    lcd.createChar(6, znak);
    lcd.createChar(7, YA);

    setTime (15, 54, 0, 7, 21, 2018);
    }


    void loop() {
    if(digitalRead(BUTTON) == HIGH)
    {
    // если нужны точные значение, то используйте float, вместо byte
    byte h = dht.readHumidity(); // считываем значение температуры
    byte t = dht.readTemperature(); // считываем значение влажности

    Serial.print("Temperature: ");
    Serial.println(t); // отправляем значение температуры на монитор

    Serial.print("Humidity: ");
    Serial.println(h); // отправляем значение температуры на монитор

    Serial.println(" "); // пустая строка

    lcd.setCursor(0,0); // ставим курсор на 1 символ первой строки
    lcd.print("TEM"); // используем латинские буквы
    lcd.print(char(2)); // выводим русскую букву "П"
    lcd.print("EPAT"); // используем латинские буквы
    lcd.print(char(3)); // выводим русскую букву "У"
    lcd.print("PA: "); // используем латинские буквы
    lcd.print(t); // выводим значение температуры на LCD
    lcd.print(char(1)); // выводим знак градуса

    lcd.setCursor(0,1); // анологично
    lcd.print("B");
    lcd.print(char(4));
    lcd.print("A");
    lcd.print(char(5));
    lcd.print("HOCT");
    lcd.print(char(6));
    lcd.print(": ");
    lcd.print(h);
    lcd.print("%");

    delay(1000);
    }
    else
    {
    lcd.clear();
    lcd.print("BPEM");
    lcd.print(char(7));
    lcd.setCursor(0, 1);
    lcd.print( hour() );
    lcd.print( ":" );
    lcd.print( minute() );

    delay(1000);
    }
    }
    Заранее огромное спасибо!
     
  2. Mitrandir

    Mitrandir Гуру

    не понял..
    какой сценарий?
    стр 1->нажатие->отпускание->страница 2>нажатие->отпускание->страница 3>нажатие->отпускание->страница 4> нажатие->отпускание->страница 1
     
  3. vanya_drugov

    vanya_drugov Нуб

    Да, но только 3 или, 2 страницы.
     
  4. Mitrandir

    Mitrandir Гуру

    Код (C++):
    int switchPin = 8;

    boolean lastButton = LOW;
    boolean currentButton = LOW;
    int pageNum = 1;

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

    boolean debounce(boolean last)
    {
      boolean current = digitalRead(switchPin);
      if (last != current)
      {
        delay(5);
        current = digitalRead(switchPin);
      }
      return current;
    }

    void loop()
    {
      currentButton = debounce(lastButton);
      if (lastButton == LOW && currentButton == HIGH)
      {
         pageNum++;
         if (pageNum>3) { //3 - количество страниц
            pageNum = 1;
         }
      }
      lastButton = currentButton;

      showPage();
    }

    void showPage(){
    // тут отрисовываем страницу. номер странице в переменной pageNum
    }

     
     
    CYITEP_BAC9I нравится это.
  5. fogary

    fogary Гик

    Состояние нажатой кнопки это HIGH или LOW у Вас?
    Если - HIGH, то переключение будет по нажатию, а не по отпусканию:
     
  6. Mitrandir

    Mitrandir Гуру

    Да, тут на нажатие, а не на отпуск срабатывает, пожалуй это логичнее. К примеру у меня сейчас на столе телефон от сиско, у него клавиатура на нажатие реагирует
     
    Последнее редактирование: 23 июл 2018
  7. Airbus

    Airbus Радиохулиган Модератор

    А я не понял причём здесь КОД ТС?Там ни нажатий ни страниц.
     
    Последнее редактирование: 23 июл 2018
  8. Tomasina

    Tomasina Сушитель лампочек Модератор

    У меня реализовано так: есть переменная byte Screen, по нажатию кнопки она увеличивается на единичку.
    В функции отрисовки экрана через switch смотрим ее состояние и отрисовываем нужный экран.
    Код приводить не буду, слишком много вычищать не относящегося к теме.
     
    CYITEP_BAC9I нравится это.
  9. vanya_drugov

    vanya_drugov Нуб


    Простите за наглость, но я не понимаю, я нуб, куда мне деть мой оставшийся код? Как дать понять ардуино, что температура и влажность - первая страница, а время - вторая?
     
  10. Mitrandir

    Mitrandir Гуру

    в метод showPage

    Код (C++):
    void showPage(){
    switch(pageNum){
    case 1:
    // если нужны точные значение, то используйте float, вместо byte
    byte h = dht.readHumidity(); // считываем значение температуры
    byte t = dht.readTemperature(); // считываем значение влажности

    Serial.print("Temperature: ");
    Serial.println(t); // отправляем значение температуры на монитор

    Serial.print("Humidity: ");
    Serial.println(h); // отправляем значение температуры на монитор

    Serial.println(" "); // пустая строка

    lcd.setCursor(0,0); // ставим курсор на 1 символ первой строки
    lcd.print("TEM"); // используем латинские буквы
    lcd.print(char(2)); // выводим русскую букву "П"
    lcd.print("EPAT"); // используем латинские буквы
    lcd.print(char(3)); // выводим русскую букву "У"
    lcd.print("PA: "); // используем латинские буквы
    lcd.print(t); // выводим значение температуры на LCD
    lcd.print(char(1)); // выводим знак градуса

    lcd.setCursor(0,1); // анологично
    lcd.print("B");
    lcd.print(char(4));
    lcd.print("A");
    lcd.print(char(5));
    lcd.print("HOCT");
    lcd.print(char(6));
    lcd.print(": ");
    lcd.print(h);
    lcd.print("%");
    break;
    case 2:
    lcd.clear();
    lcd.print("BPEM");
    lcd.print(char(7));
    lcd.setCursor(0, 1);
    lcd.print( hour());
    lcd.print(":");
    lcd.print( minute());
    break
    case 3:
    lcd.clear();
    lcd.print("АЛАРМ! АЛАРМ");
    lcd.setCursor(0, 1);
    lcd.print( "Волк унес зайчат!");

    break;

    }


    }
     
  11. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    Можно спросить у вас, как правильно и с меньшими затратами памяти организовать многоуровневое меню с всякими вкладками? в каждом пункте меню есть свое подменю в котором необходимо изменять данные. я делал чрез if ы. или через switch компактнее код получается? для примера один экран вычистил и ниже вставлю
    Код (C++):
    volatile bool Left_pressed  = 0;
    volatile bool OK_pressed    = 0;
    volatile bool Right_pressed = 0;
    //************************
    pressing_Left = digitalRead(Left);
    pressing_OK = digitalRead(OK);
    pressing_Right =   digitalRead(Right );
      check_pressing_Left();
      check_pressing_OK();
      check_pressing_Right();


    display.clearDisplay();

    // Устанавливаем размер текста
    display.setTextSize(1);
    // Выводим текст
    //экран 1
    if(Left_pressed  == 1)
    {
      page++;
      if (page==5) page=1;
    }

    if (page==1)

    {
      display.fillRect (0, 0, 83, 7, BLACK);
    display.setTextColor(WHITE, BLACK);//
    display.setCursor(22, 0); // CENTER
      display.print("PROVERKA");//"MENU"




      display.setTextColor(BLACK);
      display.setCursor(0, 8); //2 stroka
      display.print("BYSTRYY ZAMER");                  
       display.setCursor(0, 16); //3 stroka
      display.print("ZAMER FONA");
         display.setCursor(0, 24); //4 stroka
      display.print("POISK");
      display.setCursor(0, 32); //5 stroka
      display.print("ANALIZ 5 min");
    display.setCursor(0, 40); //6 stroka
      display.print("ANALIZ 10 min");


    display.display();
    //**************************************
    void check_pressing_Left()
    {
    if (pressing_Left && !F_Left)
    {
    Left_pressed  = 1;
    }
    if (!pressing_Left && F_Left)
    {
    F_Left = 0;
    }
    }
    выдернуто из скетча, поэтому возможно не все понятно. но суть в следующем при нажатии левой кнопки идет перелистывание экранов меню, при нажатии средней идет переход между пунктами меню экрана. при нажатии правой вход в подпункты меню. все проверяется if ами, только меню занимает больше 800 строк в ардуино иде это мой первый "кот" дозиметра, который я сейчас переписываю заново. (меню было очень неудобным в пользовании, но написал как умел )
    в общем если сжать вопрос до нескольких слов то будет звучать так.
    как написать грамотно многоуровневое меню, чтоб код был максимально компактным
     
    Последнее редактирование: 24 июл 2018