Всем пользователям контроллеров 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) {
// save the last time you blinked the LED
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!
Умный дом #1: Введение в умный дом на ESP32
Умный дом #1: Введение в умный дом на ESP32 Современный умный дом – это не только дорогосто..
ESP32: Генерация ШИМ на основе таймера (без LEDC)
ESP32: Генерация ШИМ на основе таймера (без LEDC) В ESP32 есть несколько способов организовать ши..
RFID NFC модуль PN532 — считыватель карт 13.56 МГц для Arduino, ESP32, STM32
PN532 NFC модуль — это универсальный RFID-считыватель/передатчик для работы с бесконтактными картами..
279.07грн.
Стойка роликовая для оси X 2шт. с крепежом
Монтажная панель из МДФ для организации оси Х автоматического лазерного гравера.Отверстия под шаговы..
167.68грн.
Переменный резистор 1 кОм
Переменный резистор или потенциометрСопротивление 1 кОмМощность 0,5 ВтТип BЛинейная характеристикаТа..
21.46грн.





