Съдържание:

Изпращайте числови данни от един Arduino към друг: 16 стъпки
Изпращайте числови данни от един Arduino към друг: 16 стъпки

Видео: Изпращайте числови данни от един Arduino към друг: 16 стъпки

Видео: Изпращайте числови данни от един Arduino към друг: 16 стъпки
Видео: Zigbee двусторонний энергомонитор постоянного тока MSH - интеграция DC UPS в Home Assistant 2024, Юли
Anonim
Изпращайте числови данни от един Arduino към друг
Изпращайте числови данни от един Arduino към друг

Въведение

от Дейвид Палмър, CDIO Tech. в университета в Астън.

Имали ли сте някога да изпращате някои номера от един Arduino на друг? Тази инструкция показва как.

Можете лесно да тествате дали работи, като просто напишете низ от числа, които да изпратите на терминала за сериен монитор, и ще видите как номерата се извеждат на втори сериен монитор, свързан към втория Arduino. Можете дори да използвате Bluetooth връзка.

Какво прави

Две програми Arduino (скици на Arduino говорят) трябва да бъдат разработени, едната Master програма за свързване към хост компютъра, работещ с Arduino Serial Monitor, едната да действа като Slave, за да получи серийното съобщение от Master, да го декодира и изпрати обратно. Подчиненият по избор е в състояние да покаже номерата, с които се занимава, на втори IDE сериен монитор - само в случай, че искате да използвате това. Това може да ви помогне да работите на първо място и да ви помогне, ако решите да направите някакви промени в програмите, за да отговарят на вашите собствени изисквания.

Оборудване

  • 2 Arduino
  • 2 USB кабела
  • кръстосани проводници (според изискванията)
  • 1 компютър/лаптоп, зареден с Arduino IDE (наличен за безплатно изтегляне от уебсайта Arduino.cc)

Стъпка 1: Настройка - Първо настройте хардуера

Настройка - Първо настройте хардуера си
Настройка - Първо настройте хардуера си
Настройка - Първо настройте хардуера си
Настройка - Първо настройте хардуера си

Включете 2 Arduinos в 2 USB порта на вашия компютър.

Съвет, добра идея е да ги обозначите като M и S (главен и подчинен), за да не се забърквате по -късно (както е показано на 2 снимки тук.)

Стъпка 2: Настройка - Настройте екрана си

Настройка - Настройте екрана си
Настройка - Настройте екрана си

Най -доброто нещо е да настроите екрана си така, че да имате

  • IDE, заредена с магистърската програма вляво и
  • че с Роба вдясно.

Дръжте серийните монитори за Maser и Slave също отляво и отдясно, както е показано на снимката на екрана тук.

Стъпка 3: Настройте главния край, след това се свържете заедно - Част 1

Настройте главния край, след това се свържете заедно - част 1
Настройте главния край, след това се свържете заедно - част 1

Когато настройвате главния си сериен монитор да изпраща два номера, винаги трябва да използвате началните и крайните знаци за разделители и знака за разделяне на запетаи, както виждате тук.

Сега трябва да свържете 2 -те Arduino заедно през сериен. Това се прави с два кръпка проводника.

Използвах зелено и жълто

  • Вземете първо жълтото, това трябва да се включи в D6 в един Arduino и D7 във втория
  • Тогава обратното за зеления проводник, D7 на първия и D6 на втория Arduino.

Като алтернатива, ако имате на разположение нещо като чифт Bluetooth модули - като HC -05 - те също ще работят, за да ви дадат точно същия ефект като кабелите по -горе.

Стъпка 4: Настройте главния край, след това се свържете заедно - част 2

Настройте главния край, след това се свържете заедно - част 2
Настройте главния край, след това се свържете заедно - част 2
Настройте главния край, след това се свържете заедно - част 2
Настройте главния край, след това се свържете заедно - част 2

Използваме библиотеката за софтуерна серия. Допълнителна информация можете да намерите на тази връзка

Можете да го видите извикан в ред 7 на някоя от програмите. Той конфигурира цифрови пинове 7 и 6 като TX и RX (предаване и приемане). По този начин данните ще преминават от Master Arduino през зеления проводник към Slave и когато Slave програмата във втория Arduino приключи работата си, обратно през жълтия проводник. В долната част на същата илюстрация (в прозореца на серийния монитор) можете да видите, че предадените от нас данни вече са преминали успешно описания тук цикъл и се връщат в компютъра, като двойката цели числа са добре разделени.

Стъпка 5: Преглед на скиците / програмите - Структурата на програмата

Преглед на скиците / програмите - Структурата на програмата
Преглед на скиците / програмите - Структурата на програмата
Преглед на скиците / програмите - Структурата на програмата
Преглед на скиците / програмите - Структурата на програмата

Оформление Както във всички скици на Arduino има 3 основни части:

  • Декларациите
  • Конфигурацията
  • Основният цикъл

Както често се случва, ние използвахме тук четвърти раздел, който е добавянето на „Функции“. Ако не сте запознати с използването на функции, можете да потърсите в Google за „функции на Arduino“и ще намерите сайтове с обяснения като примера в тази връзка: www.tutorialspoint.com/arduino/arduino_functions…..

Също така използвахме раздели, за да разделим програмата на по -управляеми блокове.

Трите блока, които използвахме, могат да се видят в горната част на всяка илюстрация на IDE прозорците по -горе:

  • simpleRxTx0330Master
  • често срещани
  • бележки

Това всъщност са отделни файлове в папката на програмата, както можете да видите в този изглед на Windows Explorer на файловете на Slave програмата.

Има много добра причина, поради която направихме това.

  • Докато изграждахме програмата, осъзнахме, че по -голямата част от програмата за Учителя е същата като за Роба.
  • В крайна сметка издърпахме всички общи части в раздел, който затова нарекохме „общ“и след това всеки път, когато дебъгирахме част (тествахме я и бяхме доволни, че работи добре), просто копирахме и поставихме целия раздел от Master към Slave или обратно.
  • Разделите с бележки също са идентични, тъй като дизайнът е общ.

Нито една от функциите не се извиква от настройката, всички те се извикват от цикъл, така че сме ги създали след настройка, но преди цикъл.

Стъпка 6: Дизайн отгоре надолу

Добра идея е да проектирате скицата си, като започнете с дефиниция на това, което искате да направите.

След като имате това, можете да започнете да правите скицата да прави тези неща. Като цяло, ако има детайл, който все още не знаете как да направите, просто го направете функция и оставете създаването на функцията за по -късно.

Това следва философията за добър дизайн, преподавана в много университети, наречена CDIO (Ако все още не знаете този, можете да го потърсите в Google и да намерите сайтове, за да го обясните като: https://www.cdio.org/s.) Това основно казва: Не започвайте дизайна, преди да сте изяснили концепцията. Не започвайте изпълнението, докато не сте изяснили дизайна. Не очаквайте да работи, преди да сте изяснили изпълнението. C първо, след това D, I и O. На всеки следващ етап правите повторение (върнете се около кръга (цикли), така че след като сте доволни от първоначалния си цикъл на проектиране обратно и проверете дали той все още отговаря на концепцията, и актуализирайте C, ако е необходимо. И така нататък, така че дори когато стигнете до Operating, върнете се чак до върха и отново вижте как изглежда C сега, след това D и I, и направете и проверете всички Промени при необходимост. С скици за програмиране това работи по същия начин, ако проектирате отгоре надолу.

Стъпка 7: Концепция и дизайн - Част 1

Концепция и дизайн - Част 1
Концепция и дизайн - Част 1
Концепция и дизайн - Част 1
Концепция и дизайн - Част 1

Концепцията тук прилича на схематичните изисквания, посочени в раздела „бележки“. “

Дизайнът може да изглежда като ранна версия на цикъла, който съответства на раздела с бележки и може да изглежда нещо като това, което виждате на тази фигура

Вижте как обичам да започна, като първо CTRL-C копирам коментарите в главата на цикъла, а след това започнете да попълвате празните места с команди, които ще направят тези неща.

Това всъщност компилира OK, както можете да видите в долната част на екрана на фигурата. Това достига от CDIO етап D до I и докато разработваме кода е добра идея да продължим да обикаляме този D-I цикъл.

Сега е време да преминем към следващия етап, там има коментар, който казва, че ще: // получим нещо от хардуерния USB, след което ще го предадем на софтуерния сериен канал. Ние пишем този код, за да се случи това - редове 133 до 138, показани тук в жълт хайлайтър

Стъпка 8: Концепция и дизайн - Част 2

Концепция и дизайн - част 2
Концепция и дизайн - част 2
Концепция и дизайн - част 2
Концепция и дизайн - част 2

Двете първи две функции, които въвеждаме тук, са (recv () и tran () за осъществяване на приемане от хардуерния порт и предаване към софтуерния порт - следователно ги извикваме с показаните параметри „hw“или „sw“.

В допълнение към тях добавихме тест за глобална променлива, наречена newData. Това е флаг, който ще зададем във функцията "void recv ();". Когато съобщението е получено, тази променлива се маркира от false към true. Правим това, за да предадем съобщение само ако е получено (флаг == true) в ред 134. И след като сме предали нашето съобщение, това е „свършена работа“, така че изчистваме флага обратно на false отново в ред 137.

Отново можем да проверим компилацията (от D до I) и този път имаме съобщение за грешка „недекларирано“(показано). Това ни казва, че не сме декларирали recv (); функция. Планираме да направим това по -късно, така че засега, за да можем да получим чиста компилация, трябва да създадем фиктивна или заместваща функция, както е показано по -долу.

Отново можем да проверим компилацията (от D до I) и този път имаме друго съобщение за грешка „недекларирано“за tran (); функция. Това се нуждае от подобно създаване на мъниче. Отново можем да проверим компилацията (от D до I) и този път ще открием, че това работи перфектно; дотук добре.

Стъпка 9: Завършете основния цикъл: A) Получаване от USB, B) Получаване от Slave Arduino

Завършете основния цикъл: A) Получаване от USB, B) Получаване от Slave Arduino
Завършете основния цикъл: A) Получаване от USB, B) Получаване от Slave Arduino
Завършете основния цикъл: A) Получаване от USB, B) Получаване от Slave Arduino
Завършете основния цикъл: A) Получаване от USB, B) Получаване от Slave Arduino

Има една последна част, която добавихме, за да завършим тази част, която е да добавим малко код за отстраняване на грешки.

Има още една инструкция за отстраняване на грешки в скици, която може да бъде посочена, за да се разбере какво сме направили тук и защо. Вижте инструкциите „Как да изграждаме и тестваме скици на Arduino, докато не работят“

Така че тези линии за отстраняване на грешки [показани 136-139] са добавени след това в основния цикъл и, ето, можете да ги тествате в главния край, като направите променливата за отстраняване на грешки вярна, и Компилиране (I), тогава ако свързвате Arduino, можете да качите, отворите серийния монитор и вижте дали това, което се връща в серийния монитор, е както е показано тук (виждате ли съобщение „DEBUG MODE“е добавено?)

Стъпка 10: Получаване и обработка на данните в Slave Arduino

Получаване и обработка на данните в Slave Arduino
Получаване и обработка на данните в Slave Arduino
Получаване и обработка на данните в Slave Arduino
Получаване и обработка на данните в Slave Arduino

Получаване от Slave Arduino

Добавете необходимия код за втория канал към основния контур, софтуерния сериен приемник, както е показано - редове 149 до 155.

Виждате ли, че структурата е свободно базирана на това, което написахме по -горе за случая Master?

Също така ще видите, че получаваме грешка на компилатора, друга недекларирана функция - този път parseData (); - така че трябва да направим и мъниче за това, преди да можем да стартираме тестова компилация без грешки.

Обработка на данните в Slave Arduino

Добавете кода на основния цикъл, необходим за Arduino, ако е конфигуриран като подчинено устройство, както е показано - редове 163 до 174. Виждате ли, че структурата му е много подобна на тази на първия канал?

Трябва да откриете, че този път се компилира абсолютно добре.

Стъпка 11: Напишете функцията за получаване

Напишете функцията за получаване
Напишете функцията за получаване

Функцията Receive - void recv (char from) {} - има две основни задачи.

1, за да получите низ от знаци от USB канала, и

2, за да получите такъв от канала Arduino към Arduino.

За първия ще трябва да използваме, защото той използва вградения в Arduino хардуер UART, а за втория използва стандартната Arduino библиотека: софтуер UART.

Когато започнем да добавяме код към функция - за да създадем функция, която прави нещо, вместо само мъниче - трябва да не забравяме да премахнем или коментираме копчето, което замества. В противен случай получаваме грешка при компилиране: референция на 'void lrec (char)'.

Опитайте да получите грешката и след това опитайте някой от предложените по -горе начини, за да се отървете от нея.

Започнете с функция, която прилича на тази, която показваме тук, на редове 75 до 88 в жълто.

Вече знаете, че като имате код, ще трябва да опитате операцията Compile. Получава ви грешка, като тези, които имахме по -рано, от типа: име на функция, която не е декларирана в този обхват. Първоначално ще се нуждаем от друг мъниче, което да ни позволи да компилираме тази грешка, така че добавете такъв както преди и се уверете, че сега можете да получите компилация без грешки.

Нека сега разгледаме кода, който сме написали за функцията recv ().

Той е доста чист, можете да видите използването на условието „if“за създаване на двете части на функцията, посочена по -горе.

Кодът в частта „sw“и „hw“е от същата форма и ще го опиша тук.

Първият от двойката редове във всеки случай е началото на цикъл while. Ако не сте запознати с времето, можете да го потърсите в сайта Arduino.cc/Reference за обяснения и примери. Тук чакаме „докато“вградената функция „Serial“не е получила никакви символи (и) и тъй като променливата newData е изключена (т.е. условието newData == false е вярно). Веднага щом се получи знак - или повече от един знак -, той ще „отпадне“до втория ред в тази двойка. Това ще извика recAstringChar (char); функция за обработка на текущия символ. След това тази двойка редове ще се редуват, докато (или докато) има някакви знаци, които все още се нуждаят от получаване. След като всички са готови, състоянието while приключва, което позволява завършването на следващото ниво if или else и от своя страна позволява rec (char); функция за прекратяване. По този начин е получено пълно съобщение.

Стъпка 12: Напишете подфункцията за получаване - част 1

Напишете подфункцията за получаване - част 1
Напишете подфункцията за получаване - част 1
Напишете подфункцията за получаване - част 1
Напишете подфункцията за получаване - част 1

Сега трябва да напишем функцията, наречена recAstringChar (char);. Виждате от коментара до ред 50 тук най -отгоре, че неговата работа е да актуализира два буфера с копия на входящото серийно съобщение. [Оказа се, докато се опитвах да накарам всичко да работи, едно нещо, което научих, беше, че имам нужда от два различни буфера - или поне това беше най -лесният начин да заобиколя някои проблеми, следователно това се превърна в нужда от 2 буфера, така че Току -що ги направих.] Извиках един буфер: полученData, а другия: полученChars.

Буферите са глобални променливи, така че те са декларирани на ниво модул, вижте редове 9 и 10 от общия раздел. В тази функция има декларирани други променливи, които следователно имат локален обхват- показан в редове 51-54 тук. Това не е мястото за обяснение на разликите между глобалните и местните, но има повече информация за това в https://www.arduino.cc/glossary/en/ под Local and Global.

Можете също да научите всичко за типовете данни и модификаторите на типове: static, boolean, byte, const, char в https://www.arduino.cc/reference/en/#variables, показани тук.

Основният програмен поток в тази функция се контролира от if на ред 56 тук и съответстващия му else в ред 74. Това се отнася за два сценария

а) [от ред 74 нататък], когато полученото съобщение започва. Това се случва, когато startMarker е забелязан - това е дефинирано като символа '<', поради което винаги, когато тестваме скицата, винаги започваме нашия низ с този знак. Ако не го направим, нищо няма да бъде обработено като получено, всичко ще бъде игнорирано, сякаш пишем глупости в подканата на клавиатурата „Serial Monitor“.

б) [редове 56 до 73], които получават всички останали знаци, каквито и да са те, но те се занимават само със знаци след валидно начало (получено е '>', както в а) по -горе.)

В тези редове (от 74 до 78) поставяме полученото <в един от буферите (полученData [0]), но не и в другия. Ние настройваме буферния указател (променлива: char ndx), за да сочи към следващата резервна буферна позиция (полученData [1]), като използваме командата post-increment (++) в реда ndx ++;, и зададохме флага за текущо действие на true.

Потокът на програмата в тази част на функцията се контролира от if в ред 57 тук и съответстващия му else в ред 65. Това се отнася за два сценария

а) [от ред 65 нататък], когато полученото съобщение приключи. Това се случва, когато endMarker е забелязан - дефиниран като>, поради което винаги, когато тестваме нашата скица, винаги завършваме нашия низ с този знак. Едно от нещата, които се случват при получаване на крайния знак, е, че глобалният флаг (технически променлива) newData е зададен true точно когато функцията завършва, така че функцията, която извиква нашата подфункция (извикващата функция: recv (char);) може да „знае“, че валидни нови данни са получени пълни.

б) [редове 57 до 64], който приема всички останали знаци, каквито и да са те. Просто делови ги паркира спретнато на редове в двата буфера.

Стъпка 13: Напишете подфункцията за получаване - част 2

Напишете подфункцията за получаване - част 2
Напишете подфункцията за получаване - част 2
Напишете подфункцията за получаване - част 2
Напишете подфункцията за получаване - част 2

Може да е полезно да дадете пример за това как изглеждат 2 буфера, когато са попълнени. Ако трябва да въведем enter, буферите ще имат символите, показани в тях:

Така че сега можете да видите, че имаме един буфер, който е точно същите символи, както първоначално въведохме, и един буфер, който има само двете стойности и разделителна запетая. Сега имаме някакъв код, който може да получи символите, които въвеждаме на клавиатурата на серийния монитор, можем да преминем от фаза I на CDIO към O, като въведем някои низове и ще видим какво се случва. Качете кода в Master Arduino, отворете Serial Monitor и опитайте да напишете нещо валидно, като enter. Получавате ли ехо на екрана на серийния монитор като този, показан тук?

Стъпка 14: Напишете функциите за предаване и анализ

Напишете функциите за предаване и анализ
Напишете функциите за предаване и анализ
Напишете функциите за предаване и анализ
Напишете функциите за предаване и анализ

Първо за предаването

Така че сега сме получили низ, можем да напишем функцията за предаване: tran (char); за да подмените клечката му. Това ще ни позволи да изпратим низ от Master към Slave Arduino, затова се уверете, че и двете устройства са включени и свързани заедно, за да тествате тази нова функционалност.

Въведете тази функция, както е показано тук в редове 117 до 133. Както ще разпознаете, тя има две части, едната за предаване към USB канала (хардуерен UART) и една за предаване към другата Arduino (софтуерна UART.) Това би трябвало да компилира грешка -безплатно и можете веднага да качите скицата и да видите какво се случва. Този път ще изпратя. Получавате ли показания резултат?

Снимката на екрана е интересна, защото Полученият низ … трябва да изглежда правилен както преди, а Предаваният низ … сега трябва да изглежда правилен. Имайте предвид обаче, че преобразуването на Integer не е работило. Има още малко код за добавяне, за да работи това.

Стъпка 15: Напишете функциите за предаване и анализ

Напишете функциите за предаване и анализ
Напишете функциите за предаване и анализ
Напишете функциите за предаване и анализ
Напишете функциите за предаване и анализ

След това за Parse

Това е парче код, който анализира низа, получен, за да извлече числовите частични низове и ги преобразува в цели числа. Това е void parseData (); функция на главния контур

Заменете кода за синтактичен анализ с кода, показан в редове 98 - 113. Качете го и нека видим дали проблемът, който имахме с 2 -те цели стойности, сега е отстранен. Да опитаме.

Да, работи, както е показано, намерените цели числа са 49 и 98.

Стъпка 16: Финал

Финал!
Финал!

Тези данни са преминали през кръга от компютъра през Master през подчиненото устройство и обратно през Master отново към компютъра. С готовата версия на общата, качена както в главния, така и в подчинения край, и с изключен режим на отстраняване на грешки сега, можем да видим правилно получените данни в двата края, както е показано тук.

Препоръчано: