also ich baue gerade ein Projekt, in dem ich den Arduino sowohl via Webserver als auch über VB steuern möchte. Soweit so gut. Jeweils einen Arduino via Webserver Steuern ist kein Problem und auch seriell geht. Aber wie ist es in einen sketch zu bekommen?
Seriell schalte ich über die Byte Codes von a-h jer eine LED an und aus, das geht. In einem Webformular hingegen nehme ich ja Variablen mit einem bestimmten Wert. Wie kan ich nun diese beiden Sachen vereinen?
Die Frage ist doch, was passiert wenn der eine dies sagt und der andere was anderes ?
Ansonsten, wenn das egal ist oder nicht vorkommt, wo ist das Problem ?
Ein Arduino macht doch nichts ausser fragen ob was gekommen ist, und in der Regel kommt nichts, also macht er auch nichts.
Wo ist das Problem, zwei mal zu fragen ?
Deine HTML Form sollte besser nicht den gewünschten Zustand, sondern die gewünschte Aktion enthalten.
Sonst musst du ( Arduino ) dir merken, was schon gemacht wurde, um zu sehen was neu ist. ( Aber auch das geht )
Hoppla, "Deine HTML Form" in meinem letzten Post geht davon aus dass der Arduino der webserver ist, und die Steuerung über einen PC Browser als client geschieht.
Ist das überhupt richtig, oder ist dein Arduino ein Client, der sich von einem Server holt, was er tun soll ?
Ich verstehe deinen ersten Eintrag so, dass beides einzeln schon läuft.
Was ist dein Problem damit, aus zwei Sketchen eines zu machen ?
also du hast schon Recht, der Arduino soll der WebServer sein. Das Code sniplet ist die Steuerung via seriell. Mein Problem ist genauer gesagt, wie kann ich z.B. einen Wert bzw. Zustand seriell auslesen, um ihn auch im Webformular darzustellen.
Konkret soll eine Steckdosenleiste mit einem 8fach Relais betrieben werden. Die Steuerung der Steckdosen soll hierbei sowohl via einer Visual Basic Anwendung gehen und auch via Web Interface. Web Interface alleine ist kein Thema, schalten über seriell auch nihct. Aber wie kann ich beide mit den gleichen Variablen verwenden und auf dem seriellen Port Zustände abfragen?
Aber wie kann ich beide mit den gleichen Variablen verwenden
Ich verstehe es immer noch nicht ganz, fürchte ich.
Oder fragst du nach so einer Erweiterung:
static boolean ledValue1; // static : behält den Wert für den nächsten loop() Durchlauf;
char incomingData = Serial.read();
// a == an und b == aus
if(incomingData == 'a'){
ledValue1 = HIGH;
Serial.println("Led 1 ON");
}
if(incomingData == 'b'){
ledValue1 = LOW;
Serial.println("Led 1 OFF");
}
digitalWrite(ledPin1, ledValue1);
// ledValue1 kann beliebig weiter verwendet werden
so ganz komme ich auch nicht mit, aber eines zum verständnis:
man kann niemals mehrere sketches auf einmal laufen lassen. wenn Du also mit webserver und seriell arbeiten willst, mußt Du das im gleichen sketch schreiben.
damit kannst Du auch bei beiden arten die gleichen variablen ansprechen, solange sie am anfang des sketches, also global, definiert sind.
Du definierst Dir ein globales Array, welches den Zustand der einzelnen "Schalter" speichert. Ist der Inhalt "0" ist der Schalter aus, bei 1 ist er an.
byte switch[8] = { 0,0,0,0,0,0,0,0};
Bekommst Du seriell Befehle, setzt Du erst den entsprechenden Wert im Array und schaltest dann das Pin
Bei der Ausgabe des Webformulars verwendest Du vermutlich sowas wie
<input type="radio" name="LED1" value="a"> LED1 on
<input type="radio" name="LED1" value="b"> LED1 off
Damit wäre aber immer die erste Auswahl aktiv, egal welchen Zustand der Schalter wirklich hat. Du mußt also den Zustand unterscheiden:
char* htmloutput;
if(switch[0] == 0) {
htmloutput=" <input type=\"radio\" name=\"LED1\" value=\"a\"> LED1 on
<input type=\"radio\" name=\"LED1\" value=\"b\" selected> LED1 off
";
} else {
htmloutput=" <input type=\"radio\" name=\"LED1\" value=\"a\" selected> LED1 on
<input type=\"radio\" name=\"LED1\" value=\"b\"> LED1 off
";
}
Damit ist dann immer der aktuelle Zustand im Formular abgebildet. Mein Beispiel ist recht uneffktiv, vor allem wenn Du 8 Schalter hast kann man das sicher "dynamischer" mit deutlich weniger redundanten Strings lösen. Wichtig ist hier nur das Schlüsselwort "selected" das dem HTML-Form sagt, welcher Radio-Button aktiv ist.
Mario.
Wow, das ist echt genial. So etwas meinte ich! Aber auf ein Array wäre ich einfach nicht gekommem... Klasse!
Nun ist nur noch die Frage, kann ich Zustände pber die serielle Schnittstelle auch abfragen?
Ich will nämlich auch in meiner VB Anwendung graphisch anzeigen, welcher Schalter, wie gesetzt ist.
laserbrain:
Nun ist nur noch die Frage, kann ich Zustände pber die serielle Schnittstelle auch abfragen?
Ja, kannst ja ein eigenes Kommando dafür machen:
if(incomingData == 'x'){
for ( int i=0;i<8;i++) {
Serial.println(switch[0],DEC);
}
}
Schickst Du ein "x" über die Serielle Schnittstelle, bekommst Du den aktuellen Zustand der Pins zurück. Mit einer "0" für LED aus und "1" für LED an.
Ich würde das auch als Ergebnis bei jedem Setzen der LEDs per serieller Schnittstelle liefern, da Du zwar eine LED schaltest, aber sich ja in der Zwischenzeit auch andere LEDs geändert haben können (via Webinterface). Damit hast Du in VB nach jedem Schaltvorgang trotzdem gleich wieder den korrekten Stand aller Schalter.
Nun habe ich dank Euerer Hilfe die serielle Kommunikation perfekt. Auch die Zustände im HTML Code werden richtig angezeigt. Aber jetzt klappt das Schalten aus dem WebServer nicht. Ich dachte mir mit:
Poste mal den ganzen Sketch.
Was mir auffällt ist, das Du
switch[0] = '0';
schreibst, damit meckert der Compiler zwar nicht, aber Du weist das Zeichen Null, nicht den Wert Null zu. Damit ist aber auch switch[0] größer Null, wenn das Zeichen "0" drin steht. Weiterhin fehlt das Schalten des Ausgangs, also ein "digitalWrite(LED1, HIGH)" oder ähnliches, oder hast Du das an einer anderen Stelle im Code?
also der ganze Sketch kommt hier. Die Variablen sind alle da und auf der seriellen Kommunikation läuft alles einwandfrei. Nur Steuern über HTML geht nicht. Anzeigen des Status schon. (Im HTML Teil ist nur eine LED bisher testweise eingebaut)
/*
Web Server
A simple web server that shows the value of the analog input pins.
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
* Analog inputs attached to pins A0 through A5 (optional)
created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
*/
#include <SPI.h>
#include <Ethernet.h>
int ledPin1 = 2;
int ledPin2 = 3;
int ledPin3 = 4;
int ledPin4 = 5;
int ledPin5 = 6;
int ledPin6 = 7;
int ledPin7 = 8;
int ledPin8 = 9;
//Globales Array mit dem Zustande der Pins...
byte pinbelegung[8] = { 0,0,0,0,0,0,0,0};
char incomingData = 0;
//Zum Lesen der Daten uas HTML GET Befehl
String readString = String(100); // string for fetching data from address
static boolean ledValue1; // static : behält den Wert für den nächsten loop() Durchlauf;
static boolean ledValue2; // static : behält den Wert für den nächsten loop() Durchlauf;
static boolean ledValue3; // static : behält den Wert für den nächsten loop() Durchlauf;
static boolean ledValue4; // static : behält den Wert für den nächsten loop() Durchlauf;
static boolean ledValue5; // static : behält den Wert für den nächsten loop() Durchlauf;
static boolean ledValue6; // static : behält den Wert für den nächsten loop() Durchlauf;
static boolean ledValue7; // static : behält den Wert für den nächsten loop() Durchlauf;
static boolean ledValue8; // static : behält den Wert für den nächsten loop() Durchlauf;
/*
//Erst Array ändern, dann Pin setzen
if(incomingData == 'a'){
switch[0] = 1;
ledValue1 = HIGH;
Serial.println("Led 1 ON");
}
if(incomingData == 'b'){
switch[0] = 0;
ledValue1 = LOW;
Serial.println("Led 1 OFF");
}
*/
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,178, 225);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(ledPin6, OUTPUT);
pinMode(ledPin7, OUTPUT);
pinMode(ledPin8, OUTPUT);
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}
zu machen, muss ich Dich leider enttäuschen. Beim nächsten Durchlauf von loop() wird das eben gesetzte incomingData durch das "char incomingData = Serial.read();" direkt wieder überschrieben.
Ich würde an Deiner Stelle folgendes machen. Das setzen der Ausgänge erfolgt erst ganz am Ende von loop() und nicht in den einzelnen Code-Zeilen. Das Ganze dann in einer Schleife. Damit das ganze einfacher wird, würde ich die einzelnen Pins für die LEDs auch in ein Array packen:
//das hier ganz oben wo auch pinbelegung[] definiert wird:
byte ledpins[8] = { 2,3,4,5,6,7,8,9};
//das hier am ende von loop um alle geänderten pins zu setzen
for (int i=0;i<8;i++) digitalWrite(ledpins[i],pinbelegung[i]);
Ich generie mir ein HTML mit radio buttons für on/off, aber ich muss das Skript immer zweimal ausführen, bis sich der Pin schalten lässt. Wenn ich den Befehl direkt an der Adresse mit übergebe,, dann passiert das nicht???
Bsp. /?incomingData0=a wird sofort ausgeführt, über
ich schalte mein wohnzimmerlicht mittels arduino-webserver, und ich habe das gleiche phänomen, wenn ich mit meinem ipod touch schalte. von jedem anderen gerät muß ich nur einmal "drücken" (computer, galaxy note, blackberry, billig-android-tablet).
hab's mir noch nicht angesehen, weil der ipod ohnehin nicht dafür gedacht ist.