Arduino и LCD 128×64 Сменяеми страници с данни от сензори

Arduino и LCD 128x64 Сменяеми страници с данни от сензори

Въведение

Този проект представлява система за визуализация на данни от няколко сензора, използвайки графичен LCD 128×64 дисплей и Arduino Uno. Проектът дава възможност за преминаване между различни страници на информация чрез натискане на бутон. Първата страница показва стойностите на аналогови входове (A0, A1, A2, A3), докато втората страница предоставя информация за температура и влажност, събрана от сензор DHT22.

Необходими компоненти

  • Arduino Uno: Основният микроконтролер, който ще се използва за събиране на данни и управление на дисплея.
  • Графичен LCD дисплей (ST7920 128×64): Дисплей, който ще визуализира данните от сензорите.
  • DHT22 сензор за температура и влажност: Сензор, който измерва температура и влажност.
  • Бутон: Използва се за превключване между различни страници на информацията на дисплея.
  • Резистор (10kΩ): Използван за свързване на бутона.
  • Резистор (4.7kΩ): Използван за свързване на DHT22 сензора.
  • Проводници: За осъществяване на свързването между компонентите.
  • Breadboard (Прототипна платка): За лесно свързване на компонентите.

Библиотеки

Този проект използва следните библиотеки:

  • U8glib: Библиотека, предназначена за работа с графични LCD дисплеи, като LCD 128×64 който ще използваме. Тя е лесна за използване и предлага разнообразие от функции за рисуване на елементи върху дисплея. Може да я свалите от тук: U8glib. Най-новите версии на билиотеката може да свалите от тук.
  • DHT: Библиотека, която улеснява работата с DHT сензори за температура и влажност (като DHT22). Тя предоставя лесен начин за изчитане на температура и влажност. Тази библитека може да свалите от тук: DHTlib.

Ако не знаете как да инсталирате тези библиотеки в средата на разработка на Arduino (Arduino IDE), прочетете нашата страница Arduino IDE бърз преглед. Там ще научите повече за възможностите на Arduino IDE.

Свързване на компонентите

За правилното свързване на схемата трябва да се запознаете с платформата Arduino UNO. В нашето ревю за нея ще намерите необходимата информация за нря, както и диаграмата на пиновете (pinout): Arduino UNO.

  • Arduino Uno и ST7920 дисплей:
    • EN (Enable) – Свържете с пин 13 на Arduino.
    • RW (Read/Write) – Свържете с пин 12 на Arduino.
    • RS (Register Select) – Свържете с пин 11 на Arduino.
    • VCC и GND на дисплея трябва да бъдат свързани съответно към захранването (5V) и земята (GND).
  • DHT22 сензор:
    • VCC – Свържете с 5V на Arduino.
    • GND – Свържете с GND на Arduino.
    • Data – Свържете към пин 3 на Arduino, като поставите резистор 4.7kΩ между пиновете Data и VCC за стабилизиране на сигнала.
  • Бутон:
    • Единият крак на бутона се свързва с пин 2 на Arduino.
    • Другият крак се свързва към GND, като използвате резистор 10kΩ за избягване на шум (pull-down резистор).
DHT22 диаграма на пиновете (pinout)

Код за управление на LCD 128×64 с Arduino

#include "U8glib.h"
#include <dht.h>

dht DHT;
#define DHT22_PIN 3

#define EN 13
#define RW 12
#define RS 11

U8GLIB_ST7920_128X64_4X lcd(EN, RW, RS);

#define BUTTON_PIN 2  // Дефинираме пин 2 като пин за бутона
int button_count = 0; // Задаваме начална стойност на брояча

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

  lcd.firstPage();
    do {
      lcd.drawFrame(0, 0, 128, 64);  // Извеждане на рамка
      lcd.setFont(u8g_font_9x18); // Задава фонт с размери 5х7. Може и да е: 4x6, 5x7, 6x10, 9x18
      lcd.drawStr(18, 20, "hello from"); // Принтира стринг с позиция х=18 , y=20 и "СТРИНГ"
      lcd.setFont(u8g_font_6x10); // Задава фонт с размери 5х7. Може и да е: 4x6, 5x7, 6x10, 9x18
      lcd.drawStr(10, 45, "www.ardudevelop.eu"); // Принтира стринг с позиция х=10 , y=52 и "СТРИНГ"
    } while (lcd.nextPage());
}

void loop() {
  // Четене на състоянието на бутона
  int buttonState = digitalRead(BUTTON_PIN);

  // Ако бутонът е натиснат
  if (buttonState == HIGH) {
    button_count++;
    delay(250); // Закъснение за да избегнем многократно увеличаване на брояча

    // Ако броячът надвиши 2, връщаме го на 1
    if (button_count >= 3) {
      button_count = 1;
    }
  }

  Serial.println(button_count); // Печатаме стойността на брояча за тест

  // Режим 1: Показване на стойностите на A0 и A1
  if (button_count == 1) {
    
    lcd.firstPage();
    do {
      // Прочитаме стойностите на A0 и A1 вътре в рендериращия цикъл


      lcd.drawFrame(0, 0, 128, 64);  // Извеждане на рамка
      lcd.drawLine(64, 0, 64, 64);   // Рисуваме линия в средата вертикално
      lcd.drawLine(0, 32, 128, 32);  // Рисуваме линия в средата хоризонтално

      // Принтираме стойността на A0
      lcd.setFont(u8g_font_5x7);
      lcd.drawStr(10, 20, "A0 = "); //x,y
      lcd.setPrintPos(35, 20);
      lcd.print(analogRead(A0));

      // Принтираме стойността на A1
      lcd.setFont(u8g_font_5x7);
      lcd.drawStr(74, 20, "A1 = ");
      lcd.setPrintPos(99, 20);
      lcd.print(analogRead(A1));

      // Принтираме стойността на A2
      lcd.setFont(u8g_font_5x7);
      lcd.drawStr(10, 52, "A2 = ");
      lcd.setPrintPos(35, 52);
      lcd.print(analogRead(A2));

      // Принтираме стойността на A3
      lcd.setFont(u8g_font_5x7);
      lcd.drawStr(74, 52, "A3 = ");
      lcd.setPrintPos(99, 52);
      lcd.print(analogRead(A3));
      
    } while (lcd.nextPage());

    delay(200);
  }

  // Режим 2: Показване на стойността на A1
  if (button_count == 2) {
    int chk = DHT.read22(DHT22_PIN);
    
    lcd.firstPage();
    do {

      lcd.drawFrame(0, 0, 128, 64);  // Извеждане на рамка
      lcd.setFont(u8g_font_6x10); // Задаване на размер на шрифта 6х10
      lcd.drawLine(0, 32, 128, 32);  // Рисуваме линия в средата хоризонтално
      
      lcd.drawStr(15, 20, "DHT-Temp= "); //x,y
      lcd.setPrintPos(73, 20);
      lcd.print(DHT.temperature, 1);
      lcd.drawStr(93, 20, " *C"); //x,y

      lcd.drawStr(15, 50, "DHT-Hum = "); //x,y
      lcd.setPrintPos(73, 50);
      lcd.print(DHT.humidity, 1);
      lcd.drawStr(93, 50, " %"); //x,y
      
    } while (lcd.nextPage());
    
    delay(200);
  }
}

Структура на кода и обяснение

След като сме свързали компонентите, ще разгледаме как да ги управляваме с помощта на кода.

#include "U8glib.h"
#include <dht.h>

Тук включваме необходимите библиотеки за управление на графичния дисплей LCD 128×64 и за работа с DHT сензора.

dht DHT;
#define DHT22_PIN 3

Създаваме обект DHT от класа dht, който ще използваме за изчитане на данни от сензора DHT22. Дефинираме DHT22_PIN като пин 3, където сме свързали изходния сигнал на DHT22 сензора.

#define EN 13
#define RW 12
#define RS 11

U8GLIB_ST7920_128X64_4X lcd(EN, RW, RS);

Дефинираме трите контролни пина на LCD дисплея (EN, RW, RS) и ги свързваме към съответните пинове на Arduino. След това създаваме обект lcd от типа U8GLIB_ST7920_128X64_4X, който ще използваме за управление на графичния LCD 128×64 дисплей с Arduino.

#define BUTTON_PIN 2  // Дефинираме пин 2 като пин за бутона
int button_count = 0; // Задаваме начална стойност на брояча

Дефинираме BUTTON_PIN като пин 2 на Arduino и го използваме за свързване на бутона. Създаваме и променливата button_count, която ще следи колко пъти е натиснат бутонът, като първоначалната ѝ стойност е 0.

Функция setup()

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

  lcd.firstPage();
  do {
    lcd.drawFrame(0, 0, 128, 64);  // Извеждане на рамка
    lcd.setFont(u8g_font_9x18); // Задава фонт с размери 9x18
    lcd.drawStr(18, 20, "hello from"); // Принтира стринг с позиция х=18 , y=20
    lcd.setFont(u8g_font_6x10); // Задава фонт с размери 6x10
    lcd.drawStr(10, 45, "www.ardudevelop.eu"); // Принтира стринг с позиция х=10 , y=45
  } while (lcd.nextPage());
}

В setup() функцията инициализираме серийния монитор със скорост 9600 бод, за да можем да следим съобщения за дебъгване. Задаваме бутона като вход чрез pinMode(BUTTON_PIN, INPUT). След това използваме lcd.firstPage() и цикъл do...while за изчертаване на първоначалната страница с послание „hello from www.ardudevelop.eu.

Основната функция loop()

В loop() се изпълнява логиката на програмата, включително обработка на бутона и изобразяване на страниците.

void loop() {
  // Четене на състоянието на бутона
  int buttonState = digitalRead(BUTTON_PIN);

  // Ако бутонът е натиснат
  if (buttonState == HIGH) {
    button_count++;
    delay(250); // Закъснение за да избегнем многократно увеличаване на брояча

    // Ако броячът надвиши 2, връщаме го на 1
    if (button_count >= 3) {
      button_count = 1;
    }
  }

  Serial.println(button_count); // Печатаме стойността на брояча за тест

Тук проверяваме състоянието на бутона с digitalRead(). Ако бутонът е натиснат (buttonState == HIGH), увеличаваме стойността на button_count с единица. Добавяме закъснение от 250 милисекунди, за да избегнем задържане на бутона и неволно увеличаване на брояча. Ако button_count достигне или надхвърли 3, го връщаме на 1, защото имаме само два режима на показване.

Страница 1: Показване на аналоговите входове

  if (button_count == 1) {
    lcd.firstPage();
    do {
      // Прочитаме стойностите на A0 и A1 вътре в рендериращия цикъл
      lcd.drawFrame(0, 0, 128, 64);  // Извеждане на рамка
      lcd.drawLine(64, 0, 64, 64);   // Рисуваме линия в средата вертикално
      lcd.drawLine(0, 32, 128, 32);  // Рисуваме линия в средата хоризонтално

      // Принтираме стойността на A0
      lcd.setFont(u8g_font_5x7);
      lcd.drawStr(10, 20, "A0 = ");
      lcd.setPrintPos(35, 20);
      lcd.print(analogRead(A0));

      // Принтираме стойността на A1
      lcd.drawStr(74, 20, "A1 = ");
      lcd.setPrintPos(99, 20);
      lcd.print(analogRead(A1));
      
      // Принтираме стойността на A2
      lcd.setFont(u8g_font_5x7);
      lcd.drawStr(10, 52, "A2 = ");
      lcd.setPrintPos(35, 52);
      lcd.print(analogRead(A2));

      // Принтираме стойността на A3
      lcd.drawStr(74, 52, "A3 = ");
      lcd.setPrintPos(99, 52);
      lcd.print(analogRead(A3));
      
    } while (lcd.nextPage());

    delay(200);
  }

Тук показваме стойностите на аналоговите входове – А0, A1, A2 и А3. За всеки вход използваме следната последователност:

  1. Шрифт: Настройваме шрифта с lcd.setFont(u8g_font_5x7), за да гарантираме, че всички изходни данни ще бъдат лесно четими и подравнени.
  2. Текстово обозначение: Извеждаме текста “А0=, A1 =“, “A2 =” и “А3=” на екрана, за да се знае коя стойност се показва, използвайки lcd.drawStr().
  3. Позиция и стойност: Използваме lcd.setPrintPos() за задаване на позицията, в която ще принтираме стойността, и lcd.print(analogRead(A0)), lcd.print(analogRead(A1)), lcd.print(analogRead(A2)) или lcd.print(analogRead(A3)) за извеждане на реалната стойност, прочетена от съответния аналогов пин.

Тази част на кода се изпълнява в рамките на рендериращия цикъл do...while (lcd.nextPage()). Това е необходимо, защото графичният дисплей се опреснява страница по страница. Функцията lcd.nextPage() завършва цикъла, след като всички страници са изобразени.

Страница 2: Показване на стойностите от DHT22 сензора

  if (button_count == 2) {
    int chk = DHT.read22(DHT22_PIN);
    
    lcd.firstPage();
    do {
      lcd.drawFrame(0, 0, 128, 64);  // Извеждане на рамка
      lcd.setFont(u8g_font_6x10); // Задаване на размер на шрифта 6х10
      lcd.drawLine(0, 32, 128, 32);  // Рисуваме линия в средата хоризонтално
      
      // Принтиране на температурата
      lcd.drawStr(15, 20, "DHT-Temp= "); // Изписваме "DHT-Temp="
      lcd.setPrintPos(73, 20);
      lcd.print(DHT.temperature, 1);    // Принтираме температурата от DHT сензора с 1 знак след десетичната точка
      lcd.drawStr(93, 20, " *C");       // Добавяме единицата за температура (градуси по Целзий)

      // Принтиране на влажността
      lcd.drawStr(15, 50, "DHT-Hum = "); // Изписваме "DHT-Hum="
      lcd.setPrintPos(73, 50);
      lcd.print(DHT.humidity, 1);       // Принтираме влажността от DHT сензора с 1 знак след десетичната точка
      lcd.drawStr(93, 50, " %");        // Добавяме единицата за влажност (процент)
      
    } while (lcd.nextPage());
    
    delay(200);
  }
}

Когато button_count е равно на 2, програмата преминава към показване на информация от DHT22 сензора. В тази част от кода:

  1. Четене на данните от DHT22: Използваме DHT.read22(DHT22_PIN) за четене на температурата и влажността от DHT22. Променливата chk съхранява резултата от операцията, който може да е полезен за диагностика, но в този случай не се използва допълнително.
  2. Инициализиране на дисплея: С lcd.firstPage() започваме рендериращия цикъл. Всяка страница от дисплея се рендерира в рамките на do...while (lcd.nextPage()).
  3. Рамка и хоризонтална линия: Подобно на предишния режим, изчертаваме рамка и хоризонтална линия, разделяща дисплея на две части, за по-добро визуално оформление.
  4. Принтиране на температурата:
    • С lcd.drawStr(15, 20, "DHT-Temp= ") изписваме текста „DHT-Temp=“.
    • С lcd.setPrintPos(73, 20) задаваме позицията, на която ще изведем стойността на температурата.
    • След това с lcd.print(DHT.temperature, 1) принтираме стойността на температурата, като използваме 1 знак след десетичната запетая.
    • Добавяме градуси по целзии към измерването („*C“) с lcd.drawStr(93, 20, " *C").
  5. Принтиране на влажността:
    • По същия начин използваме lcd.drawStr(15, 50, "DHT-Hum = "), за да изведем текста „DHT-Hum=“.
    • След това с lcd.setPrintPos(73, 50) задаваме позицията, а с lcd.print(DHT.humidity, 1) извеждаме стойността на влажността, с един знак след десетичната запетая.
    • Накрая добавяме знак за влажност („%“) с lcd.drawStr(93, 50, " %").

Arduino и LCD 128×64 Сменяеми страници с данни от сензори Видео презентация

Заключение и подобрения

В този проект създадохме система, която позволява визуализация на данни от аналогови входове и DHT22 сензор с помощта на графичен дисплей LCD 128×64 и бутон на платформата Arduino UNO. Натискането на бутона ни дава възможност да преминаваме между различни страници с информация, като използваме button_count за следене на текущия режим.

Проектът е много полезен за тези, които искат да научат повече за работата с графични LCD дисплеи, сензори и интерфейси в комбинация с Arduino.

Ето някои идеи за подобрения и разширения на проекта:

  1. Добавяне на повече сензори: Можете да добавите повече сензори, например за налягане или светлина, и да създадете допълнителни страници с информация.
  2. Подобряване на интерфейса: Можете да добавите визуални индикатори като икони за температура и влажност, за да направите интерфейса по-привлекателен.
  3. Дългосрочно съхранение на данните: Можете да добавите SD карта, на която да съхранявате данните от сензорите, което ще ви позволи по-късно да анализирате резултатите.
  4. Използване на ротари енкодер вместо бутон: Ротари енкодерът може да предостави по-удобен начин за навигация между страниците и задаване на параметри.
  5. Добавяне на аларма или известия: Можете да добавите функционалност за аларма, която да се активира при достигане на определени стойности, например при прекалено висока температура или влажност.

С този проект успяхме да покажем как да съберем данни от сензори и да ги визуализираме по удобен и достъпен начин с помощта на графичен LCD дисплей. Надявам се, че този подробен преглед ще ви помогне да разширите знанията си и да започнете да правите още по-сложни и интересни проекти с Arduino. Успех!

Translate »