Опрос


Что для Вас Умный Дом?


Результаты


Реклама


Использование OLED I2C дисплея с MegaD-328

06/02/2016 23:30:09

Некоторое время назад я опубликовал статью, в которой описал опыт подключения к MegaD-328 типичного ЖК дисплея. И хотя сама по себе идея вывода информации на ЖК- дисплеи в различных уголках дома интересна, реализация, описанная в той статье, не вызвала особенного энтузиазма у пользователей, и тому есть вполне объяснимые причины.

1. Сложность подключения. Готового решения я не предложил, а потому необходимо было "внедряться" в межблочный шлейф, припаивать проводники к дисплею, что-то придумывать с питанием.
2. Для подключения к ЖК-дисплею требовалось использование 6 (шести!) портов, а это многовато... и в конечном счете дороговато.
3. Дисплей нельзя было удалить от контроллера на сколь-нибудь приемлемое расстояние. Надежно он работал только с коротким шлейфом до 2-3 метров.
4. Символьный дисплей - не то, что хочется иметь в Умном Доме

Но с тех пор, как была опробована программная реализация работы с шиной I2C (датчик давления BMP180, датчик температуры и влажности HTU21D), стало возможным пойти дальше и попробовать подключить какой-нибудь дисплей, поддерживающий эту шину.

OLED SSD1306 I2C

Для тестирования я выбрал монохромный 0,96" OLED дисплей (128х64) стоимостью около $5-$8 со встроенным контроллером SSD1306 и поддержкой I2C. Эти дисплеи бывают, кстати, с белой и синей подсветкой, а также двухцветные.
В чем преимущество этого и подобных ему дисплеев:

1. Простота подключения. Не требуется ничего припаивать или модифицировать. Нужно только подключить 4 провода (питание +3,3В, земля, линии SCL и SDA)
2. Для работы с дисплеем требуется только 2 порта. Причем на одной шине может висеть несколько разных устройств.
3. I2C устройства могут располагаться на некотором расстоянии от контроллера (несколько метров или даже десятков метров).
4. Выводить на дисплей можно все, что угодно: графику, текст (любыми шрифтами). В контроллер дисплея даже встроены некоторые функции анимации (скроллинг).

Подключение OLED дисплея к MegaD-328 IN Kit

Подключение дисплея к исполнительному модулю MegaD-14-IN полностью аналогично подключению датчиков. Линии SCL и SDA можно подключать к любым портам. Необходимо произвести только два действия. Установить конфигурационные джамперы в нижнее положение. Установить в Web-интерфейсе контроллера тип портов NC. С питанием все очевидно - подключаем к +3,3В. Кстати, на плате дисплея присутствует стабилизатор, позволяющий подключать дисплей также к +5В. От +12В, он, замечу, тоже не сгорит, но это не рекомендуется.

Первое, что я сделал, написал драйвер дисплея для библиотеки I2C-PHP. Конечно, у меня все заработало, но прежде, чем показать результат, я бы хотел сказать несколько слов о реализации I2C-PHP для MegaD-328. Эта библиотека посредством отдельных HTTP-пакетов и стандартного MegaD API обеспечивает работу протокола I2C. Никакой специальной поддержки шины I2C в целом или конкретных устройств для этой технологии в прошивке нет. Преимущество такого подхода в том, что можно реализовать работу абсолютно с любыми устройствами без необходимости изменять прошивку. Написал программу на сервере и погнали! Но есть у этого подхода один минут - скорость работы. "Нативная" реализация I2C средствами микроконтроллера предполагает скорость от 100 до 400 Кбит/с. В случае программной реализации на PHP через протокол HTTP скорость существенно ниже. Ну, то есть, СУЩЕСТВЕННО ниже, понимаете? Дело в том, что, когда мы работаем с любыми датчиками, нам необходимо обменяться только парой тройкой байт данных. Это занимает 1-3 секунды и совершенно приемлемо. Но когда речь заходит о дисплее с 8192 точками, то скорость уже начинает иметь самое непосредственное значение. И все же... Как говорится: а что? а вдруг?..

OLED radmom gddram garbage

Когда дисплей впервые подключается к питанию, в его памяти (GDDRAM) содержится всякий мусор. Поэтому перед тем, как начать работу, дисплей необходимо проинициализировать и очистить. Инициализация проходит достаточно быстро, а вот очистка экрана занимает... порядка 75 секунд. Убийственно? Даа... Впрочем, нет, давайте разберемся по порядку. Может быть, не все так плохо?
Забегая вперед скажу, что уже есть версия прошивки, которая значительно ускоряет работу с дисплеем. Очистка или прорисовка всего дисплея занимает 10 секунд!

<?
define("SCL", "8");
define("SDA", "9");
define("MD", "http://192.168.0.14/sec/?");

require_once("mod_i2c_ssd1306.php");

ssd1306_init();
ssd1306_clear_display();
?>

В начале кода мы определяем URL устройства MegaD-328 и порты, к которым подключены линии SCL и SDA. Далее я для краткости буду пропускать эти строчки.
Инициализацию и очистку графической памяти по сути нужно произвести только один раз. Затем достаточно только обновлять изменяющуюся часть данных. Позже я покажу, как это сделать, а начать я решил с самого простого в данном случае - вывода графического изображения.

Для того, чтобы вывести на дисплей какую-нибудь произвольную графику, нужна программа, конвертирующая BMP в формат, который удобно скормить дисплею. Можно было бы написать что-то свое, тем более, что это не трудно, и даже интегрировать эту функцию в драйвер, но для простоты и наглядности я использовал программу LCD Assistant.

Затем я написал функцию, которая загружает массив данных из файла и отображает картинку на экране дисплея.

ssd1306_draw_pic("ab_log_logo");

Вот так, незамысловато. Параметр "ab_log_logo" здесь имя массива из файла libs/ssd1306/mod_ssd1306_pics.php, который включен в общий архив. Вы найдете его внизу статьи.
Собственно, результат... Конечно, для монохромной графики требуется специальная доработка любого изображения, иначе могут вылезти всякие артефакты, которые заметны на фотографии. Но это отдельная тема.

Ну а теперь самое интересное, отображение текста. В контроллере дисплея нет никаких встроенных таблиц со шрифтами или чего-то такого подобного - рисуй, что хочешь. Прекрасно, но как? В этом нам поможет другая программа: The Dot Factory, которая преобразует любые символы в формат, подходящий для отображения на дисплее.

В настройках программы нужно выбрать Rotate: 90 и Line wrap: At bitmap. The Dot Factory генерирует код для C, который нам не подходит, но я написал конвертор, который включен в архив с остальными исходными кодами. Не буду в данной статье углубляться в вопрос генерации данных со шрифтами. Скажу лишь, что мой архив уже содержит такие шрифты как Verdana 8 pt, Verdana 10 pt, Mistral 10 pt. А вот и PHP-код, который выводит текст на экран моего OLED-дисплея.

ssd1306_write_text("Температура: 24.62", "verdana_10", 0, 0);
ssd1306_write_text("Влажность: 47%", "verdana_10", 0, 2);
ssd1306_write_text("   ХОРОШЕГО ДНЯ!", "mistral_10", 0, 5);

Вывод информации на дисплеи Умного Дома

Функция ssd1306_write_text() принимает в качестве параметров: строку; имя массива, содержащего шрифт; номер колонки (от 0 до 128) и номер строки (от 0 до 7).

А вот теперь имеет смысл вернуться к вопросу о скорости работы с дисплеем. Вы помните об этих ужасных 75 секундах для прорисовки / очистки дисплея целиком. А если нам необходимо обновить не весь дисплей, а только данные по температуре и влажности? Сколько занимает отображение одного символа? Около 1 секунды. Значит, ключевые данные обновятся за 8-10 секунд. Что ж, вполне сносно... Кроме того, медленное изменение цифр выглядит где-то даже забавно. Как будто специальная этакая анимация. С модифициованной же прошивкой та же самая операция займет около 1 секунды.

ssd1306_write_text("22.82 ", "verdana_10", 84, 0);

Здесь мы указываем, что новые данные (новое значение температуры) должны отображаться, начиная с 84 колонки.

Расстояние от контроллера до дисплея.

Закономерный вопрос. На каком расстоянии от контроллера можно расположить дисплей, чтобы он стабильно работал. Я провел эксперимент, подключив дисплей обычной витой парой (UTP 5 AWG 24), используя только четыре провода. Длина кабеля 18 метров (больше одним куском в доме на этот момент не оказалось). Дисплей прекрасно работал. Никаких намеков на сбои или ошибки. Думаю, на тех расстояниях, которые есть в домашних условиях, дисплеи и другие I2C устройства будут работать нормально.

Итак. К устройствам MegaD-328 с исполнительным модулем MegaD-14-IN можно подключать OLED/LCD-дисплеи, работающие по шине I2C. Низкая стоимость такого решения и простота реализации позволяют использовать эти дисплеи в различных ситуациях. Дисплеи можно размещать в щитках для отображения текущего потребления или напряжения по фазам. Экранчики можно встраивать в корпуса для температурных датчиков, о которых я писал ранее. OLED дисплеи почти не нагреваются, а значит не будут влиять на измеряемую температуру. Будучи размещенным на корпусе датчика, дисплей может отображать информацию о текущей температуре, влажности, качестве воздуха (например, содержании CO2) и другие данные. Дисплеи можно вешать на кухне или в спальне, они могут работать как часы или отображать прогноз погоды. Управляемые сервером, дисплеи также способны менять яркость свечения в зависимости от времени суток.

PHP библиотека для работы с OLED дисплеем на контроллере SSD1306 пока умеет не очень много и содержит лишь самые простейшие функции, но если у пользователей будет интерес к данной теме, я с удовольствием продолжу разработку. Что касается медлительности в части обмена информацией с дисплеем, то и здесь есть потенциальная возможность все-таки переложить часть работы на сторону контроллера, что позволит многократно увеличить скорость отображения информации.

Я уже опробовал тестовый вариант прошивки, когда контроллеру передаются по сети Ethernet не отдельные биты, а байт целиком. Это ускоряет работу с дисплеем почти в 8 раз. Прорисовка всего дисплея занимает 10 секунд. Но, думаю, и это еще не предел.

Кстати, дисплей с белыми пикселами мне понравился больше...

Исходники I2C-PHP для MegaD-328 и дисплея OLED SSD1306

 

Автор: Andrey_B
Любое использование материалов сайта возможно только с разрешения автора и с обязательным указанием источника.



Добавить комментарий:



Сортировка комментариев: Последние сверху | Первые сверху

2017-01-04 00:54:15 | Andrey_B
Алексей, ПК может все. Например, он может сохранять у себя информацию об инициализации дисплея (в БД или в файле). Скажем, в виде флага. А когда устройство стартует/ресетится, то передача на сервер st=1 является сигналом сбросить этот флаг и проинициализировать дисплей заново. Это лишь один из вариантов.
Конечно, дисплей может проинициализировать и сам контроллер, но для этого (если мы говорим о MegaD-2561) необходимо предусмотреть настройку порта, чтобы контроллер знал, что к нему подключен дисплей.


2017-01-03 20:50:56 | Алексей Ефремов
Андрей! У вас в статье не раскрыто полностью как обновлять только изменяющиеся данные. Например, есть скрипт, который работает по cron, в нем проводим инициализацию, очистку дисплея, первичный вывод информации. Вот как проверить, что дисплей уже инициализирован и ему уже передали первичные данные, а теперь можно только обновлять меняющиеся данные? В МК было бы просто - при первом включении инициализируем, очищаем, выводим данные устанавливаем флаг - флаг есть. значит только обновляем данные. А как это сделать в linux (debian)?


2016-06-02 18:06:37 | Andrey_B
На больших дисплеях не пробовал. Но, думаю, принципиально мало что измениться.


2016-06-02 04:41:24 | Александр
Вы не смотрели - там стоят Pull-up резисторы? Обычно для I2C шины достаточно что б на одном устройстве хотя бы стояли. Если так, то могу сказать, опираясь на опыт использования I2C на RPI - подобные устройства можно свободно использовать на расстояниях до 50м даже с обычным Al+Cu CAT5E кабелем. Вложил бы фотку - да нельзя прикрепить здесь в коментарии свою схему расположения I2C устройств.
Сама I2C шина живучая и быстрая. Но больше мороки, чем с 1-Wire, например.


2016-06-02 04:25:17 | Александр
Андрей,

Вы с отображением символа градуса вопрос не решили?


2016-06-02 04:21:53 | Александр
Забыл сказать. У меня на сервере крутится скрипт. Написан на Bash.
Скрипт собирает значениях и настройках устройств за три разных промежутка времени. Вычисляет среднее значение и перезаписывает. Таким образом мой Дом подстраивается под меня.

Здесь как раз и интересно было бы видеть текущие значения на выключателях датчиках и прочей автоматике: насосах, винохранилище, сауне и т.д.


Bash - консольный язык программирования nix-серверов


2016-06-02 04:09:35 | Александр
Интерес конечно же есть! Представьте, на корпус датчика повесить сразу отображать температуру, Или же у выключателя отображать теущую яркость диммера. Ну и самое интересное - это использование с голосовыми порталами(микрофоны для передачи команд) - сразу же в реальном времени можно видеть реакцию сервера.
Я две руки За! Пожалуйста развивайте софт!


2016-06-02 02:40:58 | Александр
Отличная идея! Размер дисплея удобный, скажем для быстройинформации около выключателя. На больших дисплейя пробовали?


2016-02-25 17:08:12 | Andrey_B
Да, лучше использовать версию прошивки не ниже 3.43beta1


2016-02-25 15:43:37 | Tarasella
Андрей, на сколько я понял, Вы запускали все это дело на версии прошивки 3.43beta1?