Guten Morgen,
Ich bin zurzeit wieder am weiter programmieren meiner Wetterstation. Und
wollte gerne noch eine Anzeige Modus hinzufügen wo man die Minimale
Temperatur und die Maximale Temperatur sehen. Als ich es dann kompiliert
habe, kam im Atmel Studio 7 unten eine Fehler Nachricht. Dieses sieht so
aus:
Programm Memory Usage: 12788 bytes 39,0 % Full
Programm Memory Usage: 12788 bytes 39,0 % Full
Data Memory Usage: 2054 bytes 100,3 % Full (Memory
Overflow)
Hier nochmal als Bild: http://prntscr.com/bhug6u
Ich verwende denn ATMega328P mit 16 Mhz. Soweit ich weis und auch
gesehen wenn ich bei einen neuen Projekt denn Controllor auswähle, hat
dieser ein App./Boot Memory von 32 KBytes. Und auch im Datenblatt steht
das dieses 32 Kbytes hat.
Muss ich da vorher noch was einstellen damit ich mehr nutzen kann? Ein
anderen Controllor in meine Platine einzubauen ist nicht möglich. Da für
ein ATMega644 oder ATMega32/16 kein Platz ist.
Mfg Felix.
Gast
#4617945
> Data Memory Usage: 2054 bytes 100,3 % Full (Memory Overflow)
Die Meldung bezieht sich nicht auf den Flash-Speicher (32 KBytes)
sondern auf das RAM (2 Bytes).
Gast
#4617948
Felix N. schrieb: > Data Memory Usage: 2054 bytes 100,3 % Full (Memory > Overflow) Das ist dein RAM, und der ist voll! Die 32 KB sind dein Flash-Speicher. Flashspeicher != RAM Speicher!
klausr schrieb: > Das ist dein RAM, und der ist voll! Die 32 KB sind dein Flash-Speicher. > Flashspeicher != RAM Speicher! Ja okay. Aber im RAM werden doch nur Temporäre Daten gespeichert. Und nix dauerhaft. Und was kann ich dagegen jetzt machen?
Felix N. schrieb: > Data Memory Usage: 2054 bytes 100,3 % Full (Memory > Overflow) schaffe Platz im RAM Texte aus dem Flash direkt globale Variablen verringern, auf lokale umsteigen wo möglich Platz für Variablen reservieren die mehrere Functions nutzen können usw. zeig mal deinen Code der alles RAM verbraucht
Joachim B. schrieb: > schaffe Platz im RAM > > Texte aus dem Flash direkt > globale Variablen verringern, auf lokale umsteigen wo möglich > Platz für Variablen reservieren die mehrere Functions nutzen können > > usw. > > zeig mal deinen Code der alles RAM verbraucht Jo, aber nicht erschrecken es ist nicht grade wenig Code
Gast
#4617962
> char minTemp[100];
Warum wird das Array mit 100 Bytes angelegt?
Baltin schrieb: > Warum wird das Array mit 100 Bytes angelegt? Ääää, weis nicht habe mal 1 mit 100 angelegt und dann immer wieder. Reduziere sie mal auf 2 Bytes
wie vermutet, zuviel globales Zeugs! Kann man ja machen wenn man SRAM ohne Ende hat, so aber nicht mit nur 2K ich tippe mal deine ganzen lcd_print Texte brauchen auch RAM, die sollte im freien Flash liegen und per strcpy_P nur bei Bedarf in eine leerzeile_str kopiert werden
Gast
#4617975
Es hat keinen Sinn für jede Ausgabe einen extra Stringbuffer zu reservieren. Er braucht auch maximal so gross sein wie die Zeilenlänge des Displays. also mache
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
zu
1 | |
und mache deine ganzen Ausgaben in dieses Feld.
Deine Variable wie readingTemp, etc verbraten alle jeweils 100 Bytes RAM. Gehe den Code durch und überlege dir wie viele Bytes du maximal benötigst, und verringere die Größe der Arrays entsprechend. Andere arrays wie z.B. minuten[10] ist wiederum zu kurz für die Daten die du hinein schreibst und muss vergrößert werden. Warum du in der Funktion avg_measurement() den selben Code 10 mal hintereinander kopiert hast ist mir auch nicht ganz ersichtlich. Hier kann man mit einer Schleife den code sicherlich verkürzen. Der Tipp mit Strings in den flash verlegen wurde oben schon erwähnt. Wie das geht findest du im AVR-GCC Tutorial. Jeder deiner Strings liegt im RAM und verbraucht dort kostbaren Platz. Hier hast du auch oft quasi den selben String mehrfach im RAM(z.B. in avg_measurements()), wo sich der selbe String nur um eine Ziffer unterscheidet.
Joachim B. schrieb: > wie vermutet, zuviel globales Zeugs! > > Kann man ja machen wenn man SRAM ohne Ende hat, so aber nicht mit nur 2K > > ich tippe mal deine ganzen lcd_print Texte brauchen auch RAM, die sollte > im freien Flash liegen und per strcpy_P nur bei Bedarf in eine > leerzeile_str kopiert werden Habe mal die ganzen Array auf 1 Byte gekürzt. Dann ich ja eh nur 1 Wert reinschreibe. Und zak nur noch 69,5 % des RAM verwendet. Keine Ahnung ob die lcd_print sachen in denn RAM schreiben: So sieht der Code dazu aus: http://prntscr.com/bhuoh5
Thomas M. schrieb: > Jeder deiner Strings liegt im > RAM und verbraucht dort kostbaren Platz. Kann man nicht mit free() denn RAM wieder freigeben von einer Methode. Werde mal die avg_measuremnt mit einer vorschleife kürzen
Felix N. schrieb: > Keine Ahnung ob die lcd_print sachen in denn RAM schreiben: ne die sind es nicht, es ist dein: lcd_printlc(1, 1, "Das Ergebnis wird"); könnte man auch umformen //globale LCD Zeile char leerzeile[50]={0}; // Größe nach maximaler Zeichenlänge+1, global vor PRG strcpy_P(leerzeile, "Das Ergebnis wird"); lcd_printlc(1, 1, leerzeile);
Joachim B. schrieb: > könnte man auch umformen > > //globale LCD Zeile > > char leerzeile[50]={0}; // Größe nach maximaler Zeichenlänge+1, global > vor PRG > > strcpy_P(leerzeile, "Das Ergebnis wird"); > lcd_printlc(1, 1, leerzeile); Verbraucht dieses genau dieses Satz mehr RAM? Als die anderen?
Gast
#4617986
Frickelfritze schrieb: > und mache deine ganzen Ausgaben in dieses Feld. Dasselbe gilt für die Arrays
1 | |
2 | |
3 | |
4 | |
die allerdings - wie schon von anderen erwähnt - zu klein sind.
Felix N. schrieb: >> strcpy_P(leerzeile, "Das Ergebnis wird"); Dort meckert er mit expected ')' before '(' token Frickelfritze schrieb: > und mache deine ganzen Ausgaben in dieses Feld. Wie meinst du das?
Gast
#4617990
Deine ISR macht einen überladenen Eindruck! Auch sehe ich kein einziges "volatile". Ich schätze mal, das wird auch noch für Fehlfunktionen sorgen.
Gast
#4617993
U. F. schrieb: > Deine ISR macht einen überladenen Eindruck! > > Auch sehe ich kein einziges "volatile". > Ich schätze mal, das wird auch noch für Fehlfunktionen sorgen.
1 | |
2 | |
bei einer leeren Hauptschleife kann es keine Probleme mit Variabel in der ISR geben.
U. F. schrieb: > Deine ISR macht einen überladenen Eindruck! Ich nutze mit Absicht denn Overflow Timer. Damit ich zusätzlich noch mit _delay_ms() arbeiten kann. Deswegen steht in der Hauptschleife auch nix drin
Gast
#4617998
Felix N. schrieb: > Wie meinst du das? Zum Beispiel: alt:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
neu:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Frickelfritze schrieb: > neu: > ............ > sprintf(temp_str, "%d ms", basicTempTime); > lcd_printlc(3, 1, temp_str); > ............ > sprintf(temp_str, "%d ms", basicMeasurementTime); > lcd_printlc(3, 1, temp_str); Aso, du meinst einen Temporären String zu haben und diesen immer wieder neu beschreiben.
Gast
#4618013
Felix N. schrieb: > Aso, du meinst einen Temporären String zu haben und diesen immer wieder > neu beschreiben. Genau das, so wie hier schon beschrieben. Frickelfritze schrieb: > Es hat keinen Sinn für jede Ausgabe einen extra Stringbuffer > zu reservieren.
Frickelfritze schrieb: > Genau das, so wie hier schon beschrieben. > > Frickelfritze schrieb: >> Es hat keinen Sinn für jede Ausgabe einen extra Stringbuffer >> zu reservieren. Ja kommt glaubig daher. Das ich bevor ich mit den Controllor angefangen bin Java programmiert habe. Und dort für jede Sache eine Variable angelegt zu habe. Denn beim Rechner mit ca. 4 bis 16 GB RAM ist das auch so zimmlich egal ob er jetzt 500 mb oder 1 gb belegt. Aber ich habe nun auch mal Variablen die ich nur innerhalb einer Methode benötige aus der Globalen List oben entfernt und in die Funktion rein gepackt. So sind es ja auch nur Temp Variablen oder? Was hat das eigentlich mit diesen volatile auf sich. Ist das wichtig?
Felix N. schrieb: > Was hat das eigentlich mit diesen volatile auf sich. Ist das wichtig? das die ISR die Variable immer liest und nicht welche aus dem Cache nimmt. Das ist wichtig das wirklich die Variable immer in der richtigen Unterroutine mit den stimmigen Daten genommen wird. Sub 1 x=10 ISR x++ ohne volatile ist in Sub 1 immer noch x=10 volatile kann man aber auch mal gurgeln https://de.wikipedia.org/wiki/Volatile_(Informatik)
Gast
#4618120
Joachim B. schrieb: > das die ISR die Variable immer liest und nicht welche aus dem Cache > nimmt. Käse. Es gibt beim Arduino (besser gesagt bei den AVR Controllern) keinen Cache.
Gast
#4618136
Joachim B. schrieb: > das die ISR die Variable immer liest und nicht welche aus dem Cache > nimmt. Cache kann man gurgeln. Solltest du mal machen. > volatile kann man aber auch mal gurgeln > > https://de.wikipedia.org/wiki/Volatile_(Informatik) Scho ma deinem eigenen Link gefolgt? Solltest du ma mmachen.
Gast
#4618139
kerle schrieb: > Scho ma deinem eigenen Link gefolgt? Solltest du ma mmachen Das Forum schneidet die schließende Klammer ab. Das ist unvermeidlich.
kerle schrieb: > Cache kann man gurgeln. Solltest du mal machen. Krümelkacker, ob das nun cache oder var auf dem Stack oder aus dem Register r17 genannt wird ändert doch nix am Sachverhalt mit volatile dem Compiler oder den Nachbarn anzuweisen die Variable immer neu einzulesen. kerle schrieb: > Scho ma deinem eigenen Link gefolgt? Solltest du ma mmachen. ja, für dich den Tip an deinem Leseverständnis zu arbeiten, wenns dir nicht wichtig ist werde Schaumschläger.
Joachim B. schrieb: > das die ISR die Variable immer liest und nicht welche aus dem Cache > nimmt. Arduinoquäler schrieb: > Käse. > > Es gibt beim Arduino (besser gesagt bei den AVR Controllern) > keinen Cache. kerle schrieb: > Cache kann man gurgeln. Solltest du mal machen. Wenn Ihr beiden Trolle nicht imstande seid, zu verstehen was er sagen wollte, solltet ihr euch auch nicht zu Wort melden.
Gast
#4618421
Joachim B. schrieb: > kerle schrieb: >> Cache kann man gurgeln. Solltest du mal machen. > > Krümelkacker, ob das nun cache oder var auf dem Stack oder aus dem > Register r17 genannt wird ändert doch nix am Sachverhalt mit volatile > dem Compiler oder den Nachbarn anzuweisen die Variable immer neu > einzulesen. Den tatsächlichen Sachverhalt im ATMega328p sollte man bei deiner Antwort aber schon kennen, sonst hinterläßt sie mehr Verwirrung als Klärung. > kerle schrieb: >> Scho ma deinem eigenen Link gefolgt? Solltest du ma mmachen. > > ja, für dich den Tip an deinem Leseverständnis zu arbeiten, wenns dir > nicht wichtig ist werde Schaumschläger. Danke an ufuf, der die Ursache für das Versagen des Links bei Anklicken aufgeklärt hat. Du hast es ja nicht mal in deinem eigenen Post bemerkt. Deine Antwort war einfach nur aufgeschlagener Schaum, dem man nur wegen den daraus folgenden richtigstellenden Posts Berechtigung einräumen könnte.
Gast
#4618435
> Krümelkacker > aufgeschlagener Schaum Es wäre ja zu schön gewesen, und eigentlich war alles bis zur 8. Antwort geklärt. Aber dann kommen die Rindviecher raus und meinen, sie müssten muhen. Wieder mal ein schönes Beispiel für die Sozialkompetenz in diesem Forum.
kerle schrieb: > Danke an ufuf, der die Ursache für das Versagen des Links bei Anklicken > aufgeklärt hat OK das mit den Links hier ist mir auch schon öfter aufgefallen und ja ich hatte meinen Link vor dem Einstellen hier angeklickt nur nicht nach dem Einstellen! (Nach der ersten Antwort kann man den "Fehler" nicht mehr korrigieren) Cowboy schrieb: > Wieder mal ein schönes Beispiel für die Sozialkompetenz in diesem Forum. stimmt!
Gast
#4618547
Cowboy schrieb: > Aber dann kommen die Rindviecher raus und meinen, sie müssten muhen. und die "Cowboys" muhen mit. > Wieder mal ein schönes Beispiel für die Sozialkompetenz in diesem Forum. Dazu sage ich jetzt mal nichts weiter.
Gast
#4618569
Hab schon besser kommentierten Quelltext gesehen. Wenn man häufig sich wiederholende Routinen benötigt wo sich nur EIN Datum ändert, kann man sicher einen besseren Algorithmus programmieren, der das alles zusammenfasst.
Gast
#4618579
Felix N. schrieb: > Keine Ahnung ob die lcd_print sachen in denn RAM schreiben: So sieht der > Code dazu aus: http://prntscr.com/bhuoh5 Was meinst, wozu es hier die Funktion "Dateianhang" gibt?
Das meiste RAM verbrauchen sicher die Text-Literale, die beim AVR-GCC ohne Überredung eben dort landen. Liegt an Harward vs. Neumann. So wird der String im FLASH abgelegt und nur zu Weiterverarbeitung ins RAM geladen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Eventuell hat die LCD-Lib ja eine lcd_printstr_P() Funktion, die direkt aus dem FLASH liest. Wenn nicht ist die nicht schwer zu bauen. Das Makro PSTR() sorgt dafür das das String-Literal im FLASH landet. Die ersten grob 700 Byte gehen in überflüssigen Puffern verloren, dann noch mal ΠxDaumen 1000 Byte. Es werden also statisch 300 Byte gebraucht. Wobei bedacht werden muß, das nichtstatisch sowas wie Stack zu den anfänglichen 100,3% noch dazukommt.
@Carl Drexler (jcw2) >Eventuell hat die LCD-Lib ja eine lcd_printstr_P() Funktion, die direkt >aus dem FLASH liest. Wenn nicht ist die nicht schwer zu bauen. Das Makro >PSTR() sorgt dafür das das String-Literal im FLASH landet. #include "i2c.h" #include "lcd.h" Das ist mit hoher Wahrscheinlichkeit diese Library, sei es das Original oder die von mir aufpolierte Version. Beitrag "Re: I2CLCD Library für HD44780 LCDs" Man ersetzte die Funktionsaufrufe lcd_printlc durch lcd_printlc_P Aus lcd_printlc(1, 1, "Wetterstation:"); wird lcd_printlc_P(1, 1, PSTR("Wetterstation:")); Weiterhin sollte man sprintf(readingTemp, "Temp: +%-.2f *C", currentTemp); durch sprintf_P(readingTemp, PSTR("Temp: +%-.2f *C"), currentTemp); ersetzen, damit landen die Formatstrings auch direkt im Flash, ohne zusätzlich RAM zu verschwenden. Und daß EIN einziger String für alle variablen Ausgaben reicht, wurde ja nun schon mehrfach gesagt. Der muss auch nicht länger als eine LCD-Zeile + Terminator sein, d.h. 21 Zeichen sind ausreichend. Man kann das Programm auch noch deutlich straffen, denn Programmierer sind nicht nur (tipp)faul, sie sind auch im allgemeinen Effizienzfanatiker ;-)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
Oder noch einfacher, wenn man ein bisschen Mathematik versteht ;-)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
Diese Arien an mehreren Stellen mit einem Dutzend if() else() kann man so leicht wegrationalisieren. Das spart nicht nur massiv Tipperei, sondern bringt vor allem Übersicht.
Danke Falk, solche Ausführlichkeit hat mein Touchscreens verhindert ;-)
Falk B. schrieb: > Aus > > lcd_printlc(1, 1, "Wetterstation:"); > > wird > > lcd_printlc_P(1, 1, PSTR("Wetterstation:")); > > Weiterhin sollte man > > sprintf(readingTemp, "Temp: +%-.2f *C", currentTemp); > > durch > > sprintf_P(readingTemp, PSTR("Temp: +%-.2f *C"), currentTemp); Hallo Falk. Nach diesen Änderungen im Code ist das alles nur am Buggen. Beim verändern des Delays der Temperatur wenn ich dort um -250 verkleinern will kommt dort "/no to change" in die Zeile. + 250 Addieren geht aber. Beim Delay für das Measurment funktioniert es problemlos.
Vielleicht mal mit einfacher Ausgabe eines "Flash-Strings" starten, um dieses Legosteinchen zu testen und dann erst alle potentiellen Fehler in einen Topf schmeißen. Bitte den Eingangssatz nicht falsch verstehen, aus deinem bisher geschriebenen sprechen nicht unbedingt Jahrzehnte Programierpraxis. Und selbst nach 35 Jahren muß man das manchmal, immer seltener vielleicht, genau so machen. Stück für Stück.
Gast
#4619550
Es scheint, als brächte er nicht nur seine Identitäten durcheinander.
S. Landolt schrieb: > Es scheint, als brächte er nicht nur seine Identitäten durcheinander. Nein eigentlich nicht. Das kam daher das ich vom Laptop dieses geschreiben habe und warum auch immer mit der E-Mail Adresse meines Kumpels einloggt. Denn ich habe mal was eingestellt bei gmail. Und seit dem meldet Mikrocontrollor.net mich immer mit seinen Account an. Der übriges auch µC programmiert. Zum Problem. Das Problem wahr das ich die ganze Zeit weiter sprintf mit PSTR genutzt habe aber nich sprintf_P
@Jan Hampel (jan_h865) >Nach diesen Änderungen im Code ist das alles nur am Buggen. Du bist doch gar nicht der OP des Threads? > Beim >verändern des Delays der Temperatur wenn ich dort um -250 verkleinern >will kommt dort "/no to change" in die Zeile. + 250 Addieren geht aber. >Beim Delay für das Measurment funktioniert es problemlos. Das Programm hat so oder so noch einen Bug. In der ISR macht man keine LCD Ausgaben! Erstens, weil das recht lange dauert und 2. weil sich das mit den LCD-Ausgaben im Hauptprogramm überschneiden kann! Dann kommt Mist raus, Stichwort reentrante Funktionen (die LCD-Funktionen sind es NICHT!). Die saubere Methode ist die Verwendung von Flags zwischen ISR und Hauptprogramm. https://www.mikrocontroller.net/articles/Interrupt#Steuersignale_zwischen_ISR_und_Hauptprogramm
Falk B. schrieb: > Du bist doch gar nicht der OP des Threads? Wie bereits gesagt. Das die Antwort von ein anderen Account erstellt wurde liegt daran das ich dieses Antwort vom Laptop ausgeschrieben habe. Und ich mich bei GMail angemeldet habe um mein Kumpel zu helfen bei Problem mit sein Mail Account. Mich aber vergessen abzumelden. Und weil ich mich bei Mikrocontrollor.net mit dem Google Konto anmelde. Hat er mich mit dem Account angemeldet. Weil ich mit diesen angemeldet wahr. Und mich mit ein eigenen(Felix Neumann) abgemeldet habe. Ich hatte mich nur vergessen um zu melden nachdem ich mein Kumpel geholfen habe. Falk B. schrieb: > Das Programm hat so oder so noch einen Bug. In der ISR macht man keine > LCD Ausgaben! Erstens, weil das recht lange dauert und 2. weil sich das > mit den LCD-Ausgaben im Hauptprogramm überschneiden kann! Dann kommt > Mist raus, Stichwort reentrante Funktionen (die LCD-Funktionen sind es > NICHT!). > Die saubere Methode ist die Verwendung von Flags zwischen ISR und > Hauptprogramm. Okay, werde das gleich mal lesen. Der Bugg wahr das ich die ganze Zeit mit sprint und PSTR gearbeitet habe und nicht mit sprint_P nach der Änderung auf sprint_P funktionierte alles wieder.
Felix N. schrieb: > Denn beim Rechner mit ca. 4 bis 16 GB RAM ist das auch > so zimmlich egal ob er jetzt 500 mb oder 1 gb belegt. Klingt nach jemandem der Chrome programmiert hat. Mit dieser besch..... Einstellung ist es kein Wunder das Anwendungen immer mehr Speicher fressen. Wenn man gezwungen ist, mit begrenztem Speicher zu programmieren lernt man, das diese Einstellung nicht die Beste ist.
Frank B. schrieb: > Klingt nach jemandem der Chrome programmiert hat. > Mit dieser besch..... Einstellung ist es kein Wunder das Anwendungen > immer mehr Speicher fressen. > Wenn man gezwungen ist, mit begrenztem Speicher zu programmieren lernt > man, das diese Einstellung nicht die Beste ist. Ja gut, aus Fehlern lernt man. Nun weis ich ja wie man es am besten nicht machen sollte um viel Speicher zu fressen :D Werde es mir nun angewöhnen, möglichstes RAM schonend zu programmieren.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.