Библиотека Wire для Arduino для работы с шиной I2C
Описание библиотеки Wire
Данная библиотека позволяет вам взаимодействовать с I2C / TWI устройствами. На платах Arduino с компоновкой R3 (распиновка 1.0) SDA (линия данных) и SCL (линия тактового сигнала) находятся на выводах около вывода AREF. Arduino Due имеет два I2C / TWI интерфейса: SDA1 и SCL1 находятся около вывода AREF, а дополнительные линии находятся на выводах 20 и 21.
В таблице ниже показано, где расположены TWI выводы на разных платах Arduino.
Плата | I2C/TWI выводы |
---|---|
Uno, Ethernet | A4 (SDA), A5 (SCL) |
Mega2560 | 20 (SDA), 21 (SCL) |
Leonardo | 2 (SDA), 3 (SCL) |
Due | 20 (SDA), 21 (SCL), SDA1, SCL1 |
Начиная с Arduino 1.0, данная библиотека наследует функции Stream
, что делает ее совместимой с другими библиотеками чтения/записи. Из-за этого send()
и receive()
были заменены на read()
и write()
.
Примечание
Существуют 7- и 8-битные версии адресов I2C. 7 битов идентифицируют устройство, а восьмой бит определяет, идет запись или чтение. Библиотека Wire использует 7 битные адреса. Если у вас есть техническое описание или пример кода, где используется 8-битный адрес, вам нужно откинуть младший бит (т.е. сдвинуть значение на один бит вправо), получив адрес от 0 до 127. Однако адреса от 0 до 7 не используются, так как зарезервированы, поэтому первым адресом, который может быть использован, является 8. Обратите внимание, что при подключении выводов SDA/SCL необходимы подтягивающие резисторы. Для более подробной информации смотрите примеры. На плате MEGA 2560 есть подтягивающие резисторы на выводах 20 и 21.
Описание методов
Wire.begin()
- Описание
Инициализирует библиотеку Wire и подключается к шине I2C как ведущий (мастер) или ведомый. Как правило, должен вызываться только один раз.
- Синтаксис
Wire.begin()
Wire.begin(address)
- Параметры
address
: 7-битный адрес ведомого устройства (необязательно); если не задан, плата подключается к шине как мастер.- Возвращаемое значение
Нет.
- Пример
Примеры для ведомого устройства смотрите в примерах к методам
onReceive() и
.onRequest()
. Примеры для ведущего устройства смотрите в примерах к остальным методам.
Wire.requestFrom()
- Описание
Используется мастером для запроса байтов от ведомого устройства. Эти байты могут быть получены с помощью методов
available()
иread()
.Для совместимости с определенными I2C устройствами, начиная с Arduino 1.0.1,
requestFrom()
принимает аргумент логического типа данных, меняющий его поведение.Если этот аргумент равен
true
, тоrequestFrom()
после запроса посылает сообщение STOP, освобождая шину I2C.Если этот аргумент равен
false
, тоrequestFrom()
после запроса посылает сообщение RESTART. Шина не освобождается, что мешает другому устройству-мастеру влезть между сообщениями. Это позволяет одному ведущему устройству посылать несколько запросов, пока оно контролирует шину.По умолчанию этот аргумент равен
true
.- Синтаксис
Wire.requestFrom(address, quantity)
Wire.requestFrom(address, quantity, stop)
- Параметры
address
: 7-битный адрес устройства, у которого запрашиваются байты;quantity
: количество запрашиваемых байтов;stop
:boolean
.true
посылает сообщение STOP после запроса.false
посылает сообщение RESTART после запроса, сохраняя соединение активным.
- Возвращаемое значение
byte
: количество байтов, возвращенных от ведомого устройства.- Пример
Смотрите пример к методу
read()
.
Wire.beginTransmission()
- Описание
Начинает передачу на ведомое I2C устройство с заданным адресом. После него последовательность байтов для передачи ставится в очередь с помощью функции
write()
, и их передача с помощью вызоваendTransmission()
.- Синтаксис
Wire.beginTransmission(address)
- Параметры
address
: 7-битный адрес устройства, на которое необходимо передать данные.- Возвращаемое значение
Нет.
- Пример
Смотрите пример к методу
write()
.
Wire.endTransmission()
- Описание
Завершает передачу на ведомое устройство, которая была начата методом
beginTransmission()
и передает байты, которые были поставлены в очередь методомwrite()
.Для совместимости с определенными I2C устройствами, начиная с Arduino 1.0.1,
requestFrom()
принимает аргумент логического типа данных, меняющий его поведение.Если этот аргумент равен
true
, тоrequestFrom()
после передачи посылает сообщение STOP, освобождая шину I2C.Если этот аргумент равен
false
, тоrequestFrom()
после передачи посылает сообщение RESTART. Шина не освобождается, что мешает другому устройству-мастеру влезть между сообщениями. Это позволяет одному ведущему устройству посылать несколько передач, пока оно контролирует шину.По умолчанию этот аргумент равен
true
.- Синтаксис
Wire.endTransmission()
Wire.endTransmission(stop)
- Параметры
stop
:boolean
.true
посылает сообщение STOP после передачи.false
посылает сообщение RESTART после передачи, сохраняя соединение активным.- Возвращаемое значение
byte
, который указывает на состояние передачи:- 0: успех;
- 1: данные слишком длинны для заполнения буфера передачи;
- 2: принят NACK при передаче адреса;
- 3: принят NACK при передаче данных;
- 4: остальные ошибки.
- Пример
Смотрите пример к методу
write()
.
Wire.write()
- Описание
Записывает данные от ведомого устройства в отклик на запрос от ведущего устройства, или ставит в очередь байты для передачи от мастера к ведомому устройству (между вызовами
beginTransmission()
иendTransmission()
).- Синтаксис
Wire.write(value)
Wire.write(string)
Wire.write(data, length)
- Параметры
value
: значение для передачи, один байт.string
: строка для передачи, последовательность байтов.data
: массив данных для передачи, байты.length
: количество байтов для передачи.
- Возвращаемое значение
byte
:write()
возвращает количество записанных байтов, хотя чтение этого количества не обязательно.- Пример
#include <Wire.h> byte val = 0; void setup() { Wire.begin(); // подключиться к шине i2c } void loop() { Wire.beginTransmission(44); // передача на устройство #44 (0x2c) // адрес устройства задан в техническом описании Wire.write(val); // отправить байт значения Wire.endTransmission(); // остановить передачу val++; // увеличить значение if(val == 64) // если дошли до 64-го значения (max) { val = 0; // начать с начала } delay(500); }
Wire.available()
- Описание
Возвращает количество байтов, доступных для получения с помощью
read()
. Этот метод должен вызываться на ведущем устройстве после вызоваrequestFrom()
или на ведомом устройстве внутри обработчикаonReceive()
.- Синтаксис
Wire.available()
- Параметры
Нет.
- Возвращаемое значение
Количество байтов, доступных для чтения.
- Пример
Смотрите пример к методу
read()
.
Wire.read()
- Описание
Считывает байт, который был передан от ведомого устройства к ведущему после вызова
requestFrom()
, или который был передан от ведущего устройства к ведомому.- Синтаксис
Wire.read()
- Параметры
Нет.
- Возвращаемое значение
byte
: очередной принятый байт.- Пример
#include <Wire.h> byte val = 0; void setup() { Wire.begin(); // подключиться к шине i2c (адрес для мастера не обязателен) Serial.begin(9600); // настроить последовательный порт для вывода } void loop() { Wire.requestFrom(2, 6); // запросить 6 байтов от ведомого устройства #2 while(Wire.available()) // ведомое устройство может послать меньше, чем запрошено { char c = Wire.read(); // принять байт как символ Serial.print(c); // напечатать символ } delay(500); }
Wire.setClock()
- Описание
Изменяет тактовую частоту для связи по шине I2C. У ведомых I2C устройств нет минимальной рабочей тактовой частоты, однако обычно используется 100 кГц.
- Синтаксис
Wire.setClock(clockFrequency)
- Параметры
clockFrequency
: значение частоты (в герцах) тактового сигнала. Принимаются значения 100000 (стандартный режим) и 400000 (быстрый режим). Некоторые процессоры также поддерживают 10000 (низкоскоростной режим), 1000000 (быстрый режим плюс) и 3400000 (высокоскоростной режим). Чтобы убедиться, что необходимый режим поддерживается, обращайтесь к технической документации на конкретный процессор.- Возвращаемое значение
Нет
Wire.onReceive()
- Описание
Регистрирует функцию, которая будет вызываться, когда ведомое устройство принимает передачу от мастера.
- Синтаксис
Wire.onReceive(handler)
- Параметры
handler
: функция, которая должна будет вызываться, когда ведомое устройство принимает данные; она должна принимать один параметрint
(количество байтов, прочитанных от мастера) и ничего не возвращать, т.е.:void myHandler(int numBytes)
- Возвращаемое значение
Нет.
- Пример
Код для платы Arduino, работающей в качестве ведомого устройства:
#include <Wire.h> void setup() { Wire.begin(8); // подключиться к i2c шине с адресом #8 Wire.onReceive(receiveEvent); // зарегистрировать обработчик события Serial.begin(9600); // настроить последовательный порт для вывода } void loop() { delay(100); } // функция, которая будет выполняться всякий раз, когда от мастера принимаются данные // данная функция регистрируется как обработчик события, смотрите setup() void receiveEvent(int howMany) { while (1 < Wire.available()) // пройтись по всем до последнего { char c = Wire.read(); // принять байт как символ Serial.print(c); // напечатать символ } int x = Wire.read(); // принять байт как целое число Serial.println(x); // напечатать число }
Wire.onRequest()
- Описание
Регистрирует функцию, которая будет вызываться, когда мастер запрашивает данные от ведомого устройства.
- Синтаксис
Wire.onRequest(handler)
- Параметры
handler
: функция, которая должна будет вызываться, она не принимает параметров и ничего не возвращает, т.е.:void myHandler()
- Возвращаемое значение
Нет.
- Пример
Код для платы Arduino, работающей в качестве ведомого устройства:
#include <Wire.h> void setup() { Wire.begin(8); // подключиться к i2c шине с адресом #8 Wire.onRequest(requestEvent); // зарегистрировать обработчик события } void loop() { delay(100); } // функция, которая будет выполняться всякий раз, когда мастером будут // запрошены данные // данная функция регистрируется как обработчик события, смотрите setup() void requestEvent() { Wire.write("hello "); // ответить сообщением }