- Цифры написаны шрифтом, похожим на рукописный;
- Cмена цифр происходит с анимацией 30 кадров в секунду;
- Анимация длится половину секунды и начинается за пол-секунды до наступления анимируемого времени;
- Цвет изображения погоды зависит от температуры;
- Для улучшения визуального восприятия граничные точки сглаживаются;
- Температура рисуется теми же цифрами, что и время.
-
Используется микроконтроллер ESP32;
-
В данной реализации использован дисплей 320x240 на контроллере ILI9341;
-
Использованная графическая библиотека написана целиком мной;
-
Графическая библиотека поддерживает другие распространённые контроллеры, может одновременно использовать несколько дисплеев;
-
Графическая библиотека поддерживает не только физические, но и виртуальные экраны, которые затем можно комбинировать и выводить на физический экран;
-
Шрифты поддерживают произвольный набор
Code point-ов, можно выводить произвольныйUTF-8текст.
- Каждая цифра представляет из себя набор из трёх кубических кривых Безье link;
- Каждая кубическая кривая Безье требует 4 опорных точки для рисования;
- Многие цифры могли быть изображены только двумя кривыми, но это ограничивает возможный путь кривой линии, он может уже не всегда попадать в желаемый, особенно для цифр 2 и 5;
- Для трансформации одной цифры в другую точки каждой кривой линейно перемещаются в соответсвующие точки результирующей кривой link;
- После рисования всех необходимых элементов в виртуальных экранах происходит расчёт сколько осталось свободного времени от отведённой 1/30 секунды и задача отрисовки засыпает на этот остаток времени, передавая упраление задаче вывода на физический экран.
- После запуска микроконтроллера запускается процесс соединения с точной доступа;
- После успешного получения IP от точки доступа, запускается процесс периодического получения местоположения и процесс синхронизации времени с публичным NTP сервером;
- Для получения местоположения используется сервис ipinfo.io;
- После получения местоположения, запускается процесс получения погоды с сервера openweathermap.org;
- Получение местоположения позволяет определить временную зону для времени;
- Опрос местоположения и погоды происходит каждые 10 минут.
Кубические кривые Безье позволяют описать плавную кривую с двумя изгибами между
крайними точками
.
Этот класс кривых описан подробно описан в многочисленной литературе, а так же, в
Википедии.
Каждая цифра описывается тремя кривыми Безье. Для определённости, я мысленно расставлял
точки на поле 100х160, не используя никакого визуального инструмента. Получившиеся
символы в итоге напоминают рукописный шрифт, который, как мне говорит моя жена, очень
похож на мой собственный. Первая цифра, на которой я тренировался, была 2. Она состоит
из трёх элементов: верхний полукруг, извилистая "шейка" и основание. Эту цифру я хотел
сделать именно такой, поэтому, мне потребовалось три кривых. На большинство цифр
хватило бы и двух кривых, так что пришлось третью пристраивать куда-нибудь в любом случае.
Координаты некоторых кривых выходят за рамки поля 100х160, но сами кривые при этом
остаются внутри.
Для рисования цифр заданного размера используется операция афинного преобразования "масштабирование и сдвиг". Координаты точек в поле 100х160 масштабируется в желаемые размеры и сдвигаются на нужный вектор для рисования кривых.
Кривые рисуются отрезками прямых по сегментам. Каждая кривая разбита на 12 сегментов. Чисто подбиралось экспериментально, чтобы, с одной стороны, не создавалось проблем с быстродействием, а с другой, всё выглядело ещё достаточно плавным. Так же, все нарисованные элементы ещё дополнительно сглаживаются алгоритмом антиалиасинга, который для чёрных точек на границах элементов создаёт гладкий переход.
Для рисования толстых кривых используются толстые линии, которые, фактически, повёрнутые прямоугольники. Алгоритм рисования толстых линий оптимизирован под особенности передачи данных на экран. Если линии становятся заметно толстыми, то на изгибах кривых могут появляться разрывы на внешней стороне изгиба. Чтобы это избежать, между сегментами для толстых кривых рисуются сплошные круги, которые заглаживают эти разрывы.
Все элементы рисуются в соответствующих виртуальных экранах, которые затем передаются в основной процесс для отображения на физическом экране. Таким образом, разные процессы не будут конфликтовать за шину SPI.
Для простоты реализации алгоритма антиалиасинга, все используемые виртуальные экраны 8-битные, где каждый байт означает интенсивность цвета. При переносе 8-битного виртуального экрана на физический, используется таблица трансляции цвета в 16-битное представление. Для погоды и времени используются отдельные таблицы, для погоды она расчитывается каждый раз при изменении температуры.
Символы погоды берутся из шрифта Weather Icons. Они немного не совпадают с той формой погоды, что возвращает сервис погоды, пришлось творчески придумать отображение.
Короткий пример работы часов:
| Display | Pin |
|---|---|
| GND | GND |
| VCC | 3.3V |
| CLK | 18 |
| MOSI | 23 |
| RES | 17 |
| DC | 16 |
| BLK | Vin |
| MISO | 19 |


