Программный i2c arduino library. Библиотека AVR для работы с шиной I2C и с часами реального времени PCF8583

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

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

Эта книга задумана как продолжение бестселлера «Programming Arduino: Getting Started with Sketches». Несмотря на то что эта книга включает краткое повторение основ из книги «Programming Arduino», она познакомит читателя с более продвинутыми аспектами программирования плат Arduino.

На разных моделях Arduino интерфейс I2C подключается к разным контактам. Например, в модели Uno используются контакты A4 и A5 - линии SDA и SCL соответственно, а в модели Leonardo используются контакты D2 и D3. (Подробнее о линиях SDA и SCL рассказывается в следующем разделе.) На обеих моделях линии SDA и SCL выводятся также на колодку, находящуюся рядом с контактом AREF (рис. 7.3).

В табл. 7.1 перечисляются наиболее распространенные модели платы Arduino и контакты, соответствующие интерфейсу I2C.

Рис. 7.3. Контакты I2C на плате Arduino Uno

Таблица 7.1. Контакты I2C в разных моделях Arduino

Модель Контакты Примечания
Uno A4 (SDA) и A5 (SCL) Контакты подписаны SCL и SDA и находятся рядом с контактом AREF. Эти линии интерфейса выводятся также на контакты A4 и A5
Leonardo D2 (SDA) и D3 (SCL) Контакты подписаны SCL и SDA и находятся рядом с контактом AREF. Эти линии интерфейса выводятся также на контакты D2 и D3
Mega2560 D20 (SDA) и D21 (SCL) -
Due D20 (SDA) и D21 (SCL) Модель Due имеет вторую пару контактов I2C, подписанных SDA1 и SCL1

Протокол I2C

Для передачи и приема данных через интерфейс I2C используются две линии (отсюда второе название - двухпроводной интерфейс, Two Wire Interface). Эти две линии называют также тактовой линией (Serial Clock Line, SCL) и линией данных (Serial Data Line, SDA). На рис. 7.4 изображена временная диаграмма сигнала, передаваемого через интерфейс I2C.

Рис. 7.4. Временная диаграмма сигнала, передаваемого через интерфейс I2C

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

Библиотека Wire

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

Чтобы задействовать библиотеку Wire, ее сначала нужно подключить командой

#include

Инициализация I2C

В большинстве случаев плата Arduino играет роль ведущего устройства на любой шине I2C. Чтобы инициализировать Arduino как ведущее устройство, нужно выполнить команду begin в функции setup, как показано далее:

Обратите внимание: поскольку в данном случае плата Arduino действует как ведущее устройство, ей не нужно присваивать адрес. Если бы плата настраивалась на работу в режиме ведомого устройства, нам пришлось бы присвоить адрес в диапазоне от 0 до 127, передав его как параметр, чтобы уникально идентифицировать плату на шине I2C.

Отправка данных ведущим устройством

Чтобы отправить данные устройству на шине I2C, сначала нужно выполнить функцию beginTransmission и передать ей адрес устройства-получателя:

Wire.beginTransmission(4);

Отправка данных устройствам на шине I2C может производиться побайтно или целыми массивами типа char, как показано в следующих двух примерах:

Wire.send(123); // передача байта со значением 123

Wire.send("ABC"); // передача строки символов "ABC"

По окончании передачи должна вызываться функция endTransmission:

Wire.endTransmission();

Прием данных ведущим устройством

Чтобы принять данные от ведомого устройства, сначала нужно указать количество ожидаемых байтов вызовом функции requestFrom:

Wire.requestFrom(4, 6); // запросить 6 байт у устройства с адресом 4

В первом аргументе этой функции передается адрес ведомого устройства, от которого ведущее устройство желает получить данные, а во втором аргументе - количество байтов, которое ожидается получить. Ведомое устройство может передать меньшее количество байтов, поэтому, чтобы определить, были ли получены данные и сколько байтов действительно получено, необходимо использовать функцию available. Следующий пример (взят из пакета примеров, входящих в состав библиотеки Wire) демонстрирует, как ведущее устройство принимает все полученные данные и выводит их в монитор последовательного порта:

#include

Wire.begin(); // подключиться к шине i2c (для ведущего

// устройства адрес не указывается)

Serial.begin(9600); // инициализировать монитор последовательного порта

Wire.requestFrom(8, 6); // запросить 6 байт у ведомого устройства #8

while (Wire.available()) { // ведомое устройство может прислать меньше

char c = Wire.read(); // принять байт как символ

Библиотека Wire автоматически буферизует входящие данные.

Примеры использования I2C

Любое устройство I2C должно иметь сопроводительное техническое описание, где перечисляются поддерживаемые им сообщения. Такие описания необходимы, чтобы конструировать сообщения для отправки ведомым устройствам и интерпретировать их ответы. Однако для многих устройств I2C, которые можно подключить к плате Arduino, существуют специализированные библиотеки, обертывающие сообщения I2C в простые и удобные функции. Фактически, если вам придется работать с каким-то устройством, для которого отсутствует специализированная библиотека, опубликуйте собственную библиотеку для всеобщего использования и заработайте себе несколько очков в карму.

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

УКВ-радиоприемник TEA5767

В первом примере, демонстрирующем взаимодействие с устройством I2C, библиотека не используется. Здесь осуществляется обмен фактическими сообщениями между Arduino и модулем TEA5767. Данный модуль можно купить в Интернете очень недорого, он легко подключается к плате Arduino и используется как УКВ-приемник, управляемый Arduino.

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

На рис. 7.5 изображена схема подключения модуля к Arduino.

Рис. 7.5. Подключение модуля TEA5767 к плате Arduino Uno через интерфейс I2C

Техническое описание модуля TEA5767 можно найти по адресу www.sparkfun.com/datasheets/Wireless/General/TEA5767.pdf . Описание содержит массу технической информации, но, если пробежать взглядом по документу, можно заметить раздел с подробным описанием сообщений, распознаваемых устройством. В документации указывается, что TEA5767 принимает сообщения длиной 5 байт. Далее приводится полностью работоспособный пример, выполняющий настройку частоты сразу после запуска. На практике же обычно требуется несколько иной механизм настройки, например на основе кнопок и жидкокристаллического дисплея.

// sketch_07_01_I2C_TEA5767

#include

setFrequency(93.0); // МГц

void setFrequency(float frequency)

byte frequencyH = frequencyB >> 8;

Wire.beginTransmission(0x60);

Wire.write(frequencyH);

Wire.write(frequencyL);

Wire.write(0xB0);

Wire.write(0x10);

Wire.write(0x00);

Wire.endTransmission();

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

Чтобы преобразовать вещественное значение частоты в двухбайтное представление, которое можно послать в составе пятибайтного сообщения, нужно выполнить некоторые арифметические операции. Эти операции выполняет следующий фрагмент:

unsigned int frequencyB = 4 * (frequency * 1000000 + 225000) / 32768;

byte frequencyH = frequencyB >> 8;

byte frequencyL = frequencyB & 0XFF;

Команда >> сдвигает биты вправо, то есть операция >> 8 сдвинет старшие 8 бит в сторону младших на 8 двоичных разрядов. Оператор & выполняет поразрядную операцию И (AND), которая в данном случае сбросит старшие 8 бит и оставит только младшие. Более полное обсуждение операций с битами вы найдете в главе 9.

Остальной код в функции setFrequency инициализирует передачу сообщения I2C ведомому устройству с адресом 0x60, который закреплен за приемником TEA5767. Затем осуществляется последовательная передача 5 байт, начиная с 2 байт частоты.

Прочитав документацию, вы узнаете о множестве других возможностей, доступных посредством разных сообщений, например о сканировании диапазона, выключении одного или двух каналов вывода звука и выборе режима моно/стерео.

В приложении мы еще вернемся к этому примеру и создадим библиотеку для Arduino, чтобы упростить работу с модулем TEA5767.

Взаимодействие между двумя платами Arduino

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

Схема соединения плат для этого примера показана на рис. 7.6. Обратите внимание на то, что модуль TEA5767 имеет встроенные подтягивающие сопротивления на линиях I2C. Однако в данном случае, когда друг к другу подключаются две платы Arduinos, такие резисторы отсутствуют, поэтому понадобится включить свои сопротивления с номиналом 4,7 кОм (рис. 7.6).

Рис. 7.6. Соединение двух плат Arduino через интерфейс I2C

В платы должны быть загружены разные скетчи. Оба скетча включены в состав примеров для библиотеки Wire. Программа для ведущей платы Arduino находится в меню File->Example->Wire->master_writer (Файл-> Примеры->Wire->master_writer), а для ведомой платы - в меню File-> Example->Wire->slave_receiver (Файл->Примеры->Wire->slave_receiver).

Запрограммировав обе платы, оставьте ведомую подключенной к компьютеру, чтобы увидеть вывод с этой платы в монитор последовательного порта и обеспечить питание ведущей платы Arduino.

Начнем со скетча в ведущей плате:

#include

Wire.begin(); // подключиться к шине i2c (для ведущего устройства

// адрес не указывается)

Wire.beginTransmission(4); // инициализировать передачу устройству #4

Wire.write("x is "); // послать 5 байт

Wire.write(x); // послать 1 байт

Wire.endTransmission(); // остановить передачу

Этот скетч генерирует сообщение вида x is 1, где 1 - число, увеличивающееся каждые полсекунды. Затем сообщение посылается ведомому устройству с адресом 4, как определено в вызове beginTransmission.

Задача ведомого скетча - принять сообщение от ведущего устройства и вывести его в монитор последовательного порта:

#include

Wire.begin(4); // подключиться к шине i2c с адресом #4

Wire.onReceive(receiveEvent); // зарегистрировать обработчик события

Serial.begin(9600); // открыть монитор последовательного порта

// эта функция вызывается всякий раз, когда со стороны ведущего устройства

// поступают очередные данные, эта функция зарегистрирована как обработчик

// события, см. setup()

void receiveEvent(int howMany) {

while (1 < Wire.available()) { // цикл по всем принятым байтам, кроме

// последнего

Serial.print(c); // вывести символ

Serial.println(x); // вывести целое число

Первое, на что следует обратить внимание в этом скетче, - функции Wire.begin передается параметр 4. Он определяет адрес ведомого устройства на шине I2C, в данном случае 4. Он должен соответствовать адресу, который используется ведущим устройством для отправки сообщений.

СОВЕТ

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

Скетч для ведомой платы отличается от скетча для ведущей платы, потому что использует прерывания для приема сообщений, поступающих от ведущего устройства. Установка обработчика сообщений выполняется функцией onReceive, которая вызывается подобно подпрограммам обработки прерываний (глава 3). Вызов этой функции нужно поместить в функцию setup, чтобы обеспечить вызов пользовательской функции receiveEvent при получении любых поступающих сообщений.

Функция receiveEvent принимает единственный параметр - количество байт, готовых для чтения. В данном случае это число игнорируется. Цикл while читает по очереди все доступные символы и выводит их в монитор последовательного порта. Затем выполняются чтение единственного однобайтного числа в конце сообщения и его вывод в монитор порта. Использование println вместо write гарантирует, что значение байта будет выведено как число, а не символ с соответствующим числовым кодом (рис. 7.7).

Рис. 7.7. Вывод в монитор порта сообщений, получаемых одной платой Arduino от другой через интерфейс I2C

Платы со светодиодными индикаторами

Еще один широкий спектр устройств I2C - разного рода дисплеи. Наиболее типичными представителями этих устройств являются светодиодные матрицы и семисегментные индикаторы, производимые компанией Adafruit. Они содержат светодиодные дисплеи, смонтированные на печатной плате, и управляющие микросхемы с поддержкой интерфейса I2C. Такое решение избавляет от необходимости использовать большое число контактов ввода/вывода на плате Arduino для управления светодиодным дисплеем и позволяет обойтись всего двумя контактами, SDA и SCL.

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

#include

#include "Adafruit_LEDBackpack.h"

#include "Adafruit_GFX.h"

Adafruit_8x8matrix matrix = Adafruit_8x8matrix();

matrix.begin(0x70);

matrix.drawLine(0, 0, 7, 7, LED_RED);

matrix.writeDisplay();

Часы реального времени DS1307

Еще одно распространенное устройство I2C - модуль часов реального времени DS1307. Для этого модуля также имеется удобная и надежная библиотека, упрощающая взаимодействие с модулем и избавляющая от необходимости иметь дело с фактическими сообщениями I2C. Библиотека называется RTClib и доступна по адресу https://github.com/adafruit/RTClib .

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

#include

#include "RTClib.h"

Serial.begin(9600);

if (! RTC.isrunning()) {

Serial.println("RTC is NOT running!");

// записать в модуль дату и время компиляции скетча

RTC.adjust(DateTime(__DATE__, __TIME__));

DateTime now = RTC.now();

Serial.print(now.year(), DEC);

Serial.print("/");

Serial.print(now.month(), DEC);

Serial.print("/");

Serial.print(now.day(), DEC);

Serial.print(" (");

Serial.print(daysOfTheWeek);

Serial.print(") ");

Serial.print(now.hour(), DEC);

Serial.print(":");

Serial.print(now.minute(), DEC);

Serial.print(":");

Serial.print(now.second(), DEC);

Serial.println();

Если вам интересно увидеть, как в действительности выполняются взаимодействия через интерфейс I2C, просто загляните в файлы библиотеки. Например, исходный код библиотеки RTClib хранится в файлах RTClib.h и RTClib.cpp. Эти файлы находятся в папке libraries/RTClib.

Например, в файле RTClib.cpp можно найти определение функции now:

DateTime RTC_DS1307::now() {

Wire.beginTransmission(DS1307_ADDRESS);

Wire.endTransmission();

Wire.requestFrom(DS1307_ADDRESS, 7);

uint8_t ss = bcd2bin(Wire.read() & 0x7F);

uint8_t mm = bcd2bin(Wire.read());

uint8_t hh = bcd2bin(Wire.read());

uint8_t d = bcd2bin(Wire.read());

uint8_t m = bcd2bin(Wire.read());

uint16_t y = bcd2bin(Wire.read()) + 2000;

return DateTime (y, m, d, hh, mm, ss);

Функция Wire.read возвращает значения в двоично-десятичном формате (Binary-Coded Decimal, BCD), поэтому они преобразуются в байты с помощью библиотечной функции bcd2bin.

В формате BCD байт делится на два 4-битных полубайта. Каждый полубайт представляет одну цифру двузначного десятичного числа. Так, число 37 в формате BCD будет представлено как 0011 0111. Первые четыре бита соответствуют десятичному значению 3, а вторые четыре бита - значению 7.

В заключение

В этой главе вы познакомились с интерфейсом I2C и приемами его использования для организации взаимодействий плат Arduino с периферийными устройствами и другими платами Arduino.

В следующей главе мы исследуем еще одну разновидность последовательного интерфейса, используемого для взаимодействий с периферией. Он называется 1-Wire . Этот интерфейс не получил такого широкого распространения, как I2C, но он используется в популярном датчике температуры DS18B20.

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

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

Сегодня создано огромное количество библиотек, которые можно легко найти и скачать в интернете. Подавляющее большинство библиотек распространяются по свободной лицензии, поэтому необходимости в поиске “пиратских” версий нет. Главное, это научиться .

Стандартные библиотеки Ардуино

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

Список встроенных библиотек (они поставляются вместе с дистрибутивом Arduino IDE):

  • EEPROM
  • Ethernet / Ethernet 2
  • Firmata
  • LiquidCrystal
  • Servo
  • SoftwareSerial
  • Stepper

Подборка библиотек в одном архиве

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

Библиотеки для экранов, индикаторов и дисплеев

Библиотека I2C

Библиотека, предназначенная для работы периферийного устройства по протоколу I2C.

Пример использования:

#ifndef I2C_MASTER_H

#define I2C_MASTER_H

void I2C_init (void) – создание объекта, настройка на правильную частоту для шины.

uint8_t I2C_start () – установка соединения с новым устройством.

uint8_t I2C_write() – запись данных на текущее устройство.

uint8_t I2C_read_ack() – считывание байта с устройства, запрос следующего байта.

Библиотека LiquidCrystal

Стандартная библиотека, установленная в Arduino IDE. Предназначена для управления жидкокристаллическими дисплеями LCD.

Пример использования:

#include . Также, чтобы не ошибиться при написании, можно подключить через меню Sketch – Import Library – LiquidCrystal.

Конструктор класса – LiquidCristal(…). Аргументами являются rs, rw, en, do…d7. Первые 3 соответствую выводам сигналов RS, RW и Enable. Выводы d соответствуют номерам шин данных, к которым подключен дисплей.

void begin(cols, rows) – метод, который инициализирует интерфейс дисплея. Аргументами являются количество знаков в строке (cols) и число строк (rows). Этот метод должен задаваться первым.

void createChar(num, data) – метод, необходимый для создания пользовательских символов.

Библиотека UTFT

Стандартная библиотека, необходимая для работы Ардуино с TFT экранами разных типов. Все поддерживаемые дисплеи представлены в сопроводительном документе с библиотекой.

Пример использования:

#include

UTFT(); – создание экземпляра UTFT.

textRus(char*st, int x, int y); – метод, позволяющий выводить строку из указателя. Например, char *dht = “Температура,С”;

textRus(string st, int x, int y); – вывод строки с указанием в параметре. Например, g.textRus(“Температура, С”, 0, 20);

Библиотека LedControl

Позволяет управлять семисегментными дисплеями, объединять массив из светодиодов в одну матрицу.

Пример использования:

#include

LedControl lc1= LedControl();

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

writeArduinoOn7Segment() – отображение на дисплее всех чисел от 0 до 15. Использует функции setChar() для символов a и d и setRow() для создания макета пропущенных символов.

LedControl.shutdown() – отключение изображения.

setIntensity() – контроль яркости.

Библиотеки для работы с датой и временем ардуино

Библиотека RTClib

Библиотека для работы с часами реального времени, упрощающая взаимодействие с Ардуино.

Пример использования:

#include

RTC_DS1307 RTC; – выбор датчика (в данном случае DS1307).

rtc.adjust(DateTime(Date, Time)); – настройка времени и календаря.

dayOfTheWeek () – вывод дня недели. Аргумент от 0 до 6, 0 – воскресенье.

Библиотека Timelib

Позволяет Ардуино получать информацию о дате и времени в данный момент.

Пример использования:

#include

Time(); – создание экземпляра.

setTime (t); – установка времени. Аргумент t – час, минута, секунда, день, месяц и год.

timeStatus(); – показывает, установлено ли время.

adjustTime(adjustment); – настройка времени.

Библиотека Ds1307

Библиотека для удобного взаимодействия часов DS1307 с Ардуино c использованием библиотеки Wire.

Пример использования:

#include

class DS1307RTC – создание объекта DS1307.

SetTime() – установка времени.

get() – считывает RTC, возвращает полученную дату в формате POSIX.

Set(time_t t) – запись даты в RTC

Библиотека DS 3231

Предназначена для управления датой и временем в модуле ds3231.

#include “ds3231.h”

DS3231 Clock(SDA, SCL); – создание объекта DS3231, подключение к линии тактирования и линии данных.

getTime(); – считывание даты и времени с часов.

setDate(date, mon, year); – установка даты.

Системные библиотеки ардуино

Библиотека EEPROM

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

Пример использования:

#include

EEPROM.read(); – создание объекта, считывание байта по адресу из энергонезависимой памяти.

EEPROM.write(address, value)– запись байта в энергонезависимую память.

EEPROM.put() – запись строк чисел с плавающей запятой.

EEPROM.get() – чтение строк и чисел с плавающей запятой.

Библиотека SoftwareSerial

Библиотека, которая позволяет реализовывать последовательные интерфейсы с любых цифровых пинов. Также позволяет создавать несколько последовательных портов, которые работают на скорости до 115200 бод.

#include

SoftwareSerial mySerial(RX, TX) – создание объекта, аргументы – выводы, к которым подключены RX и TX.

Serial.begin(); – устанавливает скорость порта для связи ардуино и компьютера.

mySerial.overflow() – проверка входного буфера на переполнение.

Библиотека Math

Включает в себя большое количество математических функций для работы с числами с плавающей запятой.

Пример использования:

#include

Math(); – создание экземпляра Math.

Serial.print(“cos num = “); – возвращает косинус числа.

Serial.println (fmod (double__x, double__y)); – возвращает числа по модулю.

Библиотека Scheduler

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

Пример использования:

#include

Scheduler; – создание экземпляра.

Scheduler.startLoop() – позволяет добавить функцию, которая будет выполняться вместе с loop().

yield() – позволяет передать управление другим задачам.

Библиотеки серво моторов и шаговых двигателей

Библиотека Servo

Стандартная библиотека. Необходима для управления серводвигателями и часто используется в робототехнических проектах с манипуляторами.

Пример использования:

#include

Servo myservo; – создание объекта для серводвигателя..

myservo.attach(); – номер выхода, к которому подключен серводвигатель.

myservo.write(180, 30, true); – движение на 180 градусов, скорость 30, ожидание окончания движения.

Библиотека Stepper

Небходима для управления шаговым униполярным и биполярным двигателем.

#include

const int stepsPerRevolution = ; – количество шагов, за которое двигатель проходит полный поворот.

Stepper myStepper = Stepper(steps, pin1, pin2) – создает экземпляр класса с указанным количеством шагов и выводами, к которым подключается двигатель.

Библиотеки датчиков ардуино

Библиотека DHT

#include < DHT.h>

DHT dht(DHTPIN, DHT11); – инициализирует датчик (в данном случае DHT11).

dht.begin(); – запуск датчика.

float t = dht.readTemperature(); – считывание текущего значения температуры в градусах Цельсия.

Библиотека DallasTemperature

Предназначается для работы с датчиками Dallas. Работает совместно с библиотекой OneWire.

#include

DallasTemperature dallasSensors(&oneWire); – передача объекта oneWire для работы с датчиком.

положить ее в регистр.

printTemperature(sensorAddress); – запрос получить измеренное значение температуры.

Библиотека Ultrasonic

Обеспечивает работу Ардуино с ультразвуковым датчиком измерения расстояния HC-SR04.

#include

Ultrasonic ultrasonic (tig , echo) – объявление объекта, аргументы – контакт Trig и контакт Echo.

dist = ultrasonic.distanceRead(); – определение расстояния до объекта. Агрумент – сантиметры(СМ) или дюймы (INC).

Timing() – считывание длительности импульса на выходе Echo, перевод в необходимую систему счисления.

Библиотека ADXL345

Предназначается для работы с акселерометром ADXL345.

Пример использования:

#include

ADXL345_ADDRESS – создание объекта, указание его адреса.

ADXL345_REG_DEVID – идентификация устройства.

ADXL345_REG_OFSX – смещение по оси Х.

ADXL345_REG_BW_RATE – управление скоростью передачи данных.

Библиотека BME280

Предназначается для работы с датчиком температуры, влажности и давления BME280.

Пример использования:

#include

BME280_ADDRESS – создание объекта BME280, указание его адреса.

begin(uint8_t addr = BME280_ADDRESS); – начало работы датчика.

getTemperature – получение измеренной температуры.

getPressure – получение измеренного давления.

Библиотека BMP280

Требуется для работы с датчиком атмосферного давления BMP280.

Пример использования:

#include

BMP280_CHIPID – создание экземпляра, указание его адреса.

getTemperature(float *temp); – получение измеренной температуры.

getPressure(float *pressure); – получение измеренного значения давления.

Библиотека BMP085

Требуется для работы с датчиком давления BMP085.

Пример использования:

#include

Adafruit_BMP085 bmp; – создание экземпляра BMP085.

dps.init(MODE_ULTRA_HIGHRES, 25000, true); – измерение давления, аргумент 25000 – высота над уровнем моря (в данном случае 250 м. над уровнем моря).

dps.getPressure(&Pressure); – определение давления.

Библиотека FingerPrint

Требуется для работы со сканером отпечатков пальцев.

Пример использования :

#include

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); – объявление объекта Finger. Параметр – ссылка на объектр для работы с UART, кокторому подключен модуль.

finger.begin(); – инициализация модуля отпечатков пальцев.

Func_sensor_communication(); – вызов модуля отпечатков пальцев.

Библиотеки коммуникации

Библиотека Wire

Требуется для работы с двухпроводным интерфейсом I2C.

Пример использования:

#include

Wire.begin() – инициализация библиотеки, подключение к шине I2C.

Wire.requestFrom() – запрос мастером байтов от ведомого устройства.

Wire.beginTransmission() – начало передачи на ведомое устройство.

Библиотека Irremote

Требуется для работы ардуино с ИК приемником.

Пример использования:

#include

IRrecv irrecv(RECV_PIN); – пин, к которому подключен ИК приемник.

SetPinAndButton(int ir1,int ir2,int pin) – позволяет настроить определенный выход на срабатывание при заданных значениях ir1, ir2.

Библиотека GSM

Требуется для соединения через GSM-плату с сетью GSM/GRPS. С ее помощью можно реализовать операции, свершаемые GSM-телефоном, работать с голосовыми вызовами и подключаться к сети интернет через GRPS.

Пример использования:

#include

GSM GSMAccess – инициализирует экземпляр класса.

gprs.powerOn() – включение питания.

GPRS – настройка подключения к интернету.

GSM – управление радио-модемом.

Библиотека RFID

Требуется для соединения Ардуино и RFID -модуля.

Пример использования:

#include

RFID rfid(SS_PIN, RST_PIN); – создание экземпляра rfid, аргументы – пины, к которым подключен модуль.

rfid.init(); – инициализация модуля RFID.

Библиотека MFRC 522

Требуется для соединения Ардуино и MFRC522 -модуля.

Пример использования:

#include

MFRC522 mfrc522(SS_PIN, RST_PIN); – создание экземпляра MFRC522, аргументами указаны выходы, к которым подключен модуль.

mfrc522.PCD_Init(); – инициализация MFRC522.

Библиотека Ethershield

Новая версия https://github.com/jcw/ethercard

Требуется для подключения Ардуино к локальной сети или сети интернет. Библиотека больше не поддерживается, более новая версия Ethercard. Также существует стандартная библиотека Ethernet.

Пример использования:

#include «EtherShield.h»

#include

EtherShield es = EtherShield (); – подготовка веб-страницы

ether.begin(sizeof Ethernet::buffer, mymac,); – начало работы, аргументы – адрес Mac и номер порта, к которому подключен выход CS.

Библиотека Nrf24l01

Требуется для работы с RF24-радиомодулем.

Пример использования:

#include “RF24.h”

RF24 – Конструктор создает новый экземпляр драйвера. Перед тем, как использовать, нужно создать экземпляр и указать пины, к которым подключен чип (_cepin: контакт модуля Enable, cspin: контакт модуля Select).

Begin – начало работы чипа.

setChannel – каналы для связи RF.

setPayloadSize – установка фиксированного размера передачи.

getPayloadSize – получение фиксированного размера.

Библиотека TinyGPS

Требуется для чтения сообщений GPGGA и GPRMC. Помогает считывать данные о положении, дате, времени, высоте и других параметрах.

Пример использования:

#include

TinyGPS gps; – создание экземпляра TinyGPS.

encode () – подача на объект последовательных данных по одному символу.

gps.stats() – метод статистики. Показывает, получены корректные данные или нет.

Библиотеки в Arduino IDE

Среди всего разнообразия библиотек можно выделить 3 основных группы:

  • Встроенные – это библиотеки, изначально установленные в среде Arduino IDE. Их не нужно скачивать и устанавливать дополнительно, они доступны для использования в программе сразу после запуска среды разработки.
  • Дополнительные – это библиотеки, которые нужно самостоятельно скачивать устанавливать. Обычно такой вид библиотек разрабатывает производитель датчиков, сенсоров и других компонентов для облегчения работы с ардуино.
  • Зависимые библиотеки – устанавливаются как помощник дополнительной библиотеки, отдельно от нее не работает.

Самым простым способом работы с библиотеками в ардуино является использование встроенных возможностей среды разработки Arduino IDE. Об этом мы поговорим в отдельной статье.

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

  • Теория интерфейса I2C.
  • EEPROM, описания моей микросхемы(AT24C256) и подключение.
  • Написание библиотеки для работы с памятью.

Часть первая, I2C и библиотека «Wire».

Последовательный протокол обмена данными IIC (также называемый I2C — Inter-Integrated Circuits, межмикросхемное соединение). Разработана фирмой Philips Semiconductors в начале 1980-х как простая 8-битная шина внутренней связи для создания управляющей электроники. Так как право на использование его стоит денег фарма Atmel назвала его TWI , но смысл от этого не меняется.

Как это работает?

Для передачи данных используются две двунаправленные лини передачи данных. SDA (Serial Data) шина последовательных данных и SCL (Serial Clock) шина тактирования. Обе шины подтянуты резисторами к плюсовой шине питания. Передача/Прием сигналов осуществляется прижиманием линии в 0, в единичку устанавливается сама, за счет подтягивающих резисторов .

В сети есть хотя бы одно ведущее устройство (Master ), которое инициализирует передачу данных и генерирует сигналы синхронизации и ведомые устройства (Slave ), которые передают данные по запросу ведущего. У каждого ведомого устройства есть уникальный адрес, по которому ведущий и обращается к нему. Конечно понятно что Ведущий это наш микроконтроллер, а ведомый наша память. Ведущее устройство начинает прижимать шину SCL к нулю с определенной чистотой, а шину SDA прижимать или отпускать на определенное число тактов передавая Единичку или Нолик. Передача данных начинается с сигнала START потом передается 8 бит данных и 9-тым битом Ведомое устройство подтверждает прием байт прижимая шину SDA к минусу. Заканчивается передача сигналом STOP .

Библиотека «Wire».

Для облегчения обмена данными с устройствами по шине I2C для Arduino написана стандартная библиотека Wire которая есть уже в комплекте IDE . Она имеет следующие основные функции:

Wire.begin(Address) вызывается один раз для инициализации и подключения к шини как Ведущий или Ведомое устройство. Если Address не задан подключаемся как Мастер устройство.

Wire.beginTransmission(address) начинает передачу на ведомое I2C устройство с заданным адресом.

Wire.endTransmission() прекращает передачу данных ведомому. Функция возвращает значение типа byte :

  • 0 — успех.
  • 1- данные слишком длинны для заполнения буфера передачи.
  • 2 — принят NACK при передаче адреса.
  • 3 — принят NACK при передаче данных.
  • 4 — остальные ошибки.

Wire.write() запись данных от ведомого устройства в отклик на запрос от ведущего устройства, или ставит в очередь байты для передачи от мастера к ведомому устройству.Фактически записывает данные в буфер. Размер буфера 32 байт а (минус 2 байта адрес, фактически 30 байт ), а передает буфер функция Wire.endTransmission().

  • Wire.write(value) — value : значение для передачи, один байт.
  • Wire.write(string) — string : строка для передачи, последовательность байтов.
  • Wire.write(data, length) — data : массив данных для передачи, байты. length : количество байтов для передачи.

Wire.read() Считывает байт, который был передан от ведомого устройства к ведущему или который был передан от ведущего устройства к ведомому. Возвращаемое значение byte : очередной принятый байт.

Это самые основные функции библиотеке, остальные мы рассмотрим по ходу пьесы))

Часть вторая, EEPROM.

EEPROM (англ. Electrically Erasable Programmable Read-Only Memory ) - электрически стираемое перепрограммируемое ПЗУ (ЭСППЗУ), один из видов энергонезависимой памяти (таких, как PROM и EPROM). Память такого типа может стираться и заполняться данными до миллиона раз.

Мне прислали уже готовый модуль EEPROM с микросхемой AT24C256 фирмы Atmel объемом 32 кбайт. Что бы разобраться с этим чудом нам придется проштудировать datasheet который очень скучный и на английском. Так что я вам выдам уже готовый результат моих мук.

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

  • Низковольтные и стандартные питание. VCC = 1.7V to 5.5V.
  • 400kHz (1.7V) and 1MHz (2.5V, 2.7V, 5.0V) совместим с частотой синхронизации.
  • Выносливость: 1,000,000 Циклов Записи.
  • Внутренне организованный как 32 768 страниц x 8 бит.

выводы:

  • WP — защита от записи. Если вывод подключен к GND то можно записывать данные в память.
  • A0…A2 — выводы задающие адрес устройства.
  • Vcc — питание плюс.
  • GND — питание минус.
Адрес памяти:

Задается тремя ногами A0..A2. Если нога прижата к Gnd то значение бита 0, если к Vcc то 1. Микросхема использует восьми битный адрес, последний бит отвечает за выбор операции . Если значение бита высокий то инициализируется операция чтения, если низкий(ноль) то операция записи.

То есть если все три вывода прижаты к GND и мы хотим записать в память, адрес устройства будет выглядеть как 10100000 (в библиотеке «Wire» используется 7-ми битный адрес, сдвигаем все в право на один бит 01010000 0x50 ).

Запись данных в память:

Для записи мы с начало обращаемся к памяти с битом Записи в адресе . Потом посылаем два 8-ми битных адреса(то есть у нас 0x8000 адресов) , затем байт данных и сигнал STOP . После этого EEPROM входит во внутренне синхронизированный цикл записи tWR(Write Cycle Time 5 ms) в энергонезависимую память. Все входные сигналы
отключено во время этого цикла записи, и EEPROM не ответит, пока запись не будет завершена .

Копаемся дальше и находим в datasheet что память микросхемы организована как 512 страниц по 64 байта . То есть мы может записать сразу до 64 байт информации за одну команду. Для этого мы передаем все 64 байта информации и только после этого посылаем сигнал STOP .

Чтение данных:

С чтением данных все интересней. Память поддерживает три варианта чтения:

  • Читать текущий адрес;
  • Читать случайный адрес;
  • Последовательное чтение;

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

Что бы прочитать случайный адрес нам нужно с начало отправить команду на запись и передать адрес который хотим прочитать(не забывайте что адрес состоит из двух 8-ми битных частей ). За тем отправить команду на чтение и получить искомый байт, завершив все командой STOP.

Последовательное чтение может выполняться как с текущего адреса так и со случайного и будет продолжаться пока микроконтроллер не отправит сигнал СТОП. При переполнении адреса память ее сбросить и адресация начнется с начала.

Ну что же пришло время попробовать что нибудь записать:
#include // Подключаем библиотеку #define EEPROM_ADDRESS 0x53 // Задаем адрес памяти word address = 0; // Адрес куда будем записывать byte data_send = 170 ; // Даные void setup() { Wire.begin(); // Инициализируем I2C Serial.begin(9600); Serial.print("Write byte to EEPROM memory..."); Serial.println (data_send); Wire.beginTransmission(EEPROM_ADDRESS); // Начинаем передачу Wire.write(address >> 8); Wire.write(address & 0xFF); // Отправляем два байта адреса Wire.write(data_send); // Отправляем данные byte status= Wire.endTransmission(); // Заканчиваем передачу и проверяем статус передачи. if (status == 0)Serial.println ("Ок"); // delay(10); Serial.println("Read byte from EEPROM memory..."); Wire.beginTransmission(EEPROM_ADDRESS); // Что бы прочитать данные отравляем сначала адрес где они лежат. Wire.write(address >> 8); Wire.write(address & 0xFF); status= Wire.endTransmission(); if (status == 0)Serial.println ("Ок"); // stop transmitting Wire.requestFrom(EEPROM_ADDRESS, (byte)1); // отправляем команду на чтение одного байта данных byte data = 0; if (Wire.available()) // проверяем что есть данные для чтения. { data = Wire.read(); //читаем данные } Serial.println (data, DEC); } void loop() { }

Wire.requestFrom(address, quantity) — Используется мастером для запроса байтов от ведомого устройства. Эти байты могут быть получены с помощью методов available() и read() . Размер буфера такой же 32 байта .

  • address : 7-битный адрес устройства, у которого запрашиваются байты;
  • quantity : количество запрашиваемых байтов;

Wire.available() — Возвращает количество байтов, доступных для получения с помощью read() .

Ну и пример с записью в память строки «Hello Word»:

#include #define EEPROM_ADDRESS 0x53 word address = 0; char data_send = "Hello Word" ; void setup() { Wire.begin(); // Serial.begin(9600); Serial.print("Write byte to EEPROM memory..."); Serial.println (data_send); Wire.beginTransmission(EEPROM_ADDRESS); Wire.write(address >> 8); Wire.write(address & 0xFF); Wire.write(data_send); byte status= Wire.endTransmission(); if (status == 0)Serial.println ("Ок"); delay(10); Serial.println("Read byte from EEPROM memory..."); Wire.beginTransmission(EEPROM_ADDRESS); Wire.write(address >> 8); Wire.write(address & 0xFF); status= Wire.endTransmission(); if (status == 0)Serial.println ("Ок"); // stop transmitting Wire.requestFrom(EEPROM_ADDRESS, (byte)10); byte data = 0; for (int i=0 ; i<10 ;i++) { if (Wire.available()) { data = Wire.read(); } Serial.write (data); } } void loop() { }

Организация памяти:

Так как в datasheet об этом написано смутно. Я на практике пытался разобраться с этим. В datasheet написано что память микросхемы организована как 512 страниц по 64 байта . Что это значит? Если мы захотим записать больше 64 байт сразу,скажем по адресу 0x40(адрес начало второй страницы), при выходе адреса за границы страницы внутренний счетчик микросхемы сбросит адрес на начало страницы . А лишние байты будут записаны в начало страницы и сотрут данные которые были там записаны.

Для чтения таких ограничений нету, в даташипе написано только то что когда вы достигнете конца адресов вас автоматически перекинет на начало (адрес 0х00).

На этом я думаю все. Вы конечно можете скачать уже готовую библиотеку для EEPROM , дума сможете и написать свою. Главное мы разобрались в основном принципе работы.

LCD дисплей – частый гость в проектах ардуино. Но в сложных схемах у нас может возникнуть проблема недостатка портов Arduino из-за необходимости подключить экран, у которого очень очень много контактов. Выходом в этой ситуации может стать I2C /IIC переходник, который подключает практически стандартный для Arduino экран 1602 к платам Uno, Nano или Mega всего лишь при помощи 4 пинов. В этой статье мы посмотрим, как можно подключить LCD экран с интерфейсом I2C, какие можно использовать библиотеки, напишем короткий скетч-пример и разберем типовые ошибки.

Жидкокристаллический дисплей (Liquid Crystal Display) LCD 1602 является хорошим выбором для вывода строк символов в различных проектах. Он стоит недорого, есть различные модификации с разными цветами подсветки, вы можете легко скачать готовые библиотеки для скетчей Ардуино. Но самым главным недостатком этого экрана является тот факт, что дисплей имеет 16 цифровых выводов, из которых обязательными являются минимум 6. Поэтому использование этого LCD экрана без i2c добавляет серьезные ограничения для плат Arduino Uno или Nano. Если контактов не хватает, то вам придется покупать плату Arduino Mega или же сэкономить контакты, в том числе за счет подключения дисплея через i2c.

Краткое описание пинов LCD 1602

Давайте посмотрим на выводы LCD1602 повнимательней:

Каждый из выводов имеет свое назначение:

  1. Земля GND;
  2. Питание 5 В;
  3. Установка контрастности монитора;
  4. Команда, данные;
  5. Записывание и чтение данных;
  6. Enable;

7-14. Линии данных;

  1. Плюс подсветки;
  2. Минус подсветки.

Технические характеристики дисплея:

  • Символьный тип отображения, есть возможность загрузки символов;
  • Светодиодная подсветка;
  • Контроллер HD44780;
  • Напряжение питания 5В;
  • Формат 16х2 символов;
  • Диапазон рабочих температур от -20С до +70С, диапазон температур хранения от -30С до +80 С;
  • Угол обзора 180 градусов.

Схема подключения LCD к плате Ардуино без i2C

Стандартная схема присоединения монитора напрямую к микроконтроллеру Ардуино без I2C выглядит следующим образом.

Из-за большого количества подключаемых контактов может не хватить места для присоединения нужных элементов. Использование I2C уменьшает количество проводов до 4, а занятых пинов до 2.

Где купить LCD экраны и шилды для ардуино

LCD экран 1602 (и вариант 2004) довольно популярен, поэтому вы без проблем сможете найти его как в отечественных интернет-магазинах, так и на зарубежных площадках. Приведем несколько ссылок на наиболее доступные варианты:

Модуль LCD1602+I2C с синим экраном, совместим с Arduino Простой дисплей LCD1602 (зеленая подсветка) дешевле 80 рублей Большой экран LCD2004 с I2C HD44780 для ардуино (синяя и зеленая подсветка)
Дисплей 1602 с IIC адаптером и синей подсветкой Еще один вариант LCD1602 со впаянным I2C модулем Модуль адаптера Port IIC/I2C/TWI/SPI для экрана 1602, совместим с Ардуино
Дисплей с RGB-подсветкой! LCD 16×2 + keypad +Buzzer Shield for Arduino Шилд для Ардуино с кнопками и экраном LCD1602 LCD 1602 LCD дисплей для 3D принтера (Smart Controller for RAMPS 1.4, Text LCD 20×4), модулем кардридера SD и MicroSD-

Описание протокола I2C

Прежде чем обсуждать подключение дисплея к ардуино через i2c-переходник, давайте вкратце поговорим о самом протоколе i2C.

I2C / IIC (Inter-Integrated Circuit) – это протокол, изначально создававшийся для связи интегральных микросхем внутри электронного устройства. Разработка принадлежит фирме Philips. В основе i2c протокола является использование 8-битной шины, которая нужна для связи блоков в управляющей электронике, и системе адресации, благодаря которой можно общаться по одним и тем же проводам с несколькими устройствами. Мы просто передаем данные то одному, то другому устройству, добавляя к пакетам данных идентификатор нужного элемента.

Самая простая схема I2C может содержать одно ведущее устройство (чаще всего это микроконтроллер Ардуино) и несколько ведомых (например, дисплей LCD). Каждое устройство имеет адрес в диапазоне от 7 до 127. Двух устройств с одинаковым адресом в одной схеме быть не должно.

Плата Arduino поддерживает i2c на аппаратном уровне. Вы можете использовать пины A4 и A5 для подключения устройств по данному протоколу.

В работе I2C можно выделить несколько преимуществ:

  • Для работы требуется всего 2 линии – SDA (линия данных) и SCL (линия синхронизации).
  • Подключение большого количества ведущих приборов.
  • Уменьшение времени разработки.
  • Для управления всем набором устройств требуется только один микроконтроллер.
  • Возможное число подключаемых микросхем к одной шине ограничивается только предельной емкостью.
  • Высокая степень сохранности данных из-за специального фильтра подавляющего всплески, встроенного в схемы.
  • Простая процедура диагностики возникающих сбоев, быстрая отладка неисправностей.
  • Шина уже интегрирована в саму Arduino, поэтому не нужно разрабатывать дополнительно шинный интерфейс.

Недостатки:

  • Существует емкостное ограничение на линии – 400 пФ.
  • Трудное программирование контроллера I2C, если на шине имеется несколько различных устройств.
  • При большом количестве устройств возникает трудности локализации сбоя, если одно из них ошибочно устанавливает состояние низкого уровня.

Модуль i2c для LCD 1602 Arduino

Самый быстрый и удобный способ использования i2c дисплея в ардуино – это покупка готового экрана со встроенной поддержкой протокола. Но таких экранов не очень много истоят они не дешево. А вот разнообразных стандартных экранов выпущено уже огромное количество. Поэтому самым доступным и популярным сегодня вариантом является покупка и использование отдельного I2C модуля – переходника, который выглядит вот так:

С одной стороны модуля мы видим выводы i2c – земля, питание и 2 для передачи данных. С другой переходника видим разъемы внешнего питания. И, естественно, на плате есть множество ножек, с помощью которых модуль припаивается к стандартным выводам экрана.


Для подключения к плате ардуино используются i2c выходы. Если нужно, подключаем внешнее питание для подстветки. С помощью встроенного подстроечного резистора мы можем настроить настраиваемые значения контрастности J

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

Подключение ЖК экрана к Ардуино по I2C

Для подключения необходимы сама плата Ардуино, дисплей, макетная плата, соединительные провода и потенциометр.

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


Жидкокристаллический монитор с поддержкой i2c подключается к плате при помощи четырех проводов – два провода для данных, два провода для питания.

  • Вывод GND подключается к GND на плате.
  • Вывод VCC – на 5V.
  • SCL подключается к пину A5.
  • SDA подключается к пину A.

И это все! Никаких паутин проводов, в которых очень легко запутаться. При этом всю сложность реализации i2C протокола мы можем просто доверить библиотекам.

Библиотеки для работы с i2c LCD дисплеем

Для взаимодействие Arduino c LCD 1602 по шине I2C вам потребуются как минимум две библиотеки:

  • Библиотека Wire.h для работы с I2C уже имеется в стандартной программе Arduino IDE.
  • Библиотека LiquidCrystal_I2C.h, которая включает в себя большое разнообразие команд для управления монитором по шине I2C и позволяет сделать скетч проще и короче. Нужно дополнительно установить библиотеку После подключения дисплея нужно дополнительно установить библиотеку LiquidCrystal_I2C.h

После подключения к скетчу всех необходимых библиотек мы создаем объект и можем использовать все его функции. Для тестирования давайте загрузим следующий стандартный скетч из примера.

#include #include // Подключение библиотеки //#include // Подключение альтернативной библиотеки LiquidCrystal_I2C lcd(0x27,16,2); // Указываем I2C адрес (наиболее распространенное значение), а также параметры экрана (в случае LCD 1602 - 2 строки по 16 символов в каждой //LiquidCrystal_PCF8574 lcd(0x27); // Вариант для библиотеки PCF8574 void setup() { lcd.init(); // Инициализация дисплея lcd.backlight(); // Подключение подсветки lcd.setCursor(0,0); // Установка курсора в начало первой строки lcd.print("Hello"); // Набор текста на первой строке lcd.setCursor(0,1); // Установка курсора в начало второй строки lcd.print("ArduinoMaster"); // Набор текста на второй строке } void loop() { }

Описание функций и методов библиотеки LiquidCrystal_I2C:

  • home() и clear() – первая функция позволяет вернуть курсор в начало экрана, вторая тоже, но при этом удаляет все, что было на мониторе до этого.
  • write(ch) – позволяет вывести одиночный символ ch на экран.
  • cursor() и noCursor() – показывает/скрывает курсор на экране.
  • blink() и noBlink() – курсор мигает/не мигает (если до этого было включено его отображение).
  • display() и noDisplay() – позволяет подключить/отключить дисплей.
  • scrollDisplayLeft() и scrollDisplayRight() – прокручивает экран на один знак влево/вправо.
  • autoscroll() и noAutoscroll() – позволяет включить/выключить режим автопрокручивания. В этом режиме каждый новый символ записывается в одном и том же месте, вытесняя ранее написанное на экране.
  • leftToRight() и rightToLeft() – Установка направление выводимого текста – слева направо или справа налево.
  • createChar(ch, bitmap) – создает символ с кодом ch (0 – 7), используя массив битовых масок bitmap для создания черных и белых точек.

Альтернативная библиотека для работы с i2c дисплеем

В некоторых случаях при использовании указанной библиотеки с устройствами, оснащенными контроллерами PCF8574 могут возникать ошибки. В этом случае в качестве альтернативы можно предложить библиотеку LiquidCrystal_PCF8574.h. Она расширяет LiquidCrystal_I2C, поэтому проблем с ее использованием быть не должно.

Проблемы подключения i2c lcd дисплея

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

Во-первых, можно увеличить или уменьшить контрастность монитора. Часто символы просто не видны из-за режима контрастности и подсветки.

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

Другой часто встречающейся причиной отсутствия текста на экране может стать неправильный i2c адрес. Попробуйте сперва поменять в скетче адрес устройства с 0x27 0x20 или на 0x3F. У разных производителей могут быть зашиты разные адреса по умолчанию. Если и это не помогло, можете запустить скетч i2c сканера, который просматривает все подключенные устройства и определяет их адрес методом перебора. Пример скетча i2c сканера .

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

Заключение

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

С номиналами от 10 Ом до 1 МОм);

  • 2 резистора по 4,7 кОм (из того же набора);
  • соединительные провода (например, вот хороший набор);
  • компьютер с Arduino IDE.
  • 1 Описание интерфейса I2C

    Последовательный протокол обмена данными IIC (также называемый I2C - Inter-Integrated Circuits, межмикросхемное соединение) использует для передачи данных две двунаправленные линии связи, которые называются шина последовательных данных SDA (Serial Data) и шина тактирования SCL (Serial Clock) . Также имеются две линии для питания. Шины SDA и SCL подтягиваются к шине питания через резисторы.

    В сети есть хотя бы одно ведущее устройство (Master) , которое инициализирует передачу данных и генерирует сигналы синхронизации. В сети также есть ведомые устройства (Slave) , которые передают данные по запросу ведущего. У каждого ведомого устройства есть уникальный адрес, по которому ведущий и обращается к нему. Адрес устройства указывается в паспорте (datasheet). К одной шине I2C может быть подключено до 127 устройств, в том числе несколько ведущих. К шине можно подключать устройства в процессе работы, т.е. она поддерживает «горячее подключение».

    Давайте рассмотрим временную диаграмму обмена по протоколу I2C. Есть несколько различающихся вариантов, рассмотрим один из распространённых. Воспользуемся логическим анализатором, подключённым к шинам SCL и SDA.

    Мастер инициирует обмен. Для этого он начинает генерировать тактовые импульсы и посылает их по линии SCL пачкой из 9-ти штук. Одновременно на линии данных SDA он выставляет адрес устройства , с которым необходимо установить связь, которые тактируются первыми 7-ми тактовыми импульсами (отсюда ограничение на диапазон адресов: 2 7 = 128 минус нулевой адрес). Следующий бит посылки - это код операции (чтение или запись) и ещё один бит - бит подтверждения (ACK), что ведомое устройство приняло запрос. Если бит подтверждения не пришёл, на этом обмен заканчивается. Или мастер продолжает посылать повторные запросы.

    Это проиллюстрировано на рисунке ниже.. В первом случае, для примера, отключим ведомое устройство от шины. Видно, что мастер пытается установить связь с устройством с адресом 0x27, но не получает подтверждения (NAK). Обмен заканчивается.


    Теперь подключим к шине I2C ведомое устройство и повторим операцию. Ситуация изменилась. На первый пакет с адресом пришло подтверждение (ACK) от ведомого. Обмен продолжился. Информация передаётся также 9-битовыми посылками, но теперь 8 битов занимают данные и 1 бит - бит подтверждения получения ведомым каждого байта данных. Если в какой-то момент связь оборвётся и бит подтверждения не придёт, мастер прекратит передачу.

    2 Реализация I2C в Arduino

    Arduino использует для работы по интерфейсу I2C два порта. Например, в Arduino UNO и Arduino Nano аналоговый порт A4 соответствует SDA, аналоговый порт A5 соответствует SCL.


    Для других моделей плат соответствие выводов такое:

    3 Библиотека "Wire" для работы с IIC

    Для облегчения обмена данными с устройствами по шине I2C для Arduino написана стандартная библиотека Wire . Она имеет следующие функции:

    Функция Назначение
    begin(address) инициализация библиотеки и подключение к шине I2C; если не указан адрес, то присоединённое устройство считается ведущим; используется 7-битная адресация;
    requestFrom() используется ведущим устройством для запроса определённого количества байтов от ведомого;
    beginTransmission(address) начало передачи данных к ведомому устройству по определённому адресу;
    endTransmission() прекращение передачи данных ведомому;
    write() запись данных от ведомого в ответ на запрос;
    available() возвращает количество байт информации, доступных для приёма от ведомого;
    read() чтение байта, переданного от ведомого ведущему или от ведущего ведомому;
    onReceive() указывает на функцию, которая должна быть вызвана, когда ведомое устройство получит передачу от ведущего;
    onRequest() указывает на функцию, которая должна быть вызвана, когда ведущее устройство получит передачу от ведомого.

    4 Подключение I2C устройства к Arduino

    Давайте посмотрим, как работать с шиной I2C с помощью Arduino.

    Сначала соберём схему, как на рисунке. Будем управлять яркостью светодиода, используя цифровой 64-позиционный потенциометр AD5171 (см. техническое описание), который подключается к шине I2C. Адрес, по которому мы будем обращаться к потенциометру - 0x2c (44 в десятичной системе).


    5 Управление устройством по шине IIC

    Рассмотрим диаграммы информационного обмена с цифровым потенциометром AD5171, представленные в техническом описании:


    Нас тут интересует диаграмма записи данных в регистр RDAC . Этот регистр используется для управления сопротивлением потенциометра.

    Откроем из примеров библиотеки "Wire" скетч: Файл Образцы Wire digital_potentiometer . Загрузим его в память Arduino.

    #include // подключаем библиотеку "Wire" byte val = 0; // значение для передачи потенциометру void setup() { Wire.begin(); // подключаемся к шине I2C как мастер } void loop() { Wire.beginTransmission(44); // начинаем обмен с устройством с I2C адресом "44" (0x2C) Wire.write(byte(0x00)); // посылаем инструкцию записи в регистр RDAC Wire.write(val); // задаём положение 64-позиционного потенциометра Wire.endTransmission(); // завершаем I2C передачу val++; // инкрементируем val на 1 if (val == 63) { // по достижении максимума потенциометра val = 0; // сбрасываем val } delay(500); }

    После включения вы видите, как яркость светодиода циклически нарастает, а потом гаснет. При этом мы управляем потенциометром с помощью Arduino по шине I2C.