Как использовать I2C LCD дисплей с ESP8266

Подключение I2C LCD дисплея к ESP8266

Устали полагаться на Serial Monitor, чтобы видеть, что происходит в ваших проектах на ESP8266? I2C LCD дисплей может быть именно тем, что вам нужно.

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

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

Готовы добавить дисплей в свой следующий проект на ESP8266? Давайте начнём!

Обзор оборудования

Типичный I2C LCD дисплей состоит из двух основных частей: символьного LCD дисплея на базе HD44780 и I2C LCD адаптера. Давайте рассмотрим каждый из этих компонентов более подробно.

Символьный LCD дисплей

Символьные LCD дисплеи специально предназначены для отображения букв, цифр и символов. Например, символьный LCD 16x2 может отображать 16 символов в каждой строке, всего две строки.

Внутренняя структура пиксельной сетки символьного LCD

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

I2C LCD адаптер

Ключевым компонентом этого адаптера является 8-битная микросхема расширения ввода/вывода PCF8574. Эта микросхема преобразует данные I2C от вашего ESP8266 в параллельные данные, которые необходимы для работы LCD дисплея.

Микросхема PCF8574 на I2C LCD

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

Обзор оборудования I2C LCD адаптера

Вы заметите, что на плате есть перемычка, которая подаёт питание на подсветку. Если вы хотите управлять яркостью подсветки, вы можете просто снять эту перемычку и подключить внешний источник напряжения к контактному разъёму с маркировкой „LED“.

I2C адрес LCD

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

Для этой цели адаптер оснащён тремя паяльными перемычками/площадками (с маркировкой A0, A1 и A2). Для одного LCD вы можете оставить их без изменений; однако, если вы подключаете несколько I2C устройств или LCD, вам нужно убедиться, что каждое имеет уникальный адрес, изменив эти перемычки. Вы можете изменить адрес, замкнув перемычку небольшой каплей припоя.

Перемычки выбора I2C адреса на I2C LCD

Важно знать, что разные компании, такие как Texas Instruments и NXP Semiconductors, производят одну и ту же микросхему PCF8574. I2C адрес вашего LCD зависит от того, какая компания произвела микросхему.

Если ваш LCD имеет микросхему PCF8574 от Texas Instruments:

Согласно техническому описанию Texas Instruments, три бита выбора адреса (A0, A1 и A2) расположены в конце 7-битного регистра I2C адреса.

Регистр I2C адреса PCF8574 от Texas Instruments

Поскольку есть три входа адреса, которые могут быть HIGH или LOW, существует восемь возможных комбинаций (2^3 = 8) адресов.

Все три входа адреса по умолчанию подтянуты к HIGH с помощью встроенных подтягивающих резисторов. Это даёт PCF8574 I2C адрес по умолчанию 0x27.

Когда вы замыкаете паяльную перемычку, вы подтягиваете этот вход адреса к LOW. Если вы замкнёте все три перемычки, адрес изменится на 0x20. Таким образом, диапазон возможных адресов составляет от 0x20 до 0x27.

Вы можете установить различные I2C адреса в соответствии с этой таблицей:

Таблица выбора адреса I2C LCD перемычками для TI

Если ваш LCD имеет микросхему PCF8574 от NXP:

Согласно техническому описанию NXP Semiconductors, три бита выбора адреса (A0, A1 и A2) также расположены в конце 7-битного регистра I2C адреса. Однако остальные биты в регистре адреса отличаются от микросхемы Texas Instruments.

Регистр I2C адреса PCF8574 от NXP Semiconductors

Как и в случае с микросхемой Texas Instruments, существует восемь возможных комбинаций адресов, поскольку три входа могут быть HIGH или LOW.

Все три входа адреса по умолчанию подтянуты к HIGH с помощью встроенных подтягивающих резисторов. Это даёт PCF8574 I2C адрес по умолчанию 0x3F.

Когда вы замыкаете паяльную перемычку, вы подтягиваете этот вход адреса к LOW. Если вы замкнёте все три перемычки, адрес изменится на 0x38. Таким образом, диапазон возможных адресов составляет от 0x38 до 0x3F.

Вы можете установить различные I2C адреса в соответствии с этой таблицей:

Таблица выбора адреса I2C LCD перемычками для NXP

Таким образом, I2C адрес вашего LCD, скорее всего, 0x27 или 0x3F. Если вы не уверены, какой I2C адрес у вашего LCD, не волнуйтесь! Есть простой способ это выяснить, о котором вы узнаете далее в этом руководстве.

Распиновка I2C LCD дисплея

I2C LCD дисплей имеет всего четыре вывода. Ниже приведена распиновка:

Распиновка I2C LCD дисплея

GND — вывод заземления.

VCC — вывод питания. Подключите его к выходу 5V Arduino или внешнему источнику питания 5V.

SDA — вывод данных I2C.

SCL — вывод тактового сигнала I2C.

Подключение I2C LCD дисплея к ESP8266

Подключение I2C LCD к ESP8266 очень простое, потому что нужно подключить всего четыре вывода.

Начните с подключения вывода VCC на LCD к выводу VIN на ESP8266, а вывод GND — к одному из выводов GND (земля) на ESP8266.

Далее подключите два вывода, используемых для I2C связи. Подключите вывод SCL на LCD к D1 (GPIO#5) на ESP8266, а вывод SDA — к D2 (GPIO#4) на ESP8266.

В таблице ниже показаны все необходимые соединения:

I2C LCDESP8266
VCCVIN
GNDGND
SCLD1
SDAD2

На этой схеме показано, как именно всё подключить:

Схема подключения I2C LCD дисплея к ESP8266

Настройка контрастности LCD

После того как вы закончите подключение LCD к ESP8266, вам нужно будет настроить контрастность LCD дисплея. Найдите маленький синий подстроечный резистор на плате I2C адаптера — он управляет контрастностью LCD.

Теперь подайте питание на ESP8266. Вы должны увидеть, как подсветка сразу загорится. Возьмите маленькую отвёртку и аккуратно поверните ручку потенциометра. По мере регулировки вы начнёте видеть, как на экране появляется первый ряд прямоугольников. Эти прямоугольники — это места, где будут отображаться символы. Если вы видите эти прямоугольники чётко, поздравляем — ваш LCD работает идеально и готов к отображению текста!

Настройка контрастности ESP8266 I2C LCD поворотом потенциометра

Определение I2C адреса

Прежде чем мы перейдём к примеру кода, вам нужно узнать I2C адрес вашего LCD, чтобы правильно с ним взаимодействовать. Как мы упоминали ранее, I2C адрес вашего LCD, вероятно, либо 0x27, либо 0x3F. Вы можете найти этот адрес напечатанным на наклейке, которая шла с вашим LCD, или в информации о продукте. Но не волнуйтесь, если вы нигде не можете найти эту информацию! Есть простое решение — вы можете запустить простой скетч I2C сканера, который поможет вам автоматически определить правильный адрес.

Загрузите приведённый ниже скетч в вашу Arduino IDE.

#include <Wire.h>

void setup() {
  Serial.begin(115200);

  // Leonardo: wait for serial port to connect
  while (!Serial) {
  }

  Serial.println();
  Serial.println("I2C scanner. Scanning ...");
  byte count = 0;

  Wire.begin();
  for (byte i = 8; i < 120; i++) {
    Wire.beginTransmission(i);
    if (Wire.endTransmission() == 0) {
      Serial.print("Found address: ");
      Serial.print(i, DEC);
      Serial.print(" (0x");
      Serial.print(i, HEX);
      Serial.println(")");
      count++;
      delay(1);  // maybe unneeded?
    }            // end of good response
  }              // end of for loop
  Serial.println("Done.");
  Serial.print("Found ");
  Serial.print(count, DEC);
  Serial.println(" device(s).");
}  // end of setup

void loop() {
}

После загрузки скетча на ESP8266 откройте Serial Monitor на скорости 115200 бод и нажмите кнопку EN на ESP8266. Через несколько мгновений вы должны увидеть I2C адрес вашего LCD дисплея на экране.

Вывод I2C сканера адресов

Обязательно запишите этот адрес в надёжном месте. Он вам понадобится, когда мы будем работать с LCD в последующих примерах.

Установка библиотеки

Для управления I2C LCD мы будем использовать библиотеку LiquidCrystal_I2C. Эта библиотека значительно упрощает запись на LCD, так как она обрабатывает всю сложную I2C коммуникацию в фоновом режиме. Существует несколько версий этой библиотеки, но одна из наиболее надёжных — это версия, созданная Frank de Brabander.

Чтобы установить библиотеку:

  1. Сначала откройте программу Arduino IDE. Затем нажмите на значок Library Manager на левой боковой панели.

  2. Введите «liquidcrystal» в поле поиска для фильтрации результатов.

  3. Найдите библиотеку «LiquidCrystal I2C library», созданную Frank de Brabander.

  4. Нажмите кнопку Install, чтобы добавить её в вашу Arduino IDE.

Установка библиотеки LiquidCrystal_I2C

Базовый пример кода — Hello World!

Когда оборудование подключено и библиотека установлена, мы можем написать простой скетч Arduino для отображения текста на LCD. В этом примере мы выведем „Hello World!“ на первую строку LCD и „LCD Tutorial“ на вторую строку.

Перед загрузкой скетча вам нужно внести два важных изменения, чтобы он работал с вашим конкретным LCD. Вы должны ввести правильный I2C адрес вашего LCD (который мы нашли ранее) и указать размеры дисплея в конструкторе LiquidCrystal_I2C(). Если вы используете символьный LCD 16x2, введите 16 и 2; если вы используете LCD 20x4, введите 20 и 4.

// enter the I2C address and the dimensions of your LCD here
LiquidCrystal_I2C lcd(0x3F, 16, 2);

После внесения этих изменений вы готовы попробовать полный скетч:

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);  // set the LCD address to 0x3F for a 16 chars and 2 line display

void setup() {
  lcd.init();
  lcd.clear();
  lcd.backlight();  // Make sure backlight is on

  // Print a message on both lines of the LCD.
  lcd.setCursor(2, 0);  //Set cursor to character 2 on line 0
  lcd.print("Hello world!");

  lcd.setCursor(2, 1);  //Move cursor to character 2 on line 1
  lcd.print("LCD Tutorial");
}

void loop() {
}

После загрузки этого кода на ESP8266 вы должны увидеть на экране следующее:

Результат программы Hello World на LCD 16x2 с Arduino

Объяснение кода

Скетч начинается с подключения библиотеки LiquidCrystal_I2C, которая предоставляет все необходимые функции для управления LCD.

#include <LiquidCrystal_I2C.h>

Далее мы создаём объект класса LiquidCrystal_I2C. Конструктору LiquidCrystal_I2C нужны три параметра: I2C адрес, количество столбцов и количество строк вашего дисплея.

LiquidCrystal_I2C lcd(0x3F,16,2);

В функции setup мы вызываем три важные функции. Во-первых, функция init() инициализирует интерфейс с LCD. Во-вторых, функция clear() стирает всё содержимое экрана LCD и перемещает курсор в верхний левый угол. В-третьих, функция backlight() включает подсветку LCD, чтобы мы могли видеть текст.

lcd.init();
lcd.clear();
lcd.backlight();

Функция setCursor(2, 0) перемещает курсор в третий столбец первой строки. (Помните, что счёт начинается с 0, поэтому столбец 2 — это фактически третий столбец.) Позиция курсора указывает LCD, куда помещать новый текст на экране. Верхний левый угол считается позицией (0,0).

lcd.setCursor(2,0);

Далее мы используем функцию print() для отображения текста «Hello world!» на LCD.

lcd.print("Hello world!");

Аналогично, следующие две строки кода перемещают курсор в третий столбец второй строки и выводят „LCD Tutorial“ на LCD.

lcd.setCursor(2,1);
lcd.print("LCD Tutorial");

Пример прокрутки текста

Если у вас сообщение длиннее 16 символов, или вы хотите создать эффект бегущей строки, вы можете использовать функции scrollDisplayLeft() или scrollDisplayRight() в цикле для перемещения текста по экрану.

Скетч ниже показывает, как непрерывно прокручивать сообщение влево:

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address to 0x3F for a 16 chars and 2 line display

void setup() {
  lcd.init();
  lcd.clear();
  lcd.backlight();      // Make sure backlight is on

  // Print a message
  lcd.print("Scrolling Text Demo");
  delay(1000);  // pause to read the message initially
}

void loop() {
  lcd.scrollDisplayLeft();   // scroll everything to the left by one position
  delay(300);                // small delay for visible scrolling speed
}

Когда вы загрузите этот код на ESP8266, ваш LCD будет отображать что-то вроде этого:

Результат прокрутки текста на LCD 16x2 с Arduino

Объяснение кода

В этом примере мы выводим сообщение длиной 19 символов («Scrolling Text Demo») на LCD. Поскольку дисплей может показать только 16 символов одновременно, изначально будут видны только первые 16 символов.

// Print a message to the LCD
lcd.print("Scrolling Text Demo");

В функции loop() мы вызываем lcd.scrollDisplayLeft(), которая сдвигает всё содержимое дисплея на одну позицию влево. Повторяя это с небольшой задержкой между каждым сдвигом, сообщение плавно перемещается по экрану.

void loop() {
  lcd.scrollDisplayLeft();   // scroll everything to the left by one position
  delay(300);                // small delay for visible scrolling speed
}

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

Для прокрутки в противоположном направлении (справа налево) вы можете использовать lcd.scrollDisplayRight() вместо этого.

Другие полезные функции библиотеки LiquidCrystal_I2C

Объект LiquidCrystal_I2C предоставляет множество полезных функций для управления вашим LCD. Вот некоторые из наиболее полезных:

  • lcd.home() перемещает курсор обратно в верхний левый угол LCD (первая позиция в первой строке). В отличие от clear(), она не стирает то, что уже на экране — она только перемещает курсор в начальную позицию.

  • lcd.blink() и lcd.noBlink() включают или выключают мигающий блочный курсор. При включении с помощью blink() вы увидите сплошной блок, который мигает в текущей позиции курсора. Это отлично подходит для привлечения внимания пользователя или для указания, где появится следующий текст. Если вам не нужен этот мигающий блок, используйте noBlink() для его отключения.

  • lcd.cursor() и lcd.noCursor() управляют тем, появляется ли символ подчёркивания (_) в позиции, где будет записан следующий символ. Функция cursor() показывает эту линию, а noCursor() скрывает её. Это отличается от мигающего блока — это просто линия, показывающая, куда будет помещён следующий символ.

  • lcd.display() и lcd.noDisplay() позволяют включать и выключать весь дисплей без стирания содержимого. Когда вы используете noDisplay(), экран гаснет, но весь текст остаётся в памяти LCD. Когда вы снова вызовете display(), всё снова появится! Это идеально подходит для создания эффектов мигания или экономии энергии, когда дисплей не нужен.

Попробуйте поэкспериментировать с этими функциями в своём собственном коде, чтобы увидеть, как они работают. Они помогут вам создавать более интерактивные и динамичные дисплеи для ваших проектов!

Создание и отображение пользовательских символов

Иногда вам может понадобиться отобразить специальные символы, которые не являются частью стандартного алфавита или цифр — например, такие символы, как смайлик, символ градуса (°) для показаний температуры, или забавные иконки вроде сердечек, музыкальных нот или стрелок.

Хорошая новость в том, что LCD на базе HD44780 позволяют создать до 8 пользовательских символов собственного дизайна! Как мы узнали ранее в этом руководстве, каждый символ на LCD отображается с помощью небольшой сетки пикселей, расположенных в паттерне 5x8 (5 пикселей в ширину на 8 пикселей в высоту). Чтобы создать свой собственный символ, вам нужно решить, какие из этих крошечных точек должны быть включены, а какие — выключены.

Для создания пользовательского символа сначала нужно создать массив из 8 байтов в вашем коде. Каждый байт в этом массиве представляет одну горизонтальную строку в вашем символе, начиная с верхней строки и до нижней. Для каждого байта вы используете биты (единицы и нули в двоичной системе), чтобы указать, какие пиксели должны быть включены (1), а какие — выключены (0). Используются только первые 5 битов каждого байта, так как символ имеет ширину 5 пикселей.

После того как вы создали свой символ, настроив этот массив, вы можете использовать функцию createChar() для сохранения пользовательского символа в CGRAM (Character Generator RAM) LCD — это специальная область памяти, предназначенная для хранения пользовательских символов.

Теперь давайте создадим несколько классных пользовательских символов для ваших проектов!

Примечание

CGROM и CGRAM

Все LCD на базе контроллера Hitachi HD44780 имеют два типа памяти: CGROM (Character Generator Read-Only Memory) и CGRAM (Character Generator Random Access Memory).

CGROM — это энергонезависимая память, что означает, что она сохраняет свои данные даже при отключении питания. Она хранит предопределённые точечные паттерны для стандартных символов ASCII, таких как буквы, цифры и распространённые символы. Когда вы хотите отобразить «A» на экране, вы отправляете код для «A» (который равен 0x41 в шестнадцатеричной системе), и контроллер LCD ищет точечный паттерн для «A» в своей CGROM и отображает его. Это делает отображение обычных символов очень быстрым и простым!

CGRAM, однако, является энергозависимой памятью, поэтому она теряет свои данные при отключении питания. Эта память гибкая и позволяет хранить пользовательские точечные паттерны, которые не являются частью встроенного набора. Например, вы можете создать свои собственные символы, иконки или уникальные знаки для вашего проекта. Однако CGRAM имеет ограниченное пространство — всего 64 байта. На стандартном LCD с пикселями 5x8 это означает, что вы можете хранить только 8 пользовательских символов (так как каждому символу нужно 8 байт). Если вы используете LCD с пикселями 5x10, вы можете хранить только 4 пользовательских символа, потому что каждому нужно больше памяти.

Подводя итог, CGROM — это память только для чтения с фиксированными паттернами символов, которые нельзя изменить, а CGRAM — это записываемая память, позволяющая создавать и сохранять пользовательские символы, когда они вам нужны.

Генератор пользовательских символов

Создание пользовательских символов ещё никогда не было таким простым! Мы разработали полезный инструмент — Генератор пользовательских символов. Видите синюю сетку ниже? Вы можете нажать на любой пиксель, чтобы включить или выключить его, и при этом код для вашего символа автоматически создаётся рядом с сеткой. Вы можете скопировать этот код прямо в ваш скетч Arduino.

Выберите
пиксели
byte Character[8] =
{
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
};

Скопируйте
код в скетч

Возможности того, что вы можете создать, практически безграничны! Вы можете создать стрелки, простых животных, игровых персонажей, символы погоды или любую маленькую иконку, которая помещается в сетку 5x8. Единственное ограничение заключается в том, что библиотека LiquidCrystal_I2C позволяет использовать только восемь пользовательских символов одновременно. Но не волнуйтесь — восемь различных пользовательских символов всё ещё достаточно, чтобы сделать ваш проект уникальным и интересным!

Пример кода для ESP8266

Скетч ниже показывает, как именно отобразить ваши пользовательские символы на LCD:

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);  // set the LCD address to 0x3F for a 16 chars and 2 line display

// make some custom characters:
byte Heart[8] = {
  0b00000,
  0b01010,
  0b11111,
  0b11111,
  0b01110,
  0b00100,
  0b00000,
  0b00000
};

byte Bell[8] = {
  0b00100,
  0b01110,
  0b01110,
  0b01110,
  0b11111,
  0b00000,
  0b00100,
  0b00000
};

byte Alien[8] = {
  0b11111,
  0b10101,
  0b11111,
  0b11111,
  0b01110,
  0b01010,
  0b11011,
  0b00000
};

byte Check[8] = {
  0b00000,
  0b00001,
  0b00011,
  0b10110,
  0b11100,
  0b01000,
  0b00000,
  0b00000
};

byte Speaker[8] = {
  0b00001,
  0b00011,
  0b01111,
  0b01111,
  0b01111,
  0b00011,
  0b00001,
  0b00000
};

byte Sound[8] = {
  0b00001,
  0b00011,
  0b00101,
  0b01001,
  0b01001,
  0b01011,
  0b11011,
  0b11000
};

byte Skull[8] = {
  0b00000,
  0b01110,
  0b10101,
  0b11011,
  0b01110,
  0b01110,
  0b00000,
  0b00000
};

byte Lock[8] = {
  0b01110,
  0b10001,
  0b10001,
  0b11111,
  0b11011,
  0b11011,
  0b11111,
  0b00000
};

void setup() {
  lcd.init();
  // Make sure backlight is on
  lcd.backlight();

  // create a new characters
  lcd.createChar(0, Heart);
  lcd.createChar(1, Bell);
  lcd.createChar(2, Alien);
  lcd.createChar(3, Check);
  lcd.createChar(4, Speaker);
  lcd.createChar(5, Sound);
  lcd.createChar(6, Skull);
  lcd.createChar(7, Lock);

  // Clears the LCD screen
  lcd.clear();

  // Print a message to the lcd.
  lcd.print("Custom Character");
}

// Print All the custom characters
void loop() {
  lcd.setCursor(0, 1);
  lcd.write(0);

  lcd.setCursor(2, 1);
  lcd.write(1);

  lcd.setCursor(4, 1);
  lcd.write(2);

  lcd.setCursor(6, 1);
  lcd.write(3);

  lcd.setCursor(8, 1);
  lcd.write(4);

  lcd.setCursor(10, 1);
  lcd.write(5);

  lcd.setCursor(12, 1);
  lcd.write(6);

  lcd.setCursor(14, 1);
  lcd.write(7);
}

Когда вы загрузите этот код на ESP8266, ваш LCD будет отображать что-то вроде этого:

Результат программы генерации пользовательских символов на LCD 16x2 с Arduino

Попробуйте и поэкспериментируйте с созданием своих собственных уникальных символов!

Объяснение кода

После подключения библиотеки LiquidCrystal_I2C и настройки объекта LCD код определяет специальные массивы для наших пользовательских символов. Каждый массив содержит ровно 8 байтов, и каждый байт управляет одной строкой точек в нашей сетке символов 5x8.

Пример включает восемь различных пользовательских символов. Давайте рассмотрим массив Heart[8] в качестве примера:

byte Heart[8] = {
  0b00000,
  0b01010,
  0b11111,
  0b11111,
  0b01110,
  0b00100,
  0b00000,
  0b00000
};

Каждая строка представляет одну строку пикселей, начиная с верхней части символа. «0b» в начале просто сообщает Arduino, что это двоичное число (состоящее из 0 и 1). Каждый 0 означает «пиксель выключен», а каждая 1 означает «пиксель включён». Если вы внимательно посмотрите на паттерн, вы увидите, как единицы образуют форму сердца!

В разделе setup кода мы используем функцию createChar() для сохранения нашего пользовательского символа в памяти LCD. Этой функции нужны два параметра: число от 0 до 7 (которое указывает LCD, какой из восьми доступных слотов памяти использовать) и имя массива, содержащего дизайн нашего символа.

Код ниже сохраняет наш дизайн сердца в слот 0 памяти CGRAM LCD.

// create a new character
lcd.createChar(0, Heart);

Наконец, в разделе loop мы отображаем наш пользовательский символ с помощью функции write(). Мы указываем, какой символ отобразить, передавая номер слота памяти:

// byte(0) represents Heart character.
lcd.write(byte(0));