Працюємо з 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 разметка не поддерживается! Используйте обычный текст.
    Плохо           Хорошо
Контроллер заряда аккумулятора 3,7В или 4,2В 1А

Контроллер заряда аккумулятора 3,7В или 4,2В 1А

Плата для зарядки литиумных аккумуляторов 3,6 - 4,2В и запитки его нагрузки.Зарядка производится чер..

19.96грн.

Двойной шилд расширения для WeMos D1 Mini

Двойной шилд расширения для WeMos D1 Mini

Шилд для параллельного выстраивания модулей платы WiFi контроллера WeMos D1 MiniТакое построени..

45.38грн.

MAX7219 драйвер светодиодной матрицы

MAX7219 драйвер светодиодной матрицы

Специализированная микросхема для управления светодиодной матрицей 8х8.Так же при помощи данной микр..

32.03грн.

Вентилятор 12В 40мм

Вентилятор 12В 40мм

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

33.68грн.

BME280 датчик температуры, влажности и атмосферного давления

BME280 датчик температуры, влажности и атмосферного давления

Датчик - три в одном для метеостанции с коммуникацией I2CНапряжение питания 1,8 ... 5 ВДиапазон изме..

124.91грн.