Купил на 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]), скетч вывел в монитор следующие сообщения:
Initializing LCD...
Reading ID...0x9325
Loading LCD registers...
Filling the screen...
Done filling...
If your screen filled red, you may be able to use the library at http://misc.ws
По совету этого сообщения начал искать библиотеку на сайте misc.ws, и нашел библиотеку TFTLCD.zip (см. [2, 3]).
Как использовать библиотеку TFTLCD.zip (скачайте эту библиотеку из статьи [2], или см. архив [5]):
1. Добавьте библиотеку через меню Скетч -> Подключить библиотеку -> Добавить .ZIP библиотеку... -> выберите TFTLCD.zip. Библиотека установится в среду Arduino IDE вместе с примерами кода.
2. Для Arduino Mega 2560 загрузите по ссылке из статьи [3] исправленный модуль TFTLCD.cpp, и перепишите его в каталог C:\имяпользователя\Documents\Arduino\libraries\TFTLCD\, заменив старый файл TFTLCD.cpp.
3. Внесите исправление в файле библиотеки glcdfont.c (он находится в каталоге j:\имяпользователя\user\Documents\Arduino\libraries\TFTLCD\), после static нужно добавить const:
5. Скомпилируйте скетч и запустите через меню Скетч -> Загрузка (Ctrl+U).
Скетч выведет проверочный текст, после чего начнет выводить тест графики.
Если graphicstest выводит текст с инверсией направления, то нужно раскомментировать соответствующие строки в файле TFTLCD.cpp:
//#define INVERT_X
//#define INVERT_Y
С моим экранчиком пришлось раскомментировать строку #define INVERT_X.
Есть еще одна особенность работы с индикатором: после вызова initDisplay() необходима минимальная задержка перед тем, как начинать заполнять экран, иначе скраю экрана будут оставаться артефакты. Для своего экрана я подобрал эту задержку, получилось 25 мс:
tft.initDisplay();
delay(25);
[Проблема tft.println и tft.print]
На этом проблемы не закончились, обнаружился баг - функции println и print (когда они работают в объекте TFTLCD) при работе с индикатором выводят только один символ. Причем функция drawString в тех же условиях работает нормально:
// Выводится только один красный символ H:
tft.print("Hello World!");
// Нормально выводится весь текст "Hello World!":
tft.drawString(0, 40, "Hello World!", GREEN, 1);
Функции println и print и выводят текст через size_t TFTLCD::write(uint8_t c), причем она работает нормально, этот код выводит буквы "ABC" друг за другом:
//Выведется текст "ABC":
tft.write('A');
tft.write('B');
tft.write('C');
Функцию write использует модуль hardware\arduino\avr\cores\arduino\Print.cpp (находится в каталоге установки Arduino):
/* Реализация по умолчанию: может быть переопределена */
size_t Print::write(constuint8_t*buffer, size_t size)
{
size_t n =0;
while (size--) {
if (write(*buffer++)) n++;
elsebreak;
}
return n;
}
Тут же в комментарии есть подсказка - надо в классе 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).
Подключение к карте SD через порт SPI на плате Arduino Mega2560:
Не модифицированный 24-битный BMP-файл 320x240 загружается в экран примерно за 2.8 секунды. Оптимизированный файл (обработанный утилитой bmp2lcd2 [4]) загружается около 1.3 секунды.
Исправленный исходный код, скомпилированную утилиту можете скачать в архиве [5].
Общее впечатление от индикатора - свою цену он оправдывает, однако мало подходит для высокопроизводительных приложений на платформе AVR / Arduino. Вывод на индикатор медленный (по крайней мере с этой библиотекой), занимает много процессорного времени, и задействовано слишком много выводов портов.
[Тачскрин]
Библиотека такскрина от Adafruit [6] дает нам две координаты X и Y, которые относятся к точке касания на экране, и координату Z, которая показывает прикладываемое давление. Эти координаты совпадают с параметром поворота экрана LCD по умолчанию, когда коннектор USB платы Arduino находится вверху, и при необходиости это Вам нужно будет подстроить самостоятельно.
Возможная область возникновения проблем с тачскрином - тот факт, что тачскрин использует общие выводы с LCD:
Тачскрин
Шилд
Порт Arduino Uno
YP (Y+)
LCD_WR
A1 (аналоговый порт)
XM (X-)
LCD_RS
A2 (аналоговый порт)
YM (Y-)
LCD_D7
7 (цифровой порт)
XP (X+)
LCD_D6
6 (цифровой порт)
Поэтому если Вы вызовете методы из библиотеки тачскрина, затем сделаете вызовы функций из библиотеки LCD, то можете получить неожиданные результаты, потому что библиотека тачскрина не всегда оставляет в правильном состоянии ножки микроконтроллера, и библиотека LCD не переводит эти ножки в правильное состояние перед тем, как начать свою работу. Более новые библиотеки Adafruit могут учитывать это обстоятельство, автор [2] решил эту проблему самостоятельно.
Еще одна из возможных проблем - дебонсинг нажатий, чтобы избежать дублирования событий нажатия. Один из способов улучшенной обработки нажатий показан в статье [2]. Последняя версия библиотеки тачскрина от Adafruit [6] содержит макроопределение NUMSAMPLES, которое подстраивает способ обработки дебоунсинга.
Для того, чтобы правильно работал скетч tftpaint из примеров библиотеки TFTLCD [2], необходимо вызвать функцию инициализации тачскрина TouchScreen, где в последнем параметре должно быть указано сопротивление между контактами тачскрина X+ и X-. Это сопротивление можно измерить обычным мультиметром. Мой тачскрин имел сопротивление между Y+ и Y- 343 Ома, и между X+ и X- 661 Ом.
Мне удалось победить этот шилд, установив библиотеку LGDP4535.h. Загружаем любой пример и все работает, кроме калькулятора. Для того, чтобы он нормально заработал, нужна калибровка. Загружаем из библиотеки пример калибровки и калибруем, по окончании видим на дисплее значения, и подставляем их в скетч калькулятора (или еще куда кому нужно).
Библиотека SPFD5408-master. Reader определил ID-0X0000. В папке с файлом "срр" строк с //#define INVERT_X //#define INVERT_Y не нашел. С TFTLCD.zip не работает. Как в библиотеке SPFD5408-master сделать зеркалирование картинки?
microsin: в функциях рисования примитивов (точка, линия и т. п.) можно выполнить следующие простые преобразования. Для зеркалирования по оси X: x = SCREEN_WIDTH - x. Для зеркалирования по оси Y: y = SCREEN_HEIGHT - y.
Комментарии
microsin: с помощью ключа на транзисторе, управляемого ножкой порта GPIO микроконтроллер а.
microsin: в функциях рисования примитивов (точка, линия и т. п.) можно выполнить следующие простые преобразования. Для зеркалирования по оси X: x = SCREEN_WIDTH - x. Для зеркалирования по оси Y: y = SCREEN_HEIGHT - y.
microsin: смотрите макросы INVERT_X и INVERT_Y.
RSS лента комментариев этой записи