Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Как работает связь I2C? Учебник по Arduino и I2C

<основной класс="главный сайт" id="главный">

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

Обзор

Коммуникационная шина I2C очень популярна и широко используется многими электронными устройствами, поскольку ее можно легко реализовать во многих электронных конструкциях, требующих связи между ведущим и несколькими ведомыми устройствами или даже несколькими ведущими устройствами. Простая реализация связана с тем, что требуется всего два провода для связи между почти 128 (112) устройствами при использовании 7-битной адресации и почти 1024 (1008) устройствами при использовании 10-битной адресации.

Как работает I2C

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

Два провода или линии называются Serial Clock (или SCL) и Serial Data (или SDA). Линия SCL — это тактовый сигнал, который синхронизирует передачу данных между устройствами на шине I2C и генерируется ведущим устройством. Другая строка — это линия SDA, по которой передаются данные.

Две линии являются «открытыми», что означает, что к ним необходимо подключить подтягивающие резисторы, чтобы линии были высокими, потому что устройства на шине I2C имеют активный низкий уровень. Обычно используемые значения резисторов:от 2 К для более высоких скоростей (около 400 кбит/с) до 10 К для более низких скоростей (около 100 кбит/с).

Протокол I2C

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

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

Последовательность адресации устройства начинается со старшего значащего бита (MSB) и заканчивается младшим значащим битом (LSB). На самом деле она состоит из 7 бит, поскольку 8 th бит используется для указания того, будет ли мастер записывать на ведомый (низкий логический уровень) или читать с него (логический высокий уровень).

Следующий бит AKC/NACK используется ведомым устройством, чтобы указать, успешно ли оно приняло предыдущую последовательность битов. Таким образом, в это время ведущее устройство передает управление линией SDA ведомому устройству, и, если ведомое устройство успешно получило предыдущую последовательность, оно переводит линию SDA в состояние, называемое Подтверждением. Если ведомое устройство не тянет линию SDA вниз, это состояние называется Not Acknowledge и означает, что оно не получило успешно предыдущую последовательность, что может быть вызвано несколькими причинами. Например, ведомое устройство может быть занято, может не понимать полученные данные или команду, больше не может получать данные и так далее. В таком случае ведущее устройство решает, как действовать дальше.

Далее идет адресация внутренних регистров. Внутренние регистры — это места в памяти ведомого устройства, содержащие различную информацию или данные. Например, акселерометр ADX345 имеет уникальный адрес устройства и дополнительные адреса внутренних регистров для осей X, Y и Z. Поэтому, если мы хотим прочитать данные оси X, сначала нам нужно отправить адрес устройства, а затем конкретный адрес внутреннего регистра для оси X. Эти адреса можно найти в паспорте датчика.

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

Пример

В качестве примера я буду использовать коммутационную плату GY-80, состоящую из 5 разных датчиков, и коммутационную плату GY-521, состоящую из 3 разных датчиков. Таким образом, мы можем получать данные от 8 различных датчиков всего двумя проводами по шине I2C.

Вы можете получить эти компоненты на любом из следующих сайтов:

Вот как мы будем соединять доски. Контакт Serial Clock на плате Arduino будет подключен к контактам Serial Clock двух коммутационных плат, то же самое касается контактов Serial Data, и мы будем питать платы с помощью контакта Gnd и 5V с платы Arduino. Обратите внимание, что здесь мы не используем подтягивающие резисторы, потому что они уже есть на коммутационных платах.

Теперь, чтобы общаться с этими чипами или датчиками, нам нужно знать их уникальные адреса. Мы можем найти их в даташитах на датчики. Для коммутационной платы GY-80 у нас есть следующие 4 адреса:шестнадцатеричный 0x53 для 3-осевого датчика акселерометра, шестнадцатеричный 0x69 для 3-осевого гироскопа, шестнадцатеричный 0x1E для 3-осевого магнитометра и шестнадцатеричный 0x77 для барометра и термометра. датчик.

Для коммутационной платы GY-521 у нас есть только один адрес, и это шестнадцатеричное число 0x68. Мы также можем получить или проверить адреса с помощью скетча Arduino I2C Scanner, который можно найти на официальном сайте Arduino. Так вот, если мы загрузим и запустим этот скетч, мы получим адреса подключенных устройств на шине I2C.


датчик

3-осевой акселерометр                   Analog Devices ADXL345                   0x53                  Техническое описание

3-осевой гироскоп

3-осевой магнитометр                  Honeywell MC5883L                                        

Барометр + термометр        Bosch BMP085                                     0x77                  Техническое описание


После того, как мы нашли адреса устройств, нам также необходимо найти адреса их внутренних регистров, чтобы считать с них данные. Например, если мы хотим прочитать данные для оси X с датчика 3-осевого акселерометра коммутационной платы GY-80, нам нужно найти адрес внутреннего регистра, где хранятся данные оси X. Из таблицы данных датчика видно, что данные для оси X фактически хранятся в двух регистрах:DATAX0 с шестнадцатеричным адресом 0x32 и DATAX1 с шестнадцатеричным адресом 0x33.

Код Arduino I2C

Теперь давайте напишем код, который будет получать данные для оси X. Поэтому мы будем использовать библиотеку Arduino Wire Library, которая должна быть включена в скетч. Здесь сначала мы должны определить адрес датчика и адреса двух внутренних регистров, которые мы ранее нашли. Wire.begin() функция инициирует библиотеку Wire, а также нам нужно инициировать последовательную связь, потому что мы будем использовать Serial Monitor для отображения данных с датчика.

В цикле() мы начнем с Wire.beginTransmission() функция, которая начнет передачу на конкретный датчик, в нашем случае на 3-осевой акселерометр. Затем с помощью Wire.write() мы будем запрашивать конкретные данные из двух регистров оси X. Wire.endTransmission() завершит передачу и передаст данные из регистров. Теперь с помощью Wire.requestFrom() мы будем запрашивать передаваемые данные или два байта из двух регистров.

Провод.доступный() функция вернет количество байтов, доступных для извлечения, и если это число совпадает с запрошенными байтами, в нашем случае 2 байта, с помощью Wire.read() функцией мы будем считывать байты из двух регистров оси X. В конце мы выведем данные на серийный монитор. Вот эти данные, но имейте в виду, что это необработанные данные, и необходимо выполнить некоторую математику, чтобы получить правильные значения оси X. Вы можете найти более подробную информацию об этом в моем следующем руководстве по использованию акселерометров с платой Arduino, потому что я не хочу перегружать это руководство, поскольку его основной целью было объяснить, как работает связь Arduino I2C.

/*  
 *  How I2C Communication Protocol Works - Arduino I2C Tutorial
 *  
 *   by Dejan, www.HowToMechatronics.com 
 *   
 */

#include <Wire.h>

int ADXLAddress = 0x53; // Device address in which is also included the 8th bit for selecting the mode, read in this case.

#define X_Axis_Register_DATAX0 0x32 // Hexadecima address for the DATAX0 internal register.
#define X_Axis_Register_DATAX1 0x33 // Hexadecima address for the DATAX1 internal register.
#define Power_Register 0x2D // Power Control Register

int X0,X1,X_out;

void setup() {
  Wire.begin(); // Initiate the Wire library
  Serial.begin(9600);
  delay(100);
  // Enable measurement
  Wire.beginTransmission(ADXLAddress);
  Wire.write(Power_Register);
  // Bit D3 High for measuring enable (0000 1000)
  Wire.write(8);  
  Wire.endTransmission();
}

void loop() {
  Wire.beginTransmission(ADXLAddress); // Begin transmission to the Sensor 
  //Ask the particular registers for data
  Wire.write(X_Axis_Register_DATAX0);
  Wire.write(X_Axis_Register_DATAX1);
  
  Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers
  
  Wire.requestFrom(ADXLAddress,2); // Request the transmitted two bytes from the two registers
  
  if(Wire.available()<=2) {  // 
    X0 = Wire.read(); // Reads the data from the register
    X1 = Wire.read();   
  }
  
  Serial.print("X0= ");
  Serial.print(X0);
  Serial.print("   X1= ");
  Serial.println(X1);
}Code language: Arduino (arduino)

Производственный процесс

  1. Связь Arduino I2C с Raspi 2 WIOT
  2. Как создать монитор энергии и регистратор данных Arduino
  3. Регистратор данных температуры и влажности
  4. Связь Python3 и Arduino
  5. Как использовать NMEA-0183 с Arduino
  6. Учебное пособие по Arduino:JARVIS v1 | Как сделать домашнюю автоматизацию
  7. Как многопоточно на Arduino (Учебное пособие по протопоточности)
  8. nRF24L01 — как это работает, интерфейс Arduino, схемы, коды
  9. Руководство по акселерометру и гироскопу Arduino и MPU6050
  10. Как отслеживать ориентацию с помощью Arduino и акселерометра ADXL345