LED toggeln per Taster und Web...

Hallo ihr lieben Leute,

Ich bin schon eine Weile am Probieren und forschen, aber irgendwie fehlt mir der richtige Ansatz...
Ich habe hier eine Arduino UNO mit Ethernetshield. Als Schaltung habe ich eine LED an Pin 5 und einen Taster an Pin 7.
Nun zu meinem Problem:
Ich möchte die LED per Website an- bzw. aus-schalten können und natürlich auch per Taster auf dem Breedboard. Dabei soll auf der Webseite der aktuelle Status der LED angezeigt werden.

Hab jetzt schon einiges gelesen, aber irgendwie fehlt mir der richtig dreh!
Ich konnte schon schalten per Web aber den richtigen Status habe ich noch nicht angezeigt bekommen. Und beim Aktualisieren der Webseite wurde auch wieder geschalten... :~

Wer kann mir Tipps geben?

Gruß
TuX

Naja, ist ja eigentlich logisch.
Status speichern, bei Togglebefehl umschalten und Status aktualisieren. Aber so ohne Sketch wird's schwierig.

ja ich habe einen Tip:
Bitte sketch.
Grüße Uwe

Hallo,

Also bitte hier mein Sketch:

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0x54, 0x55, 0x58, 0x10, 0x00, 0x24 }; // entspricht einer MAC von 84.85.88.16.0.36
byte ip[] = { 192, 168, 178, 222 }; // IP-Adresse
byte gateway[] = { 192, 168, 178, 1 }; // Gateway
byte subnet[] = { 255, 255, 255, 0 };

EthernetServer server = EthernetServer(80);

int LedPin = 5;
int ButtonPin=7;
int counter=0;
int tasterWert=0;
int vorherTasterWert=0;

String readString = String(100); // string for fetching data from address
boolean LedPinON = false; // Status flag

void setup(){
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
pinMode(LedPin, OUTPUT);
pinMode(ButtonPin,INPUT);

Serial.begin(9600);
}

void loop(){

// Create a client connection
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();

//read char by char HTTP request
if (readString.length() < 100) {

//store characters to string
// readString.append(c); removed by Katsu
readString = readString + c; // insert by Katsu
// very simple but it works...
}

Serial.print(c); //output chars to serial port

if (c == '\n') { //if HTTP request has ended

if(readString.indexOf("?3=einschalten") > -1) {
digitalWrite(LedPin, HIGH);
Serial.println("LED eingeschaltet! >>WEB");
LedPinON = true;
}
if(readString.indexOf("?3=ausschalten") > -1){
digitalWrite(LedPin, LOW);
Serial.println("LED ausgeschaltet! >>WEB");
LedPinON = false;
}

if(readString.indexOf("all=Alles+aus") > -1){
digitalWrite(LedPin, LOW);
Serial.println("Alles ausgeschaltet");
LedPinON = false;
}

tasterWert= digitalRead(ButtonPin);
if (vorherTasterWert != tasterWert)
{
if(tasterWert==HIGH){
counter++;
}
}
vorherTasterWert=tasterWert;
Serial.print("tasterWert=");
Serial.println(tasterWert);
Serial.print("vorherTasterWert=");
Serial.println(vorherTasterWert);
Serial.print("counter=");
Serial.println(counter);

//--------------------------HTML------------------------
client.println("HTTP/1.1 200 OK");

client.println("Content-Type: text/html");

client.println();

client.print("");

client.print("Beleuchtung Ein/Aus-Schalten");

client.println("");

client.print("");

client.println("


");

client.println("

Beleuchtung Ein/Aus-Schalten

");

client.println("



");

client.println("

Ausgänge schalten:
");

client.println("
");

client.println("

");

client.println("

");

client.println("

");

client.println("

");

client.println("

");

if (counter%2 ==0){
digitalWrite(LedPin,HIGH);
Serial.println("Taster betaetigt, LED eingeschaltet!");
LedPinON=true;
}
else
{
digitalWrite(LedPin,LOW);
Serial.println("Taster betaetigt, LED ausgeschaltet!");
LedPinON=false;
}

if (LedPinON){
client.println("

");
client.println("
Ausgang 3
EIN");

}
if (!LedPinON){
client.println("

AUS");

}

client.println("

");
client.println("
");
client.println("");
client.println("");

//---Ausgänge schalten---

//clearing string for next read
readString="";

//stopping client

client.stop();
}}}}}

Wenn ich den Network krempel rausschmeiße schaltet der Taster. Ich bin ratlos....

Gruß
TuX

tux_der_pingu:
Wer kann mir Tipps geben?

Meine Tipps:

Tipp 1: Erstelle einen klaren und logischen Ablauf für die loop-Funktion!

Tipp 2: Wegen der Übersichtlichkeit: Lagere Code von der loop in Unterfunktionen aus!

Tipp 3: Werde Dir darüber klar: HTTP ist ein Client-Server Protokoll, d.h.: Der Client stellt die "Anfragen", daraufhin sendet der Server seine "Antworten" zurück. D.h. wenn Du auf Deinem Server (Arduino) den Button drückst und den LED-Status änderst, dann bekommt der Client (Webbrowser) davon zunächst mal nichts mit, bis er die nächste Anfrage stellt und eine Antwort zurückbekommt.

Tipp 4: Das was Du möchtest, ist daher per HTTP nur mit ständigem Polling des Arduinos zu realisieren: Der Webbrowser muß immer wieder in kurzen Zeitabständen neue Anfragen stellen, nur dann bekommt er mit, wenn der LED-Status am Arduino-Button geändert wurde und nicht über das Browser-Interface. Allerdings: Wenn der Zeitabstand zwischen den Anfragen z.B. 10 Sekunden beträgt, erfolgt beim Drücken des Schaltbuttons am Arduino die Statusanzeige im Browser immer mit einer Verzögerung zwischen 0 und 10 Sekunden, NIEMALS direkt in Echtzeit!

Tipp 5: Ein ständiges automatisches Polling bekommst Du per HTML "Meta-Refresh" hin, z.B. alle 10 Sekunden.

Tipp 6: Dein Server muss auf drei verschiedene Anfragen reagieren können:

  1. Anfrage: Schalte ein und gib den LED-Status aus
  2. Anfrage: Schalte aus und gib den LED-Status aus
  3. Anfrage: Gib einfach nur den LED-Status aus
    Dazu muß Dein Server natürlich auf drei verschiedene Client-Anfragen vom Browser reagieren können, und das kann er derzeitig nicht.

Tipp 7: Mal kurz in Pseudo-Code die von mir vorgeschlagene Logik für die Arduino-loop:

void loop()
{
if (buttonPressed()) // wenn Taste gedrueckt
LEDstatus=!LEDstatus; // Status wechseln
if client.available() // Es liegt eine Anfrage von einem Client vor
{
Anfrage=GetHTTPAnfrage(client); // welche Anfrage ist es?
if (Anfrage==einschalten) // aha, einschalten
LEDstatus=true;
else if (Anfrage==ausschalten) // aha, ausschalten
LEDstatus=false;
SendeHTML(); // sende Statusanzeige an den Client
}

Mal so als ganz grober Rahmen (das ist aber KEIN fertiger Code!) für die Programmlogik.