Automatisierte Lichtsteuerung Probleme

Hallo liebe Arduino Gemeinde,

ich habe mit einem “Arduino Ethernet” eine Automatisierte Lichtsteuerung programmiert welche mit einem C# Programm gesteuert wird.

Soweit ist diese Steuerung auch wunderbar und es läuft alles wie es soll. Allerdings habe ich folgendes Problem:

Ich habe den sporadischen Fehler, dass das C# Programm die Verbindung zum Arduino verliert und ich verzweile an der Fehlersuche.

Was heißt das genau? Ich kann das Board auch wenn dieser Fehler auftritt weiterhin anpingen. Es scheint also kein Netzwerk Problem zu sein. Auf dem Arduino läuft ein Webserver welcher in einer XML Datei (Ajax) die Zustände der Eingänge einträgt. Meine Vermutung ist, dass der Webserver sich aufhängt oder wie einen Schluckauf bekommt.

Aber gut nun erst mal hier der technische Aufbau der Steuerung.

Arduino und der PC mit dem C# Programm hängen an einem Switch und sind mit dem Netzwerk verbunden.

An dem Arduino ist an einem Digitalen Pin einmal ein Dämmungssensor und einmal ein Alarmkontakt von der Alarmanlage angeschlossen.

Am SDA/SDC (i2C) Pin sind 2 Port Expander MCP23017 angeschlossen um auf insgesamt 16 Eingangsports und 2 Port Expander MCP23017 um auf 16 Ausgangsports zuerweitern.

Programmtechnischer Ablauf:

Licht ist aus, Alarmanlagen Kontakt sagt, Gebäude ist unscharf und die Steuerung schaltet eine Teilbeleuchtung ein

Ab einer bestimmten Uhrzeit Schaltet die Steuerung dann weitere Beleuchtungskreise ein

Wenn es Dunkel wird und der Dämmerungssensor schaltet, geht die Außenbeleuchtung ein

Wenn die Alarmanlage wieder scharf geschaltet wird, dann macht die Steuerung sämtliche Beleuchtung wieder aus.

Codeablauf:

Die Zustände der Eingänge werden über Ajax in die XML Datei geschrieben. Diese XML Datei ruft das C# immer wieder ab. Wenn das C# Programm nun festellt, dass sich der Zustand von dem Alarmkontakt geändert hat, dann schickt es dem Arduino den Befehl das es diverse Ausgänge schalten soll. Dies macht das Arduino dann auch und die Zustände der Eingänge ändern sich in der XML Datei. Dies bekommt das C# dann mit und weiss das die Eingänge korrekt geschaltet sind.

Dies war jetzt nur die kurzfassng von dem Ablauf ich hoffe es ist verständlich.

Was meint ihr könnte das Problem sein?
Programmierfehler?
Hardware vom Arduino zu schwach?

Ich habe schon ein Arduino UNO mit Ethernetshild ausprobiert auch hier das selbe Problem.

Cinema.ino (10.7 KB)

SaschaH87:
Was meint ihr könnte das Problem sein?
Programmierfehler?
[/quote]
Ich tippe mal auf eine Kombination von “Programmierfehler” und “sporadische Netzwerkfehler”.
Dein Programmierfehler im Sketch scheint zu sein: FEHLENDE FEHLERBEHANDLUNG
Insbesondere:
Der W5100 Ethernet-Chip kann nur maximal 4 Ethernet-Verbindungen (“Sockets”) gleichzeitig offenhalten.
Dein Sketch neigt nun aber latent dazu, dass Ethernet-Verbindungen geöffnet, und danach nie wieder geschlossen werden.
Jedesmal, wenn der Fehler auftritt, verlierst Du eine von vier möglichen Ethernetverbindungen zwischen dem W5100 und Deinem Netzwerk.
Der konkrete Fehler dürfte sein, dass Du neue Client-Verbindungen aufbaust, mit der Zeile:
EthernetClient client = server.available();
Dabei bekommst Du, wenn ein Client eine Verbindung anfordert, eine der vier möglichen Verbindungen des W5100 zugeteilt.
Und im weiteren Verlauf wird diese Verbindung wieder freigegeben, wenn diese Zeile ausgeführt wird:
client.stop();
Die Zeile "client.stop(); " wird von Deinem Sketch allerdings nur ausgeführt, wenn vorher ein gültiger HTTP-Request empfangen und bearbeitet wurde.
Richtig wäre: Nach einem erfolgreichen Verbindungsaufbau ein TIMOUT vorsehen.
Also nachdem sich ein Client mit Deinem Webserver verbunden hat, müßte die Zeile client.stop(); spätestens(!) nach einer vernünftigen TIMEOUT Zeit von beispielsweise 10 Sekunden ausgeführt werden, und wzar unabhängig davon, ob der Sketch innerhalb dieser Zeit einen gültigen HTTP-Request erhalten hat oder nicht. Wenn Du stattdessen Client-Verbindungen immer erst nach Erhalt eines gültigen HTTP-Requests wieder schließt, kannst Du Dir bei auftretenden Netzwerkfehlern sonst schleichend alle vier Ethernetverbindungen des W5100 aufbrauchen, bis bei weiteren Verbindungsanfragen keine Ethernet-Verbindung mehr frei ist, um sich nochmal mit einem Client zu verbinden. Und dann bist Du in einer typischen Totverriegelung (logischer deadlock):
- Dein Sketch wartet nach Herstellen einer Verbindung “ewig” auf einen HTTP-Request
-und der W5100 wartet ebenso "ewig darauf, dass eine seiner vier Ethernet-Sockets wieder geschlossen wird, damit er eine neue Verbindung aufbauen kann.

Hallo jurs,

vielen dank für deine schnelle antwort.

das scheint mir alles auch sehr logisch. nach genau so einer aussage habe ich gesucht…danke…

hoffentlich ist das auch der fehler ich werde das sofort ma testen.

Würdest du den Timeout nach einem erfolgreichen Verbindungsaufbau oder nach dem die Verbindung geschlossen wurde setzen?

In deiner Antwort lese ich das einmal so und einmal so :wink:

Gruß,

Sascha

SaschaH87: Würdest du den Timeout nach einem erfolgreichen Verbindungsaufbau oder nach dem die Verbindung geschlossen wurde setzen?

In deiner Antwort lese ich das einmal so und einmal so ;-)

Der Timeout muss anfangen, die Zeit zu zählen, sobald die Verbindung zum Client aufgebaut(!) worden ist. Und falls nach Ablauf einer festgesetzten Zeit kein vollständiger HTTP-Request empfangen wurde, dann muss die Verbindung dennoch und zwangsweise mit client.stop(); getrennt werden.

Du darfst die verwaiste Verbindung, über die keine Daten laufen, nicht(!) auf ewig bestehen lassen und bei der nächsten Verbindungsanfrage wieder eine neue Verbindung aufbauen, sondern Du musst zuerst die alte Verbindung schließen (entweder nach Erhalt eines vollständigen Request-Headers oder nach Ablauf einer Timeout-Zeitspanne), erst dann darf eine neue Verbindung aufgebaut werden.

Du darfst die verwaiste Verbindung, über die keine Daten laufen, nicht(!) auf ewig bestehen lassen

Dem stimme ich zu.

sondern Du musst zuerst die alte Verbindung schließen (entweder nach Erhalt eines vollständigen Request-Headers oder nach Ablauf einer Timeout-Zeitspanne), erst dann darf eine neue Verbindung aufgebaut werden.

Da ist es, wie mit allen begrenzten Ressourcen. So viel wie da ist, kann man ohne Schaden nutzen.

Hallo,

ich wollte euch mal ein Feedback geben.

Leider ist das Problem noch nicht behoben.

Ich habe als erstes mal den Code noch ein wenig aufgeräumt, damit man ihn besser lesen kann und ich habe auch noch ein paar Zeilen gelöscht. Hier waren noch Test Zeilen von mir drin wo ich im Serial Monitor Daten reingeschrieben habe.

Als nächstes habe ich versucht euren Tipp umzusetzen allerdings bin ich hierbei nicht weiter gekommen. Ich stehe da etwas auf dem Schlauch und weiss nicht richtig wie ich das machen soll. Ich bin jetzt kein Pro in C und brauche manchmal einfach einen kleinen Anfang.

Deshalb habe ich erst mal mir im Serial Monitor den Timer anzeigen lassen. Dabei habe ich festgestellt, dass wenn ich die Seite welche der Webserver anzeigen soll ganz schnell und oft aktualisiere, dass der Timer stehen bleibt und auch nicht wieder alleine anläuft. Das heißt doch, dass sich das ganze Arduino aufgehangen hat oder?

Ok was könnte hier die Lösung sein. Ich habe also mal ein anderes Board genommen. Ein Arduino Due mit Ethernet Shield per SPI Kaberverbindung. Dieses Board ist ja ein wenig Leistungsstärker.

Auch hier habe ich den selben Versuch gestartet. Hierbie ist mir aufgefallen, dass auch dieses Board sich aufhängt aber es läuft nach einer kurzen Zeit von wenigen Sekunden auch wieder alleine an.

Jetzt die Frage an euch. Meint ihr immer noch dass eure Lösung eine Idee wäre und wenn ja könntet ihr mir dabei vielleicht kurz helfen? Oder meint ihr aus den neuen Infos ein anderes Problem zu entdecken?