Wednesday, February 8, 2012

LCD дисплей и Arduino

"- Какой LSD монитор лучше? 
- Если есть LSD, то отлично показывает даже ковер"
(с) Кажется цитата с bashorg'а

Ну, а если говорить серьезно, то в этом посте я постараюсь рассказать как заставить работать двухстрочный LCD дисплей, а заодно расскажу как его искать на ebay. Сразу хотелось бы сказать - стоит эта штука порядка 3,5$ (т.е. ну очень дешево). При сборке будут еще использоваться пара резисторов (на 100 Ом и на 1кОм), контактная гребенка, паяльник, припой, флюс и проводки. Подключать все это дело мы будем к уже хорошо знакомой Arduino, ну и в коде воспользуемся специальной библиотекой, опять же из стандартных, как например Stepper для шаговиков, LiquidCrystal.h.


И еще кое что, в процессе работы я напортачил немного, из-за чего пришлось потратить много времени на исправление собственных косяков. Я не стал выбрасывать это описание из поста, чтобы вы понимали - подобные эксперименты не проходят всегда гладко. Я тоже ошибаюсь. Большинство блоггеров не описывают свои ошибки, которые они безусловно тоже делают, из-за чего может сложиться впечатление, что все проще пареной репы. По сути оно так и есть, только вот ошибки все равно бывают, особенно если, как я, делать все поздно ночью, когда сложно даже просто разомкнуть глаза.В общем не повторяем не дочитав до конца.
Покупка
Я покупал на ebay (как и многое другое). В ходе поисков было обнаружено, что проще всего найти его по запросу "1602 LCD Display". Цена, как уже говорилось ранее, в районе 3,5$. Я заказывал с голубой подсветкой, т.к. она напоминает мне столь теплую сердцу кофемашину на работе - там установлен такой же.

Подготовительные работы
Данный дисплей поставляется без запаянной контактной гребенки. Делается это скорее всего для удобства транспортировки - эта гребенка с удовольствием бы надрывала упаковку, да и сломать её в процессе погрузки было бы не сложно.
Для удобства работы нам надо будет эту самую гребенку запаять для начала. Я для этого немного поднастроил третью руку, чтобы она могла удерживать плату в параллельном столу состоянии, на такой высоте, чтобы гребенка держалась в плате и не выпадала. Если выразиться по другому, то цель - прижать гребенку платой к столу в вертикальном положении, чтобы освободить руки для паяльника и припоя.
Третья рука будет выглядеть приблизительно так:
Кстати, при желании можно сделать то же самое просто зажав край платы в общей тетради, на случай, если не получилось с третьей рукой. Результат тот же, и вначале я думал использовать именно этот способ, но передумал почему-то.
Третья рука уже с установленной платой и гребенкой, практически готовая к пайке.
Если вы особенно внимательны и уже гуглили тему, то уже сейчас можно понять, где я накосячил. Однако я пошел дальше.
Для того чтобы хорошо припаять гребенку было принято решение в первую очередь припаять крайние контакты гребенки - в таком состоянии она будет держаться и можно будет её без проблем поднять повыше в третьей руке для пущего комфорта.
Наносим флюс и припаиваем
Один контакт готов (можно заметить пайку на правом контакте гребенки)
Проделываем все то же самое с левым контактом.
После этого флюсуем все остальные контакты за раз и быстренько пропаиваем их все.
Вот именно в момент, когда все контакты были уже припаяны, до меня дошло, что я дебил. Припаял то я все здорово, но вот как пользоваться этой гребенкой если она с той же стороны, что и сам дисплей? Ну в общем понятно - ни в макетку вставить, ни в схему какую запаять или вставить - ничерта не получится.
В общем, я осознал ошибку и потратил еще час с лишним на выпаивание обратно этой гребенки. Пайку я сделал добротную, так что выпаять было достаточно трудно. Помог оловоотсос для удаления старого припоя.
В общем, будет мне уроком - в начале думай 5 раз, и лишь потом берись за паяльник, т.к. переделывать, факт, что будет дольше, чем нормально подумать в начале. Урок усвоил.
В общем, после боя со старой гребенкой в котором я все же одержал победу, я установил её правильно.
Снова зажатый, но уже правильно, в третьей руке дисплей придавливающий гребенку.
Снова наносим флюс
Запаиваем крайний контакт...
 Дальше все один за одним
Во всем надо искать свои плюсы. Я порадовался, что в этот раз я припаял все на порядок быстрее и качественнее. Тренировку пайки никто не отменял еще, кажется. Получилось вроде бы не плохо, но оценивать вам. Кстати, не забываем отмывать плату от флюса (я использую для этого изопропанол, он же изопропиловый спирт).

Распиновка 
Составлю ка я таблицу соответствия, по которой будет достаточно легко понять, что куда и как подключать. Первый столбец - порядковый номер контакта. Если смотреть на фото выше, то считаться они будут справа налево - на самом деле дисплей находится в перевернутом состоянии.
Второй столбец - условное обозначение контакта которое было на моем дисплее.
Третий - соответствующий пин на arduino.


#Display pinArduino pin
1VSS
GND
2VDD+5V
3VO Pull-down Resistor*
4RS1
5RW2
6E3
7D0-
8D1-
9D2-
10D3-
11D44
12D55
13D66
14D77
15A
Resistor to +5V /
Transistor+Resistor to 0**
16KGND
* - я использовал 1кОм резистор подлюченный к земле (GND), можно использовать и больший номинал, меньше - наверное не стоит.
** - это анод светодиодной подсветки и можно его просто подключить к +5V через резистор (100 Ом будет достаточно) - тогда подсветка будет просто гореть всегда. Можно просто подключить через резистор к выходу Arduino. Я проверял - тоже будет нормально гореть и управляться. Но все же, для пущей безопасности, я подключил подсветку через транзистор, чтобы несколько обезопасить микроконтроллер.
Хотелось бы поделиться еще и некоторыми комментариями на счет того, какой выход за что ответственен. Итак, мы имеем:
1 - земля питания микросхемы; 2 - положительный полюс питания микросхемы; 3 - контрастность (просто подтянутая резистором к земле выставляется на максимум, на данный момент меня это устраивает); 4, 5, 6, 11, 12, 13, 14 - если не вдаваться в подробности, то это сигнальные линии, именно через них передается информация о том, какие символы необходимо отобразить дисплею. Больше пока ничего сказать не могу - сам не разбирался; 15 - анод (или положительный полюс) питания подсветки дисплея; 16 - катод (или отрицательный полюс, земля) подсветки дисплея.

Схема

Собирать будем что-то такое
Одна оговорка - все схемы я рисую с помощью прекраснейшей программки Fritzing. Она бесплатная и очень простая - зато можно наглядно нарисовать любый схемы с Arduino. Сайт программы - здесь.
Так вот, я пользовался NPN транзистором C1815, но подойдет любой другой транзистор NPN или PNP. Единственная особенность моего, это то, что в нем выходы находятся в порядке Эмиттер-Коллектор-База (ЭКБ), и выбрав такой транзистор в свойствах элемента, Fritzing "запутал" ножки. На практике надо для вашего конкретного транзистора просто смотреть как расположены у него выходы - ничего сгибать не надо. Цель, чтобы к Эмиттеру был подключен положительный полюс питания (+5v), Коллектор через резистор был соединен с 15-м выводом нашего дисплея, а База соединена с нулевым контактом нашей Arduino.

Сборка
Собственно приступим к сборке схемы.
Засовываем контактную гребенку дисплея в макетную плату.
Вставляем наш транзистор (справа) и один за одним создаем соединения.
Здесь и на нескольких последующий фото видна ошибка в соединениях - я подправил её только в самом конце. Как можно заметить - два провода слева (питание схемы дисплея)  подключены по ту сторону "хребта" макетной платы и не соединены с самим дисплеем.
Продолжаем сборку
Так как это уже не первая прошивка для Android моя, и на момент начала эксперимента она уже была зашита каким-то кодом - я стал прошивать его отключив от дисплея и схемы. Чтобы по десять раз не мучатся с проводами я решил прибегнуть к хитрости - приклеил из на скотч, и только после этого вынул из Arduino. Как результат - не надо запоминать ничего, а как следствие меньше шансов допустить ошибку впоследствии.
Вот таким образом я разъединил Arduino и остальную схему

Прошивка
Я выбрал соединение по 7-ми проводкам. Тестовый код получился следующего вида:
#include <LiquidCrystal.h>

byte backlight = 0, rs = 1, rw = 2, enable = 3,
    d4 = 4, d5 = 5, d6 = 6, d7 = 7;

// LiquidCrystal(rs, rw, enable, d4, d5, d6, d7)
// http://arduino.cc/en/Reference/LiquidCrystalConstructor

LiquidCrystal lcd(rs, rw, enable, d4, d5, d6, d7);

void setup()
{
  // begin(w,h) specifies the dimensions 
  // (width and height) of the display.
  lcd.begin(16, 2);
  // pin for backlight LED controller
  // for this example just turn it on
  pinMode(backlight, OUTPUT);
  digitalWrite(backlight, HIGH);
  lcd.print("Hello, world!");
}

void loop() {}

Собственно прошивка проще некуда. Но все же пару слов.

  • byte backlight = 0, rs = 1, rw = 2, enable = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7; - для удобства инициализировал переменные для всех выходов, просто для того, чтобы не держать в голове за что какой вывод отвечает
  • LiquidCrystal lcd(rs, rw, enable, d4, d5, d6, d7); - создал объект типа LiquidCrystal и передал в конструктор номера выходов
  • lcd.begin(162); - инициализировал размерность дисплея - 2 строки по 16 символов в каждой
  • pinMode(backlight, OUTPUT); digitalWrite(backlight, HIGH); - включает подсветку экрана.
  • lcd.print("Hello, world!"); - выводим на экран нетленный "Hello, World!"
Закачиваем прошивку в Arduino. Отключаем наш микроконтроллер от порта USB, тем самым обесточивив его. Подключаем к Arduino повисшие в воздухе, но закрепленные на скотче, проводки.

Запуск
Подключаем снова нашу плату к USB порту, тем самым обеспечивая необходимой её питание, и радуемся картиной.

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

Видео
Ну, и заканчиваю пост так, как сам люблю чтобы они заканчивались у других - видео. Для видео я немного переделал код программы, чтобы хоть как-то оживить картинку - иначе в этом самом видео не было бы ничего интересного.
Если будет интересно копнуть код из видео - пишите, поделюсь с удовольствием. Он незатейлив как грабли.


Немного о планах
В конце статьи хотелось бы немного поделиться планами на ближайшее будущее.
На данный момент у меня уже предостаточно знаний для сборки простого робота, чем я собственно и собираюсь заняться вплотную. В ближайшие недели я буду активно чертить, моделировать, резать, травить, пилить, паять, клеить, ломать и снова клеить. Если все будет хорошо, то в ближайшие дни я еще планирую выложить чертежи и схемы драйвера двигателей L293D с необходимой обвязкой, выполненный в виде отдельного модуля на печатной плате. Возможно даже вытравлю его и сделаю фото.
Помимо всего прочего, мне надо составить список покупок на ebay для этого робота. Скорее всего буду строить его на Arduino Nano плате, хотя может места хватит и для Arduino Uno - пока не прикидывал размеры не знаю точно.
План - в ближайший месяц-два собрать первого бота.