Verständnisproblem mit Sting-Matrix. Größenlimit?

Hallo,
die Forensuche hier und diverse Referenzen/Turorials haben mich zwar bis zu dem unten genannten Beispiel gebracht. Es funktioniert auch fast.
Die Matrix enthält Anfangsteile aus MP3-Dateinamen. Insgesamt 8 x 8.
Mit meinem Sprachmodul soll bei einem entsprechenden Muster die Endung ".MP3" angehängt und die passende MP3 abgespielt werden.

Das funktioniert von m=0 und s=0 bis m=6 und s = 3. Die restlichen Zellabfragen ergeben "nichts". Also kein Fehler oder Schrott, sondern einfach nichts.

Ich bin mir sicher, dass ich was falsch mache. Nur was?

void speak(int m, int s)   
{
  String myMatrix [][9] = { 
    {"0208","0108","0308","0316","0116","0216","0225","0225"},
    {"0211","0111","0311","0307","0107","0207","0206","0213"},
    {"0214","0114","0314","0319","0119","0219","0218","0204"},
    {"0209","0109","0309","0303","0103","0203","0118","0104"},
    {"0212","0112","0312","0317","0117","0217","0318","0304"},
    {"0205","0105","0305","0302","0102","0202","0306","0313"},
    {"0220","0120","0320","0315","0115","0215","0125","0225"},
    {"0201","0101","0301","0310","0110","0210","0106","0113"}
  };

    Serial.println ("********");
    Serial.print   (m);
    Serial.print   (" - ");
    Serial.print   (s);
    Serial.print   (" - ");
    Serial.println (myMatrix[m][s]);
    Serial.println ("********");                      
}

Den Rest habe ich weggelassen, weil er nichts zur Sache beiträgt.

Arduino Uno R3

lupus1952:
Ich bin mir sicher, dass ich was falsch mache. Nur was?

Den Rest habe ich weggelassen, weil er nichts zur Sache beiträgt.

Der Letzte Satz ist eine unbewiesene Behauptung, die ich widerlegen kann.
Die Ausgabe funktioniert einwandfrei:

21:18:15.632 -> Start...
21:18:15.632 -> 0208
21:18:15.632 -> 0108
21:18:15.632 -> 0308
21:18:15.632 -> 0316
21:18:15.632 -> 0116
21:18:15.632 -> 0216
21:18:15.665 -> 0225
21:18:15.665 -> 0225
21:18:15.665 -> 0211
21:18:15.665 -> 0111
21:18:15.665 -> 0311
21:18:15.665 -> 0307
21:18:15.665 -> 0107
21:18:15.665 -> 0207
21:18:15.665 -> 0206
21:18:15.665 -> 0213
21:18:15.665 -> 0214
21:18:15.665 -> 0114
21:18:15.665 -> 0314
21:18:15.665 -> 0319
21:18:15.665 -> 0119
21:18:15.665 -> 0219
21:18:15.665 -> 0218
21:18:15.665 -> 0204
21:18:15.699 -> 0209
21:18:15.699 -> 0109
21:18:15.699 -> 0309
21:18:15.699 -> 0303
21:18:15.699 -> 0103
21:18:15.699 -> 0203
21:18:15.699 -> 0118
21:18:15.699 -> 0104
21:18:15.699 -> 0212
21:18:15.699 -> 0112
21:18:15.699 -> 0312
21:18:15.699 -> 0317
21:18:15.699 -> 0117
21:18:15.699 -> 0217
21:18:15.699 -> 0318
21:18:15.699 -> 0304
21:18:15.699 -> 0205
21:18:15.699 -> 0105
21:18:15.732 -> 0305
21:18:15.732 -> 0302
21:18:15.732 -> 0102
21:18:15.732 -> 0202
21:18:15.732 -> 0306
21:18:15.732 -> 0313
21:18:15.732 -> 0220
21:18:15.732 -> 0120
21:18:15.732 -> 0320
21:18:15.732 -> 0315
21:18:15.732 -> 0115
21:18:15.732 -> 0215
21:18:15.732 -> 0125
21:18:15.732 -> 0225
21:18:15.732 -> 0201
21:18:15.732 -> 0101
21:18:15.732 -> 0301
21:18:15.732 -> 0310
21:18:15.813 -> 0110
21:18:15.813 -> 0210
21:18:15.813 -> 0106
21:18:15.813 -> 0113

@TO: Warum verwendest Du für solche konstant langen Zeichenketten von 4 Zeichen String und kein char-Array?

Evtl. könnte man die auch noch ins PROGMEM legen.

Gruß Tommy

Mich stört auch noch die [9] - es sind doch nur acht.
Und ob man da wirklich String braucht... ach nee, das lassen wir mal. Die ändern sich ja hoffentlich nicht so oft.

const char... wäre ein sinnvoller Ansatz.

Gruß Tommy

my_xy_projekt:
Der Letzte Satz ist eine unbewiesene Behauptung, die ich widerlegen kann.
Die Ausgabe funktioniert einwandfrei:

Ich stimme Dir zu, bei mir funktioniert es ebenfalls :slight_smile:

Das müssen weder String noch char sein? (sprich 3 dimensionales Array)
Es könnten auch nur eine INT-Variable sein das bei der Ausgabe eine führende Null dazubekommt.
Ich weiß wegen der üblichen Schnippelchen-taktik der TO nicht was da genau gemacht werden soll und ob ein INT Array auch funktioniert.

Grüße Uwe

my_xy_projekt:
Der Letzte Satz ist eine unbewiesene Behauptung, die ich widerlegen kann.

Dann wiederlege es doch bitte auch!

Ich frage mich nur, was der Rest meines Programmes damit zu tun hat. In der Loop werden die 2 Variablen erzeugt. Das hat für die Funktion meines Unterprogramms ja wohl keine Bedeutung.

Und dann habe ich noch die Ausgabe des erzeugten Tones anhand des aus der Matrix gelesenen Strings. Der Programmteil fehlt aber auch bei mir noch.

Das hat für die Funktion meines Unterprogramms ja wohl auch keine Bedeutung. Das Unterprogramm ist eine völlig eigenständige Sache.

Die Ausgabe funktioniert einwandfrei.

Komisch - dafür habe ich keine Erklärung. Vielleicht ist das ein Speicherproblem bezüglich der Menge. Du hast sicher nur eine kurze Loop geschrieben. Mein Programm ist aber komplett doch recht groß. Zwar lange noch nicht am Limit.

Die Lösung habe ich heute Nacht noch in einem anderen Forum gefunden. Zufällig von Tommy56 vor 1,5 Jahren.

Erklärung folgt später.

Tommy56:
@TO: Warum verwendest Du für solche konstant langen Zeichenketten von 4 Zeichen String und kein char-Array?

Evtl. könnte man die auch noch ins PROGMEM legen.

Gruß Tommy

Ich hatte bestimmt hundert Beispiele mit Matrixen im Netz gefunden. Das gleiche Verständnisproblem bezüglich Strings/Texten in einer Matrix haben viele. Aber keine der vielen Antworten war brauchbar. Ich habe alle möglichen Varianten genommen und irgendwann war eine Version dabei die mit Strings gearbeitet hat. Und irgendwo hat jemand erklärt, dass der zweite Parameter, eins größer sein muss als die Zahl der Elemente. (Was so ausgedrückt sehr mißverständlich bzw. falsch ist). Das war allerdings recht unsinnig erklärt wie ich jetzt weiß. Und dass der erste Parameter leer sein muss, weil die IDE das selbst zählt.

Die Lösung stammt sogar von der dir. Habe ich heute Nacht gefunden. Allerdings in einem anderen Forum vor ca. 1.5 Jahren. Das war bzw. ist auch die erste bisher gefundenen Lösung mit verständlicher Erklärung. Im Gegensatz zu den meisten anderen Erklärungen, die meist nur aus ein paar hingeworfenen Bemerkungen oder einzelnen Codezeilen bestanden. Deine super Erklärung sollte man in eine FAQ packen! Mehr weiter unten.

wno158:
Mich stört auch noch die [9] - es sind doch nur acht.
Und ob man da wirklich String braucht... ach nee, das lassen wir mal. Die ändern sich ja hoffentlich nicht so oft.

Die Zahl Neun stammt aus einer anderen Forenerklärung. Da hieß es, dass der Wert eins höher sein muss als die Zahl der Elemente. Das war sehr missverständlich ausgedrückt. Inzwischen weiß ich, wie das gemeint war. Nicht die Zahl der Matrixelemente in einer Reihe, sondern die Zahl der Elemente des längsten Strings + 1 (wegen der internen Abschluss-Null)

agmue:
Ich stimme Dir zu, bei mir funktioniert es ebenfalls :slight_smile:

Das sind meine Lieblingsantworten. Extrem hilfreich für alle die das gleiche Problem haben.

uwefed:
Das müssen weder String noch char sein? (sprich 3 dimensionales Array)
Es könnten auch nur eine INT-Variable sein das bei der Ausgabe eine führende Null dazubekommt.
Ich weiß wegen der üblichen Schnippelchen-taktik der TO nicht was da genau gemacht werden soll und ob ein INT Array auch funktioniert.

Grüße Uwe

Eine super tolle Hilfe. Und du konntest dabei sogar noch einen kleinen Seitenhieb auf mich verteilen. Das freut alle Leser, die das gleiche Problem haben und nach einer Lösung suchen.

Tommy56:
const char... wäre ein sinnvoller Ansatz.

Gruß Tommy

Danke - auch das habe ich gemacht. Und es funktioniert. Wie gesagt - ein alter Post (2D String Array )von dir brachte die Erleuchtung.

char animals [][5][8] = {

    {"Hund","Katze","Maus","Ratte","Elefant"},

        {"","","","",""}

};
  1. Dimension: Die 7+1 Buchstaben der Zeichenketten - Das ist selbst schon ein Array!
  2. Dimension: Die 5 Zeichenketten pro Zeile
  3. Dimension: Die Zeilen (hier 2)
    von innen nach außen.

So simpel, wenn man es weiß und auch logisch. Nur steht das in keinem Forenbeitrag oder Tutorial so erklärt. Ich bin als alter "Basic"ler sehr wohl (String-)Arrays gewohnt. Auf die Idee, dass man da noch die Länge des längsten Elements mit angeben muss, wäre ich nie gekommen. Und so hatte ich eben nur Compilerfehler.
Aber jetzt geht es mit:

const char myMatrix [8][8][5] = { 
    {"0208","0108","0308","0316","0116","0216","0225","0225"},
    {"0211","0111","0311","0307","0107","0207","0206","0213"},
    {"0214","0114","0314","0319","0119","0219","0218","0204"},
    {"0209","0109","0309","0303","0103","0203","0118","0104"},
    {"0212","0112","0312","0317","0117","0217","0318","0304"},
    {"0205","0105","0305","0302","0102","0202","0306","0313"},
    {"0220","0120","0320","0315","0115","0215","0125","0225"},
    {"0201","0101","0301","0310","0110","0210","0106","0113"}
  };

Vielen Dank

885 = 320 Byte im RAM.

vs. 8*8 = 64 Byte im PROGMEM bei belassen der Variablen im Flash.

Solltest du dir noch mal überlegen.

Schritt 1: Umbauen auf byte
Schritt 2: ab damit ins PROGMEM

lupus1952:
Dann wiederlege es doch bitte auch!

Habe ich.

Ich frage mich nur, was der Rest meines Programmes damit zu tun hat. In der Loop werden die 2 Variablen erzeugt. Das hat für die Funktion meines Unterprogramms ja wohl keine Bedeutung.

DOCH!
Denn Du selbst schreibst:

}
Ich bin mir sicher, dass ich was falsch mache. Nur was?

Wer soll sich denn da einen Reim drauf machen?

Vielleicht ist es ja einfach nur ein Leck, das dazu führt, das der Inhalt den Du haben möchtest gar nicht an der Stelle zu finden ist, wo Du suchst?
Vielleicht ist der Inhalt zerstört, bevor Du ihn auswerten kannst?

Was glaubst Du denn, was und wieviel es da an Möglichkeiten gibt?
Auf welcher Basis willst Du denn geholfen werden, wenn Du nicht mit den notwendigen Infos rumkommst.

Das Unterprogramm ist eine völlig eigenständige Sache.

Das mag für Dich so aussehen. Wenn Speicher überschrieben wird, ist das ein Problem. Und wenn Du heute damit klar kommst, weil Du den Code vollständig verändert hast und sich jetzt keine gegenseitige Beeinflussung findet, kann das ein paar neu geschriebenen Codezeilen später wieder ganz anders sein.

Ist doch gut, Du hast Deine für Dich gültige Lösung gefunden. Wie die zu werten ist kann ich nicht feststellen, aber Du hast bereits den Hinweis bekommen, das es eine der ungünstigsten ist. INsbesondere wenn DU sowieso schon so umfangreichen code hast, das Du ihn ob der Größe nicht zeigen kannst.

Das mit dem Rundumschlag solltest Du Dir evtl. überlegen. Es hat Dir niemand was getan. Wenn Du keine Hilfe willst, frag nicht.

Aus meiner Wühlkiste:

author=Martin Gerhard Reisenberg

noiasca:
885 = 320 Byte im RAM.

vs. 8*8 = 64 Byte im PROGMEM bei belassen der Variablen im Flash.

Solltest du dir noch mal überlegen.

Schritt 1: Umbauen auf byte
Schritt 2: ab damit ins PROGMEM

Danke - es gibt doch noch Leute, die sachlich antworten können, ohne sich an Nebensächlichkeiten hochzuziehen. :slight_smile:

Von PROGMEM habe ich (noch) keine Ahnung. Noch nie was von gehört. Aber ich verspreche das gleich nachzuforschen.
Umbauen auf byte möchte ich ungern. Ich könnte zwar auch mit Zahlen in Bytes arbeiten. Und die Werte dann vor der Ausgabe zu passenden Strings umbauen. Meine Dateien, die gesprochen werden sollen, haben halt alle schon fertige Namen wie z.B. "0203.mp3"

my_xy_projekt:

Das mit dem Rundumschlag solltest Du Dir evtl. überlegen. Es hat Dir niemand was getan. Wenn Du keine Hilfe willst, frag nicht.

Spar' dir bitte solche wertlosen Antworten die wohl nur deiner EGO-Stärkung dienen solle.
Ich nehme jede sachliche Hilfe gerne an. Und deshalb frage ich. Aber auf Leute wie dich verzichte ich gerne.
Andere haben mein Problem sofort erkannt. Auch nur mit meinem Codeschnipsel. Und die Superlösung hatte Tommy56. Allerdings schon vor längerer Zeit in einem anderen Forum. Das war die erste einleuchtende Erklärung zu einem Textarray, die ich im Netz gefunden habe. Solche Antworten helfen weiter!

lupus1952:
Meine Dateien, die gesprochen werden sollen, haben halt alle schon fertige Namen wie z.B. "0203.mp3"

Das Wandeln des byte auf deinen Namen ist doch nicht so schwierig:

const byte nameAlsByte = 203;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  char nameBuf[10];
  snprintf( nameBuf, 10, "%04d.mp3", nameAlsByte );
  Serial.println(nameBuf);
   
}

void loop() {
  // put your main code here, to run repeatedly:

}

combie:
Aus meiner Wühlkiste:
.....

Echt herrlich solche hilfreichen Antworten :frowning: