Sl-Alex домашняя лаборатория

GPS часы

Просмотров: 1023Комментарии: 0
Проекты

Перевод: EN

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

Краткое описание

На картинке ниже структурная схема часов:

Рисунок 1 — Структурная схема. Рисунок 1 — Структурная схема.

Сердцем часов является контроллер STM32F103C8T6 (ARM Cortex M3, 64kB flash, 20kB SRAM). Мне лень было делать свою плату, поэтому я приобрёл готовую:

Рисунок 2 — Плата контроллера. Рисунок 2 — Плата контроллера.

Плату без проблем можно найти в интернете по запросу "STM32F103C8T6 minimum system board", цена меньше 2$ за штуку.

Экран разрешением 80x24 пикселя сделан из матриц 8*8 пикселей, которые управляются драйверами HT16K33 (самый дешёвый драйвер, который удалось найти). Каждый драйвер позволяет управлять матрицей 8*16 и имеет 16 шагов регулировки яркости. Судя по документации, на него можно повесить опрос клавиатуры, но я это не использовал. Драйвер подключается по интерфейсу I2C, на одной шине можно иметь до 8 устройств. Таким образом, весь экран управляется при помощи 15 драйверов, которые пришлось повесить на 2 шины I2C. В целях экономии было заказано 10 плат, остальные 5 паялись навесным монтажом. Вот так должна выглядеть одна собранная плата:

Рисунок 3 — Плата драйвера. Рисунок 3 — Плата драйвера.

На этой картинке в левой нижней части стоят три резистора, которыми задаётся три младших бита I2C адреса модуля. Резистор R1 отвечает за бит 2, R2 за бит 1 и R3 за бит 0. Установленный резистор означает единичку в соответствующем бите.

Кроме плат драйверов, на шину I2C также подключены модули датчика освещённости BH1750 (для автоматической регулировки яркости), датчик температуры/влажности Si7021, датчик давления BMP180. Все модули доступны в интернете, выглядят вот так:

Рисунок 4 — Платы датчиков. Рисунок 4 — Платы датчиков.

Обратите внимание, на плате Si7021 чип заклеен специальной наклейкой. Не снимайте её, она защищает кристалл от воздействия окружающей среды и не мешает измерять влажность.

Дополнительно к датчикам был добавлен чип памяти FRAM FM24C04, в нём хранится история давления, чтобы при случайном сбое питания можно было восстановить предыдущие данные. Схему подключения не привожу ввиду её элементарности. GPS модуль на базе EB-800 подключён по UART и работает на скорости 9600. Модуль используется в конфигурации по умолчанию, никакой дополнительной настройки не требуется.

Прошивка

Прошивка написана в EmBitz (бывший EmBlocks), я о нём уже немного писал. Мне очень хотелось попробовать какую-нибудь маленькую ОС, поэтому я взял хорошо себя зарекомендовавший в интернете FreeRTOS. Он был выбран за хорошую документацию, кучу примеров и (не в последнюю очередь) за наличие ветки сертифицированной ветки SafeRTOS.

Немного информации о том, как это всё работает. После инициализации в контроллере активны два потока. Один обрабатывает информацию от GPS, второй раз в секунду читает показания датчиков и обновляет экран. Выглядит это всё примерно так:

Рисунок 5 — Структура программы. Рисунок 5 — Структура программы.

GPS приёмник постоянно включен и раз в секунду посылает данные о спутниках и времени по протоколу NMEA. Прерывание от UART ложит каждый принятый байт во входную очередь, которая обрабатывается в отдельном потоке. Принятые данные обрабатываются парсером NMEA и, если разница во времени составила больше одной минуты, то время на локальных часах корректируется. Парсер NMEA использует информацию из следующих NMEA пакетов:

  • GPRMC (время в UTC)
  • GPGSA (список активных спутников)
  • GPGSV (уровень сигнала с каждого спутника)
  • GPZDA (это было последнее сообщение от EB-800, использовалось для сортировки полученных спутников по уровню сигнала)
Для корректной работы часам достаточно только пакета GPRMC.

Основной поток большую часть времени проводит в заблокированном состоянии в ожидании события от RTC. Как только событие происходит, основной поток разблокируется, обновляет показания со всех датчиков и затем обновляет экран. Раз в секунду производится также запись в FRAM. Ресурс записи в FRAM составляет 1010, что позволяет не беспокоиться о повреждении ячеек.

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

Исходный код проекта, схема платы драйвера и общая схема, приведённая в начале статьи, лежат на GitHub, у меня к есть только пара комментариев к прошивке. По умолчанию используется английский язык, реализована также поддержка кириллицы. Если предполагается использовать другой язык, нужно использовать однобайтную кодовую страницу. Таблица знакогенератора хранится в файле usr_font.c, все сообщения, которые выводятся на экран, хранятся в файле usr_messages.c. Эти файлы должны быть сохранены в той же однобайтной кодировке. В моём случае это кодовая страница 1251, содержащая символы латиницы и кириллицы.

Сборка

Сборка не представляет из себя ничего сложного. Все модули драйверов были склеены между собой, каждому из них были впаяны резисторы, задающие адрес, подключено питание и залита прошивка. Передняя часть часов представляет собой сделанную на заказ фоторамку, на стекло была наклеена тёмная автомобильная тонировочная плёнка. Боковые части выпилены из купленной в строймагазине деревянной рейки, после сборки они были покрашены краской из баллончика. Сеточки, дающие воздуху циркулировать возле датчика температуры/влажности, были сделаны из небольших кухонных ситечек. Для фиксации плат активно использовался термоклей. Вот так это выглядит у меня:

Рисунок 6 — Сборка. Рисунок 6 — Сборка.

Как видите, ничего особенного, просто куча клея и немного проводов :)

Послесловие

Я понимаю, что всё это можно было сделать без всяких OS, очередей, синхронизаций и потоков, а некоторые любители написали бы всё на ассемблере или вообще спаяли из отдельных транзисторов. Эти часы были сделаны в первую очередь для того, чтобы попробовать FreeRTOS, и очень стабильно работают уже больше года. Мы с женой уже привыкли сверять по ним время. Это оказалось очень удобно, особенно зимой, когда утром за окном ещё темно. Проснулся, кинул взгляд на часы, и сразу знаешь, можно ли ещё поспать, или уже пора выползать из-под тёплого одеяла.

Напоследок краткое видео работы.