Статьи » Разработки
Добавить статью

LCD ST7920 и Arduino: Вывод различных данных

2018-02-12 в 19:53 (последнее изменение 2023-11-09 в 11:02)

В статье познакомлю вас со способом, как можно вывести некоторую информацию на LCD дисплей разрешением 128x64 пикселей и контроллере ST7920 с помощью Arduino Mega. Будем выводить температуру и влажность датчиком DHT 11, время и дату с помощью модуля реального времени, уровень освещения двумя аналоговыми датчиками освещенности на фоторезисторах.
А как вывести картинку на такой дисплей узнаете здесь.

Начнем с подключения библиотек.

Код
#include "U8glib.h"    // библиотека для работы с LCD дисплеем
#include "dht11.h"     // библиотека для работы с датчиком влажности и температуры
#include <Wire.h>     // библиотека для работы с I2C интерфесом
#include "RTClib.h"    // библиотека для работы с модулем часов реального времени (RTC - Real_time_clock)

Библиотека U8glib - скачать
Библиотека dht11 - скачать
Библиотека RTClib - скачать

Далее производим объявление переменных.

Код
RTC_DS1307 rtc;
dht11 DHT;                     // Объявление переменной класса dht11

Код
int chk;
#define DHT11_PIN 12     // Датчик DHT11 подключен к цифровому пину номер 12
const int ledlight = 9;       // К 9 выводу подключен MOSFET модуль для включения светодиодной ленты
const int sensor1 = 2;      // Первый датчик освещенности подключен к аналоговому пину 2
const int sensor2 = 0;      // Второй датчик освещенности подключен к аналоговому пину 0

Код
U8GLIB_ST7920_128X64_1X u8g( 13, 11, 10);  // Создаём объект u8g для работы с дисплеем, указывая номер вывода CS для аппаратной шины SPI

Следующий шаг - назначение вводов и выводов.

Код
pinMode(ledlight, OUTPUT);  // Определяем переменную ledlight как вывод
pinMode(sensor1, INPUT);    // Определяем переменную sensor1 как ввод

Теперь нужно сделать прорисовку на дисплее. Сверху делаем белую строку сплошной закраски.

Код
u8g.setColorIndex(1);           // Определяем закрасить (1) или нет (0)
u8g.drawBox(0, 0, 128, 10);  // Рисуем прямоугольник 128х10 пикселей в самом верху

Устанавливаем шрифт, которым будем писать в этой самой строке. Его, кстати, тоже нужно скачать и поместить в папку библиотеки дисплея.

Шрифт LCD дисплея u8g_font_5x8 - скачать.

Код
u8g.setFont(u8g_font_5x8);

Нужно указать, что следующие символы мы будем писать на белом фоне отключая пиксели (0).

Код
u8g.setColorIndex(0);

В этой строке мы выведем время и дату.

Код

    u8g.setPrintPos( 2, 8); u8g.print(now.day() / 10);
    u8g.setPrintPos( 7, 8); u8g.print(now.day() % 10);
    u8g.setPrintPos( 11, 8); u8g.print(".");
    u8g.setPrintPos( 15, 8); u8g.print(now.month() / 10);
    u8g.setPrintPos( 20, 8); u8g.print(now.month() % 10);
    u8g.setPrintPos( 24, 8); u8g.print(".");
    u8g.setPrintPos( 29, 8); u8g.print(now.year(), DEC);

    u8g.setPrintPos( 101, 8); u8g.print(now.hour() / 10);
    u8g.setPrintPos( 107, 8); u8g.print(now.hour() % 10);
    u8g.setPrintPos( 112, 8); u8g.print(":");
    u8g.setPrintPos( 117, 8); u8g.print(now.minute() / 10);
    u8g.setPrintPos( 122, 8); u8g.print(now.minute() % 10);

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

Теперь настроим вывод температуры и влажности. Все это уже будет написано другим шрифтом 6х10.

Шрифт LCD дисплея u8g_font_6x10 - скачать.

Код
u8g.setFont(u8g_font_6x10);

Код
chk = DHT.read(DHT11_PIN);

Код

    u8g.setPrintPos( 3,  20); u8g.print("Humidity");
    u8g.setPrintPos( 53, 21); u8g.print("=");
    u8g.setPrintPos( 60, 20); u8g.print(DHT.humidity, 1);
    u8g.setPrintPos( 73, 20); u8g.print("%");

    u8g.setPrintPos( 3,  31); u8g.print("Temp");
    u8g.setPrintPos( 29, 32); u8g.print("=");
    u8g.setPrintPos( 37, 31); u8g.print(DHT.temperature, 1);
    u8g.setPrintPos( 49, 31); u8g.print("°C");

    u8g.setPrintPos( 3,  42); u8g.print("Light");
    u8g.setPrintPos( 29, 43); u8g.print(" - ");
    if (digitalRead(sensor1) == HIGH) {
      u8g.setPrintPos( 45, 42); u8g.print("On");
    }
    else
    {
      u8g.setPrintPos( 45, 42); u8g.print("Off");
    }

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

Код
    u8g.setPrintPos( 65, 43); u8g.print("=");

    int val = analogRead(sensor2);
    val = map(val, 0, 1023, 0, 100);
    u8g.setPrintPos( 73, 42); u8g.print(val);
    u8g.setPrintPos( 86, 42); u8g.print("%");

И вот что должно получиться.

Код

#include "U8glib.h"    \\библиотека для работы с LCD дисплеем
#include "dht11.h"     \\библиотека для работы с датчиком влажности и температуры
#include <Wire.h>      \\библиотека для работы с I2C интерфесом
#include "RTClib.h"    \\библиотека для работы с модулем часов реального времени (RTC - Real_time_clock)

RTC_DS1307 rtc;
dht11 DHT;                                 // Объявление переменной класса dht11

int chk;
#define DHT11_PIN 12                       // Датчик DHT11 подключен к цифровому пину номер 13
const int ledlight = 9;
const int sensor1 = 2;
const int sensor2 = 0;

U8GLIB_ST7920_128X64_1X u8g( 13, 11, 10);  // Создаём объект u8g для работы с дисплеем, указывая номер вывода CS для аппаратной шины SPI

void setup() {

  pinMode(ledlight, OUTPUT);
  pinMode(sensor1, INPUT);

  if (! rtc.begin()) {
    while (1);
  }

  if (! rtc.isrunning()) {
  }

}

void loop () {
  DateTime now = rtc.now();
  if (digitalRead(sensor1) == HIGH) {
    digitalWrite(ledlight, HIGH);
  }
  else
  {
    digitalWrite(ledlight, LOW);
  }
  u8g.firstPage();                          // Всё что выводится на дисплей указывается в цикле: u8g.firstPage(); do{ ... команды ... }while(u8g.nextPage());
  do {
    u8g.setColorIndex(1);
    u8g.drawBox(0, 0, 128, 10);
    u8g.setFont(u8g_font_5x8);
    u8g.setColorIndex(0);
    u8g.setPrintPos( 2, 8); u8g.print(now.day() / 10);
    u8g.setPrintPos( 7, 8); u8g.print(now.day() % 10);
    u8g.setPrintPos( 11, 8); u8g.print(".");
    u8g.setPrintPos( 15, 8); u8g.print(now.month() / 10);
    u8g.setPrintPos( 20, 8); u8g.print(now.month() % 10);
    u8g.setPrintPos( 24, 8); u8g.print(".");
    u8g.setPrintPos( 29, 8); u8g.print(now.year(), DEC);

    u8g.setPrintPos( 101, 8); u8g.print(now.hour() / 10);
    u8g.setPrintPos( 107, 8); u8g.print(now.hour() % 10);
    u8g.setPrintPos( 112, 8); u8g.print(":");
    u8g.setPrintPos( 117, 8); u8g.print(now.minute() / 10);
    u8g.setPrintPos( 122, 8); u8g.print(now.minute() % 10);
    u8g.setColorIndex(1);
    u8g.setFont(u8g_font_6x10);
    u8g.drawStr(30, 62, "tehnopage.ru");
    u8g.setFont(u8g_font_6x10);

    chk = DHT.read(DHT11_PIN);

    u8g.setPrintPos( 3,  20); u8g.print("Humidity");
    u8g.setPrintPos( 53, 21); u8g.print("=");
    u8g.setPrintPos( 60, 20); u8g.print(DHT.humidity, 1);
    u8g.setPrintPos( 73, 20); u8g.print("%");

    u8g.setPrintPos( 3,  31); u8g.print("Temp");
    u8g.setPrintPos( 29, 32); u8g.print("=");
    u8g.setPrintPos( 37, 31); u8g.print(DHT.temperature, 1);
    u8g.setPrintPos( 49, 31); u8g.print("°C");

    u8g.setPrintPos( 3,  42); u8g.print("Light");
    u8g.setPrintPos( 29, 43); u8g.print(" - ");
    if (digitalRead(sensor1) == HIGH) {
      u8g.setPrintPos( 45, 42); u8g.print("On");
    }
    else
    {
      u8g.setPrintPos( 45, 42); u8g.print("Off");
    }

    u8g.setPrintPos( 65, 43); u8g.print("=");

    int val = analogRead(sensor2);
    val = map(val, 0, 1023, 0, 100);
    u8g.setPrintPos( 73, 42); u8g.print(val);
    u8g.setPrintPos( 86, 42); u8g.print("%");


  }    while (u8g.nextPage());
}


Не пропустите обновления! Подписывайтесь на нашу группу Вконтакте.
Так же у нас есть Telegram канал.
Вам понравился наш материал? Поделитесь с коллегами!

Просмотров: 26271. Оценка статьи: 5.0 из 5. Уже оценило 7 читателей

Об авторе - Администратор

More by Администратор

Всего комментариев: 1
Матвей 2020-04-08 12:12
Здравствуйте!
Подскажите пожалуйста, как реализовать подключение энкодера? Дело в том, что из-за данного дисплея данные с энкодера читаются некорректно, т.е. считывает лишь через десяток "тиков".
Заранее спасибо.

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]