Offline
Newbie
Karma: 0
Posts: 18
|
 |
« on: January 30, 2012, 05:21:32 am » |
Hallo zusammen, ich bin Arduinobastler in jungen Tagen und versuche mich gerade an einem Webserver, welcher im Netzwerk ansteuerbar ist und "Hallo Welt" per Klick ausgeben soll. Sende hier mal mein bisheriges Programm. Bitte schaue es sich mal jemand an und gebe mir Rückmeldung dazu. (Ich erwarte nicht unbedingt eine Musterlösung. Es würde mir auch schon ein hilfreicher Denkanstoß oder Link zu einem Tutorial helfen) Vielen Dank im Vorraus. Magic #include <SPI.h> //Anbindung microcontroller an Ethernet-Shield #include <Ethernet.h> int x;
// Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; byte ip[] = { 192,168,1, 177 };
// Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80);
void setup() { // start the Ethernet connection and the server: Ethernet.begin(mac, ip); server.begin(); pinMode(5, OUTPUT); }
void loop() {
if (x==1){ analogWrite(5, 200); } // listen for incoming clients EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); // 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(); // print something, in HTML format: client.println("<html>"); client.println("<head>"); client.println("<TITLE>Sörens Testpage</TITLE>"); client.println(" <input type='submit' name='buttoncolorchange' id='button' value='Farbwechsel' method='post' onclick=' alert('Hallo Welt') '/> "); client.println("</head>"); client.println("<body>");
client.println("</body>"); client.println("</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(); }
} |
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 126
|
 |
« Reply #1 on: January 30, 2012, 05:50:48 am » |
Hallo Magicrookie, zu allererst: Bitte setzte den Code in den Quoteblock  . Das ist deutlich übersichtlicher und man muss nicht so viel scrollen  Zu deinem Code: Generell sieht das doch ganz gut aus und man kann die ein oder andere Anleihe aus ein paar Tutorials erkennen. Ohne nun selbst den Code auf meinem Ardu aufzuspielen, kann ich dein Problem oder deine Frage nicht wirklich erkennen. (Wahrscheinlich klappt der HTML/JavaScript Teil nicht, da ein Alert in einem gekapselten Code, speziell als JS gekennzeichnet werden muss) SelfHTML AlertAnsonsten gibt es gute Threads hier: Dateien von SD über Ethernet & Arduino als HTTP ClientGruß, trib
|
|
|
|
|
Logged
|
|
|
|
|
Weinsberg, Germany
Offline
God Member
Karma: 2
Posts: 770
A Coder's Tale
|
 |
« Reply #2 on: January 30, 2012, 05:56:25 am » |
Falls Dein Problem ist dass Dein Browser nichts empfängt/tut obwohl Du per telnet was vom Arduino empfängst, dann setz mal explizit die Zeilenenden im HTTP-Header, z.B. statt client.println() schreib client.print('\r\n'). Und statt client.println(" <input type='submit' name='buttoncolorchange' id='button' value='Farbwechsel' method='post' onclick=' alert('Hallo Welt') '/> "); würde ich was wie client.println("<a href=\"javascript:alert('Hallo Welt')\">Farbwechsel</a>"); in den body-Teil schreiben.
|
|
|
|
« Last Edit: January 30, 2012, 05:59:01 am by Joghurt »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 18
|
 |
« Reply #3 on: February 06, 2012, 02:51:26 am » |
Danke erstmal für die flotten Antworten. War leider eine Woche außer Gefecht gesetzt und komme jetzt erst dazu mich mit ihnen zu befassen.
Vlt. hätte ich mein Problem dabei etwas genauer erklären sollen.
Das Ansprechen des Arduino klappt. Auch die Ausgabe Hallo Welt funktioniert einwandfrei. Jedoch möchte ich eine Aktion des Arduino mit diesem Button verknüpfen. D.h. zb soll der Button x=1 setzen. Das habe ich bisher über onclick= " x=1; " probiert , was erstmal nahe liegend aber scheinbar falsch war.
|
|
|
|
« Last Edit: February 06, 2012, 02:54:55 am by Magicrookie »
|
Logged
|
|
|
|
|
Germany
Offline
Jr. Member
Karma: 0
Posts: 64
|
 |
« Reply #4 on: February 06, 2012, 04:09:39 am » |
So einfach ist das auch wieder nicht  Was in Deinem Beispiel noch fehlt: - Ein Button, der einfach so ins Blaue hineindefiniert wird, ist wirkungslos. Du musst ihn in ein Formular einbauen, zweckmässigerweise würde ich in diesem Fall die Get-Methode benutzen. Wie das geht, findest Du bei selfhtml http://de.selfhtml.org/. Tipp: Ein hidden-Element wirst Du auch brauchen. Was das ist steht auch bei selfhtml. - Den Output des Servers musst Du irgendwie speichern, damit Du ihn dann auswerten kannst. In Deinem Beispiel wird der Output zeichenweise gelesen (c). Diese Zeichen könntest Du zu einem char-Array zusammenbauen. - Sobald der Server die erste Request-Zeile komplett übertragen hat, musst Du sie in Deinem Programm analysieren und entsprechend reagieren, das ist dann die Stelle wo Du Deiner Variablen einen neuen Wert zuweisen kannst. Viel Erfolg und Gruß, Thomas
|
|
|
|
|
Logged
|
twitter: @darktom
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 18
|
 |
« Reply #5 on: February 06, 2012, 07:48:46 am » |
Vielen Dank @ Nachtaktiv. Dein Beitrag hat mir sehr geholfen. Ich verstehe nun viele Beispiele anderer Arduinonutzer , die mir warscheinlich nun weiterhelfen können.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 18
|
 |
« Reply #6 on: February 13, 2012, 06:17:22 am » |
Soweit jetzt das aktuelle Programm. Ich kriege keine Rückgabe von der angesteuerten Homepage an den Arduino. Vlt weiß einer von euch da weiter. #include <SPI.h> //Anbindung microcontroller an Ethernet-Shield #include <Ethernet.h> #include <WString.h> #include <Client.h> #include <Server.h> int LED =4; boolean testdiode=false;
// Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; byte ip[] = { 192,168,1, 177 };
// Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80); String readString = String(100); // string for fetching data from address
void setup(){ Ethernet.begin(mac, ip); //Start der Ethernet-Verbindung und des Servers server.begin(); pinMode(4, OUTPUT); Serial.begin(9600); }
void loop(){
// listen for incoming clients EthernetClient client = server.available(); //Client Verbindung herstellen if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if (readString.length()< 100){ readString = readString + c; } Serial.print(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(); // print something, in HTML format: } else if (c == '\n') { if(readString.indexOf("3=AN") > -1) { togglediode; // verändert den status von testdiode } if(readString.indexOf("3=AUS") > -1) { togglediode; // verändert den status von testdiode }
client.println("<html>"); client.println("<head>"); client.println("<TITLE>Sörens Testpage</TITLE>"); client.println("</head>"); client.println("<body>");
client.println("<td align='center' bgcolor='#222222'><form method=get><input type=submit name=3 value='einschalten'></form></td>"); if (testdiode==true) { client.println("<input type=submit value=AN name=3 style=width:200;height:100;background-color:lightgreen;/>"); }else { client.println("<input type=submit value=AUS name=3 style=width:200;height:100;background-color:red;>"); }
client.println("</body>"); client.println("</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 readString=" "; delay(1); // close the connection: client.stop(); }
}
void togglediode (){ if (testdiode == false){ testdiode=true; digitalWrite(LED, HIGH); } else { testdiode=false; digitalWrite(LED, LOW); } }
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Jr. Member
Karma: 0
Posts: 64
|
 |
« Reply #7 on: February 13, 2012, 06:41:30 am » |
Hallo, wenn Du in Deinem Formular den Wert "einschalten" schickst und in der Auswertung dann auf "AN" oder "AUS" prüfst, kann das nicht funktionieren  if(readString.indexOf("3=AN") > -1) {
...
client.println("<td align='center' bgcolor='#222222'><form method=get><input type=submit name=3 value='einschalten'></form></td>");
Auch das Formular wird so nicht funktionieren. Der Submit-Button hat ja gar nichts zum Wegschicken. Du musst im gleichen Formular sowas definieren: <input type=\"hidden\" name=\"schalten\" value=\"aus\"> Funktioniert das denn mit den einfachen Anführungszeichen? 'einschalten' ? Ich würde schreiben \"einschalten\" Viel Erfolg!
|
|
|
|
|
Logged
|
twitter: @darktom
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 18
|
 |
« Reply #8 on: February 15, 2012, 01:44:36 pm » |
Sooo Hab die Befehle readString.append(c); und readString.contains() durch readString = readString + c; und if(readString.indexOf("3=AN") > -1) { getauscht und mit dm letzteren eine Abfrage gebastelt. Und habe mit Hidden unten drunter nochmal Name und Value bestimmt. Allerdings wenn ich nun klicke ändert sich in der Adressleiste immer noch nichts und somit kann ja auch nichts übertragen werden. Hab mir das ganze nochmal in diversen online Beispielen angeschaut und es mit meinem Code abgeglichen. Ich sehe keinen direkten Unterschied. Hab nun gute 8 Stunden damit zugebracht den Code ans laufen zu bekommen aber es läuft immer noch nicht. Zu dem folgenden Code Hier habe ich einen HTML-Code ausprobiert, welcher in einer HTML-Datei eine Rückgabe in der Adressleiste ergab, es jedoch in meinem Programm nicht tut. Vlt kann mir jmd eine Musterlösung für mein Problem geben, denn ich verzweifle so allmählig. Danke schonmal im Vorraus #include <SPI.h> //Anbindung microcontroller an Ethernet-Shield #include <Ethernet.h> #include <WString.h>
int LED =4; boolean testdiode=false;
// Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; byte ip[] = { 192,168,1, 190 };
// Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80); String readString = String(100); // string for fetching data from address
void setup(){ Ethernet.begin(mac, ip); //Start der Ethernet-Verbindung und des Servers server.begin(); pinMode(4, OUTPUT); Serial.begin(9600); }
void loop(){
// listen for incoming clients EthernetClient client = server.available(); //Client Verbindung herstellen if (client) { while (client.connected()) { if (client.available()) { char c = client.read(); if (readString.length()< 100){ readString = readString + c; } Serial.print(c); //oput chars to serial port if (c == '\n') { if(readString.indexOf("3=einschalten") > -1) { togglediode; // verändert den status von testdiode } if(readString.indexOf("3=ausschalten") > -1) { togglediode; // verändert den status von testdiode } client.println("<html>"); client.println("<head>"); client.println("<TITLE>Sörens Testpage</TITLE>"); client.println("</head>"); client.println("<body>");
client.println("<td align='center' bgcolor='#222222'><form method=get><input type=submit name=3 value='einschalten'></form></td>"); client.println(" <input type=\'hidden\' >"); client.println("<td align='center' bgcolor='#222222'><form method=get><input type=submit name=3 value='ausschalten'></form></td>"); client.println(" <input type=\'hidden\' >");
client.println("</body>"); client.println("</html>"); } } } // give the web browser time to receive the data readString=" "; delay(1); // close the connection: client.stop(); }
}
//UNTERPROGRAMME
void togglediode (){ if (testdiode == false){ testdiode=true; digitalWrite(LED, HIGH); } else { testdiode=false; digitalWrite(LED, LOW); } }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1297
|
 |
« Reply #9 on: February 15, 2012, 02:08:59 pm » |
Also was mir erstmal auffällt ist, das Deinem Formular der "action" Parameter fehlt. Außerdem müssen die hidden-Parameter innerhalb der <form> Tags stehen und nicht dahinter. Im Browser sollte Dein Formular wiefolgt aussehen <html> <head></head> <body> <form action="/" method="get"><input type=submit name=3 value='einschalten'> <input type="hidden" name="varname" value="inhalt"> </form> <form action="/" method=get><input type=submit name=3 value='ausschalten'> <input type="hidden" name="varname" value="inhalt"> </form> </body> </html>
Parameter würde ich auch nicht mit Zahlen oder Ziffern bezeichnen, sondern schon mit einem "sprechenden Namen" (z.B. "schalten=an" und "schalten=aus"), aber das ist Geschmackssache, technisch sollte das erstmal kein Problem sein. Was passiert denn, wenn Du die URL im Browser direkt anpasst, also Deinen Parameter "3=einschalten" mit einem "?" an die aufgerufene URL anhängst? Welche Ausgaben bekommst Du über die serielle Schnittstelle?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 18
|
 |
« Reply #10 on: February 27, 2012, 03:04:25 am » |
Hier mein aktueller Code #include <SPI.h> //Anbindung microcontroller an Ethernet-Shield #include <Ethernet.h> #include <WString.h> #include <Client.h> #include <Server.h> int LED =4; boolean testdiode=false;
// Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; byte ip[] = { 192,168,1, 190 };
// Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80); String readString = String(100); // string for fetching data from address
void setup(){ Ethernet.begin(mac, ip); //Start der Ethernet-Verbindung und des Servers server.begin(); pinMode(4, OUTPUT); Serial.begin(9600); }
void loop(){
// listen for incoming clients EthernetClient client = server.available(); //Client Verbindung herstellen if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if (readString.length()< 100){ readString = readString + c; } Serial.print(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(); // print something, in HTML format: } else if (c == '\n') { if(readString.indexOf("diode=AN") > -1) { togglediode; // verändert den status von testdiode } if(readString.indexOf("diode=AUS") > -1) { togglediode; // verändert den status von testdiode }
client.println("<html>"); client.println("<head>"); client.println("<TITLE>Sörens Testpage</TITLE>"); client.println("</head>"); client.println("<body>");
/* if (testdiode==true) { client.println("<input type=submit value=AN name=3 style=width:200;height:100;background-color:lightgreen;/>"); client.println("<input type=\'hidden\' name='anderung' value='AUS'> "); }else if (testdiode==false) { client.println("<input type=submit value=AUS name=3 style=width:200;height:100;background-color:red;/>"); client.println("<input type=\'hidden\' name='anderung' value='AN'> "); } */ if (testdiode==false) { client.println(" <form action='/' method='get'><input type=submit name=3 value='einschalten'> "); client.println(" <input type='hidden' name='diode' value='AN'> "); client.println(" </form> ");
} else if (testdiode==true) { client.println(" <form action='/' method=get><input type=submit name=3 value='ausschalten'> "); client.println(" <input type='hidden' name='diode' value='AUS'> "); client.println(" </form> ");
} client.println("</body>"); client.println("</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 readString=" "; delay(1); // close the connection: client.stop(); }
}
void togglediode (){ if (testdiode == false){ testdiode=true; digitalWrite(LED, HIGH); } else { testdiode=false; digitalWrite(LED, LOW); } }
Wenn ich den Button "einschalten" drücke steht Folgendes in der Adressleiste " http://192.168.1.190/?3=einschalten&diode=AN " Jedoch bleibt der LED status unverändert. Wenn ich auf der Seite " http://192.168.1.190/ " den Befehl "diode=AN" anhänge, passiert das selbe. Seriell wird ausgegeben: GET /?3=einschalten&diode=AN HTTP/1.1 GET /?3=einschalten&diode=AN HTTP/1.1 Ich vermute an dieser Stelle, das das Suchen von diode=AN im String nicht funktioniert. Kann mir allerdings nicht erklären warum nicht.
|
|
|
|
« Last Edit: February 27, 2012, 03:30:28 am by Magicrookie »
|
Logged
|
|
|
|
|
Germany
Offline
Jr. Member
Karma: 0
Posts: 64
|
 |
« Reply #11 on: February 27, 2012, 04:00:03 am » |
Hallo! Wenn Du die Funktion "togglediode" aufrufen möchtest, musst Du schreiben togglediode(); // verändert den status von testdiode Es wundert mich, dass sich Dein Code so überhaupt compilieren lässt  Zum Debuggen würde ich mir die Variable "readString" direkt vor der Auswertung anzeigen lassen: Serial.println(readString); Das ist mir jetzt so auf die Schnelle aufgefallen und heisst nicht, dass nicht noch weitere Fehler im Code sind  Viel Erfolg!
|
|
|
|
|
Logged
|
twitter: @darktom
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1297
|
 |
« Reply #12 on: February 27, 2012, 11:02:17 am » |
Um zu sehen, ob der String gefunden wird, kannst Du ja die Debugausgaben direkt an die passende Stelle schreiben: else if (c == '\n') { if(readString.indexOf("diode=AN") > -1) { Serial.println("diode=AN gefunden"); togglediode(); // verändert den status von testdiode } if(readString.indexOf("diode=AUS") > -1) { Serial.println("diode=AUS gefunden"); togglediode(); // verändert den status von testdiode }
Achso, das sich die Diode an- und ausschalten läßt, hast Du getestet, oder? Sorry für die Frage, aber manchmal ist es am Ende dann doch sowas simples. Mario.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 18
|
 |
« Reply #13 on: February 27, 2012, 02:06:39 pm » |
Danke euch beiden. Es war ein simpler Anfängerfehler. Das Unterprogramm hatte ich ohne die Klammern aufgerufen und es konnte somit nicht starten. Programm läuft. Super! Nach 3 Wochen Rumknobelei war es nun doch so etwas Simples.
An dieser Stelle stehe ich allerdings schon wieder vor einer neuen Herrausforderung. Ich würde gerne die LED dimmen und dafür über ein HTML-Textfeld eine Zahl übermitteln.
Kann mir dafür vielleicht jemand einen Tipp geben nach was ich dafür genau suchen müsste, vielleicht sogar einen Link zu einem Guide oder eine eigene kurze Erklärung eines Befehls und seiner Anwendung. Ich habe bis jetzt etwas von einem "altio" Befehl gelesen, aber wurde noch nicht sehr schlau daraus.
Vielen Dank schonmal für die kommenden Antworten! Ich freue mich drauf weiter zu machen.
PS: Falls sich jemand für den vorerst fertigen LED-Webserver-Ansteuerungcode interessiert, schreibt mir. Ich teile und helfe gerne, nachdem mir so toll geholfen wurde.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1297
|
 |
« Reply #14 on: February 27, 2012, 02:18:17 pm » |
LED dimmen geht über PWM. Siehe http://arduino.cc/en/Tutorial/Fading. Allerdings wirst Du dann die LED an einen anderen Ausgang anschliesse müssen. Pin 4 ist kein PWM Ausgang. Wenn es um das HTML-Formular geht, brauchst Du nur innerhalb der Formulars ein <input type=text name=dim></input>
Der Wert hängt dann als "&dim=111" mit an der URL dran, wenn Du das Formular abschickst. Du hast dann nur noch die Aufgabe, den Wert aus der URL zu filtern und in eine Zahl umzuwandeln. Dabei ist wichtig, das der Wertebereich von 0 bis 255 geht. Was soll denn "altio" sein? HTML, oder C-Code? Das sagt mir nämlich gar nix. Falls Du "atoi()" meinst, ist das die Funktion die einen String ein Integer umwandeln kann.
|
|
|
|
|
Logged
|
|
|
|
|
|