Oled i2c дисплей 128х64 пикселя

OLED i2c дисплей 128х64 пикселя

OLED дисплеи на сегодняшний день являются самыми совершенными типами дисплеев, и причин тому много: широкие углы обзора, низкое энергопотребление, малая толщина дисплеев и отсутствие необходимости во внешней подсветке. Из недостатков можно выделить ограниченный срок службы дисплея и относительно высокую стоимость. К тому же большинство дисплеев, построенных по технологии OLED применяются в серийно выпускаемых устройствах, а для радиолюбителей доступны лишь некоторые модели дисплеев, ассортимент которых не так уж широк. Одной из доступных для радиолюбителей моделей OLED дисплеев является 0,96-дюймовый монохромный дисплей с разрешением 128*64 пикселя, управляемый чипом SSD1306.

Дисплей был куплен в магазине Banggood, ссылка на товар. Есть они и на AliExpress. Дисплей поставляется в виде модуля, размеры модуля приведены на изображении ниже (замечу что не все размеры на чертеже проставлены правильно). Толщина самого дисплея составляет всего 1,45 миллиметра, толщина модуля с учетом smd-компонентов расположенных на задней стороне печатной платы около 4 миллиметров. Размер модуля 27*27 миллиметров, размер самого дисплея 26,7*19,3 миллиметра, при этом активное рабочее поле дисплея составляет всего 10,9*21,75 миллиметра, пиксели расположены с шагом 0,17 миллиметра, размер пикселя же всего 0,154*0,154 миллиметра.

Чип SSD1306 поддерживает 5 протоколов связи:

  • I2C;
  • 3-проводной SPI;
  • 4-проводной SPI;
  • 8-bit 68XX parallel;
  • 8-bit 80XX parallel.

В данном модуле используется протокол I2C, но встречаются модули с протоколом SPI и даже с переключением протоколов.

Данная статья является не дословным изложением «датшита» на дисплей. Я рассмотрю основные команды для работы с дисплеем, приведу пример работы с ним. Для тех кто делает первые шаги в программировании микроконтроллеров (для «ардуинщиков») в конце статьи будет приведено описание библиотеки для работы с данным дисплеем. Все примеры так же выполнены в среде ArduinoIDE, ибо статья рассчитана не столько на матерых программистов микроконтроллеров (которые и без моей помощи смогут разобраться в даташите и написать библиотеку), сколько на новичков. К тому же, на мой взгляд важнее понять как работать с дисплеем, нежели увидеть реализацию в какой-то определенной среде программирования. Кроме того, существуют готовые библиотеки для других компиляторов, включая популярную библиотеку U8glib. Их я рассматривать не буду.

Как я уже упоминал, дисплей имеет разрешение 128*64 точки, но ввиду особенностей чипа SSD1306 невозможно получить доступ к каждой точке отдельно. Что бы передать дисплею значение одной точки достаточно одного бита, но данные передаются байтами. Как вы помните, в одном байте — 8 бит, и байта достаточно для изменения значения сразу 8 точек одновременно (в данном случае эти 8 точек расположены в виде вертикального столбца). Поэтому всё поле дисплея по горизонтали разбито на страницы, в каждой странице 8 строчек. Столбцы же остаются столбцами. Итого 8 страниц и 128 столбцов, а значит для изменения значений всех 8192 пикселей на дисплее необходимо передать 1024 байта.

Получается, что одним байтом мы можем изменить значения столбца из 8 пикселей, и информация в столбец записывается сверху вниз. Что бы зажечь левый верхний пиксель дисплея, необходимо в первый столбец первой страницы (не забывайте что счет начинается с 0) записать значение 0х01.

Кроме самих данных, которые необходимо вывести на дисплей, необходимо так же отдавать команды дисплею. Что бы дисплей понял, какой байт является командой, а какой данными, предварительно посылается 0x00 для команд и 0x40 для данных. Причем посылать этот указатель надо каждый раз перед отправкой команд или данных. Команды могут состоять как из одного байта, так и из нескольких. И каждый байт команды посылается отдельно.

Перед вводом данных, необходимо выбрать область дисплея, в которую будет выводиться информация. Для этого необходимо подать команду выбора страниц, затем двумя командами задать начальное и конечное значения. Если информация должна выводиться в одной странице, то начальное и конечное значения должны совпадать. Аналогично и для столбцов. После выбора столбцов и страниц можно начинать передавать данные, и после ввода одного байта в память дисплея счетчик столбцов (или страниц, в зависимости от настроек. Но поскольку мы пишем слева направо сверху вниз, то я буду рассматривать вариант вывода данных на дисплей именно так – в каждую страницу информация записывается слева на право, при заполнении страницы данные выводятся на следующую страницу, которая находится ниже.) переключается на следующее значение.

Как я уже упоминал, для нас естественно писать слева направо сверху вниз и данные мы будем выводить так же. В даташите это называется горизонтальной адресацией.

Но предусмотрен и другой вариант: вывод данных сверху вниз слева направо (вертикальная адресация).

Так же предусмотрен совсем экзотический вариант: вывод данных в одной странице. Если данных вводится больше, чем вмещает страница (более 128 байт), то остальные данные игнорируются (постраничная адресация).

Перед выводом информации на дисплей необходимо произвести инициализацию дисплея. Процесс инициализации подробно описан в даташите, и даже в виде блок-схемы (извиняюсь за ватермарк, не знаю как избавиться от него в файлах pdf).

А теперь приведу пример скетча (написан в среде ArduinoIDE, но это не важно). Следите за комментариями, там подробные описания всех функций.

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

Список всех команд конечно же содержится в datasheet-е на дисплей, в том числе команды скроллинга, которые я не стал рассматривать. Даташит достаточно обширный, на 65 страниц. В нем конечно же не рассматриваются примеры работы с буфером.

И наконец, рассмотрим готовую библиотеку для ардуино.

Я нашел несколько библиотек для работы с данным дисплеем, и у каждой из них свои особенности:

  • OzOLED – поддерживает вывод изображений (bitmap), текста и цифр, а так же инверсию и скроллинг. Не поддерживает графические примитивы и содержит один шрифт. Проста в освоении, но мало функциональна.
  • U8glib – пожалуй самая универсальная библиотека для различных типов дисплеев, умеет многое, но сложна в освоении. Это связано в первую очередь с тем, что сразу не понятно, какая функция будет работать с определенным дисплеем (например, как поведет себя функция выбора цвета RGB на монохромных дисплеях).
  • OLED_I2C – самая удобная на мой взгляд библиотека. Поддерживает вывод изображений, текста и чисел, графических примитивов, имеет в своем составе несколько шрифтов, в том числе есть вариант библиотеки с русским и украинским шрифтами (количество шрифтов можно расширить) и имеет двойную буферизацию изображения (что одновременно и хорошо и плохо).

Итак… Библиотека OLED_I2C , довольно простая библиотека. Открываем keywords.txt и видим перечисление всех функций библиотеки. Так же открываем OLED_I2C.h чтобы посмотреть, какие аргументы может принимать та или иная функция.

Создадим каркас скетча.

Замечу, что не обязательно в начале каждого скетча настраивать яркость дисплея, по умолчанию яркость настраивается на максимум. Яркость дисплея можно установить в диапазоне 0-255. При этом 0 не означает что дисплей совсем не будет светиться, я вообще не заметил большой разницы в яркости дисплея.

Функция clrScr очищает на самом деле не дисплей, а буфер. А функция update переносит информацию из буфера в дисплей. У функции clrScr есть противоположная функция fillScr, которая зажигает все точки дисплея.

Предполагается, что исходным состоянием пикселя является не активное состояние, то есть пиксель погашен. В активном состоянии пиксель светится. Таким образом вся информация на дисплей выводится «белым по черному» (мой дисплей реально черно-белый, но встречаются черно-голубые и даже черно-желто-голубые). Но можно выводить информацию наоборот, «черным по белому». При этом у каждой функции, что вводит данные в буфер, есть инверсная функция. Я буду рассматривать их в паре. Кроме того сам дисплей поддерживает инверсию цвета, «черным по белому» можно выводить информацию всегда.

Начнем с графических примитивов. Все описания функций даны в комментариях.

Данный скетч демонстрирует все доступные графические примитивы и их инверсные аналоги (в скетче я не упомянул лишь одну функцию – invPixel(int x, int y), которая изменяет цвет пикселя на противоположный). Стоит уточнить, что начало координат находится в левом верхнем углу. Координата Х располагается вдоль длинной части дисплея и принимает значения от 0 до 127, координата У вдоль короткой (значения от 0 до 63).

Если ввести команду инверсии экрана сразу, например, в функции setup(), то все графические примитивы будут выводиться сразу черным по белому без неприятного моргания экрана.

Теперь задача посложнее – выведем изображение на экран. Для этого используем функцию drawBitmap. Рассмотрим пример из библиотеки, демонстрирующий вывод изображения.

Пример содержит два файла: собственно сам скетч OLED_I2C_Bitmap.ino и файл в котором хранятся изображения graphics.c. Я приведу немного урезанный пример, что бы не загромождать статью.

Содержимое файла graphics.c:

И содержимое самого скетча:

Можно вставить массив с изображением непосредственно в скетч, тогда скетч будет выглядеть так:

Читайте также  Как провести проводку для точечных светильников?

Теперь о том, как создать такой массив из изображения. Сперва изображение нужно создать, я сделал это в обычном «пейнте».

В свойствах изображения задал размер изображения и перевел программу в черно-белый режим.

Изображение сохранил в виде монохромного bmp-файла. Не обязательно переводить программу в монохромный режим, да и сохранить можно даже в jpeg, но результат перевода изображения в массив может быть непредсказуемым.

Далее необходимо использовать программу LCDAssistant. Что бы открыть изображение в меню выбираем File – Load image появившемся диалоговом окне выбираем необходимое изображение. Настройки в программе оставляем по умолчанию, размер устанавливается автоматически, остается ввести только имя массива в Table name. Далее File – Save output, в диалоговом окне вводим имя с расширением файла (я рекомендую расширение txt) и сохраняем файл. Из полученного файла необходим только массив, переносим его в скетч, не забывая поместить его в const uint8_t name[] PROGMEM=<…>; .

Несколько замечаний по выводу изображений на экран:

Отрицательные значения начала координат изображения (левый верхний угол изображения) допустимы, при этом изображение будет отображаться не полностью;

Отрицательные значения размера изображения не допустимы, изображение в этом случае не будет выведено на дисплей;

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

9

И наконец расскажу о выводе текста и цифр.

Шрифты содержатся в файле библиотеки DefaultFonts.c и представляют собой массив, так же как массив изображения. По сути в одном шрифте содержатся много изображений каждого символа шрифта.

Рассмотрим пример программы, выводящей текст, целые и дробные числа. Объяснение по каждой функции даны в комментариях.

Библиотека пригодится и тем, кто программирует микроконтроллеры в настоящих взрослых IDE, так как из библиотеки можно почерпнуть готовые алгоритмы как по работе с дисплеем, так и по работе с буфером.

Пожалуй на этом всё. Если описывать все возможности дисплея (например, скроллинг изображения), рассмотреть подробно работу с буфером, ввод в этот буфер графических примитивов, изображения и текста, то размер статьи будет превышать даже объем даташита. Для изучения всех этих возможностей рекомендую «поковырять» библиотеку OLED_I2C.

Как подключить OLED дисплей к Ардуино

OLED дисплей Arduino 0,96 дюйма позволяет создавать крутые проекты с экраном, при этом сохраняя миниатюрные размеры DIY устройства. Модули OLED на базе SSD1306 весьма популярны благодаря простому подключению к микроконтроллеру и высокому разрешению экрана – 128×64 пикселя. Рассмотрим характеристики OLED с I2C, подключение к Arduino и разберем команды библиотек: Adafruit_SSD1306 и OLED_I2C.

Arduino I2C OLED display подключение

OLED (Organic Light-Emitting Diode) — это полупроводниковый прибор, излучающий свет при прохождении через него электрического тока. Управление модулем осуществляет с помощью чипа SSD1306, который поддерживает пять разных протоколов связи. Встречаются модули не только с протоколом IIC, но и с протоколом SPI, и даже олед дисплеи с возможностью выбора (переключения) между этими двумя протоколами.

Характеристики OLED I2C 128×64 / 128×32

  • Цвет экрана — монохромный;
  • Разрешение — 128×64 или 128×32;
  • Графический чип — SSD1306;
  • Интерфейс — I2C или SPI;
  • Питание модуля — от 3 до 5 В;
  • Размер модуля — 27x27x4 мм.

Распиновка OLED SPI и дисплея OLED IIC

Главным плюсом OLED 128×64 iic является работа модуля без подсветки, за счет чего обеспечивается низкое потребление тока этим модулем. А высокое разрешение OLED 128×64 px Arduino позволяет вывести на дисплей большее количество информации, в отличии от текстового экрана 1602. Для подключения используется четыре разъема — два провода для питания (5V и GND) и два провода для шины IIC (SDA и SCL).

Подключение OLED I2C 128×64 к Arduino

Для этого занятия нам потребуется:

  • плата Arduino Uno / Arduino Nano / Arduino Mega;
  • lcd oled 128×32 / lcd oled 128×64;
  • провода «папа-мама».

Схема подключения OLED дисплея с i2c к Ардуино

OLED i2c 0,96 Arduino Uno Arduino Nano Arduino Mega
GND GND GND GND
VDD 5V 5V 5V
SDA A4 A4 20
SCL A5 A5 21

На изображении выше, показана схема подключения OLED I2C — разъемы SDA и SCL модуля подключаются к соответствующим пинам на микроконтроллере. У Arduino Uno и Nano SDA — пин A4, SCL — пин A5, а у Arduino Mega — 20 и 21 пин, соответственно. Питание модуля 3,3 или 5 Вольт. Далее рассмотрим две популярные библиотеки для работы с OLED SSD1306 — это библиотека OLED_I2C.h и Adafruit_SSD1306.h.

Библиотеки для OLED I2C 0,96 Arduino

Библиотека OLED_I2C.h позволяет менять шрифт текста (размер), выводить латинские и русские буквы на экран, а также позиционировать текст на дисплее (по левому и правому краю или по центру). В следующем скетче показано максимальное количество возможностей команд данной библиотеки с подробными комментариями. Подключите ОЛЕД дисплей, согласно схеме выше, и загрузите программу в плату Ардуино Уно.

Скетч. Библиотека OLED_I2C.h команды, описание

Пояснения к коду:

  1. библиотека использует много оперативной памяти микроконтроллера для загрузки шрифтов, поэтому работать с OLED дисплеем на плате Arduino Nano не получится. Скетч не загрузится из-за нехватки свободной памяти;
  2. ещё больше возможностей библиотеки можно узнать из стандартных скетчей.

Стандартные скетчи библиотеки OLED_I2C.h Arduino IDE

Еще одна библиотека, которая позволяет работать с дисплеем 0,96 по протоколу SPI и IIC, это Adafruit_SSD1306. В дополнении к этому вам потребуется еще установить библиотеку Adafruit_GFX. Все необходимые библиотеки вы можете скачать на нашем сайте — здесь. После установки необходимых файлов, вы сможете использовать команды библиотеки Adafruit_SSD1306.h для вывода текста на олед дисплей.

Скетч. Библиотека Adafruit_SSD1306.h команды

Пояснения к коду:

  1. адрес устройства — 0x3C, можно узнать с помощью программы для сканирования шины I2C микроконтроллера Ардуино;
  2. display.setTextSize(1, 2); в этой строчке можно указывать два параметра — первая цифра задает размер шрифта, а вторая высоту шрифта.

Кириллица, русский шрифт OLED I2C 128×64

Для вывода русских букв следует использовать библиотеку OLED_I2C.h, подключив русский шрифт в программе. В следующем скетче реализована возможность вывода бегущей строки с помощью цикла for Arduino IDE. Кроме того, с помощью библиотек, рассмотренных на этой странице, на олед экран можно выводить различные картинки и логотипы с прокруткой по вертикали или по горизонтали олед дисплея.

Скетч. Русификация дисплея OLED I2C Arduino

Пояснения к коду:

  1. переменная i в цикле for меняет положение надписи в строке от 128 до -40 пикселей (если надпись будет длиннее то нижний диапазон нужно увеличить);
  2. минусом библиотеки является то, что некоторые символы будут тоже переводиться в русские буквы, например, «точка» превратится в букву «ю».

Заключение. Мы постарались наиболее полно рассмотреть схему подключения OLED 0,96 к Ардуино и разобрать команды библиотек для экрана. Рассказать обо всех возможностях работы с OLED в одном обзоре довольно сложно. Вы можете изучить эту информацию на основе примеров из архива с библиотеками самостоятельно. Если у вас остались вопросы по теме — пишите их в комментариях к этой записи.

Как подключить OLED I2C дисплей к ARDUINO

Привет! Будучи любителем — энтузиастом электроники, я уверен, что всё что мы делаем – радиоэлектронные игрушки – самоделки, или большие проекты, все это от любопытства и лени. Любопытство стремится понять и постичь необъятное, не познанное, разобраться, как оно там работает, чего делает, как двигается. А лень изобретает, чтобы такого придумать, чтобы не вставать, не подходить, не поднимать, не запачкаться или еще чего ни будь важное.

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

Для тех, у кого тоже возникло подобное желание, — вот краткое руководство по подключению и проверке маленьких и не дорогих дисплеев OLED.
Далее речь пойдет об одной из широко доступных для радиолюбителей моделях OLED дисплеев, управляемых чипом SSD1306, с размером экрана 0,96-дюймов и разрешением 128*64 или 128*32 точки. Эти дисплеи идеально подходят для не больших радиолюбительских конструкций и самоделок.

Шаг 1: Основные понятия

Шаг 2: Комплектующие

Шаг 3: Подключение дисплея

Шаг 4: Сканер I2C

Каждое устройство на шине I2C имеет шестнадцатеричный адрес, поменять нельзя, он вшит намертво, каждый ответственный производитель должен где-то на корпусе или в инструкции указать его. Бывают модули с переключателями и перемычками, которыми можно изменить адрес, но… если устройства дешевые, до безобразия, то производитель может и не удосужиться заниматься такой мелочью, поэтому его придется определять самостоятельно.

Читайте также  Какая проводка нужна для духового шкафа?

Всего на шине может использоваться до 127 адресов — 119 для устройств и 8 адресов служебных. Общение ведется по этим адресам. Есть главный, он же Master, а есть ведомый, он же Slave, — Мастера запрашивают, ведомые отвечают, все просто.
Поскольку на нашем OLED-дисплей используется протокол связи I2C, а адрес может быть и не указан, мы сами попробуем узнать этот самый адрес.

Это можно сделать, загрузив коротенький скетч на свою плату Arduino с подключенным OLED. НО!
Не торопитесь сразу заливать скетч в Arduino! Давайте для начала загрузим «драйвера», т.е. подключим библиотеки, а для этого сразу перейдем к «Шагу №5», а затем вернемся и продолжим.

Шаг 4: Продолжение:

Шаг 5: Загрузка и подключение библиотек

Шаг 6: Тестирование дисплея

Откройте файл Adafruit_SSD1306.h в текстовом редакторе и найдите строки:

Должно получиться так:

Если снова ошибка – необходимо проверить правильность соединений.
После окончания загрузки вы увидите тестовую анимацию на экране, это означает, что вы успешно настроили свой OLED дисплей.

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

Шаг 7: Пишем свое собственное сообщение

Для написания собственного сообщения, сначала создадим новый скетч в среде программирования ArduinoIDE.
В заголовке мы подключаем 4 библиотеки:

Затем пишем протокол сброса:

В VOID SETUP указываем шестнадцатеричный адрес нашего дисплея 0x3C, который мы узнали на «Шаге №4».
Затем, инициализируем дисплей и очищаем его:

Далее в VOID LOOP пишем основной код, то есть наше сообщение, которое хотим отобразить на дисплее.
Для этого описываем размер текста, цвет текста, позицию курсора, и наконец, выводим сообщение с помощью команды println:

Oled i2c дисплей 128х64 пикселя

Работа с OLED дисплеем 128х64 на SSD1306 с управлением по I2C

Автор: rozorh
Опубликовано 23.02.2017
Создано при помощи КотоРед.

Здравствуйте, уважаемые коты, кошечки и котята.

В этой статье я хочу рассказать о маленьком, но весьма интересном, на мой взгляд, OLED дисплее 128х64 на SSD1306 с управлением по I2C. На незабвенном Ali его почему-то называют дисплеем для Arduino.

Cразу оговорюсь: я не писал для него никаких библиотек, но внизу статьи вы найдёте исходник с некоторым количеством комментариев, которые помогут обойти потенциальные «грабли», оставившие незабываемые впечатления на моём лбу при изучении работы этого чуда.

А выглядит оно вот так:

Yellow Blue означает, что в нём присутствуют два соответствующих, жёстко привязанных к областям вывода на экран, цвета. Если за верхнюю часть дисплея принять область, расположенную рядом с пинами подключения питания и интерфейса связи, то в верхнюю ¼ дисплея вывод информации будет осуществляться жёлтым цветом, а в нижние ¾ дисплея, соответственно, синим.

Но это так, приятное дополнение. Что же меня в нём действительно подкупило, так это управление по I2C и нужные мне габариты: небольшой экран размером 0.96” (что при замере линейкой даёт периметр в 25х15 мм), смонтированый на плате 26х26 мм.

Соответственно, подключение простейшее:

Ценник тоже приятно удивил: с доставкой они (а заказывал я шесть штук у разных продавцов) обошлись около 180 руб./шт., хотя говорят, что можно найти и дешевле.

Из даташита на SSD1306 мы узнаём, что, во-первых, адресом устройства на шине может быть или 0111100 или 0111101, в зависимости от того, как настроено оборудование в сборочном подвале у Дядюшки Ляо. Пять из полученных мною модулей откликаличь на адрес 0111100 – я так понимаю, что это самый распространённый вариант распайки, шестой отозвался на 0111101.

Вообще же в даташите алгоритм работы с этим дисплеем расписан весьма своеобразно. В режиме I2C это выглядит вот так:

С первого взгляда всё логично и, вроде бы, понятно: сначала выдаём старый добрый СТАРТ, потом байт со Slave-АДРЕСом (0111100 или 0111101) дополненный нулём в младшем бите (потому что мы ничего не будем читать из дисплея, а будем только передавать ему команды или данные). Потом принимаем бит ACK подтверждения от дисплея… А потом отсылаем некий CONTROL BYTE, содержащий всего два возможных для изменения бита: 7-й ”Cо” и 6-й “D/C” (остальные всегда нули), которые изрядно попортили мне кровь, пока я разобрался, как себя с ними вести.

Вот, что мы можем почерпнуть про них из даташита:

The D/C# bit determines the next data byte is acted as a command or a data. If the D/C# bit is set to logic “0”, it defines the following data byte as a command. If the D/C# bit is set to logic “1”, it defines the following data byte as a data which will be stored at the GDDRAM. The GDDRAM column address pointer will be increased by one automatically after each data write. If the Co bit is set as logic “0”, the transmission of the following information will contain data bytes only.

Если коротко, то “D/C” может быть единицей или нулём. Первый вариант говорит дисплею, что в СЛЕДУЮЩЕМ БАЙТЕ мы собираемся передать ему данные для отображения на экране, второй – что в СЛЕДУЮЩЕМ БАЙТЕ мы будем передавать какую-то команду, т.е. собираемся им (дисплеем) управлять.

Бит “Со” равный нулю сообщает ему же, что ВСЕ СЛЕДУЮЩИЕ БАЙТЫ пойдут потоком в виде данных для вывода на экран. И всё бы хорошо, но нет ни слова о варианте, в котором этот бит мог бы быть равным единице. А такой вариант существует. И не один – их на самом деле целых два, а вот вариант с нулём оказался единственным.

В моём исходнике все три варианта определены через дефайны, как COM (СЛЕДУЮЩИЙ БАЙТ будет командой), DAT (СЛЕДУЮЩИЙ БАЙТ будет данными) и DATS (ВСЕ СЛЕДУЮЩИЕ БАЙТЫ будут данными):

#define COM 0b10000000
#define DAT 0b11000000
#define DATS 0b01000000

Итак, если мы хотим передать в дисплей команду, т.е. изменить в нём какие-либо настройки, провести инициализацию и т.п., то после бита подтверждения ACK нам необходимо отослать контрольный байт 0b10000000 (COM), после чего, получив ещё один ACK, нашу команду, а затем вновь дождаться подтверждения ACK. Соответственно, если нам необходимо последовательно передать несколько команд, то нам придётся «крутиться» по этому же алгоритму: COM, ACK, , ACK, … и т.д. до бесконечности.

Теперь о передаче данных для вывода на экран: если мы хотим передать в дисплей ОДИН БАЙТ данных, то в качестве контрольного байта необходимо отослать 0b11000000 (DAT), а затем работать по аналогии с алгоритмом выше – DAT, ACK, , ACK, … и т.д. Однако, если нам необходимо передать целый массив данных, тогда в качестве контрольного байта мы будем отсылать уже 0b01000000 (DATS), а затем поочерёдно все данные, что мы хотим увидеть на экране, т.е. DATS, ACK, , ACK, , ACK, … и т.д. Здесь необходимо обратить внимание на то, что если после передачи последнего байта из этого массива мы вновь захотим передать какую-либо команду, нам будет необходимо отправить СТОП, после чего начать общение, что называется, с нуля – СТАРТ, АДРЕС+0, ACK, и т.д.

Байты, отосланные в дисплей, выводятся на экран последовательными вертикальными столбцами младшим битом сверху, приращение счётчика колонки вывода и переход на новую страницу/строку ведётся автоматически. Вообще о режимах вывода данных на дисплей в даташите написано хорошо и с картинками, поэтому на них останавливаться не буду, если что – настройка прокоментирована в исходнике в разделах «Очистка экрана дисплея» и «Последовательный вывод цифр от 1-го до 5-ти».

Отдельно следует затронуть вопрос инициализации. Для её проведения необходимо передать в дисплей следующую абракадабру:

СТАРТ, АДРЕС+0, 0x80, 0xA8, 0x80, 0x3F, 0x80, 0xD3, 0x80, 0x00, 0x80, 0x40, 0x80, 0xA1 , 0x80, 0xC8 , 0x80, 0xDA, 0x80, 0x12, 0x80, 0x81, 0x80, 0x7F , 0x80, 0xA4, 0x80, 0xA6, 0x80, 0xD5, 0x80, 0x80, 0x80, 0x8D, 0x80, 0x14, 0x80, 0xAF, СТОП

Не забывайте про бит подтверждения ACK после каждого байта (считайте, что вместо каждой запятой – кроме запятой после СТАРТ – в последовательности выше нужно вставить бит ACK).

Байты, отмеченные синим, определяют формат вывода информации на экран:
• 0х7F – яркость свечения пикселей (максимум задаётся 0xFF);
• 0хA1 – данные выводятся слева направо, 0хA0 – справа налево;
• 0хC8 – данные выводятся построчно сверху вниз, 0хС0 – снизу вверх (где у экрана условный верх мы разбирали раньше).

Т.о., заменив одновременно 0хA1 на 0хA0 и 0хC8 на 0хC0 мы получим разворот изображения на дисплее на 180 градусов, при этом области вывода жёлтым и синим цветом всё равно останутся там же, где и были (((

Если при подаче питания выключатель сильно «дребезжит», до начала инициализации дисплея рекомендую выждать

И пару слов о uC — это AVR ATtiny2313 с заводской установкой фьюзов.

Общаемся с дисплеем SSD1306 по i2c

Все любители электронных самоделок когда-нибудь приходят к желанию отобразить работу своей поделки самоделки на экране в виде текста или графики. Самый бюджетный способ сделать это — обратиться к алфавитно-цифровому дисплею типа LCD1602 или LCD2004, общение с которыми происходит либо по параллельному интерфейсу, либо через переходник-конвертор в I2C. Второй способ — использовать графический дисплей, их множество, например SSD1306 с размером матрицы 128×64 пикселя. Он есть в двух вариантах, с интерфейсом SPI или I2C. Я буду взаимодействовать с таким дисплеем через I2C интерфейс (он же TWI).

Читайте также  Как рассчитать какой автомат нужен на проводку?

Рисунок 1.- графический LCD дисплей SSD1306 с матрицей 128×64 пикселя

Сначала подаем команду старт

Передаем адрес дисплея SLA+W

Дальше идет m слов содержащих всевозможные настройки дисплея

Передается признак того, что дальше пойдут графические данные (1 байт) и собственно данные n байт.

Передача каждого байта устанавливает статус ACK.

Рисунок 2.- формат пакета данных для дисплея

Инициализация модуля

Вот последовательность действий для инициализации графического дисплея

Отправляем дисплей в SLEEP MODE (команда 0xAE SSD1306_DISPLAYOFF)

Установка делителя частоты (команда 0xD5 SSD1306_SETDISPLAYCLOCKDIV) параметр 0x80

Устанавливает отношение мультиплексирования (команда A8 SSD1306_SETMULTIPLEX) параметр 0x3F

Устанавливаем смещение дисплея (команда 0xD3 SSD1306_SETDISPLAYOFFSET) параметр 0x00

устанавливаем начальную линию (команда 0x40 SSD1306_SETSTARTLINE|0x00)

разрешаем charge pump (команда 0x8d SSD1306_CHARGEPUMP) параметр 0x14

устанавливаем горизонтальный режим памяти (команда 0x20 SSD1306_MEMORYMODE) параметр 0x00.

устанавливаем remapping столбцов seg0←→seg127 (команда 0xA0 SSD1306_SEGREMAP | 0x00)

устанавливаем направление сканирования строк (команда 0xС8 SSD1306_COMSCANDEC)

Устанавливаем конфигурацию выводов COM-сигналов в соответствии с компоновкой оборудования OLED — панели (команда 0xDA SSD1306_SETCOMPINS) параметр 0x12

Устанавливаем контраст (команда 0x81 SSD1306_SETCONTRAST) параметр 0xCF

Установка предзаряда (команда 0xD9 SSD1306_SETPRECHARGE) параметр 0xF1

Установка Vcomp deselect level (команда 0xDB SSD1306_SETVCOMDETECT) параметр 0x40

Возобновление отображения содержимого оперативной памяти (команда 0xA4 SSD1306_DISPLAYALLON_RESUME)

Отображение в нормальном виде команда 0xA6 SSD1306_NORMALDISPLAY

Включение дисплея в нормальном режиме команда 0xAF SSD1306_DISPLAYON

Ниже на рисунке 3 приведена ассемблерная подпрограмма инициализации дисплея

Рисунок 3.- Подпрограмма инициализации дисплея

LCD_Command — это макрос следующего вида:

Рисунок 4.- Исходный код макроса отправки коммады в LCD

Этот макрос сделан для удобства использования подпрограммы _LCD_Command. Дело в том, что параметры передаются в нее через регистры tmp1 и tmp2 и запись LCD_Command par1, par2 более естественна, чем три строчки из макроса. Стоит заметить, что и макрос и вызов подпрограммы с передачей параметров занимают одинаковое число тактов процессора и объем ROM.

Что же представляет собой подпрограмма _LCD_Command мы посмотрим на рисунке 5.

Рисунок 5.- код подпрограммы _LCD_Command

Как видно, это подпрограмма посылает управляющее слово (см рисунок 2) по I2C. Подпрограмма использует 3 регистра tmp0, tmp1 и tmp2. В двух последних передаются параметры для подпрограммы ControlByte и DataByte.

Подпрограммы i2c_start, i2c_stop, i2c_send рассмотрены в этой статье.

В нашей реализации подпрограмма инициализации дисплея занимает 152 байта. Этот размер можно уменьшить, если обратить внимание на то, что ControlByte у всех команд, отправляемых в экран равен COMMAND. Как минимум, можно переписать макросы таким образом, чтобы лишний раз не обновлять регистр tmp1.

Очистка экрана (заливка определенным паттерном)

Что такое очистка экрана — это всего лишь заполнение видеопамяти символами определенного качества, в нашем случае это заполнение каждого сегмента страницы видеопамяти графического модуля нулями. Нижеприведенный код подпрограммы будет актуален только при использовании MEMORY_MODE = 0x00 или 0x01.

Рисунок 6.- исходный код подпрограммы очистки экрана

Мы передаем по I2C DATA байты в количестве 128×64 = 8192. Каждый переданный байт определяет тип очистки. Если передается 0 — экран очищается, если 0xFF— заливается цветом. Подпрограмма состоит из двух вложенных циклов по страницам памяти (8) и по количеству сегментов (128).

Для удобства использования подпрограмма также была завернута в макрос (рисунок 7)

Рисунок 7.- Макрос очистки экрана.

Позиционирование

Рассмотрим теперь позиционирование на экране. Несмотря на то, что у нас дисплей 128×64 пикселя, адресовать номер страницы памяти и номер столбца. Каждая страница памяти это 8 строк. Поэтому, если мы хотим зажечь, допустим, 15 пиксель в 10 строке, мы должны выбрать 1 страницу памяти, в ней выбрать 15 сегмент и по этому адресу записать 4 (бинарное 0000 0100).

Выбор номера страницы памяти осуществляется командами B0-B7, или B0 | y.

Чтобы установить номер столбца, стачала нужно записать в шину последнюю (младшую) шестнадцатиричную цифру числа, затем первую (старшую).

Таким образом, позиционирование выльется в посылке 3 посылки по шине TWI (рисунок 8)

Рисунок 8.- Макрос позиционирования

В этом макросе мы устанавливаем маркер текущего положения курсора в позицию (x,y), а также присваиваем соответствующие значения переменным LCD_X, LCD_Y.

Еще один неопределенный макрос SETMEM как раз и занимается сохранением данных в памяти.

Рисунок 9.- макрос сохранения числа в память SRAM

Обзор OLED-дисплея 0.96,128х64 на SSD1306

Автор: Сергей · Опубликовано 03.02.2017 · Обновлено 13.04.2020

OLED — дисплей являются одним из самых привлекательным и современным дисплеем, при небольших размерах и незначительном энергопотребление OLED дисплей, обеспечивает насыщенную контрастность. Дисплеи в основном доступны на чипе SSD1306, работающим на интерфейсе I2C, для работы которого необходимо только 2 провода, что позволяет быстро подключить и начать использовать. В этом статье расскажу, как подключить OLED дисплей, диагональю 0.96 дюйма и расширением 128 х 64 пикселя.

Технические параметры

► Технология дисплея: OLED
► Разрешение дисплея: 128 на 64 точек
► Диагональ дисплея: 0,96 дюйма
► Уол обзора: 160°
► Напряжение питания: 2.8 В

5.5 В
► Мощность: 0,08 Вт
► Габариты: 27.3 мм х 27.8 мм х 3.7 мм

Общие сведения OLED дисплея

А что же такое, технология OLED? Расшифровывается как Organic Light-Emitting Diode, состоит дисплей из большого числа органических светодиодов, главное отличие от LCD дисплея, в том, что каждый светодиод светится сам и не нуждается в отдельной подсветки. Благодаря этому, дисплей обладает значительными преимуществом по сравнению с обычными LCD, такими как контрастностью, углом обзора и малая потребляемая мощность, конечно есть и недостатки, небольшой срок службы и дороговизна.

OLED модуль с расширением 128×64 (0.96 дюйма) состоит из двух частей, из самого дисплея, который в свою очередь можно разделить на две части, графический дисплей и контроллер SSD1306 от которого идет гибкий шлейф на обратную сторону платы. Вторая часть, модуля, представляет собой печатную плату (которая по сути является переходником), на которой установлена минимальная электрическая обвязка, однорядный разъем шаг 2.54 мм и четырьмя крепежными отверстиями.
OLED модули, выпускаются с различным расширением 128×64, 128×32 и 96×16 (в статье и примере используется дисплей с расширением 128×32), сам контроллер SSD1306 может работать с OLED матрицами с максимальным расширение 128×64, так-же, модули бывают белые, синие и сине-желтые (сверху, желтая полоса, шириной 15 пикселя). Каждый производитель, выпускают свою печатные плату с различной компоновкой электронных компонентов и выведенным интерфейсом, так-как контроллер SSD1306 поддерживает сразу три протокола работы:

► 8-bit 6800/8080-series parallel interface
► 3 /4 wire Serial Peripheral Interface
► I2C

Для изменения протокола работы, предусмотрены три линии BS0, BC1 и BS2 с помощью которых, контроллер дисплея определяет по какому протоколу ему работать. В моем случаи, OLED дисплей разработан для работы по одному протоколу I2C, в других вариантов, возможно смена протокола работы с помощью нулевых резисторах или DIP переключателей.

Ниже приведена принципиальная схема OLED дисплея на микросхеме SSD1306, работающая по интерфейсу I2C, из нее видно, что микросхема U2 выполняет функцию стабилизатора напряжение (3.3В), конденсатор C8 необходим для сглаживания выходного напряжения. Резисторы R6 и R7 выполняют функцию подтяжки линии SCL и SAD, если к шине I2C, подключено не одно устройство, необходимо использовать подтягивающие резисторы только на одном устройстве. С помощью резистора на 0 Ом (без обозначении), можно произвести смену адреса 0x78 или 0x7A.

Назначение контактов J2:
► SCL: линия тактирования (Serial CLock)
► SDA: линия данных (Serial Dфta)
► VCC: «+» питание
► GND: «-» питание

Подключение к Arduino

Необходимые детали:
► Arduino UNO R3 x 1 шт.
► OLED-дисплей 0.96,128х64, 3.3-5B, SPI, IIC, синий x 1 шт.
► Провод DuPont, 2,54 мм, 20 см, F-M (Female — Male) x 1 шт.
► Кабель USB 2.0 A-B x 1 шт.

Подключение:
В примере буду использовать плату Arduino UNO R3 и OLED дисплей (расширением 128×64), как говорил ранее, используемый интерфейс I2c, для подключения необходимо всего два провода, подключаем SDA дисплея к выводу A4 (Arduino), а SCL к выводу A5 (Arduino). При использовании, других платформ Mega или Nano необходимо использовать другие порты, для удобства приведу таблицу, подключения для различных плат. Далее, необходимо подключить питание, GND к GND, а VCC к 5 В или 3.3В, схема собрана, теперь осталось загрузить скетч.

Для работы с OLED дисплеем необходима библиотека, так-как библиотек несколько, пример работы покажу через библиотеку OLED_I2C (скачать библиотеку можно в конце статьи)
Программа только отображает текст на дисплей и больше не какого функционала не несет, скачиваем скетч и загружаем ее в плату Arduino UNO R3.