Arduino Зв’язок двох плат

З'єднайте пару плат Arduino у два процесори або зробіть віддалений датчик із радіоканалом. Великі зв'язки Ніка Вейча все це дозволяють.

Є купа причин, з яких вашому проекту може знадобитися більше одного Arduino – можливо, у вас є масив віддалених датчиків або ви хочете керувати роботом на базі Arduino з іншого Arduino. У будь-якому випадку, без взаємодії тут не обійтися. На щастя, організувати його досить легко. Способів передачі та прийому даних багато, і вибір залежить від ваших потреб – зокрема від відстані.

Використовується конфігурація «провідний/відомий», шиною управляє один пристрій, і ніхто не заговорить, доки до нього не звернуться першим. Теоретично на одній шині може бути безліч плат Arduino або інших пристроїв, якими управляє одне головне. Насправді, без застосування спеціальних апаратних повторювачів довжина створюваної шини обмежена. Щоб поговорити з пристроєм, виконайте такі дії:

Wire.begin(); Wire.beginTransmission(Slave_address); Wire.send(OxOI); Wire.endTransmission();

char bufter [8]; Wire.requestFrom(slave_address, 8); int count=0; while(Wire.available(); buffer[count] = Wire.receive(); cont++; >

Функція Wire.available() повертає кількість прийнятих байт, що у буфері в даний момент - для їх отримання використовується метод Wire.receive() . Можна й повернути до цієї передачі додатковий код. щоб переконатися в отриманні потрібної кількості даних або отримати фрагменти, що загубилися дорогою.

Для більш корисного прикладу напишемо коротку програму «пінгу». Вона встановить один пристрій як головний, інший - як підлеглий. Можна використовувати один і той же код для обох пристроїв і встановити головний пристрій наапаратному рівні, просто підключивши один із цифрових виходів до +5В і перевіряючи його всередині програми.

Ви не завжди вважаєте за краще писати код таким чином, але для перевірки набагато простіше мати один блок коду - виявляється, веденому пристрою багато чого все одно не потрібно. Заліза теж багато не буде потрібно. На рис. 1а показано, як це робиться фізично (якщо у вас хороші провідники, на макеті можна обійтися без резисторів, що підвищують, і підключити плати один до одного безпосередньо).

язок
Мал. 1а. З'єднати Arduino через шину PC просто - іноді навіть не потрібні резистори, що підвищують.

Мал. 1b прояснює цю схему, і шину можна розширити для підключення інших пристроїв.

arduino

Розіб'ємо наш тестовий код на фрагменти (повністю він наведений на DVD у файлі LXF152-arduino-code.zip):

#include const int configpin =7 bool config; unsigned char buffer[8]; int Slave=8;

Код налаштування за станом виводу визначить, чи є пристрій ведучим чи веденим, і встановить усе як слід:

void setup(void) pinMode(configpin, INPUT); config = digitalRead(configpin); Serial.begin(9600); Serial, print(lnitialised as:"); if (config) < Serial.println("transmitter"); Wire.begin(); > else < ;Serial.println("receiver"); Wire.begin(Slave); Wire.onReceive(slaveRX); Wire.onRequest(slaveTX): >

Код загалом зрозумілий. Найцікавіше відбувається у фрагменті для веденого пристрою. Існує два методи встановлення callback -функції (зворотного виклику) - в одному вона викликається, коли бібліотека Wire фіксує відправлення даних провідним пристроєм, а в іншому - коли приймається запит на повернення даних. Цим ми поки що не займалися.

У головному циклі має бути код лише для головного циклупровідного, але як зворотний зв'язок ми можемо відправляти якісь повідомлення про стан по послідовному каналу при виникненні певних подій. Основний код тут передає байт даних, та був просить передати його назад. За допомогою вбудованого таймера (шляхом виклику функції millis() можна дізнатися, скільки часу займають відправлення та повернення:

void loop(void) if (config) uint32_t time = millis(); uint32 t start: bool timeout = false; Serial.print("Now sending"); Wire.beginTransmission(Slave); Wire.send(0xFF); WireTransmissioin();

Про методи передачі даних ми говорили вище. Тепер, коли дані надіслані, можна попросити надіслати їх назад:

Serial.printlnf" Waiting for response"); delay(20); Wire.requestFrom(Slave,1); delay(20); Serial.println("Datarequested"); buffer[0]=Wire.receive(): Serial, print(response received"); Serial.println(buffer[0],HEX); Serial.print("round -trip:"); Serial.println(millis()-time): delay(2000); > 1>delay(1000); > >

Зрештою, потрібно написати функції для роботи на веденому пристрої. Кожна з них викликається з аргументом - цілим числом, яке задає кількість прийнятих чи запрошених байт:

void slaveRX(int bytes) buffer[0]=Wire.receive(); Serial.print("value received:"); ; Serial.println(buffer[0]. HEX); >; void slaveTX() Serial.println("sending reply"); ; Wire.send(buffer[0]);

Тут є кілька затримок, щоб лінії могли приходити у вихідний стан між передачами даних - на хороших шинах цього не потрібно: може, втім, виявитися, що потрібно кілька резисторів, що підвищують, якщо напруга на лініях буде важко досягати 5 В. Підключіть докожної лінії на +5 резистор опором 2 ком. На нашому тестовому устаткуванні на відправлення та прийом байта пішло близько 90 мкс без затримок. Не так вже й погано.

А що у нас із однопровідними з'єднаннями? Деякі датчики використовують саме таке з'єднання передачі даних (див. www.arduino.cc/Dlavoround/Learning/OneWire). Але для обміну великими обсягами даних між двома Arduino це не найкращий варіант.

Що нам треба? Дві плати Arduino (будь-яких). » Для схем з радіозв'язком вам знадобляться дві плати nRF2401+ (див. http://www.sparkfun.com/products/152. http://proto-pic.co.uk/transceiver-nrf2401a-with-chip-antenna/. або пошукайте на eBay). » Бібліотека RF з LXFDVD.

Якщо вам потрібен бездротовий зв'язок, варіантів кілька. З дорогих – стандарт «ZigBee», підтримуваний схемами та модулями ХВеє, надасть вам усе, про що ви мрієте. У більшості схем ХВеє застосовується простий послідовний інтерфейс, і вони часто використовуються в бібліотеках та прикладах Arduino. Великий недолік – вартість: близько 20 фунтів за пристрій – це не те, що ви охоче приплюсуєте до кожного проекту. З найбільш доступних - плати радіозв'язку, що працюють за принципом регенерації (для хизованих старомодністю, поясню: «автодини»). Вони досить дешеві, і їх легко зібрати чи переробити самим. Але їм не вистачає оснащення - доведеться писати власні протоколи для надсилання та прийому даних; Крім того, ці пристрої здатні інтерферувати один з одним, і користуватися кількома пристроями по сусідству може бути важко. "Золота середина" - серія трансіверів RF24XX. Вироблені Nordic Semiconductors, ці чудові маленькі схеми працюють на частоті 2.4 ГГц. Трохи не дійшовши до повноцінного мережного протоколу, вони пропонують такі корисні можливості, яквибір каналу, передача пакетів підтвердження та різні швидкості передачі (щоб вичавити з сигналу найбільшу відстань), і обійдуться вдесятеро дешевше за ХВее.

Ці мікросхеми можна купити змонтованими на кінцевій платі [breakout board] разом з антеною. Такі плати випускає Sparkfun. Їх досить складно прилаштувати до Arduino, але скомутувати все на макетній платі не важко.

Схеми nRF24XX є напівдуплексними. Вони можуть надсилати або приймати дані, але не одночасно. Щоб реалізувати це програмно, доведеться трохи повозитись, але ця проблема властива і іншим (не по радіоканалу) способам з'єднання. У будь-якому випадку мікросхеми ATmega для багатозадачності не зовсім придатні.

Існує пара реалізацій бібліотеки для цього пристрою. Більш складна з двох, але з більшою функціональністю - бібліотека RF24 від Джеймса Коліза-молодшого [James Coliz, Jr]. Вона підтримує багато апаратних функцій мікросхеми без зайвих ускладнень. Подивимося, як за допомогою цієї бібліотеки налаштувати з'єднання по радіоканалу та скористатися ним:

#include #include"nRF24L01.h" #include "RF24.h"

Ця бібліотека використовує бібліотеку SPI для Arduino, тому її також потрібно підключити. Тут також підключається клас RF24 – з його допомогою легко створити радіоканал, і після підключення всього цього ми створюємо екземпляр радіоканалу:

Тут ініціалізується об'єкт radio з використанням висновків 8 і 9 Arduino як висновки РЄ (Chip Enable – мікросхема активна) та CSN (Chip Select Not – мікросхема не обрана) відповідно. Назва "Мікросхема не обрана" може здатися смішною, але по суті це інвертований висновок "Мікросхема обрана" (Chip Select) - він активний у стані "нуля", і мікросхема вибирається, колицей висновок поєднується із «землею». Це звичайна справа для інтерфейсів SPI. тому навіть якщо висновок відзначений як CS або SS, перевірте, чи він активується «нульовим» рівнем. Інші висновки для обміну даними по SPI - ті, що зазвичай використовуються бібліотекою SPI Arduino: 11,12 і 13.

const uint64_t txpipe = 0x818181818101LL;; const uint64_t rxpipe1 = 0xFFFFFFFF01LL;; const uint64_t rxpipe2 = 0xFFFFFFFF02LL;

arduino
He всі мікросхеми для створення каналу зручно підключати до макету.