Arduino UNO + Ethernet mini modul a WebServer

Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
Kony
Příspěvky: 138
Registrován: 09 dub 2020, 11:43
Reputation: 0

Arduino UNO + Ethernet mini modul a WebServer

Příspěvek od Kony » 08 čer 2020, 17:27

Ahoj, snažím se rozchodit Arduino UNo s Ethernetem a aby Arduino byl WebServerem kde budu zobrazovat teploty a mít tam 4 tlačítka

nyní mám kód :

Kód: Vybrat vše

#include <SPI.h>
#include <EtherCard.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define STATIC 1  // set to 1 to disable DHCP (adjust myip/gwip values below)
#define pin 1
// nastavení komunikace senzoru přes pin
OneWire oneWire(pin);     
// převedeme onewire do Dallasu                     
DallasTemperature sensors(&oneWire);

#if STATIC
// ethernet interface ip address
static byte myip[] = { 192,168,1,200 };
// gateway ip address
static byte gwip[] = { 192,168,1,1 };
#endif

// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[500]; // tcp/ip send and receive buffer

const char page[] PROGMEM =
",n,mn,mn,mnm,n"
;

void setup(){
  Serial.begin(57600);
  Serial.println("\n[backSoon]");
  sensors.begin();

  // Change 'SS' to your Slave Select pin, if you arn't using the default pin
  if (ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0)
    Serial.println( "Failed to access Ethernet controller");
#if STATIC
  ether.staticSetup(myip, gwip);
#else
  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");
#endif

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);
}

void loop(){
  // wait for an incoming TCP packet, but ignore its contents
  if (ether.packetLoop(ether.packetReceive())) {
    memcpy_P(ether.tcpOffset(), page, sizeof page);
    ether.httpServerReply(sizeof page - 1);
}
}
Zobrazí se mi text :
,n,mn,mn,mnm,n
Vím že se ten text určuje tady
const char page[] PROGMEM =
",n,mn,mn,mnm,n"
;
Ale já bych tam potřeboval dosadit :

Kód: Vybrat vše

 "<!DOCTYPE html> <html>\n"
  "<head><meta charset=\"UTF-8\" name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n"
  "<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600\" rel=\"stylesheet\">\n"
  "<title>Teploty</title>\n"
  "<style>html { font-family: 'Open Sans', sans-serif; display: block; margin: 0px auto; text-align: center;color: #333333;}\n"
  "body{margin-top: 50px;}\n"
  "h1 {margin: 50px auto 30px;}\n"
  ".side-by-side{display: inline-block;vertical-align: middle;position: relative;}\n"
  ".humidity-icon{background-color: #3498db;width: 30px;height: 30px;border-radius: 50%;line-height: 36px;}\n"
  ".humidity-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n"
  ".humidity{font-weight: 300;font-size: 60px;color: #3498db;}\n"
  ".temperature-icon{background-color: #f39c12;width: 30px;height: 30px;border-radius: 50%;line-height: 40px;}\n"
  ".temperature-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n"
  ".temperature{font-weight: 300;font-size: 60px;color: #f39c12;}\n"
  ".superscript{font-size: 17px;font-weight: 600;position: absolute;right: -20px;top: 15px;}\n"
  ".data{padding: 10px;}\n"
  "</style>\n"
  "</head>\n"
  "<body>\n"
  
   "<div id=\"webpage\">\n"
   
   "<h1 style=\"font-size : 60px\">Teploty u bazénu</h1>\n"
   "<div class=\"data\">\n"
   "<div class=\"side-by-side temperature-icon\">\n"
   "<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n"
   "width=\"9.915px\" height=\"22px\" viewBox=\"0 0 9.915 22\" enable-background=\"new 0 0 9.915 22\" xml:space=\"preserve\">\n"
   "<path fill=\"#FFFFFF\" d=\"M3.498,0.53c0.377-0.331,0.877-0.501,1.374-0.527C5.697-0.04,6.522,0.421,6.924,1.142\n"
   "c0.237,0.399,0.315,0.871,0.311,1.33C7.229,5.856,7.245,9.24,7.227,12.625c1.019,0.539,1.855,1.424,2.301,2.491\n"
   "c0.491,1.163,0.518,2.514,0.062,3.693c-0.414,1.102-1.24,2.038-2.276,2.594c-1.056,0.583-2.331,0.743-3.501,0.463\n"
   "c-1.417-0.323-2.659-1.314-3.3-2.617C0.014,18.26-0.115,17.104,0.1,16.022c0.296-1.443,1.274-2.717,2.58-3.394\n"
   "c0.013-3.44,0-6.881,0.007-10.322C2.674,1.634,2.974,0.955,3.498,0.53z\"/>\n"
   "</svg>\n"
   "</div>\n"
   "<div class=\"side-by-side temperature-text\">Teplota vzduchu</div>\n"
   "<div class=\"side-by-side temperature\">"
   //(int)Temperature
//   (sensors.getTempCByIndex(0))
   "<span class=\"superscript\">°C</span></div>\n"
   "</div>\n"

   "<div class=\"data\">\n"
   "<div class=\"side-by-side temperature-icon\">\n"
   "<svg version=\"1.1\" id=\"Layer_2\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n"
   "width=\"9.915px\" height=\"22px\" viewBox=\"0 0 9.915 22\" enable-background=\"new 0 0 9.915 22\" xml:space=\"preserve\">\n"
   "<path fill=\"#FFFFFF\" d=\"M3.498,0.53c0.377-0.331,0.877-0.501,1.374-0.527C5.697-0.04,6.522,0.421,6.924,1.142\n"
   "c0.237,0.399,0.315,0.871,0.311,1.33C7.229,5.856,7.245,9.24,7.227,12.625c1.019,0.539,1.855,1.424,2.301,2.491\n"
   "c0.491,1.163,0.518,2.514,0.062,3.693c-0.414,1.102-1.24,2.038-2.276,2.594c-1.056,0.583-2.331,0.743-3.501,0.463\n"
   "c-1.417-0.323-2.659-1.314-3.3-2.617C0.014,18.26-0.115,17.104,0.1,16.022c0.296-1.443,1.274-2.717,2.58-3.394\n"
   "c0.013-3.44,0-6.881,0.007-10.322C2.674,1.634,2.974,0.955,3.498,0.53z\"/>\n"
   "</svg>\n"
   "</div>\n"
   "<div class=\"side-by-side temperature-text\">Teplota vody</div>\n"
   "<div class=\"side-by-side temperature\">"
  // (int)voda
   "<span class=\"superscript\">°C</span></div>\n"
   "</div>\n"

      "<div class=\"data\">\n"
   "<div class=\"side-by-side temperature-icon\">\n"
   "<svg version=\"1.1\" id=\"Layer_2\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n"
   "width=\"9.915px\" height=\"22px\" viewBox=\"0 0 9.915 22\" enable-background=\"new 0 0 9.915 22\" xml:space=\"preserve\">\n"
   "<path fill=\"#FFFFFF\" d=\"M3.498,0.53c0.377-0.331,0.877-0.501,1.374-0.527C5.697-0.04,6.522,0.421,6.924,1.142\n"
   "c0.237,0.399,0.315,0.871,0.311,1.33C7.229,5.856,7.245,9.24,7.227,12.625c1.019,0.539,1.855,1.424,2.301,2.491\n"
   "c0.491,1.163,0.518,2.514,0.062,3.693c-0.414,1.102-1.24,2.038-2.276,2.594c-1.056,0.583-2.331,0.743-3.501,0.463\n"
   "c-1.417-0.323-2.659-1.314-3.3-2.617C0.014,18.26-0.115,17.104,0.1,16.022c0.296-1.443,1.274-2.717,2.58-3.394\n"
   "c0.013-3.44,0-6.881,0.007-10.322C2.674,1.634,2.974,0.955,3.498,0.53z\"/>\n"
   "</svg>\n"
   "</div>\n"
   "<div class=\"side-by-side temperature-text\">Teplota v přepadu</div>\n"
   "<div class=\"side-by-side temperature\">"
  // (int)okap
   "<span class=\"superscript\">°C</span></div>\n"
   "</div>\n"
   
  "</body>\n"
  "</html>\n"
Včetně těch naměřených hodnot, který mám nyní zakomentovaný. Ale jakmile tohle nahraju do Arduina, tak mi ping na arduino prochází, ale jakmile otevřu IP adresu v prohížeči, tak se ping zastaví a samozřejmě se nic nezobrazí.


Kony
Příspěvky: 138
Registrován: 09 dub 2020, 11:43
Reputation: 0

Re: Arduino UNO + Ethernet mini modul a WebServer

Příspěvek od Kony » 09 čer 2020, 08:28

Tak to zkousim takto ...

Kód: Vybrat vše

const char page[] PROGMEM = 
"<!DOCTYPE html>"
"<html>"
"<meta charset=\"UTF-8\">"
"<body>"
"<center>"
"<h1>Teploty u bazénu:</h1><br>";
const char line[] PROGMEM = (sensors.getTempCByIndex(0));
const char page[] PROGMEM = 
"Click to turn <a href=\"ledOn\">LED ON</a><br>"
"Click to turn <a href=\"ledOff\">LED OFF</a><br>"
"<hr>"
"</center>"
"</body>"
"</html>"
;
Ale tohle teda nejede

martinius96
Příspěvky: 491
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Arduino UNO + Ethernet mini modul a WebServer

Příspěvek od martinius96 » 09 čer 2020, 14:40

V tom pôvodnom programe ti chýba request temperatures na OneWire zbernici.
Hodnotu teploty máš ako const char, takže sa ti nikdy nezmení. A máš tam 2x page, myslím, že sa ti to prepíše....

Na ESP8266 a ESP32 sa dal urobiť String, ktorý obsiahol celú stránku a dalo sa to tvoriť štýlom:

Kód: Vybrat vše

String stranka = "<!DOCTYPE html>\n";
stranka + = "<html>"
.
.
.
Prípadne sa to dalo dať ešte do makra F(), čím sa to celé uložilo do flashky (používal som to na statické veci na stránke, ktoré sa nemenia... HTML kód, nadpisy atď.. A až potom som tam vkladal veci, ktoré sa menili (teploty, atď).

Následne sa to na daný callback napríklad root / dalo nastaviť, že ako odpoveď pošle String stranka. Neviem však, či to takto funguje aj pod ENC28J60, nikdy som ho nevyužíval.
Skús si najprv vypísať jednoduchú HTML stránku čisto iba s textom, či ti to bude fungovať. Ak áno, môžeme potom rozmýšľať o dosadení hodnôt zo senzora DS18B20...

Kód: Vybrat vše

const char page[] PROGMEM = \
                            "<!DOCTYPE html>\n" \
                            "<html>\n" \
                            "<meta charset='UTF-8'>\n" \
                            "<body>\n" \
                            "<center>\n" \
                            "<h1>Teploty u bazénu:</h1><br>\n" \
                            "Click to turn <a href='ledOn'>LED ON</a><br>\n" \
                            "Click to turn <a href='ledOff'>LED OFF</a><br>\n" \
                            "<hr>\n" \
                            "</center>\n" \
                            "</body>\n" \
                            "</html>\n";

Kony
Příspěvky: 138
Registrován: 09 dub 2020, 11:43
Reputation: 0

Re: Arduino UNO + Ethernet mini modul a WebServer

Příspěvek od Kony » 10 čer 2020, 12:38

Tak jsem to již sprovoznil, ale mám velký problém s prostorem pro
Globální proměnné zabírají 1922 bytů (96%) dynamické paměti, 126 bytů zůstává pro lokální proměnné. Maximum je 2048 bytů
Mohl by prosím někdo mrknout na můj kod a zkusit to zredukovat ?? Sice to do Una nahraju, ale nenačte to web stránku

Kód: Vybrat vše

#include <UIPEthernet.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
boolean zacatekCteni = false;
byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x9C, 0xB7}; //MAC adresa
IPAddress ip(10,10,111,177); //IP adresa
IPAddress subnet(255, 255, 255, 0);
IPAddress gateway(10, 10, 111, 1);
EthernetServer server = EthernetServer(80); //port
#define pin A0
OneWire oneWire(pin);                         
DallasTemperature sensors(&oneWire);
#define pin1 A1
OneWire oneWire1(pin1);                         
DallasTemperature sensors1(&oneWire1);
#define pin2 A2
OneWire oneWire2(pin2);                         
DallasTemperature sensors2(&oneWire2);

void setup(){
    pinMode(7, OUTPUT);
    digitalWrite(7, LOW);
    pinMode(6, OUTPUT);
    digitalWrite(6, LOW);
    pinMode(5, OUTPUT);
    digitalWrite(5, LOW);
    pinMode(4, OUTPUT);
    digitalWrite(4, LOW);
    Ethernet.begin(mac, ip); //vytvoření serveru
    server.begin(); //spuštění serveru
    sensors.begin();
    sensors1.begin();
    sensors2.begin();
}
void loop(){
    EthernetClient client = server.available(); //načtení klienta   
    if(client){
        boolean prazdnyRadek = true;
        boolean hlavickaPoslana = false;
        sensors.requestTemperatures();  
        sensors1.requestTemperatures(); 
        sensors2.requestTemperatures(); 
        while(client.connected() && client.available()){
            if(!hlavickaPoslana){ //jednou pošleme hlavičku
                client.println("HTTP/1.1 200 OK");
                client.println("Content-Type: text/html");
                client.println();
                hlavickaPoslana = true;
                //dále pošleme obsah stránky
                client.println("<html>");
                client.println("<div class=\"container\" align=\"center\" style=\"width:900px;\">");
                client.println("<head><meta charset=\"UTF-8\"></head>");
                client.println("<p style=\"font-size:100px; font-weight: bold\">Teplota u bazénu</p>");
                client.print("<span style=\"font-size:60px\">Teplota vody    </span>");
                client.print("<span style=\"font-size:60px; color:#668cff\">");
                client.print(sensors.getTempCByIndex(0));
                client.print("   °C</span>");
                client.println("<br>");
                client.print("<span style=\"font-size:60px; align:center\">Teplota vzduchu    </span>");
                client.print("<span style=\"font-size:60px; color:#668cff\">");
                client.print(sensors1.getTempCByIndex(0));
                client.print("   °C</span>");
                client.print("<br>");
                client.print("<span style=\"font-size:60px\">Teplota přepadu    </span>");
                client.print("<span style=\"font-size:60px; color:#668cff\">");
                client.print(sensors2.getTempCByIndex(0));
                client.print("   °C</span>");
                client.print("<br><br>");
                client.println("<span style=\"font-size:50px\">");
                client.println("<p>Relé 1 : <a href=\"/?l=0\">VYPNI</a>");
                client.println(" - ");
                client.println("<a href=\"/?l=1\">ZAPNI</a></p>");
                client.println("<p>Relé 2 : <a href=\"/?l=2\">VYPNI</a>");
                client.println(" - ");
                client.println("<a href=\"/?l=3\">ZAPNI</a></p>");
                client.println("<p>Relé 3 : <a href=\"/?l=4\">VYPNI</a>");
                client.println(" - ");
                client.println("<a href=\"/?l=5\">ZAPNI</a></p>");
                client.println("<p>Relé 4 : <a href=\"/?l=6\">VYPNI</a>");
                client.println(" - ");
                client.println("<a href=\"/?l=7\">ZAPNI</a></p></span>");
                client.println("</body>");
                client.println("</html>");
            }
    char c = client.read();
            if(zacatekCteni && c == ' '){ //ukončí čtení
                zacatekCteni = false;
            }
            if(c == '?'){ //začne čtení
                zacatekCteni = true;
            }
            if(zacatekCteni){                
                if(c == 'l'){
                    client.read(); //přeskočíme jeden znak (=)
                    c = client.read(); //přečteme další znak -> hodnota LED
                    if(c == '0'){
                        digitalWrite(7, LOW);
                    }
                    else if(c == '1'){
                        digitalWrite(7, HIGH);
                    }
                    if(c == '2'){
                        digitalWrite(6, LOW);
                    }
                    else if(c == '3'){
                        digitalWrite(6, HIGH);
                    }
                    if(c == '4'){
                        digitalWrite(5, LOW);
                    }
                    else if(c == '5'){
                        digitalWrite(5, HIGH);
                    }
                    if(c == '6'){
                        digitalWrite(4, LOW);
                    }
                    else if(c == '7'){
                        digitalWrite(4, HIGH);
                    }
                    break; //vyskočí z cyklu
                }
            }
            if (c == 'n') {
                prazdnyRadek = true;
            }
            else if (c != 'r'){
                prazdnyRadek = false;
            }         
        }
        delay(1);
        client.stop();
    } 
}
Nyní jsem z html stránky odstranil nadpis a už to běží... Ale je to teda masakr :)

martinius96
Příspěvky: 491
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Arduino UNO + Ethernet mini modul a WebServer

Příspěvek od martinius96 » 10 čer 2020, 13:35

Doplň si do všetkých statických výpisov client.println makro F().
Napríklad:

Kód: Vybrat vše

client.println("<html>");
upravíš na:
client.println(F("<html>"));
a obdobne pre ďalšie statické výpisy... Uloží ti ich do flash pamäte a uvolní ti to RAM-ku. Webserver bude stabilnejší, bude mať viac RAM k dispozícii, nespadne...
Nepoužívaj to na dynamické premenné (napríklad výpis teploty zo senzora a pod).

Kony
Příspěvky: 138
Registrován: 09 dub 2020, 11:43
Reputation: 0

Re: Arduino UNO + Ethernet mini modul a WebServer

Příspěvek od Kony » 10 čer 2020, 13:58

Diky moc, pomohlo.. mam 56%

mart-in
Příspěvky: 16
Registrován: 27 kvě 2020, 21:43
Reputation: 0

Re: Arduino UNO + Ethernet mini modul a WebServer

Příspěvek od mart-in » 11 čer 2020, 06:20

Ahoj, já jsem to vždy řešil přes Ethernet shield. Ten má navíc slot pro microSD karu, na kterou jednoduše webovky uložíš. Zkus na google hledat "Arduino web server SD card" je toho plno, některé i docela propracované, které načítají i obrázky a styly css. Měl jsem to na Arduino Mega a pak jsem měl optimalizovanou verzi pro UNO, ale to nemá tolik RAMky, tak je lepší použít MEGA. Můžeš si s tím hodně vyhrát, například přidat java script pro přihlášení a pomocí css vytvořit jednoduché menu. Hodnoty z Arduina pak načítáš tak, že na určité místo v HTML dáš nějaký znak např. $+něco a to pak v Arduinu parsuješ a nahrazuješ požadovanou hodnotou z čidla.

Kony
Příspěvky: 138
Registrován: 09 dub 2020, 11:43
Reputation: 0

Re: Arduino UNO + Ethernet mini modul a WebServer

Příspěvek od Kony » 29 čer 2020, 19:54

Mohl bych poprosit jeste o jednu radu ??
Potreboval bych, abych pro kazde rele (1 az 4) bylo na www arduina videt v jakem stavu se nachazi. Tzn staci jen aby tam bylo Zapnuto/Vypnuto

martinius96
Příspěvky: 491
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Arduino UNO + Ethernet mini modul a WebServer

Příspěvek od martinius96 » 29 čer 2020, 20:28

Pridáš si do výpisu HTML stránky jednoduchú podmienku

Kód: Vybrat vše

int reading = digitalRead(rele1);
if(reading==HIGH){
client.println("<p>Zapnuté</p>");
}else{
client.println("<p>Vypnuté</p>");
}
Obdobne pre ďalšie relé.
Nakoľko nemáš Async webserver, musíš ho pravidelne aktualizovať (celú HTML stránku), napríklad do hlavičky HTML dokumentu pridáš.

Kód: Vybrat vše

client.println("<meta http-equiv='refresh' content='5'>");
Takto bude klient vidieť "real-time" hodnotu relé.
Môžeš použiť aj to F() makro, aby sa ti tie reťazce uložili do flashky.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: kiRRow a 2 hosti