Telnet-Verbindung wird unterbrochen

Hallo Zusammen,
ich möchte mit den Arduino einen Datenlogger realisieren, der die Zustände der Eingänge über Ethernet an einen PC sendet.
Auf dem PC sollen die Daten dann angezeigt und weiterverarbeitet werden.

Meine verwendete Hardware:

  • SainSmart MEGA2560 R3
  • Ethernet Shield v5.0

Prinzipiell klappt es schon das Arduino als Telentclient mit einen Telnetserver auf dem PC zu verbinden.
Auch das Datenschicken von Borad zum PC funktioniert grundsätzlich.

Allerdings bricht das Board nach einiger Zeit (Zeit und Datenmenge beliebig, nicht reproduzierbar) die Datenübertragung ab.
Ein Whiresharksmitschitt zeigt, dass bis zum Auftreten des Abruchs das Board jedes Zeichen einzeln übers Netz schickt (Scheint okay zu sein wenn ich den "client.println()"-Befehl richtig verstanden habe). Im Fehlerfall wird jedoch eine ganze Sequenz an Zeichen übertragen und dann kommt nix mehr.
Selbst ein Reset von Board und Shield bringen nix. Die Ethernetschnittstelle hängt, da nichtmal versucht wird eine Verbindung zum Server aufgebaut.
Erst nach Wegnehmen der Versorgungsspannung und anschließenden Wiederanschluss funktioniert alles wieder.
Der Server, der auf dem PC läuft erkennt den Abbruch der Verbindung. Nach Spannung AUS/AN meldet er die Verbindung und zeigt bis zum nächsten Absturz artig die Daten an. (Er muss nicht neugestartet werden.)

Hier das Testprogramm für die Datenübertragung:

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAA };
IPAddress ip(192,168,6,7);
IPAddress server(192,168,6,2); 
EthernetClient client;
String Ausgabe0 = "";
int Ausgabe1 = 0;
String Trennzeichen = ";";
String Startzeichen = "*";
String Endezeichen = "#";
int Schleife = 0;

void setup() {
  pinMode(53, OUTPUT);
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  Serial.println("connecting...");
  delay(1000);
  while (Schleife == 0)
  {
    client.connect(server, 2300);
    Serial.println("Server connection failed_" + String (client.connected(), DEC));
    delay (1000);
    if (client.connected()) 
    {
      Schleife = 1;
    }
  }
  Serial.println("Server connection OK");
  delay (100);
}

void loop() {
  Ausgabe1 = Ausgabe1 + 1;
  Ausgabe0 = String(Startzeichen + String(millis(), DEC) + Trennzeichen + String(Ausgabe1, DEC) + Endezeichen);
  Serial.println(Ausgabe0);
  client.println(Ausgabe0);
  delay(1);
}

Meine Frage ist jetzt:
Was bzw. wo mache ich etwas falsch?

Mit freundlichen Grüßen
Oliver

Vielleicht mal C Strings probieren. Das ist speicher-schonender als ständig String-Objekte zu allozieren und wieder freizugeben.

const byte bufferSize = 20;             //Größe anpassen auf mindestens maximale String-Länge + 1
char ausgabe0[bufferSize];

snprintf(ausgabe0, bufferSize, "*%d;%d#",  millis(), ausgabe1);

Ich weiß aber nicht ob es wirklich daran liegt. Kann auch was anderes sein.

Danke für den Tip.

Hilft aber leider nicht, im Gegenteil jetzt kommt der Absturz sehr viel schneller.
Ach was ich noch vergessen habe, der Serielle Monitor des Board läuft weiter als wenn nix geschehen ist. Es werden lediglich keine Daten mehr übers Netz ausgegeben.

Du concatenierst Strings dauernd mit + nur um sie dann auszugeben. Das belastet den Speicher unnötig. Warum nicht einfach alles direkt ausgeben?

Okay, das mit der unnötigen Speicherlast stimmt, hat mich bisher aber nicht gestört.
Denn ich versuche erstmal eine lauffähig minimal Version an den Start zu bringen und erst dann geht es ans schnell, schlank, schön und effizient machen.
Ich fange auch erstmit mit dem Arduino an und sammele daher noch eine Menge Wissen.

Ich habe jetzt mal die den Code wie folgt abgeändert:

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAA };
IPAddress ip(192,168,6,7);
IPAddress server(192,168,6,2); 
EthernetClient client;
String Ausgabe0 = "";
int Ausgabe1 = 0;
String Trennzeichen = ";";
String Startzeichen = "*";
String Endezeichen = "#";
int Schleife = 0;

void setup() {
  pinMode(53, OUTPUT);
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  Serial.println("connecting...");
  delay(1000);
  while (Schleife == 0)
  {
    client.connect(server, 23);
    Serial.println("Server connection failed_" + String (client.connected(), DEC));
    delay (1000);
    if (client.connected()) 
    {
      Schleife = 1;
    }
  }
  Serial.println("Server connection OK");
  delay (100);
}

void loop() {
  Ausgabe1 = Ausgabe1 + 1;
  Serial.print(Startzeichen);
  Serial.print(String(millis(), DEC));
  Serial.print(Trennzeichen);
  Serial.print(String(Ausgabe1, DEC));
  Serial.println(Endezeichen);
  client.print(Startzeichen);
  client.print(String(millis(), DEC));
  client.print(Trennzeichen);
  client.print(String(Ausgabe1, DEC));
  client.println(Endezeichen);
  delay(10);
}

leider ohne Änderungen.
Es bricht die Ethernetübertragung zusammen, ABER NICHT der Programmlauf und die Übertragung über den seriellen Port.
Gleiches gilt fürs schreiben der Daten auf eine SD-Karte, auch hier funktioniert alles einwandfrei und ohne Probleme.
Daher gehe ich davon aus, dass das Programm soweit erstmal korrekt ist, nur leider nix mehr übers Netz geht.
Eine weitere Erkenntnis die mittlerweile hinzugekommen ist: ->
Nach dem Boardreset wird für genau einen Datensatz eine Verbindung hergestellt. Es wird wieder eine ganze Sequenz übertragen und dann ist Schicht im Schacht und nix geht mehr übers Netz. Das Programm funktioniert aber einwandfrei und auf dem seriellen Port erscheinen die korrekten Anzeigen.

Ich gehe daher davon aus, dass irgendwas mit den Sendepuffer des Shield nicht passt.
Muss der freigegeben/geleert werden, oder besser kann ich mittels Befehl dafür sorgen, dass er frei/leer gemacht wird?

Mit freundlichen Grüßen
Oliver

Hallo solor!

Hast Du schon eine Lösung gefunden.
Ich habe das gleiche Problem.

mfG
Cyberling2

War da nicht mal was, dass die Verbindung unterbrochen wird wenn keine Daten mehr kommen, oder so?
Hatte beim Raspberry Pi screen dazu benutzt.