Давайте разберемся с самой удобной коммуникацией физически заложенной в контроллеры 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() { Wire.begin(); 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.
Я здесь ещё не попробовал передачу данных от мастера слейву. Если попробуете - отпишитесь.
Недостатков здесь на небольших расстояниях ощутимо меньше чем превосходств.
Продолжение Arduino Nano I2C двухсторонняя связь между контроллерами
Шилд SHT30 для Wemos D1 mini
Шилд датчика температуры и влажности на основе SHT30Коммуникационный интерфейс I2CДиапазон измерения..
98.37грн.
Модуль часов реального времени DS3231SN
Модуль часов реального времени для различных плат микроконтроллеровХарактеристики:- интерфейс: I2C ,..
144.54грн.
Мини кнопка 12 x 12 x 4,3 мм
Миниатюрная кнопка для установки на плату через отверстияРазмеры 12 x 12 x 4,3 мм..
3.97грн.
Модуль блока питания 5В 600мА
Удобный модуль питания из 220В AC в 5В постоянного тока. Разработан для установки на печатную плату...
141.01грн.