Netduino: взаимодействие с символьным жк-дисплеем

Netduino Plus 2

Netduino – это открытая электронная платформа, использующая .NET Micro Framework. Оснащена 32-битным микроконтроллером. Netduino предлагает 20 портов GPIO, объединенных с SPI, I2C, двумя UART (1 RTS/CTS), 4 ШИМ каналами и 6 каналами АЦП. .NET Micro Framework сочетает в себе простоту высокоуровневого программирования и доступ к возможностям микроконтроллеров.

Netduino также совместима по выводам с платами расширения Arduino (для некоторых из них могут понадобиться сторонние драйверы).

Netduino Plus 2

Технические характеристики

Сравнение технических характеристик Netduino Plus, Netduino Plus 2 и Netduino GoКомпоненты и возможностиNetduino PlusNetduino Plus 2Netduino Go
Процессор и память Микроконтроллер STMicro STM32F2 STMicro STM32F4 STMicro STM32F4
Скорость 120 МГц (Cortex-M3) 168 МГц (Cortex-M4) 168 МГц (Cortex-M4)
Память хранения кода программ 192 KB 384 KB 384 KB
RAM 60 KB 100+ KB 100+ KB
Операционная система .NET Micro Framework 4.2 (or 4.3) .NET Micro Framework 4.2 (or 4.3) .NET Micro Framework 4.2
Входы и выходы Сеть Ethernet: 10 Мбит/с Ethernet: 10 Мбит/с Через дополнение: ethernet gobus модуль
Совместимость с платами расширения Arduino Работает с большинством плат расширения Arduino Работает с большинством плат расширения Arduino Через дополнение: shield base gobus модуль
(некоторые требуют .net mf драйверов) (некоторые требуют .net mf драйверов)
Цифровые входы/выходы 20 GPIO, 6 ШИМ, 2 UART, I2C, SPI 22 GPIO, 6 ШИМ, 4 UART, I2C, SPI Через дополнение: входные/выходные gobus модули
(GPIO, ШИМ, UART, SPI и т.д.)
Аналоговые входы 6 каналов АЦП (12-битных) 6 каналов АЦП (12-битных) Через дополнение: аналоговые gobus модули
Хранение micro SD карта (до 2 ГБ) micro SD карта (до 2 ГБ) Через дополнение: sd card gobus модуль
gobus порты нет нет 8 gobus портов
Окружающая среда Температура 0 – 70 °C (32 – 158 °F) 0 – 70 °C (32 – 158 °F) 0 – 70 °C (32 – 158 °F)

Техническое описание

Netduino Plus 2 является следующей версией платы Netduino Plus и обладает в 4 раза большей производительностью по сравнению с предшественником. Это проявляется в увеличении тактовой частоты (168 МГц, вместо 48 МГц) и объема памяти хранения кода программ и RAM.

Netduino Plus 2. Расположение входов/выходов.

Процессор/микроконтроллер

Главной составляющей платы является процессор Atmel ARM, который содержит память RAM и память хранения кода программ, используемую приложениями. Его выводы соединены с выводами синих разъемов, расположенных по краям платы. Эти выводы используются для подключения внешних компонентов и плат расширения.

Netduino Plus 2. Процессор

Аналоговые входы

На плате расположен 6-пиновый разъем аналоговых входов, которые могут быть использованы для чтения состояния любых аналоговых датчиков, измеряющих любую величину, например:

  • влажность;
  • температура;
  • освещенность;
  • давление;
  • движение.

Кроме того, аналоговые входы могут использоваться в качестве цифровых входов/выходов.

Netduino Plus 2. Аналоговые входы

Цифровые входы/выходы

Цифровые входы/выходы служат для обработки цифровых сигналов.

  • Количество цифровых входов/выходов: 14.
  • Они могут подключаться к датчикам, имеющим два состояния (вкл/выкл), например, кнопки, тумблеры и т.д.
  • Могут использоваться в качестве выходов для управления светодиодами, реле, коммутаторами.
  • Могут использоваться для связи, использующей стандартные протоколы, например, I2C, SPI, UART.
  • Могут использоваться для передачи импульсов для изменения скорости двигателя, интенсивности света и т.д.

Особенности цифровых входов/выходов:

  • все 22 цифровых и аналоговых вывода: GPIO
  • цифровые выводы 0-1: UART 1 RX, TX
  • цифровые выводы 2-3: UART 2 RX, TX/PWM
  • цифровые выводы 5-6: PWM, PWM
  • цифровые выводы 7-8: UART 3 RX, TX (также работают как UART 2 RTS, CTS)
  • цифровые выводы 9-10: PWM, PWM
  • цифровые выводы 11-13: PWM/MOSI, MISO, SPCK
  • цифровые выводы SD/SC: SDA/SCL (также работают как UART 4 RX, TX)

Netduino Plus 2. Цифровые входы/выходы

Ethernet

Netduino Plus 2 обладает разъемом Ethernet, который позволяет нам подключать плату к сети, к локальной или к интернету. Подключение к интернету открывает целый ряд новых возможностей, например, чтение данных с удаленных серверов или передача в интернет данных от подключенных датчиков и устройств. Это позволяет нам с помощью Netduino создавать интернет вещей.

Netduino Plus 2. Ethernet

MicroSD

В эту версию Netduino был добавлен слот MicroSD. Карта MicroSD может хранить данные, используемые Netduino, или Netduino может записывать данные на карту для локального хранения. Мы можем даже хранить на карте скомпилированные программы, которые затем будут выполняться на Netduino.

Netduino Plus 2. Слот карты памяти MicroSD

Светодиоды

На плате расположено два светодиода. Белый светодиод загорается, когда на плату подается питание, и действует, как индикатор питания. Другой светодиод (синий) – это пользовательский светодиод, и может управляться из программы, запущенной на Netduino.

Netduino Plus 2. Светодиоды

Питание

Для Netduino требуется напряжение от 7,5В до 12В с плюсом на центральном выводе разъема. Питание может быть подано от AC/DC адаптера с разъемом 5,5мм на 2,1мм.

В случае подачи напряжения неправильной полярности сработает восстанавливающийся предохранитель, который вернется в исходное состояние после того, как остынет.

Netduino Plus 2. Разъем питания

MicroUSB

Данный порт выполняет несколько функций на плате:

  • соединяет плату Netduino с компьютером;
  • может использоваться для питания платы;
  • используется для загрузки приложений на плату Netduino и интерактивной их отладки;
  • может использоваться для подключения устройств ввода (например, клавиатуры или мыши).

Netduino Plus 2. Разъем MicroUSB

Площадка стирания

Это маленькая золотая точка в конце разъема цифровых входов/выходов. Она может использоваться для полного стирания Netduino, чтобы начать с нуля.

Она была добавлена, чтобы сделать плату дружественной к хакам, и чтобы Netduino могла использоваться, как простая отладочная плата для ARM микроконтроллеров.

Функция стирания активируется подключением на несколько секунд провода между выводом 3,3В и площадкой стирания.

После полного стирания мы можем установить на Netduino новую операционную систему или, начав с нуля, написать код на C++.

Netduino Plus 2. Площадка стирания

Кнопка

  • Кнопка на плате по умолчанию действует для Netduino, как кнопка рестарта.
  • Обычно используется для рестарта действий выполняемого приложения.
  • Кнопка также может быть доступна в программе, как устройство ввода, и запускать действия при нажатии.
  • Кнопка помогает ввести плату во время загрузки в режим программирования для обновления прошивки, для чего необходимо удерживать ее нажатой во время загрузки платы.

Netduino Plus 2. Кнопка

Магазины и цены

Цены на Netduino Plus 2Товар в магазинеКоличество штук в комплектеСтоимостьРасчетная стоимость за 1 шт.
Netduino Plus 2 на AliExpress 1 5196.28 руб. / 79.99 USD(на 2 октября 2016) 5196.28 руб. / 79.99 USD

5 отличных альтернатив Arduino

Не позволяйте Arduino забирать всё веселье Семейство продуктов Arduino стало очень популярным благодаря комбинации открытой аппаратной архитектуры и программного обеспечения с открытым исходным кодом, Arduino foundation ждал полный успех. Наряду с…

Источник: https://radioprog.ru/shop/merch/13

Netduino 2

Если вашим любимым языком программирования является C#, Netduino 2 позволит вам создать своё электронное устройство с комфортом. Эта плата подойдёт и тем, кто только начинает свой путь в программировании.

Мощная среда программирования Microsoft Visual Studio поможет новичкам не ошибиться в трудной ситуации, а благодаря отладочному режиму с поддержкой breakpoint’ов и watch’ей вы сможете проследить исполнение своей программы шаг за шагом.

Netduino 2 совместима с большинством плат расширения Arduino и сочетает в себе вычислительную мощь и удобство разработки.

Процессор и память

Плата оснащена 32-разрядным ARM-микроконтроллером STM32F205RF с ядром Cortex-M3, частотой 120 МГц, 60 кБ оперативной памяти и 192 кБ энергонезависимой Flash-памяти.

Входы/выходы

22 пина, расположенных в стандартной для Arduino компоновке могут быть использованы как цифровые входы или выходы.

Цифровые входы и выходы рассчитаны на работу с напряжением 3,3 В. Однако, они толерантны и к напряжению 5 В.

Внимание! При использовании цифровых входов в режиме подтяжки, напряжение на входе не должно превышать 3,6 В. Будьте внимательны при использовании этого режима.

Плата содержит в себе 4 последовательных порта, по одному интерфейсу I²C и SPI. Для работы с аналоговым сигналом присутствуют 6 аналоговых входов с разрешением в 12-бит (4096 градаций). 6 выходов поддерживают ШИМ.

На месте привычных ICSP-контактов находится 10-пиновый JTAG-интерфейс. Поэтому, если вы используете платы расширения с SPI-интерфейсом, воспользуйтесь проводами «мама-папа» для соединения ICSP-контактов и контактов SPI.

На плате присутствуют встроенная кнопка и два светодиода. Кнопка используется для сброса микроконтроллера. При желании вы можете использовать её в своём проекте в качестве элемента управления. Белый светодиод PWR используется как индикатор питания. Синий светодиод LED вы можете использовать в своём проекте для произвольных нужд.

Программирование

Плата программируется при помощи традиционной для .NET разработки среды Microsoft Visual Studio. Все необходимое для начала работы с Netduino 2 вы можете узнать из статьи на вики.

Питание

Плата может быть запитана через microUSB-кабель или при помощи источника питания постоянного тока на 7,5–9 В. Для питания платы от сети вы можете воспользоваться импульсным блоком питания.

Характеристики

  • Процессор: STM32F205RF
  • Ядро: 32-х разрядный ARM Cortex-M3 120 МГц
  • Оперативной памяти: 60 кБ
  • Энергонезависимой памяти: 192 кБ Flash, 4 кБ EEPROM
  • Напряжение питания микроконтроллера: 3,3 В
  • Количество линий ввода-вывода: 22 (все толерантны к 5 В. Подтяжка к земле или питанию толерантна к 3,6 В)
  • Максимальный ток через контакт ввода-вывода: 25 мА
  • Максимальный ток через все контакты микроконтроллера: 125 мА
  • Количество каналов АЦП: 6
  • Количество каналов ШИМ: 6
  • Количество UART: 4 шт (один из них с поддержкой RTS/CTS)
  • Количество I²C: 1 шт
  • Количество SPI: 1 шт
  • Напряжения питания платы: 5 В, 7,5–9 В

Ссылки

Источник: http://amperka.ru/product/netduino-2

AVR. Учебный курс. Подключение к AVR LCD дисплея HD44780

Сегодня разменял четверть века!

Так случилось, что прикупил я тут себе поприколу LCD дисплейчик две строки по восемь символов. Валялся он в ящике валялся, да чегото поперло меня и решил я его заюзать, попутно вкурив в его работу.

О том как подключить к AVR LCD дисплей я вам сейчас и поведаю.

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

Продается везде где только можно, стоит недорого (8х2 мне обошелся порядка 150 рублей), а также под него написана куча кода. Я же, как обычно, решил изобрести велосипед и сварганить свою собственную тру-библиотеку для работы с этим типом индикаторов. Разумеется на ассемблере, а на чем же еще? 😉

Подключение.
LCD на базе HD44780 подключается к AVR микроконтроллеру напрямую к портам. Есть два способа подключения — на 8 бит и на 4 бита. В восьмибитном режиме немножко проще закидывать байты — не нужно сдвигать байт, зато в четырех битном резко нужно тратить на целых четыре ножки контроллера меньше. Есть еще одна особенность работы в 8-битном режиме — к некоторым контроллерам можно подрубить этот дисплей как внешнее ОЗУ и засылать данные простыми командами пересылки. Лично я подключил его в режиме полного порта у меня один фиг выводы уже девать некуда было, так что не жалко.

  • Выводы DB7…DB0 это шина данных/адреса.
  • E — стробирующий вход. Дрыгом напряжения на этой линии мы даем понять дисплею что нужно забирать/отдавать данные с/на шину данных.
  • RW — определяет в каком направлении у нас движутся данные. Если 1 — то на чтение из дисплея, если 0 то на запись в дисплей.
  • RS — определяет что у нас передается, команда (RS=0) или данные (RS=1). Данные будут записаны в память по текущему адресу, а команда исполнена контроллером.

Со стороны питания все еще проще:

Подключение дисплея
Видимая и скрытая область экранной памяти
Структура адресации контроллера HD44780
Формирование символа в ячейке CGRAM

  • GND — минус, он же общий.
  • Vcc — плюс питания, обычно 5V
  • V0 — вход контрастности. Сюда нужно подавать напряжение от нуля до напряжения питания, тем самым задается контрастность изображения. Можно поставить переменный резистор, включенный потенциометром и крутить в свое удовольствие. Главное поймать значение максимального контраста, но чтобы не было видно знакомест (серый ореол из квадратов вокруг символа). Если же выставить слишком малый контраст, то символы будут переключаться лениво и задумчиво. Примерно как в калькуляторе у которого сели батарейки.
  • А — это вход Анода светодиодной подсветки. Короче плюс.
  • К — соответственно Катод, он же минус. Подсветка хавает примерно 100мА и поэтому нужно выставить туда токоограничительный резистор на 100 Ом. Кстати, многие ЖК дисплеи имеют на плате пятачки для припайки резисторов. Если прозвонить, то можно убедиться в том, что эти линии ведут на входы питания LCD, поэтому, впаяв резисторы, можно не заморачиваться на запитку подстветки, она будет подключена к питанию контроллера.

Логическая структура LCD контроллера HD44780

Контроллер имеет свой блок управления, который обрабатывает команды и память. Она делится на три вида:

DDRAM — память дисплея. Все что запишется в DDRAM будет выведено на экран. То есть, например, записали мы туда код 0x31 — на экране выскочит символ «1» т.к. 0х31 это ASCII код цифры 1.

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

То есть, например, можно засунуть в DDRAM сразу пять пунктов меню, а потом просто гонять дисплей туда сюда, показывая по одному пункту. Для перемещения дисплея есть спец команда. Также есть понятие курсора — это место в которое будет записан следующий символ, т.е. текущее значение счетчика адреса.

Курсор не обязательно может быть на экране, он может располагаться и за экраном или быть отключен вовсе.

CGROM — таблица символов. Когда мы записываем в ячейку DDRAM байт, то из таблицы берется символ и рисуется на экране. CGROM нельзя изменить, поэтому важно, чтобы она имела на борту русские буквы. Если, конечно, планируется русскоязычный интерфейс.

CGRAM — тоже таблица символов, но ее мы можем менять, создавая свои символы. Адресуется она линейно, то есть вначале идет 8 байт одного символа, построчно, снизу вверх — один бит равен одной точке на экране. Потом второй символ тем же макаром. Поскольку знакоместо у нас 5 на 8 точек, то старшие три бита роли не играют.

Всего в CGRAM может быть 8 символов, соответственно CGRAM имеет 64 байта памяти. Эти программируемые символы имеют коды от 0х00 до 0х07.

Так что, закинув, например, в первые 8 байт CGRAM (первый символ с кодом 00) какую нибудь фигню, и записав в DDRAM нуль (код первого символа в CGRAM) мы увидим на экране нашу хрень.

Доступ к памяти.
Тут все просто. Мы командой выбираем в какую именно память и начиная с какого адреса будем писать. А потом просто шлем байты. Если указано, что записываем в DDRAM то на экран (или в скрытую область) полезут символы, если в CGRAM то байты полезут уже в память знакогенератора. Главное потом не забыть переключится обратно на область DDRAM

Система команд.
Система команд проста как мычание. О том, что передается команда контроллеру дисплея сообщит нога RS=0. Сама команда состоит из старшего бита, определяющего за что отвечает данная команда и битов параметров, указывающих контроллеру HD44780 как дальше жить.

Таблица команд:

DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Значение
1 Очистка экрана. Счетчик адреса на 0 позицию DDRAM
1 Адресация на DDRAM сброс сдвигов, Счетчик адреса на 0
1 I/D S Настройка сдвига экрана и курсора
1 D C B Настройка режима отображения
1 S/C R/L Сдвиг курсора или экрана, в зависимости от битов
1 DL N F Выбор числа линий, ширины шины и размера символа
1 AG AG AG AG AG AG Переключить адресацию на SGRAM и задать адрес в SGRAM
1 AD AD AD AD AD AD AD Переключить адресацию на DDRAM и задать адрес в DDRAM

Теперь поясню что значат отдельные биты:

  • I/D — инкремент или декремент счетчика адреса. По дефолту стоит 0 — Декремент. Т.е. каждый следующий байт будет записан в n-1 ячейку. Если поставить 1 — будет Инкремент.
  • S — сдвиг экрана, если поставить 1 то с каждым новым символом будет сдвигаться окно экрана, пока не достигнет конца DDRAM, наверное удобно будет когда выводишь на экран здоровенную строку, на все 40 символов, чтобы не убегала за экран.
  • D — включить дисплей. Если поставить туда 0 то изображение исчезнет, а мы в это время можем в видеопамяти творить всякие непотребства и они не будут мозолить глаза. А чтобы картинка появилась в эту позицию надо записать 1.
  • С — включить курсор в виде прочерка. Все просто, записали сюда 1 — включился курсор.
  • B — сделать курсор в виде мигающего черного квадрата.
  • S/C сдвиг курсора или экрана. Если стоит 0, то сдвигается курсор. Если 1, то экран. По одному разу за команду
  • R/L — определяет направление сдвига курсора и экрана. 0 — влево, 1 — вправо.
  • D/L — бит определяющий ширину шины данных. 1-8 бит, 0-4 бита
  • N — число строк. 0 — одна строка, 1 — две строки.
  • F — размер символа 0 — 5х8 точек. 1 — 5х10 точек (встречается крайне редко)
  • AG — адрес в памяти CGRAM
  • АD — адрес в памяти DDRAM

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

Задача:

  1. Включить дисплей.
  2. Очистить содержимое.
  3. Сдвинуть курсор на одну позицию.
  4. И записать туда «1».

Решение (последовательность команд):

Первым делом Инициализация дисплея без которой большая часть дисплеев на HD44780 просто откажется работать. Некоторые виды имеют дефолтные состояние (шина 8 бит, курсор в 0) и им только дисплей включить. Но все же ее лучше сделать, мало ли что там намудрил разработчик. Лишней не будет.

  • 00111000 Шина 8 бит, 2 строки
  • 00000001 Очистка экрана
  • 00000110 Инкремент адреса. Экран не движется
  1. 00001100 Включили дисплей (D=1)
  2. 00000001 Очистили дисплей. Указатель встал на DDRAM
  3. 00010100 Сдвинули курсор (S/C=0) вправо (R/L=1)
  4. 00110001 — это мы уже записали данные (ножка RS=1) код «1» 0х31

Жирным шрифтом выделен идентификатор команды, ну а остальное по таблице увидите.

Задача: создать свой символ. С кодом 01 и вывести его на экран.
Считаем, что дисплей у нас уже инициализирован и готов к приему данных.

Решение:

  1. 01001000      Выбираем в CGRAM адрес 0х08 — как раз начало второго символа (напомню, что на один символ уходит 8 байт)
  2. 00000001     Это пошли 8 байт данных.

    (RS=1)

  3. 00000010     Рисуем значок молнии, ну или
  4. 00000100     ССовскую Зиг руну, кому как
  5. 00001000     больше нравится.

  6. 00011111     Старшие три бита не действуют
  7. 00000010     Туда можно писать что угодно, на
  8. 00000100     результат влиять не будет.

  9. 00001000     Последний байт данных  
  10. 10000000      А это уже команда — переключение адреса на DDRAM и указатель на адрес 0000000 — первый символ в первой строке.
  11. 00000001      И снова данные (RS=1), код 01 — именно в него мы засунули нашу молнию.

Опа и он на экране!

Так, с логикой разобрались, пора вкуривать в физику протокола общения. Код я приведу несколько позже, когда вылижу свою библиотеку и заоптимизирую до состояния идеала. Пока же дам алгоритм, а его уж на любом языке программирования реализовать можно. Хоть на ассемблере, хоть на Сях, да хоть на Васике 🙂

Алгоритм чтения/записи в LCD контроллер HD44780
Направление, а также команда/данные определяются ножками, а чтение и запись осуществляется по переходу строба (вывод Е) из 1 в 0

Инициализация портов

  1. RS, RW, E — в режим выхода.
  2. DB7..DB0 в режим входа. Впрочем, можно их не трогать, дальше переопределим.

Ожидание готовности, чтение флага занятости.

  1. Порт данных на вход с подтяжкой (DDR=0, PORT=1)
  2. RS=0 (команда)
  3. RW=1 (чтение)
  4. E=1 (Готовьсь!!!)
  5. Пауза (14 тактов процессора на 8МГЦ хватало)
  6. Е=0 (Пли!)
  7. Читаем из порта. Если бит 7 (Busy flag) установлен, то повторяем все заново, пока не сбросится.

Запись команды

  1. Ожидание готовности
  2. RS=0 (команда)
  3. RW=0 (запись)
  4. Е=1 (Готовьсь!!!)
  5. Порт на выход
  6. Вывести в порт код команды
  7. Пауза
  8. Е=0 (Пли!)
  9. Орудие на плечо Порт на вход, на всякий случай.

Запись Данных

  1. Ожидание готовности
  2. RS=1 (Данные)
  3. RW=0 (запись)
  4. Е=1 (Готовьсь!!!)
  5. Порт на выход
  6. Вывести в порт код команды
  7. Пауза
  8. Е=0 (Пли!)
  9. Порт на вход, на всякий случай.

Чтение команды

  1. Ожидание готовности
  2. Порт данных на вход с подтяжкой (DDR=0, PORT=1)
  3. RS=0 (команда)
  4. RW=1 (чтение)
  5. Е = 1 (Готовьсь! В этот момент данные из LCD вылазят на шину)
  6. Пауза
  7. Считываем данные с порта
  8. E=0 (Ать!)

Чтение Данных

  1. Ожидание готовности
  2. Порт данных на вход с подтяжкой (DDR=0, PORT=1)
  3. RS=1 (Данные)
  4. RW=1 (чтение)
  5. Е = 1 (Готовьсь! В этот момент данные из LCD вылазят на шину)
  6. Пауза
  7. Считываем данные с порта
  8. E=0 (Ать!)

С четырех разрядной шиной все точно также, только там каждая операция чтения/записи делается за два дрыга строба.

Запись:

  1. E=1
  2. Пауза
  3. Выставили в порт старшую тетраду
  4. E=0
  5. Пауза
  6. Е=1
  7. Пауза
  8. Выставили в порт младшую тетраду
  9. Е=0

Чтение

  1. E=1
  2. Пауза
  3. Читаем из порта старшую тетраду
  4. Е=0
  5. Пауза
  6. Е=1
  7. Пауза
  8. Читаем из порта младшую тетраду
  9. Е=0

Ждите код 🙂 Скоро будет 🙂
UPD:
А вот и код!

Источник: http://easyelectronics.ru/avr-uchebnyj-kurs-podklyuchenie-k-avr-lcd-displeya-hd44780.html

Как подключить LCD дисплей с I2C модулем к Arduino

В статье будем подключать к Ардуино жидкокристаллический дисплей 1602 с I2C модулем FC-113, благодаря чему подключение будет осуществляться всего по 2 проводам данных + 2 проводам питания.

  • Arduino;
  • LCD 1602 дисплей (16 символов, 02 строки);
  • I2C адаптер FC-113;
  • соединительные провода.
  • Модуль FC-113 сделан на базе микросхемы PCF8574T, которая представляет собой 8-битный сдвиговый регистр – «расширитель» входов-выходов для последовательной шины I2C. На рисунке микросхема обозначена DD1.
  • R1 – подстроечный резистор для регулировки контрастности ЖК дисплея.
  • Джампер J1 используется для включения подсветки дисплея.
  • Выводы 1…16 служат для подключения модуля к выводам LCD дисплея.
  • Контактные площадки А1…А3 нужны для изменения адреса I2C устройства. Запаивая соответствующие перемычки, можно менять адрес устройства. В таблице приведено соответствие адресов и перемычек: “0” соответствует разрыву цепи, “1” – установленной перемычке. По умолчанию все 3 перемычки разомкнуты и адрес устройства 0x27.

I2C модуль FC-113 для подключения ЖК экрана

Подключение модуля к Arduino осуществляется стандартно для шины I2C: вывод SDA модуля подключается к аналоговому порту A4, вывод SCL – к аналоговому порту A5 Ардуино. Питание модуля осуществляется напряжением +5 В от Arduino. Сам модуль соединяется выводами 1…16 с соответствующими выводами 1…16 на ЖК дисплее.

Схема подключения ЖК дисплея к Arduino по протоколу I2C

3Библиотека для работы по протоколу I2C

Теперь нужна библиотека для работы с LCD по интерфейсу I2C. Можно воспользоваться, например, вот этой (ссылка в строке “Download Sample code and library”).

Библиотека для работы по протоколу I2C

Скачанный архив LiquidCrystal_I2Cv1-1.rar разархивируем в папку libraries, которая находится в директории Arduino IDE.

Библиотека поддерживает набор стандартных функций для LCD экранов:

ФункцияНазначение
LiquidCrystal() создаёт переменную типа LiquidCrystal и принимает параметры подключения дисплея (номера выводов);
begin() инициализация LCD дисплея, задание параметров (кол-во строк и символов);
clear() очистка экрана и возврат курсора в начальную позицию;
home() возврат курсора в начальную позицию;
setCursor() установка курсора на заданную позицию;
write() выводит символ на ЖК экран;
print() выводит текст на ЖК экран;
cursor() показывает курсор, т.е. подчёркивание под местом следующего символа;
noCursor() прячет курсор;
blink() мигание курсора;
noBlink() отмена мигания;
noDisplay() выключение дисплея с сохранением всей отображаемой информации;
display() включение дисплея с сохранением всей отображаемой информации;
scrollDisplayLeft() прокрутка содержимого дисплея на 1 позицию влево;
scrollDisplayRight() прокрутка содержимого дисплея на 1 позицию вправо;
autoscroll() включение автопрокрутки;
noAutoscroll() выключение автопрокрутки;
leftToRight() задаёт направление текста слева направо;
rightToLeft() направление текста справа налево;
createChar() создаёт пользовательский символ для LCD-экрана.

4Скетч для вывода текста на LCD экран по шине I2C

Откроем образец: Файл Образцы LiquidCrystal_I2C CustomChars и немного его переделаем. Выведем сообщение, в конце которого будет находиться мигающий символ. В комментариях к коду прокомментированы все нюансы скетча.

#include // подключаем библиотеку Wire #include // подключаем библиотеку ЖКИ #define printByte(args) write(args); // uint8_t heart[8] = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0}; // битовая маска символа «сердце» LiquidCrystal_I2C lcd(0x27, 16, 2); // Задаём адрес 0x27 для LCD дисплея 16×2 void setup() { lcd.init(); // инициализация ЖК дисплея lcd.backlight(); // включение подсветки дисплея lcd.createChar(3, heart); // создаём символ «сердце» в 3 ячейке памяти lcd.home(); // ставим курсор в левый верхний угол, в позицию (0,0) lcd.print(“Hello SolTau.ru!”); // печатаем строку текста lcd.setCursor(0, 1); // перевод курсора на строку 2, символ 1 lcd.print(” i “); // печатаем сообщение на строке 2 lcd.printByte(3); // печатаем символ «сердце», находящийся в 3-ей ячейке lcd.print(” Arduino “); } void loop() { // мигание последнего символа lcd.setCursor(13, 1); // перевод курсора на строку 2, символ 1 lcd.print(” “); delay(500); lcd.setCursor(13, 1); // перевод курсора на строку 2, символ 1 lcd.print(” “); delay(500); }

Кстати, символы, записанные командой lcd.createChar();, остаются в памяти дисплея даже после выключения питания, т.к. записываются в ПЗУ дисплея 1602.

5Создание собственных символов для ЖК дисплея

Немного подробнее рассмотрим вопрос создания собственных символов для ЖК экранов. Каждый символ на экране состоит из 35-ти точек: 5 в ширину и 7 в высоту (+1 резервная строка для подчёркивания). В строке 6 приведённого скетча мы задаём массив из 7-ми чисел: {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0}.

Преобразуем 16-ричные числа в бинарные: {00000, 01010, 11111, 11111, 01110, 00100, 00000}. Эти числа – не что иное, как битовые маски для каждой из 7-ми строк символа, где “0” обозначают светлую точку, а “1” – тёмную.

Например, символ сердца, заданный в виде битовой маски, будет выглядеть на экране так, как показано на рисунке.

Создание собственного символа для LCD экрана

6Управление ЖК экраном по шине I2C

Загрузим скетч в Arduino. На экране появится заданная нами надпись с мигающим курсором в конце.

Управление ЖК экраном с помощью Arduino по шине I2C

7Что находится «за» шиной I2C

В качестве бонуса рассмотрим временную диаграмму вывода латинских символов “A”, “B” и “С” на ЖК дисплей. Эти символы имеются в ПЗУ дисплея и выводятся на экран просто передачей дисплею их адреса. Диаграмма снята с выводов RS, RW, E, D4, D5, D6 и D7 дисплея, т.е. уже после преобразователя FC-113 «I2C параллельная шина». Можно сказать, что мы погружаемся немного «глубже» в «железо».

Временная диаграмма вывода латинских символов “A”, “B” и “С” на LCD дисплей 1602

На диаграмме видно, что символы, которые имеются в ПЗУ дисплея (см. стр.11 даташита, ссылка ниже), передаются двумя полубайтами, первый из которых определяет номер столбца таблицы, а второй – номер строки.

При этом данные «защёлкиваются» по фронту сигнала на линии E (Enable), а линия RS (Register select, выбор регистра) находится в состоянии логической единицы, что означает передачу данных. Низкое состояние линии RS означает передачу инструкций, что мы и видим перед передачей каждого символа.

В данном случае передаётся код инструкции возврата каретки на позицию (0, 0) ЖК дисплея, о чём также можно узнать, изучив техническое описание дисплея.

И ещё один пример. На этой временной диаграмме показан вывод символа «Сердце» на ЖК дисплей.

Временная диаграмма вывода символа «Сердце» из ПЗУ на ЖК дисплей 1602

Опять, первые два импульса Enable соответствуют инструкции Home() (0000 00102) – возврат каретки на позицию (0; 0), а вторые два – вывод на ЖК дисплей хранящийся в ячейке памяти 310 (0000 00112) символ «Сердце» (инструкция lcd.createChar(3, heart); скетча).

Скачать LCD 1602 datasheet

  • Скачать техническое описание на LCD дисплей 1602.

Источник: https://soltau.ru/index.php/arduino/item/372-kak-podklyuchit-lcd

Z- LCD I2C модуль v3

Опубликовано 19.11.2014 20:25:00

Z- LCD I2C модуль представляет из себя символьный дисплей с переходником на микросхеме PCF8574T, который позволяет подключить дисплей к плате Arduino всего по двум проводам не считая питания.

На модуле v3 появился джампер под пайку для отключения резисторной подтяжки шины I2C, а также джампер под пайку для отключения светодиода

Основные технические характеристики:

• Дисплей: Символьный 16х02 либо 20х04 (в зависимости от комплектации)

• Подсветка: Синяя c белыми символами

• Яркость подсветки: С возможностью программного регулирования

• Контраст: Настраивается потенциометром

• Напряжение питания: 5В

• Интерфейс: I2C

• I2C адрес: На выбор 8 вариантов

• Размеры: 82мм x 35мм x 18мм

Основные элементы Z- LCD I2C модуля:

1 – Микросхема PCF8574T

2 – Подстроечный резистор для регулирования контраста

3 – DIP переключатель для выбора адресации

4 – Джампер выбора варианта работы подсветки

5 – Гребенка для подключения к Arduino

6 – Индикаторный светодиод наличия питания + 5V (возможно отключить)

7 – Джампер под пайку для отключения резисторной подтяжки шины I2C

Адресация:

Передвигая ползунки на DIP переключателе можно изменять адресацию устройства, всего 8 вариантов. Изменение адресации дает нам возможность подключить до восьми устройств на линию I2C микросхемы PCF8574T. Для её изменения необходимо притянуть выводы A0, A1, A2 к положительному либо отрицательному потенциалу. На плате положения промаркированы.

В программном коде, инициализация адреса производится в данной строке.

LiquidCrystal_I2C lcd(0x27,16,2);

Подключение к Arduino:

Для работы с данным модулем необходимо установить библиотеку LiquidCrystal_I2C1602V1

Скачиваем, распаковываем и закидываем в папку libraries в папке Arduino. В случае, если на момент добавления библиотеки, Arduino IDE была открытой, перезагружаем среду.

//Работа с курсором 
lcd.setCursor(0, 0); // Устанавливаем курсор (номер ячейки, строка)
lcd.home(); // Установка курсора в ноль (0, 0)
lcd.cursor(); // Включить видимость курсора (подчеркивание)
lcd.noCursor(); // Убрать видимость курсора (подчеркивание)
lcd.blink(); // Включить мигание курсора (курсор 5х8)
lcd.noBlink(); // Выключить мигание курсора (курсор 5х8) //Вывод информации
lcd.print(“zelectro.cc”); // Вывод информации
lcd.clear(); // Очистка дисплея, (удаление всех данных) установка курсора в ноль
lcd.rightToLeft(); // Запись производится справа на лево
lcd.leftToRight(); // Запись производится слева на право
lcd.scrollDisplayRight(); // Смещение всего изображенного на дисплее на один символ вправо
lcd.scrollDisplayLeft(); // Смещение всего изображенного на дисплее на один символ влево //Информация полезная для шпионов:)
lcd.noDisplay(); // Информация на дисплее становится невидимой, данные не стираются
// если, в момент когда данная функция активна, ничего не выводить на дисплей, то
lcd.display(); // При вызове функции display() на дисплее восстанавливается вся информация которая была //Подсветка
lcd.backlight();                  // Включение подсветки
lcd.noBacklight();                // Выключение подсветки

Модуль оборудован четырех-пиновым разъемом стандарта 2.54мм

 SCL: последовательная линия тактирования (Serial CLock)

 SDA: последовательная линия данных (Serial DAta)

 VCC: “+” питания

 GND: “-” питания

Выводы отвечающие за интерфейс I2C на платах Arduino на базе различных контроллеров разнятся

 LCD I2C модуль   На базе ATmega 328   Leonardo   MEGA, ADK, DUE 
 SCL  A5  D3  D21
SDA  A4  D2  D20
 VCC  +5V  +5V  +5V
 GND  GND  GND  GND

 

• Пример вывода информации и работы модуля с подсветкой в режиме ВКЛ/ВЫКЛ

Для работы подсветки в режиме ВКЛ/ВЫКЛ соединяем вывод BL с выводом P3 микросхемы PCF8574T

В программном коде она будет задаваться функцией

lcd.backlight();        // Включение подсветки

lcd.noBacklight();    // Выключение подсветки

// Тестировалось на Arduino IDE 1.0.5
#include  #include  LiquidCrystal_I2C lcd(0x27,16,2);   /* Задаем адрес и размерность дисплея.
При использовании LCD I2C модуля с дисплеем 20х04 ничего в коде изменять не требуется, cледует только задать правильную размерность */ void setup()
{
  lcd.init();                       // Инициализация lcd
  lcd.backlight();                  // Включаем подсветку
  delay (1000);
  lcd.noBacklight();                // Выключаем подсветку
  delay (1000);
  lcd.backlight();                  // Включаем подсветку
  lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
  lcd.print(“Hello, world!”); // Выводим текст
  lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
  lcd.print(“zelectro.cc”); // Выводим текст
} void loop()
{
}

• Пример работы модуля с регулированием яркости подсветки

Для регулирования яркости придется задействовать один ШИМ вывод контроллера. Соединяем вывод BL с любым ШИМ выводом Arduino. В зависимости от скважности ШИМ сигнала можно получить любую яркость подсветки.

В программном коде она будет задаваться функцией

analogWrite(BL, число от 0 до 255);

// Тестировалось на Arduino IDE 1.0.5
#include  #include 
int BL = 9; // Выыод “BL” подключаем к цифровому выводу 9 с поддержкой ШИМ
LiquidCrystal_I2C lcd(0x27,16,2);   /* Задаем адрес и размерность дисплея.
 При использовании LCD I2C модуля с дисплеем 16х4 ничего в коде изменять не требуется, cледует только заменить цифру отвечающую за количество сторок */ void setup()
{
  lcd.init();                       // Инициализация lcd
  analogWrite(BL, 255); // Включаем подсветку на максимальное значение
  lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
  lcd.print(“Hello, world!”); // Выводим текст
  lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
  lcd.print(“zelectro.cc”); // Выводим текст
  delay (1000);
} void loop()
{
    analogWrite(BL, 0); // Значение ШИМ минимальное – подсветка отключена
    delay(1000);
    analogWrite(BL, 120); // Значение ШИМ среднее – подсветка включена на середину яркости     
delay(1000);
    analogWrite(BL, 255); // Значение ШИМ максимальное – подсветка включена на максимум   
delay(1000);
}

• Работа с двумя и более модулями

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

Программная часть                                                                                        

// Тестировалось на Arduino IDE 1.0.5
#include  #include 
int BL = 9; // Задаем адреса и размерности дисплеев.
LiquidCrystal_I2C lcd1(0x27,16,2); 
LiquidCrystal_I2C lcd2(0x20,16,2);  void setup()
{
  // Работа с двумя дисплеями также очень проста.
  // Для общения с первым будет приставка Lcd1, для второго Lcd2
  lcd1.init();                       // Инициализация LCD 1
  lcd2.init();                       // Инициализация LCD 2
  lcd1.backlight();                  // Включаем подсветку LCD1
  analogWrite(BL, 255); // Включаем подсветку LCD2 на максимальное значение   lcd1.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
  lcd1.print(“Hello, world!”); // Выводим текст
  lcd1.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
  lcd1.print(“zelectro.cc LCD1”); // Выводим текст
  lcd2.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
  lcd2.print(“Hello, world!”); // Выводим текст
  lcd2.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
  lcd2.print(“zelectro.cc LCD2”); // Выводим текст
} void loop()
{    
}

Железная часть

При подключении более двух – трех модулей работающих по интерфейсу I2C, необходимо отключать резисторную подтяжку.

B идеале оставить подтяжку шины I2C на одном устройстве. Объяснение почему.

Итоговый пример

В качестве итогового примера поуправляем двумя модулями 16х02 и 20х04.

На первом подсветка работает в режиме регулирования яркости, а на втором в режиме ВКЛ/ВЫКЛ.

// Тестировалось на Arduino IDE 1.0.5 
#include 
#include 
int BL = 9; LiquidCrystal_I2C lcd1(0x20,20,4);
LiquidCrystal_I2C lcd2(0x27,16,2);
/* Задаем адрес и размерность дисплея.
 При использовании LCD I2C модуля с дисплеем 16х4 ничего в коде изменять не требуется, cледует только заменить цифру отвечающую за количество сторок */ void setup()
{
  lcd1.init();                       // Инициализация LCD 1
  lcd2.init();                       // Инициализация LCD 2
  lcd1.clear ();
  lcd2.clear ();   lcd2.noBacklight();            
  analogWrite(BL, 0);   delay (500);   lcd2.backlight();                  // Включаем подсветку
  analogWrite(BL, 255); // Включаем подсветку на максимальное значение
  lcd1.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
  lcd1.print(“Z-LCD I2C 2004 “); // Выводим текст
  lcd1.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
  lcd1.print(“module “); // Выводим текст
  lcd1.setCursor(0, 3); // Устанавливаем курсор в начало 2 строки
  lcd1.print(“zelectro.cc”); // Выводим текст
  lcd2.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
  lcd2.print(“Z-LCD I2C 1602 “); // Выводим текст
  lcd2.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
  lcd2.print(“module “); // Выводим текст
  delay (3000);
  lcd1.clear ();
  lcd2.clear ();
  delay (500);   lcd1.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
  lcd1.print(“Backlight “); // Выводим текст
  lcd1.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
  lcd1.print(“Demonstration “); // Выводим текст
  lcd1.setCursor(0, 2); // Устанавливаем курсор в начало 2 строки
  lcd1.print(“BL connected to”); // Выводим текст
  lcd1.setCursor(0, 3); // Устанавливаем курсор в начало 2 строки
  lcd1.print(“PWM output”); // Выводим текст   lcd2.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
  lcd2.print(“Backlight “); // Выводим текст
  lcd2.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
  lcd2.print(“Demonstration “); // Выводим текст
  delay (1000);   lcd2.noBacklight();                
  for(int i = 255; i >= 200; –i)
  {
    analogWrite(BL, i);
    delay(10);
  }
  lcd2.backlight();
  for(int i = 200; i >= 150; –i)
  {
    analogWrite(BL, i);
    delay(10);
  }
  lcd2.noBacklight();                
  for(int i = 150; i >= 100; –i)
  {
    analogWrite(BL, i);
    delay(10);
  }
  lcd2.backlight();
  for(int i = 100; i >= 50; –i)
  {
    analogWrite(BL, i);
    delay(10);
  }
  lcd2.noBacklight();                
  for(int i = 50; i >= 0; –i)
  {
    analogWrite(BL, i);
    delay(10);
  }
  delay(500);   lcd2.backlight();
  for(int i = 0; i < 50; ++i)   {     analogWrite(BL, i);     delay(10);   }   lcd2.noBacklight();     for(int i = 50; i < 100; ++i)   {     analogWrite(BL, i);     delay(10);   }   lcd2.backlight();   for(int i = 100; i < 150; ++i)   {     analogWrite(BL, i);     delay(10);   }   lcd2.noBacklight();     for(int i = 150; i < 200; ++i)   {     analogWrite(BL, i);     delay(10);   }   lcd2.backlight();   for(int i = 200; i < 255; ++i)   {     analogWrite(BL, i);     delay(10);   }   delay(1000);   lcd1.clear ();   lcd2.clear ();   delay(1500);   lcd2.noBacklight();     analogWrite(BL, 0); } void loop()
{    
}

Создание собственных символов

С выводом текста разобрались, буквы английского алфавита зашиты в память контроллера внутри дисплея и с ними проблем нет. А вот что делать если нужного символа в памяти контроллера нет?

Не беда, требуемый символ можно сделать вручную (всего до 7ми символов). Ячейка, в рассматриваемых нами дисплеях, имеет разрешение 5х8 точек. Все, к чему сводится задача создания символа, это написать битовую маску и расставить в ней единички в местах где должны гореть точки и нолики где нет.

В ниже приведенном примере нарисуем смайлик.

// Тестировалось на Arduino IDE 1.0.5
// Добавляем необходимые библиотеки
#include 
#include  // Битовая маска символа улыбки
byte smile[8] =
{
  B00010,
  B00001,
  B11001,
  B00001,
  B11001,
  B00001,
  B00010,
};     
LiquidCrystal_I2C lcd(0x27,20,4);      // Задаем адрес и размерность дисплея. void setup()
{   lcd.init();                          // Инициализация lcd
  lcd.backlight();                     // Включаем подсветку
  // Создаем символ под номером 0
  lcd.createChar(1, smile);   lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
  lcd.print(“1”); // Выводим смайлик (символ под номером 1) – “1”
} void loop()
{
}

 

Итоговый пример

P.S. Данный способ частично, ограничение в 7 символов, поможет решить проблему вывода кириллицы.

Выведем на дисплей солянку: надпись “Привет, Мир”, смайлик и текст на английском. 

// Тестировалось на Arduino IDE 1.0.5 
// Добавляем необходимые библиотеки
#include 
#include 
 
// Битовая маска буквы П
byte letter1[8] =
{
  B11111,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
};
 
// Битовая маска буквы и
byte letter2[8] =
{
  B00000,
  B00000,
  B10001,
  B10001,
  B10011,
  B10101,
  B11001,
};
 
// Битовая маска буквы в
byte letter3[8] =
{
  B00000,
  B00000,
  B11110,
  B10001,
  B11110,
  B10001,
  B11110,
};
 
// Битовая маска буквы т
byte letter4[8] =
{
  B00000,
  B00000,
  B11111,
  B00100,
  B00100,
  B00100,
  B00100,
};
 
// Битовая маска буквы M
byte letter5[8] =
{
  B10001,
  B11011,
  B10101,
  B10001,
  B10001,
  B10001,
  B10001,
};
 
// Битовая маска символа улыбки
byte smile[8] =
{
  B00010,
  B00001,
  B11001,
  B00001,
  B11001,
  B00001,
  B00010,
};
 
LiquidCrystal_I2C lcd(0x27,20,4);      // Задаем адрес и размерность дисплея.
 
void setup()
{
 
  lcd.init();                          // Инициализация lcd
  lcd.backlight();                     // Включаем подсветку
  // Создаем собственные символы
  lcd.createChar(1, letter1);
  lcd.createChar(2, letter2);
  lcd.createChar(3, letter3);
  lcd.createChar(4, letter4);
  lcd.createChar(5, letter5);
  lcd.createChar(6, smile);
 
  lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
  lcd.print(“1p23e4, 52p!”); // Вывод символа буквы П – “1”
  lcd.setCursor(15, 1);
  lcd.print(“6”); // Выводим смайлик – “6”
  lcd.setCursor(8, 3);   lcd.print(“zelectro.cc”); }
 
void loop()
{
}

Бонус

В комментариях участник сообщества скинул ссылку на генератор символов

 

Дополнительные примеры работы:

• Термометр (Z-DHT11 + Z-LCD I2C модуль) 

Документация:

• Принципиальная схема: z-lcd-i2c-module-v3-schematic.jpg

• Техническое описание микросхемы PCF8574: datasheet

Купить в России Z- LCD I2C модуль v3

В данный момент еще реализованы не все элементы нашего сообщества. Мы активно работаем над ним и в ближайшее время возможность комментирования статей будет добавлена.

Источник: http://zelectro.cc/z-lcd_i2c_module

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}