Taula de continguts:

Enviar dades numèriques d'un Arduino a un altre: 16 passos
Enviar dades numèriques d'un Arduino a un altre: 16 passos

Vídeo: Enviar dades numèriques d'un Arduino a un altre: 16 passos

Vídeo: Enviar dades numèriques d'un Arduino a un altre: 16 passos
Vídeo: 7 НАСТОЯЩИХ СТРАШНЫХ ИСТОРИЙ, КОТОРЫЕ БУДУТ НЕ СПАТЬ НО... 2024, Desembre
Anonim
Envia dades numèriques d'un Arduino a un altre
Envia dades numèriques d'un Arduino a un altre

Introducció

per David Palmer, CDIO Tech. a la Universitat Aston.

Alguna vegada ha calgut enviar alguns números d'un Arduino a un altre? Aquesta instrucció mostra com.

Podeu provar-lo fàcilment escrivint una cadena de números per enviar-los al terminal Serial Monitor i veure que els números surten en un segon monitor sèrie connectat al segon Arduino. Fins i tot podeu utilitzar un enllaç Bluetooth.

Què fa

Cal desenvolupar dos programes Arduino (esbossos en parla Arduino), un programa mestre per connectar-se a l’ordinador amfitrió que executa l’Arduino Serial Monitor, un per actuar com a esclau per rebre el missatge sèrie del mestre, descodificar-lo i tornar-lo a enviar. Opcionalment, l'esclau pot mostrar els números que tracta en un segon monitor sèrie IDE, per si de cas ho voleu fer servir. Pot ajudar-vos a fer que les coses funcionin en primer lloc i us ajudarà si decidiu fer canvis als programes per adaptar-los a les vostres necessitats.

Equipament

  • 2 Arduino
  • 2 cables USB
  • cables de connexió (segons calgui)
  • 1 PC / portàtil carregat amb Arduino IDE (disponible com a descàrrega gratuïta del lloc web Arduino.cc)

Pas 1: Configuració: configureu primer el vostre maquinari

Configuració: configureu primer el vostre maquinari
Configuració: configureu primer el vostre maquinari
Configuració: configureu primer el vostre maquinari
Configuració: configureu primer el vostre maquinari

Connecteu els 2 Arduinos a 2 ports USB de l’ordinador.

Consell, és una bona idea etiquetar-los com a M i S (mestre i esclau) perquè no pugueu ficar-vos després (com es mostra a les 2 fotos d’aquí).

Pas 2: Configuració: configureu la pantalla

Configuració: configureu la pantalla
Configuració: configureu la pantalla

El millor és configurar la pantalla de manera que tingueu

  • l'IDE carregat amb el programa Master a l'esquerra i
  • això amb l’esclau a la dreta.

Conserveu també els monitors de sèrie per a Maser i Slave a l'esquerra i a la dreta, tal com es mostra a la captura de pantalla aquí.

Pas 3: configureu el final mestre i, a continuació, connecteu-vos - Part 1

Configureu el final mestre i, a continuació, connecteu-vos - Primera part
Configureu el final mestre i, a continuació, connecteu-vos - Primera part

Quan configureu el monitor sèrie final final per enviar dos números, sempre heu d'utilitzar els caràcters delimitador inicial i final i el caràcter separador de comes tal com es veu aquí.

Ara heu de connectar els dos Arduino junts a través de sèrie. Això es fa amb dos cables de connexió.

Jo feia servir verd i groc

  • Agafeu primer el groc, aquest s’ha d’endollar a D6 en un Arduino i D7 en el segon
  • A continuació, el contrari per al fil verd, D7 al primer i D6 al segon Arduino.

Alternativament, si teniu alguna cosa disponible, com ara un parell de mòduls Bluetooth, com els HC-05, també funcionaran per donar-vos exactament el mateix efecte que els cables anteriors.

Pas 4: configureu el final mestre i, a continuació, connecteu-vos - Part 2

Configureu el final mestre i, a continuació, connecteu-vos - Part 2
Configureu el final mestre i, a continuació, connecteu-vos - Part 2
Configureu el final mestre i, a continuació, connecteu-vos - Part 2
Configureu el final mestre i, a continuació, connecteu-vos - Part 2

Estem fent ús de la biblioteca de programari de sèrie. Podeu obtenir més informació amb aquest enllaç

El podeu veure convocat a la línia 7 de qualsevol dels programes. Configura els pins digitals 7 i 6 com a TX i RX (transmissió i recepció). Així és com les dades viatjaran fora del mestre Arduino a través del cable verd cap a l’esclau i, quan el programa Slave del segon Arduino hagi acabat el seu treball, tornarà pel fil groc. A la part inferior de la mateixa il·lustració (a la finestra del monitor de sèrie) podeu veure que les dades que hem transmès ara han donat la volta al bucle descrit amb èxit i tornen al PC a mesura que el parell d’enters es separen molt bé.

Pas 5: Visió general dels esbossos / programes: estructura del programa

Visió general dels esbossos / programes: estructura del programa
Visió general dels esbossos / programes: estructura del programa
Visió general dels esbossos / programes: estructura del programa
Visió general dels esbossos / programes: estructura del programa

Disseny Com en tots els esbossos d'Arduino, hi ha 3 parts bàsiques:

  • Les declaracions
  • La configuració
  • El bucle principal

Com passa sovint, hem fet ús aquí d'una quarta secció que és l'addició de "Funcions". Si no esteu familiaritzat amb l'ús de funcions, podeu buscar a Google "Funcions Arduino" i trobareu llocs d'explicació com l'exemple en aquest enllaç: www.tutorialspoint.com/arduino/arduino_functions…..

També hem fet ús de pestanyes per separar el programa en blocs més manejables.

Els tres blocs que hem utilitzat es poden veure a la part superior de cada il·lustració de les finestres IDE anteriors:

  • simpleRxTx0330Master
  • comú
  • notes

En realitat, es tracta de fitxers separats dins de la carpeta del programa, tal com es pot veure en aquesta vista de Windows Explorer dels fitxers del programa Slave.

Hi ha una molt bona raó per la qual hem fet això.

  • Quan anàvem construint el programa, ens vam adonar que la major part del programa per al Mestre era el mateix que per a l’esclau.
  • Vam acabar traient totes les parts habituals en una pestanya, que per tant anomenàvem "comuna", i després, cada vegada que havíem depurat una part (la vam provar i ens vam conformar que funcionava bé), només vam copiar i enganxar tota aquesta pestanya a l'altre costat del mestre a l'esclau, o viceversa.
  • Les pestanyes de notes també són idèntiques, ja que el disseny és genèric.

Cap de les funcions no es diu des de la configuració, totes es diuen des del bucle, de manera que les hem creat després de la configuració, però abans del bucle.

Pas 6: Disseny de dalt a baix

És una bona idea dissenyar el vostre esbós començant per una definició del que voleu fer.

Un cop tingueu això, podeu començar a fer que l'esbós faci aquestes coses. Generalment, si hi ha un detall que encara no sabeu fer, només cal que en funcioni i deixeu la creació de la funció fins més endavant.

Això segueix la bona filosofia de disseny, ensenyada a moltes universitats, anomenada CDIO (si encara no la coneixeu, podeu fer-la amb Google i trobar llocs per explicar-la com: https://www.cdio.org/s.) Això bàsicament diu: no inicieu el disseny abans de tenir clar el concepte. No inicieu la implementació fins que no tingueu clar el disseny. No espereu que funcioni abans de tenir clara la implementació. C primer, després D, I i O. En cada etapa posterior, itereu (feu una volta al bucle), de manera que un cop satisfet amb el bucle de disseny inicial, comproveu que encara compleixi el concepte i actualitzeu-lo. la C si ho necessiteu. I així successivament, fins i tot quan hàgiu arribat a Operating, torneu fins a la part superior i torneu a veure com queda la C ara, després la D i jo, i feu i comproveu tot canvia segons calgui. Amb els esbossos de programació, això funciona igual si es dissenya de dalt a baix.

Pas 7: concepte i disseny: primera part

Concepte i disseny: primera part
Concepte i disseny: primera part
Concepte i disseny: primera part
Concepte i disseny: primera part

El concepte aquí s’assembla als requisits d’esquema que s’indiquen a la pestanya “notes”.

El disseny podria semblar una versió inicial del bucle, que coincideix amb la pestanya de notes i podria semblar alguna cosa com es veu en aquesta figura

Vegeu com m'agrada començar realment CTRL-C copiant primer els comentaris al cap del bucle i després comenceu a omplir els espais en blanc amb ordres que faran aquestes coses.

En realitat, això compila OK, tal com es pot veure a la part inferior de la pantalla de la figura. Això va des de l’etapa D CDIO fins a la I, i a mesura que anem desenvolupant el codi, és una bona idea seguir recorrent aquest bucle D-I.

Ara és hora de passar a la següent etapa, hi ha un comentari que diu que anem a: // rebre alguna cosa del maquinari USB, i després ho transmetrem al canal sèrie del programari. Escrivim aquest codi perquè això passi: les línies 133 a 138 es mostren aquí amb ressaltador groc

Pas 8: concepte i disseny: part 2

Concepte i disseny: part 2
Concepte i disseny: part 2
Concepte i disseny: part 2
Concepte i disseny: part 2

Les dues primeres dues funcions que introduïm aquí són (recv () i tran () per fer la recepció des del port de maquinari i la transmissió al port de programari, per tant, les anomenem amb els paràmetres 'hw' o 'sw' que es mostren.

A més d’ells, hem afegit una prova sobre una variable global anomenada newData. Es tracta d'una senyal que establirem dins de la funció "void recv ();". Quan s'ha rebut un missatge, aquesta variable es marca de fals a cert. Ho fem de manera que només transmetem un missatge si se n'ha rebut un (marca == true) a la línia 134. I un cop hem transmès el nostre missatge, aquesta feina està feta, de manera que tornem a esborrar la marca a fals a la línia 137.

De nou podem comprovar la compilació (D a I), i aquesta vegada tenim un missatge d'error "no declarat" (es mostra). Això ens indica que no hem declarat el recv (); funció. Tenim previst fer-ho més endavant, de manera que, ara per ara, per permetre-nos obtenir una compilació neta, hem de crear una funció fictícia o marcador de posició, com es mostra a continuació.

De nou podem comprovar la compilació (D a I), i aquesta vegada tenim un altre missatge d'error "no declarat" per al tran (); funció. Això necessita una creació similar. De nou podem comprovar la compilació (D a I), i aquesta vegada trobarem que funciona perfectament; fins ara, tot bé.

Pas 9: Acabeu el bucle principal: A) Recepció des d'USB, B) Recepció des de Slave Arduino

Acabeu el bucle principal: A) Recepció des d'USB, B) Recepció des de Slave Arduino
Acabeu el bucle principal: A) Recepció des d'USB, B) Recepció des de Slave Arduino
Acabeu el bucle principal: A) Recepció des d'USB, B) Recepció des de Slave Arduino
Acabeu el bucle principal: A) Recepció des d'USB, B) Recepció des de Slave Arduino

Hi ha una última peça que hem afegit per acabar aquesta part, que és afegir algun codi de depuració.

Hi ha una altra instrucció sobre esbossos de depuració a la qual es pot fer referència per entendre què hem fet aquí i per què. Consulteu la secció "Com es poden construir i provar esbossos d'Arduino fins que funcionin".

Per tant, aquestes línies de depuració [136-139 mostrades] s’afegeixen a continuació al bucle principal i, a continuació, podeu provar-les a l’extrem mestre fent que la variable de depuració sigui vertadera i Compileu (I), si si connecteu un Arduino cap amunt, podeu carregar, obrir el monitor de sèrie i veure si el que torna al monitor de sèrie és el que es mostra aquí (veieu que s’afegeix el missatge "MODE DE DEPORTE"?)

Pas 10: Recepció i tractament de les dades a l'Arduino esclau

Recepció i tractament de les dades a l’esclau Arduino
Recepció i tractament de les dades a l’esclau Arduino
Rebre i gestionar les dades a l’esclau Arduino
Rebre i gestionar les dades a l’esclau Arduino

Rebent de Slave Arduino

Afegiu el codi necessari per al segon canal al bucle principal, el receptor serial del programari tal com es mostra: línies 149 a 155.

Podeu veure que l'estructura es basa vagament en el que vam escriure anteriorment per al cas Master?

També veureu que obtenim un error del compilador, una altra funció no declarada: aquesta vegada parseData (); - Per tant, també hem de fer una prova per poder executar una compilació de proves sense errors.

Maneig de les dades a Slave Arduino

Afegiu el codi de bucle principal necessari per a l'Arduino si està configurat com a dispositiu esclau com es mostra: línies 163 a 174. Podeu veure que l'estructura del mateix és molt similar a la del primer canal?

I hauríeu de trobar aquesta vegada que es compila absolutament bé.

Pas 11: escriviu la funció de recepció

Escriviu la funció de recepció
Escriviu la funció de recepció

La funció de recepció (void recv (char from) {}) té dos treballs principals.

1 per rebre una cadena de caràcters del canal USB i

2 per rebre'n un del canal Arduino a Arduino.

Per a la primera haurem d’utilitzar-la perquè utilitza el maquinari integrat d’Arduino UART i, per al segon, utilitzar la biblioteca Arduino estàndard: el programari UART.

Quan comencem a afegir codi a una funció (per crear una funció que faci alguna cosa, en lloc de només un taló), hem de recordar d’eliminar o comentar el taló que substitueix. En cas contrari, obtindrem un error de compilació: refefintion de 'void lrec (char)'.

Intenteu obtenir l'error i, a continuació, proveu qualsevol de les formes suggerides anteriorment per eliminar-lo.

Comenceu amb una funció que s'assembla a la que mostrem aquí de les línies 75 a 88 en groc.

A hores d’ara ja sabeu que si teniu codi, haureu de provar l’operació Compila. S'obté un error, com els que teníem anteriorment, del tipus: nom de la funció no declarat en aquest àmbit. Inicialment necessitarem un altre registre que ens permeti compilar aquest error, així que afegiu-ne un com abans i assegureu-vos que ara podeu obtenir una compilació sense errors.

Ara fem una ullada al codi que hem escrit per a la funció recv ().

És bastant net, es pot veure l'ús de la condició "si" per produir les dues parts de la funció esmentada anteriorment.

El codi dins de la part "sw" i la part "hw" té la mateixa forma i el descriuré aquí.

El primer del parell de línies en cada cas és l'inici d'un bucle while. Si no esteu familiaritzats amb les estones, podeu consultar-les al lloc Arduino.cc/Reference per obtenir explicacions i exemples. Aquí esperem "mentre" la funció "Serial" incorporada no ha rebut cap caràcter i perquè la variable newData s'ha desactivat (és a dir, la condició falsa newData == és certa). Tan bon punt es rebi un personatge (o més d'un personatge), el "temps" passarà a la segona línia d'aquest parell. A continuació, es cridarà al recAstringChar (char); funció per gestionar el caràcter actual. Aquest parell de línies s’alternarà mentre hi hagi (o mentre) hi hagi caràcters que encara s’hagin de rebre. Un cop acabades totes, l'estat mentre s'acaba, permetent que el nivell següent o bé pugui acabar, i al seu torn permetre la rec (char); funció per acabar. Per tant, ara s'ha rebut un missatge complet.

Pas 12: escriviu la subfunció de recepció: primera part

Escriviu la subfunció de recepció: primera part
Escriviu la subfunció de recepció: primera part
Escriviu la subfunció de recepció: primera part
Escriviu la subfunció de recepció: primera part

Ara hem d’escriure la funció anomenada recAstringChar (char);. Veureu des del comentari a la línia 50 aquí, a la part superior, que la seva tasca és actualitzar dos memòries intermèdies amb còpies del missatge en sèrie entrant. [Va resultar que mentre intentava que tot funcionés, una cosa que vaig aprendre va ser que necessitava dos memòries intermèdies diferents, o almenys aquesta era la manera més senzilla de solucionar alguns problemes, de manera que va evolucionar fins a necessitar-ne 2. Acabo de fer-los.] He trucat a un buffer: ReceivedData i a l’altre: ReceivedChars.

Els buffers són variables globals, de manera que es declaren a nivell de mòdul, vegeu les línies 9 i 10 de la pestanya comuna. Hi ha altres variables declarades dins d'aquesta funció que, per tant, tenen un abast local, que es mostra a les línies 51-54 aquí. Aquest no és el lloc per explicar les diferències entre globals i locals, però hi ha més informació a https://www.arduino.cc/glossary/en/ a Local i Global.

També podeu obtenir informació sobre els tipus de dades i els modificadors de tipus: estàtic, booleà, byte, const, char a https://www.arduino.cc/reference/en/#variables, que es mostra aquí.

El flux principal del programa en aquesta funció està controlat per la línia if de la línia 56, i la resta corresponent a la línia 74. Es tracta de dos escenaris.

a) [a partir de la línia 74] quan comença el missatge rebut. Això passa quan es detecta startMarker: s'ha definit com el caràcter '<', motiu pel qual sempre que provem l'esbós sempre comencem la nostra cadena amb aquest caràcter. Si no ho fem, no es processarà res com a rebut, tot s'ignorarà com si estiguéssim escrivint tonteries a l'indicatiu del teclat "Monitor de sèrie".

b) [línies 56 a 73] que rep tots els altres caràcters, siguin quins siguin, però només tracten els caràcters després que hagi passat un inici vàlid (s'ha rebut un ">" com a la a).)

En aquestes línies (del 74 al 78) posem el que va rebre <en un dels búfers (recibidaData [0]), però no a l’altre. Ajustem el punter de memòria intermèdia (variable: char ndx) per apuntar a la següent posició de memòria intermèdia de recanvi (dataData rebuda [1]) mitjançant l'ordre post-increment (++) de la línia ndx ++;, i establim el senyalador en curs a true.

El flux del programa en aquesta part de la funció està controlat per la línia If de la línia 57, i la seva altra part corresponent a la línia 65. Es tracta de dos escenaris.

a) [a partir de la línia 65] quan finalitza el missatge rebut. Això passa quan s’indica endMarker, definit com>, motiu pel qual sempre que provem el nostre esbós sempre acabem la nostra cadena amb aquest caràcter. Una de les coses que passa quan es rep el caràcter final és que la marca global (tècnicament variable) newData s’estableix en el moment que acaba la funció, de manera que la funció que crida la nostra subfunció (la funció que crida: recv (char);) pot "saber" que s'han rebut dades noves vàlides completes.

b) [línies 57 a 64] que rep tots els altres personatges, siguin quins siguin. Simplement, els estaciona ocupadament en files de tots dos tampons.

Pas 13: escriviu la subfunció de recepció: part 2

Escriviu la subfunció de recepció: part 2
Escriviu la subfunció de recepció: part 2
Escriviu la subfunció de recepció: part 2
Escriviu la subfunció de recepció: part 2

Podria ajudar a donar un exemple de com són els 2 búfers quan s’han poblat. Si haguéssim d'introduir la tecla Enter, els buffers tindrien els caràcters que s'hi mostren:

Ara podeu veure que tenim una memòria intermèdia que és exactament els mateixos caràcters que vam escriure per primera vegada i una memòria intermèdia que només té els dos valors i una coma separadora. Ara tenim un codi que pot rebre els caràcters que escrivim al teclat Serial Monitor, podem passar de la fase I CDIO a O, escrivint algunes cadenes i veient què passa. Pengeu el codi a Master Arduino, obriu el monitor de sèrie i proveu d’escriure alguna cosa vàlida, com ara enter. Rebràs un ressò a la pantalla del monitor sèrie com el que es mostra aquí?

Pas 14: escriviu les funcions de transmissió i analització

Escriviu les funcions de transmissió i analització
Escriviu les funcions de transmissió i analització
Escriviu les funcions de transmissió i analització
Escriviu les funcions de transmissió i analització

Primer per al Transmit

Així que ara hem rebut una cadena, podem escriure la funció de transmissió: tran (char); per substituir el seu taló. Això ens permetrà enviar una cadena des del Mestre al Slave Arduino, per tant, assegureu-vos que tots dos dispositius estiguin connectats i connectats per provar aquesta nova funcionalitat.

Introduïu aquesta funció tal com es mostra aquí a les línies 117 a 133. Com sabreu, té dues parts, una per transmetre al canal USB (maquinari UART) i una per transmetre a l'altre Arduino (programari UART). Això hauria de compilar un error -Lliure, i podeu penjar l'esbós immediatament i veure què passa. Aquesta vegada l’enviaré. Voleu obtenir el resultat?

La captura de pantalla és interessant perquè la cadena rebuda … hauria de semblar correcta com abans i la cadena transmesa … ara hauria de semblar correcta. Tanmateix, tingueu en compte que la conversió sencera no ha funcionat. Encara hi ha una mica més de codi per afegir perquè funcioni.

Pas 15: escriviu les funcions de transmissió i analització

Escriviu les funcions de transmissió i analització
Escriviu les funcions de transmissió i analització
Escriviu les funcions de transmissió i analització
Escriviu les funcions de transmissió i analització

Després pel Parse

Es tracta d’un fragment de codi que analitza la cadena rebuda per obtenir les cadenes parcials numèriques i les converteix en valors enters. És el parseData buit (); funció del bucle principal

Substituïu el taló d'anàlisi pel codi que es mostra a les línies 98 - 113. Pengeu-lo i anem a veure si el problema que teníem amb els 2 valors enters ja està solucionat. Intentem.

Sí, funciona, com es mostra, els enters trobats són 49 i 98.

Pas 16: final

Final!
Final!

Aquestes dades s'han donat la volta al PC des del PC a través del Mestre a través de l'esclau i han tornat a través del Màster fins al PC de nou. Amb la versió finalitzada de common carregada als extrems mestre i esclau i amb el mode de depuració desactivat ara, podrem veure les dades rebudes correctament als dos extrems tal com es mostra aquí.

Recomanat: