Библиотека LCDBitmap для Arduino
Содержание
Введение
Данная библиотека позволяет вам создавать маленькие растровые изображения размером 20x16 пикселей и отображать их на обычном символьном дисплее на базе Hitachi HD44780. Библиотека предоставляет типовые функции рисования, такие как линия, прямоугольник, инвертирование и т.д. Управление происходит на уровне пикселей.
Данная библиотека работает как со стандартной библиотекой Liquid Crystal, так и с библиотекой New Liquid Crystal от Francisco. Она работает с разными методами подключения LCD дисплея, в том числе и с 4-битным, со сдвиговым регистром (2 или 3 провода), с I2C. Подробные примеры скетчей включены в архив с библиотекой
Библиотека работает, создавая массив памяти для растрового изображения размером 20x16 пикселей, с которым и работают функции библиотеки. Затем она преобразует это изображение в 8 пользовательских символов, доступных для HD44780, и отображает их в указанном месте как 2 строки по 4 символа. Поскольку каждый символ имеет размер 5x8 пикселей и расположен в массиве символов 4x2, общее доступное разрешение составляет 20x16. Поскольку HD44780 имеет ограничение в 8 пользовательских символов, 20x16 – это максимальное разрешение, которое может быть достигнуто (5*4=20 x 8*2=16).
Загрузка и установка
Сохраните .zip файл на свой компьютер и импортируйте библиотеку в Arduino IDE.
Примеры подключений
Синтаксис
LCDBitmap bitmap( &lcd, x, y )
&lcd
– это экземплярLiquidCrystal
,(x, y)
– положение символа изображения, 0,0 = верхний/левый угол, 12,0 = верхний/правый угол у LCD размером 16x2. Дисплей 20x16 пикселей, который создает LCDBitmap, – это участок размером 4 символа в ширину и 2 символа в высоту.bitmap.begin()
- Инициализировать изображение LCD.
bitmap.clear()
- Очистить дисплей изображения (автоматически обновляет дисплей изображения), но не очищает текст.
bitmap.inverse()
- Инвертировать изображение, автоматически обновляет дисплей изображения.
bitmap.update()
- Обновить дисплей изображения.
bitmap.clear_text()
- Очистить только текст на дисплее (изображение остается).
bitmap.home()
- Переместить курсор на домашнюю позицию
(0, 0)
. Выполняетlcd.setCursor(0, 0)
, добавлен только для удобства. bitmap.move( x, y )
- Переместить позицию LCD изображения на указанную позицию символа.
bitmap.pixel( x, y, color, update )
- Добавить пиксель в
(x, y)
,color
–ON
(включен) илиOFF
(выключен),update
–UPDATE
(обновить) илиNO_UPDATE
(не обновлять). bitmap.line( x1, y1, x2, y2, color, update )
- Нарисовать линию от
(x1, y1)
до(x2, y2)
, color и update – то же самое, что и вbitmap.pixel()
. bitmap.rect( x1, y1, x2, y2, color, update )
- Нарисовать прямоугольник от
(x1, y1)
до(x2, y2)
,color
иupdate
– то же самое, что и вbitmap.pixel()
. bitmap.rectFill( x1, y1, x2, y2, color, update )
- Нарисовать заполненный прямоугольник от
(x1, y1)
до(x2, y2)
,color
иupdate
– то же самое, что и вbitmap.pixel()
. bitmap.barGraph( bars, *graph, color, update )
- Нарисовать полосковый индикатор (гистограмму),
bars
– количество полос(1, 2, 4, 5, 10, 20)
,graph
– массив, который содержит значения высот,color
иupdate
– то же самое, что и вbitmap.pixel()
.
Примеры
Простой скетч, использующий I2C LCD интерфейс
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LCDBitmap.h>
LiquidCrystal_I2C lcd(0x38);
// Установить LCD изображение на "&lcd", установить положение LCD изображения на позицию символа (0,0).
LCDBitmap bitmap(&lcd, 0, 0);
void setup()
{
lcd.begin(16,2); // Сначала необходимо сделать это.
bitmap.begin(); // Затем инициализируем LCD изображение.
lcd.setCursor(5, 0);
lcd.print("LCDBitmap");
}
void loop()
{
// Рисуем на изображении несколько вложенных прямоугольников,
// не обновляем дисплей изображения до последней команды.
bitmap.rectFill(0, 0, 19, 15, ON, NO_UPDATE);
bitmap.rectFill(2, 2, 17, 13, OFF, NO_UPDATE);
bitmap.rectFill(4, 4, 15, 11, ON, NO_UPDATE);
bitmap.rect(6, 6, 13, 9, OFF, UPDATE);
while(1){}
}
Скетч гистограммы (полоскового индикатора), использующий стандартный 4-битный LCD интерфейс
#include <LiquidCrystal.h>
#include <LCDBitmap.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Установить LCD изображение на &lcd, установить положение LCD изображения на позицию символа (0,0).
LCDBitmap bitmap(&lcd, 0, 0);
byte graph[20];
byte bars[] = { 1, 2, 4, 5, 10, 20 };
void setup()
{
lcd.begin(16,2); // Инициализируем LCD дисплей, это необходимо сделать перед инициализацией LCDBitmap.
bitmap.begin(); // Затем инициализируем LCD изображение.
lcd.setCursor(5, 0);
lcd.print("LCDBitmap");
}
void loop()
{
byte curr_bars = bars[(millis()/3000)%6];
for (byte x=0; x<curr_bars; x++)
{
graph[x] = random(0, BITMAP_H+1);
}
bitmap.barGraph(curr_bars, graph, ON, UPDATE); // Отобразить гистограмму.
delay(50);
}
Сложный скетч, использующий 4-битный LCD интерфейс
#include <LiquidCrystal.h>
#include <LCDBitmap.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Установить LCD изображение на &lcd, установить положение LCD изображения на позицию символа (12,0).
LCDBitmap bitmap(&lcd, 12, 0);
unsigned long currentMillis; // Переманная таймера
#define sample 4000 // Устанавливает, как долго будет показываться каждый пример
void setup()
{
lcd.begin(16,2); // Инициализируем LCD дисплей.
bitmap.begin(); // Инициализируем LCD изображение.
bitmap.home(); // Перемещаем курсор на домашнюю позицию (0,0)
lcd.print("LCDBitmap");
randomSeed(analogRead(A0));
}
void loop()
{
// bitmap.pixel
lcd.setCursor(0, 1);
lcd.print(".pixel ");
currentMillis = millis();
while(millis()-currentMillis < sample)
{
for (byte i=0; i<8; i++)
{
// Добавить один случайный пиксель, но не обновлять дисплей изображения
bitmap.pixel(random(0, BITMAP_W), random(0, BITMAP_H), random(0, 2), NO_UPDATE);
}
bitmap.update(); // 8 пикселей выставлены, теперь обновим дисплей изображения
}
// bitmap.line пример #1
lcd.setCursor(0, 1);
lcd.print(".line #1 ");
bitmap.clear(); // Очистить дисплей изображения (автоматически обновляет дисплей изображения), но не очищает текст.
currentMillis = millis();
int startdelay = 120;
while(millis()-currentMillis < sample*2)
{
for (byte x=0; x<BITMAP_W; x=x+2)
{
// Нарисовать линию от (x, 0) до (BITMAP_W-x-1, BITMAP_H-1) и обновить дисплей изображения
bitmap.line(x, 0, BITMAP_W-x-1, BITMAP_H-1, ON, UPDATE);
delay(startdelay);
bitmap.clear(); // Clear the display
}
for (byte y=0; y<BITMAP_H; y=y+2)
{
bitmap.line(0, BITMAP_H-y-1, BITMAP_W-1, y, ON, UPDATE);
delay(startdelay);
bitmap.clear(); // Очистить дисплей
}
startdelay=startdelay*2/3;
}
// bitmap.line пример #2
lcd.setCursor(0, 1);
lcd.print(".line #2 ");
currentMillis = millis();
while(millis()-currentMillis < sample)
{
for (byte x=0; x<BITMAP_W; x++)
{
// Нарисовать линию от (x, 0) до (x, BITMAP_H-1) и обновить дисплей изображения
bitmap.line(x, 0, x, BITMAP_H-1, ON, UPDATE);
}
for (byte y=0; y<BITMAP_H; y++)
{
bitmap.line(0, y, BITMAP_W-1, y, OFF, UPDATE);
}
}
bitmap.clear(); // Очистить дисплей
// bitmap.rect
lcd.setCursor(0, 1);
lcd.print(".rect ");
currentMillis = millis();
while(millis()-currentMillis < sample)
{
// Нарисовать прямоугольник от (x1,y1) до (x2,y2) и обновить дисплей изображения
bitmap.rect(random(0, BITMAP_W), random(0, BITMAP_H), random(0, BITMAP_W), random(0, BITMAP_H), ON, UPDATE);
delay(150);
bitmap.clear(); // Очистить дисплей
}
// bitmap.rectFill
lcd.setCursor(0, 1);
lcd.print(".rectFill");
currentMillis = millis();
while(millis()-currentMillis<sample*1.5)
{
// Нарисовать заполненный прямоугольник от (x1,y1) до (x2,y2), дисплей изображения не обновлять
bitmap.rectFill(random(0, BITMAP_W), random(0, BITMAP_H), random(0, BITMAP_W), random(0, BITMAP_H), ON, NO_UPDATE);
// Нарисовать заполненный прямоугольник от (x1,y1) до (x2,y2) дисплей изображения не обновлять
bitmap.rectFill(random(0, BITMAP_W), random(0, BITMAP_H), random(0, BITMAP_W), random(0, BITMAP_H), OFF, NO_UPDATE);
// Заполненные прямоугольники нарисованы, теперь обновим дисплей изображения
bitmap.update();
delay(10);
}
bitmap.clear(); // Очистить дисплей
// bitmap.barGraph
lcd.setCursor(0, 1);
lcd.print(".barGraph ");
byte bars=10;
byte graph[bars]; // 10 значений полос
currentMillis = millis();
while(millis()-currentMillis < sample*2)
{
for (byte x=0; x<bars; x++)
{
graph[x] = random(0, BITMAP_H); // Заполнить массив случайными значениями высот
}
bitmap.barGraph(bars, graph, ON, UPDATE); // Отобразить гистограмму
delay(10);
if (bars == 10 && millis()-currentMillis >= sample)
bars=4;
}
bitmap.clear(); // Очистить дисплей
// Этот код создает большой "X" с помощью LCDBitmap, чтобы показать функции инвертирования и перемещения
for (byte x=0; x<=4; x++)
{
bitmap.line(x, BITMAP_H-1, x+BITMAP_H-1, 0, ON, NO_UPDATE); // Нарисовать линию, но не обновлять дисплей изображения
bitmap.line(x, 0, x+BITMAP_H-1, BITMAP_H-1, ON, NO_UPDATE); // Нарисовать линию, но не обновлять дисплей изображения
}
bitmap.update(); // Теперь, когда на изображении всё нарисовано, показать эти изменения
// bitmap.inverse
lcd.setCursor(0, 1);
lcd.print(".inverse ");
delay(1000);
int x_status = 1;
currentMillis = millis();
while(millis()-currentMillis < sample/2)
{
for (byte a=0; a<6; a++)
{
bitmap.inverse(); // Инвертировать изображение, автоматически обновляет дисплей изображения.
x_status *= -1;
delay(75);
}
}
if (x_status==-1) bitmap.inverse();
// bitmap.move
bitmap.clear_text(); // Очистить только текст на дисплее (изображение остается).
lcd.setCursor(0, 1);
lcd.print(".move");
for (byte x=11; x>4; x--)
{
bitmap.move(x,0); // Переместить позицию LCD изображения на одну позицию влево
delay(150);
}
for (byte x=6; x<13; x++)
{
bitmap.move(x,0); // Переместить позицию LCD изображения на одну позицию вправо
delay(150);
}
bitmap.home(); // Переместить курсор на домашнюю позицию (0,0)
lcd.print("LCDBitmap");
delay(500);
// bitmap.clear
lcd.setCursor(0, 1);
lcd.print(".clear ");
delay(1000);
bitmap.clear(); // Очистить дисплей изображения (автоматически обновляет дисплей изображения), но не очищает текст.
delay(2000);
}