Arduino Uno kann nicht mit zweidimensionalen Arrays umgehen

Jetzt verwendet der Code, den ich in Arduino schreibe (mit Arduino), mehrere zweidimensionale Arrays Ich drucke etwas mit dem seriellen Monitor, der es korrekt druckt, aber wenn ich das zweidimensionale Array deklariere und initialisiere, wird es nicht gedruckt.

Code:

 void setup() { Serial.begin(9600); int image_width = 56; int image_height = 96; int image_result[image_width][image_height]; for (int i=0; i<image_height; i++) { for (int j=0; j<image_width; j++) { image_result[j][i] = 5; } } Serial.print("code works"); }  

In diesem Fall wird“ Code funktioniert „nicht gedruckt, aber wenn ich die Array-Deklaration entferne, wird der Initialisierungscode gedruckt. Was ist das Problem?

Funktionieren zweidimensionale Arrays in Arduino anders oder handelt es sich um ein Platzproblem?

Kommentare

  • Sogar ein eindimensionales Array von 5376 Bytes auf einem Prozessor mit 2048 Bytes schlägt fehl.
  • Ich meinte 10752 Bytes. Ich habe übersehen, dass jedes Array-Element 2 Bytes umfasst. Denken Sie daran, dass Sie ‚ nicht einmal alle diese 2048 Bytes zur Verfügung haben. Allein die seriellen Sende- und Empfangspuffer verbrauchen 128 Byte.
  • Wenn ich ein Micro-SD-Auto anschließe, gibt es eine Methode, um ein Array in diesem Speicher zu deklarieren?
  • Sie können eine Verbindung herstellen SD-Karte und schreiben Sie Daten in den Inhalt Ihres Herzens ‚. Sie können jedoch ‚ t “ das Array im Speicher “ deklarieren. Was ist Ihre Bewerbung hier? Ein Arduino mit 2 KB RAM ist nicht ‚ nicht das Beste für die Bildverarbeitung.
  • Ich muss eine kleine BMP-Datei in einem Array von Ints in Arduino lesen und müssen etwas verarbeiten. Die Dateigröße beträgt 56 x 96 Pixel.

Antwort

2D-Arrays funktionieren auf Arduino einwandfrei, aber Sie Der Platz geht sehr schnell zur Neige.

Ein Uno hat 2 Kilobyte RAM. Ihr Array enthält 56 * 96 = 5376 2-Byte-Elemente.

Ich würde vermuten, dass Sie irgendwann über einen kritischen Speicherwert mit einer 5 schreiben, wodurch das Programm fehlschlägt.

Kommentare

  • Nicht nur über den Speicher, sondern wahrscheinlich auch über alle E / A-Register.
  • 16-Bit-Adressierung, wobei SRAM ab 256 beginnt. Damit ‚ 65279 Byte Adressraum hat. Sie werden also ‚ nicht erreichen. Außerdem bin ich mir ‚ ziemlich sicher, dass es einen Schutz gibt, der dies verhindert.
  • Es gibt keinen Schutz. Die CPU-Register werden ab Adresse 0 speicherabgebildet, dann die E / A-Register ab Adresse 32, dann beginnt der statisch zugewiesene RAM bei Adresse 256.

Antwort

Sie versuchen, mehr Speicher als verfügbar zu verwenden: 96 * 56 * 2 = 10,752 KByte. In diesem Fall kann die MCU nicht viel tun.

Wenn Sie sich das Datenblatt ansehen, werden Sie feststellen, dass Ihr Mikrocontroller (ATmega328p) nur über 2 KByte RAM verfügt.

Ich denke, die Frage ist dann, ob Sie wirklich ein so großes Array benötigen. Sie können einen externen Flash-Chip oder ein SD-Karten-Shield erwerben. Wenn Sie es nur für schreibgeschützte Zwecke benötigen (z. B. zum Nachschlagen) Tabelle) können Sie einige Ihrer Flash-Programmspeicher (Sie haben 32 KByte) verwenden.

Kommentare

  • Ich ‚ verwende ein SD-Karten-Sheild, aber ich ‚ lese die Daten in ein Array, das wie folgt deklariert ist. Wie kann ich den SD-Kartenspeicher verwenden?
  • Sie müssen ‚ normalerweise nicht alle 5376 Elemente Ihres Arrays gleichzeitig bearbeiten Teilen Sie Ihr Bild für die Verarbeitung in kleinere Teile auf. Abhängig von der Art der Verarbeitung benötigen Sie möglicherweise verschiedene Smarts, um den Prozess zu optimieren . 😉
  • Kann man immer wieder Daten in den Flash-Speicher schreiben. Was meinst du mit schreibgeschützt? Wie schreibt man die Daten einmal darauf? Zum Beispiel möchte ich die Bilddaten auf den Flash-Speicher schreiben. Wie kann ich das tun?
  • Ich beziehe mich auf Ihren Programm-Flash-Speicher. AFAIK, Sie können nur während der Programmierung in den Programm-Flash schreiben. Wenn Sie Ihre MCU starten, wird der Programm-Flash als Nur-Lese-Speicher verwendet (damit ‚ das Programm nicht durcheinander bringt, wenn es ‚ s läuft.) Da Sie Ihre Daten schreiben möchten, ist der Programm-Flash nicht geeignet.
  • Müssen Sie wirklich das gesamte Bild auf einmal verarbeiten? Wie ich ‚ bereits erwähnt habe, können Sie Ihr Bild in kleinere Blöcke unterteilen, z. B. chunk [8] [8] wäre eine komfortable Größe für Arduino schlucken, und es funktioniert gut, auch wenn Sie Faltungsfilter verwenden. (Allerdings muss ich betonen, dass das Arduino Uno für jede ernsthafte Bildverarbeitungsanwendung ungeeignet ist.)

Antwort

In der Tat ist dies ein Problem mit dem verfügbaren RAM.Wenn Sie nicht 8 Bit pro Datenelement benötigen (wenn Sie beispielsweise bereit sind, die Bildqualität zu verringern), sollten Sie Ihre Daten so komprimieren, dass Sie mehrere Daten pro Bit haben. Beispielsweise können Hex-Werte oder BCD (binär codierte Dezimalstellen) abhängig von der Größe der einzelnen Daten funktionieren.

Kommentare

  • Das OP Ich möchte eine BMP-Datei in den Speicher lesen, daher bezweifle ich, dass sie sehr nützlich in BCD umgewandelt werden kann.
  • Das ‚ ist ein guter Punkt. Vielleicht ist er ‚ bereit, seine Bildqualität deutlich zu verringern? In beiden Fällen wäre zusätzlicher Speicher sinnvoll.

Antwort

Wie andere angemerkt haben, ist Ihr Array größer als der verfügbare RAM in Ihrem Arduino. Andere erwähnten Flash-Speicher, der eine Lösung für Sie sein könnte. Ihr Arduino verfügt über 32 KB Speicher, der Ihr Array aufnehmen kann. Weitere Informationen zum Flash-Speicher finden Sie in der folgenden Referenz. Beachten Sie, dass Flash und EEPROM eine begrenzte Anzahl von Schreibzyklen haben, bevor sie unzuverlässig werden.

Versteckte Kräfte – Speichern von Daten in Flash und EEPROM

Antwort

Falls die Matrix größtenteils leer ist oder ohnehin Werte hat, die programmgesteuert berechnet werden können, spärliche Arrays könnten zur Rettung kommen. Es erfordert Speicherzuweisung und Hopping, sodass die Zugriffszeit auf einzelne Elemente nicht deterministisch ist. Sie können jedoch das Worst-Case-Szenario berechnen.

Antwort

Dies ist, was ich meinem Uno gegeben habe:

 #define IMAGEWIDTH 56 #define IMAGEHEIGHT 96 void setup() { Serial.begin(9600); int i, j; int image_result[IMAGEWIDTH][IMAGEHEIGHT]; for (i = 0; i < IMAGEWIDTH; i++) { Serial.print("\nIMAGEWIDTH "); Serial.print(i + 1); Serial.println(":"); for (j = 0; j < IMAGEHEIGHT; j++) { image_result[i][j] = i + j; Serial.print("image_result["); Serial.print(i + 1); Serial.print("]["); Serial.print(j + 1); Serial.print("]: "); Serial.println(image_result[i][j]); } } Serial.println(F("\nDone!")); } void loop() { }  

Dies wird über das gesamte Array ausgeführt, während der Druckvorgang über Serial ausgeführt wird. Anschließend wird „Fertig!“ sobald es ist. Ich schlage vor, Folgendes zu ändern:

 #define IMAGEWIDTH 56 #define IMAGEHEIGHT 96  

Auf kleinere Werte, es sei denn, Sie haben einige gute Minuten zur Hand.

Kommentare

  • Dies wird sein Problem überhaupt nicht lösen. Es ist nicht ‚ t Zeit, es ist die Größe des Arrays. 56 * 96 * 2 (ein int ist zwei Bytes) verwendet 10752 Bytes. Ihr Uno hat 2048 Bytes. Das Problem ist nicht die Zeit, es ist Speicher.
  • Nick hatte Recht, dies hat ‚ mein Problem nicht gelöst. Wie auch immer, danke, dass Sie es versucht haben.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.