Nach wenige Minuten keine Ethernetverbindung zum Arduino

Begonnen von HolgerB, 19 April 2015, 21:30:17

Vorheriges Thema - Nächstes Thema

HolgerB

Hallo zusammen,

ich hoffe ich bin hier richtig. Als ich den HTTPMOD zum Abholen der Analogwerte testen wollte bin ich nun über das Problem gestolpert, dass der Arduino nicht mehr reagiert. Interessanterweise hat allerdings ein Befehl zwischendurch mal wieder funktioniert (das automatische Ausschalten um 20:00). Dazu der der relevante Ausschnitt zu den Arduinoabfragen hier:

# Arduino Garten
# Rasensprenger
define rasenbutton FS20 55d1 07
attr rasenbutton IODev CUL433
attr rasenbutton alias Rasensprenger
attr rasenbutton group Rasen
attr rasenbutton room Garten

define rasenbuttonon notify rasenbutton:on.* { GetHttpFile("192.168.178.13:80","/?cmd=set_D7_ON");;}
attr rasenbuttonon room hidden
define rasenbuttonoff notify rasenbutton:off.* { GetHttpFile("192.168.178.13:80","/?cmd=set_D7_OFF");;}
attr rasenbuttonoff room hidden

# Beetbewässerung
define beetbutton FS20 55d1 08
attr beetbutton IODev CUL433
attr beetbutton alias Beetbewässerung
attr beetbutton group Beet
attr beetbutton room Garten

define beetbuttonon notify beetbutton:on.* { GetHttpFile("192.168.178.13:80","/?cmd=set_D8_ON");;}
attr beetbuttonon room hidden
define beetbuttonoff notify beetbutton:off.* { GetHttpFile("192.168.178.13:80","/?cmd=set_D8_OFF");;}
attr beetbuttonoff room hidden

# Teichpumpe
define teichbutton FS20 55d1 05
attr teichbutton IODev CUL433
attr teichbutton alias Teichpumpe
attr teichbutton group Teich
attr teichbutton room Garten

define teichbuttonon notify teichbutton:on.* { GetHttpFile("192.168.178.13:80","/?cmd=set_D5_ON");;}
attr teichbuttonon room hidden
define teichbuttonoff notify teichbutton:off.* { GetHttpFile("192.168.178.13:80","/?cmd=set_D5_OFF");;}
attr teichbuttonoff room hidden

define teichautoaus at 20:00:00 set teichbutton off
define teichautoan at 06:30:00 set teichbutton on

define gartensensors HTTPMOD http://192.168.178.13/?cmd=get_analog_values 300
attr gartensensors reading01Name Analog1
attr gartensensors reading01Regex 1:([\d\.]+)


Aber vermutlich liegt das eher am Sketch? Da ist m.E. nicht Aufregendes drin - oder fällt Euch was auf?

#include <UIPEthernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
// gateway and subnet are optional:
String cmd="";
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 178, 13);

// http is Port 80
EthernetServer server(80);

void setup() {
  // initialize the ethernet device
  Ethernet.begin(mac, ip);
 
  // start listening for clients
  server.begin();
 
  // Set digital pins to output
  for (int d=5; d<=9; d++) {
    pinMode(d, OUTPUT);
    digitalWrite(d, HIGH);
  }
}


void loop() {
 
  // wait for a new client:
  short i = 0;
  String s = "";
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
          if (c=='?'){
            while (c!='\r')
            {
              cmd+=c;
              c=client.read();
            }     
          }
        }
      }
    }
   
    //Send result
   
    if (cmd.indexOf("?cmd=get_digital_values")==0)
      for (short d=5; d<=9; d++)
      {
        client.print("D");
        client.print(d);
        client.print(": ");
        client.print(digitalRead(d));
        client.print(" ");
      }
    else if (cmd.indexOf("?cmd=get_analog_values")==0) {
      for (short a=1; a<=4; a++)
      {
        client.print(a);
        client.print(": ");
        client.print(analogRead(a));
        client.print(" ");
      }
    }
    else if (cmd.indexOf("?cmd=set_D") == 0) {
      if (cmd.length()>14) {
        s = cmd.substring(10,11);
        i = s.toInt();
        s = cmd.substring(12);
        if (s.indexOf("ON")==0 || s.indexOf("OFF")==0) {
          client.print("D");
          client.print(i);
          if (s.indexOf("ON")==0) {
            digitalWrite(i, LOW);
            client.print(":1");
          }
          else {
            digitalWrite(i, HIGH);
            client.print(":0");
          }
        }
      }
    }
    else {
      client.print("Test");
    }
    client.flush();
    cmd = "";   
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
}


Würde mich echt freuen, wenn jemand von Euch einen Vorschlag hätte...

Viele Grüße
  Holger

John

Hi HolgerB,

der freie verfügbare Speicher ist sehr kritisch zumal du UIPEthernet verwendest.

Mit folgender Funktion kannst du diesen ermitteln.

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}


Ich hatte in meinem Sketch zu wenig davon und er war extrem instabil.

Erst als ich mehr Reserven hatte lief alles glatt. Der Code selbst war fehlerfrei, nur eben der RAM zu wenig.

Versuche statische Strings in den Flashspeicher zu verbannen, damit spart man einiges.

Alternativ solltest du überlegen, ob du nicht besser MQTT verwendest , statt den HTTP-Kram.
Aber das ist Geschmack-Sache.

John
CubieTruck Docker Node-Red Tasmota Shelly Homematic-IP

HolgerB

Hallo John,

ich wollte gerade mein Post updaten, als Du geantwortet hast: Mir ist noch aufgefallen, dass wenn die Verbindung regelmäßig genutzt wird der Arduino schnell reagiert. Nur zum "Aufwecken" wird anscheinend eine längere Zeit benötigt die dann in einen Timeout mündet. Ist das ggf. eine Schwäche der UIPEthernet oder ist das ggf. der Architektur mit dem Ethernet Shield geschuldet?

Bzgl. des Speichers:
ZitatDer Sketch verwendet 21.700 Bytes (70%) des Programmspeicherplatzes. Das Maximum sind 30.720 Bytes.
Globale Variablen verwenden 1.210 Bytes (59%) des dynamischen Speichers, 838 Bytes für lokale Variablen verbleiben. Das Maximum sind 2.048 Bytes.
Bin ich damit noch im grünen Bereich? Brauchen die anderen Ethernet Libraries deutlich weniger Speicher?

Was das MQTT angeht: Ich hänge definitiv nicht am HTTP, aber habe mit MQTT keine Erfahrung...

Viele Grüße
  Holger

John

Hi Holger,

mit einem Standard-Ethernet-Schield verwendet man Ethernet.h.
Auf diesem Schield befindet sich ein W5100, der den TCP/IP Stack bereits integriert hat.

Wenn du jedoch einen enc28j60 verwendest, muss Arduino selbst den TCP/IP Stack übernehmen, dann ist
UIPEthernet einzusetzen. (Mehr Flash und RAM Verbrauch)

MQTT hat im Gegensatz zu der HTTP-Lösung einen permanente Client-Verbindung zum Broker und ist sehr einfach zu implementieren.
Ich behaupte einfacher, als die HTTP-Lösung.

Meine Anwendungen laufen damit total stabil (sowohl mit W5100 als auch mit enc28j60).

John
CubieTruck Docker Node-Red Tasmota Shelly Homematic-IP

Thorsten Pferdekaemper

Zitat von: HolgerB am 19 April 2015, 22:07:06
Bzgl. des Speichers: Bin ich damit noch im grünen Bereich?
Die Compiler-Meldung kann nur globale Variablen analysieren. Der Compiler "weiß" nicht, welche Funktionen tatsächlich wann aufgerufen werden. Außerdem weiß er auch nicht, wie viel Speicher mit malloc (oder new) angefordert wird. Man kann also anhand dessen noch nicht viel sagen. Die free_ram-Funktion ist viel besser.

Ich hatte mit der Verbindung mal ein ähnliches Problem, das nicht am Speicher lag. Ich habe das dadurch gelöst (glaube ich), dass ich einfach Ethernet.begin nochmal aufrufe, wenn für 15 Minuten nichts über's Netzwerk kam.

Gruß,
  Thorsten
FUIP

gero

Du hast nicht zufällig einen zweiten Arduino mit derselben MAC-Adresse am laufen?
Das könnte das geschilderte Problem erklären.

Gruß,
Gero
Odroid C1 - CULV3-868, JeeLink
16 x TX 29 DTH
MAX!: 15x Heizkörperthermostat+, 2x Wandthermostat, 14x Fenserkontakt, 1x Ecotaster
FS20 S4A, FS20IRF, BSB-Heizungssteuerung über Atmega2560
Z-Wave: ZME_UZB1, Fibaro Wall Plug + Motion Sensor

HolgerB

Zitat von: gero am 20 April 2015, 13:32:02
Du hast nicht zufällig einen zweiten Arduino mit derselben MAC-Adresse am laufen?

Nein - definitiv nicht - mit Erhöhung es Timeout und regelmäßiger Abfrage ist es heute bisher durchgelaufen - mal abwarten

Viele Grüße
  Holger