Функциональные блоки, которые являются неотъемлемой частью готового устройства, чаще всего можно применять не один раз. Например, проектируя частотометр с микроконтроллером, необходим будет не только блок усилителя, то и такие же составляющие, как для создания реле времени.
В данном случае речь идёт о микроконтроллере с «окружением», разъёмах, кнопках и дисплее. Понятно, что у частотометра нет необходимости в реле включения устройства извне, его заменяет реле времени широкополосного входного усилителя, при этом ядро остаётся прежним. Учитывая это, в первую очередь, для выполнения создания личных приложений, необходимо иметь представление об основных принципах работы каждого функционального блока и только потом объединять их функции.
Работая с платформой Arduino, необязательно разбираться с принципами функционирования каждого отдельного элемента. Допустимо объединение базовой платы с модулем/платой и создание в такой способ полностью функционирующее приложение. Отсутствие даже элементарного представления о компонентах, обрекает пользователя на блуждания в поисках решений, если возникнет проблема с рабочим процессом оборудования.
Говоря о компонентах Arduino, в основном мы представляем себе моментальный результат. На практике такой эффект проблематично совмещать с важностью изучения соответствующей информации, ведь введя всего пару команд на дисплее отобразятся первые результаты. Чтобы вникнуть в то, как это возможно, нередко требуется много времени.
Учитывая все возможные вышеперечисленные несоответствия, подаваемая информация по данной теме будет иметь две части. Благодаря первой части можно будет разобраться, что делать, чтобы добиться максимально возможного эффекта. Вторая направлена на то, чтобы показать, как именно функционирует этот узел.
Изначально стоит обратить внимание на модули, оснащённые ЖК-дисплеем, ведь с их помощью быстрее всего можно увидеть итог выполненной работы. На следующем этапе будут обсуждаться иные комплектующие пользовательского интерфейса, далее конкретные внешние системы, включающие в себя датчики и исполнительные элементы.
Более детально стоит разобраться с приёмами и способами программирования, которые можно выполнять с платформой Arduino. Среди прочих, она выделяется своей доступностью, приемлемой ценой, а также возможностью применения с целью создания полноценного оборудования или их прототипов.
Модуль символьного ЖК-дисплея
Дисплей и кнопка (кнопки) — главные составляющие основного интерфейса между микроконтроллером и пользователем. Понятно, что посредством первого компонента происходит передача сведений пользователю о протекающих рабочих процессах в микроконтроллере. Касательно кнопок, то они в некоторых случаях могут быть заменены на импульсаторы. С их помощью вводятся данные или задаются к выполнению команды.
В каталогах компании ТМ Электроникс не составит труда среди огромного числа дисплеев подобрать идеально подходящий для конкретного случая (касается и тех, которые оснащены сенсорной панелью). При этом, символьные дисплеи с контроллером HD44780 представляют собой своеобразный неформальный стандарт.
Первый пример программирования - основан на применении платы Arduino UNO R3, макетной платы, модуля символьного ЖК-дисплея с двумя строками и 16-ю символами, пары проводов для соединений. В любом случае, это всего лишь один из всевозможных вариантов. Присоединение дисплея выполняется любым удобным способом, например, при помощи пайки к плате. В данном случае предлагается метод, открывающий большие возможности для выполнения модификаций и изменения схемы соединения.
Наличие припаянных позолоченных штырей на дисплейном модуле позволяет без труда вставить его в контактную плату. Далее подсоединяем дисплей к Arduino UNO, согласно указаниям, приведённым в таблице ниже.
Стоит обратить внимание на то, что, подключая массу GND от разъёма Power к контактной плате (КП), допустимо выполнение подключения в рамках КП, при этом нет необходимости в постоянном подсоединении к разъёму Power. Он является неотъемлемой частью всей конструкции и без него не обойтись, ведь от него питается дисплей.
Рядом устанавливается разъём Analog In, из-за чего, с целью обеспечения удобства, было принято решение о применении встроенных на нём выводов микроконтроллеров. Но при это название не должно сбивать с толку, ведь управление модулем дисплея происходит посредством цифровых выходов, а не аналоговых входы/выходы. Данный разъём имеет такое название из-за дополнительно подведённых аналоговых входов, на них поддаются настройки для продуктивного функционирования в иных режимах (цифровые выходы). Подводя итог: аналоговый вход А0 представляет собой порт РС0, А1 — РС1 и так далее.
Процесс управления функционированием дисплея осуществляется при помощи библиотеки LiquidCrystal, которой было отдано предпочтение среди огромного ассортимента всевозможных вариантов программируемых контроллеров для Arduino. Создав скетч по команде #include, он подключается в первой строке программы. Выполнив подключение по указанному способу, далее приступаем к первому скетчу управления модулем ЖК-дисплея.
Плата Arduino подключается к USB персонального компьютера. Заходим в меню Arduin, где выбираем Файл, далее Новый. Отображается окно, очень схожее с указанным изображением (рис. 1). Слово «void», которое является ключевым, свидетельствует о том, что в данном месте создаётся функция, не возвращающая ни одно значение. После «void» указывается имя функции, где „{” – обозначает её начало, а „}” – конец.
Создавая скетч, Arduino уведомляет о важности определения 2-х особых функций:
- void setup() — описывает конфигурацию микроконтроллера, содержащая инструкции, которые выполняются 1 раз при запуске программы;
- void loop() — это комплекс мер, реализующиеся в бесконечном цикле.
Какова причина необходимости функционирования программы приложения в бесконечном цикле? Рабочий процесс Windows или Linux происходит под контролем ОС. При запуске приложения под Windows, по завершению работы осуществляется возврат в момент его первоначального запуска, а это в основном отображение т.н. рабочего стола, командная строка и иное. По этой причине за управление рабочего процесса отвечает ОС.
Размещённый на плате Arduino UNO микроконтроллер в загрузках не имеет никакой ОС. Поэтому в обязанности программиста входит обеспечение безопасного режима при завершении функционирования приложения. Это возможно посредством выключения микроконтроллера или выполнения зацикливания реализации инструкции, что в итоге не допустит их выполнение за границами необходимой области памяти. Для этого можно применить функцию void loop() или выбрать один из иных вариантов, что предлагаются ниже.
Перед тем, как на дисплее отобразится информация, нужно выполнить настройку микроконтроллера. Для данного случая, вполне хватит выполнить правильную настройку управляющих дисплеем выходов.
В начале скетча необходимо присоединить библиотеку функций дисплея: #include
Далее, с целью комфорта и читабельности программы, применяя директивы #define указываем наименование ножек – выводов порта С микроконтроллера:
//port PC
#define pc0 A0
#define pc1 A1
#define pc2 A2
#define pc3 A3
#define pc4 A4
#define pc5 A5
Теперь необходимо уведомить микроконтроллер о тех выводах, к которым подключен дисплей. Поможет функция lcd(), содержащая перечень аргументов инструктирующих процессор, о поступлении сигналов.
Перечисляя выводы, в обязательном порядке соблюдайте конкретную очерёдность: LiquidCrystal lcd(RS, Enable, D4, D5, D6, D7).
Создавать список аргументов лучше на основе таблицы 1, ведь в ней отображён список соединений для Arduino и модуля ЖК-дисплея: LiquidCrystal lcd(pc4, pc5, pc0, pc1, pc2, pc3).
Далее настраивается режим для функционирвоания выводов. Они должны функционировать как цифровые выводы. Данная конфигурация сохранена в функции void setup():
pinMode(pc0, OUTPUT);
pinMode(pc1, OUTPUT);
pinMode(pc2, OUTPUT);
pinMode(pc3, OUTPUT);
pinMode(pc4, OUTPUT);
pinMode(pc5, OUTPUT);
По окончанию выполнения инициализации, где в процессе устанавливается число столбцов, срок и очищается экран. По окончанию выполнения всех вышеуказанных действий, на экране ничего не должно быть. При этом, для обеспечения безопасности и корректного начала работы, лучше всего реализовать ещё одну инструкцию:
lcd.begin(16, 2);
lcd.clear();
Для отображения сообщения, в конце, необходима всего лишь одна команда: lcd.print(„Hello!”);
Совершенно иная ситуация складывается с функцией loop(), в которую не помещаются ни какие команды. В данном случае, выводя сообщения, программа просто бесконечно «крутится», при этом тратится и время процессора. Как вариант, на данном этапе имеется возможность войти в режим энергосбережения, ведь отображающееся на экране сообщение останется всё тем же. При этом возникает необходимость в детальном изучении оборудования, а это делать крайне нежелательно на данном этапе.
Полностью, с программой, которая выводит сообщение «Hello!», можно ознакомиться в прилагаемых к данному тексту дополнительных материалах. Если благодаря следованию указанному выше описанию получилось достигнуть желаемого результата, то далее можно не изучать информацию. Следующая статья будет посвящена изучению более сложных операций, суть которых будет заключаться не просто в отображении сообщений, а контента.
Процесс функционирования модуля ЖК-дисплея
Разбор данной темы следовало бы начать с обсуждения присущей микроконтроллеру конструкции, который является неотъемлемой частью платы Arduino, но учитывая, что данная тема достаточно большая, начнём мы со способов функционирования модуля ЖК-дисплея.
Для того, чтобы разобраться в процессе управления модулем ЖК-дисплея, нужно иметь хотя бы базовые понятия о схемах памяти и цифровых схемах в общем. Не обойтись и без понимания того, что представляют собой высокие и низкие логические уровни, форма сигнала, данные, восьми битовое число, бит, байт, задний и передний фронт. Необходимость в этом существует из-за того, что со стороны обработчика модуль дисплея представляет собой разновидность цифровой памяти. С ней микроконтроллер способен обмениваться данными в 2-х направлениях.
При этом модуль ЖК-дисплея оснащён своим собственным микроконтроллером, способным не только принимать информацию для её дальнейшего отображения, но и выполнять команды, непосредственно связанные с процессом функционирования модуля ЖК-дисплея и поддерживать отображение.
Учитывая то, что микроконтроллер встроен в модуль дисплея, где на него возлагается выполнение исключительно специализированной и автономной функции, данные системы характеризуют, как подчиненные или выполняющие функцию slave. На микроконтроллер, который встроен в плату Arduino, возлагается основная функция – управления. Чаще всего, характеризуют такие системы, как главные или master.
«0» и «1» логического значения
Логическая «1» свидетельствует о наличии уровня напряжения питания схемы в размере не меньше 95%, а в случае с логическим «0» — показатель напряжения равен или меньше 0,3В. Именная такая технология берётся за основу при создании схем CMOS (современные интегральные схемы).
В случае наличия встроенного источника питания в схеме процессора, что не редкость для сложных процессоров, определение логической «1» происходит на основании внутреннего источника питания. Допустима и иная ситуация, при которой схема CMOS оснащена выходами, полностью совместимыми с уровнями TTL, при этом логическая «1» будет представлять собой значение напряжения более 2,4В. Учитывая всё вышесказанное, при малейших сомнениях, лучше всего всё перепроверить и воспользоваться спецификацией данной схемы. Она общедоступна в сети Интернет.
Передний и задний фронт
Перемены в логическом уровне влекут за собой перемены и в показателях напряжения. Данные изменения имеют скачкообразный характер на протяжении некоторого временного промежутка. В момент изменения уровня с «0» на «1», можно говорить о переднем фронте, когда же данный процесс происходит в обратном порядке, то о заднем фронте. Длительность перехода при этом будет временем нарастания или падения. Как правило это занимает всего несколько наносекунд, но не всегда.
Под битом данных принято понимать отдельную линию в микроконтроллере с уровнем «0» или «1». Байт – это восемь таких линий. В Arduino UNO встроен микроконтроллер AVR с 8-ми битным словом данных, что позволяет ему обрабатывать одно байтовые слова, десятичные числа от 0 до 255. Если число превышает значение в 255, то оно должно быть разбито на «части», произвести над ним операцию и только потом собрать результат. Но беспокоиться не стоит об этом, ведь происходит это в фоновом режиме посредством компилятора языка Arduino. При этом стоит обратить внимание на то, что чем больше битов необходимо для хранения такой переменной, тем больше дольше будет происходить её обработка микроконтроллером.
Процесс управления модулем ЖК-дисплея
В данном случае процесс управления модулем ЖК-дисплея осуществляется посредством главного микроконтроллера при помощи выходных сигналов. Изменение выходных сигналов предоставляет возможность управлять логическими уровнями на входах модуля дисплея. Это позволяет ему выбирать момент для записи информации и область памяти, куда именно будут записаны эти данные.
Если на входе RS (Register Select) логическая «1», то это провоцирует запись данных в память изображения, если же это логический «0», то запись осуществляется в регистр управления модулем дисплея. Для выполнения корректной отправки команд на контроллер дисплея и информации для отображения главный микроконтроллер должен иметь доступ к управлению этим входом. В случае замыкания входа на постоянный, высокий логический уровень, модуль дисплея не сможет выполнить команды типа «очистить экран» и корректную инициализацию.
Если на входе R/W (Read/Write) логическая «1», то она провоцирует считывание информации, тогда как логический «0» — запись. Для нашего случая на вход модуля ЖК-дисплея был задан постоянный низкий уровень, подсоединив его к земле. Это допустимо только в случае записи информации на дисплей, а не для их чтения. При добавлении данного входа к постоянному логическому уровню, утрачивается способность к чтению из памяти дисплея и регистра управления, поэтому, сигнал занятости «busy».
Тестирование данного сигнала ускоряет рабочий процесс модуля дисплея и предоставляет возможность проверки корректности реакции его контроллера на полученную информацию, при этом занимает ещё одну линию порта главного микроконтроллера и нуждается в дополнительном соединении. Появляется некоторое усложнение для обработчика — задний фронт на входе «E» (Enable) провоцирует перезапись логических уровней (с входов DB0… DB7 на внутреннюю память модуля ЖК-дисплея).
Допустимо управление работой модуля символьного ЖК-дисплея в 2-х режимах:
Восьми битном — для данного случая необходимо не меньше десяти линий данных для подсоединения дисплея. Данный режим выделяется своей эффективностью в случае подсоединения к главной системе дисплея, выступающего в роли памяти на восьми битной шине данных. Адресация модуля дисплея обеспечивает установление высокого уровня на входе Enable, низкого/высокого (в зависимости от ситуации) на RS, изменение уровня на Enable на низкий и выставление данных на шину. Для ряда систем это очень упрощает обработчик.
Четырёх битном — всё так же применяется 8-битное слово, при этом к главной системе подсоединены исключительно выходы D4… D7 модуля дисплея, а восьми битные слова данных разделены на две части, где в каждой по четыре бита. В результате это усложняет обработчик и усложняет процесс подсоединения модуля дисплея к главной системе, но при этом экономит четыре линии GPIO микроконтроллера.
Считалось, что упрощенные обработчики модуля ЖК-дисплея, не применяющие линии R/W имеют полностью корректно функционирующий модуль дисплея. Конкретное время устанавливается по умолчанию (в основном составляляет 2 миллисекунды) и предполагалось, что его завершению дисплей или выполнит команду, или отобразит символ, что позволит далее отправлять иные команды.
В основном встроенный в модуль дисплея микроконтроллер функционирует лучше, ведь только на выполнение команды по очистке экрана необходимо меньше 2 миллисекунд. С иной же стороны, для нашего случая, где на экране две строки по восемь символов в каждой, не важно, отправится 16 байтов за 32 миллисекунды или 100 микросекунд. Причина в том, что ни одним пользователем он не будет замечен. Смена картинки происходит только тогда, когда дело касается графического дисплея, на который поступает значительно большее количество данных.
Платформой Arduino не предусмотрено много места для выполнения манёвров в процессе управления дисплеем. В Arduino UNO встроен микроконтроллер ATmega328, который лишён внешних адресных линий. По этой причине даже не рассматривается вариант об управлении дисплеем в восьми битном режиме с адресацией похожей на внешнюю память. При этом, в случае использования одного порта GPIO с целью управления сигналом R/W, допустима проверка флага занятости busy и считка содержимого регистров и памяти модуля ЖК-дисплея.
Выполнить настройку типа подключения дисплея через библиотеку LiquidCrystal.h можно воспользовавшись функцией LiquidCrystal ().
Выбор способа подключения непосредственно зависит от присущего списка аргументов вызова функции:
- LiquidCrystal(rs, enable, d4, d5, d6, d7) – интерфейс на четыре бита, не имеющий управление вводом R/W модуля дисплея, поэтому отсутствует возможность чтения информации;
- LiquidCrystal(rs, rw, enable, d4, d5, d6, d7) - интерфейс на четыре бита, имеющий управление входом R/W модуля дисплея и оснащён возможностью чтения данных;
- LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7) - интерфейс на восемь битов, возможность чтения данных отсутствует;
- LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7) - интерфейс на восемь битов, возможность чтения данных присутствует.
Контроллер HD44780 представляет собой специально разработанную, универсальную схему, основное предназначение которой заключается в поддержки экранов ЖК-дисплеев на различное количество символов. Подключив питание, контроллер не понимает, какой именно экран подключен, поэтому для корректного функционирования он требует настройки. В случае с Arduino, данная задача возлагается на функцию begin(), где обозначается имеющееся количество строк и столбцов. Если дисплей будет иметь две строки по 16 символов каждой, то выглядеть эта функция будет так: begin(16, 2).
Очищают экран при помощи функции clear(). Лучше всего применять её первой, после инициализации модуля ЖК-дисплея, ведь могут быть дисплеи, на которых отображаются случайные символы по окончанию инициализации. В примере так же была применена функция print(), основная задача которой заключалась в преобразовании чисел, а при необходимости представлении их в различных системах счисления:
- print (10) или print(10, DEC) –> отображается 10,
- print(10, BIN) –> отображается 1010,
- print (10, HEX) –> отображается A,
- print (10, OCT) –> отображается 12.
- print („Hello!”) –> отображает сообщение Hello!
Размещать отображаемые символы print начинает с активной позиции курсора. Чаще всего после очистки место курсора — это верхний угол ЖК-экрана.
В библиотеке функций LiquidCrystal.h находится ещё масса иных очень важных функций, но об этом уже в другой раз. Для начала стоит разобраться с изложенным выше материалом, а потом уже идти дальше.
ARDUINO UNO REV3 Arduino; ATMEGA328; GPIO,I2C,PWM,SPI,UART
EP16205-Y Дисплей: OLED; алфавитно-цифровой; 16x2; Разм: 53x20x7,6мм; желтый
EAW162-X3LW Дисплей: OLED; алфавитно-цифровой; 16x2; Разм: 80x36мм; белый