Liebes Forum, bei mir spukts. Besser gesagt: in meinem Arduino Nano.
Ich schreibe ein Programm, in dem ein (float-)Wert eingestellt werden kann: "blattdicke". Was und wozu, spielt IMHO keine Rolle. Jedenfalls muss er ins EEPROM geschrieben werden. Grundsätzlich funktiniert das auch, ABER VORHER wird der Wert leicht verfälscht.
Du bist auf eine typische Float Eigenschaft gestoßen.
Nicht alle Zahlen sind EXAKT in float darstellbar.
Weswegen sich auch Vergleiche mit == verbieten.
OK, das scheint andere auch zu stören. Aber mein Verdacht mit dem Poltergeist ist dadurch eher bestätigt als widerlegt - oder?
Lösungsvorschlag für das eigene Problem: "blattdicke" direkt und ausschließlich als INT anlegen und nur bei der Ausgabe durch 100 teilen? Ich probiere das mal aus. Gottseidank sieht man den Code ja bei der Ausführung nicht.
Danke und GRuß, kuahmelcher
Nö, funzt nicht. Vielleicht bin ich auch einfach ein zu schlichter Geist, ich hatte nur "Grundkurs MAthe". Vielleicht ist der wahre Wert von "160" eben doch nur "159". Hat man ja öfter im Leben.
Nächster Ansatz: Ich runde vorm Speichern. Dummerweise werden immer "0.05" addiert oder subtrahiert, so dass vorher mit 500 multipliziert werden müsste, aber was schlaueres fällt mir nicht ein …
Sehr gern. Also - ich habe insgesamt vier Werte, die ich speichern muss: einer ist ein byte, drei sind floats. Ich habe mir zwei Funktionen gebastelt, die eben ins EEPROM schreiben und lesen. Ich wandle momentan die "floats" in "ints" um und runde dabei so genau wie nötig (eine oder zwei Nachkommastellen). Die Schreib-Funktion zerhackt den übergebnen int-Wert erst mal arithmetisch und mit modulo und schreibt in zwei aufeinander folgende bytes. Ich glaube, das ist usus so.
Ich habe mal ein kleines Minimalbeispiel gebastelt - nonsense, aber da kannst du die Strategie leicht nachvollziehen.
Direkt floats zu speichern wäre schon an verschiedenen Stellen eine deutliche Vereinfachung.
Strukturen benutz man um verschiedenartige Dinge, zusammengehörige Dinge, zu Gruppieren.
Was zusammen gehörig ist, landet so in einem Klumpen.
Ich rate zur Ordnung und zu Systematiken.
Die Template Funktionen habe ich erstellt um (fast) ALLE Datentypen typesicher anfassen zu können. Über Referenzen. Und um von der händischen Adressvergabe weg zu kommen.
Du verwendest die feste Adresse 8. Das ist eine magische Zahl, welche du händisch festlegen musst. Ich lasse den Compiler alle Adressberechnungen machen. Der ist in dem Punkt erheblich zuverlässiger als jeder Mensch. Der ist nicht schlampig, irrt sich nicht.
Tue ich nicht.
Der wichtigste Teil:
Der Code zeigt, wie man Strukturen schreibt und liest.
Wie man eine Struktur, oder beliebige andere Variablen, im EEMEM platziert
Der Rest:
Dann zeigt er noch ein paar Wege, wie man auf die einzelnen Strukturelemente zugreifen kann, wenn man nicht den ganzen Klumpen auf einmal verarbeiten will.
Das ist kein C.
Arduino ist C++.
Und die EEPROM Klasse ist recht ausgefuchstes C++.
Die Klasse bietet u.A. ein Iterator und ein ArrayAccess Interface.
ca. 9 Jahre bist du schon dabei.
Evtl. ist es ja mal Zeit für ein schönes dickes und modernes C++ Buch, damit du die Sprache mal kennenlernst, welche du da verwendest.
Der Sinn dieses Wrappers ist doch nur, dass er sicherstellt, dass eep und ram vom gleichen Typ sind, oder?
Aber dass eep eine Variable mit EEMEM Attribut ist und ram eine normale im RAM , muss man schon selber richtig machen, damit es funktioniert.
Sonst kriegt man keinen Fehler, nicht mal eine Warnung.
Man muss also schon genau wissen was man da tut, und kann dann auch genausogut direkt EEPROM.put verwenden?
Insbesondere dass
float blattdicke; // lokale Blattdicke
eeprom_read(blattdicke,blattdickeE); // lokale Blattdicke aus EEPROM einlesen
völlig falsch ist, sagt einem keiner.
Da ist mir EEPROM.get eigentlich lieber, was auf den Unterschied zwischen einer EEPROM Adresse und einer beliebigen Variablen achtet.
Ja, das ist ein Grund!
Der zweite Grund ist den Cast auf die Adresse zu kapseln.
Typesicher zu kapseln.
Der dritte: Sich nicht um Adressen zu kümmern.
Der vierte: Weils einfach besser ist.
Der fünfte: Du bist dagegen, also hat sich die Provokation gelohnt
Ja!
Denn der Compiler weiß das nicht.
Memory Sections sind nicht Teil der C++ Spezifikation, sondern in diesem Fall eine AVR Spezialität. Schade, aber von mir nicht beeinflussbar.
Es werden durch das Verfahren mindestens drei Fehlerquellen vermieden/gemeldet.
Eine Fehlerquelle erfasst es nicht.
Und zwar: Das menschliche Unvermögen, die Funktionssignatur zu akzeptieren.
Das empfinde ich auch als schade.
Sehe aber keine Chance das ressourcenschonend zu lösen.
Häää... (du machst mich verwirrt)
Das get() interessiert sich für gar nix!
(dachte ich bisher)
Oder, zeige mir bitte was du meinst, wie get() den Unterschied beachtet, oder am besten auch meldet.
Denn das kenne ich noch nicht.
Ich möchte lernen.
OK, sicher für größere Speichernutzungen der einzig richtige Weg. Aber ausgerechnet MEIN Compiler scheint eine ziemliche Schlampe zu sein (siehe Originalpost), oder besser gesagt der Prozessor. (Ich wäre erstickt, wenn ich das nicht gesagt hätte)
Ich habe mir den Sketch mal unter 2022 gespeichert und werde ihn "zerlegen" und damit 'rumprobieren. Mittlerweile weiß ich, dass solche Dinge oft nur deshalb kompliziert erscheinen, weil ich sie noch nicht richtig verstanden habe.
Ja … allerdings bin ich bisher in diesem Forum hervorragend gefahren: Freundliche Fragen ergeben freundliche Antworten. Könntest du irgend ein Buch empfehlen? Ich bin ja nicht unwillig, nur möchte ich mich nicht mit theorielastigen, trockenen Büchern rumärgern. Das lese ich eh nicht. Wie du sicher gemerkt hast mache ich das "nur" zum Spaß.
Na - jedenfalls Danke für die Mühen, ich habe zwei neue Ansätze, die ich übernehmen werde.
Gruß, kuahmelcher.
Das klingt jetzt irgendwie enttäuscht. Da gibt‘s keinen Grund zu. Du hast mir jetzt schon geholfen und ich bin sehr dankbar. Ich will keine doku vorgelesen bekommen, die Frage war eher nach einer Empfehlung. Schlechte dokus lese ich nicht (wenn‘s nicht sein muss).
Nee, nee...
Ich bin nicht enttäuscht. Da mache dir mal keine übertriebenen Hoffnungen...
Und selbst wenn, wäre eine solche Enttäuschung, doch eher ein Grund zur Freude!
Ein C++ Grundlagen Buch ist immer Theorielastig.
Muss es sein! Es kann nicht anders.
Es ist eine aneinander Reihung von meist glasharten und staubtrocknen Fakten.
Zudem habe ich mich hier im Forum schon längst, klar und deutlich, für ein bestimmtes Buch ausgesprochen. Ok, die veraltete Auflage ist mittlerweile vergriffen (gewesen). In neuerer Version C++20 ist es weiterhin erhältlich.
Bin mir aber längst nicht sicher, dass/ob dir das Buch schmeckt. Befürchte da das Gegenteil. Denn aus deinen Postings leuchtet mir ein bisschen Ablehnung entgegen.