Анимация на I2C OLED 128x64

  • Автор
После огромного перерыва вернулся к Arduino, достаточно подробно покопался с OLED экраном, сделал несколько картинок, вывел анимацию, что очень мало кто делал, если вообще делал. На мой взгляд, немного недооцененный экран с хорошим потенциалом для самоделок, особенно в сравнении с LCD1602 и 2004, но все зависит от конкретных задач.

Характеристики:
Диагональ дисплея: 0,96″ дюйма
Разрешение: 128×64 пикселей
Рабочее напряжение: 3 — 5 В
Энергопотребление: 0.08 Вт (по факту зависит от количество горящих пикселей, так что нет смысла верить этой цифре, поскольку ток будет постоянно меняться)
Рабочая температура: -30 C — 70 °С
Угол обзора: >160°
Размеры модуля 27х27мм, в зависимости от варианта исполнения, размеры могут отличаться.
Подключение по интерфейсу I2C, для Arduino это выводы А4 (SDA), А5(SCL, SCK)
Магазины Украины и СНГ: Анимация на I2C OLED 128x64

Библиотек достаточно много, но заметил одну неприятную особенность. Одна и та же библиотека, но скаченная с разных источников отказывается компилировать программу, написанную под ее же близнеца. Так что если планируете использовать чей-то код, имейте это в виду — возможны проблемы.

Теперь самое интересное, как не сильно напрягаясь прокрутить на этом экране анимацию. Если идти кратчайшим путем — то взять уже готовую черно-белую gif анимацию. Есть онлайн сервис, который позволяет разбить ее покадрово http://picasion.com/ru/split-animated-gif/ Т.е. добавляете туда понравившуюся анимацию, в моем случае «стикман»
Магазины Украины и СНГ: Анимация на I2C OLED 128x64

а на выходе получаете архив с кучей изображений, которые потом проигрываете на экране через определенный промежуток времени
Магазины Украины и СНГ: Анимация на I2C OLED 128x64

В идеале, эти изображения требуют небольшой доработки, допустим я хотел, чтобы анимация была в центре экрана, для кого-то это может оказаться не важным, НО! не забывайте, что разрешение каждого изображения не должно превышать 128х64. Я человек, который фотошопом не пользовался никогда, поэтому все было подогнано в старом добром Paint.
Дальше каждое подготовленное изображение надо перевести в массив, для чего был использован второй онлайн сервис http://www.rinkydinkelectronics.com/_t_doimageconverter_mono.php На выходе, для каждого изображения получится отдельный файл с разрешением *.c, который нужно положить в папку со скетчем.
Магазины Украины и СНГ: Анимация на I2C OLED 128x64

Таких файлом может набраться приличное количество, однако никто вам не мешает разместить все массивы в одном файле, в конечно итоге я так и сделаю, поскольку это как минимум удобнее.
А дальше идет короткий код
#include <OLED_I2C.h>

OLED myOLED(SDA, SCL, 8);
//графика
extern uint8_t stickman_0[];
extern uint8_t stickman_1[];
extern uint8_t stickman_2[];
extern uint8_t stickman_3[];
extern uint8_t stickman_4[];
int t = 35;
//*****************************************************************
void setup()
{
myOLED.begin();
}
void stickman()//смена изображений анимации с интервалом t
{
myOLED.clrScr();
myOLED.drawBitmap(0, 0, stickman_0, 128, 64);//координата по Х, по У, имя файла, ширина в пикселях, высота
myOLED.update();
delay(t);
myOLED.clrScr();
myOLED.drawBitmap(0, 0, stickman_1, 128, 64);
myOLED.update();
delay(t);
myOLED.clrScr();
myOLED.drawBitmap(0, 0, stickman_2, 128, 64);
myOLED.update();
delay(t);
myOLED.clrScr();
myOLED.drawBitmap(0, 0, stickman_3, 128, 64);
myOLED.update();
delay(t);
myOLED.clrScr();
myOLED.drawBitmap(0, 0, stickman_4, 128, 64);
myOLED.update();
delay(t);
}
//*****************************************************************
void loop()
{
stickman();
}

Как видите ничего сложного, единственное, когда делаешь в первый раз времени отнимает адски много, но дальше все идет по отработанной схеме достаточно быстро и без сюрпризов.

Поскольку бегущий человек на экране взят в качестве примера, а делать я планировал метеостанцию, то остальные картинки я брал именно по этой теме и подгонял под разрешение 60х60.
Магазины Украины и СНГ: Анимация на I2C OLED 128x64

Мне показалось скучно использовать такой экран для вывода букв и цифр, поэтому слева будет изображение градусника, справа большими цифрами значение температуры, а снизу еще и нормальное значение по нормам для жилой комнаты — максимум информации и максимально наглядно. В последствии тоже самое буду делать для влажности и давления. Код с заготовкой под метеостанцию в качестве примера тоже может оказаться кому-то полезен.
Дополнительная информация
#include <OLED_I2C.h> //библиотека OLED дисплея
//Заготовка под метеостанцию
OLED myOLED(SDA, SCL, 8);
//шрифты
extern uint8_t SmallFont[];
extern uint8_t TinyFont[];
extern uint8_t RusFont[];
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];
extern uint8_t MegaNumbers[];
//подготовленные изображения
extern uint8_t clear[];
extern uint8_t cloudy[];
extern uint8_t rain[];
extern uint8_t rainn[];
extern uint8_t rainnn[];
extern uint8_t storm[];
extern uint8_t temperature[];
int temp=25;//произвольное значение температуры, будет браться с датчика
void normal(int t)//вовод нормальных значений в таблице, t длительность анимации
{
for (t;t>0;t--)
{
myOLED.clrScr();
myOLED.setFont(SmallFont);
myOLED.drawLine(0, 10, 128, 10); // горизонтальная и
myOLED.drawLine(83, 0, 83, 64); // вертикальная линии
myOLED.print(«20 — 25», RIGHT, 17); // Температура
myOLED.print(«30 — 60», RIGHT, 28); // Влажность
myOLED.print(«740», 98, 39); // Давление
myOLED.print(«200», 98, 50); // Высота
myOLED.setFont(RusFont);
myOLED.print(«Gfhfvtnh», LEFT, 0); // Параметр
myOLED.print(«Yjhvf», 94, 0); // Норма
myOLED.print(«Ntvgthfnehf », LEFT, 17); // Температура
myOLED.print(«Dkf;yjcnm », LEFT, 28); // Влажность
myOLED.print(«Lfdktybt », LEFT, 39); // Давление, г. Москва
myOLED.print(«Dscjnf Vjcrdf», LEFT, 50);// Высота, г. Москва
myOLED.update();
delay(1000);
}
}

void clear_status(int t)//выводим на экран облако и солнце
{
for (t;t>0;t--)
{
myOLED.clrScr();
myOLED.drawBitmap(34, 1, clear, 60, 60);
myOLED.update();
delay(1000);
}
}
void cloudy_status(int t)// выводим на экран облако
{
for (t;t>0;t--)
{
myOLED.clrScr();
myOLED.drawBitmap(34, 1, cloudy, 60, 60);
myOLED.update();
delay(1000);
}
}
void rain_status(int t)//анимация дождь
{
for (t;t>0;t--)
{
myOLED.clrScr();
myOLED.drawBitmap(34, 1, cloudy, 60, 60);
myOLED.update();
delay(250);
myOLED.clrScr();
myOLED.drawBitmap(34, 1, rain, 60, 60);
myOLED.update();
delay(250);
myOLED.clrScr();
myOLED.drawBitmap(34, 1, rainn, 60, 60);
myOLED.update();
delay(250);
myOLED.clrScr();
myOLED.drawBitmap(34, 1, rainnn, 60, 60);
myOLED.update();
delay(250);
}
}
void storm_status(int t)//анимация гроза
{
for (t;t>0;t--)
{
myOLED.clrScr();
myOLED.drawBitmap(34, 1, storm, 60, 60);
myOLED.update();
delay(250);
myOLED.clrScr();
myOLED.drawBitmap(34, 1, cloudy, 60, 60);
myOLED.update();
delay(500);
myOLED.drawBitmap(34, 1, storm, 60, 60);
myOLED.update();
delay(250);
rain_status(2);
myOLED.clrScr();
}
}
void temperature_status(int t)//
{
for (t;t>0;t--)
{
//myOLED.clrScr();
myOLED.drawBitmap(1, 3, temperature, 60, 60);
myOLED.setFont(MegaNumbers);
myOLED.printNumF(temp, 0, 70, 14);//считываем температуру с датчика давления
myOLED.update();
delay(1000);
}
}

//*****************************************************************
void setup()
{
myOLED.begin();
}

//*****************************************************************
void loop()
{
normal(3);
myOLED.clrScr();
myOLED.setFont(RusFont);
myOLED.print(«Yjhvf 20-25», 61, 57);//латинница, но набирать в русской раскладке
temperature_status(2);

clear_status (1);
cloudy_status (1);
rain_status (3);
storm_status (4);
}

По ссылке можно скачать архив с библиотекой и программами
Как это все выглядит в живую можно посмотреть на видео

Экран предоставлен магазином бесплатно, но все мы люди умные и знаем где — что покупать ;-)
В дальнейшем жду датчик bme280 и продолжу мучать предсказатель погоды, хочу попробовать накопить статистику за час или два и по перепадам давления в этот период предсказать погоду, попутно сверяясь со значениями, которые соответствую, например дождю с очень высокой вероятностью. Короче, если давление резко и значительно падает на протяжении часа — осадки неизбежны. Если повышается, но давление все еще очень низкое — значит облачно и возможны осадки. Вот такая задумка, буду делать медленно и не спеша. Как делать графику на этом экране я искал достаточно долго, так что польза от обзора все же есть.

0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.