Verständnisfrage zu Flash-Speicher im Arduino Uno

Guten Tag liebe Experten,

ich möchte eine Art LED-Leiste basteln mit 120 RGB-LEDs (WS2811 und 5050) und muss dazu jede Menge Pixel mit jeweils einem R-, G- und B-Wert beschreiben. Ich dachte so an 120 x 1.000 Pixel, aber so weit bin ich noch nicht. Die RGB-Werte erhalte ich schön geordnet aus einer JPG-Datei - das funktioniert alles.

Mein Problem ist die Speicherverwaltung im Arduino: Ich habe gelernt, dass der Sketch selbst im Flash gespeichert wird (32 KiB minus Bootloader) und die Variablenwerte im RAM (2 KiB). Wenn ich jetzt die ganzen RGB-Werte in einem array speichere, dann MÜSSTEN sie ja eigentlich im 2 KiB-RAM drin stehen:

byte rgb[][5][3] = {{{254,1,3}, {254,0,7}, {253,5,0}, {253,0,1}, {255,1,0}}, … };

Das funktioniert auch mit JPG-Dateien die 35 x 5 Pixel groß sind (also meiner Rechnung nach 35x5x3 = 525 Byte groß sind). Bei 35 x 6 funktioniert's aber schon nicht mehr!

  1. Warum nicht? Sitzt mir irgendetwas anderes im RAM, was fast dreiviertel davon blockiert (Ich nutze die FastSPI-Library)?
  2. Wie kann ich die RAM-Belegung feststellen?
  3. Warum wird mein verwendeter Flash-Speicher (der wird ja beim compilieren angezeigt) immer voller, je mehr RGB-Werte ich in das Array schreibe? Ich denke die Werte sitzen im RAM?
  4. und last but not least: der Speicher wird ja eh nicht für meine 1000 x 120 Pixel reichen. Was schlagt ihr vor? Kann man sowas mit einem EEprom 24lc256 machen?

Danke und GRuß, kuahmelcher

  1. Ein "int" braucht 2 Byte Platz, Dein Array verbraucht also 1050 Byte, was die Hälfte des gesamten RAMs ist. Was Speicher braucht, kann ich ohne den vollständigen Sketch nicht sagen.

2.: Arduino Playground - AvailableMemory

  1. Sie sind in beiden Speichern. Du kannst sie aber im Flash belassen und direkt von dort auslesen. (PROGMEM - Arduino Reference)

  2. EEPROM oder SD-Karte. Hängt auch etwas von den restlichen Anforderungen ab (z.B. Zugriffsgeschwindigkeit).

Mir kommt komisch vor, daß Du jpg Dateien darstellen kannst, da diese verlustbehaftet komprimiert sind. Meinst Du Bildmap oder TIFF?

Anstatt WS2811 und 5050 nimm gleich WS2812, da ist der WS2811 Kontroller im 5050RGB-LED integriert.
http://partfusion.com/wp-uploads/2013/01/WS2812preliminary.pdf
Die gibt es bereits als LED-Leisten zu 36/ 60/ 66 LED pro Meter. Achtung 1 LED verbraucht bis zu 60mA. Bei 120 LED (alle weiß und höchste Helligkeit sind das dann 7,2A!!!

  1. es sitzt auch der “Bildspeicher” der fastSPI Bibliothek im RAM. Die Ausgabe der Werte an die WS2811/12 ist sehr zeitkritisch darum muß dieser Bildspeicher" für die Werte der WS2811/12 im RAM sitzen.

  2. Du mußt die Werte ja irgendwo speichern. Der Sketch wird (zusammen mit allen Startwerten der Variablen) im Flashspeicher gespeichert. Die Wete der Variablen werden vom Flash in das RAM kopiert. Mit Progmem kannst Du werte die sich nicht verändern im Flash belassen.

  3. SD-Karte; die kannst Du im PC mit Daten füllen.

Ich befürchte mit einem Arduino UNO kommst Du nicht zu Deinen 120 LED. Ich weiß nicht ob die fastSPI-Bibiothek auf dem Arduino MEGA läuft. Der hätte mehr RAM und könnte 64 kByte zusätzlich anschließen.

Als Alternative zur Ansteuerung der WS2811/12 bietet sich der teensy 3.0 an.

Grüße Uwe

pylon:

  1. Ein "int" braucht 2 Byte Platz, Dein Array verbraucht also 1050 Byte, was die Hälfte des gesamten RAMs ist. Was Speicher braucht, kann ich ohne den vollständigen Sketch nicht sagen.

Sorry, ich habe meinen Post gerade noch einmal verbessert: Ich brauche und nutze natürlich nur "byte".

pylon:
2.: Arduino Playground - AvailableMemory

Ahh! Super - danke.

pylon:
3. Sie sind in beiden Speichern. Du kannst sie aber im Flash belassen und direkt von dort auslesen. (PROGMEM - Arduino Reference)

Schade, das funktioniert bei mir leider nicht. Das Programm FreeMemory zeigt immer noch den gleichen Wert an.

pylon:
4. EEPROM oder SD-Karte. Hängt auch etwas von den restlichen Anforderungen ab (z.B. Zugriffsgeschwindigkeit).

… also ich will mir die LED-Leiste am Fahrrad befestigen und damit coole Langzeitbelichtungen machen! :o) Ich vermute, dass die SD-Karte da eher zu langsam für ist
Danke für deine Hilfe,
Gruß, Kuahmelcher

uwefed:
Mir kommt komisch vor, daß Du jpg Dateien darstellen kannst, da diese verlustbehaftet komprimiert sind. Meinst Du Bildmap oder TIFF?

Momentan nutze ich ein kleines PHP-Script, was mir aus einer hochgeladenen jpg-Datei quasi Arduino-Code macht. (http://raspberrypi.fmhmamehlauorxfo.myfritz.net/rgb/index.php) Nicht schön, funktioniert aber. Wäre es möglich, dass ich aus dem Bildverabeitungsprogramm das Bild direkt als Bitmap oder TIFF auf eine SD-Karte speichern und vom Arduino den GANZEN Rest machen lassen könnte? Dann könnte ich diesen Zwischenschritt mti dem PHP-Script weglassen.

uwefed:
Anstatt WS2811 und 5050 nimm gleich WS2812, da ist der WS2811 Kontroller im 5050RGB-LED integriert.
http://partfusion.com/wp-uploads/2013/01/WS2812preliminary.pdf
Die gibt es bereits als LED-Leisten zu 36/ 60/ 66 LED pro Meter. Achtung 1 LED verbraucht bis zu 60mA. Bei 120 LED (alle weiß und höchste Helligkeit sind das dann 7,2A!!!

Die LED-Streifen habe ich bereits. Es sind übrigens - genau wie du empfohlen hast - WS2812-Treiber. IN der FastSpi-Bibliothek muss man nur WS2811 eintragen, deshalb hatte ich mich vertan. Bei 120 LEDs bin ich noch lange nicht, momentan blinken maximal 15 LEDs so wie ich das will :o)

uwefed:
4) SD-Karte; die kannst Du im PC mit Daten füllen.

Wenn ich die nur schnell genug auslesen kann, dann ist das eigentlich die optimale Lösung. Vielleicht kann ich ja dann auch anstatt meinem PHP-generierten Code die Bilddatei selbst auf die Karte speichern und die RGB-Analyse vom Arduino machen lassen. Dummerweise besitze ich so'n Kartenleser-Shield noch gar nicht :o)

uwefed:
Ich befürchte mit einem Arduino UNO kommst Du nicht zu Deinen 120 LED. Ich weiß nicht ob die fastSPI-Bibiothek auf dem Arduino MEGA läuft. Der hätte mehr RAM und könnte 64 kByte zusätzlich anschließen.

Wo siehst du denn unlösbare Probleme? Strom muss irgendwann eh aus 'ner kräftigeren Batterie kommen. Speicher wird auch nicht reichen, aber der sollte sich doch über einen eeprom mit immerhin 256 KiB oder sogar eine SD-Karte bereitstellen lassen

Danke für deine Hilfe, Gruß Kuahmelcher.

kuahmelcher:

uwefed:
Ich befürchte mit einem Arduino UNO kommst Du nicht zu Deinen 120 LED. Ich weiß nicht ob die fastSPI-Bibiothek auf dem Arduino MEGA läuft. Der hätte mehr RAM und könnte 64 kByte zusätzlich anschließen.

Wo siehst du denn unlösbare Probleme? Strom muss irgendwann eh aus 'ner kräftigeren Batterie kommen. Speicher wird auch nicht reichen, aber der sollte sich doch über einen eeprom mit immerhin 256 KiB oder sogar eine SD-Karte bereitstellen lassen

Danke für deine Hilfe, Gruß Kuahmelcher.

Bestimmte Daten müssen im RAM gehalten werden da die Bibilothek schnell darauf zugreifen muß und die Daten für eine Zeile in einem Guß mit 800kHz übertragen muß . Die WS2811/12 wollen eine Timinggenauigkeit von 150nS. Bei einem 16 MHz ATmega sind das gerade etwas mehr als mal 2 Takte (62,5 nS pro Takt).

Da kannst Du keine Daten für die aktuelle Zeile aus einem externen RAM oder EEPROM oder SD-Karte holen. Du kannst die Daten einer Zeile ins RAM laden, dann auf die WS2811/12 laden und dann die nächste Zeile holen. Bei 120 WS2811/12 braucht eine Übertragung ca 200µS (50µS reset und 150 µS Übertragung)

Grüße Uwe

uwefed:
Bestimmte Daten müssen im RAM gehalten werden da die Bibilothek schnell darauf zugreifen muß und die Daten für eine Zeile in einem Guß mit 800kHz übertragen muß . Die WS2811/12 wollen eine Timinggenauigkeit von 150nS. Bei einem 16 MHz ATmega sind das gerade etwas mehr als mal 2 Takte (62,5 nS pro Takt).

Da kannst Du keine Daten für die aktuelle Zeile aus einem externen RAM oder EEPROM oder SD-Karte holen. Du kannst die Daten einer Zeile ins RAM laden, dann auf die WS2811/12 laden und dann die nächste Zeile holen. Bei 120 WS2811/12 braucht eine Übertragung ca 200µS (50µS reset und 150 µS Übertragung)

Hallo,
ich habe mir mal die anderen Arduinos angeschaut: der "Mega" funktioniert mit der FastSPI-Lib, hat aber auch "nur" 8 KiB SRAM. Der "Arduino DUE" hat sagenhafte 96 KiB, leider habe ich aber bisher keine klaren Hinweis auf die FastSPI-Lib gefunden, die ich ja anscheinend dafür zwingend brauche, wenn ich nicht alles wieder neu erfinden will.

Aber damit ich das richtig verstehe: Es müsste doch funktionieren, wenn ich mir selbst ein 24lc256-eeprom-Shield bastle, was 256 KiB hat und einfach auf dem Arduino UNO drauf sitzt. Sobald Strom da ist, werden alle RGB-Daten der erste Spalte in den RAM geschaufelt und mit der FastSPI-Lib ausgegeben. Dann kommt die nächste Spalte und so weiter. Wahrscheinlich muss ich dann die (Fahr-)Geschwindigkeit anpassen, aber ich sollte nicht in die Arduino-FastSPI-Taktfalle geraten - ODER? :o)

SO sehen meine ersten Versuche aus, es soll eben nur viel schöner und größer (und auch komfortabler)werden: https://dl.dropboxusercontent.com/u/327492/tmp/[20130606]__00h_57m_25s_800x600.jpg

Ach ja - und noch etwas: Hältst du es für möglich, dass ich mit vertretbarem Aufwand die RGB-Analyse direkt mit einer TIFF-Datei von einer SD-Karte durchführe und mir so das PHP-Geraffel sparen kann? Da bin ich nämlich lange Zeit dran gescheitert und hab' dann eben PHP hergenommen. Das wäre schon prima. ALlerdings wird das wahrscheinlich heißen: NOCH langsamer fahren :o)

Danke und Gruß,
kuahmelcher.

GIMP kann Bilder als C Header Dateien speichern. Wenn Du Deinen Code entsprechend hinkriegst, dann kannst Du wirklich alles im Arduino machen.

Die andere Lösung wäer zu lernen wie man mit der Kommandozeile umgeht und dann ein sconstruct zu verwenden.
http://code.google.com/p/arscons/source/browse/SConstruct

kuahmelcher:
Hallo,
ich habe mir mal die anderen Arduinos angeschaut: der "Mega" funktioniert mit der FastSPI-Lib, hat aber auch "nur" 8 KiB SRAM. Der "Arduino DUE" hat sagenhafte 96 KiB, leider habe ich aber bisher keine klaren Hinweis auf die FastSPI-Lib gefunden, die ich ja anscheinend dafür zwingend brauche, wenn ich nicht alles wieder neu erfinden will.

Aber damit ich das richtig verstehe: Es müsste doch funktionieren, wenn ich mir selbst ein 24lc256-eeprom-Shield bastle, was 256 KiB hat und einfach auf dem Arduino UNO drauf sitzt. Sobald Strom da ist, werden alle RGB-Daten der erste Spalte in den RAM geschaufelt und mit der FastSPI-Lib ausgegeben. Dann kommt die nächste Spalte und so weiter. Wahrscheinlich muss ich dann die (Fahr-)Geschwindigkeit anpassen, aber ich sollte nicht in die Arduino-FastSPI-Taktfalle geraten - ODER? :o)

SO sehen meine ersten Versuche aus, es soll eben nur viel schöner und größer (und auch komfortabler)werden: https://dl.dropboxusercontent.com/u/327492/tmp/[20130606]__00h_57m_25s_800x600.jpg

Die Ansteuerung der WS2811/12 erfolgt in 2 "Stufen":

  1. Übertragung der Helligkeitswerte vom RAM für jedes LED zu den WS2811s man braucht da 120*3 Byte also 360 Byte
  2. Übertragung der Werte von einem Speichermedium (FLASH, SD-Karte, externes EEPROM am besten über SPI weil schneller als I2C)

Besonderheiten:
zu 1) die Übertragungsgeschwindigkeit und Timings sind sehr zeitkritisch. Darum ist dieser Teil in der fastSPI in Assembler geschrieben und die zu übertragenden Daten müssen im RAM abgelegt sein. Die fastSPI ist nicht mit dem Arduino DUE kompatibel weil dieser Teil neu geschrieben und auf den Kontroller des DUE angepaßt werden müßte. Die Dauer wird von der Anzahl der WS bestimmt und ist wie bereits geschrieben bei 120 WS um 200µS.

zu 2) diese Übertragung ist wenig zeitkritisch. Die Dauer bestimmt zusammen mit der Anzahl der LED die maximale mögliche "Bildwiederholrate" und darum auch die Fahrgeschwindigkeit und Belichtungsdauer.

Wie gesagt ist die SD-Karte vorzuziehen da Du da einfacher die Bilddaten übertragen kannst. Wie überträgst Du die Bilddaten vom PC in den EEPROM? Die Übertragungsgeschwindigkeit da beide SPI als Schnittstelle haben ca gleich groß.

Grüße Uwe