Библиотека Wire для Arduino для работы с шиной I2C
- Описание библиотеки Wire
- Примечание
- Описание методов
1. Описание библиотеки Wire.
Данная библиотека позволяет вам взаимодействовать с I2C / TWI устройствами. На платах Arduino с компоновкой R3 (распиновка 1.0) SDA (линия данных) и SCL (линия тактового сигнала) находятся на выводах около вывода AREF. Arduino Due имеет два I2C / TWI интерфейса: SDA1 и SCL1 находятся около вывода AREF, а дополнительные линии находятся на выводах 20 и 21.
В таблице ниже показано, где расположены TWI выводы на разных платах Arduino.
Расположение выводов I2C/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()
.
2. Примечание
Существуют 7- и 8-битные версии адресов I2C. 7 битов идентифицируют устройство, а восьмой бит определяет, идет запись или чтение. Библиотека Wire использует 7 битные адреса. Если у вас есть техническое описание или пример кода, где используется 8-битный адрес, вам нужно откинуть младший бит (т.е. сдвинуть значение на один бит вправо), получив адрес от 0 до 127. Однако адреса от 0 до 7 не используются, так как зарезервированы, поэтому первым адресом, который может быть использован, является 8. Обратите внимание, что при подключении выводов SDA/SCL необходимы подтягивающие резисторы. Для более подробной информации смотрите примеры. На плате MEGA 2560 есть подтягивающие резисторы на выводах 20 и 21.
3. Описание методов
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 "); // ответить сообщением
}
- Вернуться в справочник Arduino.