Усім користувачам контролерів Arduino відомо, що можна передавати дані через апаратний порт UART контролера, а також за допомогою вільних дискретних входів-виходів програмним UART портом. По суті для з'єднання двох контролерів між собою нам знадобляться 2 ... 3 дроти. По двох дротах буде односторонній зв'язок, а по трьох в обидва боки.
Так от, ми можемо в один контролер записати наприклад ось такий шматок програми
// Підключаємо бібліотеку Software Serial #include <SoftwareSerial.h> // Оголошуємо використані дискретні канали контролера для зв'язку SoftwareSerial outSerial(5, 6); // RX, TX float i1=40.04; float i2=5.08; float i3=-200.03; String str; unsigned long previousMillis = 0; const long interval =2000; //періодичність відправки даних в порт іншому контролеру void setup(){ Serial.begin(9600); //стандартна швидкість передачі даних апаратного UART порту (використовуємо для перевірки отримання даних від другого контролера) outSerial.begin(9600); //швидкість обміну програмного порту } void loop(){ unsigned long currentMillis = millis(); //із заданою періодичністю пишемо у програмний порт //іншому контролеру Arduino три постійно змінюваних числа float if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; str = "<"; i1 = i1+0.1; str += i1; str += ";"; i2 = i2+0.1; str += i2; str += ";"; i3 = i3+0.1; str += i3; str += ">"; outSerial.println(str); //тут відправлення типу <3.54;56.17;-140.34> } //тут віправляємо усі отримані від сусіднього контролера дані в апаратний UART у монітор порту if (outSerial.available()) { Serial.write(outSerial.read()); } }
З'єднаємо два контролери Arduino Nano R3 згідно наступної не хитрої схеми
У другий контролер запишемо програму з невеликими змінами. Ми в ній змінимо стартові величини флоатів, щоб вони явно відрізнялись від даних з першого Nano. А також переставимо місцями дискретні піни, до яких прив'язано програмний UART.
// Підключаємо бібліотеку Software Serial #include <SoftwareSerial.h> // Декларуємо використані дискретні канали контролера для зв'язку SoftwareSerial outSerial(6, 5); // RX, TX float i1=240.04; float i2=1005.08; float i3=-4200.03; String str; unsigned long previousMillis = 0; const long interval =2000; //періодичність відправлення даних в порт іншому контролеру void setup(){ Serial.begin(9600); // Звичайна швидкість передачі даних апаратного UART порту (використаємо для перевірки отримання даних від іншого контролера) outSerial.begin(9600); //швидкість обміну програмного порту } void loop(){ unsigned long currentMillis = millis(); //із заданою періодичністю пишемо в програмний порт //іншому контролеру Arduino три постійно змінюваних числа float if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; str = "<"; i1 = i1+0.1; str += i1; str += ";"; i2 = i2+0.1; str += i2; str += ";"; i3 = i3+0.1; str += i3; str += ">"; outSerial.println(str); //тут відправлення типу <3.54;56.17;-140.34> } //тут відправляємо усі отримані від сусіднього контролера дані в апаратний UART у монітор порту if (outSerial.available()) { Serial.write(outSerial.read()); } }
Тепер один Arduino потрібно буде живити окремо без нашого компа, а інший підключити до компа. Та в моніторі порта будемо отримувати наступні рядки з періодичністю в 2 секунди:
<240.64;1005.68;-4199.43>
<240.74;1005.78;-4199.33>
<240.84;1005.88;-4199.23>
const byte numChars = 32; char receivedChars[numChars]; char tempChars[numChars]; // тимчасовий масив використовується під час парсингу // змінні для зберігання отриманих даних char messageFromPC[numChars] = {0}; //текстові дані int integerFromPC = 0; //цілочисленні дані float floatFromPC = 0.0; //дійсні дані boolean newData = false; //============ void setup() { Serial.begin(9600); Serial.println("Цей приклад очікує три значення даних - текст, ціле число та число з плаваючою крапкою"); Serial.println("Передавайте дані з іншого контролера у такому вигляді <HelloWorld, 12, 24.7> "); Serial.println(); } //============ void loop() { recvWithStartEndMarkers(); if (newData == true) { strcpy(tempChars, receivedChars); parseData(); showParsedData(); newData = false; } } //============ void recvWithStartEndMarkers() { static boolean recvInProgress = false; static byte ndx = 0; char startMarker = '<'; char endMarker = '>'; char rc; while (Serial.available() > 0 && newData == false) { rc = Serial.read(); if (recvInProgress == true) { if (rc != endMarker) { receivedChars[ndx] = rc; ndx++; if (ndx >= numChars) { ndx = numChars - 1; } } else { receivedChars[ndx] = '\0'; // закінчуємо рядок recvInProgress = false; ndx = 0; newData = true; } } else if (rc == startMarker) { recvInProgress = true; } } } //============ void parseData() { // розділення даних на складові частини char * strtokIndx; // це використовується функцією strtok() як індекс strtokIndx = strtok(tempChars,","); // отримуємо значення першої змінної - рядок strcpy(messageFromPC, strtokIndx); //записуємо її в змінну messageFromPC strtokIndx = strtok(NULL, ","); // продовжуємо з останнього індексу integerFromPC = atoi(strtokIndx); // конвертуємо цю складову в integer strtokIndx = strtok(NULL, ","); floatFromPC = atof(strtokIndx); // перетворюємо цей шматок тексту у float } //============ void showParsedData() { Serial.print("Message "); Serial.println(messageFromPC); Serial.print("Integer "); Serial.println(integerFromPC); Serial.print("Float "); Serial.println(floatFromPC); }
Взагалі дуже рекомендую використовувати цей приклад скетчу у своїх проектах. Цей інструмент дозволяє нам з'єднувати два окремих контролера в одне ціле, що дає можливість збільшити кількість пінів пристрою або розподілити мізки Arduino на велику відстань. Також до Arduino Nano можна підключити другий контролер через апаратний порт UART, а програмний другий порт в мене запустити не вдалося (або я щось не правильно робив або бібліотека такого не дозволяє). Відпишіться, якщо у вас вдавалося запускати два програмних порти на одному контролері.
Піду штурмувати далі. Усім великий привіт від geekmatic!
Як перевірити дискретний датчик холла
Інколи виникає потреба перевірити наявний магнітний датчик хола на працездатність. Але при цьому ціл..
4-значний LED індикатор
Світлодіодний індикатор на основі двох мікросхем 74HC595Напруга живлення 3,3 ... 5 ВРозміри пла..
68.40грн.
Фільтрація шумів аналогового сигналу
Шум аналогового входу Будь-який аналоговий датчик, з'єднувальні дроти, та і сам аналоговий вхід кон..
Модуль енкодера
Модуль енкодера з кнопкою.Використовується для управління меню у різних пристроях. Замінює багато кн..
70.16грн.