Продолжаем разбор технологии обмена данными по коммуникации I2C
В предыдущей статье рассматривался пример сбора данных одним контроллером Arduino NANO c двух других таких же контроллеров по шине I2C и отправка их по этой же шине в жидкокристаллический индикатор. Теперь хотелось бы разобраться с двухсторонним почти равнозначным обменом между контроллерами по I2C. Я возьму на этот раз два контроллера Nano. Один будет выступать в роли мастера, другой - слейва. Мастер периодически сначала будет отправлять значение одной переменной integer подчиненному Arduino Nano, после чего делать запрос на значение такой же переменной от него. А слейв при поступлении данных от мастера будет их считывать, а при поступлении запроса будет отправлять один integer.
Видео по предыдущей статье.
Программа мастера выглядит следующим образом
#include <Wire.h> #define SLAVE_ADDRESS 0x01 byte high[2]; int com = 223; int i; int nano3; void setup() { Wire.begin(); Serial.begin(9600); } void loop() { high[0] = (com >> 8); high[1] = (com & 0xff); Wire.beginTransmission(0x01); Wire.write(high[0]); Wire.write(high[1]); Wire.endTransmission(); Serial.println("Requesting Data"); Wire.requestFrom(SLAVE_ADDRESS, 2); i=0;nano3=0; while (Wire.available()) { byte c = Wire.read(); if (i==0) nano3 = ((c & 0xff) << 8); else nano3 = nano3 | c; i++; } Serial.print("nano3 "); Serial.println(nano3); delay(2000); }
Преобразование данных выполнено по мотивам предыдущей статьи.
Адрес слейва будет иметь значение 01.
Отправлять будем целое число 223.
Программа контроллера - слейва. Arduino i2c несколько устройств
#include <Wire.h> #define SLAVE_ADDRESS 0x01 int temp=22; byte high[2]; int nano3; void setup() { Wire.begin(SLAVE_ADDRESS); Wire.onReceive(receiveEvent); Wire.onRequest(requestEvent); Serial.begin(9600); } void loop() { delay(100); } void requestEvent() { Serial.println("Request from Master. Sending: "); high[0] = (temp >> 8); high[1] = (temp & 0xff); Wire.write(high[0]); Wire.write(high[1]); } void receiveEvent(int bytes) { int i=0; nano3=0; while (Wire.available()) { byte c = Wire.read(); if (i==0) nano3 = ((c & 0xff) << 8); else nano3 = nano3 | c; i++; } Serial.print("nano3 "); Serial.println(nano3); }
Слейв Arduino Nano принимает данные от главного контроллера. В нашем случае принимает цифру 223 и выводит её в монитор порта. А при запросе данных от мастера этот Нано отправляет целое число 22. Все запросы от главного обрабатываются при помощи отдельных функций.
При правильном подключении мастер в монитор порта будет выводить полученные цифры 22, а слейв 223.
Выводы
Оказалось, что в интернете по этой тематике опубликованы или откровенно не работающие примеры программ или работающие только с байтами. Пришлось сделать по своему и в результате получилось прекрасное решение.
Мне в следующем проекте будет необходимо подключить 10 Arduino Nano к главному контроллеру. При чем 8 из них должны будут обмениваться с главным двухсторонними данными. Для этого идеально подойдет коммуникация I2C. Так что я в цикле контроллера-мастера буду последовательно, возможно в цикле FOR опрашивать слейвов и посылать им управляющие данные. Будет весело!
Ремень зубчатый 6 мм 200 мм
Зубчатый прорезиненный ремень для передачи механической энергии вращения от одного зубчатого колеса ..
41.98грн.
Шаговый двигатель NEMA17 17HS4401
Две фазы Сила удержания 40N.cm Максимальный ток потребления 1,7 А Активное сопротивлен..
465.28грн.
ST-Link V2 программатор
Программатор для микроконтроллеровАлюминиевый корпусПоддерживает следующие версии программ для проек..
147.65грн.
Винт М2х20мм оцинкованный
Винт оцинкованный с резьбой М2 для крепления элементов любительских проектовДлина резьбы 20 мм..
3.53грн.
Трансформатор тока 0-100А
Аналоговый датчик переменного тока силой до 100А. Это раскрывающийся трансформатор тока с диаметром ..
257.89грн.