====== Подключение универсального дисплейного модуля TE-ULCD к Arduino ======
В этой статье описывается схема подключения TE-ULCD к Arduino и его совместное
использование с платой расширения Ethernet Shield v2. В процессе изучения модуля
получилась библиотека и небольшой скетч получающий из сети Internet и отображающий время в формате
UTC, состояние дорожного траффика в Москве, с помощью сервиса Яндекс.пробки, и погоду,
с использованием сервиса информеров GisMeteo.
Данный модуль выбран мной как одно из немногих доступных в РФ готовых решений
на базе SPI интерфейса, т. е. не требующее много (16-32) пинов для управления.
TE-ULCD выпускается ООО “Терраэлектроника”. Модуль выполнен на основе 3,5”
(или 5,6”) цветного графического дисплея с сенсорным экраном и 32-разрядного
ARM-7 микроконтроллера. Обслуживание цветного графического дисплея с помощью
специализированного микроконтроллера позволяет разделить функции отображения
информации и управления и дает возможность обеспечить интерфейс «человек-машина»
в различных информационно-управляющих системах.
{{ :схемы-подключения:te-ulcd.jpg?nolink& |}}
В память программ микроконтроллера на этапе изготовления загружается библиотека
графических функций. Функции могут быть вызваны из прикладной программы при помощи
SPI-команд. Это значительно упрощает формирование изображения на TFT-дисплее,
а также обслуживание сенсорного экрана. Предусмотрена возможность обновления
загруженной библиотеки. Для хранения картинок в формате BMP используется карта
памяти microSD.
===== Необходимые компоненты =====
- Любая [[amp>collection/arduino|Arduino]], например [[amp>product/arduino-uno|Arduino Uno]].
- Плата расширения [[amp>product/arduino-ethernet-shield|Ethernet Shield v2]] или совместимые с ней.
- Монтажная плата ([[amp>product/breadboard|Breadboard]]) для удобного подключения.
- [[amp>product/jumper-wires|Набор перемычек]] и/или [[amp>product/wire-mm|соединительные провода]].
- Пара 10-пиновых шлейфов для подключения к модулю TE-ULCD (можно использовать [[amp>product/wire-fm|гибкие перемычки типа мама-папа]]).
- Три сопротивления номиналом 1,7 КОм (для делителя напряжения).
- Три сопротивления номиналом 3,3 КОм (для делителя напряжения).
- Четыре [[amp>product/pin-headers|штырьковых соединителя]] (для подключения 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.
{{ :схемы-подключения:te-ulcd_back.png?nolink& |}}
Подключение ардуино выполняется к разъему Х6 дисплейного модуля, согласно схеме представленной на рисунке. SPI TE-ULCD функционирует с уровнем 3,3 В, поэтому следует согласовать уровни дисплейного модуля и ардуино с помощью простого [[схемотехника:делитель-напряжения|делителя на резисторах]].
{{ :схемы-подключения:te-ulcd_connect_scheme.png?nolink& |}}
Так как планируется использовать TE-ULCD и плату расширения Ethernet Shield совместно, для выбора управляемых (ведомых) устройств будут использоваться PIN9 и PIN10 соответственно. PIN9 выбран изходя из удобства подключения и можно использовать любой другой свободный поменяв значение slaveSelectPin в скетче.
Команды записи и чтения TE-ULCD соответствуют настройкам SPI CPOL=1 и CPHA=1, что соответствует SPI_MODE3 для ардуино. Для платы расширения Ethernet Shield v2 настройки SPI соответствуют SPI_MODE0. Эти настройки понадобятся для обращения к соответствующему модулю.
===== Описание программы =====
{{:схемы-подключения:te-ulcd1.1.zip|Программа}} описанная в статье использует специально подготовленную для ардуино библиотеку {{:схемы-подключения:ulcd.zip|ULCD}}.
{{:схемы-подключения:te-ulcd_pic.zip|Картинки}} для TE-ULCD следует записать на microSD.
Описание команд, регистров и сообщений графического модуля TE-ULCD использованные
в библиотеке ULCD взяты мной из [[http://www.terraelectronica.ru/files/modules/ulcd35/manual_operator_v7.pdf|руководства оператора]] на модули TE-ULCD35/56.
Модуль TE-ULCD поддерживает два режима работы: терминальный и режим работы с
использованием библиотеки графических функций (представлен в данном примере).
{{ :схемы-подключения:arduino-te-ulcd.jpg?nolink& |}}
В настоящее время набор встроенных виджетов (примитивов графического интерфейса
пользователя) 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.zip|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 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);
- Посылаем запрос на получение [[http://info.maps.yandex.net/traffic/moscow/current_traffic_88.gif|картинки информера]]:
- Анализируем полученную картинку, она передается в стандарте 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
Точность такого времени не высока - до минут, но для простых часов подходит.
=== Получение прогноза погоды ===
Для получения прогноза погоды на ближайшие сутки я использовал сервис получения
[[http://informer.gismeteo.ru/xml/27612_1.xml|информера от GisMeteo в XML формате]]. Данные о погоде представляют из себя подробную
сводку по всем метеопараметрам, с шагом 6 часов и заблаговременностью одни сутки.
Тут все просто, указываем в запросе город и получаем в ответ для него прогноз
погоды, разбираем его и отображаем на экране прогноз на ближайшие 6 часов.
Пример запроса погоды для города Москвы:
GET http://informer.gismeteo.ru/xml/27612_1.xml
===== Дальнейшее усовершенствование =====
Представленный прототип является первым шагом к созданию самостоятельного
устройства - информатора или интернет часов-информеров способных отображать
текстовые сообщения, новости, отображать уведомления, проверять почту и т. п.
автономно без подключения ПК. Требующем только Ethernet и питание от адаптера.
Возможные дальнейшие шаги:
- Добавить отображение балла Яндекс.пробок.
- Заменить ардуино и Ethernet Shield на [[amp>product/arduino-ethernet-poe|Arduino Ethernet PoE]], тогда останется только шнур Ethernet.
- Добавить оповещение о новых письмах и твитах.
- Попробовать вариант с Wi-Fi модулем, тогда останется только шнур питания.
- Подключить внешние датчики и отображать их состояние ([[amp>collection/climatic-sensors|температура и влажность]], [[amp>product/barometer|давление]], [[amp>collection/photo-sensors|освещенность]]).
- Отображать RSS и курсы валют.
- Будильник (можно настраиваемый через интернет), потребуется добавить баззер или [[amp>product/piezo-buzzer|пьезо-пищалку]].
При работе с большими строками столкнулся с переполнением SRAM, для отслеживания
состояния памяти переменных я использовал функцию freeRam возвращающую значение
свободной памяти в байтах.
int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
Если кто то подскажет как можно улучшить программу буду благодарен :), для обсуждений есть [[http://forum.amperka.ru/threads/arduino-%D0%B8-%D1%83%D0%BD%D0%B8%D0%B2%D0%B5%D1%80%D1%81%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9-%D0%B4%D0%B8%D1%81%D0%BF%D0%BB%D0%B5%D0%B9%D0%BD%D1%8B%D0%B9-%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8C-te-ulcd.57/|ветка форума]] на Амперке.