Offline
Edison Member
Karma: 18
Posts: 1299
|
 |
« Reply #30 on: May 04, 2012, 05:53:36 am » |
( #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.
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 224
|
 |
« Reply #31 on: May 04, 2012, 06:11:22 am » |
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  Dann mach ich mal... Bis später... 
|
|
|
|
« Last Edit: May 04, 2012, 07:11:40 am by Cetax »
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 224
|
 |
« Reply #32 on: May 05, 2012, 08:13:44 am » |
Hi, ok, ich raff es nicht.  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 <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,"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 <br> </p> <input type="submit" name="submit" value="Senden"> </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="Senden"> </form>
</body </HTML>
|
|
|
|
« Last Edit: May 05, 2012, 08:29:46 am by Cetax »
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1299
|
 |
« Reply #33 on: May 05, 2012, 10:22:10 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 224
|
 |
« Reply #34 on: May 05, 2012, 06:27:44 pm » |
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.  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  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 <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,"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 <br> </p> <input type="submit" name="submit" value="Senden"> </form><br><br> <form action=""> <p>Timer 1<br> <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><br> <form action=""> <p>Timer 2<br> <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>
|
|
|
|
« Last Edit: May 06, 2012, 01:43:56 am by Cetax »
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1299
|
 |
« Reply #35 on: May 06, 2012, 03:11:59 am » |
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  , 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
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1299
|
 |
« Reply #36 on: May 08, 2012, 08:38:53 am » |
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 :-)
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 224
|
 |
« Reply #37 on: May 17, 2012, 06:40:19 am » |
Hallo allerseits, also Projekt läuft. Nochmal vielen Dank an "mkl0815" für die tolle Hilfe und Unterstützung  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.
|
|
|
|
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1299
|
 |
« Reply #38 on: May 18, 2012, 01:54:36 am » |
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 :-)
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 224
|
 |
« Reply #39 on: May 18, 2012, 12:46:43 pm » |
Moin, ja also wie soll ich sagen...  Ups.. Ich habe den falschen Button angeklickt und da war es wech.. Sorry !
|
|
|
|
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 224
|
 |
« Reply #40 on: May 18, 2012, 04:08:23 pm » |
Hallo allerseits, ich wende mich nochmal mit einem Problem an Euch. Ich versuche gerade die Rest-Zeit eines Timers auszulesen und auf einer Website mittels PHP auszugeben. Was auch teils schon geht. Im SerialMonitor wird dann z.b. 900sec angezeigt, aber auf der Website nur die erste Zahl!Wie kann ich die ganze Zahl ausgeben lassen ? Hier mal der Sketch (Case 'U' ist der Teil) : #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 6 // 6 Timer int TI; 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 'U': Serial.print("U Kommando empfangen, lese Timer "); Serial.print(TI); Serial.print(" Wert = "); Serial.println(timerlength[TI]); client.print(timerlength[TI]); //client.print(returnvalue); break;
case 'T': TI = client.read(); timerlength[TI] = client.read(); // zeit für ventil öffnung timerpin[TI] = pinnumber; timerlength[TI] = timerlength[TI] *60; // die empfangenen sec*60=min Serial.print("T Kommando empfangen, "); Serial.print("Timer "); Serial.print(TI); Serial.println(" gestartet"); Serial.print("T Kommando empfangen, setze Pin "); Serial.print(timerpin[TI]); Serial.print(" auf "); Serial.println(pinvalue); pinMode(timerpin[TI],OUTPUT); digitalWrite(timerpin[TI],pinvalue); Serial.print("T Kommando empfangen, setze Time auf "); Serial.print(timerlength[TI]); 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 die PHP-Ausgabe: <?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 "Ventil = $ret <br>\n"; //echo "1 = Zu | 0 = Auf <br>\n"; return $ret; } else { echo "Fehler, kein kontakt.<br>Kommando konnte nicht abgesetzt werden"; } }
$V1 = arduino_send($arduino_ip,$arduino_port,"U".chr(4).chr(1).chr($V1)); echo $V1; ?>
Ich hoffe Ihr versteht was ich meine  Im Serial Monitor sieht es so aus wie es eigentlich auch auf der Website zu sehen sein soll: T Kommando empfangen, Timer 0 gestartet T Kommando empfangen, setze Pin 4 auf 0 T Kommando empfangen, setze Time auf 900 sec U Kommando empfangen, lese Timer 0 Wert = 900
Und auf der Website wird nur die 9 von der 900 angezeigt. Vielen Dank...
|
|
|
|
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Germany
Offline
Full Member
Karma: 1
Posts: 224
|
 |
« Reply #41 on: May 20, 2012, 06:02:02 am » |
Moin, keiner eine Idee, warum nur die erste Zahl (bsp. 9) angezeigt wird und nicht die ganze (bsp. 900) ? Vieleicht kann ja nochma einer drauf schauen, wäre echt super 
|
|
|
|
|
Logged
|
*greatz*
CeTax
www dot blinkmann dot de
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1299
|
 |
« Reply #42 on: May 20, 2012, 10:42:52 pm » |
Guten Morgen, mal abgesehen davon, das Du in Deinem Sketch immer Timer 0 verwendest, da die Variable "TI" nie einen übergebenen Wert zugewiesen bekommt, ist die Lösung Deines Problems vermutlich recht einfach: $ret =fread($res,10);
Damit werden im PHP Code 10 Zeichen aus der Verbindung gelesen und nicht nur 1 wie vorher. Das mit den verschiedenen Timern solltest Du Dir aber nochmal ansehen. Mario.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 208
|
 |
« Reply #43 on: May 21, 2012, 04:03:35 am » |
Hi, einfach eine kurze Zwischenfrage: Um die verbindung zwischen Arduino und Pc herzustellen nutzt ihr da einen lokalen Webserver (wie z.B. Apache bei XAMPP) oder führt ihr die php-Dateien einfach von einem beliebigen Ordner im Browser (ja muss beim lokalen Webserver auch) aus?
mfg Balli
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 18
Posts: 1299
|
 |
« Reply #44 on: May 21, 2012, 04:42:06 am » |
Bei Cetax ist der Webserver glaub ich ein Synology-NAS, das auch PHP (+ Webserver) spricht. So wie die Umsetzung in diesem Projekt ist, braucht es zwingend einen Webserver. Wo der läuft ist erstmal egal, das kann auch ein lokaler XAMPP sein. Bei mir ist es ein MacMini Server :-)
|
|
|
|
|
Logged
|
|
|
|
|
|