Trushin A.N., Arutyunyan M.G. Nadviazanie spojenia a výmena dát cez bluetooth medzi Arduino a iOS aplikáciou. Parametre protokolu pre komunikáciu medzi Arduino a ESP8266 arduino komunikáciou

Stiahnuť ▼ štandardný príklad„Physical Pixel“ cez ponuku File\Examples\4.Communication\PhysicalPixel. Tento program čaká na dáta z počítača. Po prijatí znaku „H“ sa indikátor testu rozsvieti, po prijatí znaku „L“ zhasne. Poďme analyzovať jeho zdrojový kód:

int vystupPin = 13 ; // tu uložíme kontaktné číslo
int hodnota; // tu bude uložený prijatý znak

void setup()
{
Serial.begin(9600) ; //nastavíme port na 9600 bps
pinMode(outputPin, OUTPUT) ; // nastavíme pin 13 do výstupného režimu
}

void loop()
{
if(Serial.available())( //ak existuje akceptovaný znak,
val = Serial.read(); // potom si to prečítaj a ulož do val
if (val == "H" ) ( // ak je akceptovaný znak "H"...
digitalWrite(outputPin, HIGH) ; // potom zapnite LED
}
if (val == "L" ) ( // ak je akceptovaný znak "L",
digitalWrite(outputPin, LOW) ; // potom vypnite LED
}
}
}

Všimnite si vnorené podmienky a poradie otvárania a zatvárania zložených zátvoriek. Pre uľahčenie čítania programového kódu je každá ďalšia úroveň vnorenia posunutá doprava. Editor navyše pomáha pri čítaní kódu – ak umiestnite kurzor napravo od zátvorky, zvýrazní príslušnú dvojicu zátvoriek.

Ako skontrolovať fungovanie tohto programu po jeho stiahnutí do mikrokontroléra? Musíme nájsť spôsob, ako poslať znaky do COM portu počítača, aby ich mikrokontrolér prijal a spracoval. Existuje veľa možností na vyriešenie tohto problému.

Vo vývojovom prostredí Arduino používame vstavaný monitor COM portov

Toto je najjednoduchšia a najzrozumiteľnejšia metóda pre začiatočníkov.

Monitor COM portu sa spúšťa cez menu Tools\Serial Monitor alebo cez panel nástrojov. V starších verziách softvéru bol monitor dostupný iba cez panel nástrojov: . Pri volaní monitora sa uistite, že je zvolená rovnaká prenosová rýchlosť ako v programe mikrokontroléra. Teraz môžete do vstupného poľa napravo zadať ľubovoľné znaky a stlačiť tlačidlo "Odoslať" - zadané znaky budú odoslané do portu a váš program ich tam prijme. Zadajte tam latinské písmeno "H", stlačte "Odoslať" - rozsvieti sa testovacia LED. Ak pošlete "L" - vypne sa. Mimochodom, všetky údaje, ktoré váš program odošle na COM port, sa zobrazia v okne nižšie.

Pomocou programu na emuláciu terminálu HyperTerminal

Toto je trochu zložitejšia možnosť výmeny na implementáciu.

Windows zvyčajne obsahuje program na emuláciu terminálu s názvom HyperTerminal. V systéme Windows XP ho nájdete v časti Štart\Všetky programy\Programy\Príslušenstvo\Komunikácia\HyperTerminal. Pri spustení musíte odmietnuť vytvorenie pripojenia, vyberte ponuku Súbor \ Vlastnosti. V zobrazenom dialógovom okne vyberte svoj COM port, kliknite na „Konfigurovať“ a nakonfigurujte nastavenia komunikácie podľa obrázka:

Môžete použiť iný emulátor terminálu - všetky majú zvyčajne podobnú funkčnosť a podobné nastavenia.

Kliknite na "OK" v oboch oknách a raz v hlavnom okne programu sa ľubovoľný kláves na klávesnici - HyperTerminal pripojí k portu COM. Teraz všetky znaky napísané na klávesnici idú cez COM port do mikrokontroléra a všetko, čo mikrokontrolér pošle, ide na obrazovku. Stlačte klávesy „H“ a „L“ (sledujte zvolený jazyk a veľkosť písmen) – testovacia LED by sa mala rozsvietiť a zhasnúť.

Poďme si napísať vlastný PC program!

Táto možnosť je pre skutočných nadšencov, ktorí chcú programovať nielen Freeduino, ale aj PC. Prečo nie? Nepotrebujeme sa učiť detaily programovania sériový port pod Windowsom, alebo nejaké iné komplikované veci. Špeciálne na riešenie takýchto jednoduchých úloh je tu Processing language (http://processing.org), ktorý je syntaxou a dokonca aj vývojovým prostredím veľmi podobný softvéru Arduino.

Nainštalujte a spustite Processing – Uvidíte vývojové prostredie podobné Arduinu.

Zdrojový kód pre jazyk Processing je v komentároch pod hlavným textom príkladu Fyzického pixelu. Tu je to s minimálnymi zmenami - opravili sme otvor portu, aby ste mohli ľahko nahradiť jeho číslo:

import spracovanie.seriál.* ;
sériový port;
void setup()
{
veľkosť(200, 200);
noStroke() ;
frameRate(10) ;
port = new Serial(toto , "COM5" , 9600 ) ; //!!! Tu zadajte svoj COM port!
}
boolean mouseOverRect() //Vráti hodnotu true, ak je kurzor vo vnútri štvorca
{
return ((mouseX >= 50 ) && (mouseX<= 150 ) && (mouseY >= 50) & (myšY<= 150 ) ) ;
}
void draw()
{
pozadie(#222222 );
if (mouseOverRect() ) // Ak je kurzor vo vnútri štvorca....
{
fill(#BBBBB0) ; // zmena farby na jasnejšiu
port.write("H") ; // odošle "H" do mikrokontroléra
) inak ( // ak nie vo vnútri...
fill(#666660)​; // zmena farby na tmavšiu
port.write("L") ; // odošle "L" do mikrokontroléra
}
rect(50, 50, 100, 100); // nakreslite štvorec
}

Spustite program (cez menu Sketch \ Run) - objaví sa okno so štvorcom, keď doň umiestnite kurzor myši, rozsvieti sa LED na Freeduine.

Opis jazyka Processing a jeho schopností presahuje rámec tohto jednoduchého príbehu, ale mnohé z príkladov Arduina v komentároch pod telom programu ukazujú Processing PC kód, ktorý interaguje s Freeduino.

Jednoducho je pre neho životne dôležité vymieňať si informácie s mikrokontrolérom. Sú situácie, keď potrebujete manuálne, ovládaním z PC alebo notebooku, aktivovať jednu alebo druhú funkciu v programe mikrokontroléra.

Ale poďme k veci. Výmena dát s Arduinom nie je až taká náročná, no háčik je v tom, že dáta sa prenášajú znak po znaku, čo je veľmi zlé. Hľadaním tohto problému som musel stráviť dosť dlho, kým som nenarazil na jednu nádhernú knižnicu na Habrahabre. Autor v nej implementoval funkciu akceptovania čísel, t.j. do ovládača môžete poslať viac ako jednu číslicu a bude fungovať správne. Stiahnite si knižnicu (odkaz), rozbaľte ju do hardvérových knižníc a prejdime k praxi.

Najprv napíšeme náčrt a nahráme ho do Arduina (Freeduino)

#include void setup() (

Serial.begin(9600); // nastavenie rýchlosti portu

PinMode(9, OUTPUT); // nastaviť pin 9 ako výstup reproduktora

) void loop()

Dlhé intNumber; Serial.print("Zadajte číslo: ");

Číslo = SerialInput.InputNumber(); // Zadajte číslo Serial.print("Výsledok = ");

Serial.println(Číslo * Číslo, DEC);

Pípnutie(500);

} void pípnutie (nepodpísané znaky oneskorenia)(

analogWrite(9, 20); // hodnota musí byť medzi 0 a 255

// experiment pre dobrý tón

analogWrite(9, 0); // 0 - vypnutie piezo

Oneskorenie (oneskorenia); // pauza oneskorenie ms

Čo to všetko znamená. Snažil som sa poskytnúť kód s podrobnými komentármi, všetko sa zdá byť jasné. Táto skica vás požiada o zadanie ľubovoľného čísla, potom vydá svoj štvorec a prehrá zvukový signál cez piezo reproduktor pripojený na kolík 9.

A teraz to najzaujímavejšie - je čas to vyskúšať. Na prepínanie pomocou ovládača odporúčam použiť bezplatný program tmel. V nastaveniach Connection type vyberte Serial a zadajte správne číslo portu namiesto COM1 (môžete nahliadnuť do programovacieho prostredia Arduino v menu Tools->Serial Port). Stlačíme Open a v konzole sa zobrazí nápis Zadajte číslo, zadáme ľubovoľné číslo (v rozumnom rozsahu), stlačíme Enter a vidíme výsledok.

Všetko, môžete sa radovať a skákať od radosti. Prirodzene, toto všetko sa dá vylepšiť, napríklad najprv zobraziť menu na odoslanie z ovládača do konzoly, v ktorom podrobne popíšete príkazy. Zadajte napríklad číslo 0 – zapne sa LED svetlá, stlačte 1 - zhasne. Takto môžete vložiť aspoň 100 500 príkazov, ak je len dostatok pamäte mikrokontroléra (ktorá je taká malá). A o tom, ako rozšíriť dostupnú pamäť, si povieme nabudúce.

UPD: časť kódu bola vystrihnutá analyzátorom motora, takže tu je zdroj

Ako mnoho iných domácich majstrov, aj ja pravidelne používam mikrokontroléry AVR na najrôznejšie amatérske remeslá. A vďaka konceptu „Arduino“ teraz tieto remeslá nadobúdajú elegantný vzhľad. Vskutku, za približne 300 - 400 rubľov dostaneme miniatúrnu viacvrstvovú dosku s maskou, sieťotlačou a s kompletne zapojenými perifériami pre mikrokontrolér (a vo verzii SMD!). Nehovorím o najrôznejších zásuvných moduloch rovnakej série „Arduino“: senzory, ovládače, displeje a celé sady prídavných periférií, ktoré tak veľmi potrebujeme. A opäť, všetko je tiež lacné a vo vynikajúcom výkone. Prakticky nie je potrebné niečo riediť a spájkovať na „koleno“.

Ale všetky tieto rôzne amatérske remeslá si prirodzene vyžadujú, predprogramovanie. A v budúcnosti, s rôznymi vylepšeniami, tieto remeslá neustále musia reflash. Je jasné, že je pohodlnejšie to robiť na diaľku, ako ich neustále ťahať ku konvenčnému programátorovi. Vo všeobecnosti je tu vďaka rovnakej platforme Arduino veľa možností: Bluetooth, ZigBee, rádiový kanál s vaším osobným protokolom, IR a dokonca aj Wi-Fi. Všetky vám umožňujú nadviazať bezdrôtový kontakt s vaším mikrokontrolérom. My sa však zameriame na poslednú možnosť. Tu sú štyri hlavné dôvody:

1: moderný, internet vecí!

2: bezdrôtový router k dispozícii v každom apartmáne, zaregistrujte sa na domácej siete vaše zariadenia a voila!

3: vaše remeslá robia revolučný skok vo svojom vývoji; nielenže môžu byť naprogramované na diaľku, ale teraz môžu tiež komunikovať s okolitým svetom: Digitálne hodinky nezávisle vziať presný čas z hodinových NTP serverov sú výkonné zariadenia ovládané z druhej strany mesta alebo krajiny, registračné zariadenia ukladajú nahromadené dáta do cloudu atď. atď.

4: Existuje nádherná séria čipov ESP8266, na ktorých nie je veľmi jednoduché toto všetko implementovať.

Ďalej v tomto článku na príklade mechanického ramena na servách, diaľkové programovanie a výmena dát z PC (alebo čohokoľvek) so zariadeniami založenými na mikrokontroléry AVR. Chcem hneď poznamenať, že všetky programy uvedené nižšie sú čisto demonštračné a nemajú žiadnu komerčnú hodnotu. Preto tvrdenia, ako napríklad prečo je programátor taký kastrovaný a málo funkčný, alebo prečo nie sú všade dostupné doplnkové služby, nie sú akceptované. Keďže kódy sú otvorené, každý si ich môže dokončiť podľa svojho uváženia, no pre mňa je ich stále dosť na prácu.

Predpokladá sa, že čitateľ už pozná moduly (štíty) „Arduino“ a pripojenie a firmvér ESP8266. V skutočnosti bolo na webe zverejnené obrovské množstvo materiálov vysvetľujúcich základy práce s týmito zariadeniami a nerád by som sa tu opakoval. Pre začiatočníkov je na konci článku zoznam. užitočné odkazy o týchto otázkach, kde nájdete množstvo informácií, prečo vám to celé nefunguje. Z mojej skúsenosti bývalého elektrotechnického inžiniera môžem zodpovedne prehlásiť, že 99% problémov sa týka týchto problémov:

1. Zlé kontakty. Keďže štíty „Arduino“ znamenajú vzájomné prepínanie cez drôty typu „otec-matka“, a nie cez spájkovanie, veľmi často niekde niečo, ale odchádza. Skontrolujte. A vo všeobecnosti, ako sa hovorí, elektronika je veda o kontaktoch.

2. Problémy s výživou. Nenapájajte 5 voltov tam, kde sa vyžaduje 3,3. Z ESP8266 niekedy vychádza dym. Aj keď na druhej strane bez problémov strávi logické signály z päťvoltových zariadení.

3. Problémy s dostatočným napájaním. ESP8266 má priemernú povahu a niekedy dokáže čerpať takmer tristo miliampérov, hoci predtým sa mohol uspokojiť s tridsiatimi. Podľa toho krehký 3,3 voltový stabilizátor dosky Arduino, ku ktorému ste ho bez váhania pripojili, okamžite klesá na mikroskopické hodnoty. A nemôžete pochopiť, prečo to funguje alebo nie.

4. Zmätok so závermi. Vždy skontrolujte, ktoré signály kam smerujú. Prijímač RXD musí byť pripojený k vysielaču TXD, ako aj TXD k RXD, ale MOSI musí byť pripojený k MOSI, MISO k MISO atď.

5. Nespoliehajte sa na vyťahovacie odpory ESP8266 v obvode, vždy vytiahnite kolíky na nulu alebo výkon, cez 5-10 kiloohmové externé odpory, nielen prepojku. V opačnom prípade môžete v najlepšom prípade získať bezprecedentnú spotrebu prúdu a potom cítiť nepríjemný zápach spáleného plastu.

6. Burina softvér. Keďže softvér pre jednotlivých používateľov píšu tí istí nadšenci, pri aktualizácii verzií rovnakého firmvéru sa pravidelne objavujú chyby samotného firmvéru a chyby. Lieči sa to preliezaním príslušných fór, niekedy aj v angličtine. Niektorí súdruhovia dokonca tvrdili, že samotný ESP čip je vlhký ako počasie v Petrohrade, no na druhej strane existuje aj názor, že od roku 2014 (rok jeho prvého vydania) sa situácia dramaticky zlepšila (na rozdiel od počasie).

7. Záhadné závady. Ide o zriedkavý, ale nervy náročný jav. Napríklad som nemal jedno „Arduino“ zariadenie ušité na diaľku. Skôr to bolo ušité, ale s chybami. Ale bol ušitý bez chýb, ak na ňom visel kábel od programátora (ale bez samotného programátora). "YAH," povedal som si a prispájkoval som 15 pF kondenzátor medzi vysielací kolík a hodinový kolík. Všetko fungovalo. Ale zabil deň.

Začnime teda tým najjednoduchším. Máme mechanickú končatinu MechArm (ale nie tú, ktorú vyrobil Howard Wolowits) vyrobenú v Číne a Osobný počítač so systémom Windows. Úlohou je vzdialene flashovať program a spravovať ho z počítača.


Na ovládací ovládač si vezmite peknú miniatúrnu šatku Arduino Nano s kameňom ATmega328P. Táto doska dokonale zapadá do mechanického ramena.


Teraz sa rozhodneme, ako to naprogramujeme. Pre vzdialený firmvér sú najvhodnejšie tri hlavné metódy: cez rozhranie SPI, cez vstavaný bootloader, cez port JTAG.

Najjednoduchšou možnosťou je samozrejme vstavaný bootloader (bootloader). Ide o pamäť vopred napísanú vo FLASH, program, ktorý prijíma kód pomocou určitého protokolu (napríklad pomocou najjednoduchšieho UART) a zapisuje ho špeciálnymi príkazmi na miesto sťahovaného programu. Takto funguje napríklad samotný bootloader ARDUINO IDE. Po resete alebo štarte loader nejaký čas čaká na príjem dát a ak nečaká, začne vykonávať program od adresy nula. Ak prídu dáta, zapíše ich do programovej časti. Po ďalšom resete sa spustí načítaný program. V detailoch som to možno opísal nepresne, ale podstata je presne taká. Výsledkom je, že na programovanie potrebujeme iba tri piny: RTD prijímač, RESET a GND. Vo všeobecnosti sa na overenie nahraného programu používa aj vysielač TRD, ale pri jednoduchých demonštračných aplikáciách (nie pre jadrovú elektráreň) možno overenie vynechať.

Samotný bootloader je napísaný v assembleri, v datasheetoch AVR sú príklady jednoduchých bootloaderov. Existujúci bootloader môžete odhaliť, ak je v ňom otvorený prístup a stačí ho použiť v hotovej podobe, ak je známy protokol, na ktorom to funguje. Jedinou výhradou je, že na to musíte nakonfigurovať AVR v špeciálnom režime blikaním špeciálnych poistkových bitov, ktoré vykonáva obyčajný programátor, a potom všiť bootloader do pamäte mikrokontroléra (to znamená, že stále nemôžete raz sa zaobísť bez programátora).

Druhou možnosťou je programovanie sériové rozhranie SPI. Nie je tu žiadny interný bootloader, ale programujeme posielaním špeciálnych príkazov a následne dát cez spomínané rozhranie. Tu máme externý bootloader, ale musíme ho ešte napísať. Pri prenose sa okrem RESET a GND využívajú štyri prídavné výstupy MOSI, MISO - dáta, synchronizácia SLK, CS - výber kryštálov. Vo všeobecnosti však môžete odstrániť aj MISO a CS. Dáta budú iba prijímané (potom nedôjde k overeniu programu) a aj tak máme len jeden kryštál.

Každý prístup má svoje pre a proti (a to som JTAG vôbec nezvažoval, keďže ľudský život je krátky). Ale nakoniec som sa priklonil k SPI, pretože som bol príliš lenivý písať v assembleri a nenašiel som otvorené hotové nakladače (len som nevyzeral dobre).

Na stavbu bezdrôtový kanál Ja som, ako už bolo spomenuté, zvolil v súčasnosti mimoriadne známy čip ESP8266 - mikrokontrolér, respektíve celý SoC (System-on-Chip) od čínskeho výrobcu Espressif s Wi-Fi rozhraním. Okrem Wi-Fi sa vyznačuje schopnosťou spúšťať programy z externej flash pamäte. A špeciálne pre môj projekt som vzal ESP8266-07 s 512 KB pamäte na palube.


Vo všeobecnosti je vhodný akýkoľvek ESP8266, kde sú ďalšie nohy na implementáciu SPI. Preto nám najjednoduchšie ESP8266-01 nebude vyhovovať, pretože má veľmi málo nôh pre I / O porty. Ale na druhej strane je rozdiel v cene za ne menej ako sto rubľov a sú rovnako dostupné. No a veľké ladiace dosky s ESP, kde je pre pohodlie rozvedených kopa periférií, sa nám tiež nehodia, keďže sa nám nehodia tam, kde ich chceme strčiť do mechanickej ruky.

Globálna podstata myšlienky vo všeobecnosti bola nasledovná. Z počítača do ESP sa telo programu načítaného do mikrokontroléra prenáša bezdrôtovo cez WI-FI (v rámci vašej domácej siete). A ESP už po drôte pomocou rozhrania SPI zapisuje tento program priamo do FLASH pamäte mikrokontroléra. Potom ho prirodzene resetuje a umožní spustenie načítaného programu. ESP musí mať navyše samostatnú jednotku, ktorá riadi aj výmenu dát s mikrokontrolérom, keďže s ním chceme nielen programovať, ale aj vymieňať dáta. Špeciálne pre projekt MechArm po nahratí programu vysielame aj signály ovládania serva, aby sme toto rameno uviedli do pohybu. Preto je na samotnom ESP žiaduce, aby sme zvýšili TCP server na prenos programu a UDP servera na ovládanie MechArm. V súlade s tým sa tieto servery pripájajú k domácej sieti a pozorne počúvajú, či niekto chce nahrať nový kód do MechaArm alebo s ním niekomu zamávať.

Na webe som teda našiel, že firmvér vám už umožňuje vyrábať Programovanie AVR letecky, ale tam je hlavný problém, že na čo iné sa už tento firmware nedá použiť. A chceli by sme po naprogramovaní komunikovať s AVR aj na diaľku.

Aký softvér budeme používať:

Pre PC som všetko napísal v JAVA, prostredí IntelliJ IDEA. Ale v zásade sa dá použiť čokoľvek, pre nás je hlavné napísať klienta, pre ktorý pošle program Firmvér AVR na ESP8266.

Programy pre AVR píšem v ATMEL STUDIO, v C, zriedka v assembleri. V zásade nepoužívam náčrty Arduina, takmer každá potrebná knižnica je napísaná za ďalšiu hodinu a s úplným pochopením jej práce. Skúšal som skice, ale zatiaľ to na AVR nemáte operačný systém, budú skice naďalej odoberať periférne zariadenia od priateľa a pravidelne zlyhávajú. Áno, samotné Arduino IDE je v porovnaní s ATMEL STUDIO samozrejme veľmi primitívna vec. Ale tu je otázka, samozrejme, diskutabilná, pre humanitných vied a školákov to bude pravdepodobnejšie a jednoduchšie s náčrtmi.

Na programovanie ESP8266 som použil firmvér NodeMCU a programy som napísal v jazyku Lua. Nie, rád by som písal v jazyku Java a C, ale v ESP žiadne nie sú. Jazyk Lua v aplikácii na našu úlohu nie je náročný, jeho zvládnutie je pár maličkostí. A vlastne, aby som stiahol programy a ladil ich na ESP, vzal som IDE ESPlorer. Domáce bezplatný produkt(ale môžete prispieť autorovi), čo sa samozrejme nedá porovnať s prostrediami uvedenými vyššie, ale ako sa hovorí o darčekovom koňovi ... Ale aby sme mohli používať ESPlorer a písať v LUA, musíme najprv zmeniť základný firmvér (dodaný od výrobcu) v čipe ESP8266 na nový. V tomto podniku nám pomôže program NODE MCU PyFlasher. V istom zmysle to pomôže preflashovať. A samotný firmware vytvoríme a dostaneme ho do rúk na stránke tvorcov: NodeMCU. A o tomto procese si môžete prečítať viac

Všetko je veľmi prístupné a zrozumiteľné. Do základných knižníc pridávame podporu SPI a bitové operácie (v LUA sú v našom prípade bitové operácie preťažené a málo použiteľné). Nemali by ste do firmvéru strkať veľa knižníc, pretože kvôli prítomnosti všemožného softvéru zostáva na ESP8266 veľmi málo pamäte, nejakých mizerných 20 kB.

Samozrejme, môžete si vziať hotový firmvér, ktorého už na internete visí veľa, ale neodporúčam to. Už len preto, že niektoré nepodporujú bitové operácie (a my ich potrebujeme) a neexistuje regulácia rýchlosti prenosu dát cez SPI.
V súlade s tým sa štandardne prenášajú rýchlosťou 40 MHz delenou malým koeficientom, a preto ich AVR nestihne stráviť.

Ak ste príliš leniví na vytvorenie firmvéru, môžete si stiahnuť môj z cloudu.

Teraz máme firmvér a musíme ho nahrať do ESP8266 namiesto základného. Na to potrebujeme jednoduchý adaptér USB-UART.


Pripojíme nohy TXD k RXD a RXD k TXD, vytvoríme spoločnú zem, ale nepoužívame, ako sa zdalo, pohodlný výstup 3,3 V na adaptéri. Vo väčšine prípadov to ESP8266 úplne premrhá. Preto sa na to pýtame osobitne. Potom dáme ESP do programovacieho režimu (GP0 do zeme, ak by niekto zabudol) a spustíme NODE MCU PyFlasher.

Hlavne nezabudnite vymazať flash pamäť (áno, vymaže všetky dáta), inak v závislosti od verzie firmvéru môže po naprogramovaní zostať v pamäti zbytočný odpad, ktorý zase pri ďalšej práci vysype odpadky do konzoly. Predtym som pouzival softver kde nebola moznost vopred vymazat pamat, strasne som trpel, kedze nic nefungovalo. A práve sa otvorila rakva, len pravda je na anglickom fóre tvorcov NODE MCU.

Zaimev požadovaný firmvér teraz môžeme písať a ladiť programy v jazyku LUA (existuje aj MicroPython, ale ja som ho nepoužíval) pomocou veľmi pohodlných API z NODE MCU. Spúšťame už spomínaný ESPlorer.

Nakonfigurujeme ho aj na prácu s ESP8266, nastavíme parametre sériové pripojenie. Všetko je celkom jednoduché a opakovane uvedené na internete.

Teraz píšeme program v LUA, ktorý potom nahráme do ESP8266:

Bootloader Lua pre AVR zapísaný do ESP8266

funkcia InstrProgrammingEnable () -- inštrukcia pre MC "povoliť programovanie" p=0, zatiaľ čo p<31 do p=p+1 pin=8 gpio.write(pin, gpio.LOW) spi.send(1, 0xAC,0x53) read = spi.recv(1, 8) spi.send(1,0,0) gpio.write(pin, gpio.HIGH) if (string.byte(read)== 83) then print("connection established") p=33 if(p==31) then print("no connection") end end end end functionProgrammingDisable() pin=2--KONIEC ESETU PRE MK gpio.mode(pin, gpio.INPUT) pin=8 gpio.mode(pin, gpio.INPUT) pin=5--CLK MASTER pre SPI gpio.mode(pin, gpio. INPUT) pin=6--MISO MASTER pre SPI gpio.mode(pin, gpio.INPUT) pin=7--MOSI MASTER pre SPI gpio.mode(pin, gpio.INPUT) koniec funkcia ProgrammingEnable() pin=2-- RESET PRE MK gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.LOW) pin=2--POZITIV NA 4MSEC RESET PRE MK gpio.mode(pin, gpio.OUTPUT) gpio .write(pin, gpio.HIGH) tmr.delay(4) gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.LOW) tmr.delay(25000) end funkcia InstrFlashErase() pin=8 gpio.write(pin, gpio.LOW) spi.send(1,0xAC,0x80,0,0) gpio.write(pin, gpio.HIGH) tmr.delay(15000) pin=2--RESET PRE MK gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.HIGH) tmr.delay(20000) gpio.write(pin, gpio.LOW) print("FLASH je vymazaný") InstrProgrammingEnable () end funkcia InstrStorePAGE(H, adresa, údaje) pin=8 gpio.write(pin, gpio.LOW) spi.send(1,H,0,adresa,data) gpio.write(pin, gpio.HIGH) tmr.delay(500) end funkcia InstrWriteFLASH(adresa_stránky_nízka,_vysoká_adresa_stránky) pin=8 gpio.write(pin, gpio.LOW) spi.send(1,0x4C,page_address_high,page_address_low,0) gpio.write(pin, gpio.HIGH) tmr.delay(5000)-- niekedy sa flash nezapíše keď končia krátke oneskorenia funkcia Programovanie (užitočné zaťaženie) pin=8--CS MASTER pre SPI gpio.mode(pin, gpio.OUTPUT, gpio.PULLUP) pin=4--LED SVIETI NÍZKE gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio. LOW) print(string.len(payload)) page_count = 7 -- napíšte 1 kilobajt pre k =0 ,page_count ,1 do--množstvo strán pre i=0 , 127, 2 do-- -1 adresa = i/ 2 data=payload:byte(i+1+128*k) if data == nil then data = 0xff end InstrStorePAGE(0x40,address,data) -- tmr.delay(100)-- inak nie včas zapisovať dáta = payload:byte(i+1+1+128*k) if data == nil then data = 0xff end InstrStorePAGE(0x48,address,data) -- tmr.delay(100) end page_address_low=bit.band(k ,3 )*64 -- 3 je binárne 11 page_address_high=k/4+frame1024*2 tmr.delay(1000) InstrWriteFLASH(page_address_low,page_address_high) tmr.wdclr() end pin=4--LED gpio.mode. OUTPUT) gpio.write(pin, gpio.HIGH) koniec --HLAVNÝ BLOK wifi.setmode(wifi.STATION) --wifi.sta.config("názov siete","heslo") -- nastavenie SSID a hesla vášho prístupového bodu station_cfg=() tmr.delay(30000) station_cfg.ssid=" názov siete" tmr.delay(30000) station_cfg.pwd="heslo" tmr.delay(30000) wifi.sta.config(station_cfg) tmr.delay(30000) wifi.sta.connect() tmr.delay(1000000) print (wifi.sta.status()) print(wifi.sta.getip()) while (wifi.sta.status()~=1) do if(wifi.sta.status()==5) then break end end sv=net.createServer(net.TCP,30) tmr.delay(100) print("SERVER PRIPRAVENÝ") sv:počúvať(4000,funkcia(c) c:on("prijímať", funkcia(c, užitočné zaťaženie) tlač (payload) if (payload =="program\r\n") then c:send("pripraveny\r\n") print("pripraveny na program\r\n") spi.setup(1, spi.MASTER , spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8,320,spi.FULLDUPLEX) ProgrammingEnable () tmr.delay(100) InstrProgrammingEnable () tmr.delay(100) InstrFlashErase() tmr.delay=040) frame10 -počet odoslaných rámcov st=net.createServer(net.TCP,30) st:listen(4001,function(c) c:on("prijať" , function(c, payload) tmr.wdclr() Programovanie (užitočné zaťaženie) frame1024=frame1024+1 end) end) end if (payload =="data\r\n") then c:send("pripravené\r\n ") print("pripravené na dáta\r\n") srv=net.createServer(net.UDP) tmr.delay(1000) pin=10 gpio.write(pin, gpio.HIGH) uart.setup(0,9600 ,8 ,0,1,0) srv:listen(5000) srv:on("prijať", funkcia(srv, pl) pl=pl*1 --print(pl) uart.write(0,pl) tmr. wdclr( ) end) end if (payload =="stop\r\n") then if(st~=nula) then st:close() frame1024=0 ProgrammingDisable () print("stop program") end if(srv ~= nil) then srv:close() print("zastaviť údaje") end end end) end) end)


Kde zodpovedajúce funkcie robia nasledovné:

funkcia InstrProgrammingEnable()- uvedie mikrokontrolér do programovacieho režimu špeciálnym príkazom odoslaným cez SPI.

funkcia ProgrammingEnable()– pred programovaním stačí resetovať AVR na 25 ms

functionProgrammingDisable()- po naprogramovaní prevedieme piny SPI v ESP8266 do neaktívneho stavu, aby nám neprekážali pri vykonávaní kódu na mikrokontroléri (tam sú zrazu použité)

funkcia InstrFlashErase()- pred spustením programovania prepíšte flash pamäť na mikrokontroléri. Prečo to treba vysvetľovať, nie je potrebné.

funkcia InstrStorePAGE(H, adresa, údaje)- týmto príkazom sa zapíše programový bajt do vnútornej vyrovnávacej pamäte mikrokontroléra. Toto však nie je samotný flash záznam, pretože flash je tu zapísaný po 128 bajtoch.

funkcia InstrWriteFLASH(adresa_stránky_nízka,_vysoká_adresa_stránky)- ale toto je bleskový záznam a chce to čas, pozor na časové oneskorenie 5000 µs.

funkcia Programovanie (užitočné zaťaženie)- najväčšia a najdôležitejšia funkcia využívajúca vyššie uvedené funkcie. Prenášaný program vezme na kúsky s veľkosťou 1024 bajtov, rozdelí ich na bajty a vytvorí pre ne adresy a potom ich odošle do mikrokontroléra vo vnútornej vyrovnávacej pamäti a každých 128 bajtov inicializuje flash záznam. Potom vezme ďalší kilobajt kódu a zopakuje operáciu, samozrejme s posunom v adresách, aby písal ďalej a neprepísal to, čo bolo napísané. Najprv som skúšal posielať celé programy, no ak ESP8266 presiahne 6 kilobajtov, dostupná pamäť jednoducho skončí a spadne. Jeden kilobajt sa ukázal ako najvýhodnejšia jednotka, pretože je prehľadne rozdelený na časti a pohodlne prenášaný cez TCP (musíme ho ešte získať z počítača). Väčšia veľkosť tiež nie je potrebná, TCP, viete, v súčasnej verzii obmedzuje prenášaný paket na 1500 bajtov alebo tak niečo (ale z nejakého dôvodu som prenášal 1440).

Akokoľvek ťažké, no bolo treba prekonať niekoľko nástrah.

Registrujeme sa v bezdrôtovej sieti.

Najprv vytvoríme TCP server, ktorý počúva na tri príkazy:

1. „program“ (budeme programovať),

2. „údaje“ (budeme si vymieňať údaje),

3. „stop“ (všetko zastavíme).

Ak programujeme, tak najprv inicializujeme SPI a vytvoríme ďalší TCP server, ktorý chytí dáta (kód flashovaného programu) na kilobajt a volá pre ne programovacie funkcie mikrokontroléra. Chápem, že vytvorenie druhého servera vyzerá hlúpo, ale je to nevyhnutné, pretože lokálne API podporuje vytvorenie iba jedného soketu a príkazy „program“ a „data“ musíme oddeliť od samotných prenášaných údajov, pretože od oka sa nelíšia, sú tu bajty a bajty.

Ak nechceme programovať, ale vymieňať si dáta a posielať ich v našom prípade do mikrokontroléra, tak najprv cez TCP pošleme reťazec „data“. V reakcii na to už bude vytvorený UDP server (pripomínam, že riadime dynamicky mechanickou rukou a nepotrebujeme oneskorenia pri vytváraní TCP paketov a skutočne posielame jeden bajt ako celý TCP rámec neslušne ). A datagramy UDP budú malé a budú sa vytvárať rýchlo.

Potom sa UART inicializuje a každý bezdrôtovo prijatý bajt je odoslaný cez TXD vodič do mikrokontroléra, ktorý je povinný ho akceptovať, ak tam bliká príslušný program. Taktiež nie je ťažké zorganizovať výmenu dát opačným smerom, ale zatiaľ som to neimplementoval.

No a na príkaz „stop“ vyššie uvedené servery (okrem prvého) uzavrú spojenia a najdôležitejší server sa opäť dostane do stavu čakania na príkazy „program“ a „data“.

Keďže rozhranie SPI je v ESP8266 programovo emulované, môžete použiť akékoľvek I/O porty pre CS, CLK, MISO, MOSI, RESET signály (pre AVR) dostupné, a nie tie, ktoré sú uvedené v mojom bootloaderi. Navyše sa ukázalo, že CS a MISO sa v zásade dajú v tomto prípade aj odrezať, pôjde to aj bez nich. No a jeden výstup slúži na LED zabudovanú do dosky ESP8266, takže občas zabliká a ukáže, že program stále žije.

Neexistujú žiadne kontroly chýb pri zápise (s výnimkou prvej požiadavky na AVR, ale táto informácia sa jednoducho zobrazí na konzole), EEPROM nie je naprogramovaná, viac ako 32 KB nie je šitých - skrátka stále je niečo pracovať na. Výmenný kurz cez SPI je približne 115 Kbps, všetko sa preblikne za pár sekúnd, približne ako bežný sériový programátor ako ISP500).

Vezmite kód, zadajte svoje siete a heslá, skompilujte ho na ESplorer, nazvite ho „init“ (na spustenie pri reštarte) a pošlite ho do ESP8266. Malo by fungovať. Minimálne v zmysle práce ako bezdrôtový programátor.

Teraz sa budeme zaoberať ovládacou stránkou – osobným počítačom.

V skutočnosti musíme zobrať HEX súbor, na ktorý sa premenia vaše programy napísané v prostredí ATMEL STUDIO a poslať ho cez WI-FI do nám známeho socket portu (v tomto prípade 4000). Malý háčik je v tom, že na odoslanie potrebujeme binárny BIN súbor a ATMEL STUDIO nás poteší iba HEX. Sú tu dva východy; alebo ho preveďte do formátu BIN pomocou špeciálneho konvertorového programu, ako je WinHex, alebo to urobte sami vo svojom programe. Zatiaľ som to neurobil, ale zdá sa, že to nie je ťažké, musíte odstrihnúť názov a urobiť niečo iné.

V dôsledku toho som napísal program zavádzača v JAVA (hlavne preto, že neviem, ako robiť nič iné), pracujúci v jednoducho krásnom a bezplatnom prostredí IntelliJ IDEA. Vytvára klienta TCP, ktorý hľadá server spustený na ESP8266. Ak ho nájde, kontaktuje ho a pošle mu súbor umiestnený na takej a takej adrese. Kód nižšie.

Nahrávač súborov JAVA spustený na strane počítača

import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.List; verejná trieda Net( public static void main (String args) ( new Http_client(4000); )) class Http_client rozširuje vlákno ( int port; String s; String Greetings_from_S; Http_client(int port)( this.port = port; start(); ) public void run() ( //192.168.1.113 je adresa ESP8266 v mojej sieti Ale vo všeobecnosti sa to učí z komunikácie s routerom // je lepšie to urobiť staticky, routery to môžu urobiť (Socket socket = new Socket("192.168.1.113", port)) ( PrintWriter pw = new PrintWriter( new OutputStreamWriter(socket.getOutputStream( )),true); pw.println("program");// Zdravíme SERVER System.out.println("program"); ​​​​BufferedReader br = new BufferedReader(new InputStreamReader(socket) .getInputStream())); Greetings_from_S = br.readLine(); System.out.println(Greetings_from_S); if(Greetings_from_S.equals("pripravené")) ( skúste ( Súbor súboru = nový Súbor("d:BlinkOUT.bin ");// adresa súboru na nahranie BufferedInputStream bis = new BufferedInputStream(new FileInputStream(súbor)); byte data = nový bajt; bis.read(data); byte data_buffer = nový bajt; int frames = data.length/1024 ; Systém m.out.println(frames); int bydlisko = data.length%1024; pre (int i = 0; i< frames;i++) { for (int k = 0; k< (1024); k++) { data_buffer[k] = data; } sendingChunk(data_buffer); } byte data_buffer2= new byte; for (int i = 0; i < residy;i++) { data_buffer2[i] = data; } sendingChunk(data_buffer2); pw.println("stop");// System.out.println("stop program"); } catch (Exception e) { System.out.println(e); } } } catch (Exception e) { System.out.println(e); } } public void sendingChunk (byte data_buffer){ try (Socket socket = new Socket("192.168.1.113", 4001)){ BufferedOutputStream bos = new BufferedOutputStream((socket.getOutputStream())); bos.write(data_buffer); bos.flush(); System.out.println(data_buffer.length); } catch (Exception e) { System.out.println(e); } } }


Tu sa, samozrejme, navíjajú nadbytočné veci, všetky druhy pripravené v zásade nie sú potrebné. Ak sa vytvorí spojenie TCP, potom sa vytvorí. Jediným problémom bolo, že súbor sa nechcel odosielať v párnych kúskoch 1024 bajtov, ako som skutočne potreboval, hoci som veľkosť výslovne uviedol. Zjavne je z JAVA neprístupný nejaký finálny buffer a ten posiela pakety v takej veľkosti, akú chce, čo je pre prijímajúcu stranu úplne neprijateľné. Najprv som sa snažil urobiť oneskorenie, aby sa buffer omrzel čakať na ďalšie kusy a poslal to tak, ako to je. Oneskorenie ale začalo fungovať, keď dosiahlo 10 sekúnd, čo sa mi na jeden prenesený kilobajt zdalo akosi priveľa.

Potom som si však všimol, že z nejakého dôvodu vždy prvý kus vyjde presne podľa objednávky a od druhého začína nepredvídateľná bakchanália. Preto som to urobil tak, že klient otvoril spojenie, poslal časť kódu v 1024 bajtoch a spojenie zatvoril. A tak ďalej, kým sa neodošle celý súbor. Všetko úspešne fungovalo.

Jediná vec je, že na spustenie musíte nainštalovať runtime prostredie JAVA na váš počítač. Ale zvyčajne začínam okamžite od IntelliJ IDEA, pretože tam vždy vidíte, čo sa deje v konzole (tu je však potrebné aj prostredie JAVA). Aj keď, samozrejme, musíte urobiť GUI inteligentným spôsobom. Teda okno, kde vypadne cesta k súboru, možnosť zmeniť čísla portov v tom istom okne a dobre, a ďalšie potrebné veci. A toto všetko zbierajte vo forme spustiteľného súboru.

A tapericha, ako hovorieval Koroviev, vráťme občanov vlastne k mechanickej končatine MechArmu, o ktorej sa hovorilo na samom začiatku. Teraz máme možnosť ho na diaľku naprogramovať a následne ovládať. Prejdime k ovládaciemu programu na strane mikrokontroléra.

V tomto prípade potrebujeme ovládať štyri servá. Toto sú.


Takýto pohon je riadený pravouhlými impulzmi, perióda 20 ms (50 Hz) s pracovným cyklom 2 až 4 percentá. To znamená, že 2% je úplný obrat v jednom smere, 4% v druhom. Úloha je len pre vstavané PWM v AVR.

Jedno servo sa používa na pohyb vpravo-vľavo; druhý na seba - od seba; tretí hore-dole; štvrtý je samotný pazúr, ktorý musí byť stlačený a uvoľnený. Všetko je napísané v C a skompilované do HEX súboru v ATMEL STUDIO. Trochu zvláštny vzhľad programu je spôsobený tým, že spočiatku bola ruka ovládaná z klávesnice priviazanej drôtmi k mikrokontroléru. Ale drôty sú včera, musíme sa vyvíjať ďalej.

Samozrejme môžete použiť skice pre servá od "ARDUINO", ale nepáčili sa mi. Je zábavnejšie písať sám. Okrem toho musia všetky štyri servá pracovať súčasne a nie v multiplexnom režime, keď sa PWM postupne prepína na každé servo. Nikto totiž nezrušil gravitáciu a zdvihnutá končatina okamžite spadne, ak riadiace impulzy prestanú prijímať riadiace impulzy do príslušného serva. Nie som si istý, či náčrt "ARDUINO" poskytuje súčasnú prevádzku štyroch serv. Ale my sami dokážeme napísať program, ktorý spĺňa potrebné požiadavky. A vo všeobecnosti, pri absencii operačného systému, ktorý oddeľuje ovce od kôz, je použitie náčrtov súťažiacich o periférie mikrokontrolérov (a ani vopred nevieme o ktoré) príliš bug-produkujúce.

Tu je skutočný kód, ktorý zapisujeme do Arduino Nano pomocou ESP8266-07.

Riadiaci program MechArm pre mikrokontrolér AVRmega328P

#define F_CPU 16000000 #include #include // štandardné celé čísla #include #include // matematika #include //štandardné I/O #include #include #include //štandardné funkcie #define UART_BAUD_RATE 115200 // počítadlo T1 nastaví časový interval 20ms #define COUNTER1_OFF TCCR1B=0b00000000 // CS02 CS01 CS00 - 000 - vypnuté; 001 bez rozdeľovača; 010 s deliteľom 8; 011-64; 100 - 256; 101 -1024 #define COUNTER1_ON TCCR1B=0b00000011 // počítadlo T0 nastavuje šírku riadiaceho impulzu pre servá PB0 a PB1 #define COUNTER0_OFF TCCR0B=0b00000000 // CS02 CS01 CS00 - 000 - vypnuté 001 bez rozdeľovača; 010 s deliteľom 8; 011-64; 100 - 256; 101 -1024 #define COUNTER0_ON TCCR0B=0b00000100 // počítadlo T2 nastavuje šírku riadiaceho impulzu pre servá РB2(PD6) a РВ3(PD7) #define COUNTER2_OFF TCCR2B=0b000/000001 CS001 vypnuté; 001 bez rozdeľovača; 010 s deliteľom 8; 011-64; 100 - 256; 101 -1024 #define COUNTER2_ON TCCR2B=0b00000110 volatile uint16_t period_20ms; volatile uint8_t State_of_keyboard; volatile uint8_t zaciatocna_poloha ; volatile int8_t cislo_servo; ISR(USART_RX_vect)// prerušenie pre UART ( State_of_keyboard=UDR0; return; ) ISR(TIMER0_COMPA_vect)// šírka impulzu serva PB0 ( PORTB &=~(1<<0); TIMSK0&=~(1<
Podstata programu je zrejmá z textu a komentárov. Počítadlo T1 používame na referenčnú periódu 20 ms a počítadlá T0, T2 na vysielanie signálov PWM do štyroch liniek vstupno-výstupného portu, pretože každý z týchto dvoch počítadiel môže pracovať pre dve zariadenia.
Program nastaví počiatočné polohy serv načítaním počítacích registrov OCR0A, OCR0B, OCR2A, OCR2B. Zavedené sú aj obmedzujúce konštanty, pretože nie vždy potrebujeme rozpätie 180 stupňov. No, ďalej, prerušením z UART, program zachytí číslo odoslané ESP8266 (od 1 do 8) a preloží ho na príkaz pre príslušné servo. K dispozícii sú štyri jednotky, z ktorých každá pracuje v dvoch smeroch, takže stačia celé čísla od jednej do ôsmich. Po výbere čísla sa obsah vyššie uvedených registrov počítadla buď zvýši alebo zníži, pričom sa mení pracovný cyklus riadiaceho impulzu a uhol natočenia zvoleného serva. Pohony, ktoré sme nevybrali, si zachovávajú starú hodnotu uhla natočenia (keďže obsah príslušných registrov, aj keď sa aktualizoval, nezmenil) a naďalej držia mechanické rameno v rovnakej polohe.

Teraz už len musíme napísať ovládací program, prepáčte za tautológiu, na ovládanie mechanického ramena priamo z počítača cez WI-FI.
Kód je tiež napísaný v JAVA, ale trochu zušľachtený. K dispozícii bolo grafické používateľské rozhranie a možnosť upravovať čísla portov a sieťovú adresu ESP8266.

Čo sa tam deje, je jasné z okna. Text programu tu neuvádzam (je dostupný na

Mám zariadenie postavené s Arduino uno:

    Softvér Arduino nainštalovaný na Arduino uno

    možno ovládať sériovými príkazmi

    Dá sa ovládať fyzickými tlačidlami a senzormi

    pri zmene ktoréhokoľvek tlačidla/senzora zapíše aktuálny stav do sériového čísla

    Ak sa do 5 sekúnd neodošle žiadna správa, odošle sa sériová správa nezmenená

Čo potrebuješ:

    Použite ESP8266 na vytvorenie mosta medzi aktuálnym softvérom Arduino a MQTT/webom

    Môžem naprogramovať ESP8266 ako webový server, klienta MQTT atď. pomocou Arduino IDE alebo Lua (ale preferujem Arduino IDE, pretože môžem znova použiť časti kódu na generovanie/interpretáciu komunikácie).

    ESP8266 zvládne všetko potrebné pre wifi/web/MQTT; bez MQTT modulu bude Arduino časť fungovať autonómne, chýbať bude len diaľkové ovládanie.

    Chcel by som vykonať minimálne zmeny v kóde Arduina (alebo žiadne, ak je to možné). Akékoľvek zmeny si budú vyžadovať rozsiahle opätovné testovanie, ktorému sa snažím vyhnúť.

    ESP8266 nemusí byť v niektorých inštaláciách k dispozícii.

Aké možnosti som našiel:

    <�Литий>Konzistentné

ESP8266 dokáže čítať sériový výstup a byť mostom medzi sieťou/MQTT a sériovým, uloží aktuálny stav do pamäte, aby sa na požiadanie odoslal, aby sa predišlo zakaždým volaniu zariadenia.

Jednou z výhod je, že pre časť Arduino nie sú potrebné žiadne zmeny/testovanie kódu.

Urobte z Arduina I2C master a ESP8266 slave (alebo naopak) a implementujte obojsmernú komunikáciu. Dostal som tento nápad čítaním tohto vlákna.

Ďalšie informácie o sériových príkazoch:

Dátový paket (príkaz alebo popis stavu) pozostáva z 1-20 znakov s možným vrcholom 20 paketov za 5 sekúnd a priemerne jeden paket každé 3 sekundy. Ak je to potrebné, môžem to dosiahnuť na odoslanie 5 celých čísel bez znamienka namiesto alfanumerických znakov.

Ak je potrebných viac ako I2C/sériové piny, môžem upgradovať na Arduino Mega (takže počet voľných pinov nie je problém).

Sú na to iné možnosti? (protokoly, bežné knižnice pre sériovú komunikáciu atď.). Snažím sa znovu nevynájsť koleso.

Ďakujem za Tvoj čas!

3

1 odpovedí

Väčšina I2C tutoriálov urobila z každého Arduina slave a master, ale je to lepšie, pretože každé Arduino je buď master alebo slave (nie oboje) a nie je potrebné žiadne prepínanie. To všetko uľahčuje.

I2C je lepšie ako sériové, pretože do tej istej zbernice môžete pridať viac Arduin.

Implementoval som I2C medzi dve Arduina a nie je to o nič ťažšie ako čítanie/zápis na sériový port (čo ste už urobili). A som si istý, že môžete zovšeobecniť kód sériového portu tak, aby fungoval so sériovou aj I2C komunikáciou.

Toto je môj príklad (len dôkaz koncepcie). Slave Arduino ovláda niektoré piny, tep. senzor a časovač strážneho psa na objednávku majstra Arduina. Ak slave neprijme bit včas, resetuje Arduino master.

Hlavný kód

#include #define CMD_SENSOR 1 #define CMD_PIN_ON 2 #define CMD_PIN_OFF 3 #define CMD_LUMEN 4 #define CMD_BEAT 5 const byte SLAVE_ADDRESS = 42; const byte LED = 13; tlmič uhlia; void setup() ( Serial.begin(9600); Serial.println("Master"); Wire.begin(); pinMode(LED, OUTPUT); digitalWrite(LED, HIGH); delay(1000); digitalWrite(LED, LOW); Wire.beginTransmission(SLAVE_ADDRESS); Serial.println("Odoslať LED zapnuté"); Wire.write(CMD_PIN_ON); Wire.write(2); Wire.write(10); Wire.endTransmission(); int x = Wire.requestFrom(SLAVE_ADDRESS, 1); Serial.print("status="); Serial.println(x); ) //koniec void slučky nastavenia () ( Serial.println("."); Wire.beginTransmission (SLAVE_ADDRESS); Wire.write(CMD_SENSOR); Wire.endTransmission(); int x = Wire.requestFrom(SLAVE_ADDRESS, 1); Serial.print("Disponibles = "); Serial.println(x); int temp = ( int) Wire.read(); Serial.println(temp); Wire.beginTransmission(SLAVE_ADDRESS); Wire.write(CMD_LUMEN); Wire.endTransmission(); Wire.requestFrom(SLAVE_ADDRESS, 2); int light = Wire.read ()<< 8 | Wire.read(); Serial.print("Light="); Serial.println(light); Wire.beginTransmission (SLAVE_ADDRESS); Wire.write (CMD_BEAT); Wire.endTransmission(); Wire.requestFrom(SLAVE_ADDRESS, 1); delay (5000); } //end of loop

riadený kód

/* Esclavo I2C Recibe los siguientes comandos<- 1° byte -> <- 2° byte -> <- 3° byte ->CMD_SENSOR CMD_PIN_ON č. pinu trvanlivosť a ďalšie CMD_PIN_OFF č. pinu CMD_LUMEN CMD_BEAT Príkaz dostane odpoveď, je morská odvaha a stav. */ #include #include typedef struct ( int pin; unsigned long off; ) PIN_PGMA; /* Lista de pines que se pueden activar cez CMD_PIN_ON. */ #define PIN_LUMEN A0 #define PIN_LED 2 #define PIN_RESET 3 PIN_PGMA pgma = ( (PIN_LED, 0), (PIN_RESET, 0) ); const int pgmaSize = sizeof(pgma)/sizeof(PIN_PGMA); #define CMD_SENSOR 1 #define CMD_PIN_ON 2 #define CMD_PIN_OFF 3 #define CMD_LUMEN 4 #define CMD_BEAT 5 #define ST_OK 0 #define ST_BAD_PIN 1 #define ST_TIME_0 2 #define ST_BAD_PIN_0 2 #define ST_BAD_LENa 2mpo3. Pasado // je aktivované pomocou PIN_RESET. // En milisegundos. #define BEAT_INTERVAL 10000 bez znamienka long lastBeat; // Largo del reset en milisegundos. #define RESET_LENGTH 250 bajtov cmd = 0; stav bajtu = 0; int thermoDO = 11; int thermoCS = 12; int thermoCLK = 13; MAX6675 termočlánok(thermoCLK, thermoCS, thermoDO); void setup () ( Serial.begin(9600); pinMode(PIN_LUMEN, INPUT); analogRead(PIN_LUMEN); for (int i = 0; i< pgmaSize; i++) { pinMode(pgma[i].pin, OUTPUT); digitalWrite(pgma[i].pin, LOW); } lastBeat = millis(); Wire.begin (MY_ADDRESS); Wire.onReceive (receiveCommand); Wire.onRequest (sendAnswer); } void loop() { unsigned long now = millis(); // Baja la linea de RESET si no ha recibido un beat ultimamente. unsigned long diff = now - lastBeat; if (diff >BEAT_INTERVAL) ( resetPin(); ) // Obnovenie zoznamu borovíc a aktualizácií. pre (int i = 0; i< pgmaSize; i++) { if (pgma[i].off >0 && pgma[i].off<= now) { Serial.print("off pin="); Serial.println(pgma[i].pin); pgma[i].off = 0; digitalWrite(pgma[i].pin, LOW); } } } // called by interrupt service routine when outgoing data is requested void sendAnswer() { byte temp; int lightReading; switch (cmd) { case CMD_SENSOR: temp = thermocouple.readCelsius(); Wire.write(temp); break; case CMD_LUMEN: lightReading = analogRead(PIN_LUMEN); Wire.write(lightReading >> 8); wire.write(lightReading % 0xFF); prestávka; case CMD_PIN_ON: case CMD_PIN_OFF: case CMD_BEAT: Wire.write(status); stav = ST_OK; prestávka; ) cmd = 0; ) // volaná obslužnou rutinou prerušenia, keď prichádzajú prichádzajúce dáta void príjemPríkaz (int howMany) ( cmd = Wire.read (); stav = ST_OK; prepínač (cmd) ( case CMD_PIN_ON: cmdPinOn();; break; case CMD_PIN_OFF: cmdPinOff (); break; case CMD_BEAT: lastBeat = millis(); break; ) ) //koniec prijatej udalosti void cmdPinOff() ( if (Wire.available() != 1) ( status = ST_BAD_LEN; ) else ( int pin = Wire.read(); int i = searchPin(pin); if (i< 0) { status = ST_BAD_PIN; } else { pgma[i].off = 0; digitalWrite(pin, LOW); } } } int searchPin(int pin) { int i = pgmaSize - 1; while (i >= 0 && pgma[i].pin != pin) ( i--; ) return i; ) /* * Programy el encendido y duracion del RESET. */ void resetPin() ( if (digitalRead(PIN_RESET) == LOW) ( unsigned long now = millis(); int i = searchPin(PIN_RESET); pgma[i].off = now + RESET_LENGTH; lastBeat = now; digitalWrite (PIN_RESET, HIGH); ) ) void cmdPinOn() ( if (Wire.available() != 2) ( status = ST_BAD_LEN; ) else ( int pin = Wire.read(); int len ​​​​= Wire.read( ); int i = searchPin(pin); Serial.print("pin="); Serial.print(pin); Serial.print(",index="); Serial.println(i); if (i< 0) { status = ST_BAD_PIN; Serial.println("bad pin"); } else { if (len == 0) { status = ST_TIME_0; Serial.println("ban len"); } else { pgma[i].off = millis() + len * 1000; digitalWrite(pin, HIGH); Serial.println("ok"); } } } }

Na pripojenie mikrokontroléra k počítaču sa najčastejšie používa COM port. V tomto článku si ukážeme, ako posielať riadiace príkazy z počítača a odosielať dáta z ovládača.

Príprava na prácu

Väčšina mikrokontrolérov má viacero I/O portov. Pre komunikáciu s PC je najvhodnejší protokol UART. Ide o sériový asynchrónny protokol prenosu dát. Pre jeho konverziu na USB rozhranie má doska prevodník USB-RS232 - FT232RL.
Na spustenie príkladov v tomto článku potrebujete iba dosku kompatibilnú s Arduino. Používame . Uistite sa, že vaša doska má LED pripojenú na kolík 13 a tlačidlo reset.

Napríklad nahrajte kód na tabuľu, ktorá zobrazuje tabuľku ASCII. ASCII je kódovanie na reprezentáciu desatinných číslic, latinskej a národnej abecedy, interpunkčných znamienok a riadiacich znakov.

int symbol = 33; void setup() ( Serial. begin(9600 ) ; Serial. println(" ASCII Table ~ Character Map " ); ) void loop() ( Serial. write(symbol) ; Serial. print(" , dec: " ) ; Serial .print(symbol) ; Serial.print(" , hex: " ) ; Serial.print(symbol, HEX) ; Serial.print(" , oct: " ) ; Serial.print(symbol, OCT) ; Serial.print( " , bin: " ) ; Serial.println(symbol, BIN) ; if (symbol == 126 ) ( while (true) ( ​​Continue ; ) ) symbol+ + ; )

Premenná symbol ukladá kód symbolu. Tabuľka začína na 33 a končí na 126, takže symbol je na začiatku nastavený na 33.
Ak chcete spustiť prevádzku portu UART, použite funkciu Serial.begin(). Jeho jediným parametrom je rýchlosť. Rýchlosť musí byť dohodnutá na vysielacej a prijímacej strane vopred, pretože prenosový protokol je asynchrónny. V tomto príklade je rýchlosť 9600 bps.
Na zápis hodnoty do portu sa používajú tri funkcie:

  1. Serial.write()– zapisuje dáta na port v binárnej forme.
  2. Serial.print() môže mať veľa hodnôt, no všetky slúžia na zobrazovanie informácií vo forme priateľskej k človeku. Napríklad, ak sú informácie zadané ako parameter na odovzdanie uzavreté v úvodzovkách, terminálový program ich zobrazí nezmenené. Ak chcete zobraziť akúkoľvek hodnotu v určitej číselnej sústave, musíte pridať obslužné slovo: BIN-binary, OCT - osmičkové, DEC - desiatkové, HEX - hexadecimálne. Napríklad, Serial.print(25,HEX).
  3. Serial.println() robí to isté ako Serial.print(), ale po zobrazení informácií stále prekladá reťazec.

Pre kontrolu činnosti programu je potrebné, aby mal počítač terminálový program, ktorý prijíma dáta z COM portu. Arduino IDE už má jeden zabudovaný. Ak ho chcete vyvolať, vyberte z ponuky Nástroje->Monitor portu. Okno tohto nástroja je veľmi jednoduché:

Teraz kliknite na tlačidlo reštartu. MK sa reštartuje a zobrazí tabuľku ASCII:

Venujte pozornosť tejto časti kódu:

if (symbol = = 126) (pričom (pravda) (pokračovať; ))

Zastaví vykonávanie programu. Ak ju vylúčite, tabuľka sa bude zobrazovať na neurčito.
Na upevnenie získaných vedomostí skúste napísať nekonečnú slučku, ktorá raz za sekundu pošle vaše meno na sériový port. Do výstupu pridajte čísla krokov a nezabudnite preložiť riadok za názvom.

Odosielanie príkazov z PC

Predtým, ako to urobíte, musíte získať predstavu o tom, ako funguje port COM.
Po prvé, všetka výmena prebieha cez vyrovnávaciu pamäť. To znamená, že keď niečo odošlete z počítača do zariadenia, údaje sa umiestnia do nejakej špeciálnej časti pamäte. Hneď ako je zariadenie pripravené, načítava údaje z vyrovnávacej pamäte. Funkcia umožňuje kontrolovať stav vyrovnávacej pamäte serial.avaliable(). Táto funkcia vráti počet bajtov vo vyrovnávacej pamäti. Na odčítanie týchto bajtov musíte použiť funkciu Serial.read(). Pozrime sa, ako tieto funkcie fungujú na príklade:

int val = 0; void setup() ( Serial. begin(9600) ; ) void loop() ( if (Serial. available() > 0 ) ( val = Serial. read() ; Serial. print(" Dostal som: " ) ; Serial. write(val) ; Serial.println() ; ) )

Po načítaní kódu do pamäte mikrokontroléra otvorte monitor COM portu. Napíšte jeden znak a stlačte Enter. V poli prijatých údajov uvidíte: "Dostal som: X", kde namiesto X bude znak, ktorý ste zadali.
Program sa točí donekonečna v hlavnej slučke. V momente, keď sa na port zapíše bajt, funkcia Serial.available() nadobudne hodnotu 1, čiže podmienka je splnená Serial.available() > 0. Ďalšia funkcia Serial.read() prečíta tento bajt, čím vymaže vyrovnávaciu pamäť. Potom pomocou funkcií, ktoré už poznáte, dôjde k výstupu.
Používanie vstavaného monitora COM portu Arduino IDE má určité obmedzenia. Pri odosielaní dát z dosky na COM port je možné výstup usporiadať v ľubovoľnom formáte. A pri odosielaní z PC na dosku dochádza k prenosu znakov v súlade s tabuľkou ASCII. To znamená, že keď zadáte napríklad znak „1“, cez port COM sa odošle binárne číslo „00110001“ (to znamená „49“ v desiatkovej sústave).
Poďme trochu zmeniť kód a skontrolovať toto vyhlásenie:

int val = 0; void setup() ( Serial. begin(9600) ; ) void loop() ( if (Serial. available() > 0 ) ( val = Serial. read() ; Serial. print(" Dostal som: " ) ; Serial. println(val, BIN) ;))

Po stiahnutí sa v monitore portov pri odosielaní „1“ zobrazí odpoveď: „Prijal som: 110001“. Môžete zmeniť výstupný formát a zistiť, čo doska akceptuje s inými znakmi.

Ovládanie zariadenia cez COM port

Je zrejmé, že príkazmi z PC môžete ovládať ľubovoľné funkcie mikrokontroléra. Stiahnite si program, ktorý riadi činnosť LED:

int val = 0; void setup() ( Serial. begin(9600) ; ) void loop() ( if (Serial. available() > 0 ) ( val = Serial. read() ; if (val= = "H" ) digitalWrite(13 , HIGH) ; if (val= = "L" ) digitalWrite(13 , LOW) ; ) )

Keď sa do COM portu odošle znak „H“, LED na 13. výstupe sa rozsvieti a keď sa odošle „L“, LED zhasne.
Ak na základe výsledkov prijímania údajov z portu COM chcete, aby program vykonával rôzne akcie v hlavnej slučke, môžete skontrolovať podmienky v hlavnej slučke. Napríklad.