Arduino:Примеры/MasterWriter

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Ведущий отправляет / ведомый считывает[1]

Начальник без умолку делится своими гениальными планами и раздает направо и налево свои образцово-виртуозные приказы – знакомо? Это мы и попробуем сымитировать в данном примере.

В некоторых ситуациях может быть полезно использовать не одну, а две (или больше!) платы Arduino, чтобы они обменивались информацией друг с другом. В этом примере две Arduino будут запрограммированы таким образом, чтобы «общаться» друг с другом по принципу «ведущий считывает / ведомый отправляет» через синхронный последовательный протокол I2C. Для того, чтобы выполнить эту задачу, нам понадобятся ряд функций из библиотеки Wire.

Плата Arduino 1 (т.е. ведущее устройство) будет запрограммировано таким образом, чтобы каждые полсекунды отправлять 6 байтов данных плате Arduino 2 с уникальным адресом. Когда сообщение будет получено, система выведет его на Serial Monitor.

В протоколе I2C для отправки и передачи данных используется два контакта: Serial Clock (SCL), через который Arduino отбивает тактовый импульс, и Serial Data (SDA), по которому и проходит обмен данными между девайсами.

Если тактовый импульс меняется с LOW на HIGH (этот сценарий известен как «положительный фронт тактового сигнала»), Arduino через SDA-линию отсылает I2C-девайсу бит информации, содержащий адрес конкретного устройства, а также запрос на отправку данных. Если тактовый импульс меняется с HIGH на LOW («отрицательный фронт тактового сигнала»), «разбуженный» I2C-девайс в ответ на запрос отсылает Arduino необходимые данные по той же SDA-линии.

Начальные 8 бит (т.е. 8 тактовых импульсов) от ведущего устройства к ведомому содержат адрес девайса, от которого ведущее устройство хочет получить данные. Последующие биты содержат адрес памяти у ведомого устройства, откуда ведущее устройство хочет сосчитать данные или записать их туда.

У каждого ведомого устройства есть собственный уникальный адрес, причем и ведущее устройство, и ведомое поочередно коммуницируют по одной и той же линии. Таким образом, ваша Arduino может «общаться» с несколькими девайсами или другими Arduino, используя лишь два своих контакта и уникальные адреса других устройств.

Необходимое оборудование

  • Две платы Arduino;
  • Провода-перемычки;

Цепь

5-ый (SCL) и 4-ый (SDA) контакты на ведущей Arduino 1 подключите к 5-ому и 4-ому контактам на ведомой Arduino 2. Кроме того, убедитесь, что контакты с «землей» у обеих плат тоже подключены друг к другу. Также, чтобы иметь возможность запустить последовательную передачу данных, ведомая Arduino должна быть через USB подключена к компьютеру.

Если независимое питание плат сделать затруднительно, подключите 5V-контакт ведущей Arduino к VIN-контакту на ведомой.

Схема

Код

Код для ведущей платы, т.е. для Arduino 1:

// Пример «Ведущая отправляющая плата; библиотека Wire»
// от Николаса Замбетти (Nicholas Zambetti, http://www.zambetti.com).

// Демонстрирует использование библиотеки Wire.
// Отправляет данные ведомому устройству через I2C/TWI.
// Работает в паре с примером «Ведомая считывающая плата; библиотека Wire».

// Создан 29 марта 2006.

// Этот код не защищен авторским правом.

#include <Wire.h>

void setup()
{
  Wire.begin(); // подключаем шину I2C (для ведущего устройства адрес опционален)
}

byte x = 0;

void loop()
{
  Wire.beginTransmission(4); // начинаем передачу девайсу #4
  Wire.write("x is ");       // отправляем 5 байт
  Wire.write(x);             // отправляем 1 байт  
  Wire.endTransmission();    // останавливаем передачу данных

  x++;
  delay(500);
}

Код для ведомой платы, т.е. для Arduino 2:

// Пример «Ведомая считывающая плата; библиотека Wire»
// от Николаса Замбетти (Nicholas Zambetti, http://www.zambetti.com).

// Демонстрирует использование библиотеки Wire.
// Получает данные от ведущей платы через I2C/TWI.
// Работает в паре с примером «Ведущая отправляющая плата; библиотека Wire».

// Создан 29 марта 2006

// Этот код не защищен авторским правом.


#include <Wire.h>

void setup()
{
  Wire.begin(4);                // подключаем шину I2C с адресом #4
  Wire.onReceive(receiveEvent); // регистрируем событие
  Serial.begin(9600);           // запускаем последовательную передачу данных, чтобы отображать данные на Serial Monitor
}

void loop()
{
  delay(100);
}

// Эта функция будет выполнятся всякий раз, когда от ведущей платы
// будут получены какие-либо данные.
// Она зарегистрирована как событие (см. блок setup):
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // пробегаемся по всем, кроме последнего
  {
    char c = Wire.read();     // получаем байт как символ
    Serial.print(c);          // показываем символ на Serial Monitor
  }
  int x = Wire.read();        // получаем байт как целое число
  Serial.println(x);          // показываем это целое число на Serial Monitor
}

См.также

  1. Wire.begin()
  2. Wire.beginTransmission()
  3. Wire.endTransmission()
  4. Wire.send()
  5. Wire.OnReceive()
  6. Wire.available)
  7. Wire Library
  8. digital_potentiometer
  9. master_reader

Внешние ссылки