====== Подключение универсального дисплейного модуля 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/|ветка форума]] на Амперке.