Поздравление по гиковски, без написания дров



    Прочитал статью «Создание собственных драйверов под Linux» от камрада dlinyj и загорелся идеей озвученной в конце статьи. А именно

    Сейчас ничего не мешает заплатить на месяц 500 рублей (а если скинемся, сумма будет совсем мелкой), и арендовать сервак на виртуалке. Туда поставить программулину, которая будет рассылать сообщения. Либо jabber либо какие-то другие способы (да хоть nc и telnet всё сделать). А на компе поставить приёмник этих сообщений. И на Новый Год все мы будем иметь поздравления.


    И принял решение таки влиться в общую тусовку, получить и отправить своё гиковское поздравление. Искать LPT-порт на своем ноутбуке я не стал, знаю, что его нет. Зато вспомнил, что несколько лет назад делал дисплей подключаемый к COM-порту. Точнее не совсем к СОМ-порту, это переходник USB-to-UART, о котором dlinyj говорил в этом посте «UART и с чем его едят». В результате было принято решение сделать на нём.



    Железо



    Протокол там применялся самописный, не имеющий ничего общего с ESC-последовательностями. Но у меня остался один из экземпляров.

    Внешний вид платы

    На данной плате довольно много лишнего. Фактически схема выглядит следующим образом:

    СхемаПолный размер

    Ничего сложного. И у каждого радиолюбителя наверняка представленный набор элементов. Я даже больше, чем уверен, что каждый, кто работал с контроллерами AVR имеет хотя бы одну такую платку, только с чутка другими схемами. FT232RL можно заменить на MAX232 (с соответствующим обвесом) или использовать готовый USB-UART переходник. Транзистор на подсветке, так же не обязателен (это схема управления подсветкой). Можно её с лёгкостью заменить просто подсоединением к земле.

    Тем кто является счастливым владельцем отладочной платы PinBoard v1 от DIHALT даже искать и паять ничего не придется. Все необходимое уже есть.


    PinBoard v1

    Практически тоже самое можно сказать и про владельцев Arduino. Вам останется только найти дисплей, резистор для регулировки контраста и пары проводов для соединения


    Arduino

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

    Софт!



    Библиотеки для работы с LCD у меня уже имелись, код для инициализации был выдернут из старого проекта и довольно банален. Была попытка использовать библиотеку от проекта камрада dlinyj, но видимо от количества вызовов-перевызовов функций у контроллера срывало стек, и работало всё нестабильно. В результате я решил таки всё сделать на своей библиотеке.
    Целиком код приводить не буду, каждый сможет посмотреть в исходниках весь проект. Остановлюсь на ключевых моментах.

    Во первых, надо описать пины для подключения дисплея, они описываются в файле hd44780_hw.h
    #include "hd44780_hw.h"  //describe LCD PINS connection
    


    Скорость работы UART была выбрана 9600. Так сложилось исторически, и не спрашивайте почему.

    #define baudrate 9600L
    


    Вся инициализация “железа” идёт в функции HwInit. Инициализации всего ничего:

    //HW initialisation 
    void HwInit(void)
    {
    	//InitUSART
    	UBRRL = LO(bauddivider);
    	UBRRH = HI(bauddivider);
    	UCSRA = 0;
    	UCSRB = 1<<RXEN|1<<TXEN|1<<RXCIE|0<<TXCIE;
    	UCSRC = 1<<URSEL|1<<UCSZ0|1<<UCSZ1;
     	sei();//разрешаем прерывания
    	//InitLCD	
    	lcd_init(LCD_DISP_ON);
    	lcd_clrscr();
    }
    


    Осноная задача — это обработка ESC-последовательностей, которую я нагло взял у Длиного, а он соответственно взял у Michael McLellan в его проекте lptlcd. Сам обработчик вынесен в esc.c, а мы же вызываем ту же самую функцию handleInput, которая и парсит наш запрос. Вызыв этой функции идёт в обработчике прерывания по приёму UARTa

    //UART interapt
    ISR(USART_RXC_vect)
    {
    	handleInput(UDR);
    	return;
    }
    


    Каждый байт, пришедший в UART, вызывает прерывание. И в обработчике прерывания мы берём и скармливаем функции handleInput.

    Эта функция мало чем отличается от аналогичной функции в проекте драйвера на lpt-порт. Разве, что были заменены функции установки в позицию экрана, очистки экрана и вывода символа на экран на функции из моей библиотеки. Плюс так же убрана функция вывода пасхалки, т.к. она работает только на четырёхстрочном экране и с библиотеками Длиного, а у нас иная либа да и экранчик всего 16х2. Ну из неприятного, пока не реализована функция загрузки своих шрифтов. Там пока стоит заглушка.

    Тестируем



    Компилируем. Для сборки я пользуюсь AVR Studio версии 4 + avr-toolchain (3.3.0.710). Прошиваем. Пока у нас идёт прошивка, еще раз взглянем на используемые ESC-последовательности. Цитирую текст исходной статьи.

    Итак, управляющие последовательности, для нашего экрана:

    • \033 = Отправка ESC-последовательности, с которой начинаются команды
    • [A = Переместить курсор на одну строку вверх
    • [B = Переместить курсор на одну строку вниз
    • [C = Сдвинуть курсор на одну позицию вправо
    • [D = Сдвинуть курсор на одну позицию влево
    • [H = Переместить курсор в левый верхний угол — домой (позиция 0,0)
    • [J = Очистить всё, НЕ возвращает курсор домой!
    • [K = Стирает до конца строки, НЕ возвращает курсор домой!
    • [M = Новая карта символов (ДЗ — объяснить зачем!)
    • [Y = Позиция Y (см. FAQ ниже)
    • [X = Позиция X (см. FAQ ниже)
    • [R = CGRAM Выбор ячейки памяти
    • [V = Прокрутка включена
    • [W = Прокрутка вылючена
    • [b = Подсветка включена-выключена (у нас работать не будет).


    Другие полезные команды, работают без префикса \033!

    • \r = Возврат каретки (возвращают курсор в позицию 0 на текущей линии!)
    • \n = Новая линия
    • \t = Табуляция (по умолчанию 3 символа)



    Я так же настоятельно рекомендую вернуться ещё раз к оригинальной статье habrahabr.ru/post/206148 и посмотреть FAQ с картинкам — примеры их применения.
    Цепляем свежепрошитый контроллер к порту USB, и видим, коммандой dmesg, что у нас в системе появилось новое устройство:

    /dev/ttyUSB0


    И даём следующую команду:

     echo -en "\033[H\033[J   Happy GEEEKS\r\n Happy New Year"  > /dev/ttyUSB0


    И в результате получаем совершенно новогоднее поздравление от гиков:


    Поздравление по ГИКОВСКИ!!!

    Ну и ставший уже традиционным скрипт вывода времени так же работает:

    while true; do     echo -en "\033[H`date +\"%d.%m.%Y\"` \r\n`date +%r`" > /dev/ttyUSB0 ;    sleep 1s; done



    Гик-часы

    А как же PinBoard V1?



    Для переноса онного кода для пинборда не требуется много усилий. Нужно просто подключить дисплей так же как ни на схеме. Если же дисплей уже подключен и переделывать нет желания, то можно поменять дефайны пинов, к которым подключён экран в файле hd44780_hw.h. Выглядит это следующем образом:

    #define LCD_DATA_PIN_D7  PA6	/* arbitrary pin for LCD data line D7 */
    #define LCD_DATA_PIN_D6  PA5	/* arbitrary pin for LCD data line D6 */
    #define LCD_DATA_PIN_D5  PA4	/* arbitrary pin for LCD data line D5 */
    #define LCD_DATA_PIN_D4  PA3	/* arbitrary pin for LCD data line D4 */
    
    #define LCD_DATA_PINR_D7 PINA	/* input pin register for LCD data line D7 */
    #define LCD_DATA_PINR_D6 PINA	/* input pin register for LCD data line D6 */
    #define LCD_DATA_PINR_D5 PINA	/* input pin register for LCD data line D5 */
    #define LCD_DATA_PINR_D4 PINA	/* input pin register for LCD data line D4 */
    
    #define LCD_DATA_DDR_D7 DDRA	/* ddr for LCD data line D7 */
    #define LCD_DATA_DDR_D6 DDRA	/* ddr for LCD data line D6 */
    #define LCD_DATA_DDR_D5 DDRA	/* ddr for LCD data line D5 */
    #define LCD_DATA_DDR_D4 DDRA	/* ddr for LCD data line D4 */
    
    #define LCD_DATA_PORT_D7 PORTA	/* port for LCD data line D7 */
    #define LCD_DATA_PORT_D6 PORTA	/* port for LCD data line D6 */
    #define LCD_DATA_PORT_D5 PORTA	/* port for LCD data line D5 */
    #define LCD_DATA_PORT_D4 PORTA	/* port for LCD data line D4 */
    
    #define LCD_RS_DDR       DDRA   /* ddr for RS line */
    #define LCD_RS_PORT      PORTA  /* port for RS line */
    #define LCD_RS_PIN       PA0
    #define LCD_RW_DDR       DDRA  /* ddr for RW line */
    #define LCD_RW_PORT      PORTA  /* port for RW line */
    #define LCD_RW_PIN       PA1
    #define LCD_E_DDR        DDRA  /* ddr for Enable line */
    #define LCD_E_PORT       PORTA  /* port for Enable line */
    
    


    Сохраняем, компилируем и прошиваем результат в пинборд и выполняем следующую команду:

    echo -en "\033[H033[JSpasibo DiHalt" > /dev/ttyUSB0 



    Поблагодарим автора платы!

    Зачем всё это нужно?



    Если мы оторвёмся от хабра и посмотрим на календарь, то ВНЕЗАПНО обнаружим, что до Нового Года осталось 10 дней. А ведь хочется праздника не только с роднёй, но и паяльно-виртуального! Вот для того всё это и затевается.
    Товарищ dlinyj создал группу, кто хочет поздравить друг-друга по гиковски. Прямо сейчас там народ думает над серверно-клиенской частью. Она пока ещё, к сожалению, не готова. Но мы надеемся, что если ты подключишься к нам, то мы обязательно всё доведём до ума! Если у тебя есть дисплей, и ты хочешь быть в тусовке, то вступай туда. Это не несёт никакой коммерции или личной выгоды, просто добрые поздравления с новым годом на экране.

    Тем у кого экрана все же нет, а поздравления по гиковски получать хочется, расстраиваться рано. ESC-последовательности работают и в обычной консоли. Так что выводя сообщения на экран, всё будет работать

    Например, если выполнить команду:
    while true; do     echo -en "\033[H`date +\"%d.%m.%Y\"` \r\n`date +%r`" ;    sleep 1s; done


    Убирая перенаправление вывода не стоит забывать про очистку экрана. Иначе получим интересный эффект:


    Часы прямо в консоли

    Чтобы такого не было, следует перед while добавить команду clear;. Теперь будет всё выглядеть так:

     clear; while true; do     echo -en "\033[H`date +\"%d.%m.%Y\"` \r\n`date +%r`" ;    sleep 1s; done



    Консоль, вместо дисплея

    Итоги



    Хочется создать атмосферу праздника, а для праздника нужны друзья. Где ж ещё гику искать друзей, кроме своих? Поэтому возможно и мы выбираем столь экзотический способ поздравить друг-друга с Новым Годом!

    Ссылки для скачивания:



    Исходники для моей платы и Пинборда можно скачать тут
    Поделиться публикацией
    Похожие публикации
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 40
    • +4
      Спасибо, очень интересная статья с приятной новогодней атмосферой!
      И вас с Наступающим!
      • +2
        Эх, а приятно, что дело начало жить и развиваться! Будем надеется реализуем до конца и в бой курантов узрим поздравления на самодельном экране :))))
        • +2
          Или на нарисованном, если я допилю индикатор
          image
          • 0
            Выглядит очень круто!!!
            • 0
              Скажите, вот этот индикатор, что он из себя представляет? Софтовую эмуляцию HD44780? или это просто поздравлялка с необычным дизайном?
              В любом случае делитесь :)
              • 0
                Софтовый эмулятор hd44780, написанные на javascript + разбор esc-последовательностей.
                Но он пока в процессе написания.
                • 0
                  www.geocities.com/dinceraydin/djlcdsim/djlcdsim.html не видел?

                  Там можно скачать уже готовый код!!! А прикрутить парсилку esc-последовательностей должно быть просто. Джава ж на си похожа, берёшь функцию handleinput и переписываешь под себя.
                  • +1
                    ХА! Я на этом эмуляторе разбирался как работать с экраном)
          • +11
            то ВНЕЗАПНО обнаружим, что до Нового Года осталось 10 дней.


            Да твою ж мать — действительно, ВНЕЗАПНО!
            • 0
              все думал, что вам ответить, а тут с «баша» прямо в тон
              xxx: Декабрь…
              xxx: Ну вот и настало время менять ёлку.

              Меня эта внезапность приятно удивила. Желаю и вам того же.
            • +1
              Ушел прикручивать экран к малине…
              • +1
                И это замечательно. Больше вариантов, больше участников. Ждём реализации
                • +1
                  Прочитав вашу статью в уме набросал как из подручных средств сделать подобное. Однако, в итоге уперся в отсутствие нормальной возможности все это транслировать миру. Может посоветуете какой сервис стриминга видео? Желательно бесплатный или условно-бесплатный.
                  • 0
                    Эм… А зачем видео?
                    • +1
                      Чтобы не самому смотреть, а в сеть транслировать и хабрахабровцам игрушку дать потыкать палочкой, например.
                      • 0
                        ОоООоооо. Это круто, но честно — не знаю как помочь…
                        • +1
                          Спасибо =) Если до понедельника найду рабочую вебку и нормальный сервис трансляции, который под хаброэфектом не ляжет за минуту, то попробую что-то соорудить.
                          • 0
                            Тот, который транслировал, как виртурилку замораживали.
                            • 0
                              Отличная идея, кстати. Спасибо!
                              • 0
                                Как успехи с хостингом видео?
                                • +2
                                  Порядок, ЯТВ оказался вполне хорошим сервисом. Вебка есть, осталось соорудить девайс и успеть до Нового Года =)
                        • +1
                          Помню, тут, кажется, кто то уже делал похожую штуковину.
                          На интернет-странице было окошко с видео потоком, камера направлена на lcd дисплей, и тут же на странице была форма. И вот в той форме можно было написать текст, и это в реальном времени выводилось на дисплей и транслировалось через веб камеру.
                          • +1
                            Да, было. Еще камера была поворотная. Собственно, чем плохо повторить? =) Считайте, традиция.
                          • 0
                            Похоже, меня опередили =)
                    • 0
                      Там должно быть просто. Вариант либо с перекомпиляцией моего драйвера под малину, либо через USB.
                    • 0
                      Спасибо за интересную статью.
                      Помогите плз найти даташит на ЖК TIC4484… никак не найду ничего… есть сам дисплей — хочу из него часы сделать.
                      • +1
                        Если вам гугл помочь не смог, то я и подавно. Для меня это хобби, а потому стараюсь типовые решения использовать. И документированы хорошо и повторить потом легче.
                      • 0
                        devicter.ru/goods/Shield-MaTrix — уже писал про него, тоже запросто можно прикрутить к «поздравлялке». Сообщения получать через devicter.ru/goods/Iteaduino-Iboard и через nRF24l01+ передавать на матрицу
                        • +1
                          Творил на том, что есть в наличии. Но вариант тоже интересный
                        • +1
                          Кто о чем, а я о своем. Сделал версию под Pebble: github.com/vvzvlad/Pebble-NewYearGeeks
                          В принципе, уже работает. Правда, без управляющих символов.
                          • 0
                            Pebbele без телефона, как я понимаю, не может выводить сообщения. А значит есть для какой-то из платформ приложение. Можете его довести до состояния «выводить поздравления на экран телефона в виде ленты» или даже виджет сделать? Понимаю, что уходим от аппаратной реализации, но зато получаем расширение аудитории.
                            • 0
                              Там встроенное приложение на JS вот такое:
                              Pebble.addEventListener("appmessage",
                              	function(e) {
                              	var req = new XMLHttpRequest();
                              	req.open('GET', "http://146.185.136.209/messages/pebble_app_" + e.payload.UUID + "/next/", true);
                              
                              req.onreadystatechange = function() 
                              {
                                if (this.readyState != 4) return;
                              var print = this.responseText.replace(/\\033/g, ""); 
                              print = print.replace(/\[A/g, "");
                              print = print.replace(/\[B/g, "");
                              print = print.replace(/\[C/g, "");
                              print = print.replace(/\[D/g, "");
                              print = print.replace(/\[H/g, "");
                              print = print.replace(/\[J/g, "");
                              print = print.replace(/\[K/g, "");
                              print = print.replace(/\[M/g, "");
                              print = print.replace(/\[Y/g, "");
                              print = print.replace(/\[X/g, "");
                              print = print.replace(/\[R/g, "");
                              print = print.replace(/\[V/g, "");
                              print = print.replace(/\[W/g, "");
                              print = print.replace(/\[b/g, "");
                              print = print.replace(/\\r/g, "");
                              print = print.replace(/\\n/g, " ");
                              print = print.replace(/\\t/g, "");
                                        Pebble.sendAppMessage({
                                          "print":print,
                                      });
                              }
                              	req.send(null);
                              });
                              
                              


                              Довести его до состояний приложения трудновато будет. JS совсем не знаю, с этим куском полчаса сидел. Но можно попробовать на appinvertor сделать.

                              P.S. А почему на мы на вы? :)
                              • 0
                                Попробовать все же стоит. Может кто присоединится и поможет. Я вот сейчас ищу исходники написанного для меня драйвера фискального регистратора под Linux. Он там примитивный до безобразия но уже практически умеет с ESC работать. Можно будет печатать сообщения.

                                P.S. На ты так на ты. Никаких возражений по этому поводу не имею
                                • +1
                                  Сделал для андроида: тык
                                  Умеет показывать сообщения каждую секунду. Больше не умеет ничего пока.
                                  • 0
                                    Ну и отлично же. Сместить вниз, вместо белого фона елку и добавить возможность изменить частоту обновления поздравлений на экране

                                    • 0
                                      Докладываю: елка сделана, изменение времени еще нет. Тык
                                      • 0
                                        И три строки. Замечательно. Скрин пока не выложить, интернет по талонам.
                                        • 0
                                          Да скриншот я и сам могу выложить, мне просто стыдно.
                                          • +1
                                            Круто, ваяй постец :))))
                                • +1
                                  И все цифирные \*** надо заменять. А как быть с загрузкой шрифтов и очисткой экрана?

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.