Реле Tianbo - ресурс 10 млн переключений

Усовершенствованный барометр-термометр-гигрометр с E-ink дисплеем. Часть 2. Программные средства

Silicon Labs EFM8SB10F8-QFN20

- Москва

Программные средства

Программа в уже готовом загрузочном *.hex-формате (EFM8SB10F8G-A-QFN20_7.hex) приведена в дополнительных материалах к статье в разделе Загрузки. Её можно запрограммировать в МК любым из двух вышеприведенных способов. Однако для тех, кто хочет самостоятельно написать свою программу, автор хотел бы поделиться некоторыми её моментами, в основном связанными с выводом информации на дисплей, поскольку обмен информацией MK с BME280 подробно описан в [1], и, чтобы не повторяться, останавливаться на нём, на взгляд автора, не имеет смысла.

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

E-ink дисплей был приобретён автором на AliExpress по цене чуть менее 300 руб. Ни названия дисплея, ни контроллера, примененного в нем, указано не было. Единственно, что было написано про дисплей, что это 3-цветный (красно-бело-чёрный) E-ink дисплей размером 2.13 дюйма с разрешением 104×212 пикселей. Однако, как оказалось впоследствии, его разрешение было несколько выше, а именно, – 128×250, что немало удивило и обрадовало автора. Контроллер, примененный в дисплее (SSD1675), как указывалось выше, автор определил по отсутствию четвертого контакта на шлейфе. Кроме того, на этом же шлейфе удалось разглядеть и надпись: HINK-E0213A22-A0.

Наиболее полную информацию о программировании E-ink (или E-paper) дисплеев можно найти на сайтах [1] и [2], поскольку из описания контроллера SSD1675 понять, как программируются подобные дисплеи, достаточно проблематично. На этих сайтах приведены примеры программ для плат STM32 (на C), Arduino (на C), Raspberry Pi (на Phyton) и ESP8266 (на C). Вот поистине засилье подобных плат. Хотя непонятно, зачем в таких достаточно мощных в прямом (по потреблению тока в десятки мА) и переносном (по огромному объему программной и оперативной памяти и с 32-разрядными процессорами) смысле устройствах применять E-ink дисплеи. Ведь основное преимущество подобных дисплеев именно в ультранизком потреблении тока в режиме сна. Какой смысл использования дисплея с потреблением тока, например, 0.6 мкА, если сама плата потребляет десятки мА? На взгляд автора, в таких платах имеет смысл использовать OLED-дисплеи, потребляющие 20 – 30 мА, которые существенно дешевле E-ink дисплеев и, кроме того, обновление информации в которых занимает десятые (и даже сотые) доли секунды против нескольких секунд у E-ink дисплеев. Но это уже, как говорят, дело вкуса.

Тем не менее, наличие подобных программ позволяет с их помощью легко запрограммировать E-ink дисплей в более простом, 8-разрядном МК с программной памятью всего 8 КБ, каковым является EFM8SB10F8. Наиболее просты программы на Phyton, поскольку в них вся программа представлена всего одним текстовым *.py-файлом в отличие от программ на C, где имеются бесчисленные дополнительные *.h-файлы, включенные (#include <…>) в основную программу, и «лазить» по этим файлам, чтобы понять работу основной программы, – дело очень неприятное, долгое и неблагодарное.

В основном при программировании E-ink дисплея имеются две проблемы. Первая – это инициализация дисплея. В примерах программ такая инициализация заключается в выводе в дисплей порядка 30 – 35 команд и данных, определяющих разрешение дисплея, установку счетчиков строк и столбцов на начало, различные моменты установки напряжений DC/DC преобразователя, температурные параметры и т.п. и особой сложности не представляет. Для решения этой проблемы нужно просто очень внимательно, без ошибок переписать все эти команды и данные, передаваемые вслед за командами, в свою программу, и всё будет работать.

Иное дело – вывод информации в дисплей. Здесь имеются два варианта. Но прежде чем описывать эти два варианта, сделаем некоторое отступление относительно того, как вообще выводится информация в E-ink дисплей.

Итак, пусть дисплей имеет разрешение, например, 128×250 пикселей (как в нашем случае). В памяти контроллера дисплея информация представляется в виде строк и столбцов. При таком разрешении у дисплея имеются 16 строк шириной по 8 пикселей каждая. Каждый пиксель кодируется одним битом. Другими словами, имеем 16 строк шириной ровно 1 байт, начиная с 0-й и кончая 15-й. Строки располагаются на экране дисплея сверху вниз: 0-я – сверху, 15-я снизу. Кроме того, имеются ровно 250 столбцов, начиная с 0-го и кончая 249-м. Столбцы располагаются на экране слева направо: 0-й слева, 249-й справа. Если умножить количество строк (16) на количество столбцов (250), то получим ровно 4000 байт.

Теперь по поводу размера в пикселях одного символа (цифры или символа размерности, например, градус Цельсия (°C), мм рт. ст. (мм Hg) и т.п.). Пусть при разрешении дисплея 128×250 пикселей каждый символ представляет собой поле размером 48×27 пикселей (см. далее), или, другими словами, 6 однобайтных строк по 27 столбцов (6 × 27 = 162 байта). В этом случае в дисплей можно вывести символы в два ряда по 6 строк каждый и 4 пробельных строки. Например, верхняя строка – пробел, далее 6 строк 1-го ряда, далее – пара пробелов, далее 6 строк 2-го ряда и далее одну пробельную строку. Т.е. имеем 4 пробельных строки и 12 строк символов – всего 16 строк.

В первом варианте для вывода двух рядов символов в дисплее с помощью специальных команд можно сформировать два окна шириной по 6 строк и 250 столбцов каждое. Пусть в первое (верхнее) окно будут выводиться 3 цифры давления (например, «751») и символы «ммHg», а во второе (нижнее) окно будут выводиться: 2 цифры температуры (например, «25»), символ «°C», далее 2 цифры влажности (например, «47»), символ «%» и символ капли с делениями, как часто изображают показатель влажности. Для вывода символов в программной памяти МК (code) сформирован двумерный массив (например, MD [16][162]), где первое измерение (16) – количество символов (10 символов цифр «0» – «9» и 6 символов размерностей: «м», «H», «g», «°C», «%» и символ капли), а второе измерение (162) – это 162 байта, которые кодируют каждый символ.

Вывод символов в окно очень прост. Для этого необходимо указать один из 16 символов (например, 2, в этом случае будет выведена двойка) и далее вывести подряд все 162 байта. Почему подряд? Потому что контроллер дисплея автоматически инкрементирует счетчик строк (их 6) и счетчик столбцов (их 27). Т.е. вначале выводятся 6 байт в 1-й столбец (от 0 до 5), и при этом счетчик строк после вывода каждого байта инкрементируется. Но как только выведется последний байт (под номером 5), счетчик строк автоматически устанавливается в 0, а счетчик столбцов увеличивается на единицу (инкрементируется), т. е. устанавливается на следующий столбец (под номером 1). Таким образом, нет необходимости следить за этими двумя счетчиками, а просто требуется вывести подряд все 162 байта, и каждый байт выведется туда, куда нужно. Здесь необходимо отметить, что подобным образом выводится информация в OLED-дисплеи. Аналогичным образом выводятся все остальные символы 1-го ряда в верхнее окно, а также все символы нижнего ряда во второе окно.

На первый взгляд кажется, что всё очень просто. Однако здесь кроется одна ловушка (по времени). Дело в том, что после того как будет осуществлен вывод в первое окно, необходимо дать команду, которую в программах называют «update» – обновить или «refresh» – освежить (в русском языке есть выражение «освежить в памяти»). На самом деле такая команда означает, что данные, переданные из МК и записанные в памяти контроллера, будут выведены на экран дисплея. А такой вывод занимает около 4.5 секунд. Кроме того, при использовании такого оконного вывода перед ним необходимо очистить весь дисплей, т.е. вывести в память контроллера указанные выше 4000 байт, каждый из которых равен FFh, и сделать подобный «рефреш», который в этом случае займёт около 3.5 секунд. Таким образом, общее время вывода двух окон и очистки дисплея займет: 3.5 с + 4.5 с + 4.5 с = 12.5 с. При этом дисплей будет работать по полной программе и, естественно, потреблять значительный ток (до нескольких мА). В связи с этим, автор задался следующим вопросом. Если очистка дисплея с «рефрешем» занимает 3.5 секунды, нельзя ли вместо использования оконного вывода просто вывести сразу всю информацию на дисплей один раз, и один раз дать команду «рефреш». Тогда это займёт всего 3.5 секунды. Но как это сделать? Идея заключается в следующем.

Второй вариант. В самом начале выводится весь столбец, в котором содержатся все 16 байт и который занимает всю ширину дисплея: выводится один верхний пробел, затем выводятся первые 6 байт первой цифры давления (это 1-й столбец семёрки), затем выводятся два пробела, далее – первые 6 байт первой цифры температуры (это 1-й столбец двойки) и далее – последний пробел. После этого счетчик строк автоматически установится на нулевую строку, а счетчик столбцов увеличится на единицу (инкрементируется). Далее, уже во второй столбец выводим пробел, вторые 6 байт семёрки, 2 пробела, вторые 6 байт двойки и последний пробел. Подобным образом выводятся все 27 столбцов семёрки и двойки. Аналогичным образом выводятся и все остальные символы до конца, т.е. все 4000 байт (как и при очистке дисплея). После этого даётся команда «рефреш», и на этом вывод информации в дисплей заканчивается. Конечно, в программном смысле, подобный вывод несколько сложней, однако он позволяет вывести всю информацию на дисплей за один раз и за 3.5 секунды.

Загрузив программу в МК с подобным выводом информации и запустив её, автор стал следить за дисплеем. Дисплей замигал 3.5 секунды и (о чудо!) на экране появилось сразу всё изображение со всеми данными и символами. Фрагмент программы с подобным «безоконным» выводом на C51 приведен в дополнительных материалах к статье. Из этого фрагмента можно заключить, что подобный вывод информации в дисплей не так уж и сложен.

Теперь по поводу получения кодов цифр и символов. Для этого автор использовал программу GLCD Font Creator v. 1.2.0.0 (от компании MikroElektronika [3]). В ней можно выбрать практически любой шрифт, его параметры (например, размер, свойства – жирный, обычный, наклонный т.п.). Программа сформирует все символы данного шрифта и выведет их на экран. Далее необходимо убрать все пустые строки и столбцы сверху, снизу и справа, чтобы каждый символ вписался в окно определенного размера (в нашем случае это 48×27 пикселей). Это делается специальными опциями с пиктограммами, на которые необходимо навести курсор мыши и кликнуть. Для того чтобы цифры и символы выводились на дисплей слева направо и сверху вниз, каждый символ необходимо перевернуть вверх ногами (отразить по вертикали) и отразить по горизонтали. Это можно сделать всего двумя кликами мыши по соответствующим пиктограммам в меню программы (синий и красный овалы на Рисунке 4). В этом случае, например, двойка будет выглядеть как на Рисунке 4.

Скриншот фрагмента экрана компьютера при работе программы GLCD Font Creator - пиксели цифры «2» (48×27).
Рисунок 4. Скриншот фрагмента экрана компьютера при работе
программы GLCD Font Creator – пиксели цифры «2» (48×27).

После этого, нажав пиктограмму «Export for GLCD» и выбрав в открывшемся окне опцию «microC», получим файл на C (его также следует назвать), в котором будут содержаться все 162 байта для каждого символа. Для цифр был выбран шрифт

Clarendon Condensed размера 49, жирный. Для него был сформирован файл на C с названием:

//GLCD FontName : Clarendon_Condensed27x48
//GLCD FontSize : 27 x 48

который автор и использовал для отображения цифр.

Шрифт Clarendon был выбран по следующим соображениям. Он не такой строгий, как, например, Arial или Courier New, но и не слишком вычурный. По сравнению с Times New Roman жирный, Clarendon значительно «жирней», т.е. чёрные пиксели каждого символа занимают бо́льшую площадь окна 27×48 пикселей, и, естественно, символ легче читается. Кроме того, на взгляд автора, шрифт Clarendon достаточно симпатичный.

Символы, которых нет в этом шрифте, были буквально нарисованы в программе GLCD Font Creator. Это следующие символы: русскaя буква «м» (нарисована), буква «H» (нарисована), буква «g» (взята готовая из шрифта меньшего размера), «°C» («C» была немного сужена и слева пририсован «°»), «%» (нарисован, оригинальный «%» сужен), символ капли с делениями (нарисован). Рисование в программе очень простое: наведя курсор мыши на белый пиксел и нажав левую кнопку, можно получить черный пиксел, а наведя на черный и нажав правую кнопку, – белый.

После трансляции программы в специальном окне среды программирования Simplicity Studio v.4 (от Silicon Laboratories) отобразится результат этой трансляции (сообщение):

Program Size: data=121.1 xdata=0 const=0 code=7693
LX51 RUN COMPLETE. 0 WARNING(S), 0 ERROR(S)
Finished building target: EFM8SB10F8G-A-QFN20_7.omf

Из этого сообщения можно заключить, что в программе использована почти вся внутренняя оперативная память с прямой адресацией объемом 128 байт (data=121.1 байт), а внешняя оперативная память с косвенной адресацией объемом 256 байт не использована (xdata=0). Кодовая часть программы использует почти всю программную память объемом 8 КБ или 8192 байта (code=7693). Остаток программной памяти составляет: 8192 – 7693 = 499 байт  0.5 КБ. Здесь стоит отметить, что автор не делал никаких особенных ухищрений, чтобы сократить программную память, т.е. как программа написана, так и используется. Единственно, на чём автор сэкономил (правда, неумышленно) – на полноценных символах (27×48 пикселей) знака минус и пробела. Дело в том, что перед числом температуры может быть знак минус, тогда перед числом давления должен быть пробел, чтобы первая цифра давления (в вышеприведенном примере это «7») была бы строго над первой цифрой температуры («2» – в примере). Кроме того, после символа «°C» также должен следовать пробел, иначе первая цифра влажности (в примере это «4») будет вплотную «прижата» к символу «°C», что просто недопустимо. Но тогда это потребует установки полноценного пробела после последней цифры давления («1») и первым символом «м», что очень далеко и поэтому не эстетично. В связи с этим было решено полноценный символ пробела (шириной 27 пикселей) заменить «полупробелом», шириной в 14 пикселей. Тогда, если температура положительная, то вначале программно выводятся все 14 пустых столбцов (0xFF), а если отрицательная, то в верхнюю часть столбцов выводим 0xFF, нижнюю часть также заполняем числами 0xFF, кроме её середины, в которую выводим число 0x03 – это ширина минуса в 6 пикселей (03h = 00000011b), т.е. 6 нулей. Длина минуса, естественно, 14 пикселей. Такой «толстый» минус как раз штатно генерируется шрифтом Clarendon Condensed размера 49, жирный. Кроме того, после последней цифры давления вместо пробела выводим 13 пустых столбцов. Это приведет к тому, что символы «ммHg» приблизятся к числу «751» на 14 пикселей, и показание давления станет более читабельным. В таком случае символы пробела и минуса не нужны, и от них можно отказаться, что приведет к экономии 324 байт. Но, повторимся, эта экономия получилась сама собой и была сделана абсолютно неумышленно.

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

И последнее, что следует добавить по поводу программных средств. Если бы программа «не влезла» в 8 КБ, у автора имелся наготове МК EFM8SB20F16 с программной памятью 16 КБ и оперативной – 4 КБ (поэтому и не предпринималось никаких мер по снижению объёма кодовой части программы). Но, как видно из вышеизложенного, этот МК не понадобился. Другими словами, даже с таким дисплеем с относительно высоким разрешением (128×250), имеющим практически типографское качество изображения символов, МК EFM8SB10F8 вполне достаточно.

Разводка и внешний вид плат

Разводка и внешний вид платы МК. (а), (в) - вид со стороны расположения компонентов; (б), (г) - вид с обратной стороны. Разводка и внешний вид платы МК. (а), (в) - вид со стороны расположения компонентов; (б), (г) - вид с обратной стороны.
Разводка и внешний вид платы МК. (а), (в) - вид со стороны расположения компонентов; (б), (г) - вид с обратной стороны. Разводка и внешний вид платы МК. (а), (в) - вид со стороны расположения компонентов; (б), (г) - вид с обратной стороны.
Рисунок 5. Разводка и внешний вид платы МК. (а), (в) – вид со стороны расположения компонентов;
(б), (г) – вид с обратной стороны.

Разводка плат сделана автором с помощью программы Sprint Layout v.6. Файл разводки в формате *.lay6 приведен в разделе Загрузки. Из рисунков разведенных плат МК и дисплея и их внешнего вида (Рисунки 5 и 6) можно заключить, что разводка плат очень проста, а сами платы миниатюрны (размеры всего 12×14 мм и 20×23 мм, соответственно). Здесь следует добавить по поводу платы МК. Если не предполагается программирование МК с помощью COM-порта компьютера, то разъем (X1, Рисунок 1) не нужен, поэтому припаивать его (и сверлить для него отверстия) совсем не обязательно (в данном случае он отсутствует, хотя отверстия для него просверлены). На Рисунке 5в его место справа от двухконтактного разъема питания. Отличительная особенность разводки обеих плат – через все переходные отверстия (со слоя на слой) пропущены либо контакты разъемов, либо ножки выводных компонентов, которые пропаиваются с двух сторон платы. Это позволило не использовать металлизацию отверстий, технология которой в домашних условиях весьма проблематична и поэтому неприемлема.

Разводка и внешний вид платы МК. (а), (в) - вид со стороны расположения компонентов; (б), (г) - вид с обратной стороны. Разводка и внешний вид платы МК. (а), (в) - вид со стороны расположения компонентов; (б), (г) - вид с обратной стороны.
Разводка и внешний вид платы МК. (а), (в) - вид со стороны расположения компонентов; (б), (г) - вид с обратной стороны. Разводка и внешний вид платы МК. (а), (в) - вид со стороны расположения компонентов; (б), (г) - вид с обратной стороны.
Рисунок 6. Разводка и внешний вид платы дисплея. (а), (б) – вид со стороны расположения компонентов;
(в), (г) – вид с обратной стороны.

Конструкция и результаты работы прибора

Устройство в открытом корпусе.
Рисунок 7. Устройство в открытом корпусе.

Прибор (Рисунок 7) сконструирован в достаточно распространённом и недорогом корпусе размером 70×40×33 мм (Sanhe 20-33) с защелкивающейся крышкой (задней стенкой). Дисплей приклеен к стеклотекстолитовой пластине тонким двусторонним скотчем, его шлейф перегнут через прорезанную выемку в пластине и вставлен в разъем платы дисплея, которая, в свою очередь, приклеена к пластине пористой лентой с двусторонним липким слоем, куда такой же лентой приклеена и плата МК. Пластина приклеена такой же лентой к внутренней поверхности корпуса, в котором для дисплея прорезано окно. Плата с BME280 приклеена к боковой поверхности внутри корпуса такой же пористой лентой. Такой же лентой к задней стенке приклеена и батарейка. Для доступа воздуха внутрь корпуса в задней стенке просверлены 10 отверстий диаметром 4 мм. После подключения проводов питания к батарейке задняя стенка защелкивается, и прибор сразу начинает работать (Рисунок 8).

Общий вид работающего прибора.
Рисунок 8. Общий вид работающего прибора.

Для проверки работоспособности прибора при отрицательных температурах он был помещен в морозилку холодильника вместе с уличным термометром примерно на полчаса (Рисунок 9). Как видно, оба прибора показывают одну и ту же температуру –9 °C. Единственное, что автор не учёл в горизонтальном размере прорезанного окна, – символ «минус», поскольку измерение размеров окна производилось по Рисунку 6б, а про «минус» автор забыл. Но все-таки небольшую часть символа «минуса» можно увидеть на Рисунке 9. Можно было бы, конечно, разобрать прибор, отклеить стеклотекстолитовую пластину и расширить окно. Однако автор оставил всё как есть по двум причинам. Во-первых, прибор предназначен не для измерения температуры в морозилке холодильника, а для работы в комнатных условиях (а там минуса нет), во-вторых, памятуя об основной заповеди электронщика «если что-то работает, не трогай этого», автор не стал ничего менять.

Показания уличного термометра и прибора, помещённых в морозилку холодильника.
Рисунок 9. Показания уличного термометра и прибора, помещённых в морозилку холодильника.

Заключение

Применение E-ink дисплея совместно с малогабаритным микропотребляющим МК EFM8SB10F8 и готовым модулем с BME280 позволило сконструировать недорогой прибор небольшого размера, измеряющий атмосферное давление, температуру и влажность. По сравнению с подобным прибором с ЖКИ, описанным в статье [1], прибор может работать от одной таблеточной литиевой батарейки CR2477 в два раза дольше (до 10 лет) и, кроме того, визуализация его показаний существенно улучшена за счет практически типографского качества изображения.

Ссылки

  1. e-paper-display.com
  2. good-display.com
  3. mikroe.com

Литература

  1. Кузьминов А. Барометр-термометр-гигрометр с питанием от таблеточной батарейки.
  2. Кузьминов А. Ю. Связь между компьютером и микроконтроллером. Современные аппаратные и программные средства. М.: «Перо». 2018.
  3. Кузьминов А. Программирование микроконтроллеров EFM8 с помощью встроенного загрузчика программ. Радио. 2018. № 12.

Материалы по теме

  1. Datasheet Bosch Sensortec BME280
  2. Datasheet Silicon Labs EFM8SB10F8-QFN20
  3. Datasheet Nexperia PMEG3010EH
  4. Datasheet Vishay Si1308EDL
  5. Datasheet Good Display GDEH0213Z98

Загрузки

  1. Дополнительные материалы к статье

Содержание цикла «Усовершенствованный барометр-термометр-гигрометр с E-ink дисплеем»

  1. Часть 1. Принципиальные схемы
  2. Часть 2. Программные средства
Электронные компоненты. Бесплатная доставка по России
Для комментирования материалов с сайта и получения полного доступа к нашему форуму Вам необходимо зарегистрироваться.
Имя