Max. Summe an Zeichen per UDP

Hallo zusammen,

über meinen Arduino Nano laufen neun Max7219.

Ehrlich gesagt, weiß ich nicht wie viele einzelne LEDs und 7 Segment Anzeigen betrieben werden, ist aber auch egal... soweit funktioniert manuell alles einwandfrei.

Nun übertrage ich von meinen Raspberry per PHP und UDP einen String mit lauter Einsen und Nullen (in dieser Form: 1,0,1,1,1,0,0,1...........)

Einfach gesagt, schaltet der Arduino darüber die einzelnen LEDs. Funktioniert...

Aber leider ist bei 515 Zeichen schluss und mir Fehlen min. 29 Leds.

Habt ihr eine Idee was ich tun kann?

Gibt es eine Möglichkeit mehr als 515 Zeichen per UDP zu senden?

Ich hab schon versucht mehrere UPDs zu senden, aber sobald der 2. String vom Nano empfangen wird, wird der 1. überschrieben, was mir eigentlich auch klar ist.

Vielen Dank, schön Grüße und alles schöne Weihnachten

Markus

Ach ja, eine Idee hätte ich um Zeichen zu sparen, welche ich aber nur zur Not, wegen der Übersichtlichkeit anwenden würde.

Im Moment zerteilt der Nano den ankommenden UDP-String mit strtok(data, ",");

Ich könnte Zeichen sparen indem ich die Kommas weg lasse und nur 10110011001001001 übertrage.
Das wären logisch nur die hälfte an Zeichen die übertragen werden.

Allerdings weiß ich nicht, wie ich den Arduino programmieren muss, dass er jedes einzelne Zeichen
splittet.

Viele Grüße
Markus

hi,

mir ist eigentlich nicht klar, wie der nano übers netzwerk daten bekommt (hast Du ein ethernet-modul dran?).

aber die lösung für Dich ist einfach: übertrage bytes! in jedem byte können acht nullen oder einsen übertragen werden. also nicht:

1,0,1,0,1,1,0,0, usw, sondern:

10101100, also ein byte mit wert 172.

und schon kannst Du achtmal soviel senden.

gruß stefan

Markus1979:
Aber leider ist bei 515 Zeichen schluss und mir Fehlen min. 29 Leds.
Habt ihr eine Idee was ich tun kann?

Gibt es eine Möglichkeit mehr als 515 Zeichen per UDP zu senden?

Reine 0/1 Informationen belegen exakt 1 Bit, also kannst Du bereits mit einem einzigen Byte (=8 Bits) bereits acht Informationseinheiten übertragen.
Schon in nur 128 Bytes (=1024 Bits) kannst Du insgesamt 1024Informationen vom Typ "0 oder 1") übertragen.

Dein Programm geht offenbar mit vorhandenen Ressourcen höchst verschwenderisch um, wenn Du zur Übertragung von einem Bit insgesamt zwei Bytes ('0' oder '1') und noch ein zusätzliches Komma ',' übertägst. Da bist Du beim insgesamt sechzehnfachen Speicherverbrauch wie es minimal notwendig wäre.

Allerdings weiß ich nicht, wie ich den Arduino programmieren muss, dass er jedes einzelne Zeichen
splittet.

Wieso irgendwas splitten? Du kannst einfach Zeichen für Zeichen über den String iterieren.

Aber wie gesagt ist das beste hier Binärdaten zu senden. Strings sind manchmal praktisch, aber für große Datenmengen sehr verschwenderisch.

Hallo zusammen,

@stefan: ja genau... über ein LAN Modul.

Ja, es ist sicherlich Ressourcen Verschwendung, aber es läuft prima!!!! Ich möchte jetzt aber nicht allzuviel an dem Code ändern.

Dafür müsste ganz egal wie ich es mache nachher wieder die Kommas eingefügt werden.

Aber grundsätzlich... Wie kann man einen string nach jedem Buchstaben trennen und die kann man nach jedem Buchstaben was einfügen?

Viele Grüße
Markus

Da du strtok() verwendest hast du offensichtlich einen C String. Also ein Array. Da ist jeder Index ein Zeichen. Wo ist da das Problem über das Array zu iterieren?

char str[] = "01000110";

void setup()
{
  Serial.begin(9600);

  char* ptr = str;
  while (*ptr != NULL)
  {
    Serial.println(*ptr);
    ptr++;
  }
}

void loop()
{
}

Oder:

void setup()
{
  Serial.begin(9600);

  unsigned int length = strlen(str);
  for (unsigned int i = 0; i < length; i++)
    Serial.println(str[i]);
}

kann man nach jedem Buchstaben was einfügen?

Nein. Wieso braucht man das?

Hallo zusammen,

ich bin noch absoluter Anfänger in Sachen Arduino. Ich dachte, dass die Zahlen als String übergeben werden, dass jeder Buchstabe einzeln ausgegeben werden kann wußte ich nicht.

Ich bekomme die Daten in meinem Script aber nicht weiter verarbeitet.

Im Moment sieht es so aus...

void udpSerialPrint(uint16_t dest_port, uint8_t src_ip[IP_LEN], uint16_t src_port, const char *data, uint16_t len){

Serial.println(data[0]);
Serial.println(data[1]);
Serial.println(data[2]);

byte ZAHL1[13] = {B10111110,B00110000,B00011111,B00111011,B10110001,B10101011,B10101111,B00111000,B10111111,B10111011,B01000000,B11111111,B00000000};

// ************************************************************************
// Displays
// ************************************************************************

//Player 1
u1.setRow(0,0,ZAHL1[3]); //DISP1
u1.setRow(0,4,ZAHL1[0]); //DISP2
u1.setRow(0,6,ZAHL1[1]); //DISP3

Die Ausgabe im Serial-Monitor sie so aus

[UDP]
IP: 192.168.178.21
3
0
1

Leider funktioniert es nicht wie folgt

//Player 1
u1.setRow(0,0,ZAHL1[data[0]]); //DISP1
u1.setRow(0,4,ZAHL1[data[1]]); //DISP2
u1.setRow(0,6,ZAHL1[data[2]]); //DISP3

Die Ausgabe auf den drei 7-Segment Anzeigen bleiben leer.

Bin schon den ganzen Abend am lesen, finde aber leider nichts im Netz.
Liegt wahrscheinlich daran dass ich wieder nicht weiß wonach ich suchen soll :slight_smile:

Viele Grüße
Markus

Das ist nichts Arduino-spezifisches. Auch nicht C/C++. Auch in anderen Sprachen sind Strings nur ASCII (ok, manchmal Unicode)-codierte Zeichenketten. Auch wenn du irgendeine Klasse hast steckt da nichts anderes im Hintergrund. Und du hast Methoden wie charAt() um an die einzelnen Zeichen zu kommen. In C sind das halt keine Objekte, sondern nur null-terminierte Arrays aus char.

Nun hast du das Prinzip geändert! Bitte entscheide dich mal. Erst waren es Nullen und Einsen. Jetzt sind es Zahlen zwischen 0 und 12 die einen Array Index darstellen. Das ist zwar ok, aber eine Ziffer kann nur von 0 bis 9 gehen! Geht also so nicht. Aber ignorieren wir das erst mal und finden heraus wieso deine Version auch von 0 bis 9 nicht geht.

Oben habe ich schon gesagt, dass das ASCII Zeichen sind. Schau dir die ASCII Tabelle an:
http://www.asciitable.com/
Da siehst du dass ‘0’ nicht 0 ist, sondern 48. Und ‘1’ ist nicht 1, sondern 49. Dadurch ist die Wandlung trivial. Um eine einzelne ASCII Ziffer nach Dezimal zu wandeln machst du Minus 48. Oder Minus ‘0’ wenn du dir den Wert nicht merken willst.

Das geht nun aber nicht so direkt mit “10” oder “11”, da das mehrere Zeichen sind. Außerdem bräuchte man dann wieder Trennzeichen! Eine einfache Lösung hier ist Hexadezimal. Nach ‘9’ geht es so weiter:
A = 10
B = 11
C = 12
D = 13
E = 14
F = 15

Das sind 0-15 was dann hoffentlich reicht. Die Konvertierung ist durch eine Funktion einfach:

byte hexToInt(char c)
{
   if (c >= '0' && c <= '9')
      return c - '0';
   else if (c >= 'A' && c <= 'F')
      return c - 'A' + 10;
   else if (c >= 'a' && c <= 'f')
      return c - 'a' + 10;
   else
      return 0;
}

Man übergibt das Zeichen und bekommt den Integer-Wert von 0-15

Auf dem Rasperry musst du dann entsprechend den Integer in ‘0’-‘F’ konvertieren!

Nun hast du einen Wert der Binär 4 Bit belegt als 8 Bit kodiert. Wenn man direkt Binär verwendet und es richtig kodiert (also nicht 10 und 11 als zwei Bytes schickt, sondern jeweils in ein Halb-Byte packt) könnte man die Hälfte des Speichers sparen

Hallo Serenifly,

vielen vielen Dank !!!

Jetzt funktioniert es !!

Wenn man es einmal verstanden hat ist es gar nicht so schwer.
Sicherlich kann man noch etwas optimieren, aber jetzt geht es erstmal.

Vom Raspberry übergebe ich 0-9 und für "Sonderzeichen" Buchstaben.

Auf dem Arduino wird das einfach durch eine Funktion geschoben, welches mit dann eine zweistellige Zahl für das Array zurück gibt.

Sowas nennt man wahrscheinlichlich nicht schön sondern eher quick and dirty, aber darauf kann ich aufbauen

Vielen Dank nochmal für seine Hilfe!!!

Viele Grüße
Markus

Markus1979:
Sowas nennt man wahrscheinlichlich nicht schön sondern eher quick and dirty, aber darauf kann ich aufbauen

So schlimm ist es nicht. Du hast aber auf dem UNO nur 2k RAM. Das kann völlig ausreichen wenn man sonst nicht viel macht, aber es kann auch Probleme bereiten. Kommt dann auf die Anwendung an. Man muss und sollte auch nicht immer vorauseilend optimieren.
Und das mit dem Array ist schon mal wesentlich effizienter als jedes Bit als einzelnes Zeichen.

Ich verwende für Datenübertragung auch gerne Strings, da es einfach zu implementieren ist und man sehr schön Kommandos und Daten kombinieren kann. Man kann z.B. für eine Temperatur “T1:20” übertragen und weiß so gleich was das bedeutet. Und solange das nur ab und zu ein paar Zeichen sind spricht da überhaupt nichts dagegen. Wenn man sehr lange Daten und/oder diese sehr oft überträgt wird es aber problematisch. Deine Anwendung ist da vielleicht ein Grenzfall.