Ausgang per Web schalten mit PHP

Hallo,
ja also, das habe ich mir schon gedacht, Einfach geht es ja nie :grin:
Aber gut, ich hoffe das kriege auch irgendwie hin, ich werde heute abend mal eine ‚ÄúNachtschicht‚ÄĚ einlegen und mal schauen wie weit ich komme (wahrscheinlich garnicht weit :frowning: )
An millis hatte ich auch schon gedacht… (Obwohl Denke ja nicht so meine Stärke ist, wie wir festgestellt haben… LoL )

Zu Deinem PHP-Code:
Warum verwendest Du immer Arrays in den Variablennamen?
z.b.
Code:

Da wird doch bei ‚Äúled2‚ÄĚ die Zeit, die Ausgew√§hlt wird, rein gepackt, oder nicht ?

Das ist schon richtig, aber was ist der Grund f√ľr das Array? Warum nicht eine ‚Äúeinfache‚ÄĚ Variable also

<select name="led2">
    <option value="15">15 min</option>
    <option value="30">30 min</option>
    <option value="60">60 min</option>
   </select>

In Deinem PHP-Script hast Du dann ein $_GET[‚Äėled2‚Äô] das den ausgew√§hlten Wert aus dem select enth√§lt. Du bekommst bei einem Formular immer nur den im select-Tag ausgew√§hlten Wert zur√ľck, nicht alle Werte als Array.
Was den Arduino Sketch angeht. Wie immer schrittweise vorgehen. Also erstmal mit einem Pin und der Zeitsteuerung und viel Debugausgaben, bis es funktioniert und dann schrittweise erweitern.

Zur Motivation :smiley:
Ich habe das heute Morgen mal fix umgesetzt. Es war einfach zu warm um noch schlafen zu können :sweat_smile:
Es funktioniert. Sogar recht einfach. Auch die Steuerung der ‚ÄúTimer‚ÄĚ √ľber millis() ist eigentlich recht simple.
Hier der Auszug zur Steuerung:

¬† //pr√ľfen ob eine Sekunde vergangen ist
  if(millis()-previousMillis >= 1000) {
    //aktuelle Zeit merken
    previousMillis = millis();

    //alle timer auswerten 
    for(int t=0; t<NUMTIMER;t++) {

      //nur timer beachten, die auch verwendet werden sollen (positive PIN nummer)
      if(timerpin[t] > 0 ){

        //bei aktuellem timer eine sekunde abziehen, wenn "0", dann abgelaufen
        if( --timerlength[t] == 0) {

          //Ausgang umschalten ( HIGH -> LOW oder LOW -> HIGH)
          digitalWrite(timerpin[t],!digitalRead(timerpin[t]));  

          //timer deaktivieren ( timer mit pin "-1" sind inaktiv)
          timerpin[t] = -1;

          //debug
          Serial.print("Timer ");
          Serial.print(t);
          Serial.println(" abeglaufen.");
        }
      }  
    }
  }

Zur Erkl√§rung. Ich verwende mehrere Timer deren Daten ich in zwei Arrays speichere. timerlength[] enth√§lt die Dauer in Sekunden, die ein timer noch laufen muss. timerpin[] enth√§lt die Pin-Nummer, die f√ľr diesen Timer geschaltet werden soll. Der Index der Arrays entspricht jeweils einem einzelnen Timer.
Setzt man z.B. timerlength[2]=30 und timerpin[2]=9, hat man den 3. Timer auf 30 Sekunden Dauer f√ľr Pin 9 gesetzt. Gleichzeitig setzt man noch Pin 9 z.B. auf HIGH. Nach Ablauf des Timers wird der Code dann Pin 9 automatisch wieder auf LOW setzen. Setzt man Pin 9 beim Starten des Timers auf LOW, wird es nach Ablauf des Timers auf HIGH gesetzt.

Hallo Mario,
sage mal,wann schläfst du eigentlich ? XD
Du hast ja Online Zeiten… :wink:

So, aber erstmal vielen Dank f√ľr die Motivation‚Ķ :fearful:
Sieht schwierig aus, aber der Reihe nach, sollte ich nicht erstmal ein PHP/HTML Script erstellen ?
Ich habe mich mal versucht:

<html>
<head>
</head>
<body>

<h1>Test</h1>
<?php

$arduino_ip = "192.168.178.216";
$arduino_port = "23";

function arduino_send($ip,$port,$command) {
    $res = fsockopen($ip,$port);
    if($res) {
        fwrite($res,$command);
        $ret =fread($res,1);
        echo "arduino_send() returned = $ret 
\n";
        return $ret;
    } else {
        echo "Fehler, Kommando konnte nicht abgesetzt werden";
    }
}

if(isset($_GET['led1'])) {
    $led1 = $_GET['led1'];
    arduino_send($arduino_ip,$arduino_port,"S".chr(4).chr($led1));
} else {
    $led1 = arduino_send($arduino_ip,$arduino_port,"R".chr(4).chr(0));
}

if(isset($_GET['V1'])) {
    $V1 = $_GET['V1'];
    arduino_send($arduino_ip,$arduino_port,"S".chr(4).chr(1).chr($V1));
} else {
    $V1 = arduino_send($arduino_ip,$arduino_port,"R".chr(4).chr(0));
}
?>
<form action="">
  <p>
LED 1 : 
<input type="radio" name="led1" value="0" <?php if($led1==0) echo "checked" ?> >aus -
<input type="radio" name="led1" value="1" <?php if($led1==1) echo "checked" ?> >an


  </p>
  <input type="submit" name="submit" value="Abschicken">
</form>


<form action="">
  <p>
   <select name="V1">
    <option value="15">15 min</option>
    <option value="30">30 min</option>
    <option value="60">60 min</option>
   </select>
  </p>
   <input type="submit" name="submit" value="Starten">
   <input type="reset" name="stop" value="Stop">
</form>

</body>
</html>

Aber wahrscheinlich wieder falsch… :blush:
Ich trau mich schon garnicht mehr‚Ķ :~ Das ist absolutes Neuland f√ľr mich‚Ķ
Bleibt aber noch die Frage, wie kann ich den Stop Button aktivieren? Wenn ich da rauf klicke, passiert nix… :frowning:

sage mal,wann schläfst du eigentlich ?

Regelm√§√üig, bin halt nur Fr√ľhaufsteher.
Der HTML-Code sieht schon mal ganz gut aus. Wenn Du zwei Formulare machst, kannst Du aber immer nur eins abschicken, das muss Dir klar sein. Wenn das gewollt ist, dann ist das kein Problem. Du kannst dann halt entweder die Pins direkt schalten oder alt mit Zeitverzögerung.
Das <input type=reset ‚Ķ> verwendet man in Formularen, um diese wieder in den Zustand zu bringen, die sie beim Laden der Seite hatten. Also z.B. Textfelder ohne Inhalt oder wieder mit dem ‚Äúdefault‚ÄĚ-Inhalt, radio-buttons oder select-Tags die wieder die origin√§re Auswahl zeigen. Das gilt aber nur f√ľr das Formular zu dem das input-Tag geh√∂rt. Au√üerdem wird beim anklicken dieses Buttons das Formular nicht abgeschickt, das Zur√ľckstellen passiert nur im Browser, daher passiert da auch nix weiter.
Auch der PHP-Code sieht gut aus, die Auswertung f√ľr ‚ÄúV1‚ÄĚ ist korrekt und sollte funktionieren, wenn der Arduino-Code darauf angepasst wird.
Einen Verbesserungsvorschlag h√§tte ich aber trotzdem. Da die Funktionalit√§t ‚ÄúPin schalten‚ÄĚ und ‚ÄúPin auslesen‚ÄĚ bereits vorhanden ist und funktioniert (Kommando ‚ÄúS‚ÄĚ und ‚ÄúR‚ÄĚ) w√ľrde ich einfach neue Kommandos definieren, die zus√§tzlich die Funktion ‚ÄúT‚ÄĚ ‚Üí Timer f√ľr Pin x auf n Minuten setzen und z.B. ‚ÄúU‚ÄĚ ‚Üí liefere die Zeit die der Timer f√ľr Pin x noch l√§uft abbildet. Das sind dann einfach nur weitere Bl√∂cke im switch-case Konstrukt im Arduino-Code. Den gr√∂√üten Teil kannst Du sogar von ‚ÄúR‚ÄĚ und ‚ÄúS‚ÄĚ klauen und nur um die Timer-Geschichte erweitern.

Wie Du siehst, warst Du mit Deinem "Aber wahrscheinlich wieder falsch… viel zu pessimistisch.

Ein kleiner Tip noch f√ľr den Arduino-Code. Den R√ľckgabewert kann man auch mittels ‚Äúclient.print()‚ÄĚ statt client.write() zur√ľckliefern. Dann kommt die zur√ľckgelieferte Zahl (z.b. 125) als String ‚Äú125‚ÄĚ (also 3 Zeichen und nicht ein Byte) beim PHP an und kann direkt in einer Variablen weiter verarbeitet werden. Man muss dann nicht die Bytes einzeln lesen und den Wert zusammenrechnen.
Viel Erfolg im ‚ÄúK√§mmerlein‚ÄĚ :smiley:

Hi,

Einen Verbesserungsvorschlag h√§tte ich aber trotzdem. Da die Funktionalit√§t ‚ÄúPin schalten‚ÄĚ und ‚ÄúPin auslesen‚ÄĚ bereits vorhanden ist und funktioniert (Kommando ‚ÄúS‚ÄĚ und ‚ÄúR‚ÄĚ) w√ľrde ich einfach neue Kommandos definieren, die zus√§tzlich die Funktion ‚ÄúT‚ÄĚ ‚Üí Timer f√ľr Pin x auf n Minuten setzen und z.B. ‚ÄúU‚ÄĚ ‚Üí liefere die Zeit die der Timer f√ľr Pin x noch l√§uft abbildet. Das sind dann einfach nur weitere Bl√∂cke im switch-case Konstrukt im Arduino-Code. Den gr√∂√üten Teil kannst Du sogar von ‚ÄúR‚ÄĚ und ‚ÄúS‚ÄĚ klauen und nur um die Timer-Geschichte erweitern.

meinst du so (bekomme Fehlermeldungen beim kompilieren,verstehe nicht was ich ändern muss, sorry :blush: ):

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

// MAC und IP Konfiguration
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xEE, 0xF3 };
IPAddress ip(192,168,178,216);
IPAddress gateway(192,168,178,1);
IPAddress subnet(255, 255, 255, 0);

// warten auf port 23
EthernetServer server(23);

long previousMillis = 0; ¬† ¬† ¬† ¬†// speichert wie viele Sekunden seit derletzten √É‚Äěnderung vergangen sind


void setup() {
  //Ethernet initialisieren
  Ethernet.begin(mac, ip, gateway, subnet);
  // Server starten
  server.begin();
  // serielle konsole öffnen (debug)
  Serial.begin(9600);
}

void loop() {
  
  // auf eine eingehende Verbindung warten
  EthernetClient client = server.available();
  //wenn verbindung, dann 3 bytes lesen; 
  if (client) {

    char command =client.read();
    byte pinnumber =client.read();
    byte pinvalue =client.read();
    byte pintime =client.read();  //öffnungszeit Ventil zb. 15min
    long timerlength = client.read();
    byte returnvalue = 0;
    byte timerpin[] = pinnumber;  //<-- hier hagt es :-( Keine Ahnung was da hin mus...
    
 ¬† ¬†//pr√ľfen ob eine Sekunde vergangen ist
  if(millis()-previousMillis >= 1000) {
    //aktuelle Zeit merken
    previousMillis = millis();

    //alle timer auswerten 
    for(int t=0; t<NUMTIMER;t++) {

      //nur timer beachten, die auch verwendet werden sollen (positive PIN nummer)
      if(timerpin[t] > 0 ){

        //bei aktuellem timer eine sekunde abziehen, wenn "0", dann abgelaufen
        if( --timerlength[t] == 0) {

          //Ausgang umschalten ( HIGH -> LOW oder LOW -> HIGH)
          digitalWrite(timerpin[t],!digitalRead(timerpin[t]));  

          //timer deaktivieren ( timer mit pin "-1" sind inaktiv)
          timerpin[t] = -1;

          //debug
          Serial.print("Timer ");
          Serial.print(t);
          Serial.println(" abeglaufen.");
        }
      }  
    }
  }

    //Kommando auswerten
    switch(command) {

    case 'S':
      Serial.print("S Kommando empfangen, setze Pin ");
      Serial.print(pinnumber);
      Serial.print(" auf ");
      Serial.println(pinvalue);
      pinMode(pinnumber,OUTPUT);
      digitalWrite(pinnumber,pinvalue);
 ¬† ¬† //gesetzten wert auch zur√ľckliefern
      returnvalue=pinvalue;
      break;

    case 'R':
      returnvalue = digitalRead(pinnumber);
      Serial.print("R Kommando empfangen, lese Pin ");
      Serial.print(pinnumber);
      Serial.print(". Wert = ");
      Serial.println(returnvalue);
      break;

   case 'T':
     Serial.print("T Kommando empfangen, setze Pin ");
      Serial.print(pinnumber);
      Serial.print(" auf ");
      Serial.println(pinvalue);
      pinMode(pinnumber,OUTPUT);
      digitalWrite(pinnumber,pinvalue);
 ¬† ¬† ¬†Serial.print(" f√ľr ");
      Serial.print(pintime);
      Serial.print(" min");
 ¬† ¬† //gesetzten wert auch zur√ľckliefern
      returnvalue=pinvalue;
      break;
     
    default:
      Serial.println("Fehler, unbekanntes Kommando");    
      break;

    }  
    
 ¬† ¬†// r√ľckantwort senden (1 byte) die "+48" sorgen daf√ľr das der Wert 0 oder 1 als Zeichen "0" oder "1" √ľbertragen werden. 
    //das vereinfacht die verarbeitung in php.
    client.write(returnvalue+48);
    
 ¬† ¬†//√ľbertragung erzwingen
    client.flush();
    
    //10ms delay damit daten sicher gesendet werden.
    delay(10);
    
    //wichtg! client verbindung beenden
    client.stop();
  }
}

Hier die Fehlermeldungen:

Mario_1.cpp: In function 'void loop()':
Mario_1:39: error: initializer fails to determine size of 'timerpin'
PHP_Ausgang_schalten_Mario_1:53: error: invalid types 'long int[int]' for array subscript

Ich verstehe die Zuordnungen nicht … arg… ;-(
NUMTIMER ?
timerpin ? ‚Üź soll der aktive Pin sein?
timerlength ? ‚Üź l√§nge wie lange das Ventil ge√∂ffnet sein soll ?

Auch auf die Gefahr hin, das ich mich wiederhole :slight_smile:
Schrittweise vorgehen. Wenn es nicht funktioniert, dann gehe einen Schritt zur√ľck und pr√ľfe ab wann es nicht mehr so l√§uft wie es sollte.
Was mir auf alle Fälle schon mal auffällt ist:

   char command =client.read();
    byte pinnumber =client.read();
    byte pinvalue =client.read();
    byte pintime =client.read();  //öffnungszeit Ventil zb. 15min
    long timerlength = client.read();

Hier liest Du viel mehr Daten als Du mit dem PHP-Script abschickst. Wenn pintime schon der Wert f√ľr den Timer ist, wof√ľr ist dann timerlength gut?
Abgesehen davon, das Du mit client.read() nur ein Byte liest und keinen long-Wert.
timerpin[] und timerlength[] sind globale arrays, die au√üerhalb von loop() definiert werden m√ľssen, damit sie ihre Werte zwischen den einzelnen loop() Duchl√§ufen behalten. Eine Zuweisung zu diesen Arrays muss also immer mit einem Index erfolgen.
NUMTIMER ist ein ‚Äú#define‚ÄĚ mit dem man festlegt, wieviele timer es geben soll.

Ich w√ľrde sagen, wir gehen die Umsetzung des Arduino-Codes diesmal etwas anders an. Versuch mal stuchpunktartig zu beschreiben, was der Code machen soll, wenn das Kommando ‚ÄúT‚ÄĚ an den Arduino geschickt wird.
Sowas wie

  • ‚ÄúT‚ÄĚ aus verbindung gelesen
    1. Byte ‚ÄúPinnumber‚ÄĚ gelesen und in pinnumber gespeichert
    1. Byte "Pinvalue gelesen
  • ‚Ķ

Damit kannst Du Dir schrittweise (da ist es wieder :-)) klar machen was passieren soll und es dann entsprechend programmieren.

Moin,
ich verstehe diese Code Zeile nicht, bzw. was mir die Fehlermeldung sagen will… grrr
Die Codezeile wird Makiert:

//alle timer auswerten
for(int t=0; t<NUMTIMER;t++) {

Also, t=0; heißt doch es soll mit 0 beginnen, oder ?
Aber wo steht das t=0 ist ? :~
Und ‚Äút < NUMTIMER;‚ÄĚ bis dahin soll gez√§hlt werden
( #define NUMTIMER = 3; // wieviele timer es gibt (15,30,60 min) ‚Üź Oder falsch verstanden ?

Fehlermeldung:

Mario_1.cpp: In function 'void loop()':
Mario_1:47: error: expected primary-expression before '[' token
Mario_1:47: error: expected primary-expression before ']' token
Mario_1:47: error: expected primary-expression before ';' token
Mario_1:47: error: expected `)' before ';' token
Mario_1:47: error: name lookup of 't' changed for new ISO 'for' scoping
Mario_1:47: error: using obsolete binding at 't'
Mario_1:47: error: expected `;' before ')' token
Mario_1:125: error: expected `}' at end of input
Mario_1:125: error: expected `}' at end of input
Mario_1:125: error: expected `}' at end of input

Vor dem ‚Äúsetup()‚ÄĚ habe ich folgendes festgelegt:

unsigned long previousMillis = 0;       // speichert wie viele Sekunden seit derletzten aenderung vergangen sind
#define NUMTIMER[] = 3;          // wieviele timer es gibt (15,30,60 min)
int timerpin;
int timerlength;

Und im ‚Äúloop()‚ÄĚ steht das (hoffe ich habe dich da richtig verstanden (4. byte):

    char command =client.read();
    byte pinnumber =client.read();
    byte pinvalue =client.read();
¬† ¬† byte timerlength = client.read(); // zeit f√ľr ventil √∂ffnung
    byte returnvalue = 0;

Hier nochmal der ganze Code:

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

// MAC und IP Konfiguration
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xEE, 0xF3 };
IPAddress ip(192,168,178,216);
IPAddress gateway(192,168,178,1);
IPAddress subnet(255, 255, 255, 0);

// warten auf port 23
EthernetServer server(23);

unsigned long previousMillis = 0;       // speichert wie viele Sekunden seit derletzten aenderung vergangen sind
#define NUMTIMER = 3;          // wieviele timer es gibt (15,30,60 min)
int timerpin;
int timerlength;


void setup() {
  //Ethernet initialisieren
  Ethernet.begin(mac, ip, gateway, subnet);
  // Server starten
  server.begin();
  // serielle konsole öffnen (debug)
  Serial.begin(9600);
}

void loop() {
  
  // auf eine eingehende Verbindung warten
  EthernetClient client = server.available();
  //wenn verbindung, dann 3 bytes lesen; 
  if (client) {

    char command =client.read();
    byte pinnumber =client.read();
    byte pinvalue =client.read();
¬† ¬† byte timerlength = client.read(); // zeit f√ľr ventil √∂ffnung
    byte returnvalue = 0;
   
    
¬† ¬† //pr√ľfen ob eine Sekunde vergangen ist
  if(millis()-previousMillis >= 1000) {
    //aktuelle Zeit merken
    previousMillis = millis();

    //alle timer auswerten 
    for(int t=0; t<NUMTIMER;t++) {

      //nur timer beachten, die auch verwendet werden sollen (positive PIN nummer)
      if(timerpin[t] > 0 ){

        //bei aktuellem timer eine sekunde abziehen, wenn "0", dann abgelaufen
        if( --timerlength[t] == 0) {

          //Ausgang umschalten ( HIGH -> LOW oder LOW -> HIGH)
          digitalWrite(timerpin[t],!digitalRead(timerpin[t]));  

          //timer deaktivieren ( timer mit pin "-1" sind inaktiv)
          timerpin[t] = -1;

          //debug
          Serial.print("Timer ");
          Serial.print(t);
          Serial.println(" abeglaufen.");
        }
      }  
    }
  }

    //Kommando auswerten
    switch(command) {

    case 'S':
      Serial.print("S Kommando empfangen, setze Pin ");
      Serial.print(pinnumber);
      Serial.print(" auf ");
      Serial.println(pinvalue);
      pinMode(pinnumber,OUTPUT);
      digitalWrite(pinnumber,pinvalue);
¬† ¬†  //gesetzten wert auch zur√ľckliefern
      returnvalue=pinvalue;
      break;

    case 'R':
      returnvalue = digitalRead(pinnumber);
      Serial.print("R Kommando empfangen, lese Pin ");
      Serial.print(pinnumber);
      Serial.print(". Wert = ");
      Serial.println(returnvalue);
      break;

   case 'T':
     Serial.print("T Kommando empfangen, setze Pin ");
      Serial.print(pinnumber);
      Serial.print(" auf ");
      Serial.println(pinvalue);
      pinMode(pinnumber,OUTPUT);
      digitalWrite(pinnumber,pinvalue);
¬† ¬† ¬† Serial.print(" f√ľr ");
      Serial.print(timerlength);
      Serial.print(" min");
¬† ¬†  //gesetzten wert auch zur√ľckliefern
      returnvalue=pinvalue;
      break;
     
    default:
      Serial.println("Fehler, unbekanntes Kommando");    
      break;

    }  
    
¬† ¬† // r√ľckantwort senden (1 byte) die "+48" sorgen daf√ľr das der Wert 0 oder 1 als Zeichen "0" oder "1" √ľbertragen werden. 
    //das vereinfacht die verarbeitung in php.
    client.write(returnvalue+48);
    
¬† ¬† //√ľbertragung erzwingen
    client.flush();
    
    //10ms delay damit daten sicher gesendet werden.
    delay(10);
    
    //wichtg! client verbindung beenden
    client.stop();
  }
}

Irgendwie habe ich wohl was falsch deklariert oderso, kann aber nichts mit den Fehlermeldungen Anfangen :blush:

Die Variable "t" deklarierst du ja direkt in der for-Schleife.

Das einzige, was ich jetzt gefunden hab ist folgende zeile, die ich mir nicht erklären kann: digitalWrite(timerpin[t],!digitalRead(timerpin[t]));  digitalRead liefert HIGH oder LOW (1 oder 0 intern) - sagst du damit, dass es das Gegenteil von dem gelieferten Wert sein soll? Weiß nicht, ob das so funktioniert...

Hi,
laut Mario¬īs Sketch-Auszug, soll das wohl funktionieren.
Er hatte das ganze wohl schon getestet.

Zur Motivation smiley-grin
Ich habe das heute Morgen mal fix umgesetzt. Es war einfach zu warm um noch schlafen zu können smiley-sweat
Es funktioniert. Sogar recht einfach. Auch die Steuerung der ‚ÄúTimer‚ÄĚ √ľber millis() ist eigentlich recht simple.

//pr√ľfen ob eine Sekunde vergangen ist
  if(millis()-previousMillis >= 1000) {
    //aktuelle Zeit merken
    previousMillis = millis();

    //alle timer auswerten 
    for(int t=0; t<NUMTIMER;t++) {

      //nur timer beachten, die auch verwendet werden sollen (positive PIN nummer)
      if(timerpin[t] > 0 ){

        //bei aktuellem timer eine sekunde abziehen, wenn "0", dann abgelaufen
        if( --timerlength[t] == 0) {

          //Ausgang umschalten ( HIGH -> LOW oder LOW -> HIGH)
          digitalWrite(timerpin[t],!digitalRead(timerpin[t]));  

          //timer deaktivieren ( timer mit pin "-1" sind inaktiv)
          timerpin[t] = -1;

          //debug
          Serial.print("Timer ");
          Serial.print(t);
          Serial.println(" abeglaufen.");
        }
      }  
    }
  }

Damit versuche ich mich,also daraus einen ganzen SKETCH zu machen… Klapp nur irgendwie nicht, weil ich einiges (noch) nicht verstehe. :blush:

( #define NUMTIMER = 3; // wieviele timer es gibt (15,30,60 min) ‚Üź Oder falsch verstanden ?

Leider ja, denn die 15,30 und 60 Minuten sind ja nur eine Zeit, von der Du eine auswählst, das hat ja noch nichts mit einem Timer zu tun.
Verschiedene Timer brauchst Du, wenn Du mehrere Ventile steuern willst.
Z.B. timerpin[0]=9, timerlength[0]=900 w√ľrde den ersten Timer f√ľr Pin 9 auf 900 Sekunden (15min) setzen.
timerpin[1]=10, timerlength[1]=3600 w√§re dann der 2. Timer f√ľr Pin 10 und 60 Minuten.

digitalWrite(timerpin[t],!digitalRead(timerpin[t])); 
sieht seltsam aus, funktioniert aber.

unsigned long previousMillis = 0;       // speichert wie viele Sekunden seit derletzten aenderung vergangen sind
#define NUMTIMER[] = 3;          // wieviele timer es gibt (15,30,60 min)
int timerpin;
int timerlength;

Die previousMillis sind richtig, aber das define nicht. Wie bereits geschrieben, m√ľssen timerpin und timerlength beides Arrays sehen.
Also

unsigned long previousMillis = 0;       // speichert wie viele Sekunden seit derletzten aenderung vergangen sind
#define NUMTIMER 3          // wieviele timer es gibt (15,30,60 min)
int timerpin[NUMTIMER];
int timerlength[NUMTIMER];
...
void setup() {
...
}

Hinter das ‚Äú#define‚ÄĚ kommt kein Semikolon und die Zuweisung erfolgt auch nicht mit einem ‚Äú=‚ÄĚ. ‚Äúdefine‚ÄĚ ist eine Pr√§prozessoranweisung f√ľr den Compiler. Der geht einfach nur stumpf durch den gesamten Code und ersetzt √ľberall das ‚ÄúNUMTIMER‚ÄĚ durch die 3, das hat noch nichst mit dem Programm zu tun, das ist reine Textersetzung. Das Trick dabei ist, das man sp√§ter die Anzahl der Arrayeintr√§ge an einer einzigen Stelle √§ndern kann, ohne die 3 √ľberall im Code zu ersetzen.

Die Auswertung f√ľr die vergangene Zeit darf auch nicht innerhalb des ‚Äúif(client)‚ÄĚ Blocks stehen, denn die Zeit l√§uft ja auch weiter wenn kein Client connected ist.
Am besten setzt Du den Zeit-Auswertungsblock gleich an den Anfang der loop().

Was bei der Auswertung des Kommandos ‚ÄúT‚ÄĚ noch fehlt, ist das Setzen des √ľbergebenen Timer-Wertes. Der muss ja irgendwo gespeichert werden, ebenso wie die Pin Nummer, die dem Timer zugeordnet ist.

Die L√∂sung selbst ist eigentlich nicht schwer, Du versuchst aber alles auf einmal zu machen und daf√ľr fehlt die zur Zeit noch das Wissen und die √úbersicht. Versuch daher erstmal den Ablauf wie Du ihn verstehst zu beschreiben. Sobald das stimmt und Du verstehst was, wann wie passieren soll, dann f√§ngst Du an das in ein C Programm zu giessen.

Hallo Mario,
Danke f√ľr die super Erkl√§rung !!

Hinter das ‚Äú#define‚ÄĚ kommt kein Semikolon und die Zuweisung erfolgt auch nicht mit einem ‚Äú=‚ÄĚ. ‚Äúdefine‚ÄĚ ist eine Pr√§prozessoranweisung f√ľr den Compiler. Der geht einfach nur stumpf durch den gesamten Code und ersetzt √ľberall das ‚ÄúNUMTIMER‚ÄĚ durch die 3, das hat noch nichst mit dem Programm zu tun, das ist reine Textersetzung. Das Trick dabei ist, das man sp√§ter die Anzahl der Arrayeintr√§ge an einer einzigen Stelle √§ndern kann, ohne die 3 √ľberall im Code zu ersetzen.

So versteht das auch einer wie ich XD

Dann mach ich mal…
Bis später… :wink:

Hi,
ok, ich raff es nicht. :blush:
Mein Sketch sieht jetzt so aus, das er zwar kompiliert aber nicht mehr tut.
Rufe ich die Website auf, kommt die Fehlermeldung ‚ÄúKommando konnte nicht abgesetzt werden‚ÄĚ
Hier mein Sketch:

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

// MAC und IP Konfiguration
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xEE, 0xF3 };
IPAddress ip(192,168,178,216);
IPAddress gateway(192,168,178,1);
IPAddress subnet(255, 255, 255, 0);

// warten auf port 23
EthernetServer server(23);

unsigned long previousMillis = 0;       // speichert wie viele Sekunden seit derletzten aenderung vergangen sind
#define NUMTIMER 3          // wieviele timer es gibt (15,30,60 min)
int timerpin[NUMTIMER];
int timerlength[NUMTIMER];

void setup() {
  //Ethernet initialisieren
  Ethernet.begin(mac, ip, gateway, subnet);
  // Server starten
  server.begin();
  // serielle konsole öffnen (debug)
  Serial.begin(9600);
}

void loop() {
  
¬† //pr√ľfen ob eine Sekunde vergangen ist
  if(millis()-previousMillis >= 1000) {
    //aktuelle Zeit merken
    previousMillis = millis();

    //alle timer auswerten 
    for(int t=0; t<NUMTIMER;t++) {

      //nur timer beachten, die auch verwendet werden sollen (positive PIN nummer)
      if(timerpin[t] > 0 ){

        //bei aktuellem timer eine sekunde abziehen, wenn "0", dann abgelaufen
        if( --timerlength[t] == 0) {

          //Ausgang umschalten ( HIGH -> LOW oder LOW -> HIGH)
          digitalWrite(timerpin[t],!digitalRead(timerpin[t]));  

          //timer deaktivieren ( timer mit pin "-1" sind inaktiv)
          timerpin[t] = -1;

          //debug
          Serial.print("Timer ");
          Serial.print(t);
          Serial.println(" abeglaufen.");
        }
      }  
    }
  }
  
  // auf eine eingehende Verbindung warten
  EthernetClient client = server.available();
  //wenn verbindung, dann 4 bytes lesen; 
  if (client) {

    char command =client.read();
    byte pinnumber =client.read();
    byte pinvalue =client.read();
¬† ¬† byte timerlength = client.read(); // zeit f√ľr ventil √∂ffnung
    byte returnvalue = 0;
    byte timerpin = pinnumber;
   

    //Kommando auswerten
    switch(command) {

    case 'S':
      Serial.print("S Kommando empfangen, setze Pin ");
      Serial.print(pinnumber);
      Serial.print(" auf ");
      Serial.println(pinvalue);
      pinMode(pinnumber,OUTPUT);
      digitalWrite(pinnumber,pinvalue);
¬† ¬†  //gesetzten wert auch zur√ľckliefern
      returnvalue=pinvalue;
      break;

    case 'R':
      returnvalue = digitalRead(pinnumber);
      Serial.print("R Kommando empfangen, lese Pin ");
      Serial.print(pinnumber);
      Serial.print(". Wert = ");
      Serial.println(returnvalue);
      break;

   case 'T':
     Serial.print("T Kommando empfangen, setze Pin ");     
      Serial.print(timerpin);
      Serial.print(" auf ");
      Serial.println(pinvalue);
      pinMode(pinnumber,OUTPUT);
      digitalWrite(timerpin,pinvalue);
¬† ¬† ¬† Serial.print(" f√ľr ");
      Serial.print(timerlength);
      Serial.print(" min");
¬† ¬†  //gesetzten wert auch zur√ľckliefern
      returnvalue=pinvalue;
      break;
     
    default:
      Serial.println("Fehler, unbekanntes Kommando");    
      break;

    }  
    
¬† ¬† // r√ľckantwort senden (1 byte) die "+48" sorgen daf√ľr das der Wert 0 oder 1 als Zeichen "0" oder "1" √ľbertragen werden. 
    //das vereinfacht die verarbeitung in php.
    client.write(returnvalue+48);
    
¬† ¬† //√ľbertragung erzwingen
    client.flush();
    
    //10ms delay damit daten sicher gesendet werden.
    delay(10);
    
    //wichtg! client verbindung beenden
    client.stop();
  }
}

Irgendwie habe den jetzt total vermurgst‚Ķ Ich bin der Meinung ich habe alles √ľbergeben, aber anscheinend fehlt irgendwas oder ist falsch gesetzt.

Hier der PHP Teil:

<html>
<head>
</head>
<body>

<h1>Test</h1>
<?php

$arduino_ip = "192.168.178.216";
$arduino_port = "23";

function arduino_send($ip,$port,$command) {
    $res = fsockopen($ip,$port);
    if($res) {
        fwrite($res,$command);
        $ret =fread($res,1);
        echo "arduino_send() returned = $ret 
\n";
        return $ret;
    } else {
        echo "Fehler, Kommando konnte nicht abgesetzt werden";
    }
}

if(isset($_GET['led1'])) {
    $led1 = $_GET['led1'];
    arduino_send($arduino_ip,$arduino_port,"S".chr(4).chr($led1));
} else {
    $led1 = arduino_send($arduino_ip,$arduino_port,"R".chr(4).chr(0));
}

if(isset($_GET['V1'])) {
    $V1 = $_GET['V1'];
    arduino_send($arduino_ip,$arduino_port,"T".chr(4).chr(1).chr($V1));
} else {
    $V1 = arduino_send($arduino_ip,$arduino_port,"R".chr(4).chr(0));
}
?>
<form action="">
  <p>
LED 1 :
<input type="radio" name="led1" value="0" <?php if($led1==0) echo "checked" ?> >aus -
<input type="radio" name="led1" value="1" <?php if($led1==1) echo "checked" ?> >an


 </p>
  <input type="submit" name="submit" value="Senden">
</form>


<form action="">
  <p>
   <select name="V1">
    <option value="15">15 min</option>
    <option value="30">30 min</option>
    <option value="60">60 min</option>
   </select>
  </p>
   <input type="submit" name="submit" value="Senden">
</form>

</body
</HTML>

1) Du musst, wenn Du Dein Protokoll √§nderst, nat√ľrlich auch den PHP-Code anpassen. Dein Arduino-Sketch erwartet das bei JEDEM Kommando nun 4 Bytes gesendet werden. Da Du ber Beim Kommando "R" und "S" nur 3 Bytes sendest, wartet Dein Sketch entsprechend bis zum timeout und macht nicht weiter. Du kannst das auf zwei Arten beheben. Du kannst immer 4 Bytes schicken, das ist aber unpraktisch, da es ja irgendwann mit zus√§tzlichen Kommandos auch 5 oder 6 oder mehr werden k√∂nnen. Dann m√ľ√ütest Du immer alles neu Anpassen, was zum Einen Fehleranf√§llig und zum Anderen Aufw√§ndig ist. Du kannst aber auch bei jedem Aufruf nur die Bytes schicken, die Du ben√∂tigst. Dein Sketch liest dann am Anfang immer nur die minimale Anzahl von Bytes von einem client und erst in switch - case Block liest Du die f√ľr das entsprechende Kommando notwendigen zus√§tzlichen Bytes ein. Lediglich die Variablen daf√ľr w√ľrde ich bereits oben deklarieren, das ist √ľbersichtlicher.

2) Wieso glaubst Du, das Du in Deinem Sketch alles korrekt √ľbergeben hast? timerpin und timerlength sind Arrays, Du verwendest aber nirgendwo in der loop() ein Array. Im Gegenteil, Du deklarierst die Variablen timerlength und timerpin nocheinmal innerhalb von loop() als lokale Variablen vom Typ byte. Diese "verdecken" dann aber die globalen Arrays timerlength und timerpin. Die Schleife, die im Sekundentakt die einzelnen Timer abklappert erwartet aber, das die Variablen timerlength und timerpin auf ein Array zeigen und verwendet an dieser Stelle den Speicher auch so, womit Du pl√∂tzlich statt auf jeweils ein Byte, wie es deklariert ist auf 3x2x4 Bytes zugreifst und diese ver√§nderst. Damit bringst Du Dein Programm total aus dem Tritt, da Du mit Sicherheit Speicherzellen ver√§nderst, die vom Programm anderweitig verwendet werden.

Um das erstmal zum Laufen zu bekommen, ändere folgendes in Deinem Sketch:

1) Das "byte" vor timerlength und timerpin in dem Block wo die Daten gelesen werden muss weg. 2) Innerhalb von loop() änderst Du alle Vorkommen von timerlength in timerlength[0] 3) Innerhalb von loop() änderst Du alle Vorkommen von timerpin in timerpin[0]

Damit √ľberschreibt dann Dein Programm innerhalb von loop() nicht mehr die globalen Variablen f√ľr die Timer und verwendet erstmal einen timer f√ľr das Z√§hlen der Zeit. Im √ľbrigen z√§hlt Dein Sketch die timer in Sekunden nicht in Minuten. Damit es Minuten werden solltest Du den √ľbergebenen Wert noch mit 60 multiplizieren.

Leider ist Deine L√∂sung aber generell f√ľr eine Verwendung von mehreren Timern ungeeignet, da Du in Deinem Aufruf nicht √ľbergibst welcher Timer verwendet werden soll. Sobald Du mehr als ein Ventil schalten willst, bekommst Du Probleme.

Hallo Mario,
sorry wenn ich verärgert habe, aber ich habe es nicht verstanden.
Ich habe es jetzt so verändert wie du es geschrieben hast und es funktioniert.

Um das erstmal zum Laufen zu bekommen, ändere folgendes in Deinem Sketch:

  1. Das ‚Äúbyte‚ÄĚ vor timerlength und timerpin in dem Block wo die Daten gelesen werden muss weg.
  2. Innerhalb von loop() änderst Du alle Vorkommen von timerlength in timerlength[0]
  3. Innerhalb von loop() änderst Du alle Vorkommen von timerpin in timerpin[0]

Habe ich getan, es läuft. <Danke!>

Im √ľbrigen z√§hlt Dein Sketch die timer in Sekunden nicht in Minuten. Damit es Minuten werden solltest Du den √ľbergebenen Wert noch mit 60 multiplizieren.

Auch hier muss ich wieder passen, ich versuche seit 3 std heraus zu finden wo ich das eintragen muss, aber ohne erfolg. Egal wo ich es eintrage, nix, die Zeit wird nicht multipliziert. :frowning:

Leider ist Deine L√∂sung aber generell f√ľr eine Verwendung von mehreren Timern ungeeignet, da Du in Deinem Aufruf nicht √ľbergibst welcher Timer verwendet werden soll. Sobald Du mehr als ein Ventil schalten willst, bekommst Du Probleme.

Ok, aber es soll auch immer nur ein Ventik zur Zeit geöffnet sein,niemals zwei.
Auch hier stehe ich auf dem Schlauch, meinst du mit mehreren TIMERN z.b. V1, V2, V3 f√ľr Ventil1, Ventil2 usw. ? So wie im PHP angegeben?
Wenn ich es so versuche, gibt er Fehlermeldungen raus:

int NUMTIMER[] = {0,1};

0 f√ľr V1 und 1 f√ľr V2 , Dachte ich :frowning:

Ich habe jetzt mal die PHP Seite erweitert, es funktioniert, aber wie du schon sagst, im SerialMonitor, wird immer nur Timer 0 angezeigt.
Hier der Sketch:

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

// MAC und IP Konfiguration
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xEE, 0xF3 };
IPAddress ip(192,168,178,216);
IPAddress gateway(192,168,178,1);
IPAddress subnet(255, 255, 255, 0);

// warten auf port 23
EthernetServer server(23);

unsigned long previousMillis = 0;       

#define NUMTIMER 2

int timerpin[NUMTIMER];
int timerlength[NUMTIMER];

void setup() {
  //Ethernet initialisieren
  Ethernet.begin(mac, ip, gateway, subnet);
  // Server starten
  server.begin();
  // serielle konsole öffnen (debug)
  Serial.begin(9600);
}

void loop() {
  
 ¬† ¬†//pr√ľfen ob eine Sekunde vergangen ist
  if(millis()-previousMillis >= 1000) {
    //aktuelle Zeit merken
    previousMillis = millis();

    //alle timer auswerten 
    for(int t=0; t<NUMTIMER;t++) {

      //nur timer beachten, die auch verwendet werden sollen (positive PIN nummer)
      if(timerpin[t] > 0 ){

        //bei aktuellem timer eine sekunde abziehen, wenn "0", dann abgelaufen
        if( --timerlength[t] == 0) {
          //Ausgang umschalten ( HIGH -> LOW oder LOW -> HIGH)
          digitalWrite(timerpin[t],!digitalRead(timerpin[t]));  

          //timer deaktivieren ( timer mit pin "-1" sind inaktiv)
          timerpin[t] = -1;

          //debug
          Serial.print("T Kommando empfangen, Timer ");
          Serial.print(t);
          Serial.println(" abeglaufen.");
        }
      }  
    }
  }

  // auf eine eingehende Verbindung warten
  EthernetClient client = server.available();
  
  if (client) {
   
    char command =client.read();
    byte pinnumber =client.read();
    byte pinvalue =client.read();
    byte returnvalue = 0;
    
   

    //Kommando auswerten
    switch(command) {

    case 'S':
      Serial.print("S Kommando empfangen, setze Pin ");
      Serial.print(pinnumber);
      Serial.print(" auf ");
      Serial.println(pinvalue);
      pinMode(pinnumber,OUTPUT);
      digitalWrite(pinnumber,pinvalue);
 ¬† ¬† //gesetzten wert auch zur√ľckliefern
      returnvalue=pinvalue;
      break;

    case 'R':
      returnvalue = digitalRead(pinnumber);
      Serial.print("R Kommando empfangen, lese Pin ");
      Serial.print(pinnumber);
      Serial.print(". Wert = ");
      Serial.println(returnvalue);
      break;

   case 'T':
 ¬† ¬† timerlength[0] = client.read(); // zeit f√ľr ventil √∂ffnung
     timerpin[0] = pinnumber;
     Serial.print("T Kommando empfangen, setze Pin ");     
      Serial.print(timerpin[0]);
      Serial.print(" auf ");
      Serial.println(pinvalue);
      pinMode(timerpin[0],OUTPUT);
      digitalWrite(timerpin[0],pinvalue);
      Serial.print("T Kommando empfangen, setze Time auf ");
      Serial.print(timerlength[0]);
      Serial.print(" sec");
      Serial.println(" ");
 ¬† ¬† //gesetzten wert auch zur√ľckliefern
      returnvalue=pinvalue;
      break;

    default:
      Serial.println("Fehler, unbekanntes Kommando");    
      break;

    }  
    
 ¬† ¬†// r√ľckantwort senden (1 byte) die "+48" sorgen daf√ľr das der Wert 0 oder 1 als Zeichen "0" oder "1" √ľbertragen werden. 
    //das vereinfacht die verarbeitung in php.
    client.write(returnvalue+48);
    
 ¬† ¬†//√ľbertragung erzwingen
    client.flush();
    
    //10ms delay damit daten sicher gesendet werden.
    delay(10);
    
    //wichtg! client verbindung beenden
    client.stop();
  }
}

und hier der PHP-Code:

<html>
<head>
</head>
<body>

<h1>Test</h1>
<?php

$arduino_ip = "192.168.178.216";
$arduino_port = "23";

function arduino_send($ip,$port,$command) {
    $res = fsockopen($ip,$port);
    if($res) {
        fwrite($res,$command);
        $ret =fread($res,1);
        echo "arduino_send() returned = $ret 
\n";
        return $ret;
    } else {
        echo "Fehler, Kommando konnte nicht abgesetzt werden";
    }
}

if(isset($_GET['led1'])) {
    $led1 = $_GET['led1'];
    arduino_send($arduino_ip,$arduino_port,"S".chr(4).chr($led1));
} else {
    $led1 = arduino_send($arduino_ip,$arduino_port,"R".chr(4).chr(0));
}

if(isset($_GET['V1'])) {
    $V1 = $_GET['V1'];
    arduino_send($arduino_ip,$arduino_port,"T".chr(4).chr(1).chr($V1));
} else {
    $V1 = arduino_send($arduino_ip,$arduino_port,"R".chr(4).chr(0));
}

if(isset($_GET['V2'])) {
    $V2 = $_GET['V2'];
    arduino_send($arduino_ip,$arduino_port,"T".chr(5).chr(1).chr($V2));
} else {
    $V2 = arduino_send($arduino_ip,$arduino_port,"R".chr(5).chr(0));
}
?>
<form action="">
  <p>
LED 1 :
<input type="radio" name="led1" value="0" <?php if($led1==0) echo "checked" ?> >aus -
<input type="radio" name="led1" value="1" <?php if($led1==1) echo "checked" ?> >an


  </p>
  <input type="submit" name="submit" value="Senden">
</form>


<form action="">
  <p>Timer 1

   <select name="V1">
    <option value="15">15 min</option>
    <option value="30">30 min</option>
    <option value="45">45 min</option>
    <option value="60">60 min</option>
   </select>
  </p>
   <input type="submit" name="submit" value="Senden">
</form>

<form action="">
 <p>Timer 2

  <select name="V2">
  <option value="15">15 min</option>
  <option value="30">30 min</option>
  <option value="45">45 min</option>
  <option value="60">60 min</option>
  </select>
 </p>
  <input type="submit" name="submit" value="senden">
</form>

</body
</HTML>

Guten Morgen,

Auch hier muss ich wieder passen, ich versuche seit 3 std heraus zu finden wo ich das eintragen muss, aber ohne erfolg. Egal wo ich es eintrage, nix, die Zeit wird nicht multipliziert.

Wo hast Du es denn eingetragen? Und was hat nicht funktioniert? Entschuldige wenn ich so direkt frage, aber hast Du einfach nur probiert, oder √ľberlegt wo es passen k√∂nnte? Das ist nicht b√∂se gemeint, aber ich glaube Du verfolgst bei der Programmierung immer noch einen falschen Ansatz. Erstmal irgendwelchen Code schreiben und dann schauen was der macht ist keine gute Taktik. Es hat einen Grund warum ich Dich schon zwei Mal versucht habe zu √ľberzeugen erstmal die Schritte die in Deinem Programm passieren sollen in Worten als kleine Liste aufzuschreiben. Wenn Du da schon ein Problem mit dem Verst√§ndnis zum Ablauf hast, wird das beim Programmieren nicht besser, weil Du Dich dort noch zus√§tzlich auf die Syntax von C und die semantisch korrekte Umsetzung Deines Konzepts konzentrieren musst. Am Beispiel der Umrechnung der Dauer in Minuten:

  • PHP sendet die Dauer als 4. Parameter in Minuten
  • Sketch liest im switch-case Block den zus√§tzlichen 4. Parameter, wenn Kommando "T" erkannt wurde in die Variable timerlength[0]
  • timerlength[0] muss aber in Sekunden angegeben werden, daher muss der gerade √ľbermittelte Werte umgerechnet werden
  • Um auf Sekunden zu kommen, muss der Wert mit 60 multipliziert werden -> timerlength[0] = timerlength[0] *60

Ok, aber es soll auch immer nur ein Ventik zur Zeit ge√∂ffnet sein,niemals zwei. Auch hier stehe ich auf dem Schlauch, meinst du mit mehreren TIMERN z.b. V1, V2, V3 f√ľr Ventil1, Ventil2 usw. ? So wie im PHP angegeben? Wenn ich es so versuche, gibt er Fehlermeldungen raus: Code: int NUMTIMER[] = {0,1}; 0 f√ľr V1 und 1 f√ľr V2 , Dachte ich smiley-sad

Wann welches Ventil ge√∂ffnet ist, ist f√ľr die Programmierung an der Stelle erstmal v√∂llig uninteressant. Warum? 1) Weil man immer m√∂glichst allgemeine L√∂sungen baut, in diesem Fall also mit der M√∂glichkeit "Ventile" (also Pins) unabh√§ngig voneinander mit unterschiedlichen Timern zu schalten. Wie das dann von einer konkreten Anwendung genutzt wird, ist eine ganz andere Sache. 2) Ein PHP- und HTML-Script ist schnell ge√§ndert, dort steckt ja die eigentliche Anwendungslogik drin, den Arduino sp√§ter neu zu flashen ist deutlich mehr Aufwand. Den Arduino interessiert ja im Prinzip auch nicht um "was" es eigentlich geht. Der bekommt nur "Kommandos" wie "schalte Pin 3 ein" , "lese Pin 4 aus", oder "Schalte Pin 9 f√ľr 15 Minuten auf HIGH, danach wieder auf LOW" und das sollte alles unabh√§ngig voneinander funktionieren.

Du hast geschrieben, das Du das mit dem "#define NUMTIMER 3" verstanden hast, schreibst aber trotzdem wieder sowas : int NUMTIMER[] = {0,1};? Das ist das, was ich mit dem rumprobieren meine. Das f√ľhrt leider in den seltensten F√§llen zum Erfolg. Und selbst wenn, dann nur aus Gl√ľck und man versteht meistens am Ende trotzdem nicht warum es pl√∂tzlich funktioniert. Ergo -> kein guter Ansatz.

Du hast in Deinem Code ein #define NUMTIMER 2 stehen. Das bedeutet, das die beiden Arrays timerlength und timerpin je 2 Eintr√§ge haben k√∂nnen. Du hast also schon 2 Timer zur Verf√ľgung, die Du f√ľr V1 und V2 nutzen kannst (timerlength[0] und timerlength[1]. Was fehlt ist nur die Zuordnung. Dein Sketch muss ja irgendwo die Information herbekommen, welcher Timer f√ľr welches Pin verwendet werden soll. Hier hast Du auch wieder zwei M√∂glichkeiten. 1) Die einfache Variante w√§re einfach zu sagen wenn Pin 4 √ľbergeben wird, nutze Timer 0 und bei Pin 5 nutze Timer 1. Das ist aber schlechter Stil, denn Du verlagerst damit Teile Deiner Anwendungslogik in den allgemeinen Arduino-Sketch. Die Gefahr besteht, das Du irgendwann im PHP-Code pl√∂tzlich Pin 6 √ľbergibst, weil sich Deine Schaltung ge√§ndert hat und dann der Code nicht mehr greift. 2) Die allgemeinere Variante. Du √ľbergibst mit dem Kommando "T" einfach noch ein zus√§tzliches Byte, das bestimmt, welcher Timer verwendet werden soll. Dieses wird dann, genauso wie timerlength per client.read() gelesen. Allerdings musst Du aufpassen, denn Du solltest ersten die Timer-Nummer √ľbergeben, ehe Du mit timerlength[timernummer] = client.read() die L√§nge liest. (Du kannst Dir nat√ľrlich auch eine einfache "byte" Variable als "Zwischenspeicher" deklarieren.

Achso, ich bin auch nicht "ver√§rgert". Leider versuchst Du immer noch den zweiten Schritt vor dem Ersten zu machen und stolperst dabei regelm√§√üig. Das ist, sagen wir mal eine kleine Gedulds-Herausforderung f√ľr mich :D, geh√∂rt aber einfach dazu, wenn man jemanden etwas wirklich verst√§ndlich machen will. "Echtes" Lernen bedeutet nun mal, das man Prinzipien versteht und nicht einfach nur "auswendig" lernt. Damit habe ich mir als Tutor immer zus√§tzliche Arbeit gemacht und auch so machens "Opfer" zur Verzweiflung getrieben. Du bist also in guter Gesellschaft ]:D

int ledPin[] = {7,8,9}; // LED-Array mit Pin-werten

Ist korrekt, aich Dein

int NUMTIMER[] = {0,1};

war, zumindest f√ľr diese Zeile, erstmal snytaktischkorrekt.
Allerdings wird im Sketch selbst das NUMTIMER nicht als Variable oder Array verwendet, sonder nur als Platzhalter f√ľr die Zahl 3 oder 5 oder 2 oder welche Anzahl von Timern Du haben willst. NUMTIMER ist also NICHT der Timer selbst sonder nur der Wert f√ľr die Anzahl der Timer die es geben soll.
timerlength und timerpin sind die beiden Arrays, die den eigentlichen Timer bilden, denn diese speichern ja die L√§nge der Laufzeit und den Pin f√ľr einen spezifischen timer, sprich Index der Arrays.

Sch√∂n, das Dein Projekt jetzt funktioniert. Du hast Dir nat√ľrlich f√ľr den Anfang auch ein recht komplexes Projekt ausgesucht. Aus meiner Sicht etwas zu komplex f√ľr eine sinnvolle Lernkurve, denn zu viele Baustellen und Prinzipien gleichzeitig mit denen man sich auseinandersetzen muss, √ľberfordern einen doch leicht.
Nur nicht aufgeben und dran bleiben, irgendwann lichtet sich der Nebel :slight_smile:

Hallo allerseits, also Projekt l√§uft. Nochmal vielen Dank an "mkl0815" f√ľr die tolle Hilfe und Unterst√ľtzung :D

Arduino Ausg√§nge werden mittels PHP f√ľr eine Vorgegeben Zeit ge√∂ffnet und dann automatisch geschlossen. Den Code liefer ich sp√§ter nach, muss den noch kommentieren. Sollte jemand den schon vorher haben wollen, kurze PN.

Guten Morgen,

kann es sein, das aus diesem Thread Beiträge verschwunden sind? Speziell zwischen meinem letzten Post und dem vorletzten fehlt irgendwie der "es klappt jetzt" Post von Cetax. Daher mutet der Thread jetzt etwas seltsam an :-)

Moin,
ja also wie soll ich sagen… :blush:
Ups… Ich habe den falschen Button angeklickt und da war es wech…
Sorry !