Возможно, вы задумывались, как при помощи Arduino и TFT дисплея можно красиво и удобно вывести большой объём текстовой и графической информации? В данном уроке мы постараемся ответить на этот вопрос и даже написать программу для небольшого интерфейса. Использовать для этого мы будем TFT дисплей напрямую подключаемый к Arduino.
Цель урока: Подключение TFT дисплея.
Познакомится с TFT дисплеями. Научится работать с библиотекой UTFT.
Что из себя представляет TFT дисплей?
TFT расшифровывается, как Thin-film-transistor (тонкоплёночный транзистор), своё название он получил за то, что каждый пиксель на дисплее представляет из себя небольшой полевой транзистор, который выглядит, как тонкая плёнка покрывающая дисплей.
Управление происходит путём взаимодействия с пикселями, которым мы можем задать нужный цвет. В данном уроке будет использоваться уже готовая библиотека, для упрощения задачи и понимания.
Как подключить дисплей к Arduino MEGA?
Используемый дисплей представляет собой плату, которая просто надевается сверху на Arduino MEGA, что сильно упрощает работу с ней. Стоит убедиться, что все порты хорошо соединены с Arduino, иначе вы можете столкнуться со статичным белым экраном. На картинке ниже вы можете наглядно увидеть, как выглядит подключение дисплея.
Также подключим две кнопки к пинам 7 и 8, как показано на схеме ниже.
Важно, что обычные провода, используемые для макетных плат слишком высокие, поэтому стоит использовать самодельные провода, которые можно изготовить с помощью обычного макетного провода и ножниц. На картинке ниже вы можете наглядно увидеть разницу в высоте между проводами. Как вариант, можно при наличии навыков и паяльника можно припаять провода снизу Arduino.
Первый скетч для дисплея.
Для работы с дисплеем будет использоваться готовая библиотека. В файлах библиотеки вы также можете найти документацию с подробным описанием всех функций.
Начнём с самой главной функции, без которой не будут работать все остальные. InitLCD(), эта функция инициализирует дисплей, для начала работы с ним, её необходимо прописать в setup(). В данной функции, так же можно указать ориентацию экрана, указав, как аргумент одну из констант PORTRAIT (вертикальная ориентация) или LANDSCAPE (горизонтальная).
Далее идёт функция fillSrc(Color), эта функция заливает весь дисплей одним цветом.
Функция setColor(Color) можно выбрать цвет, которым будут выводится текст, фигуры и т.д. В библиотеке предустановлено несколько констант, отвечающих за цвет, но вы можете так же использовать любой цвет в RGB. Например, setColor(255,255,255).
Функция setFont(Font), используется для выбора шрифта, которым будет выводиться текст. Изначально в библиотеке предустановлено 3 шрифта, это:
- SmallFont
- BigFont
- SevenSegNumFont
Дополнительные шрифты, а также информацию об их размере и какие символы в них входят, вы можете найти здесь.
Для установки шрифта сначала нужно перейти на сайт, и скачать любой выбранный шрифт.
После этого, необходимо скачанный файл со шрифтом перекинуть в папку со скетчем.
И в конце нужно просто подключить шрифт прописав перед setup(), следующую команду extern uint8_t Название шрфита[ ];
Важно заметить, что для подключения любого из трёх стандартных шрифтов, скачивать и перекидывать их в папку со скетчем не нужно. Требуется только в начале скетча их подключить через команду extern.
Стоит так же учитывать, что каждый подключённый шрифт занимает довольно много памяти, так что не рекомендую подключать слишком много шрифтов.
#include <UTFT.h>
UTFT LCD(TFT32MEGA_2, 38, 39, 40, 41);
extern uint8_t DotMatrix_M[];
void setup()
{
LCD.InitLCD();
LCD.setFont(DotMatrix_M);
}
void loop() {
// put your main code here, to run repeatedly:
}
Для того, чтобы вывести на экран какую-либо информацию, необходимо использовать одну из трёх функций, print(char[ ], x, y, [ r ]), printNumI(int, x, y, [len], [sym]), printNumF(float , dec, x , y, [sym1], [len], [sym2]).
Разница между ними в типе выводимых данных, одна функция выводит только строки, типа char[ ], другая только целочисленные переменные, а последняя только переменные с плавающей точкой.
print(char[ ], x, y[r ]);
char[ ] – строковая переменная;
x, y – координаты начала строки;
r – угол поворота строки относительно координат x,y. (необязательный параметр)
printNumI(int, x, y, [len], [sym]);
int – целочисленная переменная;
x, y – координаты начала строки;
len – количество выводимых разрядов числа (необязательный параметр);
sym – Символы заменяющий недостающие разряды, если len больше, чем количество разрядов в числе (необязательный параметр).
printNumF(float , dec, x , y, [sym1], [len], [sym2]);
float – переменная с плавающей точкой;
dec – Количество выводимых разрядов, после запятой;
x, y – Координаты;
sym1 – Символ вместо запятой, разделитель (необязательный параметр);
len – Количество выводимых разрядов. Учитываются разряды, как перед запятой, так и после (необязательный параметр);
sym2 – Символы заменяющий недостающие разряды, если len больше, чем количество разрядов в числе (необязательный параметр).
Как итог, мы вывели 4 строки разными шрифтами, вручную настроенным цветом и с разным типом данных:
- Для вывода значка батареи мы использовали шрифт «battery_24x48», а также указали, что строку необходимо повернуть на 90 градусов. Для вывода этого значка мы использовали стандартную функцию print().
- Обычную строку типа char[ ], «Hello World!», мы вывели стандартным шрифтов «BigFont» при помощи функции print().
- Целочисленную переменную мы вывели шрифтом «DotMatrix_M», и указали в функции, что количество разрядов равно 5, а пустые разряды необходимо заменить на 0. Для вывода этого числа использовалась функция printNumI().
- Переменную с плавающей точкой мы вывели функцией, printNumF(), используя шрифт «Inconsola». В этой функции мы указали, что после разделителя должно быть два разряда, а всё число содержит 6 разрядов. Так же мы заменили стандартный разделить на тире.
#include <UTFT.h>
UTFT LCD(TFT32MEGA_2, 38, 39, 40, 41);
extern uint8_t battery_24x48[];
extern uint8_t BigFont[];
extern uint8_t DotMatrix_M[];
extern uint8_t Inconsola[];
int integer = 256;
float floating = 2.56789;
void setup()
{
LCD.InitLCD();
LCD.fillScr(VGA_BLACK);
LCD.setColor(0, 255, 0); //Вывод "уровня заряда"
LCD.setFont(battery_24x48);
LCD.print("8",32, 32,90);
LCD.setColor(162, 0, 254); //Вывод надписи "Hello Wrold!"
LCD.setFont(BigFont);
LCD.print("Hello World!", 240, 160);
LCD.setColor(255, 169, 2); //Вывод целочисленной переменной
LCD.setFont(DotMatrix_M);
LCD.printNumI(integer, 240, 192, 5, '0');
LCD.setColor(255, 255, 255); //Вывод переменной с плавающей запятой
LCD.setFont(Inconsola);
LCD.printNumF(floating, 2, 240, 224, '-', 6, '0');
}
void loop()
{
}
Немного усложним задачу.
Теперь попробуем вывести прямоугольник, а также цифры, переключаемые кнопками.
В предыдущем примере информация выводилась один раз в функции setup(), теперь попробуем обновлять выводимые данные в процессе работы программы. Если просто выводить данные, то при каждом обновлении дисплей будет мерцать, чтоб решить данную проблему, есть два способа.
Первый — это обновлять экран только по необходимости, для этого используются две булевые переменные, start и upd. Первая используется для вывода рамки по краям экрана, вторая для переключения счётчика. Устанавливаем значение переменной в true, когда требуется обновить экран и после обновления сбрасываем в false.
Второй способ, это обновление экрана частями, как вы можете увидеть в условии if(upd), мы сначала рисуем черный прямоугольник и только потом уже выводим текст, это также помогает избавится от проблемы, когда куски более длинного числа остаются на экране, если вывести поверх более короткое число.
Ниже представлен пример, где сначала выводится число 123 зелёного цвета, а потом на тех же координатах число 45 красного цвета. Как вы можете увидеть, получилось число 453, где отлично видно, что 3 осталась от предыдущего числа.
#include <UTFT.h>
UTFT LCD(TFT32MEGA_2, 38, 39, 40, 41);
extern uint8_t SevenSegNumFont[];
void setup()
{
LCD.InitLCD();
LCD.fillScr(VGA_BLACK);
LCD.setFont(SevenSegNumFont);
LCD.setColor(VGA_GREEN);
LCD.printNumI(123,240,160);
delay(30000);
LCD.setColor(VGA_RED);
LCD.printNumI(45,240,160);
}
void loop()
{
}
Эту проблему можно решить и немного другим способом, если вы выводите какое-либо числа и знайте, максимум разрядов, которое оно может содержать, можно использовать функции printNumI и printNumF. В этих функциях можно указать количество разрядов и символ, которым будут заменяться недостающие разряды.
Устранение дребезга.
Для устранения дребезга используется библиотека Bounce2, её вы можете найти в менеджере библиотек ArduinoIDE или скачать по ссылке.
Сейчас я кратко расскажу, как с ней работать. В самом начале мы объявляем массив классов, там мы указываем количество кнопок, в данном примере две.
После чего уже в функции setup(), мы конфигурируем кнопки, указываем, что мы используем пины 7 и 8 в режиме входа с подтягивающим резистором, а также интервал 25 мс, это время необходимое для считывания состояния кнопки.
Далее в функции loop(), мы каждый цикл обновляем состояние кнопки при помощи функции update(). Считываем же состояние при помощи функции fell(), она проверяет уровень логического сигнала, и если на кнопке уровень логического нуля, то возвращает ИСТИНА.
Давайте пройдёмся по алгоритму работу программы.
В начале мы инициализируем дисплей. Затем идёт конфигурация пинов 7 и 8 при помощи библиотеки Bounce2. После чего идёт вывод рамки и строки «Counter:» и настройка цвета и шрифта последующего текста.
Далее мы проверяем нажаты ли кнопки и в зависимости от того, какая кнопка нажата мы увеличиваем или уменьшаем переменную-счётчик. А также выставляем флаг обновления дисплея, upd в значение true.
В конце программы, мы проверяем значение переменной upd, если true, то мы выводим новое значение поверх старого, но так как переменная counter имеет тип uint8_t она может принимать значения от 0 до 255, включительно. Зная это, мы в функции printNumI указываем, что всегда выводим трёхзначное число с нулём вместо пустых разрядов.
#include <UTFT.h>
#include <Bounce2.h>
UTFT LCD(TFT32MEGA_2, 38, 39, 40, 41);
//Объявление дисплея, для работы с библиотекой.
//В функции указывается к каким пинам Ардуино подключены пины дисплея
//TFT32MEGA_2 - тип дисплея
//38 - RS - Register Select
//39 - WR - Write/Read
//40 - CS - Chip Select
//41 - RST - Reset
// - ALE - ОПЦИОНАЛЬНО! Используется для переключаемых 16-и битных плат
//Подключение шрифта
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];
Bounce * buttons = new Bounce[2]; //Создаём массив типа "Bounce" для работы с кнопками
bool upd = true;
uint8_t counter = 0;
void setup()
{
LCD.InitLCD();
buttons[0].attach( 7 , INPUT_PULLUP ); //Настраиваем пин 7
buttons[0].interval(25);
buttons[1].attach( 8 , INPUT_PULLUP ); //Настраиваем пин 8
buttons[1].interval(25);
LCD.fillScr(VGA_BLACK); //Заливаем фон чёрным цветом
LCD.setColor(VGA_WHITE); //выводим красивую рамку по краям
LCD.drawRoundRect(10, 10, 470, 310);
LCD.setFont(BigFont); //Выводим надпись "Counter:"
LCD.print("Counter:", 128, 0);
LCD.setFont(SevenSegNumFont); //Вывод счётчика
LCD.setColor(VGA_WHITE);
}
void loop()
{
buttons[0].update(); //Обновляем кнопку (Необходимо производить каждый цикл)
buttons[1].update();
if (buttons[0].fell()) //увеличиваем счётчик, если кнопка нажата
{
counter++;
upd = true; //Устанавливаем флаг
}
if (buttons[1].fell()) //Уменьшаем счётчик, если кнопка нажата
{
counter--;
upd = true; //Устанавливаем флаг
}
if (upd)
{
LCD.printNumI(counter, 178, 110, 3, '0');
upd = false; //Сбрасываем флаг
}
}
Мы рады объявить о нашем присутствии на Boosty! Arduino-Tex приглашает всех наших друзей и последователей поддержать нас на этой замечательной платформе. Здесь вы найдете эксклюзивный контент, уникальные проекты и возможность стать частью нашей творческой команды. Присоединяйтесь к нам на Boosty и вместе мы сделаем мир Arduino еще удивительнее!
Фотографии к статье
Файлы для скачивания
|
Исходные материалы урока.zip | 13 Kb | 804 |
Скачать
Вы можете скачать файл.
|
Комментарии