Працюємо з 09:00 до 19:00 без вихідних
Київ біля ТЦ Квадрат бул.Перова

Давайте разберемся с самой удобной коммуникацией физически заложенной в контроллеры Arduino

I2C это последовательная асимметричная шина для связи между интегральными схемами внутри электронных приборов. Тоесть данный протокол связи был разработан для внутренней связи внутри коробки устройства или внутри щита. Перед ним не ставилось задание передавать данные на большие расстояния, поэтому ходит множество мифов о максимальной дальности связи - у кого-то плохо работает уже при 50см, у кого-то при 2м.

На шине I2C может сидеть до 128 устройств. Адреса от 0 до 127.

В контроллерах Arduino заложена физическая коммуникация I2C, которая позволяет по двум информационным проводам подключать к ним как различные датчики, расширители дискретных входов-выходов, цифро-аналоговые и аналого-цифровые преобразователи, так и другие контроллеры.

О скорости передачи на сайте производителя не пишут. Но по общей документации на протокол она должна составлять как минимум 100 кбит/с



Теперь хотелось бы потестировать на сколько действительно хороша шина I2C, и на сколько сложно по ней обмениваться данными между несколькими контроллерами Arduino

Я возьму три контроллера Arduino Nano, объединю их шиной I2C, и разберусь, как по ней обмениваться данными. Первый контроллер будет выполнять роль ведущего, а остальные два - роль ведомого.

Для отображения данных буду использовать LCD-индикатор 1602 с модулем I2C, который будет подключен на ту же коммуникационную шину.

Ведущий контроллер будет последовательно опрашивать второго и третьего контроллера. Принятые данные первый контроллер должен выводить на индикатор. Опрос ведомых Arduino Nano будет проводиться с частотой 1 раз/сек.

Схема подключения


Четыре провода от каждого из 4-х устройств нужно соединить параллельно. Вывод А4 платы Arduino Nano - это шина SDA протокола I2C, а А5 - это SCL.

Я буду использовать монтажные шилды под контроллеры Nano для удобства соединений.

Питание будет подаваться просто на один из контроллеров через mini USB вход.

У LCD адрес в сети I2C по умолчанию 27. У второго контроллера установим адрес 2 и у третьего 3. У ведущего первого контроллера адрес не нужен.

Программа контроллера - мастера.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
int nano1=0;
int nano2;
int nano3;

void setup()
{
  Serial.begin(9600);
	// initialize the LCD
	lcd.begin();

	// Turn on the blacklight and print a message.
	lcd.backlight();
}

void loop()
{
  lcd.setCursor(0, 0);
  lcd.print(nano1);

  Wire.requestFrom(2, 2);    // request 6 bytes from slave device #8
  int i=0;nano2=0;
  while (Wire.available()) { // slave may send less than requested
    byte c = Wire.read(); // receive a byte as character
    Serial.print(c);
    if (i==0) nano2 = ((c & 0xff) << 8); else nano2 = nano2 | c;
    i++;
  }
  Serial.println("");
  Serial.println(nano2);
  lcd.setCursor(9, 0);
  lcd.print(nano2);
  delay(100);

  Wire.requestFrom(3, 2);    // request 6 bytes from slave device #8
  i=0;nano3=0;
  while (Wire.available()) { // slave may send less than requested
    byte c = Wire.read(); // receive a byte as character
    Serial.print(c);
    if (i==0) nano3 = ((c & 0xff) << 8); else nano3 = nano3 | c;
    i++;
  }
  lcd.setCursor(0, 1);
  lcd.print(nano3);
  delay(100);
  
  nano1++;
  delay(800);
}

Первый контроллер изменяет свою переменную типа integer и выводит ее значение на индикатор. Так же он поочереди опрашивает слейв со 2-м и 3-м адресом. Запрашивает у них два байта информации, преобразовывает их в переменную integer. В результате в первом контроллере крутятся три переменные с трёх Nano и он может вывести их на индикатор.

Программа второго контроллера

#include <Wire.h>

int nano2=0;
byte high[2];
void setup() {
  Wire.begin(2);                // join i2c bus with address #8
  Wire.onRequest(requestEvent); // register event
}

void loop() {
  delay(1000);
  nano2--;
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  high[0] = (nano2 >> 8);
  high[1] = (nano2 & 0xff);
  Wire.write(high[0]); // respond with message of 2 bytes
  Wire.write(high[1]);
}

Программа третьего Arduino Nano

#include <Wire.h>

int nano2=0;
byte high[2];
void setup() {
  Wire.begin(3);                // join i2c bus with address #8
  Wire.onRequest(requestEvent); // register event
}

void loop() {
  delay(1500);
  nano2--;
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  high[0] = (nano2 >> 8);
  high[1] = (nano2 & 0xff);
  Wire.write(high[0]); // respond with message of 2 bytes
  Wire.write(high[1]);
}

Отличаются последние две программы просто адресом в функции Wire.begin(3); и частотой изменения переменной.

Эти программы постоянно изменяют переменную integer и ожидают запроса от мастера. При запросе эта переменная раскладывается на два байта и отправляется как ответ на запрос ведущему контроллеру.

Таким образом работу связи по I2C можно контролировать по изменяющимся значениям трех переменных на жидкокристаллическом индикаторе. 

Выводы

Прекрасно все работает - цифры на дисплее меняются. Я попробовал удлиннять шлейф проводов между вторым и третьим контроллерами Arduino. Проверил работу шины связи при длине 3 м - без притензий. Длиннее не пробовал, но многие мне утверждали, что I2C не работает дальше 0,5 ... 2 м и меня воодушевила длина 3 м.

Для себя я уже вижу, где применю такую связь именно между тремя Nano.

Я здесь ещё не попробовал передачу данных от мастера слейву. Если попробуете - отпишитесь. 

Недостатков здесь на небольших расстояниях ощутимо меньше чем превосходств.

Написать отзыв

Примечание: HTML разметка не поддерживается! Используйте обычный текст.
    Плохо           Хорошо
Двойная шестерня для зубчатого ремня на 20 зубьев под ось 8 мм

Двойная шестерня для зубчатого ремня на 20 зубьев под ось 8 мм

Сдвоенная шестерня для передачи крутящего момента с одного вала на другой.Применяется для разделения..

51.98грн.

Шилд RAMPS 1.4 для Arduino MEGA

Шилд RAMPS 1.4 для Arduino MEGA

Шилд управления 3D-принтером или CNC-станком. Он устанавливается на плату контроллера Arduino MEGAСо..

172.48грн.

ЦАП цифро-аналоговый преобразователь I2C

ЦАП цифро-аналоговый преобразователь I2C

Цифро-аналоговый преобразователь с I2C интерфейсомИспользуется для организации аналогового выхо..

36.78грн.

Монтажный провод двойной 22AWG

Монтажный провод двойной 22AWG

Сдвоенный провод в изоляции для монтажа различных электронных проектов.Количество в метрах..

19.43грн.

Блок питания 5В 3А 25Вт

Блок питания 5В 3А 25Вт

Мощность блока питания 15ВтНа вход можно подавать переменное напряжение в диапазоне 100...240ВОт это..

172.48грн.