Ардуино: графический ЖК дисплей Nokia 5110

Символьный дисплей, который мы уже изучили ранее, открыл перед нами большие возможности в плане вывода информации в «человеческом» виде. Можно выводить текстовые сообщения, значения различных параметров, показания датчиков. Если. захотеть, можно даже отобразить на символьном дисплее «псевдографику». Но что, если нам требуется ещё больший уровень информативности? Если для понимания процесса нам нужен, например, график? Что, если мы хотим отобразить состояние робота не сигналом светодиода, а картинкой? Изобразить эмоцию?

IMG_20150927_150442_

Поможет нам в этом деле графический дисплей, а именно Nokia 5110 (или 3310). Этот вид дисплеев широко распространен в мире учебных микроэлектронных платформ, таких как Ардуино. Он легко подключается, и легко управляется даже слабыми микроконтроллерами.

1. Подключение дисплея Nokia 5110

Дисплей монохромный, имеет разрешение 84×48 точек. Как правило, дисплеи Nokia 5110, предназначенные для таких как мы с вами энтузиастов, поставляются на плате в паре с контроллером PCD8544 и штыревым разъемом. У такого дисплейного модуля есть всего 8 ног:

  • RST — сброс (Reset);
  • CE — выбор устройства (Chip Select);
  • DC — выбор режима (Data/Command select);
  • DIn — данные (Data In);
  • Clk — тактирующий сигнал (Clock);
  • Vcc — питание 3 — 5 Вольт;
  • BL — подсветка;
  • Gnd — земля.

Схема подключения к Ардуино:

ЖК дисплей Nokia 5110 RST CE DC DIn Clk Vcc BL Gnd
Ардуино Уно 7 6 5 4 3 +5V +5V GND

2. Программа. Вывод текста

Для управления дисплеем нам потребуется библиотека «Adafruit_GFX_Library», которую можно скачать с официального сайта Adafruit:

https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip

Устанавливаем библиотеку в Arduino IDE, и пробуем вывести на наш дисплей простой текст «Hello world!»:

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7);

void setup() {
    // инициализация и очистка дисплея
    display.begin();
    display.clearDisplay();
    display.display();
    
    display.setContrast(50); // установка контраста
    delay(1000);
    display.setTextSize(1);  // установка размера шрифта
    display.setTextColor(BLACK); // установка цвета текста
    display.setCursor(0,0); // установка цвета текста
  
    display.println("Hello, world!");
    display.display();
}

void loop() {
}

Как видим, все достаточно просто. Функция setContrast — определяет контраст дисплея. Это сродни тому, как если бы мы крутим потенциометр контраста в схеме символьного дисплея. Если после запуска программы у нас на дисплее ничего не видно, или видно плохо — варьируем значение контраста.

Задаем размер шрифта функцией setTextSize. Если указываем 1, то каждая буква шрифта будет размером 5×7 пикселей. Размер 2 увеличит символы ровно в два раза по высоте и ширине.

Следующая полезная функция — setTextColor. У нас есть всего два цвета — черный и белый. Для них определены две константы: BLACK и WHITE.

Наконец, setCursor(x, y) устанавливает курсор в заданные координаты x и y, так же как в программе символьного дисплея.

Непосредственно, сам вывод текста осуществляется уже знакомой функцией println.

Если все сделать правильно, получим такую картинку:

IMG_20150927_150646_

3. Программа. Вывод геометрии

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

За отрисовку окружности отвечает функция drawCircle. Пример вызова функции для окружности с центром в точке {20,20}, радиусом 5 пикселей и черным цветом:

drawCircle(20, 20, 5, BLACK);

Теперь попробуем прямоугольник с координатами верхнего левого угла {10,10}, нижнего правого {20,20}, и цветом BLACK (черный, то бишь).

drawRect(10, 10, 20, 20, BLACK);

Функция drawRoundRect — нарисует прямоугольник со скругленными углами. Также у этих двух функций есть варианты со сплошной заливкой внутренней части фигуры: fillRect и fillRoundRect.

У треугольника следует задать все три пары координат:

drawTriangle(10, 10, 20, 10, 20, 20, BLACK);

И у него тоже есть вариант с заливкой — fillTriangle.

Наконец, просто отрезок из точки {0,0} к точке {20,20}:

drawLine(0, 0, 20, 20, BLACK);

И самое простое, что можно нарисовать — один пиксель:

drawPixel(10, 10, BLACK);

А вот как будет выглядеть программа, если мы захотим нарисовать некоторые из этих фигур, по-очереди:

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

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

void setup() {
    // инициализация и очистка дисплея
    display.begin();
    display.clearDisplay();
    display.display();

    
    display.setContrast(50); // установка контраста
    delay(1000);
}

void loop() {
    // пиксел
    display.clearDisplay();
    display.drawPixel(10, 10, BLACK);
    display.display();
    delay(1000);

    // линия
    display.clearDisplay();
    display.drawLine(0, 0, 50, 30, BLACK);
    display.display();
    delay(1000); 

    // прямоугольник
    display.clearDisplay();
    display.drawRect(0, 0, 10, 10, BLACK);
    display.display();
    delay(1000); 

    // прямоугольник залитый
    display.clearDisplay();
    display.fillRect(0, 0, 10, 10, BLACK);
    display.display();
    delay(1000); 

    // треугольник
    display.clearDisplay();
    display.drawTriangle(0, 0, 40, 40, 30, 20, BLACK);
    display.display();
    delay(1000); 

    // окружность в центре
    display.clearDisplay();
    display.drawCircle(display.width()/2, 
                       display.height()/2, 10, BLACK);
    display.display();
    delay(1000); 
}

5. Программа. Подготовка изображений

А теперь, воспользуемся всей мощью графического дисплея — выведем на него изображение!

Чтобы отобразить на дисплее картинку, нам потребуется привести её к нужному размеру и формату. Как уже упоминалось, дисплей Nokia 5110 имеет разрешение 84×48 точек. Значит и наша картинка должна быть точно таким же размером.

Уменьшить и обрезать картинку до требуемых размеров можно в самом простом редакторе mspaint. Там же нужно сохранить картинку в формате BMP с 256 цветами.

imgtocode_paint

imgtocode_save

Следующий шаг — конвертировать bmp файл в массив нулей и единиц, который мы и вставим в программу для Arduino. Для конвертации воспользуемся онлайн сервисом на нашем сайте: http://git.robotclass.ru/tools/bmptobin.html

Просто выбираем подготовленный bmp файл на локальном компьютере, и указываем одну из систем счисления: двоичную или шестнадцатеричную. Обе одинаково подходят для нашей цели.

Результатом работы этого веб-сервиса станет огромный массив двоичных чисел, который мы должны будем вставить в следующую программу:

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

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

const unsigned char PROGMEM smileBmp[] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x1f, 0x80, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x3f, 0xc0, 0x0, 0x0, 0x7e, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x3f, 0xc0, 0x0, 0x0, 0xfe, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x79, 0xc0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x71, 0xc0, 0x0, 0x1, 0xef, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x73, 0xc0, 0x0, 0x1, 0xc7, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x73, 0xc0, 0x0, 0x1, 0xc7, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x7f, 0x80, 0x0, 0x1, 0xef, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x7f, 0x0, 0x0, 0x0, 0xfe, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x3f, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x1f, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 
0x0, 0x0, 0x3, 0xff, 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x7f, 0xfc, 0x0, 0x7, 0xff, 0xe0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x1, 0xff, 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0xf8, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};

void setup() {
 // инициализация и очистка дисплея
 display.begin();
 display.clearDisplay();
 display.display();

 // установка контраста
 display.setContrast(50);
 delay(1000);

 // отрисовка изображения
 display.drawBitmap(0, 0, smileBmp, 84, 44, BLACK); 
 display.display();
}

void loop() {
}

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

IMG_20150927_032235_

Вот и все на сегодня! В следующем уроке на тему Nokia 5110 мы попробуем анимировать изображение на дисплее. Попробуем даже сделать небольшую игру!

ezgif.com-optimize


Изменено:

Ардуино: графический ЖК дисплей Nokia 5110: 6 комментариев

  1. а конвертер в бинарный массив работает?
    у меня все элементы массива равны 0x00

    • Работает!
      Обязательно нужно проверить формат исходного файла. Должен быть 256-цветный BMP. 8 бит на пиксел.

  2. C другого сайта брал подобный скетч, вылезла проблема, все выводит, а текст почему-то нет. В тот промежуток времени, кода должен выводиться текст просто пустой экран. Взял пример с http://playground.arduino.cc/Code/PCD8544 и у меня все выводит. Где собака порылась, даже в Proteus точно так-же себя ведет.

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>