Занимательная электроника — страница 120 из 128


Контроллер WS0010

Модернизированный вариант стандартного контроллера HD44780 от Winstar носит незамысловатое наименование WS0010. Главное отличие его от стандартного заключается в наличии нескольких встроенных таблиц шрифтов, из-за чего управление этим дисплеем усложняется, и нам придется немного модернизировать стандартную библиотеку LiquidCrystal. Но проблема заключается не в одних только шрифтах — как водится, что-то улучшив, разработчики что-то и ухудшили.

Для начала следует увеличить задержку после включения питания перед инициализацией. В оригинале, согласно спецификации на традиционный контроллер HD44780, она составляет 50 мс, но для версии WS0010 этого недостаточно — документация требует минимум 500 мс. Если это исправление не внести, то и без того плохо отработанный контроллер будет «глючить» вплоть до полной неработоспособности: после включения вместо символов появятся произвольные картинки, они могут бегать по экрану и мерцать. Капризность дисплеев фирмы Winstar отмечали многие, но, к сожалению, доступную замену сыскать очень сложно.

Для увеличения задержки разыщите в папке libraries/LiquidCrystal файл LiquidCrystal.cpp. Первым делом сделайте его копию, сохранив ее, например, как LiquidCrystal.cpp.bak. Затем откройте его через Блокнот, и в тексте функции

void LiquidCrystal::begin найдите строку

delayMicroseconds(50000);

В оригинальном файле эта строка имеет номер 100. Измените число 50000 (50 мс) на 800000 (0,8 секунды) и сохраните файл. После этого нужно заново откомпилировать программы Arduino, применяющие эту библиотеку. В том числе можно это сделать и для старого типа контроллеров, если у вас такие программы имеются, — увеличение задержки при включении ничему не помешает.

Крупный недостаток этих дисплеев — ни в традиционном HD44780, ни в новом WS0010 не предусмотрено наличие аппаратного Reset. Потому при первом запуске после перепрограммирования вы, скорее всего, получите на дисплеях сплошной мусор. Кнопку Reset контроллера для перезапуска применять бессмысленно — дисплей-то при этом не перезапускается, а устанавливается в непредсказуемое состояние. Обычно помогает перезапуск отключением питания — выдергивание USB-кабеля с последующей вставкой сетевого адаптера вместо него.

Если полностью избавиться от мусора при включении станции все-таки не удается (это, кроме всего прочего, зависит и от конкретного экземпляра индикатора), то поставьте на задней панели станции кнопку с двумя парами перекидных контактов, одной парой размыкающую линию питания индикатора при нажатии, а второй в это же время замыкающей на землю вывод Reset контроллера. При отладке все время дергать USB-кабель неудобно, но в этом случае можно просто выдергивать проводок питания индикатора с последующим перезапуском контроллера кнопкой Reset на плате. Описанный в главе 21 графический дисплей MT-12864J, у которого есть нормальный аппаратный перезапуск, таких сложностей не требует, — его вывод Reset просто соединяется с выводом Reset платы Arduino (как и показано на рис. 21.4).

* * *

Заметки на полях

Отмечу; что от одного «глюка» индикаторов WEH001602B мне так и не удалось избавиться: какую из двух строк в операторе setCursor считать строкой 0, а какую строкой 1 — почему-то это зависит от характера питания. При питании всей схемы от USB нулевой строкой преимущественно оказывается нижняя, а при питании от адаптера 7,5 В — всегда верхняя, что надо учитывать при программировании.


Пишем по-русски

Далее нужно разобраться с русским языком — модели дисплеев с новым контроллером WS0010 русифицируются переключением кодовой таблицы, что в стандартной библиотеке LiquidCrystal не предусмотрено. Введением таких таблиц в фирме Winstar кардинально решили проблему национальных прошивок: 255 символов на все языки не хватает, а применение Unicode в восьмиразрядном контроллере весьма затруднено. Ранее в каждый регион приходилось поставлять дисплеи со своим языком, что вызывало понятные трудности у потребителя.

С контроллером WS0010 этого не требуется, в нем уже записаны четыре таблицы: ENGLISH_JAPANESE, две таблицы WESTERN EUROPEAN и ENGLISH_RUSSIAN. Выбор осуществляется переключением двух специальных битов FT (font table), которые в старом варианте просто не задействованы и не должны ничему мешать, — в силу чего отредактированная библиотека должна быть полностью совместима со старыми типами дисплеев. Если они все-таки мешать будут (автор, естественно, никакой гарантии дать не может), то придется использовать два варианта библиотеки или усложнять ее введением специальной функции установки font_table. Здесь же мы просто добавим одну лишнюю строку в тот же файл LiquidCrystal.срр.

Для объявления кириллической таблицы шрифтов найдите в файле начало функции void LiquidCrystal::begin. Там, внутри оператора if (lines > 1), имеется строка номер 87: _displayfunction |= LCD_2Line;. Сразу после нее (перед замыкающей операторной скобкой «}») вставьте еще одну строку:

_displayfunction |= 0x02; //russian codetable

Она устанавливает биты FT в состояние 1:0, соответствующее таблице ENGLISH_RUSSIAN. Сами коды кириллических символов одинаковы и для старого варианта HD44780 с «прошитой» русской таблицей, и для нового WS0010 (табл. 22.1). Подогнать под кодировку UTF-8 здесь их не удастся (и исправить перечеркнутый ноль тоже). В отличие от таблицы ASCII, в этих таблицах указаны только кириллические символы, отличающиеся от английских, потому в функции print () совпадающие буквы в обоих языках можно указывать напрямую, как обычно, а кириллические придется вставлять указанием их числового кода.

В табл. 22.1 приведены шестнадцатеричные коды символов (в строке записываются с предваряющим ), а также восьмеричные. В тексте программ на основе и без того совершенно нечитаемого языка С, на мой взгляд, восьмеричные выглядят компактнее, потому что требуют одного лишь предваряющего обратного слэша.



Обычные символы и коды можно писать вперемешку. Например, процедура замены английских названий дней недели на русские при выводе показаний часов DS1307 (см. далее) будет выглядеть, как показано в листинге далее. Сами часы выдают дни недели в цифровом виде, а соответствующие им англоязычные константы MON, TUE и т. п. уже определены в файле ds1307.h.



Подключение библиотеки LiquidCrystal

После подключения библиотеки LiquidCrystal к программе ее необходимо инициализировать, причем с указанием реальных контактов, к которым присоединяются выводы выбора индикатора RS, разрешения Е и линии данных. Индикаторы на базе HD44780 могут подключаться как по восьмипроводной, так и по четырехпроводной линии данных. Все реальные библиотеки в целях экономии числа соединений, естественно, выбирают второй способ. В нашем случае таких индикаторов два: четыре линии данных у них будут общие, а линии RS и Е различаются — ими мы будем обеспечивать выбор текущего дисплея.

Таким образом, тестовая программа для двух дисплеев WEH001602В, подключенных согласно схеме на рис. 22.1, будет выглядеть следующим образом:



Часы реального времени DS-1307

Модуль часов реального времени RTC на основе микросхемы DS-1307, предлагаемый в «Амперке», имеет один недостаток — к нему требуется батарейка редко встречающегося в продаже типоразмера CR1225, которую придется приобретать отдельно. Проблемой в дальнейшем это, однако, не станет: согласно спецификации, DS-1307 потребляют ток 0,5 мкА, так что в теории этой батарейки при ее емкости 48 мА-ч должно хватать примерно лет на десять — больше, чем ее гарантийный срок хранения. Надо учесть, что без установленной батарейки часы неработоспособны, и их не удастся даже запрограммировать.

Сам модуль представляет собой практически «голую» микросхему DS-1307 с установленными резисторами «подтяжки» для интерфейса 12С. К Arduino модуль подключается через штатные выводы аппаратного I2C (TWI) MK AVR, т. е. через контакты платы Arduino А4 (SDA) и А5 (SCL). Доступ к этому интерфейсу реализован в стандартной библиотеке Wire.h, поставляемой вместе со средой Arduino IDE. Подробно об интерфейсе I2С (другое название интерфейса: TWI, Two Wire Interface) можно прочесть в моей книге [21], здесь мы только укажем, что к нему одновременно могут подключаться до 128 устройств (различаются они программно по индивидуальному адресу). Поэтому на схеме к тем же выводам подключен еще и барометр, который мы рассмотрим позднее.

* * *

Заметки на полях

Следует отметить, что существует очень много библиотек Arduino для работы с часами DS-1307, и большинство из них не используют аппаратный порт I2C, предполагая подключение к другим цифровым выводам. Как рассказывается в моей книге [21], аппаратная реализация I2C (TWI) в AVR действительно оставляет желать лучшего. Но в данном случае мы пойдем именно этим путем — наш барометр тоже применяет тот же способ, а, значит, мы можем сэкономить на выводах, подключив эти устройства к одному и тому же интерфейсу. Что же касается неудобств реализации интерфейса, то все трудности здесь скрыты от нас создателями библиотеки.

* * *

Библиотеку RTC можно скачать с официального сайта Seeed[44]. Все взаимодействие программы с часами заключается в подключении библиотек ds1307.h и Wire.h, вызове функции инициализации clock.begin() и считывании показаний с помощью единственной функции clock.getTime(), которая обеспечивает обновление целого выводка скрытых переменных, таких как clock.hour, clock.minute и т. п. Потому основная проблема в программировании взаимодействия с часами не в том, чтобы периодически читать показания и выводить их на дисплей, а в том, как удобно и корректно организовать их начальную установку и периодическую коррекцию.