Энкодер управление меню на дисплее

Энкодер меню на дисплее Ардуино

Меню на дисплее LCD 1602 с энкодером Ардуино ► представим два примера: включение светодиодов и меню на дисплее с управлением яркостью светодиодов от энкодера.

Рассмотрим, как сделать меню с энкодером Ардуино на дисплее LCD 1602 I2C. Мы представим два примера: меню для включения светодиодов и меню на дисплее с управлением от энкодера яркостью светодиодов. Рекомендуем вам ознакомиться с подключением к Arduino дисплея LCD 1602 Arduino и модуля энкодер Ардуино. Если вы уже подключали данные модули, то можно приступать к этому мини проекту.

Меню на Ардуино LCD 1602 с энкодером

Видео. Меню с энкодером на Ардуино LCD 1602

Примеры меню с модулем энкодера и жк дисплеем, размещенные на этой странице, вы сможете адаптировать под свои нужды. Во многих проектах на Ардуино требуется для пользователя создать возможность для настройки или управления устройством на микроконтроллере. Энкодер позволяет сделать простое и нативное меню на LCD дисплее для управления светодиодами, микро серво Ардуино или для других задач.

Как сделать меню с энкодером на дисплее

Для этого проекта нам потребуется:

  • плата Arduino Uno / Arduino Nano / Arduino Mega;
  • модуль энкодера;
  • беспаечная макетная плата;
  • светодиоды и резисторы;
  • дисплей LCD 1602 Arduino;
  • провода «папа-папа», «папа-мама».
Управление энкодером меню дисплея LCD
Схема подключения дисплея и энкодера к Ардуино

Скетч. Управление энкодером меню дисплея LCD

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

#include "Wire.h"                                 // библиотека для протокола I2C
#include "LiquidCrystal_I2C.h"           // библиотека для дисплея
LiquidCrystal_I2C LCD(0x27, 16, 2);   // присваиваем имя дисплею

#include "RotaryEncoder.h"                // библиотека для энкодера
RotaryEncoder encoder(A2, A3);       // пины подключение энкодера (DT, CLK)

// задаем шаг энкодера и макс./мин. значение
#define STEPS  6
#define POSMIN 0
#define POSMAX 12

int lastPos, newPos;
boolean buttonWasUp = true;

void setup() {
   LCD.init();            // инициализация LCD дисплея и подсветки
   LCD.backlight();

   pinMode(9, OUTPUT);              // пины для светодиодов
   pinMode(10, OUTPUT);
   pinMode(11, OUTPUT);
   pinMode(2, INPUT_PULLUP);  // пин для кнопки энкодера

   Serial.begin(9600);
   encoder.setPosition(10 / STEPS);
}

void loop() {
   LCD.setCursor(0, 0);
   LCD.print("LED1  LED2  LED3");

   // проверяем положение ручки энкодера
   encoder.tick();
   newPos = encoder.getPosition() * STEPS;
   if (newPos < POSMIN) { encoder.setPosition(POSMIN / STEPS); newPos = POSMIN; }
   else if (newPos > POSMAX) { encoder.setPosition(POSMAX / STEPS); newPos = POSMAX; }

   // если положение изменилось - выводим на монитор и дисплей
   if (lastPos != newPos) {
      Serial.println(newPos);
      LCD.setCursor(lastPos, 1);
      LCD.print("    ");
      LCD.setCursor(newPos, 1);
      LCD.print("====");
      lastPos = newPos;
   }

   // узнаем состояние кнопки модуля энкодера
   boolean buttonIsUp = digitalRead(2);
   if (buttonWasUp && !buttonIsUp) {
      // исключаем дребезг контактов тактовой кнопки
      delay(10);
      // снова считываем сигнал с кнопки энкодера
      buttonIsUp = digitalRead(2);

      // если кнопка нажата, то включаем соответствующий светодиод
      if (!buttonIsUp  && newPos == 0) {
          digitalWrite(9, HIGH); digitalWrite(10, LOW); digitalWrite(11, LOW);
      }
      if (!buttonIsUp  && newPos == 6) {
          digitalWrite(9, LOW); digitalWrite(10, HIGH); digitalWrite(11, LOW);
      }
      if (!buttonIsUp  && newPos == 12) {
          digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(11, HIGH);
      }
   }

}

Пояснения к коду:

  1. положение курсора на LCD может принимать три значения — 0, 6 или 12;
  2. кнопка энкодера подключена к цифровому порту при помощи конфигурации пина параметром INPUT PULLUP, что позволяет считывать нажатие кнопки.

Скетч. Двухуровневое меню с энкодером Ардуино

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

#include "Wire.h"                                 // библиотека для протокола I2C
#include "LiquidCrystal_I2C.h"           // библиотека для дисплея
LiquidCrystal_I2C LCD(0x27, 16, 2);   // присваиваем имя дисплею

#include "RotaryEncoder.h"                // библиотека для энкодера
RotaryEncoder encoder(A2, A3);       // пины подключение энкодера (DT, CLK)

// задаем шаг энкодера и макс./мин. значение в главном меню
#define STEPS  6
#define POSMIN 0
#define POSMAX 12

// задаем шаг энкодера и макс./мин. значение в подменю
#define STEPS_2  10
#define POSMIN_2 0
#define POSMAX_2 250

int lastPos, newPos;
boolean buttonWasUp = true;
byte w = 2;

void setup() {
  LCD.init();            // инициализация LCD дисплея и подсветки
  LCD.backlight();

  pinMode(9, OUTPUT);              // пины для светодиодов
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(2, INPUT_PULLUP);  // пин для кнопки энкодера

  Serial.begin(9600);
  encoder.setPosition(10 / STEPS);
}

void loop() {

   // ЦИКЛ С ГЛАВНЫМ МЕНЮ НА ДИСПЛЕЕ
  while (w == 0) {
    LCD.setCursor(0, 0);
    LCD.print("LED1  LED2  LED3");
    // проверяем положение ручки энкодера
    encoder.tick();
    newPos = encoder.getPosition() * STEPS;
    if (newPos < POSMIN) {
      encoder.setPosition(POSMIN / STEPS);
      newPos = POSMIN;
    }
    else if (newPos > POSMAX) {
      encoder.setPosition(POSMAX / STEPS);
      newPos = POSMAX;
    }
    // если положение изменилось - выводим на монитор и дисплей
    if (lastPos != newPos) {
      Serial.println(newPos);
      LCD.setCursor(lastPos, 1);
      LCD.print("    ");
      LCD.setCursor(newPos, 1);
      LCD.print("====");
      lastPos = newPos;
    }
      // если кнопка нажата, то переходим в цикл с вложенным меню
      // перед входом в подменю очищаем дисплей и делаем задержку
    boolean buttonIsUp = digitalRead(2);
    if (buttonWasUp && !buttonIsUp) {
      delay(10);
      buttonIsUp = digitalRead(2);
      if (!buttonIsUp  && newPos == 0)  { LCD.clear(); delay(500); w = 1; }
      if (!buttonIsUp  && newPos == 6)  { LCD.clear(); delay(500); w = 2; }
      if (!buttonIsUp  && newPos == 12) { LCD.clear(); delay(500); w = 3; }
    }
  }

   // ВЛОЖЕННОЕ МЕНЮ-1 С ПЕРВЫМ СВЕТОДИОДОМ
  while (w == 1) {
    LCD.setCursor(0, 0);
    LCD.print("LED1  - ");
    // проверяем положение ручки энкодера
    encoder.tick();
    newPos = encoder.getPosition() * STEPS_2;
    if (newPos < POSMIN_2) {
      encoder.setPosition(POSMIN_2 / STEPS_2);
      newPos = POSMIN_2;
    }
    else if (newPos > POSMAX_2) {
      encoder.setPosition(POSMAX_2 / STEPS_2);
      newPos = POSMAX_2;
    }
    // если положение изменилось - меняем яркость светодиода
    if (lastPos != newPos) {
      LCD.setCursor(7, 0);
      LCD.print(newPos);
      analogWrite(9, newPos);
    }
    // если кнопка энкодера была нажата, то выходим в главное меню
    // перед входом очищаем дисплей и выключаем светодиод
    boolean buttonIsUp = digitalRead(2);
    if (buttonWasUp && !buttonIsUp) {
      delay(10);
      buttonIsUp = digitalRead(2);
      if (!buttonIsUp)  { LCD.clear(); digitalWrite(9, LOW); delay(500); w = 0; }
  } 
}

   // ВЛОЖЕННОЕ МЕНЮ-2 СО ВТОРЫМ СВЕТОДИОДОМ
  while (w == 2) {
    LCD.setCursor(0, 0);
    LCD.print("LED2 - ");
    // проверяем положение ручки энкодера
    encoder.tick();
    newPos = encoder.getPosition() * STEPS_2;
    if (newPos < POSMIN_2) {
      encoder.setPosition(POSMIN_2 / STEPS_2);
      newPos = POSMIN_2;
    }
    else if (newPos > POSMAX_2) {
      encoder.setPosition(POSMAX_2 / STEPS_2);
      newPos = POSMAX_2;
    }
    // если положение изменилось - меняем яркость светодиода
    if (lastPos != newPos) {
      LCD.setCursor(7, 0);
      LCD.print(newPos);
      analogWrite(10, newPos);
    }
    // если кнопка энкодера была нажата, то выходим в главное меню
    // перед входом очищаем дисплей и выключаем светодиод
    boolean buttonIsUp = digitalRead(2);
    if (buttonWasUp && !buttonIsUp) {
      delay(10);
      buttonIsUp = digitalRead(2);
      if (!buttonIsUp)  { LCD.clear(); digitalWrite(10, LOW); delay(500); w = 0; }
  }
}

   // ВЛОЖЕННОЕ МЕНЮ-3 С ТРЕТЬИМ СВЕТОДИОДОМ
  while (w == 3) {
    LCD.setCursor(0, 0);
    LCD.print("LED3 - ");
    // проверяем положение ручки энкодера
    encoder.tick();
    newPos = encoder.getPosition() * STEPS_2;
    if (newPos < POSMIN_2) {
      encoder.setPosition(POSMIN_2 / STEPS_2);
      newPos = POSMIN_2;
    }
    else if (newPos > POSMAX_2) {
      encoder.setPosition(POSMAX_2 / STEPS_2);
      newPos = POSMAX_2;
    }
    // если положение изменилось - меняем яркость светодиода
    if (lastPos != newPos) {
      LCD.setCursor(7, 0);
      LCD.print(newPos);
      analogWrite(11, newPos);
    }
    // если кнопка энкодера была нажата, то выходим в главное меню
    // перед входом очищаем дисплей и выключаем светодиод
    boolean buttonIsUp = digitalRead(2);
    if (buttonWasUp && !buttonIsUp) {
      delay(10);
      buttonIsUp = digitalRead(2);
      if (!buttonIsUp)  { LCD.clear(); digitalWrite(11, LOW); delay(500); w = 0; }
  } 
}

}

Пояснения к коду:

  1. для каждого раздела меню используется цикл while, так как изначально глобальная переменная w=0;, то выполняется цикл while (w == 0);
  2. если вы не хотите, чтобы светодиоды выключались при выходе в главное меню — удалите команду digitalWrite() во всех циклах вложенных меню.

Заключение. Мы рассмотрели два примера создания меню с энкодером на дисплее 1602 IIC Arduino. Если вы уловили всю суть управления меню с помощью энкодера (датчик угла поворота), то легко сможете использовать представленные примеры в своих собственных проектах с дисплеем на Ардуино. Если у вас еще остались вопросы по данной теме, то вы можете их оставлять в комментариях к этой записи.

1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5,00 out of 5)
Загрузка...

Похожие записи по теме:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *