Napojení Arduina na Ethernet
V tomto tutoriálu si vysvětlíme, jak připojit Arduino k lokální síti a internetu. Předpokládá se, že ovládáte základy počítačového síťování, jako je zapojení počítače do hubu/routeru pomocí RJ45 kabelů a také víte, co znamená IP, MAC adresa a podobně.
Obsah článku:
Začínáme
Budete potřebovat Arduino Uno nebo jinou desku kompatibilní s Ethernet shieldem, který používá W5100 Ethernet controller IC:
Dále budete potřebovat napájet desku pomocí externího DC socketu. W5100 IC spotřebuje více proudu, než mu dodá napájení z USB. A 9V 1A adaptér, nebo AC adaptér budou stačit. Pozor: Deska se silně zahřívá, takže se snažte nesahat na W5100 po jeho delším používání. Pokud si nebudete jistí, takto vypadá W5100 IC:
Jakmile budete mít na svém Arduinu aktivovaný Ethernet a zapojený externí zdroj (je dobré zkontrolovat, zda všechno správně funguje), otevřete Arduino IDE a vyberte File > Examples > Ethernet > Webserver. Takto načtete jednoduchý sketch, který bude zobrazovat data z analogových vstupů ve webovém prohlížeči. Ještě jej nenahrávejte, potřebuje udělat pár úprav.
Bude nutné specifikovat IP adresu Ethernet shieldu – Ta se upravuje přímo v kódu. Není to složité, přejděte na řádek:
IPAddress ip(192,168,1, 177);
A pozměňte jej tak, aby odpovídal vašemu nastavení. Například, můj domácí router má IP adresu 10.1.1.1, tiskárna je 10.1.1.50 a všechny počítače jsou pod 50. Takže nastavím adresu mého Shieldu na 10.1.1.77, tím že pozměním tento řádek na:
IPAddress ip(10,1,1,77);
Máte také možnost změnit vaší MAC adresu. Každý díl síťového příslušenství má unikátní sériové číslo, aby mohl být identifikován v síti, to je natvrdo naprogramováno ve firmwaru daného příslušenství. S Arduinem můžeme definovat MAC adresu sami. Pokud používáte ve vaší síti více jak jeden Ethernet shield, ujistěte se, že mají rozdílné MAC adresy, pozměněním hexadecimálních hodnot v řádku:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
Jestliže máte jen jeden shield, můžete to nechat být. Je statisticky velmi malá šance, že bude mít stejnou MAC adresu, jako váš používaný hardware, v tomto případě ji budete muset změnit. Jakmile pozměníte kód, uložte a nahrajte sketch. Pak otevřete webový prohlížeč a vyhledejte IP adresu, kterou jste zadali ve vašem sketchi, mělo by se vám zobrazit něco podobného, jako je na následujícím obrázku:
Co se děje? Arduino je naprogramováno tak, aby nabídlo jednoduchou webovou stránku s hodnotami měřenými analogovými vstupy. Stránku můžete znovu načíst, abyste získali aktuální hodnoty. V tomto bodě si prosím zapamatujte, že ethernet shieldy používají digitální piny 10~13, a tak je nemůžete použít pro nic jiného. Některé Arduino Ethernet shieldy mají microSD socket, který používá jiný digitální pin, takže ho najděte v jejich dokumentaci (často to bývá pin 4).
Jakmile vidíme, že Ethernet shield pracuje, můžeme se posunout k něčemu užitečnějšímu. Pojďme si vyložit předchozí příklady jednodušším způsobem a zjistit jak můžeme roztřídit informace, nebo zobrazit více zajímavých dat na síti. Všechny funkce spojené s Ethernetem jsou spravovány pomocí Ethernet Arduino library. Pokud projdete předchozí sketch, který jsme před chvilkou používali, bude nás zajímat tato část:
for (int analogChannel = 0; analogChannel < 6; analogChannel++) { int sensorReading = analogRead(analogChannel); client.print("analog input "); client.print(analogChannel); client.print(" is "); client.print(sensorReading); client.println("<br />"); } client.println("</html>");
Budeme posílat data z našeho Ethernet shieldu nazpátek do webového prohlížeče – v podobě základního typu webové stránky. Pokud si přejete získat pěkně naformátované webové stánky z vašeho Arduina, podívejte se pro začátek na základy html. Zde pak najdete pěkný HTML tahák. Pro zjednodušení ale budou následující funkce nejužitečnější:
client.print("analog input ");
Client.print (); nám umožní posílat text, nebo data zpátky na webovou stránku. Pracuje stejným způsobem jako serial.print(), takže nejde o nic nového. Můžete také specifikovat data type stejným způsobem jako u serial.print(). Další užitečný řádek je:
client.print("<br />");
HTML značka <br /> posílá do webového prohlížeče příkaz k zalomení řádku. Pokud vytváříte o něco složitější výstupní zobrazení webových stránek, stačí jen vložit další HTML tagy do client.println(). V případě že se chcete dozvědět něco více o HTML příkazech, dobré tutoriály najdete třeba zde, nebo zde.
Nakonec si všimněte, že sketch bude posílat data jen v případě, kdy jej o to požádáte. To jest ve chvíli, kdy dostane požadavek od webového prohlížeče.
Přístup k Arduinu přes internet
Zatím jde všechno dobře. Ale co dělat, když se budete chtít připojit na vaše Arduino z internetu nebo mimo prostředí vaší lokální sítě?
Budete potřebovat statickou IP adresu. To znamená IP adresu, kterou vám váš zprostředkovatel internetu přidělí, a která zůstává stejná. Pokud statickou IP adresu nemáte, přidělí vám server poskytovatele adresu vždy při připojení k síti. Ta by se po dobu připojení neměla měnit. Není však optimální se na toto spoléhat a pro tento účel je lepší mít statickou IP.
V situaci kdy vám váš poskytovatel nemůže nabídnout statickou IP adresu, můžete stále pokračovat s pomocí společností, které nabízí dynamickou DNS. Tyto organizace vám nabídnou vlastní statické hostitelské jméno (například mojo.monkeynuts.com) namísto běžné IP adresy. Jejich software sleduje změnu vaší IP adresy a automaticky na ni přesměrovává z přidělené URL. Pro bezproblémovou funkci však musí váš router podporovat DDNS služby.
Jak zjistit svojí IP adresu? Většinou je možné ji zjistit po přihlášení do administrace vašeho routeru. Často je možné použít adresu 192.168.0.1, ale může to být i jinak (záleží na nastavení routeru). Pokud si nevíte rady, můžete použít nějaký software na prozkoumání vaší sítě – pro android například aplikaci Fing. V tomto příkladu zadám do webového prohlížeče 10.1.1.1 (adresa mého routeru) a vložím heslo pro administraci mého modemu, pak se mi zobrazí tato stránka:
To co hledáte, je vaše WAN IP adresa, jak můžete vidět na obrázku nahoře. U různých routerů může být postup zjištění WAN odlišný. Když si nebudete vědět rady, prozkoumejte dokumentaci vašeho routeru.
Pokud byste se nyní připojili na vaši WAN adresu, dostali byste se pravděpodobně do administrace vašeho routeru. Pro přesměrování vnější WAN adresy na adresu IP ve vnitřní síti se používá technika zvaná port-forwarding. S její pomocí můžeme routeru přikázat, kam má přesměrovat příchozí požadavky z vnějšího světa. Jakmile modem dostane takový požadavek, chceme jej přeposlat na zvolenou IP a port našeho Ethernet shieldu. Níže vidíte příklad konfiguračního formuláře pro port-forwarding.
Z čísel na obrázku můžete vidět, že číslo portu bylo nastavené na 125 a IP adresa Ethernet shieldu na 10.1.1.77, stejně jako ve sketchi. Po uložení nastavení jsme připraveni. Externí adresa mého Ethernet shieldu bude WAN:125. Takže pro přístup na Aduino použiji WAN adresu s 125 na konci.
V příkladu budeme komunikovat na portu 125. Pro vytvoření serveru naslouchajícího portu 125 použijeme příkaz – respektive změníme číslo portu v předchozím příkladu.
EthernetServer server(125);
Dále budete pravděpodobně potřebovat změnit nastavení firewallu na vašem modemu, abyste dovolili portu 125 “otevřít se“ příchozím požadavkům. Správný postup naleznete v dokumentaci vašeho modemu.
V této chvíli mohu na téměř každém zařízení s internetem vložit můj WAN a číslo portu do pole pro URL v prohlížeči a získat výstupy z Arduina. Například pomocí mobilního telefonu, který je připojený na internet přes síť LTE:
V tomto momentu můžete zobrazit data z jednoduché webové stránky vytvořené Arduinem odkudkoliv. Tímto způsobem můžete zobrazit data ze senzorů, nebo dalších částí sketche.
Zobrazení dat senzorů na webu
Pro příklad zobrazení dat ze senzorů na webové stránce použijeme levný a populární senzor teploty a vlhkosti DHT22. Budete si potřebovat nainstalovat knihovnu Arduino pro DHT22, kterou najdete zde. Pokud zkoušíte DHT22 poprvé, vyzkoušejte ukázkový sketch přiložený ke knihovně.
Zapojte DHT22 do datového pinu Arduina D2, Vin do 5v pinu a GND do GND:
V příkladu níže zobrazíme data o teplotě a vlhkosti z DHT22 na jednoduché webové stránce:
#include <SPI.h> #include <Ethernet.h> // for DHT22 sensor #include "DHT.h" #define DHTPIN 2 #define DHTTYPE DHT22 // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress ip(10,1,1,77); // Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(125); DHT dht(DHTPIN, DHTTYPE); void setup(){ dht.begin(); // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } // start the Ethernet connection and the server: Ethernet.begin(mac, ip); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); } void loop() { // listen for incoming clients EthernetClient client = server.available(); if (client){ Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()){ if (client.available()){ char c = client.read(); Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\\n' && currentLineIsBlank){ // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); // the connection will be closed after completion of the response client.println("Refresh: 30"); // refresh the page automatically every 30 sec client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); // get data from DHT22 sensor float h = dht.readHumidity(); float t = dht.readTemperature(); Serial.println(t); Serial.println(h); // from here we can enter our own HTML code to create the web page client.print("<head><title>Office Weather</title></head><body><h1>Office Temperature</h1><p>Temperature - "); client.print(t); client.print(" degrees Celsius</p>"); client.print("<p>Humidity - "); client.print(h); client.print(" percent</p>"); client.print("<p><em>Page refreshes every 30 seconds.</em></p></body></html>"); break; } if (c == '\\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); Serial.println("client disonnected"); } }
A takto může vypadat výsledek:
Toto je překlad článku uveřejněného na webu http://tronixstuff.com/2013/12/06/arduino-tutorials-chapter-16-ethernet/ pod licencí Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
vito
24.1.2017 at 14:23Ahoj, nezkoušel jste někdo použít arduino s ethernet shieldem současně jako client i jako server v jednom skeči? Nemám veřejnou IP, takže si clientem posílám teplotu kotle do sql na wz.cz, na kterou pak musím přes jejich webové rozhraní. Když jsem ale doma, tak bych se mohl podívat přímo na arduino přes server. Půjde to?
Díky
Zbyšek Voda
24.1.2017 at 14:33Dobrý den,
ano, jde to – prostě na střídačku zkoumáte, jestli se někdo nepřipojil a odesíláte data na server.
Když ale data máte na wz.cz, nebylo by jednodušší si je zobrazit tam? 🙂
vito
26.1.2017 at 22:10Díky za odpověď. Co se týká zobrazení na webu, jistě by to byla cesta. Mám v plánu udělat si v php nebo javě stránku s hodnotami, ale nejdřív se to musím naučit a na to zase nemám teď čas. Potřebuji pouze jednu hodnotu a než se nyní přihlásím do sql a otočím zobrazení db od nejnovějších hodnot, mám lokální webserver načtený desetkrát 😉 Ale i tak děkuji na námět.
smiigl
21.1.2017 at 18:43Je možno přečíst a zpracovat arduino clientem více dat naráz z arduino webserveru, který mi zobrazuje data?
Zbyšek Voda
22.1.2017 at 10:50Dobrý den, tím „více dat naráz“ myslíte více hodnot, že?
Určitě to jde. Jsou dvě možnosti, jak toho dosáhnout.
a) Parametrem v URL adrese si řeknete, jakou hodnotu chcete získat a na server se dotazujete několikrát, jen měníte parametr v URL. Na každý dotaz získáte jednu hodnotu.
b) Server vám pošle všechny požadované hodnoty najednou. V tomto případě musí být hodnoty v předem domluveném formátu – například JSON, nebo jenom oddělené čárkou apod.
Už máte nějaký server hotový, nebo jenom zkoumáte možnosti?
smiigl
23.1.2017 at 10:20No momentálně mám 4 clienty, které posílají data na sql. Občas se ale stane, že se nějaká data ztratí. Další problém nastane, že potřebuji co nejčastěji kontrolovat vstupy a u clienta je rychlost ovlivněna připojením k serveru. Proto přemýšlím, že bych měl 4 webservery a jedním clientem zpracoval data a ty pak poslal do databáze.
FilipPospisil
4.1.2017 at 22:55Dobrý den,
tímto tedy Arduino připojím na síť a budu se moci odkudkoli kouknout na webové stránky, vytvořené v Arduinu s informacemi, které dává?
Zbyšek Voda
5.1.2017 at 13:28Dobrý den, ano, takto se podíváte ne IP adresu, kde uvidíte naměřené hodnoty.
Je otázka, jestli by nebylo lepší použít Arduino spíše jako klienta. V uvedeném příkladu totiž Arduino slouží jako server, který má nějakou IP v lokální síti a vy v routeru nastavíte přesměrování veřejné IP na lokální adresu Arduina. Takže když se pak odkudkoliv připojíte na veřejnou IP, uvidíte to, co se děje na připojeném Arduinu.
Kdyby Arduino fungovalo jako klient, tak by hodnoty někam logovalo. Vy byste se pak připojil na nějakou URL (třeba thingspeak.com, nebo vlastní server) a tam byste hodnoty viděl. Nevýhoda je, že byste musel vyřešit server, kam by se hodnoty logovaly. Pokud jde ale o logování nějaké jedné hodnoty, tak myslím, že je použití Thingspeak.com naprosto vyhovující 🙂
Něco o této problematice jsem sepsal tady: https://bastlirna.hwkitchen.cz/programovani-webovych-rozhrani-pro-arduino/
FilipPospisil
20.1.2017 at 10:05Dobrý den,
děkuji za odpověď! 🙂 Chtěl bych nechat ARD na chatě a nejspíše nejlépe přes Wi-Fi Shiled bych chtěl posílat informace na internet a mít vždy přístup např. k teplotě, která momentálně uvnitř chaty je 😉
Dominik
5.7.2015 at 16:33Mě to nefunguje 🙁
Dominik
5.7.2015 at 17:03Tak už funguje. Chyba byla v kabelu
Dominik
5.7.2015 at 18:29Poradil by prosím někdo jak nastavit „kodování“ aby se zobrazovala správně písma s diakritikou. Děkuji
Tomas
20.12.2014 at 23:07Pěkný tutorial. Jen je tam malá chybka, kdy arduino nenačte všechny hlavičky od klienta. Testování c by mělo být c == ‚\n‘ a c != ‚\r‘. Jinak super a díky
Zbyšek Voda
23.12.2014 at 17:05Díky:) Opraveno
Daniel
1.12.2014 at 23:22Moc pěknej tutoriál dlouho jsem něco takového hledal 🙂