Hallo liebe Community, Ich würde gerne mal eure Meinung hören. Ich programmiere seit letzten Jahr Oktober 2018 ein Aquarium Controller. Da mein Projekt ständig weiter entwickelt wird, wird nun auch langsam der Programmspeicher meines Mikrocontrollers knapp. Hatte damals schon den ATMega644 gegen ein ATMega1284P ausgetauscht. Da die 64K des 644 voll waren, nun der ATMega1284P hat 128K Flash und 16K SRAM. Im Moment sieht es bei mir so aus das ich 100K Flash benutze und 7Kb SRAM. Von den 128K gehen noch 4K für den Bootloader runter. Mein Projekt ist jedoch noch nicht fertig und ich habe noch einige Sachen die ich umsetzten möchte. Nun für ein Funktionsfähiges Menü verbrauche ich ungefähr 10-15KB Flash, RAM ist immer Unterschiedlich. Ein großer Teil des Flash Speicher geht für die Text drauf die ich auf dem ILI9341 TFT Display darstelle. Ich stelle mir nun aber die Frage was mache ich wenn der Speicher endgültig voll ist? Es gibt noch den ATMega2560 der den doppeln Speicher aufweist jedoch dafür nur den halben RAM von ATMega1284P. Naja und ist halt SMD aber das wäre das kleinste Problem. Oder vielleicht ein kompletter Umstieg auf ein ganzen anderen Prozessor wie zum Beispiel den STM32 den gibt es ja bis 2MB Flash und 512kB RAM. Aber mal ganz abgesehen das ich noch keinerlei Erfahrung mit dem STM32 habe. Das habe ich so im Moment an Peripherie angeschlossen: - TFT Display(ILI9341) - SD Karte(FatFs) - Netzwerkchip ENC28J60 - Externes EEPROM - RTC(MCP7940M) - Rotary Encoder(Bedienung) Geplant ist noch: - Akustischer Signalgeber - Fehlerspeicher(SD Karte) - SMTP(nicht sicher) - USV(nicht sicher) Was würdet ihr machen wenn es bei euch so wäre. Upgrade auf ATMega2560 oder kompletter Wechsel auf einen Prozessor zb. STM32? Schönen Sonntag noch Lg
Gast
#5965741
Wenn du eh eine SD-Karte planst eventuell Texte auslagern? (Oder extern flash) Kannst dann immerhin auf der bekannten Plattform bleiben
Ist denn der Stromverbrauch oder besondere Echtzeitfähigkeit ein wichtiges Kriterium? Falls nicht, hätte ich da schon einen Raspi Zero W genommen ;)
Da müsste man den Code sehen.. wenn das so schnell voll ist für so eine einfache Aufgabe muss da wohl die Arduino IDE am Werk sein? Bei Arduino und anderen normalen Librarys kann man eine Menge optimieren/abspecken.. EDIT: das meisste müsste der ENC28J60 ausmachen.. da sollte man heutzutage lieber den W5100 oder nen ESP8266 nehmen. ( beim ENC baust Du die kommunikation im Atmega zusammen, beim w5100 macht das der w5100 schon selbst) Welche IDE wird denn benutzt?
Mein Vorschlag: https://www.olimex.com/Products/OLinuXino/A64/A64-OLinuXino/open-source-hardware Das erschlägt sehr viel von dem, was Du selber mühselig programmieren musstest: - TFT Display, wahlweise mit Touch direkt anschließbar, z.B. das hier https://www.olimex.com/Products/OLinuXino/LCD/LCD-OLinuXino-7/open-source-hardware - SD-Karte wird direkt vom Linux unterstützt - Gigabit Ethernet ist direkt da. - EEPROM brauchst Du wahrscheinlich nicht mehr, ist aber leicht anschließbar - RTC ist bereits drin - Encoder sollte kein Problem sein, aber den könntest Du eventuell mit Toucheingabe besser in Software implementieren - Akustischer Signalgeber: Audio 3.5" Stereo-Klinke vorhanden, Beeper kann einfach über GPIO angeschlossen werden - SMTP: installier einfach einen postfix auf dem Linux, und gut ist. - USV: LiPo-Akku anschließbar. Du wirst das meiste sofort da haben, ohne groß basteln zu müssen. fchk PS: Einen Pi würde ich nicht nehmen, da verlierst Du einfach zu viele IOs, wenn Du ein RGB-TFT anschließen willst. Die Peripherie ist beim PI viel schlechter als bei Alternativprodukten.
Gast
#5965752
Frank K. schrieb: > Mein Vorschlag: Booaaahhhh, einen Quad Core für die Aquariumsteuerung. Das ist wirklich die optimale Lösung!
Ver Wunderter schrieb: > Frank K. schrieb: >> Mein Vorschlag: > > Booaaahhhh, einen Quad Core für die Aquariumsteuerung. > > Das ist wirklich die optimale Lösung! Ja und? Für die AVR-Lösung wird der Fragesteller sicher insgesamt mehr bezahlt haben als die 36 Oiro, die Olimex für das Board aufruft. fchk
Wie wäre denn ein XMega384? Neben mehr Flash gibt dazu bis zu 60MHz (inoffiziell 64MHz) und zusätzliche Ports, SPIs, I2Cs, UARTs, .....
Hallo, micha schrieb: > Wenn du eh eine SD-Karte planst eventuell Texte auslagern? SD Karte ist schon drin, habe ich auch schon gedacht jedoch kann man die SD Karte aus dem System entfernen um zb. den Fehlermeldungen am PC auslesen zu können. Die Grundfunktionen sollen erhalten bleiben. Daher fiel diese Auswahl weg. Philipp K. schrieb: > Arduino IDE am Werk sein? Nein, programmiere das Ding in Atmel Studio 7 in C. Philipp K. schrieb: > Bei Arduino und anderen normalen Librarys kann man eine Menge > optimieren/abspecken.. ENC28J60 -> Eine Library von Tuxgraphics welche vom Inhalt her größten Teils auf der Arduino EtherShield und EtherCard Lib basiert. ILI9341 -> Hat Ähnlichkeit mit der Adafruit Lib SD Karte -> FatFs von ELM ChaN Rotary Encoder -> kommt aus diesen Forum. Andere Sachen wie Kommunikation wie I2C, SPI, USART, EEPROM sind selbst geschrieben Philipp K. schrieb: > das meisste müsste der ENC28J60 ausmachen Ja ein großen Anteil macht der ENC aus mit der SD Karte zusammen. Der ENC28J60 ist halt im rohen zustand Dumm wie Brot. TCP/IP HTTP ist halt in Software gelöst. Philipp K. schrieb: > lieber den W5100 oder nen ESP8266 nehmen. Muss mal schauen ob es den W5100 in einzel Ausführung gibt ohne Arduino Shield. Frank K. schrieb: > Das erschlägt sehr viel von dem, was Du selber mühselig programmieren > musstest: Ich hatte am Anfang ein PI in der Hand gehabt, habe mich letzte endlich aber für den AVR entschieden da dich das ganze gerne selber "klassisch" programmieren wollte. Lg
Gast
#5965776
Felix N. schrieb: > Muss mal schauen ob es den W5100 in einzel Ausführung gibt ohne Arduino > Shield. Gibt es. Ganz handlich ... https://www.ebay.de/itm/Mini-W5100-Arduino-LAN-Ethernet-Shield-Network-Module-Board-TCP-IP/223614689695?hash=item341079619f:g:6~wAAOSw241YXMLw
W5100Usa schrieb: > Gibt es. Ganz handlich ... > > Ebay-Artikel Nr. 223614689695 Ah okay du warst schneller als ich :) Danke Werde ich mal bestellen und ausprobieren. Crazy H. schrieb: > Wie wäre denn ein XMega384? Hmm, hörst sich ja auf im ersten Moment nicht schlecht an, weißt du ob es möglich ist mit bestehen ATMega Kenntnissen den XMega programmieren zu können. Oder ist der von der Struktur komplett anderes? Mfg
Gast
#5965786
Eventuell macht hier ein Wechsel auf ein ganz anderes Kaliber Sinn: Raspberry Pi Wobei ich mich schon frage, wie man 128kB für ein Aquarium voll bekommt. Das muss man erstmal schaffen.
Gast
#5965792
Felix N. schrieb: > Ah okay du warst schneller als ich :) Danke Wenn du erst mal die Last des Ethernet- und TCP-Handling vom ENC weg hast wirst du schon mal eine ganze Menge Speicher gewonnen haben. Und falls du bis jetzt Arduino-Klassen verwendet hast und auf "normale" Programmierung umsteigst noch mal eine ganze Menge. ATXmegas sind meines Wissens nach nicht vom Arduino Environment unterstützt.
Gast
#5965800
Felix N. schrieb: > ob > es möglich ist mit bestehen ATMega Kenntnissen den XMega programmieren > zu können. Oder ist der von der Struktur komplett anderes? Die Register heissen ein bisschen anders und es sind viel mehr, aber sonst kein grosser Umschwung.
W5100Usa schrieb: > Wenn du erst mal die Last des Ethernet- und TCP-Handling vom > ENC weg hast wirst du schon mal eine ganze Menge Speicher > gewonnen haben. Ich habe kurz die Netzwerk Initialisierung und Anfragen auskommentiert. Mit ENC verwende ich Aktuell: Program Memory Usage : 99750 bytes 76,1 % Full Data Memory Usage : 7001 bytes 42,7 % Full Und ohne: Program Memory Usage : 85646 bytes 65,3 % Full Data Memory Usage : 5746 bytes 35,1 % Full W5100Usa schrieb: > Und falls du bis jetzt Arduino-Klassen verwendet hast und > auf "normale" Programmierung umsteigst noch mal eine ganze > Menge. Ich nutze kein Arduino IDE, Ich habe mit Header und C Dateien. W5100Usa schrieb: > ATXmegas sind meines Wissens nach nicht vom Arduino > Environment unterstützt. Muss es ja auch nicht. Ich kann den ATXMega in Atmel Studio ja als Prozessor auswählen. Lg
Gast
#5965833
Wenn du auf einen ESP8266 oder ESP32 wechselst, hast du Flash ohne Ende und das Netzwerk Interface auch schon dabei. Allerdings sind deren I/O Pins nicht ganz so flexibel einsetzbar, wie du es von deinem AVR gewohnt bist. Eine Kombination aus einem AVR für die eigentliche Steuerung + einem ESP 8266 für das Benutzerinterface wäre vielleicht eine praktikable Option für Dich, wenn du bei Mikrocontrollern bleiben möchtest.
Gast
#5965838
Felix N. schrieb: > Ich habe kurz die Netzwerk Initialisierung und Anfragen auskommentiert. Ob du damt alles wegbekommst? Dazu müsste dein Linker schon sehr intelligent sein alle unbenutzten Funktionen zu detektieren und herauszunehmen. Ich denke um zu einem genaueren Ergebnis zu kommen müsstest du wirklich die Ethernet- und TCP Lib voll herausnehmen. Aber es käme auch Code dazu: die W5100 Einbindung kostet natürlich trotzdem was an Programm-Speicher und RAM ....
Felix N. schrieb: > Ein großer Teil des Flash Speicher geht > für die Text drauf die ich auf dem ILI9341 TFT Display darstelle. Dann machst Du irgendwas grundlegend falsch. Mußt Du wirklich ganze Romane an Text anzeigen? Was belegen denn die vielen Zeichensätze allein? In der Regel reicht ein Font in 3 Größen völlig aus.
Gast
#5965881
> Ich habe kurz die Netzwerk Initialisierung und Anfragen auskommentiert. > > Mit ENC verwende ich Aktuell: > Program Memory Usage : 99750 bytes 76,1 % Full > Data Memory Usage : 7001 bytes 42,7 % Full > > Und ohne: > Program Memory Usage : 85646 bytes 65,3 % Full > Data Memory Usage : 5746 bytes 35,1 % Full Sehr gut. Nun machst die selbe Datenerhebung für jeden anderen Teilbereich deines Aquariumprogramms auch und führst Buch. (wenn deine FW sauber modularisiert ist, solltest du bis runter auf eine "leere" main(..)-Funktion gelangen. Wobei: man kann alles übertreiben...) Dann steckst Du Hirnschmalz erstmal in die 3 Speicherintensivsten Bereiche, mit Fokus auf Verkleinerung. Danach vergleichst Du die Bereiche untereinander und suchst Code-Doppelspurigkeiten. Da wo's nur ähnlich ist arbeitest solange daran rum bis es gleich wird. Dann ausfaktorieren . Wenn Du echt viele Präsentationstexte (Anzeige) hast, überlege ob ALLE diese in was anderem als ASCII codierbar wären. Schliesslich belegt 1 Buchstabe 1Byte, ASCII hat aber nur 127 wovon du auch nicht alle benötigst. Code welcher das dann handhaben würde, müsste dann aber die Platzersparnis nicht auffressen... (ich habe in Konditional geschrieben...) Viel Erfolg!
Wenn Du ein intelligentes Display verwendest hast Du plötzlich eine Menge Speicher über, Touch läuft dann nebenbei und Anzeige und Bedienung werden viel flüssiger, weil die Bildrate sehr viel höher sein kann bei einem Bruchteil an zu übertragenden Daten. Sowas wie das hier: https://www.matrixorbital.com/ftdi-eve/eve-bt815-bt816/eve3-43g Das hat Zeichensätze eingebaut und einen FLASH Chip den man mit u.a. Bildern, UTF-8 Zeichensätzen und Texten füllen kann. Die Kapazitiv-Touch Version habe ich ausgewählt, weil Resistiv-Touch im Vergleich einfach nur eklig ist. Resistiv-Touch werde ich mir hoffentlich nie wieder antun müssen. Die haben eine SPI Schnittstelle die mit 3,3V Pegeln läuft und benötigen ein 3,3V Netzteil, je größer das Display, desto mehr Strom. Das sind so ~200mA bei 3,5", ~300mA bei 4,3", ~500mA bei 5" und ~750mA bei 7". Ja, die Größen habe ich alle schon mit AVR benutzt, bei 40+ Bildern pro Sekunde hat der Controller auch noch nicht wirklich was zu tun. Aber sowas wie eine Animation für z.B. eine Pumpe läuft schön flüssig, so mit Drehung des Bildes durch den Grafik-Chip.
BerAVRter schrieb: > Sehr gut. Nun machst die selbe Datenerhebung für jeden anderen > Teilbereich deines Aquariumprogramms auch und führst Buch. Man könnte aber auch die Größe der einzelnen Programmteile im MAP-File ablesen.
Gast
#5965898
Ein Klassiker: Wenn du Strings einfach "normal" (wie beim PC) in Anführungsstriche schreibst, dann belegen sie doppelt Speicher, nämlich Flash und RAM. Wenn du die gleichen Strings in mehreren Quelltext-Dateien hast, dann wird auch Speicherplatz vergeudet. Kennst du die Makros PSTR und PROGMEM?
Felix N. schrieb: > Frank K. schrieb: >> Das erschlägt sehr viel von dem, was Du selber mühselig programmieren >> musstest: > > Ich hatte am Anfang ein PI in der Hand gehabt, habe mich letzte endlich > aber für den AVR entschieden da dich das ganze gerne selber "klassisch" > programmieren wollte. Was heißt für Dich "klassisch"? Unter Unix haben schon Generationen vor Dir in C und C++ entwickelt. Und solche Sachen wie TCP/IP, USB, Filesysteme usw. muss man heute nicht mehr selber entwickeln, das kann man ruhig einem Betriebssystem überlassen. Das ist jedenfalls der Weg, über den Du mit minimaler Arbeit das Maximum an Möglichkeiten bekommst. Alternativ: http://www.ti.com/tool/EK-TM4C1294XL Da bekommst Du auch eine ganze Menge an Rechenleistung und Speicher, dazu 10/100 MBit Ethernet MAC+PHY im Chip, USB und was man sonst noch alles so braucht. Und dazu gibts ein schönes RTOS und eine umfangreiche Treiberbibliothek. fchk
Gast
#5965908
Hm. Wieviel Speicher belegen denn die Texte? Es gibt Techniken um den Speicher dafür zu verringern. Angefangen von Kompression bis zur Zerlegung in kleinere Textbautsteine. Ob sich das im konkreten Fall lohnt, hängt natürlich von der Menge an Text ab, denn im Austausch ist Code für die Dekompression bzw. das zusammensetzen der Textbausteine nötig. Eine etwas schwieriger zu realisierende Möglichkeit ist, die Texte zu kürzen bzw. entfallen zu lassen. Schwieriger, weil es dazu nötig ist, gewisse Wünsche und Vorstellungen zu verändern. Dabei steht man sich mitunter selbst im Weg. :-)
Gast
#5965922
Theor schrieb: > Eine etwas schwieriger zu realisierende Möglichkeit ist, die Texte zu > kürzen bzw. entfallen zu lassen. Werden denn überhaupt so viele Texte verwendet, bzw. können Deine Fische lesen? Ich vermute eher, ungeschickte Programmierung uneinheitlicher Menüs benötigt zu viel Speicher. Um nicht den µC komplett zu wechseln, würde ich Funktionen in einen 2. AVR auslagern und über IIC ankoppeln. Der Hauptprozessor erledigt dabei die Bedienung. Genaueres kann man nur sagen, wenn man sieht, was jetzt vorhanden und wie es umgesetzt ist.
Es gibt auch neuere AVRs mit deutlich mehr Speicher. Sie lösen das Problem der Optimierung nur bedingt ;). Im wirklichen Leben wäre das der Gau, da man sich im Vorfeld keine Gedanken über die richtige Plattform für sein Projekt gemacht hat. Der ESP32 wäre die Lösung allerdings muss dein Code auch für ein OS geeignet sein. Das heißt sich mit Threads und einem völlig anderen Framework beschäftigen zu müssen. Wie viel Aufwand es ist den Code auf einer anderen Plattform zum laufen zu bringen hängt von deinem Programmierstil ab.
Gast
#5965936
Felix N. schrieb: > Da mein Projekt ständig weiter entwickelt wird, [...] > Das habe ich so im Moment an Peripherie angeschlossen: > - TFT Display(ILI9341) > - SD Karte(FatFs) > - Netzwerkchip ENC28J60 Schau nach vorne, mach einen Plattformwechsel, aber richtig. Vermutlich tust Du Daten loggen und die Daten irgendwie mit Netzwerk abrufbar machen oder irgendwohin speichern etc. Es wird nicht lang gehen, und Du willst evtl. schöne Webseiten mit Messwerten etc. darstellen. Vielleicht soll das auch per MQTT etc. an einen Cloud-Hoster angebunden werden etc. Tu' Dir den Gefallen und rüste auf. Ich vermute, es wird Dir weiterhin viel Spaß machen neue Funktionen einzubauen und auszuprobieren. Lass Dir den Tag von Kleingeistern nicht versauern. Die Zeit ist zu Schade, um sich mit Beschränkungen der Plattform rumärgern zu müssen. - Willst Du mehr in Richtung Netzwerk und Daten machen, nimm etwas in der Raspi-Klasse. - Wenn das Netzwerk wirklich nur ganz trivial bleiben soll, nimm einen richtig fetten Controller mit viel RAM und richtig Flash und mehr Bits. Das Aquarium selbst benötigt so sehr viel mehr Energie und Wartung, da brauchst Du nicht am Controller sparen. Nicht kleckern, sondern klotzen.
Gast
#5965939
Felix N. schrieb: > - SMTP(nicht sicher) Ach, das hatte ich überlesen. Nimm einen Raspi. Die Wahrscheinlichkeit dass Du zwingend TLS brauchst, ist hoch.
Gast
#5965943
Erfahrener Entwickler schrieb: > Das Aquarium selbst benötigt so sehr viel mehr Energie und Wartung, da > brauchst Du nicht am Controller sparen. Als ob der Preis des µC das Problem wäre ;-) > Tu' Dir den Gefallen und rüste auf. Ja was denn nun: aufrüsten oder umrüsten?
Durch geschickte Programmoptimierungen kann man immer ein paar Bytes heraus schinden (z. B fixed point statt floating point nutzen) Kann man die Texte oder Fonts komprimiert abspeichern? (z. B. nur 7 bit statt 8 verwenden, würde schon 12,5% sparen) Hast du denn schon heraus gefunden, was den meisten Speicher braucht? Gruß Roland
Gast
#5965973
Vielleicht hat er die Texte alle als Bitmap abgelegt. Felix, bist du noch da? Ich glaube es wäre Sinnvoll, wenn du dich an der Diskussion beteiligen würdest. Ansonsten können wir unser Urteil gegen Dich in Abwesenheit sofort fällen :-)
Gast
#5965976
Felix N. schrieb: > Da mein Projekt ständig weiter entwickelt wird, wird nun auch langsam > der Programmspeicher meines Mikrocontrollers knapp. Hatte damals schon > den ATMega644 gegen ein ATMega1284P ausgetauscht. Hossa, du schaffst es, 128k Flash und 16k SRAM mit der Steuerung eines Aquariums zu füllen? Das ist doch nicht etwa ein Aquarium mit der Komplexität etwa von dem in Manly Beach, Sydney, NSW, Australia? Weil: ich kann mir kaum vorstellen, dass man sich SOWAS mal eben zu Hause hinstellen kann... Wie auch immer: die Jungs dort kommen jedenfalls mit ca. 4k SRAM und 48K ROM klar. SPS und HMI zusammengezählt... Mir scheint, du musst ein wenig an deiner Programmierkompetenz arbeiten, statt nach mehr Hardware zu schreien...
W5100Usa schrieb: > Ob du damt alles wegbekommst? Nein ich habe die #includes ja nicht auskommentiert. Es sollte ja auch nur verdeutlichen das der ENC28J60 circa. 20Kbyte an Speicher frisst. W5100Usa schrieb: > die W5100 Einbindung kostet > natürlich trotzdem was an Programm-Speicher und RAM .... logisch. Peter D. schrieb: > Mußt Du wirklich ganze Romane an Text anzeigen? Sorry, habe mich vertan ich die Texte liegen im RAM und nicht im Flash. Ich habe im Moment ja nur die Grundlegende Menüs fertig(Hauptmenü, Uhrzeit, Co2, pH Elektrode, SD Karte, Netzwerk und Lichtsteuerung) die Texte die da drin sind brauche ich so wie sie sind. BerAVRter schrieb: > Dann steckst Du Hirnschmalz erstmal in die 3 Speicherintensivsten > Bereiche, mit Fokus auf Verkleinerung. Ich weiß zb. das die ENC Lib auch UDP und NTP vorhanden sind und auch benutzt werde diese Funktionen mal entfernen da ich diese nicht verwende und auch nicht vor habe zu verwenden. Rudolph R. schrieb: > intelligentes Display Hört sich auf jeden Fall interessant an, gut die FPS bei dem ILI9341 mit 8 MHz Clock Speed sind jetzt nicht sonderlich hoch aber ich hatte bis jetzt noch nicht vor Grafiken zu verwenden. Aber werde ich auf jeden Fall im Hinterkopf behalten. m.n. schrieb: > Ich vermute eher, ungeschickte Programmierung uneinheitlicher Menüs > benötigt zu viel Speicher. Ich habe jetzt mal mein letztes Menü angehängt in diesem wird die Lichtsteuerung gehandelt. m.n. schrieb: > Um nicht den µC komplett zu wechseln, würde ich Funktionen in einen 2. > AVR auslagern und über IIC ankoppeln. Der Hauptprozessor erledigt dabei > die Bedienung. Also würde ein Prozessor als Externer Speicher arbeiten? Würde SPI nicht besser sein weil dort höhere Geschwindigkeiten erreicht werden als max. 400KHz bei I2C? Erfahrener Entwickler schrieb: > Die Wahrscheinlichkeit > dass Du zwingend TLS brauchst Ja deswegen steht da auch hinter (nicht sicher) ... Roland P. schrieb: > Hast du denn schon heraus gefunden, was den meisten Speicher braucht? Ja der ENC und die SD Karte. Der ENC ca. 20Kb die SD ca. 15kb. Und der Rest geht wahrscheinlich auf die sprintf's drauf, habe gehört die sollen auch nicht so speicher Schonend sein. Mfg
Gast
#5966002
Ui. Menues zu Fuß programmiert, wie es aussieht. Das braucht natürlich Code noch und nöcher. Und häufig doppelter Code. (Vermutlich z.T. durch die Optimierung abgefangen). Und, wie zu vermuten war, reichlich mehrfache Kopieen von Texten. Das sowas sich so (aus-)wächst ist bei einem Anfänger der dann noch dieses oder jenes Feature haben will normal (und auch nichts Schlimmes), Aber, das macht die Entwicklung auf die Dauer immer schwieriger und schwieriger. Also, falls Dein einziges großes Projekt (im Leben) überhaupt sein soll, dann lass es so und hör auf, wenn der FLASH-Speicher voll ist. Ansonsten, gehe den nächsten Schritt zur Meisterschaft und überarbeite den Code gründlich.
Gast
#5966028
Felix N. schrieb: > die Texte liegen im RAM und nicht im Flash Warum? Schau Dir mal in der Doku der AVR C Library die Beschreibung der PSTR und PROGMEM Makros an. Ich habe dafür zwar ein -1 bekommen, aber ich bin zuversichtlich, dass du damit eine große Menge RAM frei bekommen wirst. Statt sprintf nutzt du dann sprintf_P.
Beitrag #5966040 wurde von einem Moderator gelöscht.
Felix N. schrieb: > Von den 128K gehen noch 4K für den Bootloader runter. Optiboot 512 Byte https://github.com/Optiboot/optiboot woher kommen deine 4K?
Theor schrieb: > Das sowas sich so (aus-)wächst ist bei einem Anfänger der dann noch > dieses oder jenes Feature haben will normal (und auch nichts Schlimmes), > Aber, das macht die Entwicklung auf die Dauer immer schwieriger und > schwieriger. Hallo, Gut das ich ein guter Programmier bin habe ich nie gesagt, ich habe mir mein gesamtes Programmier wissen aus YouTube Videos, Code Schnippels, teilweise Bücher und Foren zusammen gesammelt. Habe Beruflich nix damit zutun. Nur Hobby. Das was funktioniert hat habe ich am Anfang erst mal auch nicht mehr verändert. Warum? Es hat ja funktioniert da habe ich mir kein Kopf gemacht ob dieses nun maximal Optimiert ist oder nicht. Gut das mag vielleicht nach einer schlechten Einstellung klingen. So soll es aber nicht rüber kommen. Ich bin jeder Zeit bereit aus meinen Fehlern zu lernen und diese zu dann zu verhindern/verbessern. Schließlich siehst Du den Code ja ganz anderen Augen als Ich, mag vielleicht an deiner Erfahrung liegen. Stefanus F. schrieb: > Warum? Schau Dir mal in der Doku der AVR C Library die Beschreibung der > PSTR und PROGMEM Makros an. Ich habe dafür zwar ein -1 bekommen, aber > ich bin zuversichtlich, dass du damit eine große Menge RAM frei bekommen > wirst. Statt sprintf nutzt du dann sprintf_P. Hi, Wenn ich mich nicht irre werden Texts die man direkt übergibt im RAM ausgelagert. Ich kenne die PSTR und PROGMEM Makros. Ich weiß auch das Sie Texte in den Flash auslagern und so Platz im RAM Schaffen. Nur ich habe 16K RAM und belege 7K zurzeit. Wenn die die ganzen Texte in den Flash Schiebe wird mein Programmspeicher doch noch weniger. Und gerade der Flash Speicher ist ja mein Problem. Oder habe ich jetzt da was falsch verstanden? MaWin schrieb im Beitrag #5966040: > Poste mal bitte deinen Sourcecode Hi, ich habe jetzt mal eine rar Datei angehängt wo mein ganzer Source Code drin ist. Mfg
Gast
#5966078
Felix N. schrieb: > Ich bin jeder Zeit bereit aus meinen Fehlern zu lernen Ich hab nur kurz in den Anzeigecode geschaut, aber was mir sofort auffaellt ist der Mangel an Abstraktion bzw. die Wiederholung von (fast oder) identem Code, e.g.
1 | |
2 | |
Das wird dann noch gemacht mit nur anderem Text. Du findest sowas zuhauf im Code. Da kannst du genug einsparen. leo
Und Du benutzt float. Das ist meistens vermeidbar. Wenn ich Bruchteile von Volt messen will, dann nehme ich einfach die passende Einheit. Nicht Volt, sondern mV oder uV. Zack, schon kann ich mit Ganzzahlen rechnen. Floats brauchst DU nur, wenn Du einen hohen Dynamikbereich brauchst, d.h. gleichzeitig sehr kleine und sehr große Zahlen und dazwischen 10 oder mehr Zehnerpotenzen. Ohne float wird auch stdio sehr viel kleiner. Das ist mir nach 30s aufgefallen. Auf dem vomn mir vorgeschlagenen Olimex-Board wäre das völlig egal. Da brauchst Du Dich auch nicht um Menüs oder Strings im ROM zu kümmern. Als Programmierumgebung nimmst Du Qt, das nimmt Dir alles ab. In der richtigen Welt würde niemand mehr den von Dir gewählten Weg nehmen. Zu viele Einschränkungen, zu aufwändig zu programmieren, zu aufwändig zu warten. Schlicht zu teuer in der Entwicklung. fchk
Felix N. schrieb: > Wenn ich mich nicht irre werden Texts die man direkt übergibt im RAM > ausgelagert. Ich kenne die PSTR und PROGMEM Makros. Ich weiß auch das > Sie Texte in den Flash auslagern und so Platz im RAM Schaffen. Nur ich > habe 16K RAM und belege 7K zurzeit. Wenn die die ganzen Texte in den > Flash Schiebe wird mein Programmspeicher doch noch weniger. Und gerade > der Flash Speicher ist ja mein Problem. Oder habe ich jetzt da was > falsch verstanden? Die Texte sind doch sowieso im Flash. Müssen sie auch. Von wo anders als auch dem Flash sollen sie denn nach dem Einschalten herkommen? Klar, aus einem .data-Segment, das von der Compiler-Runtime noch vor main() ins RAM kopiert wird. Und DAS ist vermeidbar. Ja, nun hast DU auch eine Architektur (AVR) gewählt, wo Programm- und Daten in getrennten Adressräumen liegen. Bei anderen Architekturen wie ARM oder MIPS (PIC32) oder x86 ist das nicht so. Bei AVR, 8051 und 8-Bit PIC muss halt der Programmierer entsprechend Grips in der Birne haben. fchk
Gast
#5966106
Frank K. schrieb: > Und Du benutzt float. Das ist meistens vermeidbar. Ja, das stimmt. Aber es ist nur ein Funktionsaufruf, traegt kaum zur Codegroesse bei, nur viel zur Laufzeit. leo
Gast
#5966110
leo schrieb: > Mangel an Abstraktion Rein zufaellig, aber wohl exemplarisch:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
leo
Frank K. schrieb: > Nicht Volt, sondern mV oder uV ich nehme cV centi Volt oder dV dezi Volt als Ganzzahl und füge das Komma per Stringmanipulation ein.
mal als Beispiel..
im code sind 34 mal "ili9341_drawRect(277, 17, 36, 32,BLABLA); und auch
andere doppelt und dreifach..
dann lieber komprimieren mit:
void RechteckBLA(uint32_t color){
ili9341_drawRect(277, 17, 36, 32,color)
}
an der richtigen stelle dann ersetzen rechteckBLA(ORANGE);
Gast
#5966123
leo schrieb: > Rein zufaellig, aber wohl exemplarisch: > ...... Exemplarische Korinthenkackerei.
Gast
#5966124
Felix N. schrieb: > Theor schrieb: >> Das sowas sich so (aus-)wächst ist bei einem Anfänger der dann noch >> dieses oder jenes Feature haben will normal (und auch nichts Schlimmes), >> Aber, das macht die Entwicklung auf die Dauer immer schwieriger und >> schwieriger. > > Hallo, > > Gut das ich ein guter Programmier bin habe ich nie gesagt, > [...] Und ich habe auch nicht behauptet, dass Du das von Dir gesagt hättest. :-) Darum ging es mir nicht. Du brauchst Dich auch nicht zu rechtfertigen. Es geht darum, wie bestimmte Dinge entstehen. Es geht um Erklärungen, nicht um Vorwürfe. Es darum, was die Folge bestimmter Vorgehensweisen ist und wie man, meiner Ansicht nach, reagieren sollte, wenn einem diese Folgen auf die Füsse fallen. Mehr nicht. > Das was funktioniert hat habe ich am Anfang erst mal auch nicht mehr > verändert. Warum? > Es hat ja funktioniert da habe ich mir kein Kopf > gemacht ob dieses nun maximal Optimiert ist oder nicht. Gut das mag > vielleicht nach einer schlechten Einstellung klingen. So soll es aber > nicht rüber kommen. Im Prinzip ist das sinnvoll. Aber es macht doch einen Unterschied, ob man weiß, dass es bestimmte Entwurfsmuster gibt und ob man zur rechten Zeit das Entwurfsmuster wechselt oder ob man das nicht weiß oder nicht wechselt. > Ich bin jeder Zeit bereit aus meinen Fehlern zu lernen und diese zu dann > zu verhindern/verbessern. Schließlich siehst Du den Code ja ganz anderen > Augen als Ich, mag vielleicht an deiner Erfahrung liegen. Gerade so möchte ich von Dir verstanden werden. Ich gebe Dir Urteile über Deinen Code ab - nicht über den Wert Deiner Person. (Von Deiner Einstellung habe ich ja auch garnichts geschrieben. Das mag aber in manchen Fällen durchaus ein sinnvolles Thema sein. Sagt aber immer noch nichts über den Wert Deiner Person). Also nochmal in Kürze, da Du darauf nicht eingangen bist: 1. Benutze datengetriebene Menuesysteme, wenn der explizite Code für jeden Menuepunkt groß wird. Ab, über den Daumen gepeilt, mal so 5 bis 8 Menupunkten sind datengetriebene Systeme meist kleiner als "zu Fuß" programmierte. Das äussert sich auch darin, dass Du häufig gleiche Sequenzen von Funktionsaufrufen hast. Siehe: Beitrag "Re: ATMega Flash wird langsam knapp. Upgrade o. Plattformwechsel?" 2. Da Du sehr häufig gleiche Texte oder Textteile verwendest, kannst Du Speicher sparen, wenn Du diese Texte nicht als Literale im Code verwendest, sondern nur einmal hinschreibst und anschliessend Zeiger darauf verwendest. In diesem Zusammenhang solltest Du wissen, dass Texte in jedem Fall im Flash gespeichert werden, denn von irgendwo müssen sie ja auch dann herkommen, wenn sie in das RAM geschrieben werden (also kopiert werden). Insofern ist PSTR resp. PROGMEM sinnvoll. Zusätzlich: Ich habe das vorher nicht erwähnt. 3. Vermeide die Verwendung von Literalen, insbesondere von Zahlenliteralen im Code. Halte sie lieber an einer zentralen Stelle, falls möglich. Gleiches gilt für String-Literale (mal unabhängig davon, ob Du nun ein Menuesystem verwendest). So sind Änderungen, insbesondere wenn wegen der Änderung eines Wertes auch andere Werte geändert werden müssen, einfacher. Ich hoffe ich habe meine Absichten und Haltung Dir gegenüber klarer gemacht und Du entscheidest Dich dafür, meine Einwände zu überdenken. Jedenfalls, auch wenn Du es nicht tust, wünsche ich Dir Erfolg.
Gast
#5966130
Stefanus F. schrieb: > Wenn du auf einen ESP8266 oder ESP32 wechselst, hast du Flash ohne Ende > und das Netzwerk Interface auch schon dabei. Ich habe einen Aufbau mit Arduino AT328 und ENC28J60, der im Prinzip läuft, aber das RAM nicht mehr ausreicht. Die Idee war, auf den ESP32 zu wechesln. Aber: Jegliche Suche nach Libraries für Ethernet als UDP-Server endete ohne Erfolg. Du schreibst immer, wie toll Ethernet vom ESP unterstützt würde, nachvollziehen kann ich das nicht.
Manfred schrieb: > wie toll Ethernet vom > ESP unterstützt würde, nachvollziehen kann ich das nicht. mindestens jede ENC oder W5100 Arduino library kann das.. praktischerweise ist das bestimmt Via WLAN gemeint.
Gast
#5966133
W5100Usa schrieb: > Exemplarische Korinthenkackerei. Aha, du hast dir den Code also angeschaut? leo
Frank K. schrieb: > Und Du benutzt float. Das ist meistens vermeidbar. Diese Angst ist unbegründet, die float Lib kostet nur einmal Flash (~1kB ohne printf, scanf). Bei einem AVR mit 4kB Flash würde ich überlegen, aber nicht bei 128kB.
Gast
#5966244
Felix N. schrieb: > Wenn die die ganzen Texte in den > Flash Schiebe wird mein Programmspeicher doch noch weniger. Nein. Denn ohne PSTR und PROGMEM müssen sie beim Start vom Flash ins RAM kopiert werden. Wo sollen die Texte sonst liegen, in den Elkos?
Felix N. schrieb: > SD Karte ist schon drin, habe ich auch schon gedacht jedoch kann man die > SD Karte aus dem System entfernen um zb. den Fehlermeldungen am PC > auslesen zu können. Die Grundfunktionen sollen erhalten bleiben. Daher > fiel diese Auswahl weg. Dann schliess parallel am SPI noch einen kleinen SPI-Flash-Baustein an. Kein Grund für reine Daten einen uC mit größerem Flash zu nehmen. Gibts für wenig Geld bis in MByte-Größen und kannst du einfach im Programm von der SD-Karte aus befüllen.
PSTR wird doch schon benutzt.
Theor schrieb: > Zusätzlich: Ich habe das vorher nicht erwähnt. > > 3. Vermeide die Verwendung von Literalen, insbesondere von > Zahlenliteralen im Code. Halte sie lieber an einer zentralen Stelle, > falls möglich. Das ist Quatsch bzw. stimmt nur für C-Strings (bei AVR). Zahlliterale (als core-constant) werden vom Compiler immer direkt in den generierten Code eingebaut.
Wenn Du doch sowieso schon ein externes Eeprom hast: Warum nicht dort die Strings ablegen?
Gast
#5966311
Andreas B. schrieb: > Wenn Du doch sowieso schon ein externes Eeprom hast: Warum nicht dort > die Strings ablegen? Die paar Texte sind doch überhaupt nicht das Problem, zumal der Compiler gleiche Texte in der Regel erkennt und nur einmal anlegt. Die wiederholten, nahezu gleichen Abläufe fressen Platz. Geschickter ist es, mit Strukturen für die Bedienfelder zu arbeiten. Das ist einmaliger Aufwand aber danach sehr effizient und transparent. Für einen Anfänger ist das aber zunächst ein mächtiger Happen, der zu schlucken ist, zumal es auch anfangs an der Einsicht dafür fehlen wird. Und auch nur so, behält man bei unkommentiertem Code den Überblick. Aber da muß man durch, egal wie "fett" der verwendete µC ist.
m.n. schrieb: > Andreas B. schrieb: >> Wenn Du doch sowieso schon ein externes Eeprom hast: Warum nicht dort >> die Strings ablegen? > > Die paar Texte sind doch überhaupt nicht das Problem, zumal der Compiler > gleiche Texte in der Regel erkennt und nur einmal anlegt. Ich sehe eine ganze Menge Strings. 10% Einsparung würde ich schätzen. > > Die wiederholten, nahezu gleichen Abläufe fressen Platz. Geschickter ist > es, mit Strukturen für die Bedienfelder zu arbeiten. Das ist einmaliger > Aufwand aber danach sehr effizient und transparent. Das ist allerdings wahr. Das ganze Bediengedöns sieht recht ineffektiv aus.
Gast
#5966368
ich vermisse eine Angabe der Compileroptimierung Stand das schon irgendwo? Ansonst ja ... man kann immer etwas einsparen alternativ die Discovery boards ... gibt ja welche mit LCD + touch + ethernet + sdCard
Gast
#5966375
Ich plädiere nochmal für diese Lösung: Frank K. schrieb: > Mein Vorschlag: > > https://www.olimex.com/Products/OLinuXino/A64/A64-OLinuXino/open-source-hardware Mann kann ja nie genug Cores haben. Und die Megaherz sind auch ganz wichtig, besonders beim Aquarium-Steuern.
Felix N. schrieb: > Ich weiß auch das > Sie Texte in den Flash auslagern und so Platz im RAM Schaffen. Nein, sie werden nicht ins Flash ausgelagert. Da stehen sie sowieso. Sie werden mit Progmen/PSTR nur nicht ins RAM geschoben beim Start des uCs. Ich hab mir den Thread jetzt nicht genau durchgelesen, nur überflogen. Aber generell würde ich mir über Optimierungen mal Gedanken machen wenn ich sehe, dass 128 kB Flash nicht reichen.
Felix N. schrieb: > Hallo, > > Gut das ich ein guter Programmier bin habe ich nie gesagt, ich habe mir > mein gesamtes Programmier wissen aus YouTube Videos, Code Schnippels, > teilweise Bücher und Foren zusammen gesammelt. Habe Beruflich nix damit > zutun. Nur Hobby. Naja, da haben wir schon deutlich schlimmere Dinge gesehen ;-)
1 | |
2 | |
3 | |
4 | |
Diese Funktion ist maximal albern, wenn gleich sie sicher nicht wahnsinnig viel Flash braucht.
1 | |
2 | |
3 | |
Schon mal was von einer Schleife gehört?
1 | |
Au weia! Sieht du in den Massen an Schreibzugriffen selber noch durch? Schon mal was von einem struct gehört?
1 | |
2 | |
3 | |
Naja, theoretisch korrekt, praktisch eher ungünstig. Du hast so oder so nur wenig Speicher, da reicht es, eine lokale, temporäre Variable (Array) anzulegen. Mit ein wenig Nachdenken kommt diese Funktion sogar ohne Zwischenspeicher aus, wenn man einfach die Lücke im Originalstring vor dem Austausch passend zurecht schiebt.
1 | |
Auch hier wieder sinnlose, endlose Funktionsaufrufe, die nur einen anderen Parameter haben! Sowas macht man mit einem Array, idealerweise liegt der im Flash (PROGMEM) und einer Schleife. Das ergibt nicht nur deutlich weniger Quelltext, der deutlich übersichtlicher ist, sondern auch deutlich weniger Flashverbrauch.
1 | |
Du hast viele sprintf() Funtkionen drin. Nimm sprintf_P, dann liegt der Formatstring direkt im FLASH und verbraucht keinen RAM! Denk dran, konstante Strings und Array, welche "normal" benutzt werden, verbrauchen beim AVR Flash UND RAM in gleicher Größe. Erst wenn man sie mittels der passenden Funktionen in den Flash schiebt und entsprechend anspricht, entfällt der RAM-Verbrauch.
1 | |
Auch hier das Gleiche. Du musst deine Funktion auf PROGMEM-Strings umbauen. Dann sparst du massiv RAM.
1 | |
2 | |
3 | |
4 | |
5 | |
Gleiches Problem wie oben. Du spricht direkte, absolute Adressen im EERPOM an. Das ist Low Level Programmierung, wie man sie nicht mal in Assembler machen will. Man will Variablen mit gescheitem Namen ansprechen! Denn sonst sieht man irgendwann nicht mehr durch.
1 | |
2 | |
Hier hast du schon eines der Probleme bei Fließkommazahlen erkannt. Ein direkter Vergleich auf Gleichheit geht meist schief. Vermutlich ist für deine Anwendung Festkommaarithmetik ausreichend und macht dir nicht solche Probleme.
1 | |
Auch hier bringt die Funktion strcpy_P RAM-Ersparnis. Allgemein sieht man in deinem Ansatz zum Menuaufbau tonnenweise Funktionsaufrufe zum Zeichnen. Vermutlich ist da sehr viel doppelt und dreifach drin, das kostet schon einiges an Flash. Das kann man mit einem besseren Ansatz lösen. Man muss ja nicht gleich eine GUI-Menu-Bibliothek programmieren. Aber man sollte mit deutlich mehr Datenstrukturen arbeiten, welche die einzelnen Menus beschreiben. Ein kleine, kompakte Funktion kann diese dann auswerten und ja nach Menu zeichnen. Außerdem sollte man mehr mit universellen Hilffunktionen arbeiten, damit wiederholende Aufgaben nicht mehrfach aufgedröselt hingeschrieben werden müssen. Das spart FLASH, Tipparbeit und minimiert Fehlerquellen. Strukturierte Programmierung auf Mikrocontrollern
1 | |
2 | |
3 | |
4 | |
5 | |
Ist auch maximaler Unsinn. Das macht man mit einem PROGMEM-Array! Etwa so
1 | |
2 | |
Falk B. schrieb: > Ist auch maximaler Unsinn. Das macht man mit einem PROGMEM-Array! Das zum einem, es zeigt aber noch etwas weiteres: So eine Woche hat ja nur 7 Tage: Ein Case hätte man sich auch hier sparen können. Auch ein ENUM hätte hier wahrscheinlich besser gepasst als das Switch-Statement. Aber es wurde ja schon festgestellt, dass in dem Code enorm viel Optimierungspotential steckt.
Gast
#5966491
W5100Usa schrieb: > Mann kann ja nie genug Cores haben. Völlig richtig. Es soll jetzt einen neuen ATtiny885 geben mit sagenhaften 8 Kernen!
Noch was
1 | |
2 | |
3 | |
4 | |
Das ist Unsinn und macht im Extremfall nicht das, was du willst. Eine 0 durch die Gegend schieben ist sinnlos. Das funktioniert hier nur, weil die Bits im Register nach dem Reset sowieso schon auf Null stehen. Wenn man sicherstellen will, daß diese Pins Eingänge werden, dann eher so, siehe Bitmanipulation.
1 | |
2 | |
3 | |
4 | |
Gast
#5966556
> Autor: MaWin (Gast) > Datum: 08.09.2019 20:47 Noch so ein Trollbeitrag vom Psychopathen...
MaWin schrieb: >> Autor: MaWin (Gast) >> Datum: 08.09.2019 20:47 > > Noch so ein Trollbeitrag vom Psychopathen... Und du Plinse schaffst es seit Jahren nicht, dir einen Login zuzulegen. Selber Schuld! Aber was wäre die Welt ohne Paranoia?
Noch was
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
Genau SO macht man das eben nicht! Der Witz der Funktion encode_read4() ist es ja, daß man sie relativ langsam und selten in einer Schleife im Hauptprogramm aufrufen kann und als Ergebnis die Anzahl der Schritte seit dem letzten Aufruf nach links oder rechts bekommt. Ein Aufruf in der ISR ist sinnlos und kontraproduktiv! Die Beispiele hier im Wiki machen das auch nicht!
Gast
#5966609
Falk B. schrieb: > CODER_DDR |= (0<<CODER_PINA) | (0<<CODER_PINB) | (0<<CODER_BUTTON); > Eine 0 durch die Gegend schieben ist sinnlos. Kostet allerdings auch keinen Speicherplatz. Der Compiler reduziert das auf eine simple Zuweisung: CODER_DDR |=0
Stefanus F. schrieb: > Falk B. schrieb: >> CODER_DDR |= (0<<CODER_PINA) | (0<<CODER_PINB) | (0<<CODER_BUTTON); >> Eine 0 durch die Gegend schieben ist sinnlos. > > Kostet allerdings auch keinen Speicherplatz. Der Compiler reduziert das > auf eine simple Zuweisung: CODER_DDR |=0 Wenn der Compiler schlau ist, macht er dabei gar nichts (was ich mal stark vermute). Mit 0 verodern gibt immer noch das gleiche wie vorher.
Gast
#5966735
Andreas B. schrieb: > Wenn der Compiler schlau ist, macht er dabei gar nichts (was ich mal > stark vermute). Mit 0 verodern gibt immer noch das gleiche wie vorher. Alle Register sind volatile, ich glaube dass der Compiler die Zugriffe daher nicht weg optimieren darf.
Gast
#5966751
Wilhelm M. schrieb: > Theor schrieb: > >> Zusätzlich: Ich habe das vorher nicht erwähnt. >> >> 3. Vermeide die Verwendung von Literalen, insbesondere von >> Zahlenliteralen im Code. Halte sie lieber an einer zentralen Stelle, >> falls möglich. > > Das ist Quatsch bzw. stimmt nur für C-Strings (bei AVR). Zahlliterale > (als core-constant) werden vom Compiler immer direkt in den generierten > Code eingebaut. Lieber Wilhelm. du zitierst nur einen Teil meines Textes und unterstellst dann, ohne dass ich dafür einen vernüfntigen Grund erkennen kann, dass ich den von Dir zitierten Teil geschrieben habe, weil ich annehme, dass damit Speicherplatz gespart wird. Ich zitiere mich selbst und hebde der Deutlichkeit halber die von mir genannte Begründung für meine Aussage, die zu zitieren Du unterlassen hast. (Die Hervorherbung geschieht hier, in dem die Zitatzeichen '>' von dem Satz entfernt wurden. Eine andere Möglichkeit, den Satz etwa mit Unterstreichung hervorzuheben und ihn dabei weiter als Zitat zu kennezeichen, habe ich leider nicht gefunden). Das Original kann hier Beitrag "Re: ATMega Flash wird langsam knapp. Upgrade o. Plattformwechsel?" nachgelesen werden. Theor schrieb: >[...] > 3. Vermeide die Verwendung von Literalen, insbesondere von > Zahlenliteralen im Code. Halte sie lieber an einer zentralen Stelle, > falls möglich. > Gleiches gilt für String-Literale (mal unabhängig davon, ob Du nun ein > Menuesystem verwendest). _So sind Änderungen, insbesondere wenn wegen der Änderung eines Wertes auch andere Werte geändert werden müssen, einfacher._ > [...] Es mag sein, dass Du das nicht gesehen hast. Dann ist das sicher nur ein Mißverständnis. Ich hoffe, nun ist klarer, was ich sagen wollte.
Gast
#5966761
Falk B. schrieb: > MaWin schrieb: >>> Autor: MaWin (Gast) >>> Datum: 08.09.2019 20:47 >> >> Noch so ein Trollbeitrag vom Psychopathen... > > Und du Plinse schaffst es seit Jahren nicht, dir einen Login zuzulegen. > Selber Schuld! Aber was wäre die Welt ohne Paranoia? Lasst uns einen MaWin-Day einführen an dem alle mit seinem Namen posten :)
Stefanus F. schrieb: > Alle Register sind volatile, ich glaube dass der Compiler die Zugriffe > daher nicht weg optimieren darf. Macht er auch nicht:
1 | |
2 | |
3 | |
4 | |
5 | |
Hallo, Theor schrieb: >> Hallo, >> >> Gut das ich ein guter Programmier bin habe ich nie gesagt, >> [...] > > Und ich habe auch nicht behauptet, dass Du das von Dir gesagt hättest. > :-) > > Darum ging es mir nicht. Okay, dann hatte ich das falsch aufnehmen. Sorry! leo schrieb: > Das wird dann noch gemacht mit nur anderem Text. Du findest sowas zuhauf > im Code. Ja weil ich zuvor den bestehen Text überschreiben muss mit einem schwarzen Rechteck um da sonst wildes Zeug raus kommt wenn ich es weg lasse. Andreas K. schrieb: > Dann schliess parallel am SPI noch einen kleinen SPI-Flash-Baustein an. Andreas K. schrieb: > kannst du einfach im Programm von > der SD-Karte aus befüllen. Das heißt wenn ich das richtig verstehe ich schreibe 1x die meine ganzen Strings auf die SD Karte und schreibe sie dann in den SPI Flash und dort bleiben sie ja bis ich sie wieder lösche. Muss ich dann nicht massig Zugriffe machen, um die Strings dort wieder raus zubekommen? M. K. schrieb: > Sie > werden mit Progmen/PSTR nur nicht ins RAM geschoben beim Start des uCs. Achso. Falk B. schrieb: > Diese Funktion ist maximal albern, wenn gleich sie sicher nicht > wahnsinnig viel Flash braucht. 500 Bytes hat Sie verbraucht. War noch eine alte Funktion um die Temperatur Korrektur zu machen für die pH Elektrode ist aber Mittlerweile nicht mehr in Gebrauch. Falk B. schrieb: > Schon mal was von einer Schleife gehört? Ja habe. Ich habe jetzt eine for Schleife eingefügt. Falk B. schrieb: > Auch hier wieder sinnlose, endlose Funktionsaufrufe, die nur einen > anderen Parameter haben! Sowas macht man mit einem Array, idealerweise > liegt der im Flash (PROGMEM) und einer Schleife. Das ergibt nicht nur > deutlich weniger Quelltext, der deutlich übersichtlicher ist, sondern > auch deutlich weniger Flashverbrauch. Also ich habe das mal versucht umzusetzen, doch ist der Flash verbrauch nicht gesunken sondern um 0,2%(256Bytes) gestiegen. Möglicherweiße habe ich es auch falsch gemacht, habe den Quellcode von ili9341_init() als Datei angehängt. Falk B. schrieb: > Nimm sprintf_P Falk B. schrieb: > direkt im FLASH und verbraucht keinen RAM! Falk B. schrieb: > Du musst deine Funktion auf PROGMEM-Strings > umbauen. Dann sparst du massiv RAM. Irgendwie stehe ich gerade auf den Schlauch. Es wurde ja bereits öfters geschrieben das ich mit PSTR und PROGMEM oder _P Strings aus dem RAM ins Flash lege. Aber erhöhe ich nicht zwangsweise dadurch den Flash Verbrauch? RAM habe ich ja 16K wovon ich nicht mal 50 % im Moment benutze oder habe ich da was falsch verstanden? Falk B. schrieb: > Du spricht direkte, absolute Adressen im > EERPOM an. Das ist Low Level Programmierung > Man will Variablen mit gescheitem Namen > ansprechen! Was heißt den jetzt Low Level? Und wieso ist es schlecht das ich der Variable direkt den Wert aus dem EEPROM zuweiße? Wüsste jetzt nicht wie ich es sonst machen sollte. Was meinst du genau mit gescheitem Namen? Ich mein ich weiß ja warum die Variable zb. ontime_co2_hour heißt oder ist damit gemeint das ich besser ein Array erstelle wie zb.
1 | |
Und dann dem Array 0 bis 4 die Adressen zuweiße? Falk B. schrieb: > Sieht du in den Massen an Schreibzugriffen selber noch durch Falk B. schrieb: > Denn sonst sieht man irgendwann nicht mehr durch. Naja manchmal ist es schon ein bisschen speziell. Aber ich habe ein Excel Dokument wo ich Eintragen habe wie und wo welche Adresse und Wert abgespeichert ist und was das macht. Falk B. schrieb: > Schon mal was von einem struct gehört? Gehört schon aber noch nie benutzt. Falk B. schrieb: > Allgemein sieht man in deinem Ansatz zum Menuaufbau tonnenweise > Funktionsaufrufe zum Zeichnen. Ich rufe die Menüs ja schon in der buttonpressed() Funktion auf die in der Menu Funktion vorhanden ist. Somit lade ich ja die Menüs schon vor. Wäre es besser wenn ich dort zb. ein Integer als Menü Index setze und ein Wechsel Boolean so das in der Menu geschaut wird ob gerade ein Wechsel erforderlich ist zb. vom Hauptmenü aufs RTC Menu und wenn das der Fall dann wechseln. Somit würde ich die Menüs ja unter ein anderer nicht mehr aufrufen sondern nur noch 1x Zentral von der main.c Falk B. schrieb: > Das ist Unsinn und macht im Extremfall nicht das, was du willst. Ah gut zu wissen das nicht alles gewonnenes wissen richtig ist habe das mal so aufgeschnappt in einem Online Artikel über die AVR Programmierung ... Deswegen habe ich das so gemacht. Bis jetzt hat es mich auch noch nicht im Stich gelassen. Falk B. schrieb: > Genau SO macht man das eben nicht! Falk B. schrieb: > Die Beispiele hier im Wiki > machen das auch nicht! Da war mal irgendwas warum ich das gemacht habe. Werde mir nochmal den Wiki Artikel durchlesen. Lg
Gast
#5967109
Felix N. schrieb: > leo schrieb: >> Das wird dann noch gemacht mit nur anderem Text. Du findest sowas zuhauf >> im Code. > > Ja weil ich zuvor den bestehen Text überschreiben muss mit einem > schwarzen Rechteck um da sonst wildes Zeug raus kommt wenn ich es weg > lasse. Du verstehst offensichtlich das Problem nicht. Du hast die selben 3 Zeilen Code x mal, nur mit anderem Text anstatt den Code genau 1 mal in einer Funktion zu haben, der du den unterschiedlichen Text uebergibst. leo
Gast
#5967110
Felix N. schrieb: > Aber erhöhe ich nicht zwangsweise dadurch den Flash Verbrauch? Nochmal: Nein Ich kann das auch gerne 100 mal schrieben, wenn es Dir hilft: Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, Nein, ...
leo schrieb: > Du hast die selben 3 > Zeilen Code x mal, nur mit anderem Text anstatt den Code genau 1 mal in > einer Funktion zu haben, der du den unterschiedlichen Text uebergibst. Hallo, ich glaube ich weiß jetzt wie du das meinst. Ich beziehe mich mal auf ein Code Schnippel aus der Co2Menu.c Datei Zeile 118-119 dort habe ich zwei Zeilen Code
1 | |
2 | |
In Zeile 126-127 und 133-134 wiederholt sich der Code nur mit einem anderen Text. Ich habe mir jetzt folgende Funktion überlegt die halt das fillrect macht und den Text mittels PSTR übergibt:
1 | |
2 | |
3 | |
4 | |
Wenn ich die Zeilen die ich oben genannt habe durch die Funktion ersetze habe ich 46 Bytes Flash wieder frei. Stefanus F. schrieb: > Ich kann das auch gerne 100 mal schrieben, wenn es Dir hilft: Nein. Aber ich glaube ich habe es jetzt verstanden. Ich habe mir den Link mal durchgelesen und mal mich erkundigt wie das mit dem RAM und Flash ungefähr funktioniert. https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Speicherzugriffe Wenn ich das nun richtig verstanden habe belegt ein normaler String Flash und RAM. Wobei der String beim Start zusätzlich in den RAM kopiert wird. Das ist der Grund warum ich direkt drauf zugreifen kann. richtig? Wenn ich jetzt den String mit PSTR oder PROGMEM anlege je nach dem, wird er erst gar nicht in den RAM kopiert. Er wird also nur im Flash anlegt. Wenn ich jetzt ein direkten Zugriffe drauf mache versucht das Programm die Adresse der Variable im RAM zu finden, wird es aber nicht da sie mit PSTR oder PROGMEM gar nicht erst ins RAM geladen wurde und ich bekomme irgendwas zurück. Daher muss ich mit den Makros pgm_read_byte/word/... arbeiten damit das Programm nicht die Adresse des Strings aus dem RAM ließt sondern nach der Adresse im Flash. Somit würde ich den doppelten Speicher belegen wenn ich ein String ohne PROGMEM anlege, das würde ja auch bedeuten das wenn ich einen normalen String anlege ohne PROGMEM das im RAM zwar eine Kopie liegt aber sie jedoch nur auf die Adresse des Strings im Flash verweist oder? Lg
Gast
#5967229
Felix N. schrieb: > Wenn ich die Zeilen die ich oben genannt habe durch die Funktion ersetze > habe ich 46 Bytes Flash wieder frei. Sehr gut. Ich denke da sind noch viel mehr Wiederholungen, auch mit leicht anderen Koordinaten oder anderen Texten. Du kannst noch viel mehr in Funktionen zusammenfassen. leo
Felix N. schrieb: > Somit würde ich den doppelten Speicher belegen wenn ich ein String ohne > PROGMEM anlege, das würde ja auch bedeuten das wenn ich einen normalen > String anlege ohne PROGMEM das im RAM zwar eine Kopie liegt aber sie > jedoch nur auf die Adresse des Strings im Flash verweist oder? Eine Kopie ist genau das: eine Kopie und kein Zeiger/Verweis. Ein Zeiger würde bei einem 16 Bit Adressraum nur 2 Byte brauchen, egal wie groß das Original ist. Eine Kopie braucht exakt so viel Platz wie das Original. Das Problem bei AVR ist, dass Du einmal Adressen von 0...65535 fürs Flash hast und einmal Adressen von 0...65535 fürs RAM. Diese beiden Adressen sind nicht miteinander kompatibel, d.h. Du hast einmal eine wie strcpy für RAM-Adressen und einmal eine Spezialversion strcpy_P für Flash-Adressen. Bei ARM, MIPS und den meisten anderen Architekturen hast Du diese Unterscheidung nicht. Da hast Du nur einen Satz von Adressen von 0 bis 4G-1, und da ist alles drin: Flash, RAM, IO-Ports usw. Ist damit einfacher zu programmieren und ermöglicht es auch, Code aus dem RAM ablaufen zu lassen. Das ist auch etwas, was bei AVR grundsätzlich nicht geht. fchk
Gast
#5967239
Felix N. schrieb: > Wenn ich das nun richtig verstanden habe belegt ein normaler String > Flash und RAM. Wobei der String beim Start zusätzlich in den RAM kopiert > wird. Das ist der Grund warum ich direkt drauf zugreifen kann. richtig? ... und was du danach geschrieben hast ja alles richtig. pgm_read_byte/word/...nutze ich nur sehr selten. Denn für viele String Funktionen gibt es noch die _P Varianten, die aus dem Flash lesen, anstatt aus dem RAM. Zum Beispiel sprintf_P().
Was Falk geschrieben hat ist richtig auch wenns nicht besonders diplomatisch war. Lass Dich nicht von diesen Helden mit den ESP- oder WIZ-Zeugs beeindrucken. Damit schaffts Du nur neue Baustellen. Mein eigenes Projekt nutzt fast die gleiche Peripherie aber als FBH-Steuerung. Auch bei mir ist Speicher irgendwann knapp geworden. Habe dann auf den 2560 + 64k XMEM aufgerüstet - damit lebt es sich ganz entspannt. Das läuft 24/7 seit ein paar Jahren äußerst zuverlässig.
Gast
#5967270
Felix N. schrieb: > > [...] > Falk B. schrieb: >> Du musst deine Funktion auf PROGMEM-Strings >> umbauen. Dann sparst du massiv RAM. > > Irgendwie stehe ich gerade auf den Schlauch. Es wurde ja bereits öfters > geschrieben das ich mit PSTR und PROGMEM oder _P Strings aus dem RAM ins > Flash lege. Es ist vielleicht noch nicht klar genug beschrieben worden: Nach dem Reset des Prozessors geschieht in Bezug auf literale, also konstante, Strings, u.A. Folgendes: 1. Der FLASH-Speicher enthält grundsätzlich Dein gesamtes Programm inklusive aller in Deinem Programm verwendeten konstanten Strings (Zeichenketten), egal ob Du nun PSTR verwendest oder nicht. 2. Das RAM enthält nach dem Reset (sozusagen) Nichts. Soweit es Dich im Moment angeht, enthält es keine sinnvollen Werte, keine Strings oder Zahlen aus Deinem Programm. (Genau genommen stimmt das nur, falls zuvor der Strom ausgeschaltet war, aber zunächst mal kommt es für Dich auf das selbe hinaus, ob der Strom vor dem Reset an war oder nicht). 3. Ein Teil der ersten Befehle nach dem Reset, kopiert Deine Strings, die Du in dem Programmtext hingeschrieben hast, aus dem FLASH-Speicher in das RAM. Das geschieht, weil Zugriffe auf das RAM schneller gehen als Zugriffe auf Daten im FLASH-Speicher. D.h. wird auf Strings im Programm mehr als zwei- oder dreimal zugegriffen, dann geht das aus dem RAM insgesamt schneller als aus dem FLASH. Dieser Vorgang des kopierens wird durch Programmcode beschrieben, den Du normalerweise nicht zu sehen bekommst. Man nennt das den "Startup-Code". D.h. mit der Verwendung von PSTR und PROGRMEM (usw.) legst Du nicht Strings aus dem RAM ins FLASH! Nicht so, wie Du das vermutlich meinst. Die Strings sind eben nicht von vorne herein (beim Reset) im RAM. Wie sollten sie da hinkommen? Es ist wichtig, dass Dir klar wird, was Du im Programmtext eigentlich beschreibst und zu welchem Zeitpunkt es eine Wirkung hat. Wenn Du im Programmtext PSTR hinschreibst und das Programm kompilierst, dann erzeugt der Compiler für diese Variable, vor der PSTR steht, keinen Code, der sie in das RAM kopiert. PSTR wirkt sich auf den Code aus und der Code tut gewisse Dinge dann nicht. In Deinem Fall ist nun eine Maßnahme (von mehreren, die Dir hier vorgeschlagen wurden), dass Du (fast) alle Strings ausschliesslich im FLASH-Speicher vorhälst. Deswegen sollst Du PSTR vor (fast) alle Strings schreiben. > Aber erhöhe ich nicht zwangsweise dadurch den Flash Verbrauch? RAM habe > ich ja 16K wovon ich nicht mal 50 % im Moment benutze oder habe ich da > was falsch verstanden? Nein. Eben nicht. Wie oben beschrieben, sind Strings immer_ und _grundsätzlich im FLASH Speicher enthalten. Denn das ist der Speicher, der auch nach dem Abschalten des Stroms erhalten bleibt. RAM verliert seinen Inhalt. Du bewirkst also mit PSTR nicht, das der FLASH-Speicher voller wird, denn die Strings stehen da auch dann drin, falls Du PSTR nicht verwendest. Woher sollen sie sonst kommen, wenn sie ins RAM kopiert werden? Mit der Verwendung von PSTR bewirkst Du aber, dass die Strings nicht ins RAM kopiert werden und sparst dadurch, weil Du soviel Text hast, viel RAM. Eine Folge der Verwendung von PSTR ist aber, dass sich die Ausführungszeit des Programmes insgesamt etwas erhöht, denn wie gesagt, dauert es länger, die Strings aus dem FLASH zu laden, als aus dem RAM. Nur macht das in Deinem Fall nicht viel aus, da die Anzeige nicht zeitkritisch ist. Du würdest nur bei extrem langen Texten (vielleicht ab etwa 100Bytes oder mehr etwas davon merken. Klar? Oder hast Du noch Fragen?
Gast
#5967275
Na toll. Da war ich zu langsam. :-)
Gast
#5967280
Schon mal Ethersex angeschaut?
Felix N. schrieb: > Das heißt wenn ich das richtig verstehe ich schreibe 1x die meine ganzen > Strings auf die SD Karte und schreibe sie dann in den SPI Flash und dort > bleiben sie ja bis ich sie wieder lösche. > > Muss ich dann nicht massig Zugriffe machen, um die Strings dort wieder > raus zubekommen? Naja, soo viel ist das nicht, kann man relativ einfach in eine Funktion packen. Aber soweit musst du gar nicht gehen, du hast noch VIEL Luft nach oben. Erstens durch eine gescheite Umstruktuerierung deines Codes (neudeutsch Refactoring) und 2. durch den großen Bruder mit 256kB Flash. >Also ich habe das mal versucht umzusetzen, doch ist der Flash verbrauch >nicht gesunken sondern um 0,2%(256Bytes) gestiegen. Darf nicht sein. > Möglicherweiße habe >ich es auch falsch gemacht, habe den Quellcode von ili9341_init() als >Datei angehängt. Naja, schon mal besser, wenn gleich noch ausbaufähig. Vor allem schreibt man nicht eine supermegalange Zeile! Viel mehr als 100-120 Zeichen gehören nicht in eine Zeile. Ein Array darf problemlos über mehrere Zeilen gehen. Ich hätte aber aber anders, gemacht, damit wird es kompakter. Kodiere die Befehle mit 16 Bit und nutze die oberen Bits zur Unterscheidung von Befehl und Daten. Das verschwendet zwar 7 Bit, macht das in Summe aber wieder wett (ein Maschinenbefehlt hat beim AVR auch 16 Bit). Siehe Anhang, ist aber nur beispielhaft, den Rest must du ergänzen. >Aber erhöhe ich nicht zwangsweise dadurch den Flash Verbrauch? RAM habe >ich ja 16K wovon ich nicht mal 50 % im Moment benutze oder habe ich da >was falsch verstanden? Ja hast du, immer noch. Wenn man beim AVR "normale", konstante Strings benutzt, liegen die im Flash und werden vor dem Start von main() in den RAM kopiert. Mit denen arbeitet dann dein Programm. Die Strings im Flash werden danach nie wieder angesprochen. Mit dem _P Funktionen etc. entfällt die Kopie in den RAM und die Strings werden DIREKT aus dem Flash gelesen und verarbeitet. Capice? >Was heißt den jetzt Low Level? Du kriechst im IT-Urschleim! > Und wieso ist es schlecht das ich der >Variable direkt den Wert aus dem EEPROM zuweiße? Weil das Hacker und Amateurmurks ist und du ganz schnell nicht mehr durchsiehst. Warum wohl wurden selbst beim Assembler Namen für Variablen verwendet und keine Adressen? Weil der Mensch mit NAMEN deutlich besser klar kommt! > Wüsste jetzt nicht wie >ich es sonst machen sollte. Richtig? Solche Sache packt man in ein struct.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Ist das nicht DEUTLICH lesbarer und vor allem selbsterklärend? >Naja manchmal ist es schon ein bisschen speziell. Aber ich habe ein >Excel Dokument wo ich Eintragen habe wie und wo welche Adresse und Wert >abgespeichert ist und was das macht. AUA! Genau SO macht man es NICHT! Denn dieser Job gehört dem COMPILER! Der verwaltet die Adressen! Du legst Variablen mit gescheiten Namen an, ggf. als Struct zusammengefaßt. >Wäre es besser wenn ich dort zb. ein Integer als Menü Index setze und >ein Wechsel Boolean so das in der Menu geschaut wird ob gerade ein >Wechsel erforderlich ist zb. vom Hauptmenü aufs RTC Menu und wenn das >der Fall dann wechseln. JA! > Somit würde ich die Menüs ja unter ein anderer > nicht mehr aufrufen sondern nur noch 1x Zentral von der main.c Das ist der Witz der Sache!
Hier der Anhang.
Gast
#5967521
Felix N. schrieb: > Wenn ich die Zeilen die ich oben genannt habe durch die Funktion ersetze > habe ich 46 Bytes Flash wieder frei. hi und so geht das durch den gesammten code weiter. ABER ... Alle haben mal angefangen und gelernt das jede Architektur seine eigene Programmierweise hat... siehe AVR mit PROGMEM und das er nunmal variablen > 8bit nicht so mag Ich selbst arbeite momentan viel mit Cortex M7 Da dieser Cache hat und immer 32byte aligned arbeitet muss man auch "komisch" programmieren. Ebenso der "ART" ist ein 128byte Cache für den Flashzugriff. Alle Funktionen >128bytes brauchen deutlich mehr Zeit. Ergo... alles zerhackstücken das man lieber viele viele kleine funktionen hat. 8bit ist hier eher kontraproduktiv weil trotzdem 32bit verbraucht werden... usw ... Wenn ich manchmal code durchschaue den ich vor 2-3 Jahren mal geschrieben habe erkenne ich sofort optimierungspotenzial. Das wird mir in 2-3 Jahren bei einem aktuellen Projekt sicher auch so gehen ^^ Aber zumindest macht man keine grunsätzlichen fehler mehr... nicht mehr so doll ^^ Man muss halt nur immer dazulernen. Habe selbst ein Aquarium ( meerwasser ) und mir damals was gebaut. funktioniert bis heute. Habe dazu aber kein LCD eingebaut und nur den Netzwerkanschluss genutzt. Das Ding hat eine Webseite die alle Daten liefert und ggf. auch von "Außen" Zugriff gewährt. Vieleicht als Idee für dich ... Da ein Handy ja auch ein LCD ist .. und man mit CSS / HTML sicherlich mehr grafische Möglichkeiten hat als auf dem ILI .. Encoderbedienung brauch man auch nicht mehr.. gibt ja Eingabemöglichkeiten auf der Seite. Die webseite wird komplizierter... dafür wird die Blackbox einfacher :-)
gdgddfgdfd schrieb: > hi > > und so geht das durch den gesammten code weiter. > > ABER ... > Alle haben mal angefangen und gelernt das jede Architektur seine eigene > Programmierweise hat... > siehe AVR mit PROGMEM Sicher, ist halt eine Besonderheit. Wenn man sie kennt ist es aber kein echtes Problem, nur ein wenig mehr Aufwand. > und das er nunmal variablen > 8bit nicht so mag UNSINN!!! > Ich selbst arbeite momentan viel mit Cortex M7 > Da dieser Cache hat und immer 32byte aligned arbeitet muss man auch > "komisch" programmieren. > Ebenso der "ART" ist ein 128byte Cache für den Flashzugriff. Alle > Funktionen >128bytes brauchen deutlich mehr Zeit. > Ergo... alles zerhackstücken das man lieber viele viele kleine > funktionen hat. 8bit ist hier eher kontraproduktiv weil trotzdem 32bit > verbraucht werden... usw ... Quark^3. Kein Mensch optimiert C-Funktionen, damit sie in den Cache der CPU passen. Das macht man, wenn überhaupt, in Assembler, und auch nur dort, wo es ULTIMATIV nötig ist. https://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung Die Grundlagen gelten ganz allgmein. https://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung#Was
Gast
#5967541
Falk B. schrieb: >> und das er nunmal variablen > 8bit nicht so mag > > UNSINN!!! Zugriffe auf 16/32bit sind also weiter in einem Takt möglich? Ich glaube nicht ... Es geht auch nicht darum das man jetzt bei einer Tasateneingabe optimiert. Aber , wenn man in der summe etwas darauf achtet ist so ein AVR lange nicht am limit .. auch wenn hier oft solche threads erscheinen. Oft werden "int" oder "short" sogar "float" variablen genutzt ohne das diese sinn machen. da werden dann zahlen im bereich 0-10 übergeben. Die funktion wird im code 100x aufgerufen und jedesmal speicher verbraten. Sowas meine ich damit. Das man beim programmieren etwas auf die architektur achtet. Auch wenn die compiler recht intelligent sind. Falk B. schrieb: > Quark^3. Kein Mensch optimiert C-Funktionen, damit sie in den Cache der > CPU passen. Das macht man, wenn überhaupt, in Assembler, und auch nur > dort, wo es ULTIMATIV nötig ist. Ich habe ein Projekt mit einem M7 der (nebenbei) mjpeg decodiert. Ohne diese Anpassung auf 32bit alianing oder kleinere Funktionen liegt die Bildrate bei QVGA bei ca 10-13fps , mit dieser Optimierung bei ca 22-25fps. Die Anpassung ist im C code und damit auch wieder für andere M7 portabel. (getestet auf STM F7 H7 und NXP RT1060 ) Generell ist der M7 etwas tricky. durch die diversen Speicherbereiche und deren verhalten ( caching , BUSse )
Man kann es ruhig auf die Spitze treiben. Alle ähnlichen Codesequenzen, die an 2 oder mehr Stellen auftreten, macht man zu einer Funktion, der nur die Unterschiede übergeben werden. Es schaded auch nicht, wenn diese Funktionen nur aus 1 oder 2 Zeilen bestehen. Der große Vorteil neben der Codeersparnis ist, man macht auch alle Fehler immer nur an einer Stelle, muß also nur eine Stelle korrigieren.
Gast
#5967549
Falk B. schrieb: >> siehe AVR mit PROGMEM > > Sicher, ist halt eine Besonderheit. Wenn man sie kennt ist es aber kein > echtes Problem, nur ein wenig mehr Aufwand. richtig. Bezieht sich darauf das der TE den Unterschied zwischen RAM und Flash Nutzung bei Strings jetzt ja kennt. Wenn er in zukunft darauf achtet .. ist das kein thema mehr. Wenn er mal mit Cortex M zu tun hat wird er der einfachheit halber auf
1 | |
zurückgreifen.
gdgddfgdfd schrieb: > Wenn er mal mit Cortex M zu tun hat wird er der einfachheit halber auf >
1 | |
2 | |
> zurückgreifen. Oder auch für AVR
1 | |
schreiben. Damit sind gleiche Strings auch nur einmal im Flash, der Zugriff ist gekapselt, man kann kein _P mehr bei irgendeiner Funktion vergessen. Daher der Ratschlag: bevor er die Plattform wechselt, was sicher bei der Auquariensteuerung völlig unnötig ist, erstmal mit dem Thema Softwareentwicklung intensiv befassen. Und das nicht auf dem µC, sondern in einer komfortableren Umgebung, etwa ein PC mit geeigneter IDE.
gdgddfgdfd schrieb: > Falk B. schrieb: >>> und das er nunmal variablen > 8bit nicht so mag >> >> UNSINN!!! > > Zugriffe auf 16/32bit sind also weiter in einem Takt möglich? > Ich glaube nicht ... War das die Frage? Ist das für einen Aquariumcontroller wichtig? > Aber , wenn man in der summe etwas darauf achtet ist so ein AVR lange > nicht am limit .. auch wenn hier oft solche threads erscheinen. EBEN! >> Quark^3. Kein Mensch optimiert C-Funktionen, damit sie in den Cache der >> CPU passen. Das macht man, wenn überhaupt, in Assembler, und auch nur >> dort, wo es ULTIMATIV nötig ist. > > Ich habe ein Projekt mit einem M7 der (nebenbei) mjpeg decodiert. > Ohne diese Anpassung auf 32bit alianing oder kleinere Funktionen liegt > die Bildrate bei QVGA bei ca 10-13fps , mit dieser Optimierung bei ca > 22-25fps. Eben DAS ist so eine Anwendung, wo sich so eine Optimierung lohnt. Das sollte man aber schon dazu sagen!
Gast
#5967587
Peter D. schrieb: > Es schaded auch nicht, wenn diese Funktionen nur aus 1 oder 2 Zeilen > bestehen. Das ist ein Punkt, der mich anfangs überraschte, da ich vor Mikrocontroller überwiegend PC's programmierte. Beim PC sind Funktionsaufrufe oft (nicht immer) wesentlich teurer, als beim AVR. Insbesondere dann, wenn die angesprungene Funktion in einem anderen Speicherberbereich liegt, der sich gerade nicht im CPU Cache befindet. Bei AVR kosten Funktionsaufrufe hingegen fast keinen Overhead. Dazu kommt, dass der Compiler einige Funktionen durch inline-Code ersetzt, wenn er das für vorteilhaft hält.
Gast
#5967636
Das alles in summe betrachtet führt dazu das der flash nicht so schnell voll ist. auch funktionen mit vielen übergabeparametern frisst nicht nur zeit und ram .. sondern auch flash. Die sichtweise wie man sachen verallgemeinert oder modularisiert ohne groß aufzublähen fehlt oft am anfang. Aber nur durch fehler lernen wir , oder?
gdgddfgdfd schrieb: > Aber nur durch fehler lernen wir , oder? Viele nicht mal dadurch. Das geht schon bei der Groß/Kleinschreibung los . . .
Gast
#5967682
Falk B. schrieb: > gdgddfgdfd schrieb: >> Aber nur durch fehler lernen wir , oder? > > Viele nicht mal dadurch. Das geht schon bei der Groß/Kleinschreibung los > . . . Stimmt. Bei mir liegts nur an der Faulheit. Hat sich seit 30 Jahren nicht gebessert.
Gast
#5967713
Peter D. schrieb: > Der große Vorteil neben der Codeersparnis ist, man macht auch alle > Fehler immer nur an einer Stelle, muß also nur eine Stelle korrigieren. Und die positive Kehrseite ist, daß Änderungen nur an einer zentralen Stelle vorgenommen werden müssen. Wenn man viele Änderungen vornimmt, dann wirkt sich das enorm zeitsparend aus. Ich muß aber gestehen, daß ich manchmal auch Programmteile kopiere, wodurch sich dann zwangsläufig redundante Codeteile ergeben, weil das einfacher ist als eine Funktion zu schreiben. Wenn genügend Speicher da ist, kann ich mir diesen Luxus erlauben...
Gast
#5967806
gdgddfgdfd schrieb: > ich vermisse eine Angabe der Compileroptimierung > Stand das schon irgendwo? Ich möchte nochmal auf diese Frage hinweisen - ob mit -O0 oder -Os kompiliert wird, dürfte die Programmgröße massiv beeinflussen. Genauso die Linker-Optionen überprüfen, ob zum Beispiel LTO aktiv ist. Und diese andere Option, deren Name mir gerade nicht einfällt, dass nicht die ganze Bibliothek dazu gelinkt wird, wenn nur eine einzelne Funktion daraus benötigt wird. Sollte zwar standardmäßig aktiv sein, aber besser mal nachsehen... Falk B. schrieb: >>Also ich habe das mal versucht umzusetzen, doch ist der Flash verbrauch >>nicht gesunken sondern um 0,2%(256Bytes) gestiegen. > > Darf nicht sein. Vielleicht, weil durch die Änderung eine/mehrere der _P-Funktionen mit gelinkt wird, die vorher nicht benötigt wurde(n)? Die "normalen" Funktionen (ohne _P) werden ja für die ungeänderten Teile nach wie vor gebraucht. MfG, Arno
Gast
#5967892
Ich habe gerade gesehen das er in seiner main.c ganz viele Infos zum Start ausgibt. Das ist als Anfänger schön wenn da was steht , ist aber oft auch totaler nonsins^^... Es belegt Speicher und man baut künstliche delays ein damit man Zeit hat das zu lesen. Ich hab beim AVR damals immer eine eigene Datei für alle Strings angelegt. Diese war entsprechend formatiert. texte_de.txt
1 | |
2 | |
3 | |
4 | |
im quelltext dann irgendwo:
1 | |
2 | |
3 | |
im source gab es dazu passend eine liste
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
damit lies sich verhindern das texte vlt doppelt im flash landen. und bei mehreren Sprachen brauch man nur den pointer (strings_de) verändern.
1 | |
2 | |
3 | |
auch Lesbarkeit:
1 | |
ist nichtssagend.
mach dir dafür defines
#define MAIN_MENUE 1
#define RTC_MENUE 2
oder eine enumeration
enum{
MENUE_NONE = 0,
MENUE_MAIN,
MENUE_RTC,
...
};
Noch was. Die One Wire Kommunikation ist NICHT solide, denn während der Übertragung eines Bits müssen die Interrupts gesperrt sein, damit das Timing wasserdicht ist! Außerdem braucht man auch hier für die Temperatur keine Fließkommazahlen. Außerdem fehlt die CRC-Prüfung, das kann bisweilen auch mal daneben gehen. Was macht deine Steuerung dann? So geht es sicher und besser. Beitrag "Onewire + DS18x20 Library"
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Auch das hier ist Unsinn. Hier werden echte Variablen angelegt, die echten RAM verbrauchen. Das braucht keiner, denn das sind alles Konstanten. In C nutzt man hier eher #define
1 | |
2 | |
Falk B. schrieb: > uint8_t MCP7940_ADDRESS = 0x6F; // > Device address, fixed value // > uint8_t MCP7940_RTCSEC = 0x00; // > Section 1: timekeeping // > uint8_t MCP7940_RTCMIN = 0x01; // > // > uint8_t MCP7940_RTCHOUR = 0x02; // > // > [/c] > > Auch das hier ist Unsinn. Hier werden echte Variablen angelegt, die > echten RAM verbrauchen. Das braucht keiner, denn das sind alles > Konstanten. In C nutzt man hier eher #define > >
1 | |
2 | |
3 | |
Oder static const uint8_t, wenn es typsicher sein soll. fchk
Frank K. schrieb: > Oder static const uint8_t, wenn es typsicher sein soll. > > fchk Das wird dann aber in C auch eine echte Variabel mit RAM-Verbrauch, oder?
Frank K. schrieb: > Falk B. schrieb: > >> uint8_t MCP7940_ADDRESS = 0x6F; // >> Device address, fixed value // >> uint8_t MCP7940_RTCSEC = 0x00; // >> Section 1: timekeeping // >> uint8_t MCP7940_RTCMIN = 0x01; // >> // >> uint8_t MCP7940_RTCHOUR = 0x02; // >> // >> [/c] >> >> Auch das hier ist Unsinn. Hier werden echte Variablen angelegt, die >> echten RAM verbrauchen. Das braucht keiner, denn das sind alles >> Konstanten. In C nutzt man hier eher #define >> >>
1 | |
2 | |
3 | |
> > Oder static const uint8_t, wenn es typsicher sein soll. Mmh, und
1 | |
ist ein sinnvoller Ausdruck? Also, typsicher bedeutet etwas anderes!
Falk B. schrieb: > Frank K. schrieb: >> Oder static const uint8_t, wenn es typsicher sein soll. >> >> fchk > > Das wird dann aber in C auch eine echte Variabel mit RAM-Verbrauch, > oder? Das ist eine read-only Variable (constexpr gibt es nur in C++), die auch ein schlechter Compiler sicher gut wegoptimieren kann.
Falk B. schrieb: > Die One Wire Kommunikation ist NICHT solide, denn während der > Übertragung eines Bits müssen die Interrupts gesperrt sein, damit das > Timing wasserdicht ist! Das muss nicht Wasserdicht sein, da der AVR nicht im Aquarium ist ;-)
Gast
#5968071
Armin K. schrieb: > Das muss nicht Wasserdicht sein, da der AVR nicht im Aquarium ist ;-) Aber die Quad-Core Lösung mit 64-Bit ARM ist nach heutigem Diskussions-Stand Pflicht! Frank K. schrieb: > Mein Vorschlag: > > https://www.olimex.com/Products/OLinuXino/A64/A64-OLinuXino/open-source-hardware
Gast
#5968098
W5100Usa schrieb: > Armin K. schrieb: >> Das muss nicht Wasserdicht sein, da der AVR nicht im Aquarium ist ;-) > > Aber die Quad-Core Lösung mit 64-Bit ARM ist nach heutigem > Diskussions-Stand Pflicht! Der Zweck des Forums und dieser Diskussion ist meiner Ansicht nach, Empfehlungen zu ggeben und vernünftige Gründe dafür zu nennen. Ausserdem, nach Möglichkeit konkrete Informationen darüber, wie diese Empfehlungen realisiert werden können. Welche Diskussion zwischen welchen Diskussionsteilnehmern meinst Du? Die Diskussion hier fokussiert sich, meiner Meinung nach zu Recht, auf eine Überarbeitung des Codes und hat, wiederum meiner Meinung nach zu Recht, die Voraussetzung, dass bei Umsetzung der Ratschläge der AVR (der vom TO genannte Typ resp. der nächstgrössere) völlig ausreicht. Wer oder was verpflichtet hier den TO oder sonstwen und mit welcher Rechtfertigung tut er oder es das? "Pflicht" ist hier gar Nichts. Der TO hat das Recht jede Lösung zu nehmen, die er möchte - sogar wenn dies von Anderen als unvernünftig betrachtet wird.
Hallo, Arno schrieb: > Ich möchte nochmal auf diese Frage hinweisen - ob mit -O0 oder -Os > kompiliert wird, dürfte die Programmgröße massiv beeinflussen. Habe mal unter AVR/GNU C Compiler -> Optimization nach geschaut dort steht drin: Optimization Level: Optimize(-O1). Ich habe es mal testweise umstellt bei -O0 kann ich erst gar nicht kompilieren dort kommt der Fehler: "region `text' overflowed by 14018 bytes" Ja -O1 wird ja benutzt dort habe ich im Moment 98952 Bytes an Flash und 6853 Bytes an SRAM. Mit -Os habe ich 89932 Bytes Flash und 6893 Bytes an SRAM. Habe ich dadurch irgendwelche Nachteile wenn ich das auf -Os umstelle? Arno schrieb: > Genauso die Linker-Optionen überprüfen, ob zum Beispiel LTO aktiv ist. Kann ich nicht finden. Weder als Checkbox noch in der Command Zeile. Falk B. schrieb: > gescheite Umstruktuerierung deines Codes Ja da bin ich im Moment noch am Überlegen was mehr Sinn macht. Das Projekt neu Anlegen und den alten Code Schritt weiße übernehmen und dabei überarbeiten. Zb. Floats weg lassen ... oder im bestehenden Code überarbeiten. Falk B. schrieb: > Capice? Frank K. schrieb: > Eine Kopie ist genau das: eine Kopie und kein Zeiger/Verweis. Stefanus F. schrieb: > ja alles richtig. Theor schrieb: > Klar? Oder hast Du noch Fragen? Habe es mittlerweile kapiert^^. Danke euch :) Falk B. schrieb: > Weil der Mensch mit NAMEN deutlich besser > klar kommt! Falk B. schrieb: > Denn dieser Job gehört dem COMPILER! > Der verwaltet die Adressen! Moment mal. Das heißt ich definiere gar nicht die Adressen fürs EEPROM, sondern die werden dann Zufällig zugewiesen, oder wie muss ich das verstehen? In deinem Struct Beispiel bezieht sich die 16 Bit Variable(min_temperature) ja nicht auf den gelesen Wert vom EE sondern auf die Adresse im EE wo der Wert liegt. Oder muss ich die Variablen einmal mit einer Adresse definieren?
1 | |
Falk B. schrieb: > Ist das nicht DEUTLICH lesbarer und vor allem selbsterklärend? Ja auf jeden Fall. Aber eine Frage habe ich dazu noch du legt ja eine Variable von der Struktur im EEMEM an wobei sich EEMEM wahrscheinlich auf das Interne EEPROM des uC bezieht. Ich benutze ja ein externes EEPROM, reicht es dann wenn ich es nur mit
1 | |
initialisiere? Falk B. schrieb: > Hier der Anhang. Clever auf jeden Fall. Wäre ich aber im Leben nie drauf gekommen mit Bit Operatoren da zu arbeiten ... Falk B. schrieb: > Ist das für einen Aquariumcontroller wichtig? Zeitkritisches habe ich eigentlich nix in meinem Projekt drin und wenn der pH Wert mal unter 6.80 sinken wird werden meine Fischis auch nicht davon sterben. Das einzige wovor ich immer Angst hatte war das sich mein Controller aufhängt während gerade das Magnetventil für die Co2 Zufuhr geöffnet ist, konnte ich aber relativ einfach mit dem Watchdog Timer beheben. Zudem hat er sich bis jetzt auch noch nie aufgehängt. gdgddfgdfd schrieb: > Das ist als Anfänger schön wenn da was steht , ist aber > oft auch totaler nonsins^^ Es hatte am Anfang wirklich mal ein Sinn gehabt, mein Controller hatte sich durch nicht ganz korrekte Verdrahtung und scheinbar Kapazitive Einkopplung der SCL und SCK Leitungen zu System Hängen geführt hat. Habe ich ein Start Up Bildschirm gemacht um zu sehen wo er sich aufhängt, es war auch mal eine Startzeit Messung drin aber das ist alles mittlerweile nicht mehr nötig. Hatte die Texte damals dennoch drin gelassen, können aber raus. Muss die main eh mal aufräumen und ein paar Funkionen entfernen und auslagern. gdgddfgdfd schrieb: > auch Lesbarkeit:if(menuSelector == 2) > ist nichtssagend. Ja ich weiß menuSelector, menuPointer, menuInlinePointer ... mir war damals nix besseres eingefallen. Falk B. schrieb: > Außerdem fehlt die CRC-Prüfung, das > kann bisweilen auch mal daneben gehen. Was macht deine Steuerung dann? Die sollte weiterlaufen liefert mir nur dann eine Temperatur von -0.06°C. Den Link werde ich mir mal anschauen. Falk B. schrieb: > In C nutzt man hier eher #define Ah ok. Ja die Lib kommt aus dem I-Net. Werde ich abändern. Schaue mir dann auch gleich mal die anderen Libs an ob es da noch sowas gibt. Theor schrieb: > Die Diskussion hier fokussiert sich Theor schrieb: > auf > eine Überarbeitung des Codes und hat Jor das wahr zwar eigentlich nicht mein Ziel. Aber der Richtung wechsel in die Code Optimierung finde gut. Bin gar nicht erst auf die Idee gekommen. Das der Flash wegen vielleicht falscher Programmierung voll ist. Da habe ich am Ende mehr von als wenn ich mir jedesmal ein neuen uC kaufen mit mehr flash/ram etc. Lg
Gast
#5968264
Armin K. schrieb: > as muss nicht Wasserdicht sein, da der AVR nicht im Aquarium ist ;-) Wäre aber möglich. Wir haben schon einen µC in Epoxyd eingegossen und unter Wasser betrieben. (Meine Idee war das nicht!) Wegen der Wärmeentwicklung (läuft an 24V) wurde aber ein Schaltregler eingesetzt. Funktioniert tatsächlich. ;-)
Gast
#5968327
Felix N. schrieb: >> Genauso die Linker-Optionen überprüfen, ob zum Beispiel LTO aktiv ist. > kann ich nicht finden. Weder als Checkbox noch in der Command Zeile. Ich empfehle diese Optionen: FLAGS = -Wall -O1 -fshort-enums -ffunction-sections -fdata-sections CFLAGS = -std=c99 CPPFLAGS = -fno-exceptions LDFLAGS = -lm -Wl,--gc-sections Zum Compilieren für *.c Dateien: FLAGS und CFLAGS Zum Compilieren für *.cpp Dateien: FLAGS und CPPFLAGS Zum Linken: FLAGS und LDFLAGS
Gast
#5968343
Erklärung: -Wall Aktiviert alle empfohlenen Warnungen (es gibt noch mehr, deswegen ist das Wort "all" irreführend). -O0 Optimiert gar nicht -O1 Optimiert auf Performance, geringfügig zu Lasten der Größe -O2 Optimiert auf Performance, mehr zu Lasten der Größe -O3 Optimiert auf Performance, ohne Rücksicht auf die Größe -Os Optimiert auf Größe, geringfügig zu Lasten der Performance -Og optimiert ein bisschen, soweit es den Debugger nicht stört -fshort-enums Die numerischen Werte von enums sind 8bit groß - Normal wären es 16bit -ffunction-sections -fdata-sections Diese beiden Optionen ermöglichen es dem Linker (nach dem Compilieren), den Code auseinander zu nehmen und unbenutzte Funktionen zu entfernen. -std=c99 Aktiviert Erweiterungen der Sprache C, die ich gerne benutze -fno-exceptions Deaktiviert das Exception-Handling in C++, was kompakteren Code ergibt. Dann kann man aber eben keine Exceptions mehr nutzen. Macht man auf µC eh nur selten. -lm Bindet die Math Library ein, für Fließkommazahlen --gc-sections Diese Optionen sagen dem Linker, dass er nicht verwendeten Code weg schmeißen soll. Wenn du in printf() Fließkommazahlen brauchst, dann brauchst du noch die LDFLAGS += -Wl,-u,vfprintf -lprintf_flt Für Fließkommazahlen in scanf(): LDFLAGS += -Wl,-u,vscanf -lscanf_flt
Stefanus F. schrieb: > Ich empfehle diese Optionen: > > FLAGS = -Wall -O1 -fshort-enums -ffunction-sections -fdata-sections > CFLAGS = -std=c99 zusätzlich: -mrelax -mcall-prologues und natürlich -Os statt -O1. Stefanus F. schrieb: > -fshort-enums Die numerischen Werte von enums sind 8bit groß - Normal > wären es 16bit Das ist allerdings keine Optimieruns-Option, sonder wählt ein anderes ABI. > -lm Bindet die Math Library ein, für Fließkommazahlen Braucht man schon seit X Jahren nicht mehr.
Felix N. schrieb: > Ja da bin ich im Moment noch am Überlegen was mehr Sinn macht. Das > Projekt neu Anlegen und den alten Code Schritt weiße übernehmen und > dabei überarbeiten. Ja! neu anlegen und gründlich überarbeiten, da sind locker 30% code reduction drin, hinweise gab es hier doch reichlich und mal klartext - dein code ist sehr "bescheiden" so im sinne von level two auf einer scala von 1-10. mit 128k kannst du bei dem project lange bis ewig leben, wenn du sinnig programmierst. und wenn noch nicht geschehen tausche auch die gcc version, gute erfahrung habe ich mit v8.3 bzgl. optimization. und für die ferne zukunft würde ich vielleicht mal esp32 mit micropython andenken, python macht richtig spass braucht aber auch einige zeit bis man das halbwegs drauf hat und pythonkenntnisse kann man immer gebrauchen auf allen plattformen als schweizer-messer oder als die eierlegende wollmilchsau! mt
Felix N. schrieb: > Habe ich dadurch irgendwelche Nachteile wenn ich das auf -Os umstelle? Nein. > Falk B. schrieb: >> Denn dieser Job gehört dem COMPILER! >> Der verwaltet die Adressen! > > Moment mal. Das heißt ich definiere gar nicht die Adressen fürs EEPROM, Ja. > sondern die werden dann Zufällig zugewiesen, Nicht ganz, aber im Normalfall ist die exakte Adresse einer Variable vollkommen egal. Das kann der Compiler zusammenbasteln wie er will. Es gibt Ausnahmen, logisch. > oder wie muss ich das > verstehen? Bei Structs legt der Compiler die Daten exakt so in der Reihenfolge an, wie sie aufgeschrieben sind. Aber er darf bisweilen Lücken einfügen, wenn es die Architektur verlangt oder es Vorteile bringt. > In deinem Struct Beispiel bezieht sich die 16 Bit > Variable(min_temperature) ja nicht auf den gelesen Wert vom EE Aber sicher! > sondern > auf die Adresse im EE wo der Wert liegt. > > Oder muss ich die Variablen einmal mit einer Adresse definieren? > my_struct.irgendwas = eeprom_adresse; NEIN! Ok, hier gibt es ein Mißverständnis. Beim internen EEPROM übernimmt der Compiler die Adressverwaltung, genauso wie im RAM oder ROM (Flash). Bei externem, seriellen Speicher ist der Compiler nicht beteiligt, dort muss man alles "zu Fuß" organisieren. Aber auch dort ist man gut beraten, zumindest teilweise die Funktionen des Compilers zu nutzen. Eben indem man einen Struct definiert und die Daten struc(block) weise in den externen Speicher schreibt bzw. von dort liest. > Falk B. schrieb: >> Ist das nicht DEUTLICH lesbarer und vor allem selbsterklärend? > > Ja auf jeden Fall. Aber eine Frage habe ich dazu noch du legt ja eine > Variable von der Struktur im EEMEM an wobei sich EEMEM wahrscheinlich > auf das Interne EEPROM des uC bezieht. Ich benutze ja ein externes > EEPROM, reicht es dann wenn ich es nur mitmy_struct my_ee;initialisiere? Nein, das geht leider nicht, siehe oben. Aber auch dann arbeitet man nicht derartig mit absoluten Adressen. > Falk B. schrieb: >> Ist das für einen Aquariumcontroller wichtig? > > Zeitkritisches habe ich eigentlich nix in meinem Projekt drin und wenn > der pH Wert mal unter 6.80 sinken wird werden meine Fischis auch nicht > davon sterben. Deine CPU wird so oder so tödlich gelangweilt sein, ganz egal wie ineffizient dein Programm ist. > Jor das wahr zwar eigentlich nicht mein Ziel. Aber der Richtung wechsel > in die Code Optimierung finde gut. Bin gar nicht erst auf die Idee > gekommen. Das der Flash wegen vielleicht falscher Programmierung voll > ist. Vor allem. Wenn du sie meisten (alle?) konstanten Strings in den Flash verlagerst (PROGMEM und so), dann wird massiv RAM frei und du kanst problemlos mit dem großen Bruder 2561 (aka Arduino Mega) mit 256kB Flash und 8kB RAM arbeiten, ohne ins Schwitzen zu kommen.
Felix N. schrieb: > Ja -O1 wird ja benutzt dort habe ich im Moment 98952 Bytes an Flash und warum 4K für den Bootloader wo 512 Byte reichen?
Apollo M. schrieb: > Ja! neu anlegen und gründlich überarbeiten Ja glaubig auch. Werde ich auch machen. Apollo M. schrieb: > nd wenn noch nicht geschehen tausche auch die gcc version, gute > erfahrung habe ich mit v8.3 bzgl. optimization. Nein ich benutze die GCC Version 5.4.0 die Version 8.3.0 kann ich nicht finden habe nur die AVR-GCC 9.2.0 gefunden zum Downloaden: http://blog.zakkemble.net/avr-gcc-builds/ Jedoch scheint da irgendwas faul zu sein. Beim Kompilieren meckerte er erst bei der Zusatz Option "unrecognized debug output level 'c-sections'" habe dann -gc-sections entfernt dann konnte ich Kompilieren jedoch habe ich nun 0 Bytes Flash und 0 Bytes RAM Belegung. Yeah! Oder auch irgendwie nicht. Er lädt zumindest immer mein altes Programm hoch welches ich mit GCC 5.4.0 Kompiliert habe. Habe nur die neuen Daten der Toolchain in den bestehen Ordner der Toolchain im Atmel Studio Ordner geschoben und halt 5.4.0(Ordner) gelöscht. Falk B. schrieb: > Aber sicher! OK? Falk B. schrieb: > eeprom_write_word(&my_settings.max_temperature, max); Da ich die interen EEPROM Funktion des AVRs nicht nutze habe ich mir mal kurz die Funktion angeschaut und der erste Parameter ist die Adresse im EEPROM der zweite Parameter der Wert. Das heißt doch folglich dann wenn du als erstes die Variable aus der Struktur(max_temperature) übergibt als 1en Paramter das in dieser Variable(max_temperature) nicht Wert steht sondern nur die EEPROM Adresse die vom Kompiler vergeben wird steht. Und das der zweite Parameter(max) die Variable ist welchen den eigentlichen Wert enthält der ins EEPROM geschrieben werden soll. Oder nicht? Falk B. schrieb: > Ok, hier gibt es ein Mißverständnis. Beim internen EEPROM übernimmt der > Compiler die Adressverwaltung, genauso wie im RAM oder ROM (Flash). Bei > externem, seriellen Speicher ist der Compiler nicht beteiligt, dort muss > man alles "zu Fuß" organisieren. Sorry habe mit diesen Strukturen noch nie gearbeitet. Absolutes Neuland für mich. Wenn ich das Interne EEPROM nutze brauch ich mir keine Gedanken machen um die Adressen im EEPROM. Nutze ich(wie jetzt) ein externes EEPROM muss ich diese ihm einmal Mitteilen. Würde das jetzt so machen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
Falk B. schrieb: > Nein, das geht leider nicht Muss ich dieses Struktur überhaupt initialisieren, ich meine du hast dort ja ein Datentyp im EEPROM anlegt. Kann ich dann direkt damit arbeiten sprich wie im meinem Beispiel oben? Joachim B. schrieb: > und warum 4K für den Bootloader wo 512 Byte reichen? Der Controller liegt schon seit ein paar Jahren bei mir(so 2016) den habe ich damals fertig mit Bootloader bei unserem ehemaligen Elektronikshop um der Ecke gekauft, für glaubig 10 Eur. Dort sagte man mir es ist schon ein Bootloader drauf der würde ca. 4 Kb vom Flash in Anspruch nehmen. Aber gut zu wissen dann kann ich den neuen ja mal bei Gelegenheit drauf brennen. Mfg
Felix N. schrieb: > Nein ich benutze die GCC Version 5.4.0 die Version 8.3.0 kann ich nicht > finden habe nur die AVR-GCC 9.2.0 gefunden zum Downloaden: Warum nimmst du nicht einfach Atmelstudio? Dort ist alles fix und fertig drin. Dieses Rumgehacke mit Kommandozeile und Dutzenden Parametern ist gerade für Anfänger wie du schlicht Unsinn. >> eeprom_write_word(&my_settings.max_temperature, max); > > Da ich die interen EEPROM Funktion des AVRs nicht nutze habe ich mir mal > kurz die Funktion angeschaut und der erste Parameter ist die Adresse im > EEPROM der zweite Parameter der Wert. Ja. > Das heißt doch folglich dann wenn du als erstes die Variable aus der > Struktur(max_temperature) übergibt als 1en Paramter das in dieser > Variable(max_temperature) nicht Wert steht sondern nur die EEPROM > Adresse die vom Kompiler vergeben wird steht. Und das der zweite > Parameter(max) die Variable ist welchen den eigentlichen Wert enthält > der ins EEPROM geschrieben werden soll. Ja sicher. Wo liegt das Problem? > Wenn ich das Interne EEPROM nutze brauch ich mir keine Gedanken machen > um die Adressen im EEPROM. Nutze ich(wie jetzt) ein externes EEPROM muss > ich diese ihm einmal Mitteilen. So einfach ist es nicht. Weig gesagt, bei externem EEPROM muss man vieles manuell machen. Man kann es nur dahingehend vereinfachen bzw. dem "Normalfall" angleichen, indem man z.B. beim Start einen Datenblock aus dem externen EEPROM in ein struct vom gleichen Typ in den RAM kopiert. Dann hat man alle Einstellungen im RAM und kann dort beliebige Schreib/Lesezugriffe machen. Irgendwann muss man dann aber die Daten vom RAM wieder in den EEPROM kopieren, damit sie dauerhaft erhalten bleiben. Auch das macht man meist sinnvoll als Datenblock und nicht mit Einzeldaten. Würde das jetzt so machen: > typedef struct { //Struktur definieren > uint8_t: karbonathaerte; > uint8_t: benutzeDimmung; > uint8_t: pHSoll; > ... > } my_eepromAddress; Das ist nicht ganz richtig. typedef definiert einen Datentyp, keine Variable. Und schon gar nicht eine Adresse! Solche Namen sind maximal irreführend! Die Variable muss dann im 2. Schritt normal definiert werden, wie in meinem Beispiel. Man kann zwar auch direkt eine Variable als struc anlegen, ohne einen Typ zu definieren, das ist aber meistens ungünstig. Näheres erklärt dir ein C-Buch. > void setEEEPROMAddress(void) { //EEPROM Adressen einmal während des > Startup laden Falsch. Adressen werden nicht geladen. Gewöhn dir eine klare, saubere Sprache bzw. Beschreibung/Namensgebung an, sonst wurschtelst du nur rum. Strukturierte Programmierung auf Mikrocontrollern > my_eepromAddress.karbonathaerte = 0x01; > my_eepromAddress.benutzeDimmung = 0x02; > my_eepromAddress.phSoll = 0x03; Was du meinst ist das Laden der EEPROM-Werte mit einem Startwert oder Standardwert. Das kann der Compiler selber. struct my_settings EEMEM = {1, 2, 3}; Damit wird vom Compiler ein .eep File (Intel-HEX) erzeugt, daß ebenso wie der Flash einfach in den AVR programmiert wird. Damit hast du im internen EEPROM initialisierte Daten stehen. Beim externen EEPROM geht das freilich nicht. Da ist wieder Handarbeit angesagt.
Falk B. schrieb: > struct my_settings EEMEM = {1, 2, 3}; Die bessere Schreibweise ist:
1 | |
2 | |
3 | |
4 | |
5 | |
Es müssen auch nicht alle Elemente initialisiert werden, die nicht aufgefürten werden mit 0 initialisiert.
Gast
#5968774
Felix N. schrieb: > Da ich die interen EEPROM Funktion des AVRs nicht nutze habe ich mir mal > kurz die Funktion angeschaut und der erste Parameter ist die Adresse im > EEPROM der zweite Parameter der Wert. ich greife das nochmal auf. Wenn er immer den externen nutzt. muss er es eh anders machen. der compiler kennt den externen nicht hier muss man dieses struct bei der init auf die startadresse des externen eeprom setzen. bei einem neugerät kann man am anfang des struct ein flag setzen default sind die externen auf 0xFF gesetzt. wenn 0xFF im ersten byte an adresse 0x0000 steht kann der µC seine default werte in den externen EEPROM schreiben also auch das erste byte auf einen anderen wert setzen
Gast
#5968833
Felix N. schrieb: > Arno schrieb: >> Ich möchte nochmal auf diese Frage hinweisen - ob mit -O0 oder -Os >> kompiliert wird, dürfte die Programmgröße massiv beeinflussen. > > Habe mal unter AVR/GNU C Compiler -> Optimization nach geschaut dort > steht drin: Optimization Level: Optimize(-O1). > > Ich habe es mal testweise umstellt bei -O0 kann ich erst gar nicht > kompilieren dort kommt der Fehler: "region `text' overflowed by 14018 > bytes" Also statt 98kB 142kB (128kB plus 14kB, die nicht mehr in den Speicher passen). > Ja -O1 wird ja benutzt dort habe ich im Moment 98952 Bytes an Flash und > 6853 Bytes an SRAM. Mit -Os habe ich 89932 Bytes Flash und 6893 Bytes an > SRAM. > > Habe ich dadurch irgendwelche Nachteile wenn ich das auf -Os umstelle? Es wird an der einen oder anderen Stelle ein bisschen langsamer sein. Hast du gerade ein Zeit- oder ein Speicherplatzproblem? (rhetorische Frage) > Arno schrieb: >> Genauso die Linker-Optionen überprüfen, ob zum Beispiel LTO aktiv ist. > > Kann ich nicht finden. Weder als Checkbox noch in der Command Zeile. Das, was ich meinte, ist: Stefanus F. schrieb: > Erklärung: > > -ffunction-sections -fdata-sections Diese beiden Optionen ermöglichen es > dem Linker (nach dem Compilieren), den Code auseinander zu nehmen und > unbenutzte Funktionen zu entfernen. > > --gc-sections Diese Optionen sagen dem Linker, dass er nicht verwendeten > Code weg schmeißen soll. Wichtig bei --gc-sections: Das muss direkt nach -Wl, stehen, ohne Leerzeichen. Denn damit weiß der Compiler, dass er das einfach so an den Linker weiterreichen soll (sonst kommt die Fehlermeldung, die du gesehen hast, denn der Compiler versteht --gc-sections nicht). Also genau wie von Stefan geschrieben: -Wl,--gc-sections MfG, Arno
Gast
#5968920
Hab das bei mir mal durchlaufen lassen mit meinen Standardoptionen (-Os): avr-size release/aqutest.elf text data bss dec hex filename 86024 3410 3597 93031 16b67 release/aqutest.elf Ist natürlich komplett ungetestet. Arbeitest du mit Debugger und Debuginfos im Code? Ich helfe mir da immer so, dass ich in meinem makefiles den Code in 2 Gruppen teile. Einmal den der mit -Os optimiert bleibt und der andere der mit -O0 zum Debuggen von der Optimierung befreit ist. Aber schon Ewigkeiten nicht mehr mit AVRs sondern mit Cotexen. Höchstens mal noch einen tiny841. Das meiste im bss dürften deine Strings belegen wie schon gesagt wurde, in soweit hast du da noch Optimierungsmöglichkeiten wenn du auf den größeren AVR umsteigst. Auf den Flash hat das kaum Auswirkung. Wenn du den RAM nicht anderweitig brauchst ist es verschenkte Lebenszeit das nur zur Optik anders zu machen. Ob du mit Änderungen am eigenen Code 30% sparen kannst wie hier behauptet wird, wage ich zu bezweifeln da der Verhältnis zu den Libs schon nicht mehr als 30% ist. Wenn du 10 Leute fragst wie guter Code aussieht kriegst du 10 Meinungen und jeder findet seinen Stil am besten. Traue auch keinen der großspurige Behauptunge in der Form: "das macht man doch nicht!" von sich gibt. Das ist in der Regel nur nachgeplappertes Geschwätz. Für ein komplettes Redesign würde ich dir den Umstieg auf einen Cortex Mx empfehlen. Allerdings nur wenn dir die Lernphase einen Zusatznutzen bringt. Die Zeit die du bis jetzt darauf verwendet hast dürfte nochmal draufgehen. Auf alle Fälle gibt es in diesem Bereich mehr fertige Boards als für große AVRs. z.B. https://www.hotmcu.com/lpc1768minidk2-development-board-28-tft-lcd-p-12.html?cPath=1_21&zenid=tdo7s5kaoj499q667hl9du1rl7 Auch wenn die ESPxxxx Controller massiv Flash und Ram haben und auch schnell sind, die bescheidenen Debugmöglichkeiten wären für mich ein NoGo für größere Projekte. Höchstens als Interface für BLE oder WLAN in einer Mehrcontrollerumgebeung.
Gast
#5969048
Moin, also ICH würde zunächst einige der Verbesserungsvorschläge einarbeiten, z.B. Texte ins EE, Menüstruktur, Funktionen und Unterprogramme mehr nutzen. Dann ergibt sich wahrscheinlich eine deutliche Reduktion der Codegröße, zumindest für das RAM, aber wahrscheinlich auch für das Flash. Und zu lernen, wie man effizienter programmiert, kann grundsätzlich nicht schädlich sein, egal für welches System. Der Ruf nach stärkerer Hardware ist immer die Nullösung für schlechte Programmierung. Und wenn es wirklich zu knapp werden sollte, dann umsteigen auf eine Art "Mega256 als Nano", der sich auch in eigene Platinen per THT einlöten läßt: https://www.mikrocontroller-elektronik.de/mini-controllerboard-mit-atmel-atmega2560-und-usb/ Und wenn 256 kB für eine Aquariensteuerung nicht ausreichen, dann sollte man das wirklich ganz lassen, denn dann muß die dermaßen mit Funktionen oder Gimmicks überfrachtet sein, daß die Regelung vermutlich viel zu unzuverlässig wird... ;-))
svensson schrieb: > Und wenn es wirklich zu knapp werden sollte, dann umsteigen auf eine Art > "Mega256 als Nano", der sich auch in eigene Platinen per THT einlöten > läßt: > https://www.mikrocontroller-elektronik.de/mini-controllerboard-mit-atmel-atmega2560-und-usb/ Schönes Marketinggefasel! >Leistungsstarker Controller ATMega2560 (einer der wohl leistungsfähigsten > 8 Bit AVR-Controller überhaupt), 100 Pins am Gehäuse, BlaBla. Der CPU-Kern ist bei allen AVRs praktisch gleich und damit gleich leistungsfähig. Nur die Speichergröße sowie IO-Module variieren >256.000 Bytes Flash Speicher Jaja, große Zahlen braucht das Land! Warum nicht gleich 2048000 Bit? Außerdem sind es 256KiB, was 262144 Bytes entspricht. https://de.wikipedia.org/wiki/Binärpräfix >8000 Byte RAM >4000 Bytes EEPROM Dito.
Gast
#5969127
svensson schrieb: > Und wenn 256 kB für eine Aquariensteuerung nicht ausreichen, dann sollte > man das wirklich ganz lassen, denn dann muß die dermaßen mit Funktionen > oder Gimmicks überfrachtet sein, daß die Regelung vermutlich viel zu > unzuverlässig wird... ;-)) Bevor du weiter faselt, lade dir das Programm mal runter. Bei ihm machen im Moment die Libs den meisten Teil aus. Ethernet, Filesystem, Grafik und Kommunikation belegen da schon eine ganze Menge. Und was er für sich für Funktionen und Gimmicks einbaut war weder die Frage noch geht es dich was an. Und wieso sollte der Flashverbrauch irgendwelchen Einfluss auf die Geschwindigkeit einer Temperaturregelung haben?
Gast
#5969160
@Falk Mir ging es auch nicht um den Inhalt der Seite (den habe ich mir gar nicht angesehen), sondern um die Bauform (Bilder). Das einzig entscheidende Kriterium ist, daß der Mega256 eben 256 kB Flash hat, was einer Verdoppelung zur jetzigen Situation gleichkäme. Wenn ich es richtig verstanden habe, nutzt der TE jetzt die DIL-Bauform, d.h. er lötet das Dingens irgendwo ein oder nutzt ein Steckbrett. Bei dem gezeigten Beispiel wäre das eben, sogar relativ einfach, auch so möglich. @temp Nun aus langjähriger Erfahrung kann ich sagen, KISS (keep it simple and stupid) gilt immer, läßt sich sogar mathematisch beweisen. Es gäbe auch noch die Möglichkeit, das ganze Projekt in Teilbereiche aufzuteilen, z.B. Regelaufgaben und Datenlogging/Aufbereitung der Meßwerte zu trennen.
Gast
#5969228
habe was gefunden wo er sparen kann aus der main.c folgende zeilen vor der loop entfernen:
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 | |
dann kann er die _delay_ms(1500); auch entfernen Das sind infos zum start die anfangs zum debugging vlt brauchbar sind .. aber am gerät später keinen nutzen haben
Felix N. schrieb: > Nein ich benutze die GCC Version 5.4.0 die Version 8.3.0 kann ich nicht > finden habe nur die AVR-GCC 9.2.0 gefunden zum Downloaden: > > http://blog.zakkemble.net/avr-gcc-builds/ ... die gcc v8.3 findest du auch bei zakkemble, du nimmst den link der 9.2 und ersetzt entsprechend auf 8.3.0. ich benutze atmelstudio und kann bei mir via script mit einem klick zwischen den versioen 5.4-9.2 wechseln. ABER! ... du musst immer die 5.4 avr_size.exe nehmen sonst wird dir bzgl. used code size müll angezeigt. UND! ... zum debuggen eher auch die 5.4 nehmen, weil atmel studio sonst ein problem hat beim anzeigen mit den variables/symboles. mt temp schrieb: > Auch wenn die ESPxxxx Controller massiv Flash und Ram haben und auch > schnell sind, die bescheidenen Debugmöglichkeiten wären für mich ein > NoGo für größere Projekte. der esp32 lässt sich z.b. unter vsc einfach/vollständig debuggen, also kein problem, wenn man ahnung hat!
Der AVR-GCC hat eine CommandLineOption -mcall-prologues mit der er (gegen minimalste Extralaufzeit) die Push/Pop-Orgien am Anfang/Ende von Funktionen optimiert. Wenn man also die 128k Flash nicht nur mit Bitnaps, sondern auch mit ausführbarem Code belegt hat, dann spart das eventuell die entscheidenden 5%. Oder man versucht mal mit -flto in der Compiler-CommandLine Link-Time-Optimization. Dabei wird der ganze Code über alle C-Files hinweg optimiert. Letzteres muß nicht auf Anhieb funktionieren, aber das deutet dann eher auf Ungereimtheiten im Code hin, ganz so wie "das Programm läuft nur mit -O0". "Call-Prologs" ist aber völlig transparent und dürfte keine Probleme machen. Wenn man LTO nicht probieren will/kann, dann auf alle Fälle alle Funktionen die nicht von außerhalb ihres Source-Files gerufen werden, als "static" definieren. Dann spart sich der Compiler den Call eventuell ganz. Schneller und kleiner!
Hallo alle miteinander, Falk B. schrieb: > Warum nimmst du nicht einfach Atmelstudio? Nutze ich doch. Ich habe mal ein Bild angehängt um nun die Frage zgl. welche IDE ich benutze hochgeladen. Falk B. schrieb: > Ja sicher. Wo liegt das Problem? Weil ich oben gefragt ob sich die Variable(min_temperature) nicht auf den gelesen Wert vom EE bezieht sondern nur auf die Adresse. Falk B. schrieb: >> In deinem Struct Beispiel bezieht sich die 16 Bit >> Variable(min_temperature) ja nicht auf den gelesen Wert vom EE > > Aber sicher! Ich habe jetzt unter "Aber sicher" verstanden, das sie doch den gelesen Wert enthält und nicht die Adresse. Aber das hat sich ja nun geklärt. Falk B. schrieb: > Näheres erklärt dir ein C-Buch. Irgendwie check das immer noch nicht mit den Strukturen. Aber ich habe mal in mein Buch rein geschaut dort wird es so erklärt:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
Falk B. schrieb: > Gewöhn dir eine klare, saubere > Sprache bzw. Beschreibung/Namensgebung an Werde ich versuchen. gdgddfgdfd schrieb: > muss er es eh anders machen. > der compiler kennt den externen nicht Das heißt ich muss einmal beim Programmstart die Variablen in der Struktur die passenden EEPROM Adressen zuweisen, zb. im EEPROM steht unter der Adresse 0x0A der Wert der Karbonathärte also muss ich einmal struktur.karbonathaerte = 0x0A machen? Arno schrieb: > Wichtig bei --gc-sections: Das muss direkt nach -Wl, stehen, ohne > Leerzeichen. Ah danke jetzt tut es. svensson schrieb: > Wenn ich es richtig verstanden habe, nutzt der TE jetzt die DIL-Bauform, > d.h. er lötet das Dingens irgendwo ein oder nutzt ein Steckbrett. Früher Steckbrett hat aber zu viele Probleme mit Kapazitive Einkopplungen gemacht habe mir dann eine Platine ätzen lassen. Wenn ich wirklich auf den 2560 umsteige mache ich eh wieder eine neue Platine da teile der jetzigen Platine nicht mehr gebraucht werden. Dann kann ich auch gleich den IC in SMD drauf löten. gdgddfgdfd schrieb: > Das sind infos zum start die anfangs zum debugging vlt brauchbar sind .. > aber am gerät später keinen nutzen haben Es war mal zum Debuggen nötig: Felix N. schrieb: > Es hatte am Anfang wirklich mal ein Sinn gehabt, mein Controller hatte > sich durch nicht ganz korrekte Verdrahtung und scheinbar Kapazitive > Einkopplung der SCL und SCK Leitungen zu System Hängen geführt hat. Habe > ich ein Start Up Bildschirm gemacht um zu sehen wo er sich aufhängt, es > war auch mal eine Startzeit Messung drin aber das ist alles mittlerweile > nicht mehr nötig. Ist aber nun entfernt. Apollo M. schrieb: > ... die gcc v8.3 findest du auch bei zakkemble, du nimmst den link der > 9.2 und ersetzt entsprechend auf 8.3.0. Habe es gefunden. Apollo M. schrieb: > ABER! Apollo M. schrieb: > UND! Ich lasse es erstmal bei 5.4.0 und werde mich erstmal um mein Programm kümmern. Das wird mir sonst alles zu kompliziert. Mfg
Gast
#5969618
Ich würde dir empfehlen: Code optimieren, aber nicht komplett neu anlegen, auch nur die wichtigsten Sachen optimieren, keine riesigen Sachen, dann auf den mit 256kb umsteigen. Auf gar keinen Fall würde ich die Plattform wechseln, da investierst du locker mal 100h nur fürs umprogrammieren, einlesen, Entwicklungsumgebung aufsetzen, etc. musst du noch draufrechnen. Wirklich hübschen Code würde ich beim nächsten Projekt von Anfang an schreiben, das jetzt groß umändern, kostet einfach viel Zeit.
Falk B. schrieb: > So einfach ist es nicht. Weig gesagt, bei externem EEPROM muss man > vieles manuell machen. ... eigentlich nicht, wenn man es sinnig angeht. z.b. - zuerst mal die extEEprom read/write byte/word/block functionen schreiben, die i2c oder spi oder parallel angetrieben sind. - dann ein struct z.b. extEE definieren wo ALLE anderen struct's , variablen drin sind. also die struct extEE ist ein "data container" - nun einen ptr pExtEE mit z.b. addr=0 (ext eeprom start addr) auf die extEE struct definieren und dann entsprechend mit pExtEE-> und den extEE read/write functions drauf zugreifen. so what?
Felix N. schrieb: > Irgendwie check das immer noch nicht mit den Strukturen. Aber ich habe > mal in mein Buch rein geschaut dort wird es so erklärt: Ist OK. >> muss er es eh anders machen. >> der compiler kennt den externen nicht > > Das heißt ich muss einmal beim Programmstart die Variablen in der > Struktur die passenden EEPROM Adressen zuweisen, Nein! Du musst die Daten vom externen EEPROM in eine Kopie im RAM laden. Man könnte auch immer direkt mit dem Zugriff auf den externen EEPROM arbeiten, aber das ist meist deutlich ungünstiger. > zb. im EEPROM steht > unter der Adresse 0x0A der Wert der Karbonathärte also muss ich einmal > struktur.karbonathaerte = 0x0A machen? Du verwechselt irgendwie permanent die Adresse mit dem Inhalt einer Variablen. > Wenn ich wirklich auf den 2560 umsteige mache ich eh wieder eine neue > Platine da teile der jetzigen Platine nicht mehr gebraucht werden. Dann > kann ich auch gleich den IC in SMD drauf löten. Naja, kauf dir lieber einen Arduino Mega und bastel dir einen passenden "Shield" dafür. > Ich lasse es erstmal bei 5.4.0 und werde mich erstmal um mein Programm > kümmern. Das wird mir sonst alles zu kompliziert. Gute Wahl! Einen Vielfrontenkrieg gewinnt man nicht! (Urdeutsche Erkenntnis . . .)
Gast
#5969639
Falk B. schrieb: > Einen Vielfrontenkrieg gewinnt man nicht! (Urdeutsche > Erkenntnis . . .) Doch, ich weiß wie das geht.
Felix N. schrieb: > svensson schrieb: >> Wenn ich es richtig verstanden habe, nutzt der TE jetzt die DIL-Bauform, >> d.h. er lötet das Dingens irgendwo ein oder nutzt ein Steckbrett. > > Früher Steckbrett hat aber zu viele Probleme mit Kapazitive > Einkopplungen gemacht habe mir dann eine Platine ätzen lassen. > > Wenn ich wirklich auf den 2560 umsteige mache ich eh wieder eine neue > Platine da teile der jetzigen Platine nicht mehr gebraucht werden. Dann > kann ich auch gleich den IC in SMD drauf löten. Der 2560 hat ein External Bus Interface. Da kannst Du z.B. extern noch ein 32kb RAM anschließen. Z.B. https://www.reichelt.de/sram-32-kb-4-k-x-8-4-5-5-5-v-tsop-28-62256-70-m-p40086.html?r=1 Das liegt dann direkt im Adressraum des Prozessors wie das interne RAM auch, und für 1.45€ kann man das ruhig auf Vorrat verbauen. Und Du kannst zusätzlich ein TFT-Display daran anschließen, z.B.: https://www.buydisplay.com/default/serial-spi-3-2-inch-tft-lcd-module-display-ili9341-power-than-sainsmart Das könnte zwar auch SPI, aber die Ansteuerung über das External Bus Interface geht VIEL schneller (Faktor 5 und mehr), weil jeder TFT-Registerzugriff nur ein einziger Speicherzugriff ist. Schneller kann man keine Daten in das Display reinbekommen. fchk
tschut tschut schrieb: > Wirklich hübschen Code würde ich beim nächsten Projekt von Anfang an > schreiben, das jetzt groß umändern, kostet einfach viel Zeit. ... das klingt nach blümchen sex! wir reden hier über neudeutsch refactoring! und das ist immer sinnvoll. coding ist art ... ich habe kein project/program wo ich nicht gefüllt den code 2-3mal fast neugeschrieben habe - in teilen sogar x-mal neu. und da ging es nicht darum wie z.b. in c sinnig programmiert wird, sondern wie ein problem/aufgabe sinnvoll abgebildet wird bzgl. structure, algorithm, data abstruction, use of rtos, ... mit jeder itteration lernt man dann fett was dazu (hoffentlich). mt
tschut tschut schrieb: > Auf gar keinen Fall würde ich die Plattform wechseln, > da investierst du locker mal 100h nur fürs umprogrammieren, einlesen, > Entwicklungsumgebung aufsetzen, etc. musst du noch draufrechnen. Autsch. Da könnte man ja was bei lernen. Das Denken ist zwar allen Menschen erlaubt, aber vielen bleibt es erspart. Mal ein Schwank aus meiner Kindheit: Ich habe 1981 mit Z80 Assembler angefangen (C existierte zwar, war aber wenig verbreitet). Nach 6 Monaten war ich soweit, dass ich die wichtigsten der 300 Opcodes im Kopf hatte und meine Programme direkt als hexdumps eingeben konnte. An der Wand hingen seitenweise Spickzettel mit Befehlslisten und Codierungen. Mein Rechner hatte keinen Assembler, nur einen Disassembler. Als ich dann einige Jahre später 6502 angefangen hhabe, brauchte ich nur noch 6 Wochen, um genauso produktiv zu sein. Genauso ist es hier: Kennst Du einen, kennst Du alle. Ja, Register, Bitbelegungen und andere Details sind zwar anders, aber Technik, Vorgehensweise und Grundlagen bleiben. Und bei Dir wird sogar noch die Programmiersprache die gleiche bleiben. Mann, hast Du es heute gut. Wir früher... fchk
Gast
#5969691
Frank K. schrieb: > Mal ein Schwank aus meiner Kindheit: Im Sandkasten habe ich eine kleine Schaufel gehabt. Heute nehme ich zum Blumenumtopfen einen Bagger. Meintest Du das? Die Tage hat hier jemand eine Möglichkeit gesucht, eine LED mit einem I7 blinken zu lassen:Beitrag "LED blinken mit Intel core i7" Hattest Du ihm dazu geraten?
Mal (eine) ganz simple Frage(n) an den TO: Gibt es einen Grund den Debug-Build zu benutzen? Wird ein Sourcecode-Debugger benutzt? Falls die letze Frage nicht mit eindeutigem JA beantwortet werden kann: Ein Release-Build mit -Os kommt auf 97017 Byte Flash. Da ist noch Luft. Und es ist nicht erkennbar, daß irgend ein Code vom Makro "DEBUG" abhängen würde. Wie auch immer man so einen Berg Code zu laufen bekommt, ohne irgendwie zu debuggen. Ich könnte es nicht. Nachtrag: Die SD-Lib braucht viel Flash für die Benutzung langer Filenamen inclusive Unterstützung der Codepage 1250. Wird das wirklich gebraucht? WCHAR (16bit) Zeichenverarbeitung paßt einfach besser zum i7 als zum AVR.
Gast
#5969697
Carl D. schrieb: > [...] > Wie auch immer man so einen Berg Code zu laufen bekommt, > ohne irgendwie zu debuggen. Ich könnte es nicht. Was man mal lobend hervorheben könnte. Es muss ungeheure Energie dazu gehören, mit den verwendeten unzureichenden Methoden und geringen Kenntnissen so weit zu kommen. Ein Paradebeispiel für "die harte Tour". Hut ab und alle Achtung. Auch wenn es doch etwas tragisch ist.
m.n. schrieb: > Frank K. schrieb: >> Mal ein Schwank aus meiner Kindheit: > > Im Sandkasten habe ich eine kleine Schaufel gehabt. Heute nehme ich zum > Blumenumtopfen einen Bagger. Meintest Du das? > > Die Tage hat hier jemand eine Möglichkeit gesucht, eine LED mit einem I7 > blinken zu lassen:Beitrag "LED blinken mit Intel core i7" > Hattest Du ihm dazu geraten? Nein, davon distanziere ich mich. Ich bin kein Bastler, ich mach das beruflich. Und ich nehme dazu das, was am besten für die jeweilige Aufgabe geeignet ist, was Rechenleistung, Verlustleistung, Platzbedarf, Bauteilekosten, Leiterplattenkosten, Entwicklungsaufwand, Kundenwünsche usw usw angeht. Bei einem Bastler ist der Weg das Ziel. Von mir werden Ergebnisse erwartet, und meine Zeit ist teuer. Sehr teuer. Da ist es oft unterm Strich sinnvoller, bei der Hardware etwas größer als unbedingt notwendig zu dimensionieren, um dafür Entwicklungs-Zeit und damit -Kosten zu sparen. Ja, in diesem Forum gibts auch Spezialisten, die am liebsten alles in Assembler machen würden, um alles optimal und auf der kleinstmöglichen Hardware erledigen zu können. Im Echten Leben™ würde die gefeuert werden, weil die ihre Abgabetermine nicht einhalten würden und das kein Kunde bezahlen wollen würde. Dazu kommt: Ein 8-Bit Controller wie z.B. der ATMEGA2561-16AU für 10.83€ (aktueller Digikey-Preis) ist heutzutage kommerziell nur noch interessant, wenn man an die Architektur gebunden ist. Selbst wenn 5V VCC und 5V IO gefordert sind, gibts beispielsweise den 16 Bit DSPIC33EV256GM106-I/PT mit mehr und besserer Peripherie, mehr RAM und wesentlich mehr Rechenleistung im gleiche Gehäuse (TQFP64 im 0.5mm Raster) für 3.82€. Jetzt erklär mir mal jemand, warum ich unbedingt eine technisch schlechtere Alternative zum 3-fachen Preis nehmen soll, wenn Binärkompatibilität keinerlei Rolle spielt. Die Aquariumsteuerung hätte ich mit dem von mir anfangs erwähnten Olimex-Board und einem passenden TFT-Touch-Display und einer Implementation in Phython in ein paar Tagen fertig gehabt. Das mal als Vergleich, was die Produktivität angeht. Klar, Webservice, Mail, SD-Karten-Unterstützung und das Malen von Pixeln auf ein Display sind Sachen, die dann einfach da sind und funktionieren. Um schnell zu Ergebnissen zu kommen, ist das der bessere Weg. Ja, ich weiß, dass es viele Leute gibt, die da anderer Meinung sind, aber das ist halt so. fchk PS: Irgendwelche Argumente von wegen Open Source, GPL, Community sind mir egal. Ich habe es nicht so mit Ideologien, und GPL-Code darf ich in meinen beruflichen Projekten eh im Allgemeinen nicht verwenden.
Gast
#5969752
Frank K. schrieb: > Ich bin kein Bastler, ich mach das beruflich. Und ich nehme dazu das, > was am besten für die jeweilige Aufgabe geeignet ist, was > Rechenleistung, Verlustleistung, Platzbedarf, Bauteilekosten, > Leiterplattenkosten, Entwicklungsaufwand, Kundenwünsche usw usw angeht. Das klingt sinnvoll. > Bei einem Bastler ist der Weg das Ziel. Das ist Unsinn. Meine Hobbyprojekte verfolgen ein Ziel: Ich habe eine Idee und ich will ein funktionierendes Gerät mit überschaubarem Aufwand. Es ist sicher nicht in meinem Sinne, möglichst lange daran zu pruckeln. Da es Einzelstücke sind, jucken mich ein paar Euro mehr an Bauteilekosten meist nicht. > Von mir werden Ergebnisse > erwartet, und meine Zeit ist teuer. Sehr teuer. Da ist es oft unterm > Strich sinnvoller, bei der Hardware etwas größer als unbedingt notwendig > zu dimensionieren, um dafür Entwicklungs-Zeit und damit -Kosten zu > sparen. So pauschal klingt das falsch: Ich habe früher Prüf- und Meßtechnik gemacht, individuelle Einzelstücke, da waren Materialkosten kein Thema. Geht man aber in die Entwicklung von Serienprodukten, sieht das deutlich anders aus. Da darf der Entwicklungsaufwand gerne ein paar Mannwochen größer werden, wenn die Hardware bei xxxxxx-Stück pro Jahr ein paar cent billiger zu fertigen ist.
Gast
#5969756
Frank K. schrieb: > Der 2560 hat ein External Bus Interface. Da kannst Du z.B. extern noch > ein 32kb RAM anschließen. Das hätte der Mega1280-V auch, aber der dürfte nicht auf die vorhandene Platine passen ohne Anpassungsarbeiten. Frank K. schrieb: > Dazu kommt: Ein 8-Bit Controller wie z.B. der ATMEGA2561-16AU für 10.83€ > (aktueller Digikey-Preis) ist heutzutage kommerziell nur noch > interessant ... Den Arduino 2560 PRO MINI bekommt man schon für ca. 7,50 und braucht nicht einmal SMD-Teile zu löten. Außerdem handelt es sich um ein privates Hobbyprojekt, also ein Einzelstück, an dem jetzt schon fast ein Jahr programmiert wird. Da spielt diese Summe doch nun wirklich keine Rolle. Wahrscheinlich wird das alles aber gar nicht notwendig werden, sofern der TE nicht noch weitere große Libs einbindet, denn 20kB sind ja noch frei. Und nach Optimierung wahrscheinlich eher 30-40kB.
Manfred schrieb: > So pauschal klingt das falsch: Ich habe früher Prüf- und Meßtechnik > gemacht, individuelle Einzelstücke, da waren Materialkosten kein Thema. > > Geht man aber in die Entwicklung von Serienprodukten, sieht das deutlich > anders aus. Da darf der Entwicklungsaufwand gerne ein paar Mannwochen > größer werden, wenn die Hardware bei xxxxxx-Stück pro Jahr ein paar cent > billiger zu fertigen ist. Klar, bei den Stückzahlen ist das klar. Bei meinem aktuellen Arbytegeber sind das aber nie mehr als xxx-Stück für etwa xxxxxx€ pro Stück. fchk
svensson schrieb: > Außerdem handelt es sich um ein privates Hobbyprojekt, also ein > Einzelstück, an dem jetzt schon fast ein Jahr programmiert wird. Da > spielt diese Summe doch nun wirklich keine Rolle. Siehst Du. Mir der gleichen Begründung hätte ich selber zu dem Olimex-Board für 36€ gegriffen und wäre innerhalb weniger Tage fertig gewesen. fchk
Gast
#5969948
Frank K. schrieb: > svensson schrieb: > >> Außerdem handelt es sich um ein privates Hobbyprojekt, also ein >> Einzelstück, an dem jetzt schon fast ein Jahr programmiert wird. Da >> spielt diese Summe doch nun wirklich keine Rolle. > > Siehst Du. Mir der gleichen Begründung hätte ich selber zu dem > Olimex-Board für 36€ gegriffen und wäre innerhalb weniger Tage fertig > gewesen. Es geht aber nicht um Dich oder einen anderen erfahrenen Entwickler hier, sondern allein um den TO. Mancheiner hätte sich auch jede weitere Anschaffung sparen können und die Hardware einfach aus der Schublade gekramt - LIBs für den Rest inklusive. Frank K. schrieb: > Von mir werden Ergebnisse > erwartet, und meine Zeit ist teuer. Sehr teuer. Eventuell zu teuer? ;-)
Hallo nochmal, Apollo M. schrieb: > so what? Ich werde es mal versuchen umzusetzen. Falk B. schrieb: > Du verwechselt irgendwie permanent die Adresse mit dem Inhalt einer > Variablen. Ich werde es mir versuchen abzugewöhnen. Frank K. schrieb: > Der 2560 hat ein External Bus Interface. Da kannst Du z.B. extern noch > ein 32kb RAM anschließen. Z.B. Das ist dieses XMEM Interface. Für 1,45 Euro kann ich das wohl mit in einbauen. Anschlüsse habe ich ja so oder so genug am Ende. Muss nach der Code Optimierung mal einen neuen Schaltplan erstellen für den 2560. Carl D. schrieb: > Gibt es einen Grund den Debug-Build zu benutzen? > Wird ein Sourcecode-Debugger benutzt? Der Debug Build wahr voreingestellt und habe ihn auch nie umstellt. Nein es wird auch kein Sourcecode Debugger benutzt. Das einzige was ich mal zum "Debuggen" nutze sind Textnachrichten die ich an den UART sende. Carl D. schrieb: > Ein Release-Build mit -Os kommt auf 97017 Byte Flash. Da ist noch Luft. Ich habe mal das ganze auf Release umstellt jedoch habe ich keine vergrößern von Flash/RAM im Vergleich zu dem Debug Build. Habe alles im Release Build wieder eingestellt(-Wl,-gcc-section, -Os ...). Oder muss ich da noch was einstellen? Theor schrieb: > Hut ab und alle Achtung. Auch wenn es doch etwas tragisch ist. Soll ich das jetzt positiv oder negativ verstehen? Theor schrieb: > Es muss ungeheure Energie dazu gehören, mit den verwendeten > unzureichenden Methoden und geringen Kenntnissen so weit zu kommen. Puff naja, ich arbeite an diesem Projekt halt dann wann ich Lust und Laue dazu habe. Ja es steckt viel Arbeit drin jedoch kam es auch schon vor das ich am meinem Aquarium Controller Wochenlang nicht weiter programmiert habe. Und mit den geringen Kenntnissen naja je nach dem mit wem man mich nun vergleich oder? Ich habe 2014 das Programmieren in Java angefangen für ein Jahr habe ich mich mit Bukkit Plugins(Minecraft) versucht später dann ein bisschen Java an sich ohne Bezug auf Plugins. Seit 2016 habe ich mit den Mikrocontrollern angefangen. Kann mir gut vorstellen das wenn sich ein richtiger Programmier der eine Ausbildung gemacht hat und Beruflich damit zutun, sich mein Code anschaut das er fast vom Stuhl fällt. Habe mir halt alles selber erlernt das einzige Buch was ich über C habe ist "Grundlagen C von Jürgen Wolf". svensson schrieb: > ofern > der TE nicht noch weitere große Libs einbindet, denn 20kB sind ja noch > frei. Und nach Optimierung wahrscheinlich eher 30-40kB. Neue Libs sind erstmal nicht geplant. Ich werde jetzt die nächsten Tagen mein Projekt neu anlegen und den Code überarbeiten. Werde auf jeden Fall die ganzen Strings mit PSTR und PROGMEM überarbeiten. Floats entfernen und mit Integers arbeiten und mal schauen was ich noch verbessern kann. Frank K. schrieb: > wäre innerhalb weniger Tage fertig > gewesen. Das Ziel war für mich natürlich auch klar das es am Ende funktionieren soll. Ich habe dieses jedoch als langes Projekt geplant. Am Anfang war es nur ein Temperatur Messgerät mit Serieller Ausgabe dann kam ein 16x2 LC Display dann eine pH Messer wo man die Kalibrierten Spannung in den Code direkt eintragen musste. Und so hat sich das dann weiter entwickelt. ... Es war nicht Ziel dieses Projekt innerhalb von wenigen Tagen abzuschließen. Spaß an diesem Projekt habe ich besonders an der Software Entwicklung und auch an der Konstruktion an sich(Gehäuse, Bauteile, Platine, Kühlung etc..) Möchte mich aber bei euch allen bedanken für eure Hilfe und euren vielen Tipp und Ratschläge. Werde es die nächsten Tage angehen! Vielen Dank :)! Mfg
Felix N. schrieb: > das einzige Buch was ich über C habe ist "Grundlagen C von Jürgen Wolf". kannst du halbwegs in english was lesen/verstehen, dann schick ich dir ein "pdf-buchpacket" mit guten bookz zu C und mehr drumrum. wenn interesse pm an mich mit email. mt
Felix N. schrieb: > Hallo nochmal, > > Apollo M. schrieb: >> so what? > > Ich werde es mal versuchen umzusetzen. > > Falk B. schrieb: >> Du verwechselt irgendwie permanent die Adresse mit dem Inhalt einer >> Variablen. > > Ich werde es mir versuchen abzugewöhnen. > > Frank K. schrieb: >> Der 2560 hat ein External Bus Interface. Da kannst Du z.B. extern noch >> ein 32kb RAM anschließen. Z.B. > > Das ist dieses XMEM Interface. Für 1,45 Euro kann ich das wohl mit in > einbauen. Anschlüsse habe ich ja so oder so genug am Ende. > > Muss nach der Code Optimierung mal einen neuen Schaltplan erstellen für > den 2560. > > Carl D. schrieb: >> Gibt es einen Grund den Debug-Build zu benutzen? >> Wird ein Sourcecode-Debugger benutzt? > > Der Debug Build wahr voreingestellt und habe ihn auch nie umstellt. Nein > es wird auch kein Sourcecode Debugger benutzt. Das einzige was ich mal > zum "Debuggen" nutze sind Textnachrichten die ich an den UART sende. > > Carl D. schrieb: >> Ein Release-Build mit -Os kommt auf 97017 Byte Flash. Da ist noch Luft. > > Ich habe mal das ganze auf Release umstellt jedoch habe ich keine > vergrößern von Flash/RAM im Vergleich zu dem Debug Build. Habe alles im > Release Build wieder eingestellt(-Wl,-gcc-section, -Os ...). > > Oder muss ich da noch was einstellen? > Release-Build bedeutet hauptsächlich, daß nicht -O0, sondern -Os oder -O1/2/3 Größer als Debug-Builds werden die Release-Build (praktisch) nie. Wie schon geschrieben, im konkreten Fall ca. 97kB statt 142kB. > > Es war nicht Ziel dieses Projekt innerhalb von wenigen Tagen > abzuschließen. Spaß an diesem Projekt habe ich besonders an der Software > Entwicklung und auch an der Konstruktion an sich(Gehäuse, Bauteile, > Platine, Kühlung etc..) Wenn man die "extremen" Realtime-Anforderungen der aktuellen Version anschaut, nämlich praktisch keine, dann könnte man natürlich schon auf die Idee kommen, eine Raspi-Zero zu verwenden. Der hat Disk/Filesystem, Netzwerk, WLAN (wenn aktuelle Version), unmengen Speicher und Rechenleistung, komfortables OS, Python als relative einfache und doch mächtige Implementierungssprache, Webinterface inclusive und seinen Pinheader lassen sich die benutzten IO-Bausteine auch betreiben, wobei auf ein EEPROM nicht nötig ist, die Daten schreibt man einfach in ein File. Man braucht auch beim Rechnen keine Klimmzüge machen, denn das Ding kann Floatingpoint mit double Genauigkeit berechnen. AVR kann das nicht. Wenn also "Spaß" ein wesentlicher Faktor ist, dann kann man was anderes ausprobieren. Wobei so Raspi-Zero mit WLAN und Flas-Karte wenn überhaupt kaum mehr kostet, als ein Mega256n-Board mit ENC, ... Von fehlenden Nervenkitzel eines "selbstgeschriebenen" Filesystems oder Netzwerkstacks mal ganz abgesehen.
Carl D. schrieb: > Wenn man die "extremen" Realtime-Anforderungen der aktuellen Version > anschaut, nämlich praktisch keine, dann könnte man natürlich schon auf > die Idee kommen, eine Raspi-Zero zu verwenden. ... und selbst wenn man "Realtime-Anforderungen" hat, dann flanscht man per UART, SPI, etc. irgendeinen 08/15 Controller à la ATTiny dran und fertig.
Christopher J. schrieb: > Carl D. schrieb: >> Wenn man die "extremen" Realtime-Anforderungen der aktuellen Version >> anschaut, nämlich praktisch keine, dann könnte man natürlich schon auf >> die Idee kommen, eine Raspi-Zero zu verwenden. > > ... und selbst wenn man "Realtime-Anforderungen" hat, dann flanscht man > per UART, SPI, etc. irgendeinen 08/15 Controller à la ATTiny dran und > fertig. Notfalls, aber nachdem ich den aktuellen AVR-Code gesehen hab: etwas Zeitsteuerung, das man locker mit cron machen kann und was schneller reagieren muß, wie z.B. der Drehgeber, ist im Python machbar. Es gibt das sogar fertig auf https://thepihut.com/blogs/raspberry-pi-tutorials/how-to-use-a-rotary-encoder-with-the-raspberry-pi. BTW, habe ich weiter oben ganz vergessen: ein ordentliches Display kann man natürlich per HDMI auch dran hängen. Und sollte man keine Lust/Zeit für Frischfisch haben, kann ein größerer Monitor auch gleich eine Aquqrium-Simulation anzeigen. ;-)
Gast
#5970855
Wenn das Projekt auch eine Regelung des Aquariums ist, also Pumpen, Heizungen, Beleuchtung, Belüftung, Filtration, Denitrifikation usw. betreibt, dann würde ich unbedingt beim µC bleiben, weil das alles absolut zuverlässig funktionieren muß, sonst gehen die Tiere hops. Wenn es sich lediglich um die Darstellung von Meßwerten handelt, dann ist man natürlich völlig frei. Für animierte Grafiken per WLAN aufs Smartphone wäre ein Kleinstcomputer wie Raspi&Co sicherlich die bessere Wahl.
svensson schrieb: > Wenn das Projekt auch eine Regelung des Aquariums ist, also Pumpen, > Heizungen, Beleuchtung, Belüftung, Filtration, Denitrifikation usw. > betreibt, dann würde ich unbedingt beim µC bleiben, weil das alles > absolut zuverlässig funktionieren muß, sonst gehen die Tiere hops. Auch Unix-/Linux-System können jahrelang störungsfrei funktionieren, wenn Hardware, Betriebssystem und Anwendungssoftware von Leuten mit Ahnung entwickelt wurden. Das ist kein Entscheidungskriterium, sondern universelle Grundvoraussetzung. Andersrum: Der Linux-Code ist inzwischen so gut getestet und debuggt, dass die Wahrscheinlichkeit für Bugs um Zehnerpotenzen geringer ist als Code, den irgend so ein Anfänger aus Bruchstücken aus dem Netz zusammengerührt hat. Das gilt vor allem, wenn Fehler auftreten und beispielsweise die SD-Karte keine Lust mehr hat. Eine richtige Fehlerbehandlung hab ich in DEM Code hier nicht gesehen. Oder beispielsweise ein Watchdog. Nee, so wird das nix mit SIL. Und die zugrunde liegenden physikalischen Prozesse sind so träge, dass die Echtzeitanforderungen sehr gering sind. 1000 Liter Wasser haben so viel thermische Kapazität, da ändert sich die Temperatur nicht eben mal von einer Sekunde zur anderen. Solltest Du auch nur einen Hauch von physikalischem Verständnis haben, kannst Du gerne mal die kWh ausrechnen, die Du brauchst, um das Becken von 18°C auf 28°C aufzuheizen und dann mal schauen, wie lange Du dafür mit einem normalen Heizstab brauchst. Und als Bonus kannst Du dann noch ausrechnen, wie viel Reboots Du in dieser Zeit machen kannst. fchk
Gast
#5971509
Frank K. schrieb: > Andersrum: Der Linux-Code ist inzwischen so gut getestet und debuggt, > dass die Wahrscheinlichkeit für Bugs um Zehnerpotenzen geringer ist als > Code, den irgend so ein Anfänger aus Bruchstücken aus dem Netz > zusammengerührt hat. Das gilt vor allem, wenn Fehler auftreten und > beispielsweise die SD-Karte keine Lust mehr hat. Eine richtige > Fehlerbehandlung hab ich in DEM Code hier nicht gesehen. Oder > beispielsweise ein Watchdog. Nee, so wird das nix mit SIL. Dafür ist es in der Summe Zehnerpotenzen mehr Code der für das zusammenspielen aller Teile dazugehört. Aus der Sicht also Patt. Viele Libs und gerade die von ChaN für das Filesystem sind wenigstens genauso gut oder besser getestet wie Treiber für exotische Hardware in Linux. Code ohne Fehlerbehandlung kann man in Linux auch schreiben. Raspberry Zero scheidet ja wohl aus weil Ethernet fehlt. 5W rund um die Uhr sind auch fast 45kWh im Jahr. Ne, dann lieber beim Avr o.ä. bleiben.
Gast
#5971781
svensson schrieb: > würde ich unbedingt beim µC bleiben, weil das alles > absolut zuverlässig funktionieren muß Mein Raspberry Pi läuft genau so stabil, wie meine AVR und ESP8266 Projekte. Jahrelang ohne Aussetzer halt ich für vollkommen normal. Gut, ich habe nur Welse und Gildfische im Aquarium, daher brauche ich mir um die nicht vorhandene Heizung keinen Kopf machen. Aber wenn da eine wäre, würde ich zumindest die Heizung durch eine unabhängige Schaltung (nämlich dem darin eingebauten Thermostaten) absichern. Die Pumpe darf ruhig mal einen halben Tag ausfallen, davon geht die Welt nicht unter.
temp schrieb: > Raspberry Zero scheidet ja wohl aus weil Ethernet fehlt. Stimmt, die WLAN-Kabel sind zu teuer. > 5W rund um die Uhr sind > auch fast 45kWh im Jahr. Ne, dann lieber beim Avr o.ä. bleiben. Dann am besten auf Kaltwasserfische umstellen.
Gast
#5971812
> 5W rund um die Uhr sind sind auch fast 45kWh im Jahr Im Ruhezustand nimmt der Raspberry Pi weniger Strom auf, rechne mal mit ca. 2W + 1W Verlust im Netzteil. Klar, das ist immer noch mehr, als ein AVR. Die Frage ist, wo man sonst noch so kleine Leistungen vergeudet ohne darüber nachzudenken. > Dann am besten auf Kaltwasserfische umstellen. Eben, deswegen habe ich zwei Goldfische, wo früher 15 andere kleinere waren.
Felix N. schrieb: > Werde auf jeden Fall die ganzen Strings mit PSTR und PROGMEM > überarbeiten. Ja, und am besten sich wiederholende Sequenzen nach Möglichkeit datengetrieben aufbauen. Wenn du bestimmte Dinge in einer Tabelle organisieren kannst, dann brauchst du keinen zusätzlichen Code. > Floats entfernen und mit Integers arbeiten und mal schauen > was ich noch verbessern kann. Das ist nicht unbedingt nötig. Die Kosten für float (den Bibliothekscode für die Funktionen) bezahlst du nur einmal, ab dann sind das nur normale Funktionsaufrufe. Da das nicht zeitkritisch ist, ist die Rechenzeit nicht so wichtig - aber mit Float kannst du natürliche Einheiten ohne Skalierung benutzen. Das macht es einfacher, Werte auf Plausibilität zu prüfen. Ansonsten: Übung macht den Meister. Hier wurden viele gute Ideen genannt, und wenn du jetzt das Projekt passend umstrukturierst, wirst du hoffentlich genug gelernt haben, um die Fehler zu vermeiden. Du wirst dafür viele neue Fehler machen, aber genau dadurch lernt man. Viel Erfolg und Spaß!
Stefanus F. schrieb: > Mein Raspberry Pi läuft genau so stabil, wie meine AVR und ESP8266 > Projekte. Jahrelang ohne Aussetzer halt ich für vollkommen normal. hahaha, mir sind schon 3 SD und µSD Karten im PI gestorben, die werden durch das swap oder cache Dateien einfach kaputtgeschrieben. Ohne Nennung von OS und wie du Schreibvorgänge auf der SD abschaltest ist deine Aussage wertlos. Die 2 Transcend microSD wollten nicht mal am PI2 und PI3 laufen, einigermaßen durchgehalten haben Samsung SD Karten, aber 2 hat das Kodi auf dem PI auch kaputtgeschrieben, eine steht kurz vor dem Lebensende mit raspbian jessiePIXEL. Mittlerweile habe ich swap und chromium cache auf das NAS ausgelagert, wie gesagt um die Schreibvorgänge auf die SD zu minimieren.
Joachim B. schrieb: > Ohne Nennung von OS und wie du Schreibvorgänge > auf der SD abschaltest ist deine Aussage wertlos. Ich wüsste jetzt nicht, warum deine Inkompetenz die Aussage von Stefanus ungültig machen sollte. Aber fürs Topic: Mein Raspberry Pi hat auch noch keine SD-Karte gefressen.
S. R. schrieb: > warum deine Inkompetenz wieder nur Geschwafel S. R. schrieb: > Mein Raspberry Pi hat auch noch keine SD-Karte gefressen. schaffe ich auch, wenn man den PI im Schrank liegen lässt :)
Gast
#5973569
Joachim B. schrieb: > Ohne Nennung von OS und wie du Schreibvorgänge auf der SD abschaltest > ist deine Aussage wertlos. Rasbian ohne GUI ansonsten in Standard-Konfiguration. Anwendungen: Fileserver samba (kaum genutzt), sowie ein Shell-Script das alle 10 Sekunden eine Logmeldung ausgibt. Wenn die SD Karte frühzeitig ablegt, dann entweder wegen schlechter Qualität oder ein Anwendungsprogramm hat sie überfordert.
Stefanus F. schrieb: > Rasbian ohne GUI installiert raspbian jetzt nicht mehr serienmäßig eine SWAP Partition oder macht das nur die mit GUI?
Gast
#5973607
Joachim B. schrieb: > Stefanus F. schrieb: >> Rasbian ohne GUI > > installiert raspbian jetzt nicht mehr serienmäßig eine SWAP Partition > oder macht das nur die mit GUI? Ich weiß nicht was es "jetzt" macht, denn meiner ist ja schon über 2 Jahre alt. Der hat jedenfalls eine swap Partition. Da sie kaum verwendet wird, habe ich mir keinen Kopf darum gemacht.
Stefanus F. schrieb: > Ich weiß nicht was es "jetzt" macht, denn meiner ist ja schon über 2 > Jahre alt. na denn..... 2 Jahre mit wenig Schreiben ist eine recht kurze Zeit. ich nutze den PI seit 6 Jahren und habe 5 PIs und Kodi sowie Chromium schreiben recht viel auf die SD Karten und Kartenausfall gab es nicht nur bei mir, auch im PI Forum waren einige betroffen. Die Karten gehen in den write protect Modus, da ist dann nichts mehr zu "löten" die lassen sich nicht mehr löschen oder initialisieren. Mein Webserver auf AVR 1284p Basis läuft seit 2008
Hallo Felix, ich habe nicht den ganzen Thread Wort für Wort gelesen, aber das Problem, denke ich, verstanden. Erst mal Hut ab für Deinen unbedarften Einstieg in die Sache. Genau so habe ich vor Jaaaahren (80er) gelernt, Software zu schreiben. Die vielen Fehler und Ungelenkigkeiten in meinen Entwicklungen waren der gründlichste Weg, dazu zu lernen. Deine Sources habe ich überflogen. Wenn Du hier so etwas postest, bekommst Du von 20 Softwerkern natürlich mindestens 30 andere Lösungen für jedes Einzelproblem. Hinzu kommt, dass manche Protagonisten sich gegenseitig mit "noch besseren" Lösungen überhäufen, was Dir aber am Ende wenig nützt. Also lass Dich nicht entmutigen, das ist normal. ;-) Ich möchte mich nicht unbedingt dazu gesellen, weil es einfach Dutzende Ansätze gibt, den Code übersichtlicher zu strukturieren und weniger redundant zu machen. Um aber Deine Eingangsfrage zu beantworten: - Wenn Du einfach nur mehr reinpacken willst, und die Dir die Optimierung Deines Werks nicht so wichtig ist, nimm was Größeres. Dann hast Du vermutlich schneller Ergebnisse. Allerdings ist der Umstieg auf (z.B.) einen STM32 nicht trivial. Der ATMEGA2560 hätte vermutlich genug Flash für das, was Du noch machen möchtest. Und hinsichtlich der Optimierung des SRAMs dürfte es auch noch genügend Raum geben. - Wenn Du aber dazu lernen möchtest und es Dir nicht primär auf "viel drin, schnell fertig" ankommt, rate ich Dir zu einer grundlegenden Reorganisation Deines Projektes, einschließlich der damit verbundenen Erarbeitung der entsprechenden Grundlagen. Dann hast Du alles richtig gemacht, klassisches "learning by doing". Ich persönlich bin am Ende immer den zweiten Weg gegangen. Zuweilen war aber auch mir das "viel drin/schnell fertig" wichtig. Nur endete das dann in aller Regel in schwer wartbaren und final neu zu schreibenden Programmen. Fehlersuche, Optimierung und Erweiterung der Software waren am Schluss aufwändiger als es die Neuorgansiation bzw. ein Neustart gewesen wäre. Letztlich eine Frage der Geduld. Ernsthafte Software-Entwicklung ist nach meiner Erfahrung immer ein iterativer Prozess, der häufig ein gründliches Refactoring verlangt, und, wenn man einfach so hineingestolpert ist, i.d.R. auch ein umfassendes Neudesign. Siehe majortom: "ich habe kein project/program wo ich nicht gefüllt den code 2-3mal fast neugeschrieben habe - in teilen sogar x-mal neu.". Kann ich unterschreiben. Und auch das hier "und da ging es nicht darum wie z.b. in c sinnig programmiert wird, sondern wie ein problem/aufgabe sinnvoll abgebildet wird". Da offenbart sich der Unterschied zwischen Design und Koden. Du hast kodiert. Das ist nichts Schlimmes, aber auf Dauer reicht das eben nicht, jedenfalls nicht bei nicht-trivialen Aufgaben, Und das, was Du da machst, ist durchaus nicht trivial. Vor dem Koden steht daher die Isolierung und Formulierung des Problems bzw. der Aufgabe und verbunden damit der Einzelprobleme und -aufgaben. Ist das geschafft, lassen sich solche Blöcke viel einfacher handhaben. Was ich machen würde: Viel Papier auf den Tisch legen, die einzelnen Aufgaben definieren und als Meta-Code aufschreiben, den Code reorganisieren (sowohl "physisch", also in Einzeldateien zerlegen, als auch logisch) und dann mit einem klaren Konzept neu aufsetzen. Zu diesem Zeitpunkt sollten dann neben den aktuellen Features auch die für die Zukunft angedachten bekannt und eingeplant sein. So sollte Dein vorhandener Prozessor noch für einiges mehr tauglich sein, als Du vermutest.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
