Forum: Mikrocontroller und Digitale Elektronik Arduino als Server oder Client


von Stefan (Gast)


Lesenswert?

Hallo Leute

Ich bin momentan an einem Übungsprojekt. Dabei geht es um die 
Ansteuerung eines Arduino Uno mit Ethernet Shield übers Internet.

Übers Internet kann eine 4stellige Zahlenkombination ans Arduino 
gesendet werden. Am Arduino sind zwei Taster angeschlossen, mit welchen 
man ebenfalls eine 4stellige Zahlenkombination eingeben kann. Stimmt die 
eingegebene Kombi mit der aus dem Netz gesendeten überein, leuchtet eine 
grüne LED, ansonsten eine Rote. Im Browser soll der angezeigt werden, ob 
die Kombination richtig eingegeben wurde oder nicht.

Momentan habe ich das so gelöst, dass das Arduino den Webserver spielt. 
Ein Client connected und sendet per POST Befehl die Zahlenkombination. 
Um den aktuellen Status auszulesen mache ich alle paar Sekunden einen 
GET Befehl. Soweit funktioniert alles bestens, einziges Problem ist, 
dass wenn ich die Zahlenkombination mit den Taster eingebe und 
gleichzeitig ein eine GET Anfrage kommt, die Eingabe für rund 2s 
blockiert ist.

Dies möchte ich nun so lösen, dass der Status nur gesendet wird, wenn er 
sich geändert hat.  Dazu müsste ich ja vom Arduino aus einen POST Befehl 
absetzen. Da das Arduino aber der Server ist, ist dies nicht möglich.

Nun meine Frage, wie könnte ich das lösen?

Danke für antworten.

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:

Die Frage ist eher:

> gleichzeitig ein eine GET Anfrage kommt, die Eingabe für rund 2s
> blockiert ist.


Warum gibt es hier eine 2s Blockade?

von Stefan (Gast)


Lesenswert?

Karl Heinz schrieb:
> Stefan schrieb:
>
> Die Frage ist eher:
>
>> gleichzeitig ein eine GET Anfrage kommt, die Eingabe für rund 2s
>> blockiert ist.
>
> Warum gibt es hier eine 2s Blockade?

Karl Heinz schrieb:
> Warum gibt es hier eine 2s Blockade?

Weil die GET Anfrage bearbeitet und geantwortet wird.

von avr (Gast)


Lesenswert?

Stefan schrieb:
> Weil die GET Anfrage bearbeitet und geantwortet wird.

nein, weil dein Programm Zeit verbrät. Da werden zu 99.9% 
delay-Funktionen genutzt.

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:
> Karl Heinz schrieb:
>> Stefan schrieb:
>>
>> Die Frage ist eher:
>>
>>> gleichzeitig ein eine GET Anfrage kommt, die Eingabe für rund 2s
>>> blockiert ist.
>>
>> Warum gibt es hier eine 2s Blockade?
>
> Karl Heinz schrieb:
>> Warum gibt es hier eine 2s Blockade?
>
> Weil die GET Anfrage bearbeitet und geantwortet wird.

Natürlich tut es das.
Aber das verbrät keine 2 Sekunden, wenn man es richtig macht :-)

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

>> Weil die GET Anfrage bearbeitet und geantwortet wird.
>
> Natürlich tut es das.
> Aber das verbrät keine 2 Sekunden, wenn man es richtig macht :-)


Wenn du dich an das Webserver Tutorial gehalten hast, das ich auf die 
schnelle gefunden habe
1
void loop()
2
{
3
    EthernetClient client = server.available();  // try to get client
4
5
    if (client) {  // got client?
6
        boolean currentLineIsBlank = true;
7
        while (client.connected()) {
8
            if (client.available()) {   // client data available to read
9
                char c = client.read(); // read 1 byte (character) from client
10
... 
11
           } // end if (client.available())
12
        } // end while (client.connected())
13
        delay(1);      // give the web browser time to receive the data
14
        client.stop(); // close the connection
15
    } // end if (client)
16
}

... ja dann wundert mich das nicht mehr, dass du da in Zeitprobleme 
kommst. Das ist genau so programmiert, dass man eben nicht den µC 
mehrere Dinge quasi gleichzeitig erledigen lassen kann.

von Alexander S. (esko) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
> void loop()
> {
>     ...
>         delay(1);      // give the web browser time to receive the data
>     ...
> }
Man hat das Gefühl, Arduinos verführen zu schlechtem Code. Danke für das 
Beispiel, Karl-Heinz.

von cybmorg (Gast)


Lesenswert?

Arduinos verleiten hoechstens gewisse Nutzer zu schlechten Kommentaren.

von Karl H. (kbuchegg)


Lesenswert?

Alexander Schmidt schrieb:
> Karl Heinz schrieb:
>> void loop()
>> {
>>     ...
>>         delay(1);      // give the web browser time to receive the data
>>     ...
>> }
> Man hat das Gefühl, Arduinos verführen zu schlechtem Code. Danke für das
> Beispiel, Karl-Heinz.

Der Delay ist an dieser Stelle gar nicht mal so sehr das Problem. 
delay(1) ist laut Arduino Doku 1 Millisekunde. Das wäre noch 
verschmerzbar.

Aber dieser Code will die komplette Transaktion vom Anmelden des 
Web-Browsers, bis zur Vollständigen Behandlung der kompletten Abfrage in 
einem Rutsch durchziehen.
Wobei: wenn ich mich nicht täusche dann melden sich doch Web-Browser gar 
nicht beim Server ab. Oder? D.h. das hier
1
    while (client.connected()) {
ist doch im Grunde nichts anderes als eine versteckte Abfrage auf "Hat 
sich der Browser lange genug nicht gemeldet, so dass man das als Timeout 
werten könnte". Kann auch sein, dass ich da daneben liege. So intim bin 
ich dann mit den Details da auch wieder nicht. Aber selbst wenn, sind 
das immer noch ein paar Pakete, die auf den Leitungen hin und her gehen 
müssen.

: Bearbeitet durch User
von Stefan (Gast)


Lesenswert?

Karl Heinz schrieb:
> Wenn du dich an das Webserver Tutorial gehalten hast, das ich auf die
> schnelle gefunden
>
> ... ja dann wundert mich das nicht mehr, dass du da in Zeitprobleme
> kommst. Das ist genau so programmiert, dass man eben nicht den µC
> mehrere Dinge quasi gleichzeitig erledigen lassen kann.

Ja henauso hab ich das proggrammiert. Wie könnte man dies besser lösen?

von Jürgen S. (jurs)


Lesenswert?

Stefan schrieb:
> Ja henauso hab ich das proggrammiert. Wie könnte man dies besser lösen?

Wenn Du möchtest, dass das Programm sowohl mit verbundenem Web-Client 
als auch mit nicht verbundenem Web-Client unmittelbar auf Tastendrücke 
reagiert, dann mußt Du eine Funktion zum Behandeln von Tastendrücken 
sowohl innerhalb Deiner längerlaufenden while-Schleife aufrufen als auch 
normal in der loop. Mal angenommen, die Funktion zum Behandeln von 
gedrückten Tasten nennst Du "handleInput()", dann beispielsweise:
1
void loop()
2
{
3
    EthernetClient client = server.available();  // try to get client
4
5
    if (client) {  // got client?
6
        boolean currentLineIsBlank = true;
7
        while (client.connected()) {
8
            handleInput();
9
            if (client.available()) {   // client data available to read
10
                char c = client.read(); // read 1 byte (character) from client
11
... 
12
           } // end if (client.available())
13
        } // end while (client.connected())
14
        delay(1);      // give the web browser time to receive the data
15
        client.stop(); // close the connection
16
    } // end if (client)
17
    handleInput();
18
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.