Arduino:Примеры/MasterWriter
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Ведущий отправляет / ведомый считывает[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
}
См.также
- Wire.begin()
- Wire.beginTransmission()
- Wire.endTransmission()
- Wire.send()
- Wire.OnReceive()
- Wire.available)
- Wire Library
- digital_potentiometer
- master_reader