Germany
Offline
Full Member
Karma: 1
Posts: 214
|
 |
« Reply #15 on: May 01, 2012, 07:18:18 am » |
Hallo GOTT  äh, ich meine Mario... Also, es funktioniert jetzt!!! Jetzt habe ich glaube ich auch kapiert, was ich falsch gemacht habe. Manchmal sieht es erst wenn es fertig ist. Habe zwar schon ein bischen mit PHP gemacht, aber leider zu wenig um die kurzform der schreibweise zu verstehen. Du bist wohl auch PHP-Guru, oder ? Was wir hier,nein was DU, hier gemacht hast, hat ja eigentlich nix mit Arduino zu tun. Also echt Suuper !! Mein Respekt, das du die Gedult hattest mich da so ran zu führen, das ein Anfänger wie ich, das auch versteht und es letztendlich läuft. DANKE !!Jetzt muss das ganze noch für 8 Ausgänge optimiert werden und ein büschen aufhübschen...  Dennoch habe noch eine Frage, vieleicht bekomme ich das aber auch allein irgendwie raus. Die Pins sind ja nun als Ausgänge deklariert "pinMode(Pin4, OUTPUT);" , wenn der Sketch startet, ist Pin4 AN, obwohl er AUS-geschaltet sein sollte. Und wenn ich dann auf AN klicke schaltet er AUS, sozusagen sind 1 und 0 vertauscht. Was ich aber nicht verstehe, da ich doch mit dem PHP-Script 1 (also AN) sende und er aber AUS macht. Hier der funktionierende Sketch: /* Webclient Es soll mittels einer PHP-Seite, die auf einem Webserver liegt, ein oder mehrere Ausgänge AN/AUS geschaltet werden. */
#include <SPI.h> #include <Ethernet.h>
// Ethernet einrichten 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);
// telnet defaults to port 23 EthernetServer server(23); boolean gotAMessage = false; // whether or not you got a message from the client yet
int Pin4 = 4; int Pin5 = 5; int Pin9 = 9;
void setup() { // initialize the ethernet device Ethernet.begin(mac, ip, gateway, subnet); // start listening for clients server.begin(); // open the serial port Serial.begin(9600); pinMode(Pin4, OUTPUT); pinMode(Pin5, OUTPUT); pinMode(Pin9, OUTPUT); }
void loop() { // wait for a new client: EthernetClient client = server.available(); // when the client sends the first byte, say hello: if (client) { if (!gotAMessage) { Serial.println("We have a new client"); gotAMessage = true; } //Achtung super simpler Quickhack ohne Püfung der Eingabe oder ob Daten vorhanden sind char input[3];
for(int i=0;i<3;i++) { input[i] = client.read(); }
//pin setzen if(input[0] == 'S') { digitalWrite(input[1],input[2]); } //pin lesen und an den Client schicken if(input[0] == 'R') { client.print(digitalRead(input[1])); } } client.stop(); client.flush(); } Klar, ich kann einfach 1 und 0 tauschen, aber damit habe ich es ja nicht verstanden. Ansonsten, nochmal VIELEN DANK für deine Mühe und Geduld Mario aka "mkl0815"
|
|
|
|
« Last Edit: May 01, 2012, 07:21:00 am by Cetax »
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1297
|
 |
« Reply #16 on: May 01, 2012, 08:37:11 am » |
Kein Problem, der Aufwand war ja überschaubar und Du hast einiges gelernt. Mit HTML und PHP wurschtel ich schon seit über 10 Jahren herum. Ich wollte halt nur nicht sofort die komplette Lösung liefern, Du solltest schon selbst bestimmte Dinge machen. Es geht ja schliesslich darum, das Du am Ende etwas lernst. Ansonsten würde ich noch aufpassen, beim Ethernet-Shield und beim Arduino-Ethernet wird das Pin 4 glaub ich für das Chip-Select der SD-Karte verwendet. Keine Ahnung, ob das einen Einfluss hat. Ich denke nicht zwar nicht, aber man weiss ja nie. 0 und 1 sollten eigentlich nicht vertauscht sein, ist es bei mir auch nicht. Schau mal nach, nicht das Dein HTML-Formular bei den radio-buttons die Werte vertauscht hat. Das ist der Grund warum ich GET statt POST verwende, da sehe ich in der URL sofort was verschickt wird. Hier der Code auf dem Arduino, den ich verwende: /* Arduino TCP Control A simple server that waits for incoming connections to set or read digital Output Pins Using an Arduino Wiznet Ethernet shield or an Arduino Ethernet. Circuit: * Ethernet shield attached to pins 10, 11, 12, 13 created 2012-04-28 by Mario Keller */
#include <SPI.h> #include <Ethernet.h>
// MAC und IP Konfiguration byte mac[] = { 0xDE, 0xAD, 0xBC, 0xAF, 0xFE, 0xED }; IPAddress ip(192,168,0, 29); IPAddress gateway(192,168,0, 252); IPAddress subnet(255, 255, 255, 0);
// warten auf port 23 EthernetServer server(23);
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 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;
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(); } }
|
|
|
|
« Last Edit: May 01, 2012, 08:40:28 am by mkl0815 »
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 214
|
 |
« Reply #17 on: May 01, 2012, 01:42:25 pm » |
Hallo, also dein Sketch sieht Professionell aus, mit Überprüfung und so, nicht schlecht  Ich habe rausgefunden, warum die LED immer an war, obwohl 0 gesendet wurde. Ich würde mal sagen, klassischer Anfänger Fehler, ich hatte verkehrtrum gepohlt.  Jetzt gehts  Nun geht es weiter, das ganze per Zeit zu steuern, also das ich sage, öffne Ventil für 15min und dann wieder zu, mal sehen, wie weit ich da kommen...  Mach ich das am besten per PHP und übergebe das dann an den Arduino ? Oder sollte der Arduino das machen ? (Mit millis oderso ?)
|
|
|
|
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 214
|
 |
« Reply #18 on: May 01, 2012, 04:00:28 pm » |
Moin Moin, kann man auch ein viertes Byte übertragen ? Z.b. 15 ? Soll bedeuten, das die LED für 15 min AN ist und sich dann wieder ausschaltet. Ich dachte da an sowas wie, die "15" wird an millis/delay übergeben. //pin setzen if(input[0] == 'S') { digitalWrite(input[1],input[2]); delay[3]; }
Auszug aus der PHP: if(isset($_GET['led2'])) { $led2 = $_GET['led2']; arduino_send($arduino_ip,$arduino_port,"S".chr(9).chr(1).chr($led2[])); //Pin9 AN für x min } else { $led2 = arduino_send($arduino_ip,$arduino_port,"R".chr(9).chr(0)); } .... <form action=""> <p> <select name="led2[]"> <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>
Geht sows oder mal wieder völlig daneben ? 
|
|
|
|
« Last Edit: May 01, 2012, 04:21:51 pm by Cetax »
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1297
|
 |
« Reply #19 on: May 02, 2012, 06:41:15 am » |
Du willst also eine Zeitshaltung bauen? Natürlich geht das, allerdings wird das aus verschiedenen Gründen etwas komplexer. Aber der Reihe nach. //pin setzen if(input[0] == 'S') { digitalWrite(input[1],input[2]); delay[3]; }
Das geht schon mal nicht, wenn schon dann delay(input([3]), was aber bei input[3]=15 nur 15 Millisekunden und nicht 15 Minuten wären. Ein 4. Byte übertragen ist kein Problem, das ist nur eine Anpassung im PHP Code, indem Du dem "$command" ein 4. byte hinzufügst. Dein Problem beim Delay ist aber, das der Arduino dann die nächsten X Minuten (im schlimmsten Fall eine Stunde) nicht auf weitere Verbindungen reagieren würde. Die Zeitsteuerung über PHP zu machen ist auch keine gute Idee, da Du ja ständig "reloads" der Seite machen müßtest, bzw. mit Ajax arbeiten. Und wenn der User den Browser schliesst, dann geht dein Ventil im schlimmsten Fall nie wieder zu :-) Ein guter Grundsatz bei komplexen Systemen ist immer, das Aufgaben nach Möglichkeit an den Stellen (in den Komponenten) gelöst werden, wo sie anfallen. In Deinem Fall ist das der Arduino, der ja nach z.b. 15 Minuten das Ventil wieder schliessen muss. Ich würde einfach für jedes "Ventil" (sprich Arduino Ausgang) eine Variable " unsigned long vtimer1 = millis() + (1000 * 60 * input[3])" definieren, wenn das "Ventil" über die PHP-Funktion geschaltet wird. vtimer1 (als Beispiel für Ventil 1) enthält dann den Zeitpunkt, wann das Ventil wieder umgeschaltet werden soll. Das kannst Du dann in jedem loop() Durchlauf mit dem aktuellen Wert von millis() vergleichen. Das kannst Du dann unabhängig für jedes Ventil machen, ohne ein delay() verweden zu müssen. Zu Deinem PHP-Code: Warum verwendest Du immer Arrays in den Variablennamen? z.b. <select name="led2[]"> Das ist eher unübersichtlich und eigentlich unnötig, außer Du willst ALLE "Ventile" in ein Array packen, dann würde es Sinn machen, müßte aber auch anders aussehen. Mario.
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 214
|
 |
« Reply #20 on: May 02, 2012, 07:39:40 am » |
Hallo, ja also, das habe ich mir schon gedacht, Einfach geht es ja nie  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  ) 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:
<select name="led2[]">
Das ist eher unübersichtlich und eigentlich unnötig, außer Du willst ALLE "Ventile" in ein Array packen, dann würde es Sinn machen, müßte aber auch anders aussehen.
Mmmh, das stammt doch aus dem Formular ? Oder irre ich da? <select name="led2[]"> <option value="15">15 min</option> <option value="30">30 min</option> <option value="60">60 min</option> </select> Da wird doch bei "led2[]" die Zeit, die Ausgewählt wird, rein gepackt, oder nicht ? 
|
|
|
|
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1297
|
 |
« Reply #21 on: May 02, 2012, 08:19:28 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1297
|
 |
« Reply #22 on: May 02, 2012, 11:37:52 pm » |
Zur Motivation Ich habe das heute Morgen mal fix umgesetzt. Es war einfach zu warm um noch schlafen zu können  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.
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 214
|
 |
« Reply #23 on: May 03, 2012, 01:29:41 pm » |
Hallo Mario, sage mal,wann schläfst du eigentlich ?  Du hast ja Online Zeiten...  So, aber erstmal vielen Dank für die Motivation...  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 <br>\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 <br> </p> <input type="submit" name="submit" value="Abschicken"> </form><br><br> <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...  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... 
|
|
|
|
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1297
|
 |
« Reply #24 on: May 03, 2012, 02:16:18 pm » |
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" 
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 214
|
 |
« Reply #25 on: May 03, 2012, 03:00:27 pm » |
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  ): #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 ?
|
|
|
|
« Last Edit: May 03, 2012, 03:59:23 pm by Cetax »
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1297
|
 |
« Reply #26 on: May 04, 2012, 02:56:56 am » |
Auch auf die Gefahr hin, das ich mich wiederhole :-) 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
- 2. Byte "Pinvalue gelesen
- ...
Damit kannst Du Dir schrittweise (da ist es wieder :-)) klar machen was passieren soll und es dann entsprechend programmieren.
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 214
|
 |
« Reply #27 on: May 04, 2012, 04:28:53 am » |
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 
|
|
|
|
« Last Edit: May 04, 2012, 04:33:21 am by Cetax »
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Offline
God Member
Karma: 8
Posts: 621
42
|
 |
« Reply #28 on: May 04, 2012, 04:38:06 am » |
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...
|
|
|
|
« Last Edit: May 04, 2012, 04:42:58 am by Marcus W »
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 214
|
 |
« Reply #29 on: May 04, 2012, 04:47:37 am » |
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. 
|
|
|
|
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
|