Редактор изображений для Arduino
Предыстория
Однажды мне захотелось создать очередную метеостанцию на Arduino. Да, вы правы, порой кажется, что ардуинщики только и делают, что создают метеостанции и мигают светодиодами.
Но моя новая метеостанция должна была быть написана на чистом Си без использования сторонних библиотек. Мне было интересно посмотреть, насколько это сложно сделать и как сократится размер прошивки для ATmega328P. Это означало, что мне пришлось погрузиться в спецификации подключаемых по I2C модулей и написать для них драйверы.
Одним из таких модулей, для которого я писал драйвер, был OLED-дисплей SSD1306. Про этот дисплей подробно писали на Хабре, поэтому не буду повторяться. Это достаточно популярный дисплей для вывода текстовой и графической информации.
Изображения в дисплей загружаются в формате X BitMap. Подготовить изображение можно в любом графическом редакторе, а потом специальной утилитой или веб-сайтом сконвертировать его в формат X BitMap.
Этот процесс показался мне не очень удобным и сложным для новичков. Мне хотелось подготавливать картинки в одном месте, хранить коллекцию своих монохромных изображений для OLED-дисплея и иметь возможность пересылать их друзьям. Не найдя подходящего редактора, я решил написать свое PWA-приложение.
В этой статье мы рассмотрим возможности редактора X BitMap-изображений под названием Bitmap Editor, загрузку изображения в Arduino-устройство и немного поговорим о шрифтах.
Проект создан в любительских целях, рассчитан на новичков и любителей Arduino. Возможно, он будет вам полезен. Также приглашаю вас поучаствовать в развитии проекта: поделиться своими идеями в issue или добавить новый функционал в редактор.
Создание нового изображения, панель рисования
Если вы пиксель-арт-художник, то, возможно, вам это понравится. Что может быть лучше пиксельной графики на монохромном дисплее?
Перейдите в Bitmap Editor.
Нажмите кнопку «Создать».
На странице заполните форму и нажмите кнопку «Сохранить».
Обратите внимание, что ширина изображения должна быть кратна 8 для корректного отображения на SSD1306 (а возможно, и на других моделях). Это обусловлено схемой кодирования, в которой каждый сегмент страницы хранит 8 ячеек памяти.
После создания изображения вы попадёте на страницу его редактирования.
Вы можете рисовать, используя правую кнопку мыши, инвертировать цвет, отменять свои действия, настраивать сетку.
Обратите внимание, что ваши правки сохраняются автоматически в локальном хранилище браузера.
Чтобы вернуться к списку ваших изображений, нажмите на логотип приложения.
После загрузки изображения в Arduino вы увидите на экране:
Создание изображения из картинки
Возможно, у вас уже есть картинка, которую вы хотели бы отобразить на OLED-дисплее?
Тогда вам нужно зайти в Bitmap Editor и нажать на кнопку «Импортировать» — «Из изображения».
В форме выберите файл вашего изображения.
Если ваша картинка выглядит не очень хорошо в монохромном виде, то вам необходимо настроить её с помощью ползунка «Чувствительность».
Изменить размер картинки можно с помощью значений в полях «Ширина» и «Высота».
Если вы хотите сделать размер изображения по контуру заполненных пикселей, то выберите «Обрезать».
Заполните форму и нажмите кнопку «Сохранить».
После загрузки изображения на Arduino вы увидите на экране:
Создание изображения из коллекции иконок
Подбирать картинки для интерфейса Arduino-приложения — задача не из лёгких и порой утомительная. Поэтому в редакторе есть большой набор готовых иконок, которые вы можете использовать в своём интерфейсе.
Перейдите в Bitmap Editor и нажмите кнопку «Импортировать» → «Из коллекции».
Выберите понравившуюся иконку, настройте и сохраните её.
Импорт/экспорт изображений
Как я уже писал выше, все ваши изображения хранятся в локальном хранилище вашего браузера.
А что если вы захотите поделиться с другом своими любимыми bitmap-картинками?
Для этого зайдите в Bitmap Editor и нажмите на иконку с дискетой у нужного элемента списка.
В появившемся диалоговом окне выберите изображения для экспорта. Они будут сохранены в JSON-файл, который вы сможете передать друзьям.
Чтобы импортировать bitmap-картинки из JSON-файла, на главной странице приложения нажмите «Импортировать» — «Из JSON».
Обратите внимание: если вы пытаетесь импортировать изображение, которое уже есть в вашем списке, то импорт этого изображения будет проигнорирован. Каждое изображение получает уникальный идентификатор при создании.
Загрузка изображения в Arduino
Итак, пришло время отобразить наши изображения на OLED-дисплее Arduino.
Схема подключения SSD1306 к Arduino UNO:
- GND (SSD1306) к GND (Arduino)
- VCC (SSD1306) к 5V (Arduino)
- SCL (SSD1306) к A5 (Arduino)
- SDA (SSD1306) к A4 (Arduino)
Заходим в Bitmap Editor, нажимаем на нужный элемент списка.
На странице редактирования изображения нажимаем кнопку «Экспорт в C».
В диалоговом окне настраиваем параметры экспорта.
Самое важное здесь — правильно указать «Порядок битов» в зависимости от используемой библиотеки OLED-дисплея: U8g2 или Adafruit.
Пример кода для U8g2:
// ssd1306_u8g2.ino
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
#define BITMAP_WIDTH 96
#define BITMAP_HEIGHT 64
static const unsigned char PROGMEM bitmap[] = { 0x0, 0x0, 0xff, 0x3f, 0x0, 0x0, 0x0, 0x0, 0xff, 0x3f, 0x0, 0x0, 0x0, 0xe0, 0xff, 0xff, 0x1, 0x0, 0x0, 0xe0, 0xff, 0xff, 0x1, 0x0, 0x0, 0xf8, 0xff, 0xff, 0xf, 0x0, 0x0, 0xf8, 0xff, 0xff, 0x7, 0x0, 0x0, 0xfe, 0xff, 0xff, 0x1f, 0x0, 0x0, 0xfe, 0xff, 0xff, 0x1f, 0x0, 0x0, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0xff, 0xff, 0xff, 0x3f, 0x0, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x1, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x3, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x1, 0xf0, 0xff, 0xf, 0xfc, 0xff, 0x7, 0xf0, 0xff, 0xf, 0xfc, 0xff, 0x7, 0xf0, 0xff, 0x1, 0xc0, 0xff, 0xf, 0xf8, 0xff, 0x1, 0xe0, 0xff, 0x7, 0xf8, 0x7f, 0x0, 0x0, 0xff, 0x1f, 0xfc, 0x7f, 0x0, 0x80, 0xff, 0xf, 0xfc, 0x1f, 0x0, 0x0, 0xfc, 0x3f, 0xfe, 0x1f, 0x0, 0x0, 0xfe, 0x1f, 0xfc, 0xf, 0x0, 0x0, 0xf8, 0x7f, 0xff, 0xf, 0x0, 0x0, 0xfc, 0x1f, 0xfe, 0x7, 0x0, 0x0, 0xf0, 0x7f, 0xff, 0x7, 0x0, 0x0, 0xf8, 0x3f, 0xfe, 0x7, 0x0, 0x0, 0xe0, 0xff, 0xff, 0x3, 0xf0, 0x1, 0xf0, 0x3f, 0xfe, 0x3, 0x0, 0x0, 0xc0, 0xff, 0xff, 0x1, 0xf0, 0x1, 0xe0, 0x7f, 0xff, 0x3, 0x0, 0x0, 0x80, 0xff, 0xff, 0x0, 0xf0, 0x1, 0xc0, 0x7f, 0xff, 0x1, 0x0, 0x0, 0x80, 0xff, 0x7f, 0x0, 0xf0, 0x1, 0xc0, 0x7f, 0xff, 0x1, 0x0, 0x0, 0x0, 0xff, 0x7f, 0x0, 0xf0, 0x1, 0xc0, 0x7f, 0xff, 0x0, 0x0, 0x0, 0x0, 0xfe, 0x3f, 0x80, 0xff, 0x3f, 0x80, 0x7f, 0xff, 0x80, 0xff, 0xff, 0x0, 0xfe, 0x3f, 0x80, 0xff, 0x3f, 0x80, 0x7f, 0xff, 0x80, 0xff, 0xff, 0x0, 0xfc, 0x1f, 0x80, 0xff, 0x3f, 0x80, 0x7f, 0xff, 0x80, 0xff, 0xff, 0x0, 0xfc, 0x1f, 0x80, 0xff, 0x3f, 0x80, 0x7f, 0xff, 0x80, 0xff, 0xff, 0x0, 0xfe, 0x1f, 0x80, 0xff, 0x3f, 0x80, 0x7f, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0x3f, 0x0, 0xf0, 0x1, 0xc0, 0x7f, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0x7f, 0x0, 0xf0, 0x1, 0xc0, 0x7f, 0xff, 0x1, 0x0, 0x0, 0x80, 0xff, 0x7f, 0x0, 0xf0, 0x1, 0xc0, 0x7f, 0xff, 0x1, 0x0, 0x0, 0xc0, 0xff, 0xff, 0x0, 0xf0, 0x1, 0xe0, 0x7f, 0xff, 0x3, 0x0, 0x0, 0xc0, 0xff, 0xff, 0x1, 0xf0, 0x1, 0xe0, 0x3f, 0xfe, 0x3, 0x0, 0x0, 0xe0, 0xff, 0xff, 0x3, 0x0, 0x0, 0xf0, 0x3f, 0xfe, 0x7, 0x0, 0x0, 0xf0, 0xff, 0xff, 0x7, 0x0, 0x0, 0xf8, 0x3f, 0xfe, 0xf, 0x0, 0x0, 0xf8, 0x3f, 0xff, 0xf, 0x0, 0x0, 0xf8, 0x1f, 0xfc, 0x1f, 0x0, 0x0, 0xfc, 0x3f, 0xfe, 0xf, 0x0, 0x0, 0xfc, 0x1f, 0xfc, 0x3f, 0x0, 0x0, 0xfe, 0x1f, 0xfe, 0x3f, 0x0, 0x0, 0xff, 0xf, 0xf8, 0xff, 0x0, 0x80, 0xff, 0xf, 0xfc, 0xff, 0x0, 0x80, 0xff, 0xf, 0xf8, 0xff, 0x3, 0xe0, 0xff, 0x7, 0xf8, 0xff, 0x3, 0xe0, 0xff, 0x7, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x3, 0xf0, 0xff, 0x3f, 0xfc, 0xff, 0x3, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x1, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x1, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0xfe, 0xff, 0xff, 0x3f, 0x0, 0x0, 0xfe, 0xff, 0xff, 0x1f, 0x0, 0x0, 0xf8, 0xff, 0xff, 0xf, 0x0, 0x0, 0xf8, 0xff, 0xff, 0xf, 0x0, 0x0, 0xe0, 0xff, 0xff, 0x3, 0x0, 0x0, 0xe0, 0xff, 0xff, 0x3, 0x0, 0x0, 0x0, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x7, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x3, 0xff, 0xf1, 0x1f, 0x3c, 0x3c, 0xff, 0xe7, 0xe3, 0xe1, 0xf, 0xe0, 0x7, 0xff, 0xf3, 0x7f, 0x3c, 0x3c, 0xff, 0xe7, 0xe3, 0xf1, 0x1f, 0xf0, 0x7, 0xff, 0xf3, 0xff, 0x3c, 0x3c, 0xff, 0xe7, 0xe7, 0xf9, 0x3f, 0xf0, 0x7, 0xc7, 0xf7, 0xf8, 0x3c, 0x3c, 0xf8, 0xe0, 0xe7, 0x79, 0x3c, 0xf0, 0x7, 0xc7, 0xf7, 0xf0, 0x3d, 0x3c, 0xf8, 0xe0, 0xe7, 0x3d, 0x78, 0x78, 0xe, 0xc7, 0xf7, 0xe0, 0x3d, 0x3c, 0xf8, 0xe0, 0xef, 0x3d, 0x78, 0x78, 0xe, 0xff, 0xf3, 0xe0, 0x3d, 0x3c, 0xf8, 0xe0, 0xef, 0x3d, 0x78, 0x78, 0xe, 0xff, 0xf1, 0xe0, 0x3d, 0x3c, 0xf8, 0xe0, 0xff, 0x3d, 0x78, 0x7c, 0x1e, 0xff, 0xf0, 0xe0, 0x3d, 0x3c, 0xf8, 0xe0, 0xff, 0x3d, 0x78, 0xfc, 0x1f, 0xf7, 0xf1, 0xe0, 0x3d, 0x3c, 0xf8, 0xe0, 0xfd, 0x3d, 0x78, 0xfc, 0x1f, 0xe7, 0xf1, 0xe0, 0x3d, 0x3c, 0xf8, 0xe0, 0xfd, 0x3d, 0x78, 0xfc, 0x1f, 0xe7, 0xf3, 0xf0, 0x3c, 0x3c, 0xf8, 0xe0, 0xf9, 0x3d, 0x78, 0xfe, 0x3f, 0xc7, 0xf3, 0xfc, 0x7c, 0x3e, 0xf8, 0xe0, 0xf9, 0x79, 0x3c, 0x1e, 0x3c, 0xc7, 0xf7, 0x7f, 0xfc, 0x3f, 0xff, 0xe7, 0xf9, 0xf9, 0x3f, 0x1e, 0x7c, 0x87, 0xf7, 0x3f, 0xf0, 0x1f, 0xff, 0xe7, 0xf1, 0xf1, 0x1f, 0xe, 0x78, 0x87, 0xf7, 0xf, 0xe0, 0x7, 0xff, 0xe7, 0xf1, 0xe1, 0x7 };
void setup(void) {
if (!u8g2.begin()) {
Serial.println(F("SSD1306 allocation failed"));
for (;;) {
// Don't proceed, loop forever
}
};
u8g2.clearDisplay();
u8g2.drawXBMP(16, 0, BITMAP_WIDTH, BITMAP_HEIGHT, bitmap);
u8g2.sendBuffer();
}
void loop(void) {}
Пример кода для Adafruit:
// ssd1306_adafruit.ino
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <avr/pgmspace.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BITMAP_WIDTH 96
#define BITMAP_HEIGHT 64
static const unsigned char PROGMEM bitmap[] = { 0x0, 0x0, 0xff, 0xfc, 0x0, 0x0, 0x0, 0x0, 0xff, 0xfc, 0x0, 0x0, 0x0, 0x7, 0xff, 0xff, 0x80, 0x0, 0x0, 0x7, 0xff, 0xff, 0x80, 0x0, 0x0, 0x1f, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x1f, 0xff, 0xff, 0xe0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xf8, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xf8, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x1, 0xff, 0xff, 0xff, 0xff, 0x0, 0x1, 0xff, 0xff, 0xff, 0xff, 0x0, 0x3, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3, 0xff, 0xff, 0xff, 0xff, 0x0, 0x3, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x7, 0xff, 0xff, 0xff, 0xff, 0x80, 0xf, 0xff, 0xf0, 0x3f, 0xff, 0xe0, 0xf, 0xff, 0xf0, 0x3f, 0xff, 0xe0, 0xf, 0xff, 0x80, 0x3, 0xff, 0xf0, 0x1f, 0xff, 0x80, 0x7, 0xff, 0xe0, 0x1f, 0xfe, 0x0, 0x0, 0xff, 0xf8, 0x3f, 0xfe, 0x0, 0x1, 0xff, 0xf0, 0x3f, 0xf8, 0x0, 0x0, 0x3f, 0xfc, 0x7f, 0xf8, 0x0, 0x0, 0x7f, 0xf8, 0x3f, 0xf0, 0x0, 0x0, 0x1f, 0xfe, 0xff, 0xf0, 0x0, 0x0, 0x3f, 0xf8, 0x7f, 0xe0, 0x0, 0x0, 0xf, 0xfe, 0xff, 0xe0, 0x0, 0x0, 0x1f, 0xfc, 0x7f, 0xe0, 0x0, 0x0, 0x7, 0xff, 0xff, 0xc0, 0xf, 0x80, 0xf, 0xfc, 0x7f, 0xc0, 0x0, 0x0, 0x3, 0xff, 0xff, 0x80, 0xf, 0x80, 0x7, 0xfe, 0xff, 0xc0, 0x0, 0x0, 0x1, 0xff, 0xff, 0x0, 0xf, 0x80, 0x3, 0xfe, 0xff, 0x80, 0x0, 0x0, 0x1, 0xff, 0xfe, 0x0, 0xf, 0x80, 0x3, 0xfe, 0xff, 0x80, 0x0, 0x0, 0x0, 0xff, 0xfe, 0x0, 0xf, 0x80, 0x3, 0xfe, 0xff, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xfc, 0x1, 0xff, 0xfc, 0x1, 0xfe, 0xff, 0x1, 0xff, 0xff, 0x0, 0x7f, 0xfc, 0x1, 0xff, 0xfc, 0x1, 0xfe, 0xff, 0x1, 0xff, 0xff, 0x0, 0x3f, 0xf8, 0x1, 0xff, 0xfc, 0x1, 0xfe, 0xff, 0x1, 0xff, 0xff, 0x0, 0x3f, 0xf8, 0x1, 0xff, 0xfc, 0x1, 0xfe, 0xff, 0x1, 0xff, 0xff, 0x0, 0x7f, 0xf8, 0x1, 0xff, 0xfc, 0x1, 0xfe, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xfc, 0x0, 0xf, 0x80, 0x3, 0xfe, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xfe, 0x0, 0xf, 0x80, 0x3, 0xfe, 0xff, 0x80, 0x0, 0x0, 0x1, 0xff, 0xfe, 0x0, 0xf, 0x80, 0x3, 0xfe, 0xff, 0x80, 0x0, 0x0, 0x3, 0xff, 0xff, 0x0, 0xf, 0x80, 0x7, 0xfe, 0xff, 0xc0, 0x0, 0x0, 0x3, 0xff, 0xff, 0x80, 0xf, 0x80, 0x7, 0xfc, 0x7f, 0xc0, 0x0, 0x0, 0x7, 0xff, 0xff, 0xc0, 0x0, 0x0, 0xf, 0xfc, 0x7f, 0xe0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xe0, 0x0, 0x0, 0x1f, 0xfc, 0x7f, 0xf0, 0x0, 0x0, 0x1f, 0xfc, 0xff, 0xf0, 0x0, 0x0, 0x1f, 0xf8, 0x3f, 0xf8, 0x0, 0x0, 0x3f, 0xfc, 0x7f, 0xf0, 0x0, 0x0, 0x3f, 0xf8, 0x3f, 0xfc, 0x0, 0x0, 0x7f, 0xf8, 0x7f, 0xfc, 0x0, 0x0, 0xff, 0xf0, 0x1f, 0xff, 0x0, 0x1, 0xff, 0xf0, 0x3f, 0xff, 0x0, 0x1, 0xff, 0xf0, 0x1f, 0xff, 0xc0, 0x7, 0xff, 0xe0, 0x1f, 0xff, 0xc0, 0x7, 0xff, 0xe0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf, 0xff, 0xfc, 0x3f, 0xff, 0xc0, 0x3, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1, 0xff, 0xff, 0xff, 0xff, 0x0, 0x1, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xf8, 0x0, 0x0, 0x1f, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x1f, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x7, 0xff, 0xff, 0xc0, 0x0, 0x0, 0x7, 0xff, 0xff, 0xc0, 0x0, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xf, 0xe0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xc0, 0xff, 0x8f, 0xf8, 0x3c, 0x3c, 0xff, 0xe7, 0xc7, 0x87, 0xf0, 0x7, 0xe0, 0xff, 0xcf, 0xfe, 0x3c, 0x3c, 0xff, 0xe7, 0xc7, 0x8f, 0xf8, 0xf, 0xe0, 0xff, 0xcf, 0xff, 0x3c, 0x3c, 0xff, 0xe7, 0xe7, 0x9f, 0xfc, 0xf, 0xe0, 0xe3, 0xef, 0x1f, 0x3c, 0x3c, 0x1f, 0x7, 0xe7, 0x9e, 0x3c, 0xf, 0xe0, 0xe3, 0xef, 0xf, 0xbc, 0x3c, 0x1f, 0x7, 0xe7, 0xbc, 0x1e, 0x1e, 0x70, 0xe3, 0xef, 0x7, 0xbc, 0x3c, 0x1f, 0x7, 0xf7, 0xbc, 0x1e, 0x1e, 0x70, 0xff, 0xcf, 0x7, 0xbc, 0x3c, 0x1f, 0x7, 0xf7, 0xbc, 0x1e, 0x1e, 0x70, 0xff, 0x8f, 0x7, 0xbc, 0x3c, 0x1f, 0x7, 0xff, 0xbc, 0x1e, 0x3e, 0x78, 0xff, 0xf, 0x7, 0xbc, 0x3c, 0x1f, 0x7, 0xff, 0xbc, 0x1e, 0x3f, 0xf8, 0xef, 0x8f, 0x7, 0xbc, 0x3c, 0x1f, 0x7, 0xbf, 0xbc, 0x1e, 0x3f, 0xf8, 0xe7, 0x8f, 0x7, 0xbc, 0x3c, 0x1f, 0x7, 0xbf, 0xbc, 0x1e, 0x3f, 0xf8, 0xe7, 0xcf, 0xf, 0x3c, 0x3c, 0x1f, 0x7, 0x9f, 0xbc, 0x1e, 0x7f, 0xfc, 0xe3, 0xcf, 0x3f, 0x3e, 0x7c, 0x1f, 0x7, 0x9f, 0x9e, 0x3c, 0x78, 0x3c, 0xe3, 0xef, 0xfe, 0x3f, 0xfc, 0xff, 0xe7, 0x9f, 0x9f, 0xfc, 0x78, 0x3e, 0xe1, 0xef, 0xfc, 0xf, 0xf8, 0xff, 0xe7, 0x8f, 0x8f, 0xf8, 0x70, 0x1e, 0xe1, 0xef, 0xf0, 0x7, 0xe0, 0xff, 0xe7, 0x8f, 0x87, 0xe0 };
void setup() {
Serial.begin(9600);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;) {
// Don't proceed, loop forever
}
}
display.clearDisplay();
display.drawBitmap(16, 0, bitmap, BITMAP_WIDTH, BITMAP_HEIGHT, SSD1306_WHITE);
display.display();
}
void loop() {}
После загрузки изображения в Arduino вы увидите на экране:
Работа со шрифтами
Как таковой работы со шрифтами в редакторе нет.
Но для метеостанции, которую я делал, очень нужно было отображать показания температуры и некоторые символы.
На самом деле дисплей SSD1306 не имеет встроенной поддержки шрифтов. Всё, что вы отображаете, — это bitmap-изображения.
Это значит, что и каждый символ шрифта — это маленькая bitmap-картинка, которая просто отображается в нужном месте дисплея.
Этот метод не очень подходит для работы с библиотеками U8g2 и Adafruit, так как у них своя система кодирования шрифтов. Разве что вы захотите отображать каждый символ отдельной картинкой.
Но в моем случае, поскольку я писал свой драйвер дисплея, я добавил к нему поддержку определяемых шрифтов.
Фокус в том, что из редактора можно выгрузить в код на Си не только целое изображение, но и его часть. Таким образом, мы можем собрать свой шрифт, выгружая нужные символы.
Для этого нужно открыть bitmap-изображение, выделить нужную область с помощью кнопки «Область» и нажать кнопку «Экспорт в C». Будет экспортирована только выделенная часть изображения.
Отображение данных на дисплее метеостанции:
Итоги
Работа над драйверами для метеостанции заслуживает отдельной статьи на Хабре. Она затянулась на продолжительное время и стала настоящим приключением.
Bitmap Editor помог мне завершить проект метеостанции на Arduino.
В дальнейшем я планирую развивать и улучшать его. Возможно, в какой-то из версий появится полноценная работа со шрифтами для Arduino-библиотек.
Присоединяйтесь к разработке проекта! Поддержите проект звёздами на GitHub.
Спасибо за прочтение и удачных вам самоделок на Arduino!