Вы здесь

I2C Arduino он же TWI и IIC

I2C Arduino он же TWI и IIC

Arduino поддерживает много интерфейсов передачи данных, одним из которых является достаточно популярный на сегодняшний день I2C. Когда-то давно этот протокол связи придумала компания Philips и зарегистрировала под запатентованным названием “I2C”, вы также можете встретить его под названиями TWI, 2 line interface, но все они работают по единому принципу.

Весь смысл I2С шины состоит в том, что на 2 провода можно повесить большое (128) количество различных устройств, от датчиков температуры, до микроконтроллеров.
диаграмма I2C TWI и IIC
Но в тоже время по скорости I2C уступает UART и SPI, из-за основных принципов работы, т.к. две линии всегда подтянуты к резисторам(Vcc), а значит на графике мы получаем не прямоугольные импульсы, а трапециевидные, в отличие от вышеупомянутых.

SDA -  отвечает за передачу информации(начало передачи, адрес, данные)
SCL - тактирование шины

В I2C устройства могут быть двух типов  Master и Slave

Теперь разберём основные принципы программирования с помощью стандартной библиотеки Wire.h :

Wire.begin(uint8_t address) - используется для инициализации устройства, в режиме слейва нужно ввести адрес, в режиме мастера Wire.begin() . Вместо Wire можно использовать любое другое слово.

Wire.requestFrom(uint8_t address, uint8_t quantity) – запрос на получения какого-то количества байт от определенного устройства(7 бит адрес). Возвращает число считанных байт.

Wire.beginTransmission(uint8_t address)- начало передачи

Wire.endTransmission()- конец передачи,возвращает номер ошибки или успех(0)

Wire.write(uint8_t data) –может принимать значение одиночного  байта(value), нескольких байт(string), массива, определенной длинны (data, lenght). Располагается между: beginTransmission и endTransmission. Возращает число записанных байт.

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

Wire.read() – считывает байт от ведомого устройства. Пишется после requestFrom.

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

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

Для примера рассмотрим подключение и работу акселерометра и гироскопа Gy-521.

Подключаем согласно схеме (подтягивающие резисторы встроены в модуль):
подключение Gy-521 через I2C к Ардуино
Модуль может работать как от 3.3 вольт, так и от 5.

 

#include <Wire.h> // подключаем библиотеку работы с i2c интерфейсом
const int MPU_addr = 0x68; // I2C адрес GY-521
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ; // переменные для записи значений
void setup() {
  Wire.begin(); // инициализируем i2c шину
  Wire.beginTransmission(MPU_addr); // начало передачи
  Wire.write(0x6B);  // записываем определенные регистры для инициализации модуля
  Wire.write(0);     // отправляем ноль для выведения модуля из сна
  Wire.endTransmission(true);
  Serial.begin(9600);
}
void loop() {
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // начинаем с этого регистра
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true); // читаем все регистры
  AcX = Wire.read() << 8 | Wire.read(); // 0x3B
  AcY = Wire.read() << 8 | Wire.read(); // 0x3D
  AcZ = Wire.read() << 8 | Wire.read(); // 0x3F
  Tmp = Wire.read() << 8 | Wire.read(); // 0x41
  GyX = Wire.read() << 8 | Wire.read(); // 0x43
  GyY = Wire.read() << 8 | Wire.read(); // 0x45
  GyZ = Wire.read() << 8 | Wire.read(); // 0x47
  Serial.print("AcX = ");   Serial.print(AcX);      // выводим данные в Serial
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp / 340.00 + 36.53); // выводим температуры по формуле
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
  delay(333);
}