Графический экран WG12864B (и ему подобные на ks0107/ks0108)


Когда-то товарищ burjui рассказал нам как работать с знакосинтезирующим lcd экраном, а также обучил его русской речи и даже основам графики – нарисовал несколько значков. Вот только примитивные значки это максимум, что можно получить от символьных дисплеев — и то с некоторым трудом, без проблем только буковки-циферки, строчные-заглавные. А хочется картинок. Размеров, шрифтов разных, курсивов, там, менюшек модных.
Для этого придумали графические дисплеи.
Они, как и символьные, формируют изображение зажигая/гася точки-пиксели.
Кстати, как-то мы обошли вниманием в прошлый раз тот факт, что работать с точечками напрямую было бы очень уныло — никаких выводов не напасёшься (80х16 точек у символьного и 128х64 у графического). Но добрые китайские духи электроники позаботились о нас и снабдили эти девайсы собственными контроллерами. Для символьных экранов стандартный контроллер HD44780 (ks0066) а для графических — ks0107 (ks0108).
В случае WG12864B их там целых два — на на правую и левую часть экрана. Это потому что ks0108 может обеспечить вывод только на 64х64точки, вот и получился двухядерный дисплей=)

Общаться с контроллерами дисплея предстоит по:

DB0-DB7 — шине данных
R/W — указывая, передаём — 0 (или читаем — 1)
D/I — данные — 1 (или команду — 0)
CS1, CS2 — какому контроллеру
E – и проталкивая каждое действие синхроимпульсом
Также есть:
RST — сброс(резет)
Vdd — питание 5В
GND — земля
Vo — контраст
Vee — источник отрицательного напряжения для контраста(если экран инверсный)
A — анод и
K — катод светодиода подсветки

Поиграемся с WG12864B-TML, вот его распиновка:

Итого минимум 13 линий дуины предстоит принести в жертву красоте индикации=\
Подключается дисплей довольно просто (если, конечно, не считать количества проводков=) Как и в случае с символьным экраном кроме линий связи с мк понадобятся потенциометр регулировки контраста (обратите внимание на оригинальное подключение)
и токоограничительный резистор для подсветки.
Хотя некоторые его не ставят.
Напрасно, кстати — падение на светодиодах подсветки, как гласит датащит, не более 4.6 вольт, и впихивая туда все 5, рискуем их пожечь безвозвратно.

В ИДЕ-шку не включена библиотека для работы с графическими дисплеями, а на плейграунде лежит старая версия, поэтому берём отсюда, или у нас.
Подключаем согласно описанию (GLCD_Documentation.pdf лежит в папке glcd\doc, можно взять здесь или почитать перевод), наш дисплей — “Panel A”(в доке ошибка, см далее, юзайте эту схему, она правильная)

Удивляясь столь извращённому методу разбрасывания проводов по дуине, читаем чуть внимательней и узнаём, что совсем не обязательно именно так плести этот клубок

можно поменять расположение линий поправив glcd\config\ks0108_Arduino.h. То есть можем расположить эти 13 выводов в произвольном порядке, оставляя свободными именно те пины (…все 7, ни в чём себе не отказывайте, ага=), которые понадобятся нам для подключения всего остального.
Но мы так делать не будем, а просто побыстрей закинем в arduino-xxx\hardware\libraries папку glcd из скачанного архива. Запустим ИДЕ-шку и выбрав File->Exampes->glcd>ks0108example, трясущимися руками зальём всё это дело в плату. Залилось, включилось, крутим контраст…и что-то фигово видно=\

Меряем питание и узнаём что наш экран ужасно прожорлив=) Просело аж до 4.2 В.
Подключаем внешнее питание.

Чтозаужоснах!
Экран перепутался пополам=\ Тут самое время вспомнить, что у нас именно два контроллера и запись в них осуществляется по очереди, посредством выбора одного из них еденичкой на линии CS1 или CS2. Они-то у нас и перепутались… как-то, а точнее положение их не соответствует, предложенной автором распиновке=\
Меняем местами.

Так гораздо лучше=)
Симпатично, можно позаливать ещё примеры. Там есть «игра» жизнь, с ужасной скоростью прокручиваемые шрифты и бегущие таймеры, всем своим видом показывающие не высокую скорость обновления данного дисплея=) Часы мне так и не удалось скомпилировать — ИДЕ-шка непрерывно ругается на отсутствие библиотек (а при их добавлении сыплет другими ошибками). Особого внимания стоит игра Rocket, добавив потенциометр и бузер можно немного по ностальгировать=)

Но пора уже слепить что-нибудь своё, пусть и не столь впечатляющее.
Для этого придётся почитать объёмистое описание этой убербиблиотеки.
А для более полного краштеста сделаем свой рисунок и свой шрифт=)

Шрифты генерятся утилиткой GLCDFontCreator2, качать здесь, или у нас.
Запускается жмаканьем на start.bat, вот такой френдли интерфейс.

Кнопки Open Font/Save Font — это для внутреннего, понятного только для GLCDFontCreator2, формата шрифтов(рабочие файлы), открывать сами шрифты прога не умеет — ни сконвертированные ею самою в .h ни .ttf=(
Так что жмём NewFont, и уже там импортируем какой-нибудь шрифт из уже установленных у вас в системе.

Стоит сразу как-нибудь осмысленно обозвать своё творение, т.к. именно под этим именем (newFont у меня=) он, впоследствии, будет доступен нашему скетчу.
Можно что-нибудь подрисовать.

Давим кнопку Export, указывая желаемое имя файла и расположение (да и не забудьте к имени файла дописать «.h», программа не считает, что это нужно=)
Всё это круто, за исключением одной мелочи — русских букв программа не знает=(
Если указать диапазон символов помимо стандартного (Start Index и Char Count), то на месте родной кириллицы открытого шрифта видны только пустые шедевры Малевича.
Можно попробовать вместо них намалевать чего-нибудь, но мне жутко лень=)
К тому же товарищ SkyFort уже провёл соответствующие исследования и работы. Правда он пошёл несколько иным путём — не через GLCDFontCreator2 а используя KS0108v 4.0 For PIC (если с narod.ru что-то случится то файл можно взять у нас).
В результате у него получился шрифт SystemRus5x7.h его то я и использую=)

Так, накреативили шрифты, теперь займёмся картинками.

Для этого нам прям в архив с библиотекой засунули папку bitmaps, которая хорошо видна в виде тестового скетча из примеров glcd в Arduino IDE, но почему-то не компилится=)))
А всё дело в том, что там лежит скетч для Processig-а, и даже готовый к запуску файлик glcd/bitmaps/utils/java/glcdMakeBitmap.jar
Программа ещё более юзерфрендли и поддерживает втаскивание в своё окно картинок в нескольких форматах.

Правда на этом её дружелюбность заканчивается — пихать туда надо уже чёрно-белую картинку нужного размера, приведения размеров и цветов программа не производит.
Если картинка смогла прожеваться то в окошке нам об этом сообщат, и даже покажут что получилось, а в папке glcd/bitmaps появится файл «имя_втащеного_файла.h»

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

#include <glcd.h> //подключим библиотеку
#include "SystemRus5x7.h" // прицепим шрифты
#include "new_Font.h"
#include "Gothic.h"

#include "zb.h" // прицепим картинки
#include "bender.h"

gText LeftTextArea;

void setup() {
GLCD.Init(); //инициализация
}

void loop()
{
GLCD.SelectFont(SystemRus);       //выбираем шрифт
GLCD.println("Графические экраны, "); //пишем им
GLCD.println(" это жутко прикольно");
delay(2000);
GLCD.println("сюда можно впихнуть ");
GLCD.println("много текста=)");
delay(2000);
GLCD.println("");
GLCD.println("И даже разными ");
GLCD.println("   шрифтами");

delay(3000);
GLCD.ClearScreen(); //очистим экран
GLCD.SelectFont(Gothic); //выберем другой шрифт
GLCD.CursorToXY(8,5); //установим курсор
GLCD.println("RoboCraft");  //и напишем там чего-нибудь
GLCD.SelectFont(new_Font);
GLCD.CursorToXY(10,35);
GLCD.println("WG12864B");
delay(5000);

GLCD.ClearScreen();
GLCD.SelectFont(SystemRus);
GLCD.CursorToXY(0,25);
GLCD.println(" А еще можно выводить");
GLCD.println("  простые картинки");
delay(3000);

GLCD.ClearScreen();
GLCD.DrawBitmap(zb, 0,  0); //выведем картинку
delay(2000);

GLCD.ClearScreen();
GLCD.DrawBitmap(bender, 0,  0); //и ещё одну
delay(2000);

GLCD.FillRect(GLCD.CenterX + 12, 0, GLCD.CenterX -22, GLCD.Bottom, WHITE); //сотрём участок картинки
GLCD.DrawRoundRect(GLCD.CenterX + 13, 0, 49, GLCD.Bottom, 5); // и нарисуем там "облачко" почти как в комиксах=)
delay(200);
LeftTextArea.DefineArea(GLCD.CenterX + 15, 3, GLCD.Right-2, GLCD.Bottom-3, SCROLL_UP); // в облачке сделаем текстовую область с прокруткой вверх
LeftTextArea.SelectFont(SystemRus); //выберем шрифт для этой текстовой области
LeftTextArea.println("Работать, жалкие людишки!");// бендер говорит
LeftTextArea.println(" ");
delay(2000);
LeftTextArea.println("Слава");
LeftTextArea.println("робатам!");
LeftTextArea.println(" ");
delay(2000);
LeftTextArea.println("Смерть человекам!");
delay(3000);
GLCD.ClearScreen();
}

Шрифты и картинки в скетч включаются также как и библиотеки, и жрут немало места(особенно крупные шрифты)Например этот скетч влезет только(как минимум) в плату на базе Atmega328 .
Скетч, шрифты и картинки одним архивом.

Видео того, что получилось:

Осталось разобраться с менюшками и прикрутить экран к сдвиговым регистрам для экономии ног.
Но это уже совсем другая история=)

Подробности про всю сигнально — битовую светотень творящуюся на линии связи МК и экрана почитать можно у ДиХальта, как обычно, всё разжёвано подробно и толково.
Перевод описания библиотеки GLCD.
Также, пока я собирался выложить эти статьи товарищ SinauRus перевёл мануал а SkyFort заставил wg1286 говорить по-русски=)


0 комментариев на «“Графический экран WG12864B (и ему подобные на ks0107/ks0108)”»

  1. А можно освободить аналоговые выходы ардуины, т.е. перекинуть на цифровые? Мне нужна шина I2C. И было интересно, если бы кто-нибудь подсказал можно ли такой дисплей подключить через сдвиговые регистры?

    • можно поменять расположение линий поправив glcd\config\ks0108_Arduino.h

      Пробовал, работает, там всё предельно просто и понятно=)

      … можно ли такой дисплей подключить через сдвиговые регистры?

      ИМХО более чем возможно, пока в процессе. Но не обещаю=)

  2. Привет всем!
    Прикупил дисплей, подключил, на AVR без проблем, все ок!
    На STM32, не хочет вообще ничего показывать. Перепробывал пару либ, пусто.
    Мог бы кто нибудь поопытнее проверить, работают ли они реально.
    Либы:
    ya-el-chuv.narod.ru/index/0-2 // В Keil не собралась, ошибка на буфер (Symbol Video_buffer multiply defined (by main.o and lcd.o)) В кокосе собралась, но не работает
    en.radzio.dxp.pl/ks0108/ // Либа для любого кристала. Тоже не заработала
    И еще одна либа от конторы ST (в кокосе присутствует)

  3. Доброго времени суток! Не могу понять почему в картинке (нарисованной мной) не выводятся 2-3 нижних ряда пикселей (картинка получается обрезанной снизу)? Картинки-примеры, идущие с библиотекой выводятся нормально (пробовал примеры преобразовать заново = выводятся нормально! Кто подскажет в чем причина?
    Спасибо.

    • Сам разобрался! В файле «имя картинки.h» увеличил параметр height (высота) на 2 пункта = картинки отображаются нормально. И так для каждой преобразованной картинки.

  4. В общем посыпалось всякое:

    In file included from C:\PROG\arduino-1.6.0\libraries\glcd/glcd.h:38:0,
    from GLCD_BigDemo.pde:12:
    C:\PROG\arduino-1.6.0\libraries\glcd/fonts/SystemFont5x7.h:48:28: error: variable ‘System5x7’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    static uint8_t System5x7[] PROGMEM = {

    и такого типу тоже штук 25:
    C:\PROG\arduino-1.6.0\libraries\glcd/bitmaps/ArduinoIcon64x32.h:25:41: error: variable ‘ArduinoIcon64x32’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
    static unsigned char ArduinoIcon64x32[] PROGMEM ={

    Кто подскажет, что это?

    • Всё, решил просто: в библиотеке шрифта заменил единственное объявление:
      static uint8_t System5x7[] PROGMEM = {
      на:
      const uint8_t System5x7[] PROGMEM = {

      И так везде, на что ругается (что-то новому IDE не нравится). В общем это лечится просто.

    • Такая же проблема!
      Исправил:
      static uint8_t System5x7[] PROGMEM = {
      на:
      const uint8_t System5x7[] PROGMEM = {

      И добавил, только после этого начала работать:
      #ifdef PROGMEM
      #undef PROGMEM
      #define PROGMEM __attribute__((section(".progmem.vars")))
      #endif

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

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Arduino Bluetooth CraftDuino DIY Google IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение