Hallo liebe mikrocontroller.net Community.
der Soll Zustand meines Arduino Projektes ist der folgende:
Dem Nutzer wird eine mp3 Datei mit einer Zielfrequenz vorgespielt.
Dieser muss anschließend singend/pfeiffend/summend ebendiese
Zielfrequenz treffen. Das verwendete Mikro ist ein MAX4466, die FFT
Funktion ist für meine Zwecke hinreichend genau. Ferner ist es
problemlos möglich das ganze auf dem LCD Display anzuzeigen.
Die gewünschte Erweiterung des ganzen, war den Frequenzpegel nicht nur
als Zahl, sondern auch als Linienpegel auf einer 9x9 Dotmatrix mit
MAX7219 Modul darzustellen. Ab diesem Zeitpunkt kollabiert das Projekt.
Von einem Offsetfehlers meiner Frequenz um 600Hz bis zur schlichten
Nichtansteuerbarkeit der Matrix bei gleichzeitiger Zerstörung der
Frequenzerkennung war da jeder denkbare und undenkbare Fehler dabei.
Anbei mein Code, vielleicht kann mir jemand weiterhelfen.
Markus schrieb:> Anbei mein Code
Bitte Bedienungsanleitung lesen...
> vielleicht kann mir jemand weiterhelfen.
Teile und herrsche!
Trenn die Aufgaben und sorge dafür, dass jede Einzelaufgabe
funktioniert. Kannst du die Frequenzberechnung weglassen und einfach
einen hochlaufenden Zähler auf der Anzeige als Balken ausgeben?
> Ab diesem Zeitpunkt kollabiert das Projekt.
Ich tippe auf einen amoklaufenden Pointer...
BTW: Diese level1..8 Bitmustertabellen kann man übrigens auch ganz
einfach in Echtzeit berechenen. Dadurch wird die Funktion LedMatrix()
auf einemal ganz kurz.
BTW2: Falls dein LCD flackert, dann liegt es am lc.clearDisplay(0).
Besser ist es, wenn du nur den Cursor platzierst und die angezeigten
Buchstaben überschreibst.
BTW3: welchen Arduino verwendest du? Wenn es einer der AVR-dinos ohne
FPU ist, dann sind float und double gnadenlose Performance-Fresser. Und
sonst in den meisten Fällen einfach unnötig. Kann dein µC eigentlich
double? Oder macht er double automatisch auch in float mit nur 6
signifikanten Vorkommastellen?
Übersehe ich was oder tastest du deine Messwerte in der Loop ab?
Wenn dir ein Interrupt dazwischen kommt stimmt deine Abtastung nicht
mehr.
Ich würde Abtasten in einem Timer Interrupt oder mit DMA (falls
vorhanden).
Die Ausgabe dann in Loop alle 50ms oder so.
Lothar M. schrieb:> Trenn die Aufgaben und sorge dafür, dass jede Einzelaufgabe> funktioniert. Kannst du die Frequenzberechnung weglassen und einfach> einen hochlaufenden Zähler auf der Anzeige als Balken ausgeben?
Ja. Dies habe ich bereits getestet. Es scheitert immer nur an der Fusion
der Programmteile - dabei auch völlig unabhängig was die DotMatrix
machen soll; auch eine simple void Funktion, bei der alle LED's leuchten
sollen, erzeugt Probleme.
>> Ab diesem Zeitpunkt kollabiert das Projekt.> Ich tippe auf einen amoklaufenden Pointer...
Gut möglich. Bei mir hat sich mittlerweile nur leider etwas
Betriebsblindheit eingestellt. Durch den fehlenden Debug-Modus habe ich
mir auch schon zahlreiche Zwischenwerte auf den seriellen Monitor
ausgeben lassen. Leider hat das aber bisher noch keinerlei Verständnis
dafür geschaffen, wo mein Fehler liegen könnte.
> BTW2: Falls dein LCD flackert, dann liegt es am lc.clearDisplay(0).> Besser ist es, wenn du nur den Cursor platzierst und die angezeigten> Buchstaben überschreibst.
Großartiges Flackern war nicht, habe es trotzdem behoben.
> BTW3: welchen Arduino verwendest du? Wenn es einer der AVR-dinos ohne> FPU ist, dann sind float und double gnadenlose Performance-Fresser.
Arduino UNO R3, dementsprechend keine FPU.
Markus schrieb:> Arduino UNO R3
Der mega328 hat 2 kB SRAM. Allein deine 2x 128 double-Arrays brauchen
1kB davon. Dazu noch 64 Bytes für die Pixel-Arrays und der Puffer für
die RS232-Schnitte. Und auch sonst sind auch noch einige
speicherfressende Variablen im Spiel.
Sieh dir mal den Speicherverbrauch an. Und auch, was die FFT an lokalen
Variablen auf dem Stack anlegt.
Ich hätte gesagt, das die Datenübertragung zur Matrix zu lange dauert,
weil das ja auch bei einem fixen Bild passiert.
Dadurch kommt die FFT ins schleudern...
Mach mal eine einzelne LED an einen Pin, und lass die in der Wartezeit
auf die FFT-Startzeit leuchten, danach aus.
Dann siehst du: ohne das Display leuchtet sie ein bissel, weil Zeit
überbleibt, mit Display leuchtet sie nicht weil der Startzeitpunkt
überschritten wurde.
Oder: mach sie an, wenn der Startpunkt überschritten war. Fehlerlampe
"CPU-Load >100%" sozusagen.
Jens M. schrieb:> Ich hätte gesagt, das die Datenübertragung zur Matrix zu lange dauert,> weil das ja auch bei einem fixen Bild passiert.> Dadurch kommt die FFT ins schleudern...
Da läuft nichts nebenher. Das läuft völlig unabhängig und streng
sequentiell:
1. Samples einlesen
2. FFT
3. nach dem 5. Durchlauf: Mittelwertbildung und Ausgabe
4. weiter bei 1.
> Fehlerlampe "CPU-Load >100%" sozusagen.
Die CPU-Load ist bei diesem Programmierstil immer genau 100%. Das
Ganze wird einfach mit längerem Programm immer langsamer. Es wird jetzt
schon nicht arg schnell sein...
Lothar M. schrieb:> Da läuft nichts nebenher. Das läuft völlig unabhängig und streng> sequentiell:
Ja genau.
Und zwischen Einlesen und FFT ist ein Warter, der dafür sorgt das die
Samples zur richtigen Zeit genommen und FFTt werden.
Wenn das Display jetzt aber zu lange braucht so das der Warter ein
Durchläufer wird, stimmt die Samplefrequenz nicht mehr, oder?
Lothar M. schrieb:> Die CPU-Load ist bei diesem Programmierstil immer genau 100%.
Ich hoffe du veräppelst mich.
Jens M. schrieb:> Wenn das Display jetzt aber zu lange braucht so das der Warter ein> Durchläufer wird, stimmt die Samplefrequenz nicht mehr, oder?
Nein, weil die Zeit für die Abtastfrequenz in den Zeilen 60+65 gemacht
wird.
Die "nächste" Runde an Samples wird eben zu einem anderen Zeitpunkt
genommen.
Aber das dürfte egal sein. Wenn es nicht egal ist, dann hätte man auch
in der Version ohne Punktdisplay keine Zeile mehr einfügen oder ändern
dürfen (z.B. serielle Schnitte oder LCD).
> Lothar M. schrieb:>> Die CPU-Load ist bei diesem Programmierstil immer genau 100%.> Ich hoffe du veräppelst mich.
Nein, es ist genau so: immer dann wenn die CPU mit irgendwas fertig ist,
muss sie den nächsten Befehl ausführen. Sie hat auch keine Pause und sie
muss auch nicht irgendwie "schnell genug" fertig sein. Je nach
Durchlaufzeit ergibt sich dann eben eine andere Aktualisierungsrate auf
dem Display. Weil dazu aber nichts gefordert ist, ist sie auch immer
"schnell genug".
Würde hier aber eine Aktualisierungsrate von z.B. 5x pro Sekunde
gefodert, dann wäre die CPU schlagartig völlig überlastet, weil sie das
nicht schafft.
Im echten Leben und mit steigender Erfahrung wird man natürlich den
Programmierstil signifikant umstellen. Da kopiert man dann (hoffentlich)
nicht einfach irgendwelche Codeschnipsel hintereinander und nennt das
dann "mein Programm".
Lothar M. schrieb:> Nein, es ist genau so: immer dann wenn die CPU mit irgendwas fertig ist,> muss sie den nächsten Befehl ausführen
Dann hast du mich nicht veräppelt, aber es auch nicht verstanden.
Genau die von dir als
Lothar M. schrieb:> Nein, weil die Zeit für die Abtastfrequenz in den Zeilen 60+65 gemacht> wird.
erkannten Zeilen sorgen für das Timing.
Und so lange dreht sich der Computer da drin im Kreis, weil eben noch
Zeit über ist.
Meine Vermutung ist nun, das das zusätzlich eingefügte Display diese
nach der Warteschleife eingefügte Programmschleife zeitlich zu lang
macht, so das eben keine Zeit mehr zum Warten überbleibt, salopp als
"CPU-Load >100%" bezeichnet.
Soweit ich den Code verstehe wirkt sich diese Verzögerung direkt aus,
weil eben nicht in konstantem Zeitraster gesampelt wird, was dann in der
FFT für wilde Signale sorgt, weil die ja rechnerisch nicht nur auf einen
festen, sondern sogar einen definiert langen Zeitablauf festgelegt ist.
Lothar M. schrieb:> dann hätte man auch> in der Version ohne Punktdisplay keine Zeile mehr einfügen oder ändern> dürfen (z.B. serielle Schnitte oder LCD).
"Keine Zeile" wird es nicht sein, ein wenig Reserve traue ich dem
Controller schon noch zu.
Aber Display oder Com dürfte ebenfalls zu lang sein, ja.
Daher ja der Vorschlag, eine LED einzubauen um diese verwartete Zeit in
den Zeilen 60-65 anzuzeigen, im Grunde genau das was im
Windows-Taskmanager der Nulltask auch macht: so lange er läuft hat die
CPU noch Zeit zum Denken.
Jens M. schrieb:> Und so lange dreht sich der Computer da drin im Kreis, weil eben noch> Zeit über ist.
Nein, es ist keine Zeit über, die vom Programm für andere Aufgaben
verwendet wird. Lediglich die Syseminterrupts (Timer, SIO) kommen durch.
Aber die helfen dem Programmablauf auch nicht weiter.
Also dreht sich dort in den Zeilen 60..65 der µC mit voller
Rechenleistung "im Kreis". Es wird aktiv Rechenzeit vernichtet, da
bleibt keine Zeit übrig, die das Programm anderweitig sinnvoll verwenden
kann.
Dein Ansatz geht in die Richtung: wenn man es anders machen würde, dann
wäre noch Zeit über, die für was anderes verwendet werden könnte. Aber
"würde, wäre, könnte" ist halt eben nur Konjunktiv und ein frommer
Wunsch.
Jens M. schrieb:> so das eben keine Zeit mehr zum Warten überbleibt
Es ist nirgends eine maximale Zeit für irgendwas definiert. Wenn irgend
ein Programmteil länger braucht, dann kommt der Rest eben später dran.
Jens M. schrieb:> Lothar M. schrieb:>> dann hätte man auch>> in der Version ohne Punktdisplay keine Zeile mehr einfügen oder ändern>> dürfen (z.B. serielle Schnitte oder LCD).> "Keine Zeile" wird es nicht sein, ein wenig Reserve traue ich dem> Controller schon noch zu.
Wenn das Timing zwischen 2 der FFT-Wandlungen kritisch wäre, dann käme
es auf jede Zeile an, jede eingefügte Zeile würde dieses kritische
Timing ändern.
Ich bin mir nach wie vor ziemlich sicher, dass es auf ein
Speicherproblem rausläuft. 2kB sind nicht viel, wenn da nach der
statischen Analyse nicht noch 500 Bytes übrigbleiben, dann läuft der
Stack in den deklarierten Speicher und überschreibt dort Daten.
Lothar M. schrieb:> Nein, es ist keine Zeit über, die vom Programm für andere Aufgaben> verwendet wird.
Doch, es ist Zeit über.
Weil eine neue Wandlung noch nicht dran ist und die CPU eben so lange im
Park Tauben füttern kann bzw. sogar muss.
Das der Quarz nicht anhalten kann und so halt einfach im Kreis geNOPt
wird sollte jedem µC-Programmierer klar sein.
Es bleiben keine Rechenzyklen über, aber es ist halt gerade nix zu tun.
Also muss der Dampf abgelassen werden.
Lothar M. schrieb:> wenn man es anders machen würde, dann> wäre noch Zeit über, die für was anderes verwendet werden könnte.
Ja, das ist auch so. z.B. eben für das Display.
Hier ist es fest in den Zyklus nach dem Warten eingebaut. Da es sich
beim Warten aber um einen festen Ablauf "wait till period is um" und
eben nicht um ein Delay handelt, kann sich das ganze verschlucken, wenn
der Ablauf des Rests zu lange dauert und somit eben keine Zeit mehr im
Warteschleifendings verbracht werden muss. Das jittert dann halt,
genau als wenn regelmäßig ein Int reinkommt und die ISR länger braucht
als Zeit ist. Dann fehlt halt zwischen drin einer, weil das Flag schon
wieder kam bevor der µC bereit war.
Lothar M. schrieb:> Es ist nirgends eine maximale Zeit für irgendwas definiert. Wenn irgend> ein Programmteil länger braucht, dann kommt der Rest eben später dran.
Jaha. Deswegen ist da auch kein Delay drin sondern eine getaktete
Abfrage. Was eine maximale Zeit definiert. Suche "sampling_period".
Lothar M. schrieb:> Wenn das Timing zwischen 2 der FFT-Wandlungen kritisch wäre, dann käme> es auf jede Zeile an, jede eingefügte Zeile würde dieses kritische> Timing ändern.
Nope.
Jede Extrazeile würde dem Warter etwas Zeit wegnehmen. So lange er
dennoch zuverlässig "+1" über hat bleibt alles im Lot. Sobald man zuviel
einfügt (eben z.B. SPI, I2C, Delay, Display) kann der Warter den Takt
nicht mehr halten.
Und ich deute das so, das es sehr wohl auf die Zeit zwischen den FFTs
ankommt, denn sonst hätte man den Warter auch einfach rauslassen können
und einfach volle Socke samplen & FFTn bis der Prozessor kocht.
Lothar M. schrieb:> Ich bin mir nach wie vor ziemlich sicher, dass es auf ein> Speicherproblem rausläuft.
Das könnte man ja testen in dem man anzeigen lässt ob noch Zeit in der
Warteschleife verbrannt wird. Wenn ja, hast du gewonnen. Wenn nein, ich.
Das wäre jedenfalls mein Ansatz, denn weder das Display noch der Rest
sind so an sich als Code nicht lauffähig. Zusammen aber nicht mehr, und
das ist entweder RAM-Knappheit oder Prozessorzyklenknappheit.
Und da die Displaygeschichte viel Zeit verplempert mit der
Datenrausschieberei, aber so gut wie kein RAM braucht, liegen meine
Chips auf "CPU-Zeit-Mangel".
Jens M. schrieb:> Doch, es ist Zeit über.
Demnächst gebe ich nach...
> Weil eine neue Wandlung noch nicht dran ist und die CPU eben so lange im> Park Tauben füttern kann bzw. sogar muss.
Kann sie aber mit dem obigen Programm nicht (und nur um dieses Programm
geht es hier). Sie wartet da mit aller ihr zur Verfügung stehenden
Rechenleistung darauf, dass die Zeit bis zum nächsten Sample vergeht.
> Jede Extrazeile würde dem Warter etwas Zeit wegnehmen.
Sage ich ja: Konjunktiv. Aber wo im obigen Programm kann irgendwas
irgendwem Zeit wegnehmen? Ich kann da zwischen irgendwelche der
Ablaufpunkte Sampling-FFT-Anzeige sogar ein Delay mit 1 Sekunde
einbauen, dann wird der Ablauf eben noch langsamer, aber er läuft
weiterhin in genau gleicher Form ab.
> Wenn ja, hast du gewonnen. Wenn nein, ich.
Im Grunde egal, meine virtuelle Wand hängt eh schon voll solcher
virtueller Siege. Mal sehen, was der Markus letztlich rausfindet.
Ich habe aber einfach mal den Code compiliert und der Compiler sagt mir:
"Globale Variablen verwenden 1584 Bytes (77%) des dynamischen Speichers,
464 Bytes für lokale Variablen verbleiben." Und in die verbleibenden
"464 Bytes für lokale Variablen" muss blöderweise der Stack auch rein.
Lothar M. schrieb:> aber er läuft> weiterhin in genau gleicher Form ab.
Und eben das ist falsch.
Direkt nach dem while, das auf den festgelgten Startpunkt wartet wird
der nächste Startpunkt festgelegt.
Wenn der hinzugefügte Code länger läuft als Zeit bis zu eben diesem
vorher festgelgten Startpunkt vorhanden ist, tritt eine Verzögerung auf,
die die vorher festgelegte Samplingfrequenz versaut.
Was meines Erachtens die FFT stört und vmtl. genau die Fehler verursacht
die hier auftreten.
Kennst du einen einfachen Trick, den Stack bzw. das anecken des selbigen
zu erkennen?
Meinen "CPU-Load-Trick" hab ich ja schon verraten.
Das 464 Byte für Stack und temporäre Variablen nicht reichen mag ich
kaum glauben, aber ausschließen würd ich das auch nicht.
Jens M. schrieb:> Und eben das ist falsch.
Keine Ahnung, wo du da einen Knoten siehst, aber der ist nicht da.
> Direkt nach dem while, das auf den festgelegten Startpunkt wartet wird> der nächste Startpunkt festgelegt.
Und gleich wieder in der for-Schleife weitergemacht, bis 256 Samples
eingelesen sind. Es werden in diesem Programm zuerst alle 256 Samples
eingelesen, dann wird darauf die FFT genacht, dann nach 5 Durchläufen
dieser beiden Schritte der Mittelwert ausgegeben.
Der Programmablauf ist also so:
1. 256 Samples einlesen
2. FFT darauf machen und Ergebnis speichern
3. 256 Samples einlesen
4. FFT darauf machen und Ergebnis speichern
5. 256 Samples einlesen
6. FFT darauf machen und Ergebnis speichern
7. 256 Samples einlesen
8. FFT darauf machen und Ergebnis speichern
9. 256 Samples einlesen
10. FFT darauf machen und Ergebnis speichern
11. Mittelwert bilden
12. Mittelwert ausgeben
13. weiter bei 1.
Da ist nur der Zeitablauf beim Einlesen der Samples ist kritisch und der
wird dort lokal per micros() abgehandelt.
Damit dieses Timing passt, wird vor jeder der 5 Sampling-Runden die
jeweils aktuelle Zeit als Startzeit genommen.
Jens M. schrieb:> Kennst du einen einfachen Trick, den Stack bzw. das anecken des selbigen> zu erkennen?
Nein, nicht beim AVR...
Jens M. schrieb:> Speicher mit FF vollmachen
Kann ins Auge gehen, denn bis man mit seinem Programm daherkommt läuft
ja schon der Startupcode mit Timertic usw...
> und dann "von unten" nachkucken wann das> erste nicht-FF kommt? Das wäre zumindest ein Anhaltspunkt.
1. Wenn nicht grade wer FF auf den Stack gelegt hat. Na gut, das wäre
Pech.
2. Diese Verfahren gehe nur "offline", man bekommt also erst forensisch
heraus, dass was passiert ist, aber nicht wo/wann es passiert ist.
3. Mit einem anständigen Debugger kann ma sich den Speicher einfach mal
an einem Breakpoint ansehen. Aber irgendwie ist genau dieser Debugger
das, was mir am Arduino von Anfang an fehlt. Keine Ahnung, wie man ohne
Debugger ein Programm effizient debuggen kann. Das Terminal mit der
seriellen Schnitte ist grade mal ein feuchter Witz eines Debuggers.
Lothar M. schrieb:> Kann ins Auge gehen, denn bis man mit seinem Programm daherkommt läuft> ja schon der Startupcode mit Timertic usw...
Ja, das muss man natürlich hart programmieren können. Arduino ist dazu
verkehrt, wenn man nicht in die Untiefen eintaucht.
Lothar M. schrieb:> Wenn nicht grade wer FF auf den Stack gelegt hat. Na gut, das wäre> Pech.
Ja, kann man sich halt verschätzen. Wenn bei "464byte frei" das erste FF
bei 460 liegt, weiß man das ist eng. Bei 350 würd ich sagen das passt.
Lothar M. schrieb:> Diese Verfahren gehe nur "offline", man bekommt also erst forensisch> heraus, dass was passiert ist, aber nicht wo/wann es passiert ist.
Wäre aber eine Kontrolle, die sagt "das ist eng" oder "das geht".
Evtl. das Programm 1 Minute laufen lassen und dann via Taste abbrechen
und den Stackbegrenzer ausgeben lassen. Bleibt das Problem das man diese
Findehilfe in Arduino einfrickeln müsste.
Lothar M. schrieb:> Aber irgendwie ist genau dieser Debugger> das, was mir am Arduino von Anfang an fehlt.
Die Leute, für die Arduino ursprünglich mal gedacht war, könnten mit
einem Debugger nicht umgehen. ;)
Lothar M. schrieb:> Ich bin mir nach wie vor ziemlich sicher, dass es auf ein> Speicherproblem rausläuft. 2kB sind nicht viel,
Ich sehe das ganz genauso. Vor allem nachdem alle Teile einzeln perfekt
laufen, aber sobald er alle in einen Sketch packt, kollabiert alles;
allein diese Formulierung des OP ließ mich an ein Speicher-Problem
denken.
CPU-Überlastung könnte zwar grundsätzlich auch eine Folge der
Vereinigung separat funktionierender Teilprogramme sein, in dem, obigen
Sketch aber wohl kaum nicht, da dort keinerlei zeitkritische Passagen
aus verschiedenen Teilprogrammen ineinander verwoben werden. Außerdem
äußert sowas sich aber eher in Symptomen wie scheinbaren Hängern,
fehlerhaften Sampledaten, die zu unsinnigen FFT Ergebnissen führen
usw...
> statischen Analyse nicht noch 500 Bytes übrigbleiben,> dann läuft der Stack in den deklarierten Speicher> und überschreibt dort Daten.
Genau die Konstellation bei der sich i.A. plötzlich alles in totales
Chaos verwandelt oder eben wie der OP formuliert: kollabiert.
Meine Alternativ-Vermutung wäre ein Konflikt aus der speziellen
Kombination von Libraries; der gäbe ich aber auch max. ein paar Prozent
Wahrscheinlichkeit.
Jens M. schrieb:> Wenn das Display jetzt aber zu lange braucht> so das der Warter ein Durchläufer wird, stimmt> die Samplefrequenz nicht mehr, oder?
Und weiter? Klar, die FFT wird fehlerhafte Werte liefern, möglicherweise
auch kraß unsinnige, aber auch das kann im weiteren Verlauf nicht zum
vollständigen Kollaps führen; da wird ja nur noch ein Mittelwert
berechnet und ausgegeben. Bliebe also nur die FFT-Lib selbst, aber wenn
die nur Aufgrund einer fehlerhaften Samplerate alles kollabieren läßt,
das würde ich das als heftige Bug in der Library ansehen - kann man zwar
im Arduino-Ökosystem nie völlig ausschließen, halte ich aber doch für
sehr unwahrscheinlich; auch weil ArduinoFFT wohl keine Orchideen-Lib mit
gerade mal einstelliger Nutzerzahl ist.
Jens M. schrieb:> Die Leute, für die Arduino ursprünglich mal> gedacht war, könnten mit> einem Debugger nicht umgehen. ;)
In dem Punkt würde ich Jens vollinhaltlich zustimmen.
Ob das aber der Hauptgrund ist, daß es nach wie vor keinen gibt, würde
ich trotzdem nicht wetten wollen.
Veit D. schrieb:> der TO könnte die Konstanten ins Flash schieben.
oder aber ins EEPROM, dann aber dem Arduino verbieten den EEPROM zu
löschen EESAVE.
Deswegen mag ich ja die ATmega1284p Version mit 16KB SRAM und 128KB
flash.
Veit D. schrieb:> Wegen freien RAM "sichtbar" machen. Das sollte helfen können denke ich.> https://github.com/arduino/ArduinoCore-API/issues/73
Wie soll das denn helfen?
Ich bin vor ein paar Jahren an einer Sache gescheitert, die diesem
Thread verdammt ähnlich ist, mit OLED-Display: Alle Programmteile für
sich funktionierten einwandfrei, auch Kombinationen dieser. Sobald alles
eingebunden war, schmierte der A*ProMini direkt ab.
Später kam es zum Laufen, nachdem ich eine deutlich simplere Library für
das OELD gefunden hatte. Ich bin mit ziemlich sicher, dass der
dynamische Speicher während der Laufzeit übergelaufen ist. Das vermute
ich auch hier, die Grafik braucht halt Speicher.
Wie will man dessen Auslastung messen / melden, wenn der Kram direkt
abschmiert?
Joachim B. schrieb:> Deswegen mag ich ja die ATmega1284p Version mit 16KB SRAM und 128KB> flash.
Wenn Du eigene Leiterplatten machst, ja. Als fertiges Board auf dem
A*Mega braucht das Ding unverschämt viel Platz.