INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Programmabsturz
07.04.2016, 14:28
Beitrag #1
Programmabsturz
Hallo allerseits,
Ich habe mir einen kleinen Wetterserver gebastelt mit arduino Uno, ethernetshield, RTC und div. Sensoren.
Das Sketch ist aus verschieden Beispielen zusammengestellt.
Eigentlich funktioniert das auch. Im Netz zu erreichen unter http://hjmbsob.selfhost.eu
Nach einigen Stunden Betrieb ist der Server jedoch nicht mehr erreichbar, und zwar nicht nur im internet, sondern auch bei mir intern. Also wohl kein Problem des DynDNS.
Hat jemand eine idee, warum das Programm abstürzt?

Code:
/*
Ulis kleiner Wetterserver
  
A0 - Helligkeitssensor
A1 - Feuchtigkeitssensor

*/

#include <SPI.h>                          //serieller peripherer Internetbus
#include <Streaming.h>
#include <Ethernet.h>                     // Ethershield
#include <DS3232RTC.h>                    // RealTimeClock
#include <Time.h>                          //Zeitberechnung
#include <Wire.h>                          // I²C
#include <Adafruit_BMP085.h>
#include "DHT.h"
#define DHTPIN 15                          // DHT - benutzter ARDUINO-Pin (Analog-Pin 1)
#define DHTTYPE DHT11                      // DHT Typ22
DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP085 bmp;


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x31};
IPAddress ip(192, 168, 2, 106);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

int Tag;
int Monat;
int Jahr;
int Stunde;
int Minute;
int Sekunde;
int t;
char zeitstring[130];
char t_string[5];

void setup() {
  bmp.begin();
  dht.begin();
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
setSyncProvider(RTC.get);   // the function to get the time from the RTC
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  EthernetClient client = server.available();
  if (client) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<h2>Ulis kleiner Wetterserver</h2>");
          client.println("<h3>Bad Sobernheim, Leinenborner H&oumlhe</h3>");        

        // Datum, Uhrzeit ermitteln und senden
           static time_t tLast;
           time_t t;
           t = now();
           Tag = day(t);
           Monat = month(t);
           Jahr = year(t);
           Stunde = hour(t);
           Minute = minute(t);
           Sekunde = second(t);
          
           sprintf(zeitstring,"%02d.%02d.%4d &nbsp %02d:%02d:%02d Uhr",Tag,Monat,Jahr,Stunde,Minute,Sekunde);
           client.println("<html>");
           client.print("aktualisiert: &nbsp&nbsp");
           client.print(zeitstring);
          client.print("<br>");
          client.print("<hr />");
        
        //Sensoren lesen und senden
          int He = analogRead(A0);
          client.print("Helligkeit:  ");
          client.println(He);
          client.print("<br>");
          float T = bmp.readTemperature();
          dtostrf(T, 4, 1, t_string);
          client.print("Temperatur: ");
          client.print(t_string);
          client.print(" &#xb0;C");
          client.print("<br>");
          int P = bmp.readPressure() / 100 + 27; // 27 = Höhenkorrektur
          client.print("Luftdruck: ");
          client.print(P);
          client.print(" HPa");
          client.print("<br>");
          int Hu = dht.readHumidity();
          client.print("rel. Feuchtigkeit: ");
          client.print(Hu);
          client.print(" %");
          
          //Kommentare senden
          client.print("<br><br>");
          client.print("Die Sensoren liegen noch auf dem Basteltisch.<br>");
          client.print("Au&szligenmontage bei w&aumlrmerem Wetter.<br>");        
          client.println("</html>");
        }
      
    // give the web browser time to receive the data
    delay(100);
    // close the connection:
    client.stop();
  }
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.04.2016, 16:07
Beitrag #2
RE: Programmabsturz
Ich habe mir den Sketch angesehen aber keinen Fehler entdecken können.
Ich habe einen Variablen-Überlauf vermutet, konnte aber derartiges nicht finden.

Um dem Problem auf die Schliche zu kommen, solltest du die einzelnen Programmteile (Uhr, Sensoren, Ethernet) in eigene Funktionen packen und dann einzeln freigeben und laufen lassen.

So kannst du feststellen, in welcher Funktion das Problem auftritt.

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.04.2016, 18:18 (Dieser Beitrag wurde zuletzt bearbeitet: 07.04.2016 19:08 von rkuehle.)
Beitrag #3
RE: Programmabsturz
Hallo sowerum,

das Problem ist die Ethernet-Lib.
Die Lib (besser der Wiznet 5100 Chip) kann gleichzeitig max. 4 Sockets / Verbindungen in beide Richtungen "betreuen".
Sobald die 4 Sockets verbraucht sind kommt man in Schwierigkeiten falls alle Sockets auf dem gleichen Port laufen, da die Ethernet Lib zu den existierenden Sockets keine Daten mitführt von wem die Verbindung auf welchem Port angefordert wurde.
Die Folge ist, dass es passieren kann, dass zB. eine Anforderung über Socket 1 reinkommt, die Antwort aber über Socket 4 rausgeht.
Der Code stürzt also nicht ab, sondern arbeitet nur "falsch".

Es gibt zwei Möglichkeiten dies zu umschiffen:
1. das delay() im loop() wesentlich zu vergrößern (> 30000 ms)
Das geht, da die Sockets bei "Untätigkeit" eine maximale Lifetime haben und dann zwangsweise geschlossen werden. So kommt die Lib nicht mit den Sockets durcheinander.
2. Korrektur der Ethernet-Lib. Siehe hier:
http://subethasoftware.com/2013/04/08/ar...nnections/ (Ist in Englisch - aber sehr gut geschrieben).
Hoffe es war verständlich ausgedrückt und man erkennt was gemeint war.

Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
08.04.2016, 11:23 (Dieser Beitrag wurde zuletzt bearbeitet: 08.04.2016 16:17 von sowerum.)
Beitrag #4
RE: Programmabsturz
(07.04.2016 18:18)rkuehle schrieb:  Hallo sowerum,

das Problem ist die Ethernet-Lib.
Die Lib (besser der Wiznet 5100 Chip) kann gleichzeitig max. 4 Sockets / Verbindungen in beide Richtungen "betreuen".
Sobald die 4 Sockets verbraucht sind kommt man in Schwierigkeiten falls alle Sockets auf dem gleichen Port laufen, da die Ethernet Lib zu den existierenden Sockets keine Daten mitführt von wem die Verbindung auf welchem Port angefordert wurde.
Die Folge ist, dass es passieren kann, dass zB. eine Anforderung über Socket 1 reinkommt, die Antwort aber über Socket 4 rausgeht.
Der Code stürzt also nicht ab, sondern arbeitet nur "falsch".

Es gibt zwei Möglichkeiten dies zu umschiffen:
1. das delay() im loop() wesentlich zu vergrößern (> 30000 ms)
Das geht, da die Sockets bei "Untätigkeit" eine maximale Lifetime haben und dann zwangsweise geschlossen werden. So kommt die Lib nicht mit den Sockets durcheinander.
2. Korrektur der Ethernet-Lib. Siehe hier:
http://subethasoftware.com/2013/04/08/ar...nnections/ (Ist in Englisch - aber sehr gut geschrieben).
Hoffe es war verständlich ausgedrückt und man erkennt was gemeint war.

Grüße Ricardo

Da scheint tatsächlich das Problem zu liegen.Ich kann den Fehler manchmal provozieren, wenn ich zwei Connects gleichzeitig tätige. Manchmal wird dann ein Client garnicht bedient, manchmal geht überhaupt nichts mehr.
Zur Kontrolle habe ich mal ein "Serial.println(zeitstring);" in den loop eingefügt. Diese Funktion wird dann auch nicht mehr ausgeführt.
Ob ich mit der Korrektur der Ethernet-lib zurecht komme, muss ich mal probieren, ich bin nicht so richtig der Könner. Aber vielleicht gehts ja auch mit dem verlängerten Delay.

Bei einem Deiay von 30000 hat ja das automatische Refresh nach 5 oder 10 sec., was ich in dem HTML-Code vorgesehen habe, keinen Sinn. Wenn ich den Refresh herausnehme, dürfte es keine Kollisionen mehr geben, und das lange Delay erübrigt sich dann auch. Dann muss der Client das Aktualisieren der Werte manuell veranlassen.
Ich glaube so lass ich's. Die englische Seite schaue ich mir trotzdem noch an.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
08.04.2016, 16:37
Beitrag #5
RE: Programmabsturz
Hallo,
wenn die Anzahl der gleichzeitigen Sockets wirklich das Problem verursacht, würde ich erst mal
Code:
client.println("Refresh: 5");  // refresh the page automatically every 5 sec
aus der Webseite rauswerfen oder die Zeit verlängern.

Dann hatte ich wie hier beschrieben auch mal ein Problem mit dem Timeout einer Verbindung. Das ließ sich lösen ohne in die Library einzugreifen.
Vielleicht hat die dort beschriebene Einstellung auch Auswirkungen auf die Lebenszeit der Sockets, oder es gibt einen ähnlichen Workaround dafür.

Dann gibt es inzwischen auch ein Ethernet Shield 2 welches mit dem Wiznet 5500 Chip arbeitet und dieser kann laut Datenblatt "Supports 8 independent sockets simultaneously".
Dazu braucht man aber auch die "Ethernet2.h", welche in den IDEs von arduino.org enthalten ist.

Gruß
Arne

ExclamationMit zunehmender Anzahl qualifizierter Informationen bei einer Problemstellung, erhöht sich zwangsläufig die Gefahr auf eine zielführende Antwort.Exclamation
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.04.2016, 00:41
Beitrag #6
RE: Programmabsturz
Also obwohl ich den Refresh gelöscht habe, hatte ich wieder einen Absturz.
Mir fällt auf, dass in meinem Sketch, den ich ja ,wie schon gesagt, aus Beispielen zusammengestellt habe, die Ausgabe mit "client.print()" erfolgt. Andere Beispiele mit ähnlicher Funktion benutzen "server.print()". Kann da evt. das Problem liegen?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
11.04.2016, 12:06
Beitrag #7
RE: Programmabsturz
(09.04.2016 00:41)sowerum schrieb:  Mir fällt auf, ... , die Ausgabe mit "client.print()" erfolgt. Andere Beispiele mit ähnlicher Funktion benutzen "server.print()". Kann da evt. das Problem liegen?

Ich lese den Thread nur mit, und hab keine einschlägige Erfahrung, aber das kannst Du ja selber recht schnell ausprobieren.

Grüße
Talim
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste