TRMNL своими руками
Недавно на хабре упоминались http://usetrmnl.com/ и я не удержался. Вот только не удержался не только я, и у них бэклог на еще месяца полтора… Но есть выход!

Что это
TRMNL — это 7.5» экран на жидких чернилах, предназначенный «настроил и забыл» показывать тебе то, что тебе нужно. Обновляются данные не часто, самое быстре — раз в 15 минут. Экран может обновляться чуть чаще: раз в 5 минут, показывая разные элементы из плейлиста. Плейлист гибко настраивается на то, какие экраны показывать и можно настроить разные плейлисты на разное время. Девайс продолжает обрастать фичами, так что это описание может уже устареть :)
Я пока пользуюсь выводом mash-up, когда 4 плагина сразу показываются на одном экране весь день, и данные на нём обновляются где-то раз в 15 минут.
Куда оно
Собственно, зачем мне устройство? Поставить возле выхода. Каждый раз выходя из квартиры я смотрю погоду и актуальное расписание, чтоб понять в какую сторону из дома идти. Это был первый план.
Поскольку сервис поддерживает не только BYOS (когда их железо и свой сервер), но и BYOD (своё железо), пока я жду официального — решил собрать второй девайс, дабы отладить желаемые плагины да и пусть их будет два — второй поставлю возле компа, чтобы видеть когда пора проветрить (данные с Netatmo датчиков) и сколько еще играть в игры перед сном (график шагов с fitbit и сахара с nightscout).
Как сейчас помню, после прошлых экспериментов с nRF для тредмила, у меня дома был ворох разных чипов — точно помню, валялась пара чипов на ESP32. Не нашел. Что ж, начнём издалека: привези мне почта, цветочик аленький…
Список покупок
Waveshare 800×480 7.5inch E-Ink display + HAT. Взял на Али за ~$50
Seeed Studio XIAO ESP32C3, взял на местном развале за ~$6.
Печать корпуса по вкусу, где-то ~$25+$10 доставка на craftcloud3d (я печатал внешний, вкладыш и задняя стенка; вот еще вариант корпуса, гуглятся еще для желающих).
BYOD лицензия, ~$35 (нагуглил дисконт-купон).
Итого: ~$126. Почти как девайс, без батарейки, но быстрее. Плюс, можно было взять и экран дешевле, и чип дешевле, и печатать без задней крышки… В общем, неважно, все хоббиты бесценны!
Сборка трезвым, пайка взрывом
Сборка в общем-то не требует никаких навыков. И если вместо Seeed взять официальный девкит, то проблем будет еще меньше. Но мы не ищем лёгких путей!
Экран вкладывается во внешний корпус и аккуратно закрывается внутренним. Мне приехал внутренний лист с отверстиями чуть меньше 3 мм, так что он не ложился --, но два вжика сверлом на 3 мм шуруповертом решило проблему и он начал вкладываться как там и был, аккуратно залипая на 3.03 пеньках внешнего корпуса.
На штырьки насаживаем HAT, и хвост экрана прикрепляем в разъём. (У разъёма поднимается черная часть, после чего оттуда убирается удлиннитель, вкладывается провод от экрана и черная часть прижимается обратно, готово).

Для подключения к чипу осталось только подцепить процессор. Мне приехала свежайшая ревизия HATа, 2.3, у которого 9 хвостов, а прошивка расчитана на 8. Решений три: правка прошивки, прицепить хвостик на постоянные +3.3 (то есть экран будет засыпать, но не отключаться), запаять резистор на него (фактически, подать те самые +3.3 без хвоста).
Я пошел по пути правки прошивки, об этом ниже.
Итак, у нас есть две детальки лего, к одной мы только что напаяли пины, из другой выходит плёточка. Их надо скрестить:

Да, положение переключателя «Display Config» смотрится по тому, как экран работает — у меня хорошо видно в режиме A;, а Interface Config должен быть в 4-line SPI, то есть 0.
Тут нам поможет официальная документация с распиновкой:

Итак, получаем, по порядку, снизу вверх:
VCC [красный] => идёт на 3V3 (это просто)
GND [черный] => GND (вау!)
DIN [синий] => EPD_MOSI_PIN (очевидно же) => GPIO8 => D8
CLK [желтый] => EPD_SCK_PIN (sck это clk) => GPIO7 => D5
CS [оранжевый] => EPD_CS_PIN => GPIO6 => D4
DC [зеленый] => EPD_DC_PIN => GPIO5 => D3
RST [белый] => идёт на EPD_RST_PIN => GPIO10 => D10
BUSY [фиолетовый] => идёт на EPD_BUSY_PIN => GPIO4 => пин D2
PWR [коричневый] => это новый хвост, идёт на свободный GPIO (кроме 2, 3, 9) => GPIO21 => D6
Пин GPIO3 используется для измерения заряда батареи. Если надо — то через два резистора зеркалим батарею на GPIO3, который A1, который пин D1. Я собрал без батареи, так что вырезал в прошивке.
Где и как внутри закрепить чип и выставить наружу USB хвост — по желанию :)
Прошивка
Так как я сразу собирался заняться правкой под фичи, то под сборку правка прошивки изначально была в планах, так что клонируем https://github.com/usetrmnl/firmware и правим:
В
lib/esp32-waveshare-epd/src/DEV_Config.h
добавляем пин куда повесили PWR и объявляем функцию выхода (стянул идею из последней версии дров):#define EPD_PWR_PIN 21 void DEV_Module_Exit(void);
А в
lib/esp32-waveshare-epd/src/DEV_Config.cpp
внутрьGPIO_Config
добавляемpinMode(EPD_PWR_PIN, OUTPUT); digitalWrite(EPD_PWR_PIN, HIGH);
Плюс определяем функцию:
void DEV_Module_Exit(void) { digitalWrite(EPD_PWR_PIN, LOW); }
Правим внутри
src/display.cpp
, добавляем последнюю строку в функциюdisplay_sleep
:DEV_Module_Exit();
Последняя правка: вырезаем проверку батареи в
src\bl.cpp
:static float readBatteryVoltage(void) { return 3.7; // 42 слишком банально }
Отлично. Последний штрих, для сборки добавляем в platformio.ini
нашу платформу:
[env:seeed-c3]
extends = env:esp32-c3-devkitc-02
board = seeed_xiao_esp32c3
build_flags =
-D ARDUINO_USB_MODE=1
-D ARDUINO_USB_CDC_ON_BOOT=1
-D CORE_DEBUG_LEVEL=0
-D WAIT_FOR_SERIAL=1
-D ARDUINOJSON_ENABLE_ARDUINO_STRING=1
build_flags
можно опустить, если не нужна отладочная информация, естественно.

Выбираем нашу новую платформу в выпадашке (1), жмём на кнопочку Build (2), потом перезагружаем семечку кнопкой и заливаем на неё по кнопке (3).
Он должен прогрузиться и показать экран отсутствия настройки.
Настройка
На сервере usetmnl вводим MAC адрес чипа (можно подглядеть в логах), после чего подключаемся к wifi сети TRMNL, вводим данные своей домашней сетки… Он перезагружается… И показывает дефолтную настройку:

Теперь можно изгаляться над ним как душе угодно!
Habrahabr.ru прочитано 4007 раз