Працюємо з 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 разметка не поддерживается! Используйте обычный текст.
    Плохо           Хорошо
Модуль PN532 NFC RFID

Модуль PN532 NFC RFID

NFC модуль на базе микросхемы NXP PN532, контроллера для бесконтактной связи на частоте 13,56 МГц на..

177.21грн.

Муфта на двигатель 3x5x25мм

Муфта на двигатель 3x5x25мм

Данная муфта служит переходником между валами 3 мм и 5 мм. Тоесть имеет с одной стороны отверстие ди..

42.29грн.

Универсальная монтажная плата на 830 отверстий

Универсальная монтажная плата на 830 отверстий

Макетная плата на 830 отверстий для макетирования любительских схемотехнических проектов. Имеет 4 ли..

100.66грн.

LCD Keypad shield для Arduino

LCD Keypad shield для Arduino

Шилд расширения для Arduino с LCD-дисплеем LCD1602 и набором кнопокСоответсвие занятых выводов ..

113.60грн.

Arduino основы программирования

Arduino основы программирования

Arduino основы программирования Здесь мы научимся писать элементарную программу способную сделать..