Категории публикаций
Подписка на рассылку по Email
новости (подписчиков: 4)
комментарии (подписчиков: 2)

Отменить подписку
Популярные публикации
Интересный опрос
Какую платежную систему вы предпочетаете?

Счет в Банке
Webmoney
PayPal
BitCoin и другие криптовалюты
okPay
ePayServices
AdvCash
Ее нет в списке
Поблагодарить автора
donate
1B4ZZ2PXUd9E7AqEB82AqFnkpk2bt5hQG7

OLED дисплей SSD1306 (128х64px) и Raspberry Pi, подключение и эксперименты

Размещено в категории: Железо

Рассмотрены примеры работы с маленьким (128х64 пикселей) и экономичным OLED-дисплеем на основе микросхемы SSD1306. Для управления использована платформа Raspberry Pi, а программы будем писать на языке Python.

Приведу примеры кода для вывода на экран строчки текста, рисунков в формате PNG, а также проведу небольшой практический эксперимент с отображением на экране значения от датчика качества воздуха.

Содержание статьи:

  1. Дисплей на основе SSD1306 и что такое OLED
  2. Принципиальная схема
  3. Подключение дисплея
  4. Библиотека для работы с SSD1306 на Python
  5. Выводим текст на экран
  6. Используем внешний TrueType шрифт (TTF)
  7. Отображаем символы кириллици (TTF)
  8. Рисуем геометрические фигуры
  9. Отображаем рисунки
  10. Подготовка рисунков
  11. Индикатор качества воздуха
  12. Заключение

Дисплей на основе SSD1306 и что такое OLED

SSD1306 - это название универсальной микросхемы-контроллера, на основе которой построены миниатюрные, экономичные OLED-дисплеи.

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

В магазинах электронных компонентов можно найти достаточно много разных дисплеев которые построены на данной микросхеме. В данной статье я буду рассматривать дисплей с разрешением 128х64 пикселей (0,96 дюйма) и шиной для управления - I2C.

Экономичный OLED дисплей 128х64 пикселей на SSD1306 с шиной I2C

Рис. 1. Экономичный OLED дисплей 128х64 пикселей на SSD1306 с шиной I2C.

Основные характеристики дисплея:

  • Драйвер - SSD1306;
  • Размер экрана - 0.96' (дюйма);
  • Тип экрана - OLED;
  • Разъем для подключения - 4-pin (IIC+питание);
  • Напряжение питания - от 3,3В до 5В;
  • Потребляемый ток на один пиксель - 100 мкА;
  • Общий потребляемый, максимальный ток - примерно 15 мА;
  • Разрешение матрицы дисплея - 128x64 пикселей;
  • Угол обзора - более 160 градусов;
  • Размеры - 11x27x27мм (толщина без разъема - 4мм);
  • Вес - 4 грамма;
  • Рабочая температура - от –30 до +70 градусов по Цельсию.

Приобретенный мною дисплей - двухцветный (синий+желтый), верхняя часть (15 пикселей) светится желтым цветом, а остальная часть дисплея - синим. При покупке такого дисплея нужно быть внимательным, поскольку из описания можно подумать что в нем каждый пиксель может светиться двумя разными цветами, но это не так. К тому же двухцветная модель немного дороже одноцветной.

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

Принципиальная схема

Ниже приведена принципиальная схема модуля с дисплеем SSD1306. Из схемы видно что на плате размещен сам дисплей, микросхема-стабилизатор напряжения (3,3В), а также несколько конденсаторов и резисторов для обвязки.

Резисторы R6 и R7 - подтягивающие для шины I2C. Если вы подключаете к шине несколько устройств то нужно оставить подтягивающие резисторы только на одном устройстве, а на остальных - выпаять. К примеру на платке с дисплеем можно резисторы оставить. а на всех остальных устройствах - выпаять! Об этой особенности я уже рассказывал в статье где мы знакомились с шиной I2C.

Принципиальная схема модуля SSD1306

Рис. 2. Принципиальная схема модуля SSD1306.

Подключение дисплея

Для подключения дисплея к устройствам и управления отображением информации на нем используется шина I2C (4 провода - VCC, GND, SDA, SCL), о том как работать с этой шиной я писал в статье по ADC-DAC PCF8591.

Адрес дисплея на шине I2C по умолчания - 0x3c. Для подключения к одной шине двух таких дисплеев нужно задать им разные адреса, сделать это можно перепаяв перемычку (резистор) на плате дисплея под названием "IIC ADDRESS SELECT".

В моем варианте адреса на обратной стороне указаны не верно (привет китайцам): 0x78 и 0x7A, в реальности дисплей имеет адрес 0x3c, в этом можно убедиться подключив его к Raspberry Pi и просканировав устройства на шине при помощи команды "i2cdetect". После перепайки перемычки нужно будет определить новый реальный адрес, это может быть 0x3d или другой.

Для подключения трех и более таких дисплеев (или других устройств с одинаковым адресом) на одну шину I2C можно использовать I2C-мультиплексоры (I2C Multiplexers/Switches), например микросхему PCA9540BD или другие с нужными параметрами и количеством каналов.

Ниже приведена простая схема подключения дисплея к Raspberry Pi 2, для питания используем пин 1 (3,3В).

Схема подключения дисплея SSD1306 к Raspberry Pi2 по шине I2C

Рис. 3. Схема подключения дисплея SSD1306 к Raspberry Pi2 по шине I2C.

Библиотека для работы с SSD1306 на Python

Для экспериментов с дисплеем мы напишем несложные программы на языке Python, будем использовать готовые библиотеки написанные разработчиком Ричардом Халом (Richard Hull).

Первым делом создадим временный каталог для наших экспериментов:

mkdir ~/Temp && cd ~/Temp

Библиотеки для работы с SSD1306 на Python можно скачать из репозитория - https://github.com/rm-hull/ssd1306. Также можно сделать локальный клон репозитория, для этого должен быть установлен GIT.

Выполним приведенные ниже команды на raspberry Pi и произведем установку GIT в Debian/Ubintu GNU Linux (Raspbian), создадим новый каталог и локально склонируем в него репозиторый:

apt-get install git
mkdir ~/Temp/ssd1306
git clone https://github.com/rm-hull/ssd1306 ~/Temp/ssd1306

В приведенных ниже примерах мы не будим устанавливать в систему данную библиотеку. По сути, для использования в наших примерах нам нужны только два файла device.py и render.py, а также установленная библиотека Pillow (для работы с изображениями) для Python.

Чтобы проверить установлен ли модуль Pillow для Python в операционной системе нашего Raspberry Pi, выполним следующую команду, подключившись для этого к малинке по консоли:

sudo pip list | grep Pillow

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

sudo pip install Pillow

Теперь скопируем в текущую директорию (~/Temp) из недавно склонированного репозитория файлы device.py и render.py. Для этого выполним две команды:

cp ~/Temp/ssd1306/oled/device.py ~/Temp
cp ~/Temp/ssd1306/oled/render.py ~/Temp

Теперь все готово к проведению экспериментов!

Выводим текст на экран

В первом эксперименте с дисплеем SSD1306 мы выведем текст "Hello World" в двух строчках - сверху и по середине экрана. Откроем для редактирования новый файл:

nano ~/Temp/ssd1306_text_hello_wolrd.py

Скопируем в окно редактора следующий код:

#!/usr/bin/env python
# "Hello World" for display SSD1306 in Raspberry Pi
# 2016 https://ph0en1x.net

from device import ssd1306
from render import canvas
from PIL import ImageFont

device = ssd1306(port=1, address=0x3C) # for RPi rev 2 port(smbus) = 1
font = ImageFont.load_default()

with canvas(device) as draw:
    draw.text((10, 0), "*** Hello World ***", font=font, fill=255)
    draw.text((20, 30), "Hello World! :)", font=font, fill=255)

Выходим из редактора (Ctrl+X) и сохраняем файл (Y и Ентер), после этого можем запустить программу и посмотреть результат:

python ~/Temp/ssd1306_text_hello_wolrd.py

В результате дисплей должен "ожить" и на нем появятся строчки с приветствием:

Результат работы программы hello_world для ssd1306

Рис. 4. Результат работы программы hello_world для ssd1306.

Код программы не сложный, всю основную "низкоуровневую" работу выполняют библиотеки и модуль Pilow, поэтому расскажу кратко. Сначала мы импортируем класс ssd1306 (для работы с дисплеем по шине I2C) из модуля device (файл deice.py), потом из модуля render (файл render.py) импортируем класс canvas (для подготовки области вывода на дисплей), оба файла должны лежать в одной директории с файлом программы. Также из библиотеки PIL (Pillow, установлена в системе) импортируем ImageFont для работы со шрифтами.

Теперь выполним инициализацию устройства "device = ssd1306(port=1, address=0x3C)", указав его адрес (0x3C) и адрес шины I2C (1 - для Raspberry Pi rev2, 0 - для rev1).

Для рисования выполним подготовку шрифта "font = ImageFont.load_default()" - здесь используется шрифт по умолчанию (позже в примерах мы попробуем использовать свой шрифт).

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

Если более детально, то в приведенном примере "draw" является экземпляром класса ImageDraw библиотеки Pillow, в котором уже содержится набор методов для рисования различной 2D-графики. Этот экземпляр нам подготовлен и передан из класса canvas (модуль render.py).

Строчкой кода "draw.text((10, 0), "*** Hello World ***", font=font, fill=255)" мы готовим к выводу текст "*** Hello World ***" в координатах экрана x=10, y=0 и с заполнением - 255 (если 0 - то не отображается).

В следующей строчке кода мы готовым к выводу еще одну строку текста, задаем ей координаты так чтобы она была помещена примерно по центру.

Используем внешний TrueType шрифт (TTF)

Для следующей демонстрации мы скопируем из репозитория файл со шрифтом "C&C Red Alert [INET].ttf", выполним команду:

cp ~/Temp/ssd1306/fonts/C\&C\ Red\ Alert\ \[INET\].ttf ~/Temp/ra.ttf

В директории ~/Temp появится файл с названием "ra.ttf".

Теперь модифицируем немного предыдущую программу таким образом, чтобы текст по середине дисплея выводился с использованием шрифта из файла "ra.ttf" и был покрупнее в размере.

Создадим новый файл для этого эксперимента:

nano ~/Temp/ssd1306_text_hello_wolrd_font_ra.py

Поместим в редактор код для новой программы:

#!/usr/bin/env python
# "Hello World" for display SSD1306 in Raspberry Pi using TTF Font
# 2016 https://ph0en1x.net

from device import ssd1306
from render import canvas
from PIL import ImageFont

device = ssd1306(port=1, address=0x3C) # for RPi rev 2 port(smbus) = 1
font = ImageFont.load_default()
font_ra = ImageFont.truetype('ra.ttf', 20)

with canvas(device) as draw:
    draw.text((10, 0), "*** Hello World ***", font=font, fill=255)
    draw.text((20, 30), "Hello World! :)", font=font_ra, fill=255)

Выходим из редактора и сохраняем изменения. Здесь мы при помощи метода "ImageFont.truetype" подгрузили шрифт из файла "ra.ttf" , а потом указали при подготовке текста что нужно использовать экземпляр этого шрифта "font=font_ra".

Запускаем программу:

python ~/Temp/ssd1306_text_hello_wolrd_font_ra.py

Результат работы программы:

Текст на дисплее ssd1306 с использованием шрифта TTF

Рис. 5. Текст на дисплее ssd1306 с использованием шрифта TTF. Фото получилось размытое, экран достаточно контрастный и сфокусировать камеру было очень не просто.

Отображаем символы кириллици (TTF)

Как оказалось, здесь также нет ничего сложного - используем нужный шрифт с поддержкой кириллици, а также несколько хитростей при работе с кодом на Python.

Где взять подходящий шрифт? -Вот два источника со свободными шрифтами (для верстки, типографии, дизайна, разных поделок и т.п.):

Качаем понравившийся шрифт, распаковываем архив и используем нужный *.ttf файл.

Для примера: заходим на страничку со шрифтами от Гугла, справа в выпадающем списке "Languages" выбираем - "Cyrillic", нам ведь нужно чтобы шрифт поддерживал кириллицу. Выбираем понравившийся шрифт, жмем "Select this font" - снизу видим уведомление что шрифт выбран, жмем на это уведомление - всплывет окно, сверху справа будет иконка при нажатии на которую можно будет скачать весь пак со семейством шрифтов.

В примере ниже я использовал Open Sans - из архива извлек OpenSans-Regular.ttf. Шрифт должен лежать рядом с файлом программы, а также рядом с файлами device.py render.py (все в одной папке). Для размещения файла со шрифтом в другой директории в коде придется прописать полный путь к файлу.

Создадим новый файл для этого эксперимента:

nano ~/Temp/ssd1306_text_hello_wolrd_font_cyrillic.py

Код программы для вывода кириллици на дисплей SSD1306:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# "Hi, friend" program for display SSD1306 in Raspberry Pi using cyrillic TTF Font
# 2016 https://ph0en1x.net

from device import ssd1306
from render import canvas
from PIL import ImageFont

device = ssd1306(port=1, address=0x3C) # for RPi rev 2 port(smbus) = 1
font = ImageFont.load_default()
font_ra = ImageFont.truetype('OpenSans-Regular.ttf', 12)

with canvas(device) as draw:
    draw.text((5, 0), "*** Hi, friend! ***", font=font, fill=255)
    draw.text((0, 30), unicode("Доброго дня, друже! :)", 'utf-8'), font=font_ra, fill=255)

Вот что изменилось в программе по сравнению с предыдущей в которой мы также выводили текст:

  • Указана внутренняя кодировка файла для Python: "# -*- coding: utf-8 -*-";
  • Используем шрифт с поддержкой кириллици, размером 12: "('OpenSans-Regular.ttf', 12)";
  • Перед передачей текста на обработку конвертируем его в UTF-8: "unicode("Доброго дня, друже! :)", 'utf-8')".

Команда для запуска:

python ~/Temp/ssd1306_text_hello_wolrd_font_cyrillic.py

Результат работы:

отображаем кириллический текст на дисплее SSD1306

Рис. 6. Отображаем кириллический текст (украинский, русский и другой) на дисплее SSD1306.

Кроме символов кириллици можно попробовать отобразить другие буквы и символы в кодировке UTF-8 для разных языков (зависит от шрифта). К примеру со шрифтом Open Sans корректно отображается символ Ω (знак Ома U+03A9) и другие. Тестируйте сами нужную вам комбинацию.

Для удобного поиска и выбора символов в Linux есть программа KCharSelect, установку можно выполнить из репозитория (Ubuntu, Debian, Mint...) командой:

sudo apt-get install kcharselect

Все просто и работает отлично!

Рисуем геометрические фигуры

После того как научились выводить простой текст, неплохо бы попрактиковаться в выводе геометрических фигур. В следующем примере мы выведем на экран:

  • 1-я точка;
  • 2-я точка (по сути будем рисовать линию длиной в 1 пиксель);
  • Линия (последовательность пикселей);
  • Прямоугольник 40x30 пикселей, заполним его цветом. Для двухцветного дисплея получится прапор Украины (желто-синий);
  • Колечко (елипс без заполнения цветом);
  • Круг (елипс заполненный цветом);
  • Треугольник (полигон, набор соединенных прямых линий).

Создадим новый файл для программы:

nano ~/Temp/ssd1306_geom_figures.py

Код программы:

#!/usr/bin/env python
# Geometric figures test for SSD1306 in Raspberry Pi
# 2016 https://ph0en1x.net

from device import ssd1306
from render import canvas
from PIL import ImageFont

device = ssd1306(port=1, address=0x3C) # for RPi rev 2 port(smbus) = 1
font = ImageFont.load_default()

with canvas(device) as draw:
    print 'Display dimensions: ' + str(device.width) + 'x' + str(device.height)
    # 1st point
    draw.point((device.width-1, 0), fill=255)
    # 2nd point
    draw.line((device.width-1, 16, device.width, 16), fill=256)
    # line
    draw.line((device.width-25, 0, device.width, device.height-30), fill=256)
    # rectangle filled with color
    draw.rectangle((0, 0, 40, 30), outline=255, fill=255)
    # circle
    draw.ellipse((0, 35, 30, 64), outline=255, fill=0)
    # filled circle
    draw.ellipse((device.width-20, 40, device.width, 60), outline=0, fill=255)
    # triangle
    draw.polygon([(64, 64), (42,32), (86,32)], outline=255, fill=0)

Запускаем:

python ~/Temp/ssd1306_geom_figures.py

После запуска на экране отобразятся геометрические фигуры и точки, а в консоли будут выведены размеры экрана в пикселях. Ниже приведено фото того что должно получиться:

Рисуем геометрические фигуры на дисплее ssd1306 используя Python и Raspberry Pi

Рис. 7. Рисуем геометрические фигуры на дисплее ssd1306 используя Python и Raspberry Pi.

Более детальную информацию по работе с функциями рисования 2D-графики можно узнать почитав документацию по модулю ImageDraw для Pillow (PIL), смотри ссылку внизу статьи.

Отображаем рисунки

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

Для следующего примера скопируем из репозитория файл с логотипом Raspberry Pi, выполним команду: 

cp ~/Temp/ssd1306/examples/images/pi_logo.png ~/Temp

Откроем новый файл для программы:

nano ~/Temp/ssd1306_image_test.py

Код программы:

#!/usr/bin/env python
# Image test for display SSD1306 using Raspberry Pi
# 2016 https://ph0en1x.net

from device import ssd1306
from render import canvas
from PIL import Image

device = ssd1306(port=1, address=0x3C) # for RPi rev 2 port(smbus) = 1

with canvas(device) as draw:
    pic = Image.open('pi_logo.png')
    draw.bitmap((32, 0), pic, fill=255)

Запустим программу:

python ~/Temp/ssd1306_image_test.py

Результат работы:

Отображаем PNG-рисунок на дисплее ssd1306 используя Python и Raspberry Pi

Рис. 8. Отображаем PNG-рисунок на дисплее ssd1306 используя Python и Raspberry Pi.

Как видим, все предельно просто благодаря использованию библиотеки Pillow!

Подготовка рисунков

Для приведенного выше примера вы можете загрузить в папку с экспериментом свой рисунок, а для его отображения нужно будет изменить строчку кода "pic = Image.open('pi_logo.png')", указав имя и путь для своего файла-рисунка вместо pi_logo.png. Можно также использовать графические файлы в формате JPG.

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

Для подготовки рисунков отлично подойдет графический редактор GIMP. Создадим новый бланк рисунка (CTRL+N) с размерами 128 на 64 пикселя, поместим туда какое-то изображение (можно использовать буфер обмена для вставки рисунка - CTRL+V) или же нарисуем что либо при помощи инструментов редактора.

Ниже приведен оригинал изображения (иконка Адама Дженсена из Deus Ex HR, взята с просторов интернета) с которым будем работать:

Исходный рисунок для эксперимента с дисплеем ssd1306

Рис. 9. Исходный рисунок (128x64) для эксперимента с дисплеем ssd1306.

Поскольку дисплей на драйвере ssd1306 является черно-белым (белый цвет - это желтый и синий на дисплее) то нужно конвертировать рисунок в режиме "оттенки серого", для этого в редакторе GIMP выберем Image - Mode - Grayscale, получится вот такой рисунок:

Черно-белый рисунок для эксперимента с дисплеем ssd1306

Рис. 10. Черно-белый рисунок для эксперимента с дисплеем ssd1306.

В принципе уже можно экспортировать рисунок в файл формата JPG - жмем CTRL+E, указываем имя файла и в конце расширение ".jpg". При загрузке такого файла в нашей программе он будет автоматически конвертирован, цвета преобразованы с добавлением альфа-канала (Alpha-channel), на дисплее рисунок будет содержать только элементы которые имеют цвет или же содержат пустоту (прозрачные).

Рисунок с Адамом Дженсеном, выведенный на OLED дисплей ssd1306

Рис. 11. Рисунок с Адамом Дженсеном, выведенный на OLED дисплей ssd1306.

Если сейчас попытаться экспортировать и сохранить рисунок в формат PNG, то при загрузке программы получим ошибку: "ValueError: bad transparency mask".

Перед экспортом в PNG проведем дополнительную подготовку. Используем рисунок, полученный на предыдущем этапе (черно-белый), выбираем пункты меню Image - Mode - RGB.

Теперь преобразуем рисунок таким образом, чтобы черный цвет у нас стал прозрачным, выбираем Colors - Color to Alpha, нажимаем выпадающий список и в палитре цветов выбираем черный. Вот что должно получиться:

 Черный цвет преобразован в Альфа-канал в редакторе GIMP

Рис. 12. Черный цвет преобразован в Альфа-канал в редакторе GIMP (режим RGB).

После данной операции можем выполнить экспорт рисунка в файл формата PNG (CTRL+E) и загрузить его в нашу программу. Чтобы указать редактору GIMP что нужно сохранить рисунок в формате PNG достаточно изменить расширение сохраняемого файла на ".png".

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

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

  • Созадим пустое изображение (CTRL+N) с размерами 128 на 64 пикселя;
  • Скопируем откуда-то какой-то рисунок в буфер обмена и вставим его в редакторе (CTRL+V);
  • Переконвертируем рисунок в черно-белом режиме: Image - Mode - Grayscale;
  • Вернемся в цветной RGB режим: Image - Mode - RGB (рисунок останется в серых тонах).

У нас получится изображение как на рисунке 8. Теперь выберем в меню Colors - Posterize, укажем значение - 2 и жмем ОК. Вот что должно получиться:

Постеризированный в редакторе GIMP рисунок

Рис. 13. Постеризированный в редакторе GIMP рисунок (режим RGB).

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

Преобразуем черный цвет в Альфа-канал: Colors - Color to Alpha, выбираем черный цвет и жмем ОК. Получится вот такой рисунок:

Готовый рисунок после постеризации и преобразования черного цвета в прозрачность

Рис. 14. Готовый рисунок после постеризации и преобразования черного цвета в прозрачность.

Теперь данный рисунок можно немного подкорректировать, что-то убрать или добавить, а потом выполнить экспорт в файл формата PNG. Загрузив такой файл программа без проблем его обработает и на дисплее мы увидим его точно 1 в 1 (посмотрите рисунок 11).

В редакторе GIMP есть еще масса разных полезных инструментов, эффектов и фильтров при помощи которых можно улучшить изображение и подогнать его до нужного уровня. GIMP - отличная, свободная замена платным редакторам уровня Adobe Photoshop!

Индикатор качества воздуха

Теперь попробуем собрать более-менее полезный проект с использованием дисплея SSD1306, АЦП-ЦАП PCF8591P и газового анализатора MQ-135. О том как сдружить последних два блока я рассказывал в предыдущей статье, поэтому детально останавливаться на этом здесь не буду.

Вот что будет делать наш индикатор качетва воздуха:

  • Отображать на дисплее в реальном времени числовое состояние входа АЦП PCF8591P, к которому подключен датчик MQ-135;
  • При превышении допустимого значения вредных веществ в воздухе на экране отобразим рисунок означающий "токсичность".

Для данного эксперимента соберем вот такую схему:

Схема подключения PCF8591P, MQ-135 и SSD1306 к Raspberry Pi 2

Рис. 15. Схема подключения PCF8591P, MQ-135 и SSD1306 к Raspberry Pi 2.

Схема включения выглядит идентично той, которую я приводил в эксперименте с датчиком газов MQ-135, здесь лишь к шине I2C дополнительно подключен дисплей SSD1306.

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

После подключения схемы и загрузки Raspberry Pi подключимся к малинке и в консоли проверим какие устройства на шине I2C у нас присутствуют:

sudo i2cdetect -y 1

Пример вывода команды:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

Здесь видно что на шине I2C присутствуют два устройства:

  • адрес 48 - это PCF8591P;
  • адрес 3с - это SSD1306.

Все отлично, можем приступать к программированию. Создадим новый файл для нашей программы:

nano ~/Temp/ssd1306_gas_sensor.py

Код программы:

#!/usr/bin/env python
# SSD1306 + gas sensor MQ135 + ADC-DAC PCF8591P
# 2016 https://ph0en1x.net

import os
import time
from smbus import SMBus
from device import ssd1306
from render import canvas
from PIL import Image
from PIL import ImageFont

display = ssd1306(port=1, address=0x3C) # for RPi rev 2 port(smbus) = 1
font_ra = ImageFont.truetype('ra.ttf', 18)
toxic_img = Image.open('toxic.png')
ADC_ADDR = 0x48
adc_channel = 0b1000010 # 0x42 (activate AIN2)
bus = SMBus(1)          # 1 - I2C bus address for RPi rev.2

while(1):
    os.system('clear')
    print("Press Ctrl C to stop...\n")
    # read sensor value from ADC
    bus.write_byte(ADC_ADDR, adc_channel)
    bus.read_byte(ADC_ADDR)
    bus.read_byte(ADC_ADDR)
    value = bus.read_byte(ADC_ADDR)
    text = 'Gas level = ' + str(value)
    # draw on display
    with canvas(display) as draw:
        draw.text((5, 0), text, font=font_ra, fill=255)
        if value > 40:
            draw.bitmap((20, 18), toxic_img, fill=1)
    # pause 100 milliseconds
    time.sleep(0.1)

Выполним запуск программы:

python ~/Temp/ssd1306_gas_sensor.py

Установить значение при котором появится рисунок можно изменив число в строке "if value > 40:". Для следующего фото я специально занизил это значение, поэтому на экране уровень с датчика равен 30 и отображается картинка со знаком токсичности.

Собранная конструкция из модулей с дисплеем SSD1306 в работе

Рис. 16. Собранная конструкция из модулей с дисплеем SSD1306 в работе.

Ниже приведено видео, на котором продемонстрирована работа данной связки, здесь был установлен пороговый уровень для отображения рисунка - 100. Для теста использован достаточно токсичный растворитель - дихлорэтан, нанесенный на кончик отвертки, этого вполне достаточно для уверенной реакции датчика.

Заключение

Как видим, на миниатюрном дисплее SSD1306 можно выводить тексты на английском, украинском, русском и других языках, отображать рисунки и геометрические фигуры - отображать что угодно!

Все файлы и скрипты для приведенных выше примеров собрал в один архив - ssd1306-display-raspberry-pi.zip (149 КБ).

Еще можно найти немало различных применений миниатюрному и экономичному OLED экранчику на основе SSD1306. К примеру можно сделать табло отображающее свободные ресурсы в ОС для Raspberry Pi, подключить дисплей к AVR микроконтроллеру и собрать на их основе миниатюрный вольт-амперметр...

Веселого и удачного вам творчества!

Полезные ресурсы:

 (5/5) голосов: 1   просмотров: 340


Тематика:  OLED  SSD1306  Raspberry Pi  Linux  Python  MQ 135

Комментарии к публикации (4)
slgeo 1 slgeo 
26 Ноябрь 2016 23:18

А как кириллицу вывести на экран?

+1 
ph0en1x 2 ph0en1x 
27 Ноябрь 2016 21:06

Дополнил статью, добавил раздел Отображаем символы кириллици (TTF).
Обновил архив с примерами - добавлен шрифт и скрипт с примером кода.
Пользуйтесь!

+2 
slgeo 3 slgeo 
29 Ноябрь 2016 23:10

Огромное спасибо, был шаге )
Если сделаю бегущую строку, обязательно поделюсь

+1 
slgeo 4 slgeo 
12 Декабрь 2016 22:50

Как и обещал, "бегущая строка":

# -*- coding: utf-8 -*-
#!/usr/bin/env python
# "Ticker" for display SSD1306 in Raspberry Pi
# 2016 by slgeo
from oled.device import sh1106
from oled.render import canvas
 
#from device import ssd1306
#from render import canvas
from PIL import ImageFont
 
device = sh1106(port = 1, address = 0x3C) # for RPi rev 2 port(smbus) = 1
font = ImageFont.load_default()
font_ra = ImageFont.truetype("/home/pi/ssd1306/fonts/OpenSans-Regular.ttf",12)
y = 130
while y > -250:
  with canvas(device) as draw:
    draw.text((10, 0), "*** Hello World ***", font=font, fill=255)
    str = "В лесу родилась елочка, в лесу она росла"
    draw.text((y, 30), unicode(str, 'utf-8'), font=font_ra, fill=255)
  y = y - 5 # 5 - скорость движения бегущей строки
  if y < -245:
    y = 130 
+1 

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