Skip to content

Дисплей tm1637 на FreeBSD

Всё началось с покупки нового телевизора...
С полки исчезла DVB-T2 приставка, почти ненужная, но Чемпионат по футболу смотрел именно на ней! Через пару-тройку дней, когда интерес к новым возможностям телевизора угас, я осознал, что с приставкой потерял нечто важное - часы! Простенькие электронные часы на лицевой панели приставки, самосинхронизирующиеся как-то там, всегда на виду... были... Но, вроде бы, не всё безнадёжно - рядом на полке стоит мой... эээ... мини-сервер точного времени для домашней сети - Raspberry Pi 2 c GLONASS-приёмником и под управлением FreeBSD (и кому, как не ему, знать точное время?), а в ящике стола завалялся 7-сегментный цифровой дисплей tm1637 0.36" с двумя точками как на часах и четырьмя контактами (рублей 50 за него отдал на Aliexpress.com)... Четыре проводка с F-F-контактами для соединения с "малинкой" тоже найдутся.
Посмотрим, что мы с этим можем сделать...


  • Первым делом поищем в Интернете типовые подключения для таких дисплейчиков, ну, чтобы не "городить огород"... Ага, предлагают пины 38 и 40 для CLK и DIO, соответственно. С питанием, интересно, - 5В, но прекрасно работает и от 3.3В.
    Итак, наши первые данные - пины на разъёме "Малины":
    • CLK - 38 (GPIO20)
    • DIO - 40 (GPIO21)
    • VCC - 17 (3.3V)
    • GND - 34 (GND)
    Подключенный дисплей "молчит". Самое время поискать библиотеку (драйвер) для управления этим экраном, а, справедливости ради, это надо было бы сделать в самую первую очередь, ведь команда разработчиков для Raspberry Pi и её сообщество, в массе своей, разрабатывают код для ОС Linux, точнее её ветки Raspbian, а у меня (и, если Вы читаете эту статью, то, скорее всего, и у Вас) на "Малине" установлена FreeBSD. Но, спокойствие! у нашей истории счастливый финал.
  • На просторах Интернета была найдена вполне работоспособная библиотека от bitbank2, адаптированная для Linux:
  • Но она использует libarmbianio для доступа к gpio, а у нас libgpio. Посмотрев её код и "покурив" man gpio я решил попытаться заменить вызовы AIOWriteGPIO на аналогичные gpio_pin_high и gpio_pin_low. Дело оказалось проще, чем я думал и, после нескольких правок типов переменных, библиотечка собралась. Окрылённый быстрым результатом, я запустил по инструкции сборку приложенной к коду демонстрационной программы, получил бинарник и запустил его ... а уж, после того как до меня дошло, что номера пинов 38 и 40 в исходном коде программки следует заменить номерами GPIO 20 и 21, соответственно (см. "Raspberry PI pinout" в любимом поисковике), по дисплею бодро побежали циферки с мигающим двоеточием.
  • Осталось написать свою программку с использованием этой библиотеки для отображения времени. Её задачи просты:
    • Зажечь (инициализировать) дисплей;
    • В фоне периодически опрашивать локальное (местное) время системы;
    • Выводить полученное время на цифровой дисплей;
    • При окончании работы, по возможности, корректно завершить взаимодействие с устройствами;
    • Неплохо бы реализовать авто-(старт|стоп) при старте и выключении системы.

    Язык програмирования С я учил "по ходу" :-), но програмка, на мой взгляд, получилась маленькая и лаконичная. В ней реализованы наши первые 4 задачи - бесконечный цикл, в цикле запрос localtime(3), форматирование строки и вывод её на дисплей 2 раза в секунду, чередуя при этом наличие разделительных двух точек, а также, программа при старте перехватывает сигналы SIGTERM и SIGINT (нормальное завершение и прерывание выполнения) с целью выключить дисплей.
    Пятая задача решается сервисным скриптом /usr/local/etc/rc.d/digitalclock в котором она "демонизируется" (запускается в фоновом режиме, отключенной от терминала, с помощью команды daemon(8). Если эта возможность интересна, то скрипт следует скопировать в указанное место и активировать строчкой
    CODE:
    digitalclock_enable="YES"

    в системный файл конфигурации /etc/rc.conf или, что более модно, в индивидуальный файл конфигурации /usr/local/etc/rc.conf.d/digitalclock

Вот, как будто, и всё!

Но после того, как мне надоело любоваться делом рук своих, у программки обнаружилась несколько недостатков:
  • Вывод времени происходил два раза в секунду, и выводилось сразу 4 знака, поэтому занимала эта задача ~0.30% процессорного времени, что мне показалось многовато. Хотелось выводить 4 знака, только когда часы и минуты реально изменились, а в остальное время выводить только мигающее двоеточие. Этого используемая библиотека не позволяет;
  • Смешно сказать, но секунды оказались не совсем секундами - рядом с дисплеем находится GLONASS-приёмник и частота мигания у них обоих явно не совпадает;
  • Для запуска программы в качестве сервиса, приходится использовать системную утилиту daemon(8) и она висит дополнительным процессом, что, как-то, не комильфо.

Для решения первой проблемы была найдена и адаптирована аналогичным образом к libgpio ещё одна библиотека, написанная для Arduino:
Библиотека описывает класс для tm1637 и для сборки использует c++ (в нашем случае clang++).
Для автоматической сборки был создан Makefile - его задача, собрать стандартную библиотеку с версией, софтверную ссылку на неё со стандартным именем, типа libtm1637.so, и положить её на стандартное место, в /usr/local/lib - у предыдущей библиотеки он был.

Как пользоваться методами объявленного класса понятно из папки ./examples. Эта библиотека уже позволяет выводить произвольный символ в произвольную позицию, в частности, для мигающего двоеточия достаточно 2 раза в секунду выводить только один символ (экономия в 4(!) раза).

Для точного вывода секунд я использовал POSIX-таймер, создаваемый через timer_create(2), вызывается точно 2 раза в секунду и, если время изменилось с момента прошлого вызова, печатает все 4 знака, а если не менялось, то печатает только второй знак, каждый раз включая или выключая у него признак двоеточия (если кто не знает, то двоеточие - это дополнительный сегмент второго по порядку знака на дисплее tm1637. Я не знал).

В программу добавилось создание файла с номером процесса pidfile(3) и процедура daemon(3) (Пример использования прямо в man pidfile), что избавило от запуска дополнительной утилиты (Ох уж эти шутники из FreeBSD - в конце примера открывается бесконечный цикл с дублированием процессом самого себя. "Малины" хватило секунд на 20 - да, наступил на грабли, не заметил шутки).

Переписан оказался и скрипт запуска сервиса - он стал проще и лаконичнее.

То, что что получилось, мне понравилось! Теперь задача потребляет только ~0.10%, а секунды на дисплее мигают в такт индикатору PPS на GLONASS - приёмнике.

В Makefile библиотеки добавил сборку первоначальной программы (та, что с простым циклом), слегка поправленной для новой библиотеки. Чтобы её попробовать, нужно набрать в каталоге библиотеки:

CODE:
make demo ./demo


Поскольку для FreeBSD прикладного ПО для GPIO, мягко сказать, не очень много, мне приятно добавить свои 2 копейки в корзинку.
Отсюда можно скачать исходные коды библиотеки tm1637 для FreeBSD и программы:
Работает "как часы".

Я тут подумал, и ...закажу-ка я, пожалуй, ещё один такой дисплей, но ностальгически жёлтого цвета и размером 0,56".

P.S.: Подтверждаю работоспособность библиотеки на Orange Pi Zero (Allwinner H2+) под управлением FreeBSD. Только поправить номера пинов - они различаются.

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

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

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.
Опции формы