Arduino via Webserver und seriell Steuern?

Halllo Leute,

also ich baue gerade ein Projekt, in dem ich den Arduino sowohl via Webserver als auch über VB steuern möchte. Soweit so gut. Jeweils einen Arduino via Webserver Steuern ist kein Problem und auch seriell geht. Aber wie ist es in einen sketch zu bekommen?

Seriell schalte ich über die Byte Codes von a-h jer eine LED an und aus, das geht. In einem Webformular hingegen nehme ich ja Variablen mit einem bestimmten Wert. Wie kan ich nun diese beiden Sachen vereinen?

Viele Grüße Can

Die Frage ist doch, was passiert wenn der eine dies sagt und der andere was anderes ?
Ansonsten, wenn das egal ist oder nicht vorkommt, wo ist das Problem ?

Ein Arduino macht doch nichts ausser fragen ob was gekommen ist, und in der Regel kommt nichts, also macht er auch nichts.
Wo ist das Problem, zwei mal zu fragen ?

Deine HTML Form sollte besser nicht den gewünschten Zustand, sondern die gewünschte Aktion enthalten.
Sonst musst du ( Arduino ) dir merken, was schon gemacht wurde, um zu sehen was neu ist. ( Aber auch das geht )

Ich habe mein gedankliches Problem mit den verschieden Variablen, die das gleiche tun sollen.

Ich habe seriell an so eine Lösung gedacht:

 // a == an und b == aus
                if(incomingData == 97){
                  digitalWrite(ledPin1, HIGH);
                  Serial.println("Led 1 ON");
                }
                if(incomingData == 98){
                  digitalWrite(ledPin1, LOW);
                  Serial.println("Led 1 OFF");
                }

aber wie kann ich diese Variablen auch so im Webserver verwenden?

Hoppla, "Deine HTML Form" in meinem letzten Post geht davon aus dass der Arduino der webserver ist, und die Steuerung über einen PC Browser als client geschieht.
Ist das überhupt richtig, oder ist dein Arduino ein Client, der sich von einem Server holt, was er tun soll ?

Ich verstehe deinen ersten Eintrag so, dass beides einzeln schon läuft.

Was ist dein Problem damit, aus zwei Sketchen eines zu machen ?

Hi nochmal,

also du hast schon Recht, der Arduino soll der WebServer sein. Das Code sniplet ist die Steuerung via seriell. Mein Problem ist genauer gesagt, wie kann ich z.B. einen Wert bzw. Zustand seriell auslesen, um ihn auch im Webformular darzustellen.

Konkret soll eine Steckdosenleiste mit einem 8fach Relais betrieben werden. Die Steuerung der Steckdosen soll hierbei sowohl via einer Visual Basic Anwendung gehen und auch via Web Interface. Web Interface alleine ist kein Thema, schalten über seriell auch nihct. Aber wie kann ich beide mit den gleichen Variablen verwenden und auf dem seriellen Port Zustände abfragen?

Aber wie kann ich beide mit den gleichen Variablen verwenden

Ich verstehe es immer noch nicht ganz, fürchte ich.
Oder fragst du nach so einer Erweiterung:

          static boolean ledValue1; // static : behält den Wert für den nächsten loop() Durchlauf;

          char incomingData = Serial.read();
 
         // a == an und b == aus
                if(incomingData == 'a'){
                  ledValue1 = HIGH;
                  Serial.println("Led 1 ON");
                }
                if(incomingData == 'b'){
                  ledValue1 =  LOW;
                  Serial.println("Led 1 OFF");
                }
                
             digitalWrite(ledPin1, ledValue1);

             // ledValue1 kann  beliebig weiter verwendet werden

hi,

so ganz komme ich auch nicht mit, aber eines zum verständnis:
man kann niemals mehrere sketches auf einmal laufen lassen. wenn Du also mit webserver und seriell arbeiten willst, mußt Du das im gleichen sketch schreiben.
damit kannst Du auch bei beiden arten die gleichen variablen ansprechen, solange sie am anfang des sketches, also global, definiert sind.

gruß stefan

Du definierst Dir ein globales Array, welches den Zustand der einzelnen "Schalter" speichert. Ist der Inhalt "0" ist der Schalter aus, bei 1 ist er an.

byte switch[8] = { 0,0,0,0,0,0,0,0};

Bekommst Du seriell Befehle, setzt Du erst den entsprechenden Wert im Array und schaltest dann das Pin

                if(incomingData == 'a'){
                  switch[0] = 1;
                  ledValue1 = HIGH;
                  Serial.println("Led 1 ON");
                }
                if(incomingData == 'b'){
                  switch[0] = 0;
                  ledValue1 = LOW;
                  Serial.println("Led 1 OFF");
                }

Bei der Ausgabe des Webformulars verwendest Du vermutlich sowas wie

    <input type="radio" name="LED1" value="a"> LED1 on

    <input type="radio" name="LED1" value="b"> LED1 off

Damit wäre aber immer die erste Auswahl aktiv, egal welchen Zustand der Schalter wirklich hat. Du mußt also den Zustand unterscheiden:

char* htmloutput;
if(switch[0] == 0) {
    htmloutput="    <input type=\"radio\" name=\"LED1\" value=\"a\"> LED1 on
<input type=\"radio\" name=\"LED1\" value=\"b\" selected> LED1 off
";
} else {
    htmloutput="    <input type=\"radio\" name=\"LED1\" value=\"a\" selected> LED1 on
<input type=\"radio\" name=\"LED1\" value=\"b\"> LED1 off
";
}

Damit ist dann immer der aktuelle Zustand im Formular abgebildet. Mein Beispiel ist recht uneffktiv, vor allem wenn Du 8 Schalter hast kann man das sicher "dynamischer" mit deutlich weniger redundanten Strings lösen. Wichtig ist hier nur das Schlüsselwort "selected" das dem HTML-Form sagt, welcher Radio-Button aktiv ist.
Mario.

Wow, das ist echt genial. So etwas meinte ich! Aber auf ein Array wäre ich einfach nicht gekommem... Klasse!

Nun ist nur noch die Frage, kann ich Zustände pber die serielle Schnittstelle auch abfragen?
Ich will nämlich auch in meiner VB Anwendung graphisch anzeigen, welcher Schalter, wie gesetzt ist.

Viele Grüße, Can

laserbrain:
Nun ist nur noch die Frage, kann ich Zustände pber die serielle Schnittstelle auch abfragen?

Ja, kannst ja ein eigenes Kommando dafür machen:

if(incomingData == 'x'){
   for ( int i=0;i<8;i++) {
                  Serial.println(switch[0],DEC);
    }
}

Schickst Du ein "x" über die Serielle Schnittstelle, bekommst Du den aktuellen Zustand der Pins zurück. Mit einer "0" für LED aus und "1" für LED an.
Ich würde das auch als Ergebnis bei jedem Setzen der LEDs per serieller Schnittstelle liefern, da Du zwar eine LED schaltest, aber sich ja in der Zwischenzeit auch andere LEDs geändert haben können (via Webinterface). Damit hast Du in VB nach jedem Schaltvorgang trotzdem gleich wieder den korrekten Stand aller Schalter.

Super genial, ich merke schon ich habe noch viel zu lernen.

Danke schön! Ich werde berichten wie es ausgegangen ist mit meinem Projekt.

Nun habe ich dank Euerer Hilfe die serielle Kommunikation perfekt. Auch die Zustände im HTML Code werden richtig angezeigt. Aber jetzt klappt das Schalten aus dem WebServer nicht. Ich dachte mir mit:

if(readString.indexOf("LED1=a") >0)
              {switch[0] = '1';}
          if(readString.indexOf("LED1=b") >0)
              {switch[0] = '0';}

Wird mein richtiger Wert geschrieben, aber da tut sich einfach gar nichts...

Poste mal den ganzen Sketch.
Was mir auffällt ist, das Du

switch[0] = '0';

schreibst, damit meckert der Compiler zwar nicht, aber Du weist das Zeichen Null, nicht den Wert Null zu. Damit ist aber auch switch[0] größer Null, wenn das Zeichen "0" drin steht. Weiterhin fehlt das Schalten des Ausgangs, also ein "digitalWrite(LED1, HIGH)" oder ähnliches, oder hast Du das an einer anderen Stelle im Code?

Hi und guten Morgen,

also der ganze Sketch kommt hier. Die Variablen sind alle da und auf der seriellen Kommunikation läuft alles einwandfrei. Nur Steuern über HTML geht nicht. Anzeigen des Status schon. (Im HTML Teil ist nur eine LED bisher testweise eingebaut)

/*
  Web Server
 
 A simple web server that shows the value of the analog input pins.
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 * Analog inputs attached to pins A0 through A5 (optional)
 
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 
 */

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

int ledPin1 = 2;
int ledPin2 = 3;
int ledPin3 = 4;
int ledPin4 = 5;
int ledPin5 = 6;
int ledPin6 = 7;
int ledPin7 = 8;
int ledPin8 = 9;

//Globales Array mit dem Zustande der Pins...
byte pinbelegung[8] = { 0,0,0,0,0,0,0,0};

char incomingData = 0;

//Zum Lesen der Daten uas HTML GET Befehl
String readString = String(100);      // string for fetching data from address

    static boolean ledValue1; // static : behält den Wert für den nächsten loop() Durchlauf;
    static boolean ledValue2; // static : behält den Wert für den nächsten loop() Durchlauf;
    static boolean ledValue3; // static : behält den Wert für den nächsten loop() Durchlauf;
    static boolean ledValue4; // static : behält den Wert für den nächsten loop() Durchlauf;
    static boolean ledValue5; // static : behält den Wert für den nächsten loop() Durchlauf;
    static boolean ledValue6; // static : behält den Wert für den nächsten loop() Durchlauf;
    static boolean ledValue7; // static : behält den Wert für den nächsten loop() Durchlauf;
    static boolean ledValue8; // static : behält den Wert für den nächsten loop() Durchlauf;
    
/*
//Erst Array ändern, dann Pin setzen
if(incomingData == 'a'){
                  switch[0] = 1;
                  ledValue1 = HIGH;
                  Serial.println("Led 1 ON");
                }
                if(incomingData == 'b'){
                  switch[0] = 0;
                  ledValue1 = LOW;
                  Serial.println("Led 1 OFF");
                }
*/



// 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(192,168,178, 225);

// 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() {
  

 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
  pinMode(ledPin5, OUTPUT);
  pinMode(ledPin6, OUTPUT);
  pinMode(ledPin7, OUTPUT);
  pinMode(ledPin8, OUTPUT);


  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

Teil 2 vom Sketch:

void loop() {
                //Daten aus seriellen Kanälen auswerten!
                 char incomingData = Serial.read();
                
                
                 // a == an und b == aus
                //Schaltet ersten Pin!
                  if(incomingData == 'a' ){
                    pinbelegung[0] = 1;
                    ledValue1 = HIGH;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 ON");
                  }
                  if(incomingData == 'b'){
                    pinbelegung[0] = 0;
                    ledValue1 =  LOW;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 OFF");
                  }
                  
                  digitalWrite(ledPin1, ledValue1);  // ledValue1 kann  beliebig weiter verwendet werden
                  
                // c == an und d == aus
                //Schaltet ersten Pin!
                  if(incomingData == 'c' ){
                    pinbelegung[1] = 1;
                    ledValue2 = HIGH;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 ON");
                  }
                  if(incomingData == 'd'){
                    pinbelegung[1] = 0;
                    ledValue2 =  LOW;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 OFF");
                  }
                  
                  digitalWrite(ledPin2, ledValue2);  // ledValue1 kann  beliebig weiter verwendet werden
             
                 // e == an und f == aus
                //Schaltet ersten Pin!
                  if(incomingData == 'e' ){
                    pinbelegung[2] = 1;
                    ledValue3 = HIGH;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 ON");
                  }
                  if(incomingData == 'f'){
                    pinbelegung[2] = 0;
                    ledValue3 =  LOW;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 OFF");
                  }
                  
                  digitalWrite(ledPin3, ledValue3);
                  
                   // g == an und h == aus
                //Schaltet ersten Pin!
                  if(incomingData == 'g' ){
                    pinbelegung[3] = 1;
                    ledValue4 = HIGH;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 ON");
                  }
                  if(incomingData == 'h'){
                    pinbelegung[3] = 0;
                    ledValue4 =  LOW;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 OFF");
                  }
                  
                  digitalWrite(ledPin4, ledValue4);
                  
                 
                    // i == an und j == aus
                //Schaltet ersten Pin!
                  if(incomingData == 'i' ){
                    pinbelegung[4] = 1;
                    ledValue5 = HIGH;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 ON");
                  }
                  if(incomingData == 'j'){
                    pinbelegung[4] = 0;
                    ledValue5 =  LOW;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 OFF");
                  }
                  
                  digitalWrite(ledPin5, ledValue5);
                  
                    // k == an und l == aus
                //Schaltet ersten Pin!
                  if(incomingData == 'k' ){
                    pinbelegung[5] = 1;
                    ledValue6 = HIGH;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 ON");
                  }
                  if(incomingData == 'l'){
                    pinbelegung[5] = 0;
                    ledValue6 =  LOW;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 OFF");
                  }
                  
                  digitalWrite(ledPin6, ledValue6);
 
 
               // m == an und n == aus
                //Schaltet ersten Pin!
                  if(incomingData == 'm' ){
                    pinbelegung[6] = 1;
                    ledValue7 = HIGH;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 ON");
                  }
                  if(incomingData == 'n'){
                    pinbelegung[6] = 0;
                    ledValue7 =  LOW;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 OFF");
                  }
                  
                  digitalWrite(ledPin7, ledValue7);
                  
                  // o == an und p == aus
                //Schaltet ersten Pin!
                  if(incomingData == 'o' ){
                    pinbelegung[7] = 1;
                    ledValue8 = HIGH;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 ON");
                  }
                  if(incomingData == 'p'){
                    pinbelegung[7] = 0;
                    ledValue8 =  LOW;
                    //Serial.println(ledValue1);
                    Serial.println("Led 1 OFF");
                  }
                  
                  digitalWrite(ledPin8, ledValue8);
                  
  // 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);
         
         //String zum Lesen zusammensetzen         
         if (readString.length() < 100)
            {
              //store characters to string
              readString += c; //replaces readString.append(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) {
          
        //HTML gelesenen String in Argument umwandeln!
          if(readString.indexOf("incomingData=a") >0)
              {incomingData = 'a';}
          if(readString.indexOf("incomingData=b") >0)
              {incomingData = 'b';} 
        
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          
          client.println("<form method=get>");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
          //client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          
          //char* htmloutput;
              if(pinbelegung[0] == 0) {
                  client.println("<input type=\"radio\" name=\"incomingData\" value=\"a\"> LED1 on
<input type=\"radio\" name=\"incomingData\" value=\"b\" checked> LED1 off
");
              } else {
                 client.println("<input type=\"radio\" name=\"incomingData\" value=\"a\" checked> LED1 on
<input type=\"radio\" name=\"incomingData\" value=\"b\"> LED1 off
");
              }

          
        client.println("<input type=submit name='Schalten'></form>");
          
          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(350);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
          
          
                      //Ausgabe aller Zustände auf Console
                      if(incomingData == 'x'){
                       for ( int i=0;i<8;i++) {
                                      Serial.println(pinbelegung[i],DEC);
                        }
                    }
        
        
        
}

Du schaltest im HTML-Teil ja auch die Pins nicht. Falls Du denkst, das es reicht ein

if(readString.indexOf("incomingData=a") >0)
              {incomingData = 'a';}

zu machen, muss ich Dich leider enttäuschen. Beim nächsten Durchlauf von loop() wird das eben gesetzte incomingData durch das "char incomingData = Serial.read();" direkt wieder überschrieben.
Ich würde an Deiner Stelle folgendes machen. Das setzen der Ausgänge erfolgt erst ganz am Ende von loop() und nicht in den einzelnen Code-Zeilen. Das Ganze dann in einer Schleife. Damit das ganze einfacher wird, würde ich die einzelnen Pins für die LEDs auch in ein Array packen:

//das hier ganz oben wo auch pinbelegung[] definiert wird:
byte ledpins[8] = { 2,3,4,5,6,7,8,9};

//das hier am ende von loop um alle geänderten pins zu setzen
for (int i=0;i<8;i++) digitalWrite(ledpins[i],pinbelegung[i]);

Oh man, da wäre ich nicht drauf gekommen. Aber dann bastel ich jetzt mit den Infos, so weiter.

Viele Dank!

So mein Projekt nähert sich dem Ende...

Aber ein Problem ist sehr merkwürdig.

Ich generie mir ein HTML mit radio buttons für on/off, aber ich muss das Skript immer zweimal ausführen, bis sich der Pin schalten lässt. Wenn ich den Befehl direkt an der Adresse mit übergebe,, dann passiert das nicht???

Bsp. /?incomingData0=a wird sofort ausgeführt, über

LED0 on

muss ich das Formular eben zweimal abschicken...

Poste mal den kompletten HTML-Code Deines Formulars.

hi,

ich schalte mein wohnzimmerlicht mittels arduino-webserver, und ich habe das gleiche phänomen, wenn ich mit meinem ipod touch schalte. von jedem anderen gerät muß ich nur einmal "drücken" (computer, galaxy note, blackberry, billig-android-tablet).
hab's mir noch nicht angesehen, weil der ipod ohnehin nicht dafür gedacht ist.

gruß stefan