Урок 7 – графическая библиотека для дисплея st7783

ОБОРУДОВАНИЕ
ТЕХНОЛОГИИ
РАЗРАБОТКИ

Блог технической поддержки моих разработок

Урок 14. Создание и использование библиотек для STM32. Библиотека Debounce.

В уроке научимся создавать пользовательские библиотеки на примере класса Debounce. Также я расскажу, как применять в проекте готовые библиотеки.

В предыдущем уроке мы разработали класс Debounce для обработки дискретных сигналов. С помощью него можно устранять дребезг контактов, фильтровать сигнал, ослаблять влияние электромагнитных помех и т.п.

Класс отлажен, проверен, закончен. Но использовать его в других программах достаточно неудобно. Главная проблема – необходимо копировать исходный код класса в новую программу. При этом можно ошибиться и долго отлаживать давно проверенный и забытый код. Ну и, конечно, ненужный код будет загромождать текст программы, ухудшать читаемость.

Выход очевиден – оформить класс библиотекой. Давайте этим и займемся.

Последовательность действий для создания библиотеки STM32.

Библиотека, по крайней мере, на нашем уровне программирования, это тот же класс, только размещенный в других файлах. В текст программы файлы библиотеки включаются директивой препроцессора #include . Таким образом, текст библиотеки в нашей программе мы не видим. А на этапе компиляции он “подсовывается” компилятору директивой #include . И благополучно транслируется вместе с остальным исходным кодом.

Я скопировал проект предыдущего урока Lesson13_1 в новую папку Lesson14.

Переименовал его в Lesson14_1.

Открыл в Atollic TrueStudio и переименовал его в IDE еще раз. Все это мы уже делали.

Получился проект с классом Debounce из предыдущего урока. Этот класс мы будем оформлять библиотекой.

Библиотека состоит как минимум из двух файлов:

  • заголовочного файла, с расширением .h ;
  • файла исходного текста, расширение .cpp.

Заголовочный файл должен содержать описание класса, объявление переменных, константы. Программный код в нем не размещают.

Второй файл (.cpp) содержит код методов класса.

Давайте создадим файлы библиотеки. Чтобы в структуре проекта не было путаницы, создадим для всех пользовательских библиотек папку Libraries. А в ней папку Debounce, уже для нашей библиотеки.

Правой кнопкой мыши нажимаем на имя проекта, New -> Folder.

Задаем имя папки Libraries.

Теперь нажимаем на Libraries, New -> Folder.

Создаем папку Debounce.

Теперь выбираем папку Debounce, New -> File.

Создаем в ней файлы Debounce.h и Debounce.cpp.

Заголовочный файл Debounce.h.

Неплохо в начале файла поместить краткую информацию о библиотеке. У кого, на что хватит фантазии. Естественно, надо оформить этот блок комментариями.

/*
* Debounce.h – библиотека обработки дискретных сигналов STM32.
*
* Может быть использована для устранения дребезга контактов, цифровой фильтрации сигналов от помех.
*
* Работает в фоновом режиме.
*
* В параллельном процессе регулярно должен вызываться один из методов обработки:
*
* void scanStability(void); // метод ожидания стабильного состояния сигнала
* void scanAverage(void); // метод фильтрации сигнала по среднему значению
*
* В результате формируются признаки состояния сигнала:
*
* uint8_t flagLow; // признак СИГНАЛ В НИЗКОМ УРОВНЕ
* uint8_t flagRising; // признак БЫЛ ПОЛОЖИТЕЛЬНЫЙ ФРОНТ
* uint8_t flagFalling; // признак БЫЛ ОТРИЦАТЕЛЬНЫЙ ФРОНТ
*
* Признаки могут быть прочитаны функциями:
*
* uint8_t readFlagLow(void); // чтение признака СИГНАЛ В НИЗКОМ УРОВНЕ
* uint8_t readFlagRising(void); // чтение признака БЫЛ ПОЛОЖИТЕЛЬНЫЙ ФРОНТ
* uint8_t readFlagFalling(void); // чтение признака БЫЛ ОТРИЦАТЕЛЬНЫЙ ФРОНТ
*
* Пример создания объекта:
* Debounce button(GPIOC, 1
*
* Подробно описана http://mypractic.ru/uroki-stm32 в уроках 12, 13, 14
*
* Разработана Калининым Эдуардом.
*
* http://mypractic.ru
*/

Дальше следует объявление класса, которое надо заключить в конструкцию.

/* Проверка, что библиотека не подключена */
#ifndef DEBOUNCE_H
#define DEBOUNCE_H

#endif /* DEBOUNCE_H */

Это предотвратит повторное подключение библиотеки.

И еще необходимо подключить файл stm32f103xb.h. В нем содержатся CMSIS-имена регистров.

/* Проверка, что библиотека не подключена */
#ifndef DEBOUNCE_H
#define DEBOUNCE_H

#include “stm32f103xb.h”

class Debounce <

#endif /* DEBOUNCE_H */

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

#include “Debounce.h”

Все библиотека создана. Теперь необходимо подключить ее.

Прежде всего, удаляем из main.cpp все то, что мы переместили в библиотечные файлы. А именно: объявление класса и код методов.

Подключаем нашу библиотеку.

#include “../Libraries/Debounce/Debounce.h”

Мы указали полный путь к папке библиотеки.

Можно написать короче:

#include “Debounce.h”

Но тогда путь к папке необходимо сообщить компилятору:

Project -> Build Settings -> Tool Settings -> C++ Compiler -> Directories -> Add (зеленый плюсик сверху).

В списке появится путь к нашей библиотеке

../Inc
../Libraries/Debounce
../Drivers/STM32F1xx_HAL_Driver/Inc
../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy
../Drivers/CMSIS/Device/ST/STM32F1xx/Include
../Drivers/CMSIS/Include

Еще вариант той же операции:

Правой кнопкой мыши нажимаем на папку Debounce в проекте, Add/Remove Include Path -> OK

В списке путей для include появится

Транслируем проект. Получаем сообщения об ошибках компиляции.

Компилятор не нашел коды для методов класса. Мы не сообщили ему, где находится файл Debounce.cpp.

Можно поместить этот файл в папку Src. Компилятор привык там искать исходные тексты. Но мы не будем ломать стройности проекта.

Сделаем так: Project -> Build Settings -> C/C++ General -> Paths and Symbols -> Source Location -> Add Folder -> Libraries -> OK

Другой способ, немного проще:

Правой кнопкой по Libraries, Properties -> C/C++ General -> Paths and Symbols -> Source Location -> Add Folder -> Apply

Свершилось. Теперь компилируется без ошибок.

Вот ссылка на полный проект:

Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!

Применение библиотеки.

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

Нам надо реализовать задачу – на каждое нажатие кнопки светодиод меняет свое состояние.

Мы собираемся воспользоваться готовой библиотекой Debounce.

Загружаем ее архив.

Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!

В нем 2 файла в папке Debounce.

С помощью STM32CubeMX создаем проект Lesson14_2.

  • Устанавливаем конфигурацию системы тактирования.
  • Вывод PB13 конфигурируем на активный выход.
  • Вывод PB12 (кнопка) не трогаем.

Конвертируем проект в C++.

Создаем папку Libraries и копируем в нее папку Debounce с файлами библиотеки.

Задаем в IDE путь к библиотеке. Правой кнопкой по Libraries, Properties -> C/C++ General -> Paths and Symbols -> Source Location -> Add Folder -> Apply

Подключаем библиотеку Debounce.

#include “../Libraries/Debounce/Debounce.h”

Создаем объект button.

Debounce button(GPIOB, 1 // экземпляр класса Debounce

Лучше запустить компиляцию, убедиться, что ошибок нет.

Теперь мы можем использовать объект button.

/* Infinite loop */
/* USER CODE BEGIN WHILE */

while (1)
<
if(button.readFlagFalling() != 0)
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_13);

Все. Компилируем, загружаем в плату, проверяем.

Вот ссылка на проект:

Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!

Папку Libraries со своим библиотеками удобно копировать в проект целиком, а не выбирать нужные библиотеки. Не подключенные директивой #include файлы компилироваться не будут.

В следующем уроке будем работать с прерываниями по таймеру. Поговорим о параллельных процессах.

Урок 7 – графическая библиотека для дисплея st7783

Библиотека TFT включена в среду разработки Arduino IDE, начиная с версии 1.0.5.

Данная библиотека позволяет Ардуино взаимодейстовать с модулем, содержащим TFT LCD-экран. Функции библиотеки значительно упрощают процесс вывода на экран различных фигур, линий, изображений и текста.

Библиотека Arduino TFT разработана на основе библиотек Adafruit GFX и Adafruit ST7735, и значительно расширяет их возможности. Библиотека GFX в основном содержит процедуры отрисовки графики, в том время, как ST7735 – функции для взаимодействия с TFT-экраном. Все дополнения библиотеки, касающиеся Ардуино, спроектированы таким образом, чтобы обеспечивать API-режим работы с экраном.

Помимо самого экрана, на плате TFT-модуля расположен разъем для подключения SD-карты памяти, взаимодействовать с которым можно посредством библиотеки SD.

Многие методы библиотеки TFT, работающие с экраном и SD-картой памяти, опираются на функции библиотеки SPI. Поэтому, для нормальной работы программ, взаимодействующих с TFT-экраном, треубется объявление модуля SPI.h.

Использование библиотеки

Организовать работу с TFT-экраном можно двумя способами. Первый способ – использовать аппаратную шину SPI Ардуино, второй – вручную объявить расположение необходимых выводов. С точки зрения функциональности экрана, нет никакой разницы между первым и вторым способом. Однако скорость работы аппаратного интерфейса SPI значительно выше.

Если на TFT-модуле планируется использование SD-карты памяти, то взаимодействовать с модулем необходимо только через аппаратный интерфейс SPI. Он используется во всех примерах к данной библиотеке.

На Arduino Uno при использовании аппаратного SPI в программе необходимо объявить номера выводов CS, DC и RESET. Выводы MOSI (11) и SCLK (13) заданы по умолчанию.

Для использования аппаратного SPI на Arduino Leonardo, необходимо объявить эти выводы следующим образом:

Для работы с TFT-экраном через программный интерфейс SPI можно использовать любые не занятые выводы. В этом случае, помимо CD, DC и RESET, в программе необходимо объявить номера выводов MOSI и SCLK:

Использование библиотеки TFT на Arduino Esplora

В Arduino Esplora предусмотрен отдельный разъем для подключения TFT-экрана, поэтому выводы, взаимодействующе с ним, заданы аппаратно и не подлежат изменению. В этом случае для работы с экраном необходимо использовать специальный класс EsploraTFT.

Сходство с языком Processing

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

Примеры

Все примеры работы с TFT-экраном можно условно разбить на две группы: программы для Arduino Esplora и программы для остальных плат, подобных Arduino Uno или Leonardo. Переносить код с одного устройства на другое довольно просто, имея под рукой описание библиотеки и ее функций.

  • Esplora TFT Bitmap Logo: считывание графического файла с карты памяти micro-SD и вывод его содержимого в произвольной области экрана.
  • Esplora TFT Color Picker: использование джойстика и слайдера для изменения цвета TFT-экрана.
  • Esplora TFT Etch a Sketch: реализация классической игры “Etch-a-Sketch” для Esplora.
  • Esplora TFT Graph: вывод показаний датчика света на TFT-экран в виде графика.
  • Esplora TFT Horizon: рисование линии искуственного горизонта по показаниям акселерометра.
  • Esplora TFT Pong: простая версия классической игры.
  • Esplora TFT Temperature: считывание температуры со встроенного датчика и вывод ее на экран.
  • TFT Bitmap Logo: считывание графичекого файла с карты памяти micro-SD и вывод его содержимого в произвольной области экрана.
  • TFT Display Text : считывание показаний датчика и вывод их на экран.
  • TFT Pong: реализация одноименной классической игры для Arduino
  • Etch a Sketch: реализация классической игры “Etch-a-Sketch” для Ардуино.
  • Color Picker: изменение цвета TFT-экрана с помощью трех датчиков.
  • Graph: вывод сопротивления переменного резистора на TFT-экран в виде графика.

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

Когда-то товарищ 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 лежит в папке glcddoc, можно взять здесь или почитать перевод ), наш дисплей — “Panel A”(в доке ошибка, см далее, юзайте эту схему, она правильная)

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

можно поменять расположение линий поправив glcdconfigks0108_Arduino.h. То есть можем расположить эти 13 выводов в произвольном порядке, оставляя свободными именно те пины (… все 7, ни в чём себе не отказывайте, ага=), которые понадобятся нам для подключения всего остального.
Но мы так делать не будем, а просто побыстрей закинем в arduino-xxxhardwarelibraries папку 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 > А всё дело в том, что там лежит скетч для Processig-а, и даже готовый к запуску файлик glcd/bitmaps/utils/java/glcdMakeBitmap.jar
Программа ещё более юзерфрендли и поддерживает втаскивание в своё окно картинок в нескольких форматах.

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

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

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

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

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

Урок 7 – графическая библиотека для дисплея st7783

Купил на AliExpress шилд Arduino с индикатором 2.4″ TFT LCD, и при попытке его запустить столкнулся с проблемами.

· 2.4″ диагональ, LCD TFT, разрешение 240 x 320 точек.
· Подсветка из 4 белых светодиодов, которая может управляться через транзистор от цифрового порта.
· Поддержка 18-битного цвета 262000 оттенков.
· 4-проводный резистивный тачскрин.
· Контроллер предположительно SPFD5408 со встроенным ОЗУ видеобуфера картинки.
· Параллельный 8-битный интерфейс, с 4 линиями управления. Для этого используются цифровые порты 5-13 Arduino и аналоговые 0-3. Это означает, что Вы можете использовать цифровые порты 2, 3 и аналоговые 4 и 5. Порт 12 доступен, если не используется карта micro-SD.
· Интерфейс совместим с уровнями логики 5V и 3.3V.
· Имеется встроенный LDO-регулятор 3.3V 300mA.
· Размер 71 x52 x 7 мм, вес около 31 грамм.

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

[LCD_ID_Reader]

В Интернете нашел замечательный проект [1], который позволяет определить тип контроллера и библиотеку для индикатора. Это скетч Arduino, который не использует сам по себе никакую библиотеку, и поэтому может работать с любым индикатором. Скетч считывает идентификатор контроллера, выводит его в консоль монитора, и дает рекомендацию, где искать библиотеку для индикатора.

Как определить тип индикатора, процесс по шагам (подразумевается, что Arduino IDE уже установлена):

1. Скачайте архив LCD_ID_Reader.zip с сайта [1], распакуйте его в любую папку.

2. В среде Arduino IDE скетч LCD_ID_Reader.ino, скомпилируйте его и запустите на плате Arduino с подключенным индикатором.

Я проверял этот скетч на платах Arduino Uno (ATmega328) и Arduino Mega 2560 (ATmega2560). Если все нормально, то скетч заполнит экран красным цветом, и выведет ID индикатора. У моего индикатора оказался ID 0x9325 (контроллер ILI9325 [7]), скетч вывел в монитор следующие сообщения:

По совету этого сообщения начал искать библиотеку на сайте misc.ws, и нашел библиотеку TFTLCD.zip (см. [2, 3]).

HX8347-A 240×320 >ILI9320 240×320 >ILI9325 240×320 >ILI9327 240×400 >ILI9329 240×320 >ILI9335 240×320 >ILI9341 240×320 >ILI9481 320×480 >ILI9486 320×480 >ILI9488 320×480 >LGDP4535 240×320 >RM68090 240×320 >R61505V 240×320 >R61505W 240×320 >R61509V 240×400 >—– S6D0139 240×320 >S6D0154 240×320 >SPFD5408 240×320 >—– SSD1963 800×480 >SSD1289 240×320 >ST7781 240×320 >ST7789V 240×320 >

[TFTLCD.zip]

Как использовать библиотеку TFTLCD.zip (скачайте эту библиотеку из статьи [2], или см. архив [5]):

1. Добавьте библиотеку через меню Скетч -> Подключить библиотеку -> Добавить .ZIP библиотеку. -> выберите TFTLCD.zip. Библиотека установится в среду Arduino IDE вместе с примерами кода.

2. Для Arduino Mega 2560 загрузите по ссылке из статьи [3] исправленный модуль TFTLCD.cpp, и перепишите его в каталог C:имяпользователяDocumentsArduinolibrariesTFTLCD, заменив старый файл TFTLCD.cpp.

3. Внесите исправление в файле библиотеки glcdfont.c (он находится в каталоге j:имяпользователяuserDocumentsArduinolibrariesTFTLCD), после static нужно добавить const:

4. Загрузите скетч примера через меню Файл -> Примеры -> TFTLCD -> graphicstest.

5. Скомпилируйте скетч и запустите через меню Скетч -> Загрузка (Ctrl+U).

Скетч выведет проверочный текст, после чего начнет выводить тест графики.

Если graphicstest выводит текст с инверсией направления, то нужно раскомментировать соответствующие строки в файле TFTLCD.cpp:

С моим экранчиком пришлось раскомментировать строку #define INVERT_X.

Есть еще одна особенность работы с индикатором: после вызова initDisplay() необходима минимальная задержка перед тем, как начинать заполнять экран, иначе скраю экрана будут оставаться артефакты. Для своего экрана я подобрал эту задержку, получилось 25 мс:

[Проблема tft.println и tft.print]

На этом проблемы не закончились, обнаружился баг – функции println и print (когда они работают в объекте TFTLCD) при работе с индикатором выводят только один символ. Причем функция drawString в тех же условиях работает нормально:

Функции println и print и выводят текст через size_t TFTLCD::write(uint8_t c), причем она работает нормально, этот код выводит буквы “ABC” друг за другом:

Функцию write использует модуль hardwarearduinoavrcoresarduinoPrint.cpp (находится в каталоге установки Arduino):

Тут же в комментарии есть подсказка – надо в классе TFTLCD переопределить функции println и print. К сожалению, я не большой спец в иерархии классов библиотек Arduino, поэтому просто взял готовые реализации функций вывода на печать из модуля Print.cpp, и сделал их аналоги в классе TFTLCD. Возможно, это не самый лучший вариант решения проблемы, потому что чреват дублированием кода при совместном использовании классов Serial и TFTLCD:

Исправленную библиотеку можно скачать по ссылке [5]. Конечно, можно обойти проблему другим способом – функции print и println для индикатора не использовать, для вывода текста пользоваться только функцией drawString.

[Слот карты microSD]

Пробовал скетч MyBitmapExperiment.ino [2] на Arduino Uno (ATmega328) и на Arduino Mega 2560 (ATmega2560). Скетч заработал только на Arduino Uno, проблема с библиотекой SD – на Arduino Mega 2560 карта microSD не инициализировалась. Причина в том, что у Arduino Mega 2560 выводы SPI привязаны к цифровым портам 50..53 вместо 10..13 у Arduino Uno, и эти порты SPI находятся совсем на другом разъеме.

Утилита bmp2lcd2 [4] преобразует 24-битную RGB BMP-картинку в формат 16-бит RGB (R5G6B5), который использует контроллер индикатора, благодаря чему можно ускорить вывод растрового изображения на экран.

В утилите bmp2lcd2 я нашел и исправил некоторые ошибки. Выходной файл там ошибочно открывался как текстовый, по этой причине некоторые картинки, в которых имелись байты 0x0A, сохранялись с ошибками (0x0A это конец строки в стиле Unix, и в текстовом режиме этот байт заменялся на 2 байта 0x0D 0x0A).

SS

СигналШилдArduino UnoArduino Mega 2560Функция
SD_SSport 10

SS (PB2)

port 53

SS (PB0)

Выборка карты, активный 0.
MOSISD_DIport 11 MOSI (PB3)port 51 MOSI (PB2)Данные, выход AVR, вход карты.
MISOSD_DOport 12 MISO (PB4)pin 50 MISO (PB3)Данные, вход AVR, выход карты.
SCKSD_SCKport 13 SCK (PB5)pin 52 SCK (PB1)Такты, выход AVR, вход карты.

Подключение к карте SD через порт SPI на плате Arduino Mega2560:

Не модифицированный 24-битный BMP-файл 320×240 загружается в экран примерно за 2.8 секунды. Оптимизированный файл (обработанный утилитой bmp2lcd2 [4]) загружается около 1.3 секунды.

Исправленный исходный код, скомпилированную утилиту можете скачать в архиве [5].

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

[Тачскрин]

Библиотека такскрина от Adafruit [6] дает нам две координаты X и Y, которые относятся к точке касания на экране, и координату Z, которая показывает прикладываемое давление. Эти координаты совпадают с параметром поворота экрана LCD по умолчанию, когда коннектор USB платы Arduino находится вверху, и при необходиости это Вам нужно будет подстроить самостоятельно.

Возможная область возникновения проблем с тачскрином – тот факт, что тачскрин использует общие выводы с LCD:

ТачскринШилдПорт Arduino Uno
YP (Y+)LCD_WRA1 (аналоговый порт)
XM (X-)LCD_RSA2 (аналоговый порт)
YM (Y-)LCD_D77 (цифровой порт)
XP (X+)LCD_D66 (цифровой порт)

Поэтому если Вы вызовете методы из библиотеки тачскрина, затем сделаете вызовы функций из библиотеки LCD, то можете получить неожиданные результаты, потому что библиотека тачскрина не всегда оставляет в правильном состоянии ножки микроконтроллера, и библиотека LCD не переводит эти ножки в правильное состояние перед тем, как начать свою работу. Более новые библиотеки Adafruit могут учитывать это обстоятельство, автор [2] решил эту проблему самостоятельно.

Еще одна из возможных проблем – дебонсинг нажатий, чтобы избежать дублирования событий нажатия. Один из способов улучшенной обработки нажатий показан в статье [2]. Последняя версия библиотеки тачскрина от Adafruit [6] содержит макроопределение NUMSAMPLES, которое подстраивает способ обработки дебоунсинга.

Для того, чтобы правильно работал скетч tftpaint из примеров библиотеки TFTLCD [2], необходимо вызвать функцию инициализации тачскрина TouchScreen, где в последнем параметре должно быть указано сопротивление между контактами тачскрина X+ и X-. Это сопротивление можно измерить обычным мультиметром. Мой тачскрин имел сопротивление между Y+ и Y- 343 Ома, и между X+ и X- 661 Ом.

Также нужно подобрать значение параметров минимума и максимума координат тачскрина, это следующие макроопределения:

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

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

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

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

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

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

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

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

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

Нужно указать, что следующие символы мы будем писать на белом фоне отключая пиксели (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.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”);
>

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

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 \библиотека для работы с 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

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

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);

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(“%”);

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

Вам понравился наш материал? Поделитесь с друзьями!

RoboHobby

Детали для моделирования роботов

Категории товаров

Поиск товаров

Программирование

Уроки

Оплата и доставка

Урок 5. Вывод информации на OLED дисплей

Это пятый урок из цикла «Знакомство с Arduino». В этом уроке Вы научитесь основам работы с OLED дисплеем.

Для урока Вам понадобится следующие детали:

  • Arduino Nano;
  • беспаечная макетная плата (она же breadboard);
  • провода типа папа-папа;
  • дисплей OLED 0.96».

Также Вам понадобится скачать и установить библиотеки Adafruit_GFX и Adafruit_SSD1306 и среду Arduino IDE. Если не знаете/забыли как это сделать, то вернитесь к уроку по среде Arduino IDE.

После установки необходимых библиотек, для OLED 128 × 64 нужно отредактировать файл Adafruit_SSD1306.h. Найдите строки:

И раскомментируйте строчку #define SSD1306_128_64. Должно получиться так:

Если у нужно пользоваться дисплеем 128 × 32 или 96 × 16 тогда раскомментируйте нужную строку, а остальные закомментируйте.

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

Давайте научимся основам работы с OLED дисплеями. Мы изучим их подключение к Arduino и основные команды для работы с ними. В наших примерах рассмотрим принципы вывода информации на OLED.

OLED дисплеи подключаются к Arduino по стандартному интерфейсу I2C (есть модели, которые подключаются по SPI). Подключите OLED к Arduino, воспользовавшись следующими схемами:

Электрическая принципиальная схема:

Схема подключения на макетной плате:

Так, дисплей мы подключили, а как же на него вывести информацию? Давайте начнём с классического примера из программирования: вывести на экран «Hello, world!».

Итак, схема у нас уже собрана. Подключите модуль Arduino к компьютеру. Далее откройте среду разработки Arduino IDE. Вам нужно только записать в Arduino следующую программу:

Текст программы:

При помощи директивы #include мы подключаем необходимые для работы с OLED библиотеки. Функция setup() запускается однократно при запуске программы. В ней мы инициализируем дисплей, а также выставляем все необходимые настройки (цвет текста (display.setTextColor(WHITE)), его размер (display.setTextSize(1)) и устанавливаем местоположение курсора, откуда мы начнём выводить наше сообщение (команда display.setCursor(0, 0)). После того, как мы настроили OLED, можно выводить на экран наше сообщение. Для этого при помощи команды display.print («Hello, world!») мы записываем наше сообщение в буфер, а затем выводим его непосредственно на экран (команда display.display()). Обратите внимание, весь текстовая информация сначала помещается в буфер, а затем при помощи команды .display() она отображается на экране (т.е. нужные пиксели загораются). Функция loop() вызывается после функции setup(). Функция представляет собой бесконечный цикл, в котором выполняется пользовательская программа. В ней при мы ничего не делаем, т.к. нам просто нужно было вывести сообщение однократно, что мы и сделали в setup().

Когда программа успешно записана в Arduino, на OLED в верхнюю строчку будет выведено наше сообщение «Hello, world!». Мы выполнили поставленную задачу.

Существует большое количество функций, которые позволяют добавить свои краски при выводе информации на OLED. Одной из таких «фишек» является автоматическое прокручивание текста в различные стороны (scrolling).

Давайте попробуем прокручивать наше сообщение поочерёдно слева направо и затем справа налево. Запишите в модуль Arduino Nano следующую программу:

Читайте также:  Зарядное устройство от солнечных батарей
Рейтинг
( Пока оценок нет )
Загрузка ...
Adblock
detector