Arduino Nokia 5110 - Меню

Arduino
Автор темы, Сержант
Сержант
Аватара
Arduino
Автор темы, Сержант
Сержант
Сообщения: 64
Зарегистрирован: 19 апреля 2017
С нами: 6 лет 11 месяцев

#1 Arduino » 23 июня 2019, 23:59

phpBB [media]


Сегодня мы узнаем, как создать собственное меню для популярного ЖК-дисплея Nokia 5110, которое позволит сделать наши проекты более удобными для пользователя и более функциональными. Сегодня мы будем использовать Arduino Uno, но вы, очевидно, можете использовать любую другую плату Arduino.

Цель работы над проектом проста. Когда устройство включено, появляется простое меню, и с помощью трех кнопок мы сможем перемещаться по меню с помощью кнопок «вверх», «вниз» и выбора пункт меню.
Первая опция в меню - установить контрастность дисплея. При выборе первой опции будет отображаться новый экран пользовательского интерфейса, а с помощью кнопок вверх и вниз мы можем изменить контрастность дисплея. Если мы снова нажмем среднюю кнопку, мы вернемся к основному экрану пользовательского интерфейса.

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

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

Этот проект является просто демонстрацией, демонстрирующей, что возможно в отношении размещения меню на ЖК-дисплее Nokia 5110, вы можете изменить проект, чтобы он соответствовал требованиям вашего собственного более сложного проекта.

Вот и все для ознакомления. Давайте теперь посмотрим, как построить этот проект.

Код: Выделить всё

RS
CE
DC
DIN
(MOSI)
CLK (SCK)

Схема подключения:
Спойлер
Arduino Nokia 5110 - Меню.png
Arduino Nokia 5110 - Меню

Как видно из схемы, кнопки подключены без резистора

Для этого проекта мы будем использовать две библиотеки от Adafruit, чтобы мы могли легко общаться с LCD во время написания кода.

Adafruit GFX
Nokia 5110

Код: Выделить всё

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

boolean backlight = true;
int contrast=50;

int menuitem = 1;
int page = 1;

volatile boolean up = false;
volatile boolean down = false;
volatile boolean middle = false;

int downButtonState = 0;
int upButtonState = 0;  
int selectButtonState 
= 0;          
int lastDownButtonState 
= 0;
int lastSelectButtonState = 0;
int lastUpButtonState = 0;

Adafruit_PCD8544 display = Adafruit_PCD8544( 5, 4, 3);

void setup() {

  pinMode(2, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(0, INPUT_PULLUP);
  pinMode(7,OUTPUT);

  digitalWrite(7,LOW); //Включить подсветку
  
  Serial
.begin(9600);
  
  display
.begin();      
  display
.setContrast(contrast); //Установите контраст до 50
  display.clearDisplay(); 
  display
.display();   
}

void loop() {
  
  drawMenu
();

  downButtonState = digitalRead(2);
  selectButtonState = digitalRead(1);
  upButtonState =   digitalRead(0);
 
  checkIfDownButtonIsPressed
();
  checkIfUpButtonIsPressed();
  checkIfSelectButtonIsPressed();

  if (up && page == 1 ) {
    up = false;
    menuitem--;
    if (menuitem==0)
    {
      menuitem=3;
    }      
  
}else if (up && page == 2 ) {
    up = false;
    contrast--;
    setContrast();
  }


  if (down && page == 1) {
    down = false;
    menuitem++;
    if (menuitem==4) 
    
{
      menuitem=1;
    }      
  
}else if (down && page == 2 ) {
    down = false;
    contrast++;
    setContrast();
  }


  if (middle) {
    middle = false;
    
    if 
(page == 1 && menuitem==2) 
    
{
      if (backlight) 
      
{
        backlight = false;
        turnBacklightOff();
        }
      else 
      
{
        backlight = true; 
        turnBacklightOn
();
       }
    }

    if(page == 1 && menuitem ==3)
    {
      resetDefaults();
    }


else if (page == 1 && menuitem==1) {
      page=2;
     }
else if (page == 2) {
      page=1;
     }
   }
   
  
}

  void checkIfDownButtonIsPressed()
  {
    if (downButtonState != lastDownButtonState) 
  
{
    if (downButtonState == 0) 
    
{
      down=true;
    }
    delay(50);
  }
   lastDownButtonState = downButtonState;
  }

void checkIfUpButtonIsPressed()
{
  if (upButtonState != lastUpButtonState) 
  
{
    if (upButtonState == 0) {
      up=true;
    }
    delay(50);
  }
   lastUpButtonState = upButtonState;
}

void checkIfSelectButtonIsPressed()
{
   if (selectButtonState != lastSelectButtonState) 
  
{
    if (selectButtonState == 0) {
      middle=true;
    }
    delay(50);
  }
   lastSelectButtonState = selectButtonState;
}

  
  void drawMenu
()
  {
    
  if 
(page==1) 
  
{    
    display
.setTextSize(1);
    display.clearDisplay();
    display.setTextColor(BLACK, WHITE);
    display.setCursor(15, 0);
    display.print("MAIN MENU");
    display.drawFastHLine(0,10,83,BLACK);
    display.setCursor(0, 15);
   
    if 
(menuitem==1) 
    
{ 
      display
.setTextColor(WHITE, BLACK);
    }
    else 
    
{
      display.setTextColor(BLACK, WHITE);
    }
    display.print(">Contrast");
    display.setCursor(0, 25);
   
    if 
(menuitem==2) 
    
{
      display.setTextColor(WHITE, BLACK);
    }
    else 
    
{
      display.setTextColor(BLACK, WHITE);
    }    
    display
.print(">Light: ");
    
    if 
(backlight) 
    
{
      display.print("ON");
    }
    else 
    
{
      display.print("OFF");
    }
    display.display();
    
    if 
(menuitem==3) 
    
{ 
      display
.setTextColor(WHITE, BLACK);
    }
    else 
    
{
      display.setTextColor(BLACK, WHITE);
    }  
    display
.setCursor(0, 35);
    display.print(">Reset");
    display.display();
  }
    
 
  else if 
(page==2) 
  
{
    
    display
.setTextSize(1);
    display.clearDisplay();
    display.setTextColor(BLACK, WHITE);
    display.setCursor(15, 0);
    display.print("CONTRAST");
    display.drawFastHLine(0,10,83,BLACK);
    display.setCursor(5, 15);
    display.print("Value");
    display.setTextSize(2);
    display.setCursor(5, 25);
    display.print(contrast);
 
    display
.setTextSize(2);
    display.display();
  }
  
  
}

  void resetDefaults()
  {
    contrast = 50;
    setContrast();
    backlight = true;
    turnBacklightOn();
  }

  void setContrast()
  {
    display.setContrast(contrast);
    display.display();
  }

  void turnBacklightOn()
  {
    digitalWrite(7,LOW);
  }

    void turnBacklightOff()
  {
    digitalWrite(7,HIGH);
  }




Есть также две очень важные глобальные переменные: страница переменной и пункт меню переменной. Страница переменной запоминает, какой экран пользовательского интерфейса в данный момент отображается на экране. Таким образом, если переменная страницы равна 1, мы находимся на главном экране пользовательского интерфейса, а если переменная равна 2, мы находимся на экране контрастного пользовательского интерфейса. Пункт меню запоминает выбранный пункт меню. Таким образом, если его значение равно 1, выбирается первый элемент меню, поэтому функция drawMenu должна нарисовать этот пункт меню как черный с белыми буквами. Если пункт меню равен 2, то выбирается второй пункт меню и так далее.


Arduino
Автор темы, Сержант
Сержант
Аватара
Arduino
Автор темы, Сержант
Сержант
Сообщения: 64
Зарегистрирован: 19 апреля 2017
С нами: 6 лет 11 месяцев

#2 Arduino » 24 июня 2019, 20:15

phpBB [media]


Загрузил видео вверх ногами :grin: но в общем то на общую картину это не влияет.

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

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

Чтобы продемонстрировать меню поворотного энкодера Arduino, мы создадим простое меню, которое отображается на ЖК-дисплее Nokia 5110 при включении проекта, а с помощью поворотного энкодера мы сможем перемещаться вверх или вниз по меню, выбирая меню Опция нажатием кнопки поворотного энкодера. Меню состоит из 6 пунктов, и когда мы перемещаемся и выбираем каждый элемент, отображение изменится соответственно.

Подключите компоненты / детали, как показано на схеме ниже.

Спойлер
Arduino Nokia 5110 - Меню энкодером .png
Arduino Nokia 5110 - Меню энкодером


Arduino Nokia 5110 - Меню энкодером 2.png
Arduino Nokia 5110 - Меню энкодером

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

Adafruit GFX
Nokia 5110
Encoder Library
TimerOne library

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

Код: Выделить всё

   //////////////////////////////////////////////
  //       Arduino Rotary Encoder Menu        //
 //                 v1.0                     //
//           http://www.educ8s.tv           //
/////////////////////////////////////////////

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <ClickEncoder.h>
#include <TimerOne.h>

int menuitem = 1;
int frame = 1;
int page = 1;
int lastMenuItem = 1;

String menuItem1 = "Contrast";
String menuItem2 = "Volume";
String menuItem3 = "Language";
String menuItem4 = "Difficulty";
String menuItem5 = "Light: ON";
String menuItem6 = "Reset";

boolean backlight = true;
int contrast=60;
int volume = 50;

String language[3] = { "EN", "ES", "EL" };
int selectedLanguage = 0;

String difficulty[2] = { "EASY", "HARD" };
int selectedDifficulty = 0;

boolean up = false;
boolean down = false;
boolean middle = false;

ClickEncoder *encoder;
int16_t last, value;

Adafruit_PCD8544 display = Adafruit_PCD8544( 5, 4, 3); //Download the latest Adafruit Library in order to use this constructor

void setup() {

  pinMode(7,OUTPUT);
  turnBacklightOn();
  
  encoder 
= new ClickEncoder(A1, A0, A2);
  encoder->setAccelerationEnabled(false);
   
  display
.begin();      
  display
.clearDisplay(); 
  setContrast
();  

  Timer1
.initialize(1000);
  Timer1.attachInterrupt(timerIsr); 
  
  last 
= encoder->getValue();
}

void loop() {

  drawMenu();

  readRotaryEncoder();

   ClickEncoder::Button b = encoder->getButton();
   if (!= ClickEncoder::Open) {
   switch (b) {
      case ClickEncoder::Clicked:
         middle=true;
        break;
    }
  }    
  
  if 
(up && page == 1 ) {
     
    up 
= false;
    if(menuitem==&& frame ==2)
    {
      frame--;
    }

     if(menuitem==&& frame ==4)
    {
      frame--;
    }
      if(menuitem==&& frame ==3)
    {
      frame--;
    }
    lastMenuItem = menuitem;
    menuitem--;
    if (menuitem==0)
    {
      menuitem=1;
    } 
  
}else if (up && page == 2 && menuitem==) {
    up = false;
    contrast--;
    setContrast();
  }
  else if (up && page == 2 && menuitem==) {
    up = false;
    volume--;
  }
  else if (up && page == 2 && menuitem==) {
    up = false;
    selectedLanguage--;
    if(selectedLanguage == -1)
    {
      selectedLanguage = 2;
    }
  }
    else if (up && page == 2 && menuitem==) {
    up = false;
    selectedDifficulty--;
    if(selectedDifficulty == -1)
    {
      selectedDifficulty = 1;
    }
  }

  if (down && page == 1) //We have turned the Rotary Encoder Clockwise
  {

    down = false;
    if(menuitem==&& lastMenuItem == 2)
    {
      frame ++;
    }else  if(menuitem==&& lastMenuItem == 3)
    {
      frame ++;
    }
     else  if(menuitem==&& lastMenuItem == 4 && frame!=4)
    {
      frame ++;
    }
    lastMenuItem = menuitem;
    menuitem++;  
    if 
(menuitem==7) 
    
{
      menuitem--;
    }
  
  
}else if (down && page == 2 && menuitem==1) {
    down = false;
    contrast++;
    setContrast();
  }
  else if (down && page == 2 && menuitem==2) {
    down = false;
    volume++;
  }
   else if (down && page == 2 && menuitem==) {
    down = false;
    selectedLanguage++;
    if(selectedLanguage == 3)
    {
      selectedLanguage = 0;
    }
  }
  else if (down && page == 2 && menuitem==) {
    down = false;
    selectedDifficulty++;
    if(selectedDifficulty == 2)
    {
      selectedDifficulty = 0;
    }
  }
  
  if 
(middle) //Middle Button is Pressed
  {
    middle = false;
   
    if 
(page == 1 && menuitem==5) // Backlight Control 
    {
      if (backlight) 
      
{
        backlight = false;
        menuItem5 = "Light: OFF";
        turnBacklightOff();
        }
      else 
      
{
        backlight = true; 
        menuItem5 
= "Light: ON";
        turnBacklightOn();
       }
    }

    if(page == 1 && menuitem ==6)// Reset
    {
      resetDefaults();
    }


    else if (page == 1 && menuitem<=4) {
      page=2;
     }
      else if (page == 2) 
     
{
      page=1; 
     
}
   }   
  
}
  
  void drawMenu
()
  {
    
  if 
(page==1) 
  
{    
    display
.setTextSize(1);
    display.clearDisplay();
    display.setTextColor(BLACK, WHITE);
    display.setCursor(15, 0);
    display.print("MAIN MENU");
    display.drawFastHLine(0,10,83,BLACK);

    if(menuitem==&& frame ==1)
    {   
      displayMenuItem
(menuItem1, 15,true);
      displayMenuItem(menuItem2, 25,false);
      displayMenuItem(menuItem3, 35,false);
    }
    else if(menuitem == 2 && frame == 1)
    {
      displayMenuItem(menuItem1, 15,false);
      displayMenuItem(menuItem2, 25,true);
      displayMenuItem(menuItem3, 35,false);
    }
    else if(menuitem == 3 && frame == 1)
    {
      displayMenuItem(menuItem1, 15,false);
      displayMenuItem(menuItem2, 25,false);
      displayMenuItem(menuItem3, 35,true);
    }
     else if(menuitem == 4 && frame == 2)
    {
      displayMenuItem(menuItem2, 15,false);
      displayMenuItem(menuItem3, 25,false);
      displayMenuItem(menuItem4, 35,true);
    }

      else if(menuitem == 3 && frame == 2)
    {
      displayMenuItem(menuItem2, 15,false);
      displayMenuItem(menuItem3, 25,true);
      displayMenuItem(menuItem4, 35,false);
    }
    else if(menuitem == 2 && frame == 2)
    {
      displayMenuItem(menuItem2, 15,true);
      displayMenuItem(menuItem3, 25,false);
      displayMenuItem(menuItem4, 35,false);
    }
    
    else if
(menuitem == 5 && frame == 3)
    {
      displayMenuItem(menuItem3, 15,false);
      displayMenuItem(menuItem4, 25,false);
      displayMenuItem(menuItem5, 35,true);
    }

    else if(menuitem == 6 && frame == 4)
    {
      displayMenuItem(menuItem4, 15,false);
      displayMenuItem(menuItem5, 25,false);
      displayMenuItem(menuItem6, 35,true);
    }
    
      else if
(menuitem == 5 && frame == 4)
    {
      displayMenuItem(menuItem4, 15,false);
      displayMenuItem(menuItem5, 25,true);
      displayMenuItem(menuItem6, 35,false);
    }
      else if(menuitem == 4 && frame == 4)
    {
      displayMenuItem(menuItem4, 15,true);
      displayMenuItem(menuItem5, 25,false);
      displayMenuItem(menuItem6, 35,false);
    }
    else if(menuitem == 3 && frame == 3)
    {
      displayMenuItem(menuItem3, 15,true);
      displayMenuItem(menuItem4, 25,false);
      displayMenuItem(menuItem5, 35,false);
    }
        else if(menuitem == 2 && frame == 2)
    {
      displayMenuItem(menuItem2, 15,true);
      displayMenuItem(menuItem3, 25,false);
      displayMenuItem(menuItem4, 35,false);
    }
    else if(menuitem == 4 && frame == 3)
    {
      displayMenuItem(menuItem3, 15,false);
      displayMenuItem(menuItem4, 25,true);
      displayMenuItem(menuItem5, 35,false);
    }   
    display
.display();
  }
  else if (page==&& menuitem == 1) 
  
{    
   displayIntMenuPage
(menuItem1, contrast);
  }

  else if (page==&& menuitem == 2) 
  
{
   displayIntMenuPage(menuItem2, volume);
  }
   else if (page==&& menuitem == 3) 
  
{
   displayStringMenuPage(menuItem3, language[selectedLanguage]);
  }
  else if (page==&& menuitem == 4) 
  
{
   displayStringMenuPage(menuItem4, difficulty[selectedDifficulty]);
  }
  else if (page==&& menuitem == 4) 
  
{
   displayStringMenuPage(menuItem4, difficulty[selectedDifficulty]);
  }
  
  
}

  void resetDefaults()
  {
    contrast = 60;
    volume = 50;
    selectedLanguage = 0;
    selectedDifficulty = 0;
    setContrast();
    backlight = true;
    menuItem5 = "Light: ON";
    turnBacklightOn();
  }

  void setContrast()
  {
    display.setContrast(contrast);
    display.display();
  }

  void turnBacklightOn()
  {
    digitalWrite(7,LOW);
  }

    void turnBacklightOff()
  {
    digitalWrite(7,HIGH);
  }

  void timerIsr() {
  encoder->service();
}

void displayIntMenuPage(String menuItem, int value)
{
    display.setTextSize(1);
    display.clearDisplay();
    display.setTextColor(BLACK, WHITE);
    display.setCursor(15, 0);
    display.print(menuItem);
    display.drawFastHLine(0,10,83,BLACK);
    display.setCursor(5, 15);
    display.print("Value");
    display.setTextSize(2);
    display.setCursor(5, 25);
    display.print(value);
    display.setTextSize(2);
    display.display();
}

void displayStringMenuPage(String menuItem, String value)
{
    display.setTextSize(1);
    display.clearDisplay();
    display.setTextColor(BLACK, WHITE);
    display.setCursor(15, 0);
    display.print(menuItem);
    display.drawFastHLine(0,10,83,BLACK);
    display.setCursor(5, 15);
    display.print("Value");
    display.setTextSize(2);
    display.setCursor(5, 25);
    display.print(value);
    display.setTextSize(2);
    display.display();
}

void displayMenuItem(String item, int position, boolean selected)
{
    if(selected)
    {
      display.setTextColor(WHITE, BLACK);
    }else
    {
      display.setTextColor(BLACK, WHITE);
    }
    display.setCursor(0, position);
    display.print(">"+item);
}

void readRotaryEncoder()
{
  value += encoder->getValue();
  
  if 
(value/> last) {
    last = value/2;
    down = true;
    delay(150);
  }else   if (value/< last) {
    last = value/2;
    up = true;
    delay(150);
  }
}


 


  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Программирование»

Кто сейчас на форуме (по активности за 5 минут)

Сейчас этот раздел просматривают: 6 гостей