Віримо в перемогу ЗСУ!
Працюємо з 09:00 до 18:00 Пн-Сб

Усім користувачам контролерів 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>

Усе гарно та душевно. Кожний з двох контролерів покаже нам свої здібності одночасної передачі та прийому даних, але поки рано танцювати чечітку від радості. Справа в тому, що отримані дані тільки у моніторі порта схожі на очікувані дані, а насправді це просто масив байтів, з яким важко далі працювати та виокремити з нього корисні складові.
Провівши пошуки на сайті ардуіно, я знайшов на перший погляд грубий спосіб виділення з байтів необхідної текстової, дійсну та цілочислену інформацію. Спробувавши його в дії, мені стало ясно, що це доволі класний приклад отримання, обробки та парсингу даних для нашої задачі обміну корисними даними.
Наступний код для Arduino контролерів дозволяє отримати з відправленого рядка вигляду <HelloWorld, 12, 24.57> три змінні, що розділені наперед заданим символом ",", кожну свого визначеного типу: рядок char, ціле число int та дійсне число float. Також в цьому прикладі код перевіряє наявність початкового символу "<" рядка даних та кінцевого символа ">"

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!

<< Проекти << Усі товари >> Статті, уроки >>

Написати відгук

Примітка: HTML размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
Трансформатор струму 0-50А

Трансформатор струму 0-50А

Трансформатор струму призначений для вимірювання сили змінного струму, що тече через дріт. Для підкл..

74.69грн.

Підсилювач PAM8610 10x2Вт з регулюванням гучності та роз'ємами

Підсилювач PAM8610 10x2Вт з регулюванням гучності та роз'ємами

Стерео підсилювач звукової частоти класу D зі змінним резистором регулювання гучності, роз'ємами та ..

126.61грн.

Уроки Arduino для новачків 1.1.2 Плата Arduino

Уроки Arduino для новачків 1.1.2 Плата Arduino

Отже продовжимо розмову про плату Arduino. Поговоримо про різні електронні компоненти на ній.&n..

Огляд плат Arduino

Огляд плат Arduino

Оригинальный Arduino был разработан для одной специфической задачи, и справился с этой задачей в сов..

Датчик доща, вологи

Датчик доща, вологи

Датчик вологи з дискретним та аналоговим виходомДискретним виходом керує компаратор LM393. Його..

42.90грн.