Продолжаем разбор технологии обмена данными по коммуникации 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 опрашивать слейвов и посылать им управляющие данные. Будет весело!
Модуль стабилизатора напряжения 3,3 В
Модуль предназначен для питания различных электронных устройств, модулей, работающих на напряжении 3..
16.39грн.
Трансформатор тока 0-50А
Трансформатор тока предназначен для измерения силы переменного тока, протекающего через провод. Для ..
71.01грн.
Радиатор 25х23х16мм
Радиатор алюминиевый для транзисторов, симисторов ... с установкой на печатную платуОкрашенный в чер..
15.73грн.
ESP32 пианино из фруктов
Тема проекта: ESP32 пианино из фруктов. Друзья, рад вас всех сегодня видеть опять. Хочу проде..
Набор перемычек (папа-папа) 40шт 20см
Набор соединительных проводов для соединения плат контроллера с периферией без пайки. Подходят под с..
49.41грн.