240x40 Array per Ethernet an PC übertragen?

Hallo Forum,

ich habe ein Arduino Mega 2560 und ein Ethernet Shield. Ich würde gerne wissen, ob man ein Array mit einer Größe von 240 Zeilen und 40 Spalten per Ethernet an den PC übertragen kann?

Ich habe schon zum Anfang ein Programm geschrieben das einen einfachen String mit dem Befehl UDP.Write an den PC sendet. Das klappt soweit!

Jetzt würde ich gerne ein ganzes Array übertragen. Ist das möglich und wenn ja wie?

Vielen Dank, MfG

Sicher geht das. Muss es denn UDP sein, oder darf auch TCP verwendet werden? TCP würde das Übertragen der Daten in mehreren Paketen erleichtern, weil sich der TCP-Stack um die Flusskontrolle kümmert.
Dazu noch folgende Fragen:

  1. Welchen Datentyp hat das Array (byte, int, float, long ...)??
  2. Selbst bei 8 bit (Byte) wären 240x40Bytes schon 9960 Bytes und damit mehr als in den RAM des Mega2560 passt (der hat nur 8K SRAM) Woher stammen also die Daten? Wenn die zeitversetzt generiert werden, ist das wichtig für die Übertragung (Stichwort Timerout)
  3. Wer verarbeitet die Daten auf der PC-Seite? Ein selbst geschriebenes Programm oder ein vorgegebenes. Davon hängt ab wie man die Datenübetragung gestalten muss, ggf. gibt es ja schon ein vorgegebenes Protokoll
  4. Welches Ethernet-Shield hast Du? WizNet5100 Chip oder ENC26J80? Auch das hat Einfluss auf Dein Programm, vor allem wenn mehrere Pakete übertragen werden müssen.

Mario.

Hi Mario,

ob TCP oder UDP ist mir egal.

  1. Hierbei handelt es sich um Integer Werte
  2. Bei den Integer Werten handelt es sich um Bildpixel, die zeitversetzt generiert werden
  3. Ein selbstgeschriebenes Programm verarbeitet die Daten und erzeugt aus dem Array ein Bild
  4. WizNet5100

Jetzt kommt wahrscheinlich die Frage warum man nicht einfach immer nur einen sendet. Das kommt nicht in Frage, weil das in Sachem Zeit nicht effizient ist!

Wenn ich das richtig verstanden habe, reicht der RAM des Mega nicht aus, um so ein großes Array im ganzen zu verschicken?

mkl0815:
Sicher geht das. Muss es denn UDP sein, oder darf auch TCP verwendet werden? TCP würde das Übertragen der Daten in mehreren Paketen erleichtern, weil sich der TCP-Stack um die Flusskontrolle kümmert.
Dazu noch folgende Fragen:

  1. Welchen Datentyp hat das Array (byte, int, float, long ...)??
  2. Selbst bei 8 bit (Byte) wären 240x40Bytes schon 9960 Bytes und damit mehr als in den RAM des Mega2560 passt (der hat nur 8K SRAM) Woher stammen also die Daten? Wenn die zeitversetzt generiert werden, ist das wichtig für die Übertragung (Stichwort Timerout)
  3. Wer verarbeitet die Daten auf der PC-Seite? Ein selbst geschriebenes Programm oder ein vorgegebenes. Davon hängt ab wie man die Datenübetragung gestalten muss, ggf. gibt es ja schon ein vorgegebenes Protokoll
  4. Welches Ethernet-Shield hast Du? WizNet5100 Chip oder ENC26J80? Auch das hat Einfluss auf Dein Programm, vor allem wenn mehrere Pakete übertragen werden müssen.

Mario.

Es gibt für vieles eine Lösung.
Ein SRAM oder FRAM am I2C oder SPI
oder beim Arduino Mega1280/2560 einen zusätzlichen Speicherbaustein anschließen der als internes RAm gesehen wird.
Erklärung:

Platine:
http://ruggedcircuits.com/html/megaram.html
http://ruggedcircuits.com/html/quadram.html

Die Frage beleibt wieso keinen Arduino DUE oder Raspberry PI?

Grüße Uwe

Hallo Uwe,

ein Arduino Due hätte ich auch vorliegen!

Wie kann man dort am leichtesten ein Array dieser Größe übertragen?

Vielen Dank!

Wenn die Daten sequentiell entstehen und nicht ins RAM passen, würde ich sie einfach sequentiell an den PC senden und da zusammenbauen.
So in der Art:

EthernetUDP Udp;
...
for (int zeile=0;zeile<240;zeile++) {
Udp.beginPacket(remoteIP,remotePort);
for (int spalte=0;spalte<40;spalte++) {
Udp.write(wert_von(zeile,spalte));
}
Udp.endPacket();
}

So könntest du die Werte zeilenweise senden und auf dem PC wieder zusammenbauen. Es würde auch Integer-weise oder in anderer "Stückung" gehen :slight_smile:

PS: gerade gelesen, dass aus Performancegründen nicht alles einzeln geschickt werden soll - in dem Fall würde ich immer so viel senden, wie eben noch ins RAM passt. Also nach X Bytes einfach Udp.endPacket(); gefolgt von Udp.beginPacket(remoteIP,remotePort);
Bei Ethernet beträgt die MTU, also die maximale Größe eines einzelnen IP-Paketes, bevor es fragmentiert wird, 1500 Byte. D.h. es wird im Falle von UDP sowieso kaum weniger effizient, die Pakete zu splitten.

UDP ist für diesen Zweck ungeeignet, da es keinerlei Verbindungskontrolle gibt. Selbst die Reihenfolge der Pakete die beim PC ankommen muss nicht die gleiche sein, wie beim losschicken. Entweder man baut das in das eigene Protokoll mit ein (inkl. erneutes Übertragen von Paketen die nicht angekommen sind), oder man verwendet gleich TCP, da bekommt man das nämlich automatisch dazu.

Siehe auch:

http://www.tcp-ip-info.de/tcp-ip-schulung/sld121.htm

Mario.

Wenn man Overhead und Latenzen gering halten möchte und im nicht zu sehr ausgelasteten LAN unterwegs ist, ist UDP nicht verkehrt. Package loss ist eher die Ausnahme, das Thema Reihenfolge kann man durch eine Sequenzummer lösen. Wenn ich recht verstehe, soll eine Kamera o.ä. ausgelesen werden, d.h. durch ein verlorenes Paket würde nur ein Teil des Bildes mal nicht aktualisiert...

Könnte mir jemand ein beispiel schreiben wie ich z.b. ein 1D Array mit sagen wir mal 3 Integer Werten im Ganzen per TCP oder UDP versenden kann?

Komme durch probieren nicht weiter.....

MfG

DANINO24:
Ich habe schon zum Anfang ein Programm geschrieben das einen einfachen String mit dem Befehl UDP.Write an den PC sendet. Das klappt soweit!

Ein C-String ist doch auch blos ein char-Array.

Ansonsten für TCP:

byte server[] = {192,168,22,155 }; 
byte data[3] = {1,2,3};

EthernetClient client;

if (client.connect(server, 80)) {
    Serial.println("connected");
    for (int i=0; i<3;i++) {
        client.print(data[i]);
    }
    delay(50);  //etwas zeit für den Server die Daten zu empfangen
    client.stop() //verbindung trennen
  } else {
    Serial.println("connection failed");
  }
}