Працюємо з 09:00 до 19:00 без вихідних
Київ біля ТЦ Квадрат бул.Перова

Продолжаем разбор технологии обмена данными по коммуникации 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.

Программа контроллера - слейва.

#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 опрашивать слейвов и посылать им управляющие данные. Будет весело!


Написать отзыв

Примечание: HTML разметка не поддерживается! Используйте обычный текст.
    Плохо           Хорошо
Вольтметр цифровой 3,2 ... 30 В

Вольтметр цифровой 3,2 ... 30 В

Диапазон измерения напряжения 3,2 ... 30 ВТочность измерения 0,01 В в диапазоне 3,2 ... 10 ВТочность..

56.83грн.

Корпус для Raspberry PI 2 B или 3 B

Корпус для Raspberry PI 2 B или 3 B

Корпус для мини-компьютера Raspberry PI 2 или 3 модель BМатериал - прозрачный акрил толщиной 3 ммВ к..

96.10грн.

Гироскоп GY-50

Гироскоп GY-50

Цифровой инерциальный трёхосевой гироскоп GY-50 на MEMS микросхеме L3G4200D.Используе..

102.23грн.

Набор перемычек (мама-папа) 40шт 20см

Набор перемычек (мама-папа) 40шт 20см

Набор соединительных проводов для соединения плат контроллера с периферией без пайки. Подходят под с..

39.28грн.

Сменное жало паяльника 900M-T 1шт.

Сменное жало паяльника 900M-T 1шт.

Жало для паяльника 60Вт с регуляторомДиаметр рабочей части 3 ммВнутренний диаметр отверстия под нагр..

22.75грн.