Библиотека LCDBitmap для Arduino

Добавлено 11 февраля 2018 в 13:39

Содержание

Введение

Данная библиотека позволяет вам создавать маленькие растровые изображения размером 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.

Примеры подключений

Подключение через стандартные 4 бита
Подключение через стандартные 4 бита
Подключение через сдвиговый регистр
Подключение через сдвиговый регистр
Подключение к Teensy 2.0
Подключение к Teensy 2.0

Синтаксис

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), colorON (включен) или OFF (выключен), updateUPDATE (обновить) или 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 интерфейс

Простой скетч, использующий I2C LCD интерфейс
Простой скетч, использующий 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 интерфейс

Скетч гистограммы (полоскового индикатора), использующий стандартный 4-битный LCD интерфейс
Скетч гистограммы (полоскового индикатора), использующий стандартный 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);
}

Теги

ArduinoLCD дисплейГрафикаПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.