Всем пользователям контроллеров 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!
Концевик с колесом для 3D принтера или CNC ramps 1.4
Концевой выключатель для установки на 3D-принтер или CNC-станок системы ramps 1.4В комплекте ка..
50.19грн.
Шестерня для зубчатого ремня на 40 зубьев под ось 8 мм
Используется для передачи и редукции крутящего момента от двигателя до оси 8 ммКоличество зубьев 40 ..
83.82грн.
Датчик цвета TCS230
Датчик определения цвета основан на микросборке TCS230, которая представляет из себя матрицу фо..
114.20грн.
Радиатор для транзистора 21х15х10мм
Радиатор алюминиевый для пассивного охлаждения различных полупроводниковых силовых компонентов: тран..
13.03грн.
Переменный резистор 1 кОм
Переменный резистор или потенциометрСопротивление 1 кОмМощность 0,5 ВтТип BЛинейная характеристикаТа..
20.60грн.