Подключение универсального дисплейного модуля TE-ULCD к Arduino
В этой статье описывается схема подключения TE-ULCD к Arduino и его совместное использование с платой расширения Ethernet Shield v2. В процессе изучения модуля получилась библиотека и небольшой скетч получающий из сети Internet и отображающий время в формате UTC, состояние дорожного траффика в Москве, с помощью сервиса Яндекс.пробки, и погоду, с использованием сервиса информеров GisMeteo.
Данный модуль выбран мной как одно из немногих доступных в РФ готовых решений на базе SPI интерфейса, т. е. не требующее много (16-32) пинов для управления.
TE-ULCD выпускается ООО “Терраэлектроника”. Модуль выполнен на основе 3,5” (или 5,6”) цветного графического дисплея с сенсорным экраном и 32-разрядного ARM-7 микроконтроллера. Обслуживание цветного графического дисплея с помощью специализированного микроконтроллера позволяет разделить функции отображения информации и управления и дает возможность обеспечить интерфейс «человек-машина» в различных информационно-управляющих системах. В память программ микроконтроллера на этапе изготовления загружается библиотека графических функций. Функции могут быть вызваны из прикладной программы при помощи SPI-команд. Это значительно упрощает формирование изображения на TFT-дисплее, а также обслуживание сенсорного экрана. Предусмотрена возможность обновления загруженной библиотеки. Для хранения картинок в формате BMP используется карта памяти microSD.
Необходимые компоненты
- Любая Arduino, например Arduino Uno.
- Плата расширения Ethernet Shield v2 или совместимые с ней.
- Монтажная плата (Breadboard) для удобного подключения.
- Пара 10-пиновых шлейфов для подключения к модулю TE-ULCD (можно использовать гибкие перемычки типа мама-папа).
- Три сопротивления номиналом 1,7 КОм (для делителя напряжения).
- Три сопротивления номиналом 3,3 КОм (для делителя напряжения).
- Четыре штырьковых соединителя (для подключения TE-ULCD к монтажной плате).
- Универсальный дисплейный модуль TE-ULCD35 или TE-ULCD56 (разница только в размерах экрана 320х240 или 640х480).
Подключение
Питание дисплейного модуля осуществляется от 5 вольт постоянного тока, в руководстве пользователя производитель указывает номинальный ток 0,2 А. Я измерил потребляемый ток с помощью цифрового блока питания получилось стабильно 0,299 А, так что стоит ориентироваться на 0,3 А. При питании TE-ULCD от ардуино, преобразователь напряжения установленный на плате грелся довольно сильно, поэтому на всякий случай я запитал дисплейный модуль от USB персонального компьютера взяв шнурок от старой мышки. Разъем Х8 TE-ULCD предназначен для подачи питания и имеет следующую распиновку: PIN 1, 3, 7 и 9 - вход 5 В, PIN 2, 4, 6, 8, 10 - GND, PIN5 используется как ключ для контроля правильности подключения. Подавать питание можно на один любой пин +5 В и GND. Подключение ардуино выполняется к разъему Х6 дисплейного модуля, согласно схеме представленной на рисунке. SPI TE-ULCD функционирует с уровнем 3,3 В, поэтому следует согласовать уровни дисплейного модуля и ардуино с помощью простого делителя на резисторах. Так как планируется использовать TE-ULCD и плату расширения Ethernet Shield совместно, для выбора управляемых (ведомых) устройств будут использоваться PIN9 и PIN10 соответственно. PIN9 выбран изходя из удобства подключения и можно использовать любой другой свободный поменяв значение slaveSelectPin в скетче.
Команды записи и чтения TE-ULCD соответствуют настройкам SPI CPOL=1 и CPHA=1, что соответствует SPI_MODE3 для ардуино. Для платы расширения Ethernet Shield v2 настройки SPI соответствуют SPI_MODE0. Эти настройки понадобятся для обращения к соответствующему модулю.
Описание программы
Программа описанная в статье использует специально подготовленную для ардуино библиотеку ULCD. Картинки для TE-ULCD следует записать на microSD.
Описание команд, регистров и сообщений графического модуля TE-ULCD использованные в библиотеке ULCD взяты мной из руководства оператора на модули TE-ULCD35/56. Модуль TE-ULCD поддерживает два режима работы: терминальный и режим работы с использованием библиотеки графических функций (представлен в данном примере).
В настоящее время набор встроенных виджетов (примитивов графического интерфейса пользователя) TE-ULCD включает в себя:
- Frame (0х01). Является обязательным, используется для размещения виджетов.
- Window (0х00). Предназначено для размещения виджетов, обладает заданным набором свойств.
- Panel (0х06). Предназначена для размещения виджетов, обладает заданным набором свойств.
- StaticLine (0х12). Представляет собой линию с тенью, может быть использован для отделения одних компонентов от других.
- Button (0х0А). Позволяет разместить кнопку и выполнить какие-либо действия при нажатии на нее.
- Text (0х07). Служит для отображения текста на экране.
- Bitmap (0х05). Предназначен для вывода на экран изображения в формате bmp.
- RotateControl (0х0В). Предназначен для вывода на экран изображения регулятора в виде вращающегося "колесика".
- Slider (0х0С). Предназначен для вывода на экран изображения регулятора в виде "ползунка".
Использование библиотеки ULCD
В библиотеке ULCD для ардуино реализованы следующие процедуры для работы с универсальным дисплейным модулем TE-ULCD:
ULCD()
- конструктор;void RESET()
- программный сброс модуля;void digitalPortWrite(byte value)
- отправка одного байта от ардуино к TE-ULCD;void LOAD_FONT(byte R, String FileName)
- загрузка шрифта из флеш-памяти TE-ULCD в регистр TE-ULCD;void LOAD_PICTURE(byte R, String FileName)
- загрузка картинки в формате BMP с microSD карты в регистр TE-ULCD;void LOAD_TEXT(byte R, String Text)
- загрузка текстовой строки из ардуино в регистр TE-ULCD;void LOAD_SCRIPT(byte R, byte Number)
- загрузка скрипта из ардуино в регистр TE-ULCD;void SET_SIZE(int X, byte Y)
- установка размера виджета;void SET_POS(int X, byte Y)
- установка позиции (левого нижнего угла) виджета;void SET_BACK_COLOR(byte R, byte G, byte B)
- установка цвета фона виджета;void SET_FONT_COLOR(byte R, byte G, byte B)
- установка цвета шрифта виджета;void SET_FONT(byte R)
- установка шрифта виджета из регистра TE-ULCD;void SET_MAIN(byte R)
- установка виджета главным (применяется только для фрейма);void SET_SCALE(byte min, byte max, byte pos)
- задание минимального, максимального и значения по умолчанию виджета (для слайдера и "колесика");void SET_SCRIPT(byte R)
- установка скрипта для виджета (действия которое будет выполнено TE-ULCD при заданном событии) из регистра TE-ULCD;void SET_TEXT(byte R)
- установка строки для виджета из регистра TE-ULCD;void SET_PICTURE(byte R)
- установка картинки в формате BMP для виджета из регистра TE-ULCD;void SEND_REG(byte R1, byte R2)
- переслать содержимое регистра R2 в R1;void WRITE_REG(byte R, byte value)
- запись значения в указанный регистр TE-ULCD;void CR_WID(byte WidType)
- создание виджета указанного типа (из списка встроенных виджетов TE-ULCD);byte READ(byte R)
- чтение содержимого регистра TE-ULCD;void REPAINT_TEXT(byte R1, byte R2, String Text)
- заменить (перерисовать) текст виджета хранящегося в регистре R1, на текст передаваемый в переменной Text, сохранить текст в регистре R2;- void REPAINT_BMP(byte R1, byte R2) - перерисовать картинку виджета хранимого в регистре R1 на картинку хранимую в регистре R2;
Например фоновый рисунок в программе устанавливается следующим образом:
#include <ULCD.h> ULCD lcd; // ... lcd.LOAD_PICTURE(1, "back.bmp"); //Загружаем картинку с microSD в регистр R1 lcd.CR_WID(5); //Создаем виджет BitMap (для фона) lcd.SET_SIZE(320, 240); //Устанавливаем размер BitMap равным размеру экрана TE-ULCD35 lcd.SET_POS(0, 0); //Устанавливаем позицию BitMap lcd.SET_PICTURE(1); //устанавливаем картинку для виджета из регистра R1
Для удобства пользователя TE-ULCD располагает 32-мя регистрами (R0-R31) общего назначения для хранения указателей на виджеты (картинки, текст, скрипты). При желании указатели можно хранить в ардуино.
Получение состояния дорожного траффика
Сделать свой светофор захотелось сразу после того как увидел подобный в Яндексе, только там он управлялся с ПК, а хочется все таки автономный - только ардуино и Ethernet Shield. Напрямую запрос о состоянии трафика с сервера Яндекс.пробки получить нельзя. Письмо в техподдержку команду Я.пробки тоже не помогло: “Благодарим за внимание к нашему сервису. Мы не поставляем такую информацию. Попробуйте, подключить модуль пробок и использовать элемент управления "Пробки".”
Для получения состояния дорожного трафика я воспользовался информером, точнее картинкой которая передается в нем. Алгоритм действий следующий:
- Подключаемся к серверу (info.maps.yandex.net);
- Посылаем запрос на получение картинки информера:
- Анализируем полученную картинку, она передается в стандарте PNG (0xFF 0xA4 0x00 желтый, 0x3F 0xBB 0x00 зеленый, 0xFF 0x2A 0x00 красный ), наличие цветов уникально для каждого состояния зеленый-желтый-красный (даже более того, считая количество пикселей каждого цвета можно определить балл пробок, а не только цвет);
- Отображаем картинку на экране TE-ULCD.
Запрос картинки информера имеет следующий вид:
GET http://info.maps.yandex.net/traffic/moscow/current_traffic_88.gif HTTP/1.1 Accept: image/gif Accept-Language: en-US; Cache-Control: max-age=0 Host: info.maps.yandex.net User-Agent: Chrome
Данный запрос подходит для Москвы, но можно запрашивать состояние траффика в любом городе для которого работает сервис информеров Я.пробки. Данный блок с небольшой доработкой можно использовать для управления собственным светофором с помощью ардуино и реле, будет как в Яндексе :).
Получение времени
Самый простой и легкий способ получения времени в формате UTC - послать запрос на какой либо сервер (сначала я использовал гугл, но потом для экономии памяти перешел на сервер яндекс.пробки) и разобрать ответ, получаемая таким образом строка имеет вид:
Wed, 10 Aug 2011 09:48:43 GMT.
В настоящий момент запрос для получения времени выглядит так:
GET http://info.maps.yandex.net/traffic/moscow HTTP/1.1
Точность такого времени не высока - до минут, но для простых часов подходит.
Получение прогноза погоды
Для получения прогноза погоды на ближайшие сутки я использовал сервис получения информера от GisMeteo в XML формате. Данные о погоде представляют из себя подробную сводку по всем метеопараметрам, с шагом 6 часов и заблаговременностью одни сутки. Тут все просто, указываем в запросе город и получаем в ответ для него прогноз погоды, разбираем его и отображаем на экране прогноз на ближайшие 6 часов.
Пример запроса погоды для города Москвы:
GET http://informer.gismeteo.ru/xml/27612_1.xml
Дальнейшее усовершенствование
Представленный прототип является первым шагом к созданию самостоятельного устройства - информатора или интернет часов-информеров способных отображать текстовые сообщения, новости, отображать уведомления, проверять почту и т. п. автономно без подключения ПК. Требующем только Ethernet и питание от адаптера.
Возможные дальнейшие шаги:
- Добавить отображение балла Яндекс.пробок.
- Заменить ардуино и Ethernet Shield на Arduino Ethernet PoE, тогда останется только шнур Ethernet.
- Добавить оповещение о новых письмах и твитах.
- Попробовать вариант с Wi-Fi модулем, тогда останется только шнур питания.
- Подключить внешние датчики и отображать их состояние (температура и влажность, давление, освещенность).
- Отображать RSS и курсы валют.
- Будильник (можно настраиваемый через интернет), потребуется добавить баззер или пьезо-пищалку.
При работе с большими строками столкнулся с переполнением SRAM, для отслеживания состояния памяти переменных я использовал функцию freeRam возвращающую значение свободной памяти в байтах.
int freeRam () { extern int __heap_start, *__brkval; int v; return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); }
Если кто то подскажет как можно улучшить программу буду благодарен :), для обсуждений есть ветка форума на Амперке.