Здравствуйте, уважаемые Датагорцы! Представляю вашему вниманию электронные часы с функцией измерения температуры, изготовленные мною в качестве подарка деду ко дню Советской Армии.
. Это моя первая статья.
»), измеряющего температуру и передающего по воздуху её значение центральному (далее — «
») для отражения совместно с текущими датой и временем на экране дисплея.
в) USB-кабелем питания — через заднюю панель корпуса.
Схема соединений элементов ЦМ представлена на Рисунке 1.
модуля DS1307 подключён к пину PD3 МК, поскольку сигнал с частотой 1 Гц на указанном выводе RTC использован в качестве источника внешнего прерывания INT1 ATmega328P для обновления значений времени и даты на экране дисплее.
nRF24L01 передаётся на пин PD2 МК, инициируя внешнее прерывание INT0, что обеспечивает своевременное чтение из трансивера нового значения температуры.
Для обмена данными с RTC, дисплеем и трансивером использованы пины ATmega328P не аппаратных I2C (PC5/PC4 для SCL/SDA, соответственно) и SPI (PB3/PB4/PB5 для MOSI/MISO/SCK, соответственно), а произвольные, поскольку в проекте реализованы программные версии указанных протоколов, а выбор пинов определялся из соображений топологии платы.
Источником питания ЦМ послужило зарядное устройство смартфона на 5В.
При включении ЦМ переходит в основной режим — отображения на экране дисплее текущих значений температуры, времени, даты и дня недели.
Рисунок 2. Значения, отражаемые на экране дисплея в основном режиме ЦМ
1. При поступлении сигнала с вывода SQ DS1307 микроконтроллер считывает из RTC текущие значения времени/даты, которые, в случае наличия изменений, обновляются на дисплее. Кроме того, символ двоеточия «
» в показаниях времени попеременно меняет цвет с белого на чёрный, т.е. блинкует с частотой 1 Гц.
2. В случае, когда nRF24L01 посредством прерывания INT0 сигнализирует о поступлении радио-пакета, МК считывает из трансивера текущее значение температуры и выводит на экран дисплея.
3. Длительное (более 4-х секунд) нажатие кнопки энкодера (далее - «
») переводит ЦМ в режим установки даты/времени. В указанном режиме, посредством вращения ротора энкодера (далее - «
»), сопровождаемого перемещением рамки, и короткого нажатия кнопки можно выбирать между установкой времени, установкой даты, возвратом в основной режим.
s» на экран дисплея выводится следующее меню.
Рисунок 4. Меню установки времени
Здесь, вращая ротор и ориентируясь на текущее положение рамки, необходимо выбрать требуемый разряд (десятки или единицы часов/минут), после чего коротко нажать кнопку. Последующее вращение ротора приведёт к изменению значения выбранного разряда. Очередное нажатие кнопки возвращает вращению ротора функцию перемещения рамки для выбора того или иного параметра.
» меню, а затем коротким нажатием кнопки сохранить новые значения в EEPROM DS1307 и вернуться к меню из Рисунка 3.
Рисунок 5. Меню установки даты
» меню на Рисунке 3.
Как следует из вышеприведённого видео, ПМ — выносной модуль измерения температуры с возможностью передачи её значения через радиоканал.
На рисунке 6 представлена схема соединений элементов ПМ.
Учитывая, что в ATtiny85 нет полноценной аппаратной поддержки требуемых протоколов обмена данными, в коде ПМ были использованы программные варианты 1-Wire (в случае с DS18B20) и SPI (в случае с nRF24L01), поэтому выбор соответствующих пинов МК — произвольный. Выводы
трансивера не использовались, в связи с отсутствием необходимости.
Большую часть времени ПМ проводит в режиме сна. При этом, согласно даташитов, ATtiny85 потребляет 10 мкА, а nRF24L01 – 900 нА.
• вводит трансивер в режим сна и засыпает сам.
Потребление ATtiny85 в активном режиме вырастает до 0.55 мА , а nRF24L01 — до 11.3 мА. Учитывая длительность операций в активном режиме (миллисекунды), можно предполагать, что емкости 240 мА/ч
.
, который, при необходимости, перекладывался мною с ассемблера или С на С++. Поэтому, далее буду делать ссылки на соответствующую публикацию указанного автора.
, скомпилировано посредством GCC и выложено в архив статьи. Прежде, чем перейти к особенностям кода каждого из модулей, остановлюсь на общих для обоих моментах.
Содержимое файла с основной функцией main() я предпочитаю ограничивать вызовом двух функций —
— которые прописываю уже в файле device.cpp. Такой подход даёт возможность хранить main.cpp, наряду с Makefile, в папке с шаблонами и переносить его без изменений из проекта в проект.
статьи.
Для обмена данными с внешними устройствами были применены программные версии соответствующих протоколов. См. подробнее в датагорских статьях:
Во всех вышеуказанных статьях даны подробные объяснения и комментарии к коду, поэтому не вижу смысла дублировать их текст в данной работе.
Для размещения кода ЦМ в МК потребуется 22.6 кБайт флэш-памяти, в т.ч. 3.1 кБайт — под шрифты. Кроме того, программа использует как минимум 982 байта ОЗУ, причём подавляющая часть этого объёма оперативной памяти выделяется под строковые переменные, применяемые при оформлении меню.
Учитывая большое количество перекрёстных ссылок, а также для удобства были вынесены:
• макроопределения состояний флагов энкодера и определения структур — в файл globals.h,
• распиновка соединений МК с внешними устройствами — в файл pinout.h.
1. Поле структуры
отражает факт нажатия кнопки и принимает значения ENCODER_BUTTON_PUSH_TIME_SHORT или ENCODER_BUTTON_PUSH_TIME_LONG при коротком или длительном нажатии, соответственно. Сбрасывается в состояние ENCODER_BUTTON_PUSH_TIME_NO_PUSH при инициализации энкодера и перед реакцией МК на нажатие.
отражает факт поворота ротора и принимает значения ENCODER_ROTOR_TURNED_CLOCK_WISE или ENCODER_ROTOR_TURNED_COUNTER_CLOCK_WISE при повороте по или против часовой стрелки, соответственно. Сбрасывается в состояние ENCODER_ROTOR_STOPPED при инициализации энкодера и перед реакцией МК на поворот.
принимает значение 1 в обработчике прерывания от nRF24L01 при поступлении радио-пакета от ПМ. Сбрасывается в 0 при инициализации трансивера и перед реакцией МК на поступление пакета.
принимает значение 1 в обработчике прерывания при поступлении сигнала от DS1307. Сбрасывается в 0 при инициализации RTC и перед реакцией МК на поступление сигнала.
» в значении времени на экране дисплея (1 — белый, 0 — чёрный). Меняет состояние на противоположное при очередной прорисовке значения времени.
2. Поле структуры
используется для выбора действия на экране дисплея при повороте ротора энкодера: 0 — движение рамки, 1 — изменение значения параметра (десятки/единицы времени и даты, день недели и т.д.).
определяет, какое именно меню будет прорисовано на экране дисплея в данный момент.
идентифицирует элемент меню, на который в данный момент указывает рамка в тех меню, где предполагается её наличие и движение.
устанавливаются в 1 при выборе пункта «save» в меню «time settings» и «date settings», соответственно, что является сигналом для МК к сохранению установленных в указанных меню новых значений времени и даты в EEPROM DS1307.
Остальные поля структуры menu предназначены для хранения текущих и предыдущих параметров рамки, времени, даты и температуры.
• дисплей ST7735.
Контроль энкодера осуществляется посредством кода из одноимённых cpp- и хидер- файлов, содержимое которых представлено ниже.
1. Поле структуры
обеспечивает подсчёт количества шагов ротора при его повороте в одном направлении.
предназначено для подсчёта длительности нажатия кнопки.
отражает текущее состояние кнопки и может принимать одно из четырёх значений, определённых в том же файле выше:
• ENCODER_BUTTON_IS_PUSHED_BEFORE_BOUNCE (или 2, когда кнопка нажата, но время дребезга не истекло),
• ENCODER_BUTTON_IS_PUSHED_AFTER_BOUNCE (или 3, когда кнопка нажата, и время дребезга истекло),
• ENCODER_BUTTON_IS_RELEASED_BEFORE_BOUNCE (или 4, когда кнопка отпущена, но время дребезга не истекло).
2. Параметры учёта текущего положения ротора необходимы для исключения дребезга при вращении последнего, о чём — ниже.
Для полноценного функционирования ЦМ необходимо обеспечить корректную реакцию МК на четыре события, генерируемые энкодером:
1. Длительное (более 4-х секунд) нажатие кнопки.
2. Короткое (менее 4-х секунд) нажатие кнопки.
3. Поворот ротора по часовой стрелке.
4. Поворот ротора против часовой стрелке.
При этом, следует иметь в виду, что производителем модуля энкодера, использовавшегося в проекте, не предусмотрены цепи подавления дребезга.
Учитывая вышеизложенное, было принято решение использовать в коде обработки сигналов от кнопки:
• организации задержки при нажатии кнопки для исключения дребезга, длительность которого, как правило, не превышает указанный период,
• подсчёта времени удержания кнопки в нажатом состоянии.
кнопки, для обеспечения немедленной реакции на её нажатие/отпускание.
Алгоритм действий МК при нажатии/отпускании кнопки можно понять из Рисунка 9.
на Рисунке 9, помня о том, что время между двумя соседними из них составляет 32.8 мс.
. Происходит нажатие кнопки, в связи с чем в обработчике прерывания PCINT8:
— кнопка нажата, но время дребезга не истекло) в поле buttonState структуры device, отражающее текущее состояние кнопки,
. Генерируется первое, после нажатия кнопки, прерывание таймера, в обработчике которого:
• инкрементируется поле counter структуры device, призванное считать длительность нажатия кнопки.
. Инкрементируется поле counter.
. Кнопка отпускается, вследствие чего генерируется прерывание PCINT8, в обработчике которого:
• в последний раз инкрементируется поле counter, после чего его значение анализируется (если оно меньше 125, значит длительность нажатия — меньше 32.8 мс х 125 = 4 секунд, в противном случае — больше 4 секунд) и обнуляется, а в поле encoderButtonGlag структуры device при этом записывается соответствующее значение (ENCODER_BUTTON_PUSH_TIME_SHORT или ENCODER_BUTTON_PUSH_TIME_LONG),
таймера, чтобы обеспечить корректное время задержки на период дребезга.
. По завершению задержки на время дребезга генерируется прерывание таймера, в обработчике которого:
• сбрасывается записью в него 1 флаг PCIF1, поднятый дребезгом после отпускания кнопки,
• локально разрешается прерывание PCINT8 для фиксации следующего нажатия кнопки.
Точки A – G из Рисунка 9 указаны, для полноты понимания, в коде обработчиков прерываний таймера и PCINT8 в тексте приведённого выше файла encoder.c.
Алгоритм интерпретации сигналов от ротора основан на том факте, что комбинация логических уровней на его выходных контактах в любой момент времени составляет, как видно из Рисунка 10, одно из четырёх чисел —
.
в encoder.cpp и подробно прокомментирован, поэтому ограничусь лишь короткими пояснениями:
1. Выбор соседних пинов одного и того же порта МК (в нашем случае —
) для подключения контактов ротора позволяет заметно упростить код. При этом макроопределение ENCODER_ROTOR_PIN_LS в pinout.h обязательно должно быть дано пину с меньшим порядковым номером (в нашем случае —
).
2. Применение двойного сдвига влево предыдущего значения числа, формируемого комбинацией логических уровней на пинах PC2 и PC1, снижает влияние дребезга. Вследствие сдвига и последующей операции ИЛИ с текущим значением, окончательное число для определения направления поворота будет не 0, 1, 2, 3, а
при повороте против часовой стрелки.
3. Накопление до 4 количества шагов поворота ротора в одном направлении так же, как и в предыдущем случае, помогает в борьбе с дребезгом.
Содержимое файлов контроля за RTC DS1307 представлено ниже.
Думаю, вы легко догадаетесь о назначении большинства полей и методов класса DS1307, исходя из их названий. Отмечу лишь, что:
включают и выключают, соответственно, тактирование микросхемы часов реального времени,
призваны разрешать и запрещать, соответственно, сигнал заданной частоты на выводе
необходимы для преобразования десятичного числа в двоично-десятичное и обратно, соответственно,
• в конструкторе класса осуществляется лишь включение тактирования.
Работу трансивера обеспечивают, помимо упомянутого выше pinout.h, представленные ниже файлы.
Поясню основные моменты.
1. При оформлении кода приняты во внимание требования спецификации nRF24L01, выложенной в архив статьи.
2. Метод
• переводит nRF24L01 в режим передатчика (как в случае с ПМ) или приёмника (как в случае с ЦМ), в зависимости от значения входного аргумента
.
трансивера.
3. Методы
обеспечивают перевод трансивера в режим передатчика и приёмника, соответственно, используя маски, определённые в хидер-файле.
4. Методы
позволяют реализовать режим сна nRF24L01.
5. Методы
.
Даташит ST7735 выложен в архив статьи. В проекте использовалась версия дисплея, поддерживающая SPI, в связи с чем для обмена данными с ним применялась та же библиотека протокола, что и в случае с nRF24L01.
.
Помимо упомянутых выше SPI.h и SPI.cpp работу дисплея обеспечивают нижеследующие файлы.
В вышеуказанной статье вы найдёте подробнейшие объяснения и комментарии. Остановлюсь лишь на двух наиболее важных моментах:
• окрашивание экрана дисплея в выбранный цвет (в нашем случае — чёрный).
позволяет нарисовать точку размером 1х1 пиксель с учётом заданных параметров — цвета и координат. Именно на этой функции построены методы графической библиотеки GFX, файлы которой приведены ниже.
Кроме файлов ST7735, графическая библиотека GFX использует вспомогательные файлы iconsFonts, в которых содержатся:
• шрифты для отражения значения времени (Arial36), а так же температуры, даты и других параметров (Arial16), сгенерированные посредством
.
#include "iconsFonts.h"
/* Константные строковые переменные */
const char timeSettings[] PROGMEM = "time settings";
const char dateSettings[] PROGMEM = "date settings";
const char exit[] PROGMEM = "exit";
PGM_P const tdeMenu[3] PROGMEM = {timeSettings, dateSettings, exit};
const char save[] PROGMEM = "save";
PGM_P const tsMenu[1] PROGMEM = {save};
/* Шрифт времени Arial36 */
const unsigned char image_data_Arial36_0x30[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x3f, 0x7f, 0x7c, 0xf8, 0xf0, 0xf0, 0xf8, 0x7c, 0x7f, 0x3f, 0x0f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xe0, 0xfc, 0xff, 0xff, 0x0f, 0x07, 0x03, 0x03, 0x07, 0x0f, 0xff, 0xff, 0xfc, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x30 = {image_data_Arial36_0x30, 16, 42};
const unsigned char image_data_Arial36_0x31[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x7f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x31 = {image_data_Arial36_0x31, 16, 42};
const unsigned char image_data_Arial36_0x32[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1e, 0x7f, 0x7f, 0xfc, 0xf0, 0xf0, 0xf0, 0xf0, 0xf8, 0x7f, 0x7f, 0x1f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x3f, 0xff, 0xfe, 0xf8, 0xe0, 0x00, 0x00, 0x01, 0x07, 0x1f, 0x3f, 0xff, 0xff, 0xfb, 0xf3, 0xe3, 0x83, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x32 = {image_data_Arial36_0x32, 16, 42};
const unsigned char image_data_Arial36_0x33[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3c, 0x7e, 0x7e, 0xf8, 0xf0, 0xf0, 0xf0, 0xf8, 0x7f, 0x7f, 0x3f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x7c, 0xff, 0xff, 0xe7, 0x83, 0x01, 0x00, 0x00, 0x18, 0x1e, 0x3f, 0x3f, 0x0f, 0x07, 0x03, 0x03, 0x03, 0x0f, 0xff, 0xff, 0xfe, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x33 = {image_data_Arial36_0x33, 16, 42};
const unsigned char image_data_Arial36_0x34[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x3f, 0xfe, 0xf8, 0xe0, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0xf8, 0xf8, 0x78, 0x78, 0x78, 0x78, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x34 = {image_data_Arial36_0x34, 16, 42};
const unsigned char image_data_Arial36_0x35[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x38, 0xf8, 0xfc, 0xfc, 0xf8, 0x70, 0xf0, 0xf0, 0xf8, 0xfc, 0x7f, 0x3f, 0x1f, 0x07, 0x00, 0x00, 0x18, 0x1e, 0x3f, 0x3f, 0x0f, 0x07, 0x03, 0x03, 0x07, 0x0f, 0xff, 0xff, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x35 = {image_data_Arial36_0x35, 16, 42};
const unsigned char image_data_Arial36_0x36[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x1f, 0x3f, 0x7c, 0xf8, 0xf0, 0xf0, 0xf0, 0xf8, 0x7e, 0x7e, 0x3c, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x3e, 0x38, 0x78, 0x78, 0x78, 0x7e, 0x3f, 0x1f, 0x0f, 0x03, 0x00, 0x00, 0xe0, 0xfc, 0xff, 0xff, 0x0f, 0x07, 0x03, 0x03, 0x03, 0x0f, 0xff, 0xff, 0xfe, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x36 = {image_data_Arial36_0x36, 16, 42};
const unsigned char image_data_Arial36_0x37[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf3, 0xff, 0xff, 0xff, 0xfc, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x3f, 0xff, 0xff, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x37 = {image_data_Arial36_0x37, 16, 42};
const unsigned char image_data_Arial36_0x38[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x3f, 0x7f, 0x7f, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0, 0xf8, 0x7f, 0x7f, 0x3f, 0x0f, 0x00, 0x00, 0xc0, 0xe3, 0xf7, 0xff, 0x3f, 0x1e, 0x1e, 0x1e, 0x1e, 0x3f, 0xff, 0xf7, 0xe3, 0xc0, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x07, 0x03, 0x03, 0x03, 0x03, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x38 = {image_data_Arial36_0x38, 16, 42};
const unsigned char image_data_Arial36_0x39[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x7f, 0xfc, 0xf0, 0xf0, 0xf0, 0xf8, 0x7c, 0x7f, 0x3f, 0x0f, 0x01, 0x00, 0x00, 0xf0, 0xfc, 0xfe, 0xff, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0c, 0x0f, 0x1f, 0x1f, 0x87, 0x83, 0x83, 0x83, 0x07, 0x0f, 0xff, 0xfe, 0xfc, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x39 = {image_data_Arial36_0x39, 16, 42};
const unsigned char image_data_Arial36_0x3a[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial36_0x3a = {image_data_Arial36_0x3a, 10, 42};
/* Шрифт температуры, даты и др. */
const unsigned char image_data_Arial16_0x20[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x20 = {image_data_Arial16_0x20, 4, 20};
const unsigned char image_data_Arial16_0x21[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x21 = {image_data_Arial16_0x21, 3, 20};
const unsigned char image_data_Arial16_0x22[] PROGMEM =
{
0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x22 = {image_data_Arial16_0x22, 5, 20};
const unsigned char image_data_Arial16_0x23[] PROGMEM =
{
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x88, 0x8f, 0xf8, 0x88, 0x8f, 0xf8, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x23 = {image_data_Arial16_0x23, 8, 20};
const unsigned char image_data_Arial16_0x24[] PROGMEM =
{
0x03, 0x04, 0x04, 0x0f, 0x04, 0x03, 0x00, 0x86, 0x41, 0x21, 0xff, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
};
tImage Arial16_0x24 = {image_data_Arial16_0x24, 7, 20};
const unsigned char image_data_Arial16_0x25[] PROGMEM =
{
0x00, 0x03, 0x04, 0x04, 0x03, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x21, 0xc6, 0x18, 0xe0, 0x1e, 0x21, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x25 = {image_data_Arial16_0x25, 12, 20};
const unsigned char image_data_Arial16_0x26[] PROGMEM =
{
0x00, 0x00, 0x03, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xb1, 0x61, 0x51, 0x8e, 0x0e, 0x19, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x26 = {image_data_Arial16_0x26, 9, 20};
const unsigned char image_data_Arial16_0x27[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x27 = {image_data_Arial16_0x27, 3, 20};
const unsigned char image_data_Arial16_0x28[] PROGMEM =
{
0x00, 0x00, 0x03, 0x04, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0xc0, 0x20,
};
tImage Arial16_0x28 = {image_data_Arial16_0x28, 4, 20};
const unsigned char image_data_Arial16_0x29[] PROGMEM =
{
0x04, 0x03, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x20, 0xc0, 0x00, 0x00,
};
tImage Arial16_0x29 = {image_data_Arial16_0x29, 4, 20};
const unsigned char image_data_Arial16_0x2a[] PROGMEM =
{
0x02, 0x02, 0x07, 0x02, 0x02, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x2a = {image_data_Arial16_0x2a, 5, 20};
const unsigned char image_data_Arial16_0x2b[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x2b = {image_data_Arial16_0x2b, 7, 20};
const unsigned char image_data_Arial16_0x2c[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00,
};
tImage Arial16_0x2c = {image_data_Arial16_0x2c, 4, 20};
const unsigned char image_data_Arial16_0x2d[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x2d = {image_data_Arial16_0x2d, 4, 20};
const unsigned char image_data_Arial16_0x2e[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x2e = {image_data_Arial16_0x2e, 4, 20};
const unsigned char image_data_Arial16_0x2f[] PROGMEM =
{
0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x1c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x2f = {image_data_Arial16_0x2f, 5, 20};
const unsigned char image_data_Arial16_0x30[] PROGMEM =
{
0x01, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0xfc, 0x02, 0x01, 0x01, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x30 = {image_data_Arial16_0x30, 7, 20};
const unsigned char image_data_Arial16_0x31[] PROGMEM =
{
0x00, 0x00, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x31 = {image_data_Arial16_0x31, 7, 20};
const unsigned char image_data_Arial16_0x32[] PROGMEM =
{
0x03, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x03, 0x05, 0x09, 0x11, 0x21, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x32 = {image_data_Arial16_0x32, 7, 20};
const unsigned char image_data_Arial16_0x33[] PROGMEM =
{
0x03, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x06, 0x01, 0x21, 0x21, 0x52, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x33 = {image_data_Arial16_0x33, 7, 20};
const unsigned char image_data_Arial16_0x34[] PROGMEM =
{
0x00, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x18, 0x28, 0xc8, 0x08, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x34 = {image_data_Arial16_0x34, 7, 20};
const unsigned char image_data_Arial16_0x35[] PROGMEM =
{
0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0xe6, 0x21, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x35 = {image_data_Arial16_0x35, 7, 20};
const unsigned char image_data_Arial16_0x36[] PROGMEM =
{
0x01, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0xfc, 0x22, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x36 = {image_data_Arial16_0x36, 7, 20};
const unsigned char image_data_Arial16_0x37[] PROGMEM =
{
0x04, 0x04, 0x04, 0x04, 0x05, 0x06, 0x00, 0x00, 0x07, 0x38, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x37 = {image_data_Arial16_0x37, 7, 20};
const unsigned char image_data_Arial16_0x38[] PROGMEM =
{
0x01, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0x8c, 0x52, 0x21, 0x21, 0x52, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x38 = {image_data_Arial16_0x38, 7, 20};
const unsigned char image_data_Arial16_0x39[] PROGMEM =
{
0x01, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0xc6, 0x21, 0x11, 0x11, 0x22, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x39 = {image_data_Arial16_0x39, 7, 20};
const unsigned char image_data_Arial16_0x3a[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x3a = {image_data_Arial16_0x3a, 4, 20};
const unsigned char image_data_Arial16_0x3b[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00,
};
tImage Arial16_0x3b = {image_data_Arial16_0x3b, 4, 20};
const unsigned char image_data_Arial16_0x3c[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x50, 0x50, 0x88, 0x88, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x3c = {image_data_Arial16_0x3c, 8, 20};
const unsigned char image_data_Arial16_0x3d[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x3d = {image_data_Arial16_0x3d, 8, 20};
const unsigned char image_data_Arial16_0x3e[] PROGMEM =
{
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x88, 0x88, 0x50, 0x50, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x3e = {image_data_Arial16_0x3e, 8, 20};
const unsigned char image_data_Arial16_0x3f[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x3f = {image_data_Arial16_0x3f, 16, 20};
const unsigned char image_data_Arial16_0x40[] PROGMEM =
{
0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x7e, 0x81, 0x7e, 0x81, 0x81, 0x82, 0x4e, 0xf1, 0x01, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x20, 0x20, 0x20, 0x40, 0x40, 0x80, 0x00,
};
tImage Arial16_0x40 = {image_data_Arial16_0x40, 13, 20};
const unsigned char image_data_Arial16_0x41[] PROGMEM =
{
0x00, 0x00, 0x00, 0x03, 0x04, 0x03, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x70, 0x90, 0x10, 0x90, 0x70, 0x0e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x41 = {image_data_Arial16_0x41, 9, 20};
const unsigned char image_data_Arial16_0x42[] PROGMEM =
{
0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0xff, 0x21, 0x21, 0x21, 0x21, 0x21, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x42 = {image_data_Arial16_0x42, 9, 20};
const unsigned char image_data_Arial16_0x43[] PROGMEM =
{
0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0xfc, 0x02, 0x01, 0x01, 0x01, 0x02, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x43 = {image_data_Arial16_0x43, 9, 20};
const unsigned char image_data_Arial16_0x44[] PROGMEM =
{
0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0xff, 0x01, 0x01, 0x01, 0x01, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x44 = {image_data_Arial16_0x44, 9, 20};
const unsigned char image_data_Arial16_0x45[] PROGMEM =
{
0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0xff, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x45 = {image_data_Arial16_0x45, 9, 20};
const unsigned char image_data_Arial16_0x46[] PROGMEM =
{
0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0xff, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x46 = {image_data_Arial16_0x46, 8, 20};
const unsigned char image_data_Arial16_0x47[] PROGMEM =
{
0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0xfc, 0x02, 0x01, 0x01, 0x11, 0x11, 0x11, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x47 = {image_data_Arial16_0x47, 10, 20};
const unsigned char image_data_Arial16_0x48[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x48 = {image_data_Arial16_0x48, 9, 20};
const unsigned char image_data_Arial16_0x49[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x49 = {image_data_Arial16_0x49, 3, 20};
const unsigned char image_data_Arial16_0x4a[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0e, 0x01, 0x01, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x4a = {image_data_Arial16_0x4a, 7, 20};
const unsigned char image_data_Arial16_0x4b[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0xff, 0x20, 0x40, 0xb0, 0x08, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x4b = {image_data_Arial16_0x4b, 9, 20};
const unsigned char image_data_Arial16_0x4c[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x4c = {image_data_Arial16_0x4c, 7, 20};
const unsigned char image_data_Arial16_0x4d[] PROGMEM =
{
0x00, 0x07, 0x06, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x07, 0x00, 0x00, 0xff, 0x00, 0xe0, 0x1c, 0x03, 0x1c, 0xe0, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x4d = {image_data_Arial16_0x4d, 11, 20};
const unsigned char image_data_Arial16_0x4e[] PROGMEM =
{
0x00, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xff, 0x00, 0xc0, 0x30, 0x08, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x4e = {image_data_Arial16_0x4e, 9, 20};
const unsigned char image_data_Arial16_0x4f[] PROGMEM =
{
0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0xfc, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x4f = {image_data_Arial16_0x4f, 10, 20};
const unsigned char image_data_Arial16_0x50[] PROGMEM =
{
0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x50 = {image_data_Arial16_0x50, 9, 20};
const unsigned char image_data_Arial16_0x51[] PROGMEM =
{
0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0xfc, 0x02, 0x01, 0x01, 0x05, 0x02, 0x06, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
};
tImage Arial16_0x51 = {image_data_Arial16_0x51, 10, 20};
const unsigned char image_data_Arial16_0x52[] PROGMEM =
{
0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0xff, 0x20, 0x20, 0x20, 0x30, 0x38, 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x52 = {image_data_Arial16_0x52, 9, 20};
const unsigned char image_data_Arial16_0x53[] PROGMEM =
{
0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x8c, 0x42, 0x21, 0x21, 0x21, 0x12, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x53 = {image_data_Arial16_0x53, 9, 20};
const unsigned char image_data_Arial16_0x54[] PROGMEM =
{
0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x54 = {image_data_Arial16_0x54, 7, 20};
const unsigned char image_data_Arial16_0x55[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xfc, 0x02, 0x01, 0x01, 0x01, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x55 = {image_data_Arial16_0x55, 9, 20};
const unsigned char image_data_Arial16_0x56[] PROGMEM =
{
0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, 0x80, 0x70, 0x0e, 0x01, 0x0e, 0x70, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x56 = {image_data_Arial16_0x56, 9, 20};
const unsigned char image_data_Arial16_0x57[] PROGMEM =
{
0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x80, 0x7c, 0x03, 0x3c, 0xc0, 0x00, 0xc0, 0x3c, 0x03, 0x7c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x57 = {image_data_Arial16_0x57, 12, 20};
const unsigned char image_data_Arial16_0x58[] PROGMEM =
{
0x04, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x04, 0x01, 0x02, 0x8c, 0x70, 0x50, 0x8c, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x58 = {image_data_Arial16_0x58, 8, 20};
const unsigned char image_data_Arial16_0x59[] PROGMEM =
{
0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x80, 0x60, 0x1f, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x59 = {image_data_Arial16_0x59, 9, 20};
const unsigned char image_data_Arial16_0x5a[] PROGMEM =
{
0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x06, 0x03, 0x05, 0x19, 0x21, 0xc1, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x5a = {image_data_Arial16_0x5a, 7, 20};
const unsigned char image_data_Arial16_0x5b[] PROGMEM =
{
0x00, 0x07, 0x04, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xe0, 0x20, 0x00,
};
tImage Arial16_0x5b = {image_data_Arial16_0x5b, 4, 20};
const unsigned char image_data_Arial16_0x5c[] PROGMEM =
{
0x06, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x1c, 0x03, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x5c = {image_data_Arial16_0x5c, 4, 20};
const unsigned char image_data_Arial16_0x5d[] PROGMEM =
{
0x00, 0x04, 0x07, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x20, 0xe0, 0x00,
};
tImage Arial16_0x5d = {image_data_Arial16_0x5d, 4, 20};
const unsigned char image_data_Arial16_0x5e[] PROGMEM =
{
0x00, 0x01, 0x06, 0x01, 0x00, 0x00, 0x20, 0xc0, 0x00, 0xc0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x5e = {image_data_Arial16_0x5e, 6, 20};
const unsigned char image_data_Arial16_0x5f[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
};
tImage Arial16_0x5f = {image_data_Arial16_0x5f, 7, 20};
const unsigned char image_data_Arial16_0x60[] PROGMEM =
{
0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x60 = {image_data_Arial16_0x60, 4, 20};
const unsigned char image_data_Arial16_0x61[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x89, 0x89, 0x52, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x61 = {image_data_Arial16_0x61, 7, 20};
const unsigned char image_data_Arial16_0x62[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x42, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x62 = {image_data_Arial16_0x62, 8, 20};
const unsigned char image_data_Arial16_0x63[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x63 = {image_data_Arial16_0x63, 7, 20};
const unsigned char image_data_Arial16_0x64[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x42, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x64 = {image_data_Arial16_0x64, 8, 20};
const unsigned char image_data_Arial16_0x65[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x52, 0x91, 0x91, 0x52, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x65 = {image_data_Arial16_0x65, 8, 20};
const unsigned char image_data_Arial16_0x66[] PROGMEM =
{
0x00, 0x07, 0x04, 0x80, 0xff, 0x80, 0x00, 0x00, 0x00,
};
tImage Arial16_0x66 = {image_data_Arial16_0x66, 3, 20};
const unsigned char image_data_Arial16_0x67[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x42, 0xff, 0x00, 0x00, 0xc0, 0x20, 0x20, 0x20, 0x40, 0x80, 0x00,
};
tImage Arial16_0x67 = {image_data_Arial16_0x67, 8, 20};
const unsigned char image_data_Arial16_0x68[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x40, 0x80, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x68 = {image_data_Arial16_0x68, 7, 20};
const unsigned char image_data_Arial16_0x69[] PROGMEM =
{
0x00, 0x04, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x69 = {image_data_Arial16_0x69, 3, 20};
const unsigned char image_data_Arial16_0x6a[] PROGMEM =
{
0x00, 0x04, 0x00, 0x00, 0xff, 0x00, 0x20, 0xe0, 0x00,
};
tImage Arial16_0x6a = {image_data_Arial16_0x6a, 3, 20};
const unsigned char image_data_Arial16_0x6b[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x10, 0x30, 0x4c, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x6b = {image_data_Arial16_0x6b, 7, 20};
const unsigned char image_data_Arial16_0x6c[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x6c = {image_data_Arial16_0x6c, 3, 20};
const unsigned char image_data_Arial16_0x6d[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x40, 0x80, 0x80, 0x7f, 0xc0, 0x80, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x6d = {image_data_Arial16_0x6d, 11, 20};
const unsigned char image_data_Arial16_0x6e[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x40, 0x80, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x6e = {image_data_Arial16_0x6e, 7, 20};
const unsigned char image_data_Arial16_0x6f[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x6f = {image_data_Arial16_0x6f, 8, 20};
const unsigned char image_data_Arial16_0x70[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x42, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x70 = {image_data_Arial16_0x70, 8, 20};
const unsigned char image_data_Arial16_0x71[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x42, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
};
tImage Arial16_0x71 = {image_data_Arial16_0x71, 8, 20};
const unsigned char image_data_Arial16_0x72[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x72 = {image_data_Arial16_0x72, 4, 20};
const unsigned char image_data_Arial16_0x73[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x91, 0x91, 0x89, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x73 = {image_data_Arial16_0x73, 7, 20};
const unsigned char image_data_Arial16_0x74[] PROGMEM =
{
0x00, 0x07, 0x00, 0x80, 0xff, 0x81, 0x00, 0x00, 0x00,
};
tImage Arial16_0x74 = {image_data_Arial16_0x74, 3, 20};
const unsigned char image_data_Arial16_0x75[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x01, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x75 = {image_data_Arial16_0x75, 7, 20};
const unsigned char image_data_Arial16_0x76[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x0e, 0x01, 0x0e, 0x70, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x76 = {image_data_Arial16_0x76, 7, 20};
const unsigned char image_data_Arial16_0x77[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3c, 0x03, 0x3c, 0xc0, 0x3c, 0x03, 0x3c, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x77 = {image_data_Arial16_0x77, 9, 20};
const unsigned char image_data_Arial16_0x78[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x66, 0x18, 0x66, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x78 = {image_data_Arial16_0x78, 7, 20};
const unsigned char image_data_Arial16_0x79[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x0e, 0x01, 0x0e, 0x70, 0x80, 0x00, 0x20, 0x20, 0xc0, 0x00, 0x00, 0x00,
};
tImage Arial16_0x79 = {image_data_Arial16_0x79, 7, 20};
const unsigned char image_data_Arial16_0x7a[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x99, 0xa1, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
tImage Arial16_0x7a = {image_data_Arial16_0x7a, 7, 20};
const unsigned char image_data_Arial16_0x7b[] PROGMEM =
{
0x00, 0x07, 0x04, 0x00, 0x08, 0xf7, 0x00, 0x00, 0x00, 0xe0, 0x20, 0x00,
};
tImage Arial16_0x7b = {image_data_Arial16_0x7b, 4, 20};
const unsigned char image_data_Arial16_0x7c[] PROGMEM =
{
0x00, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0x00,
};
tImage Arial16_0x7c = {image_data_Arial16_0x7c, 3, 20};
const unsigned char image_data_Arial16_0x7d[] PROGMEM =
{
0x04, 0x07, 0x00, 0x00, 0x00, 0xf7, 0x08, 0x00, 0x20, 0xe0, 0x00, 0x00,
};
tImage Arial16_0x7d = {image_data_Arial16_0x7d, 4, 20};
const unsigned char image_data_Arial16_0x7e[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x40, 0x60, 0x20, 0x20, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
tImage Arial16_0x7e = {image_data_Arial16_0x7e, 8, 20};
const unsigned char image_data_Arial16_circle[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
tImage Arial16_circle = {image_data_Arial16_circle, 16, 20};
tChar Arial16_array[] =
{
{&Arial16_0x20},
{&Arial16_0x21},
{&Arial16_0x22},
{&Arial16_0x23},
{&Arial16_0x24},
{&Arial16_0x25},
{&Arial16_0x26},
{&Arial16_0x27},
{&Arial16_0x28},
{&Arial16_0x29},
{&Arial16_0x2a},
{&Arial16_0x2b},
{&Arial16_0x2c},
{&Arial16_0x2d},
{&Arial16_0x2e},
{&Arial16_0x2f},
{&Arial16_0x30},
{&Arial16_0x31},
{&Arial16_0x32},
{&Arial16_0x33},
{&Arial16_0x34},
{&Arial16_0x35},
{&Arial16_0x36},
{&Arial16_0x37},
{&Arial16_0x38},
{&Arial16_0x39},
{&Arial16_0x3a},
{&Arial16_0x3b},
{&Arial16_0x3c},
{&Arial16_0x3d},
{&Arial16_0x3e},
{&Arial16_0x3f},
{&Arial16_0x40},
{&Arial16_0x41},
{&Arial16_0x42},
{&Arial16_0x43},
{&Arial16_0x44},
{&Arial16_0x45},
{&Arial16_0x46},
{&Arial16_0x47},
{&Arial16_0x48},
{&Arial16_0x49},
{&Arial16_0x4a},
{&Arial16_0x4b},
{&Arial16_0x4c},
{&Arial16_0x4d},
{&Arial16_0x4e},
{&Arial16_0x4f},
{&Arial16_0x50},
{&Arial16_0x51},
{&Arial16_0x52},
{&Arial16_0x53},
{&Arial16_0x54},
{&Arial16_0x55},
{&Arial16_0x56},
{&Arial16_0x57},
{&Arial16_0x58},
{&Arial16_0x59},
{&Arial16_0x5a},
{&Arial16_0x5b},
{&Arial16_0x5c},
{&Arial16_0x5d},
{&Arial16_0x5e},
{&Arial16_0x5f},
{&Arial16_0x60},
{&Arial16_0x61},
{&Arial16_0x62},
{&Arial16_0x63},
{&Arial16_0x64},
{&Arial16_0x65},
{&Arial16_0x66},
{&Arial16_0x67},
{&Arial16_0x68},
{&Arial16_0x69},
{&Arial16_0x6a},
{&Arial16_0x6b},
{&Arial16_0x6c},
{&Arial16_0x6d},
{&Arial16_0x6e},
{&Arial16_0x6f},
{&Arial16_0x70},
{&Arial16_0x71},
{&Arial16_0x72},
{&Arial16_0x73},
{&Arial16_0x74},
{&Arial16_0x75},
{&Arial16_0x76},
{&Arial16_0x77},
{&Arial16_0x78},
{&Arial16_0x79},
{&Arial16_0x7a},
{&Arial16_0x7b},
{&Arial16_0x7c},
{&Arial16_0x7d},
{&Arial16_0x7e}
};
tFont Arial16 = {Arial16_array};
для работы с пропорциональным шрифтом.
В конечном итоге, с использованием всех описанных выше файлов был оформлен графический интерфейс проекта. Причём, было решено разбить его на две части:
• прорисовка значений времени, даты и температуры (файлы text.h и text.cpp).
• общая прорисовка меню и управляющий интерфейс (файлы display.h и display.cpp).
Такое разбиение обусловлено не только объёмом кода, но и соображениями о возможности использования файлов text в других проектах без внесения особых изменений.
Думаю, из комментариев и названий функций не сложно понять их назначение.
Рассмотрим детальнее функции из device.cpp.
1.
• присваивает значение 0x0f полям структуры menu, хранящим предыдущие значения времени, даты и температуры для предотвращения непрорисовки соответствующего параметра в случае, если при первом считывании его значение равно нулю,
• прорисовывает меню из Рисунка 2.
2.
— непосредственно функция прорисовки меню, результат исполнения которой зависит от текущего значения menu.name.
3.
— функция прорисовки рамки в тех меню, где предполагается её наличие.
4.
вызывается при каждом прерывании от DS1307 или nRF24L01 и ответственна за обновление в меню из Рисунка 2 значений времени, даты, температуры, а также цвета символа двоеточия.
5.
• первоначальной прорисовки меню из Рисунка 3 — при длительном нажатии на кнопку в основном режиме ЦМ,
• перехода к меню из Рисунка 4 или 5, либо возврата к меню из Рисунка 2 — при коротком нажатии на кнопку.
6.
• изменение на экране дисплея значений того или иного параметра, а также движение рамки в меню из Рисунка 4 — при повороте ротора и коротком нажатии на кнопку.
• установку в 1 значения поля menu.TSsaveFlag и возврат к меню из Рисунка 3 при выборе пункта «save» меню из Рисунка 4.
7.
ответственны за те же действия, что и функции из п.6, но для меню из Рисунка 5.
Общее управление ЦМ осуществляется функциями из файлов device.
1. В обработчиках прерываний от nRF24L01 и DS1307 лишь устанавливаются в 1 значения полей device.payloadReceivedFlag и device.colonBlinkFlag, соответственно.
2. В функции
• локально и глобально разрешаются прерывания.
3. В функции
• выбор пункта «save» меню из Рисунков 4 и 5.
4. Функция
считывает из DS1307 текущее значение времени, а затем помещает значения десятков и единиц часов и минут в соответствующие поля структуры menu.
5. Функция
«склеивает» значения десятков и единиц часов и минут, выбранных в меню из Рисунка 4, а затем записывает их в RTC.
6. Функции
производят те же действия, что и две предыдущие, только по отношению к значениям даты.
7. Функция
вычленяет из двух полученных от ПМ байтов значения знака, десятков, единиц и десятых долей текущей температуры и размещает их в соответствующих полях структуры menu.
Код управления ПМ занимает 4.8 кБайт флэш-памяти и 10 байт ОЗУ.
За корректную работу DS18B20, даташит которого выложен в архив статьи, отвечает код следующих файлов.
1. Поскольку в ПМ используется лишь один датчик, для обращения к нему выбрана общая команда
.
2. Посредством команды
запускается измерение датчиком температуры. При этом, требуется задержка в 750 мс, поскольку дефолтное разрешение DS18B20 – 12 бит (смотрите Таблицу 2 даташита).
3. Команда
позволяет считать данные из памяти датчика. В рамках проекта достаточно чтения первых двух байт, в которых и содержится значение температуры.
4. Результат измерения возвращается в формате float. Однако, при необходимости можно воспользоваться и непосредственно значениями считанных байтов, для хранения которых предусмотрено поле
класса. Именно этот вариант и реализован в проекте.
Для контроля за трансивером ПМ применялась та же библиотека nRF24, что и в случае с ЦМ.
лишь для передачи текущего значения температуры.
С целью максимально снизить энергопотребление ATtiny85 оформлены файлы sleep, представленные ниже.
предназначена для подсчёта количества прерываний сторожевого таймера, а макроопределение WDT_COUNTER_MAX задаёт её максимальное значение.
• включается сторожевой таймер с периодом счёта 8 секунд, а так же разрешается его прерывание,
».
Общий контроль за работой ПМ осуществляется посредством файлов device, код которых приведён ниже.
, из которого выводится посредством прерывания сторожевого таймера. Поскольку максимальный период счёта последнего составляет 8 секунд, в обработчике прерывания происходит инкремент переменной wdtCounter и лишь по достижению ею значения
(т.е. один раз в час) микроконтроллер:
• сам погружается в сон.
Все элементы ЦМ уместились в корпусе размером 66х66х50 мм, а ПМ — 53х53х25 мм. Детали корпусов обоих модулей и ручка энкодера были смоделированы в онлайн-среде
и распечатаны на 3-D принтере ANYCUBIC I3 MEGA, а их объектные файлы выложены в архив статьи.