Данная библиотека позволяет вам взаимодействовать с 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
, который указывает на состояние передачи:
Смотрите пример к методу 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 "); // ответить сообщением }