Arduino EEprom ATTiny85 oder ESP8266 read/write

Hallo,
ich versuche leider bisher ohne Erfolg das interne EEprom des ATTiny85
zu benutzen.
Ich möchte ein Byte , hier eine 9 oder 5 reinschreiben.
Der ATTiny85 lässt sich programmieren, eine Led an und ausmachen.
Soweit zur Beschreibung das der Tiny richtig programmiert über USB ASP funktioniert.

Ich nutze hier die

#include <EEPROM.h>

und habe auch mit EEProm Write und Read probiert , leider ohne Erfolg.
Nun habe ich was gelesen, das man die Fuse Bits verstellen muss.
Dies beim Tiny85. Damit komme ich ganz nicht weiter. Ich lese welches Fusebits das sind aber den Ort "boards" wo die genändert werden müssen, beim AVR Dude , das klappt bei mir nicht so ganz.

Deswegen habe ich das ganze mal mit einem ESP8266 probiert. Der soll keine Fusebits brauchen.
Auch hier die obige EEprom Lib verwendet.
Aber auch das geht nicht. Zum Testen für den ESP8266

EEPROM.begin(4095);   // oder auch mit 512 getestet
EEPROM.write(0, 9);
delay(100);
EEPROM.commit();

delay(100);
byte Wert = EEPROM.read(0);
delay(100);
EEPROM.end();

..nun sollte doch in Wert "9" drinn sein,was es aber nicht ist.

Was mache ich den falsch, so viel ist es doch nicht.
Es muss was wesentliches sein, aber was.
Vielleicht könnt ihr mir bitte helfen.

Ich brauche das EEprom um 2 mal am Tag einen Wert reinzuschreiben.
Bei 100.000 R/W Zyklen des Tiny85 hällt das über 273 Jahre, also Verwendung ok.
Aber es sollte gehen, zuerst auf dem ESP8266 das ich es verstehe und dann
Final auf dem ATtiny85.

Viele Grüße
Rainer

Wie siehst du was für ein Wert “Wert” hat nachher?

Der ESP hat kein EEPROM... nur eine Emulation.
Ist also kaum vergleichbar.

Die Fuse beim Tiny ist nur nötig, wenn du die Daten über einen Upload hinweg retten möchtest,
Für den Normalbetrieb ist sie nicht nötig.

Keine Ahnung.
Bei mir funktioniert das EEPROM, auch mit Tinys
Und auch die Emulation auf ESP

Ich vermute du hältst den Fehler geheim.

  1. Vor dir selber
  2. Damit auch vor uns

Ein Testprogramm aus meiner Wühlkiste, allerdings für AVR Arduinos, z.B. UNO, Mega usw.

#include <EEPROM.h> 

// ein plaetzchen im eeprom reservieren
byte speicher EEMEM {4}; // Arduino erzeugt *.eep Datei

void setup() 
{
  Serial.begin(9600);
  EEPROM[int(&speicher)] = 9;
}

void loop() 
{
  byte wert = EEPROM[int(&speicher)];
  Serial.println(wert);
  delay(10000);
}

Ohne avr-gcc Dokumentation zu wühlen, gehe ich davon aus, dass EEMEM ein Attribut ist, mit dem Speicher im EEPROM reserviert wird, ähnlich wie PROGMEM für den Flash. Und dass dieser Speicher einen eigenen Adressbereich hat, unabhängig und parallel zu Flash und RAM.
Mich würde interessieren, welches Byte mir der Compiler zuweist:

#include <EEPROM.h>
byte speicher EEMEM {4};  // Arduino erzeugt *.eep Datei, die beim Upload den EEPROM überschreibt
void setup() {
  Serial.begin(9600);
  uint16_t pos= (uint16_t) &speicher;
  Serial.print("EEPROM Adr. 0x");
  Serial.print(pos, HEX);
  Serial.print( " : ");
  Serial.println(EEPROM[pos], HEX);
  Serial.println(speicher, HEX);  // Wäre schön, wenn dasselbe Ergebnis heraus käme, aber da geht das EEMEM Attribut verloren

  EEPROM[pos]++;  // 1 Byte im EEPROM ändern 
                  // ( beim nächsten Reset ohne neuen Upload zu sehen )


}

void loop() { }

Immer blöd Das ist das Dilemma, wenn man sich die Innereien anschaut, statt nur gegen das dokumentierte Interface zu programmieren. Damit ist man für alle Probleme beim Portieren selber verantwortlich.

Das EEROM ist halt eine recht exotische Hardware Eigenschaft der AVRs.

Wenn du nicht das .eeprom Section Feature nutzen möchtest und auch nicht per USBasp das EEPROM beschreiben willst. Also auf alle diese genialen Features verzichten möchtest, kannst du immer noch die EEPROM Daten in Strukturen ablegen und die Pos in der Struktur mit offsetof() vom Kompiler berechnen lassen.
Das funktioniert dann mit ALLEN Gcc und ALLEN Speichern, egal ob internes EEPROM oder I2C FRAM usw., wenn denn die Pointer Size(Adressraum) ausreichend ist.

Wichtig ist, meines bescheidenen Erachtens nach:
Die händischen Berechnungen/Festsetzungen der Adressen aus dem Code vollständig zu eliminieren.
Denn das ist eine ganz fatale Fehlerquelle!

#include <EEPROM.h> 

// ein plaetzchen im eeprom vorsehen
struct Eeprom
{
  byte speicher;
  byte osccal;
  float interneRefrenzSpannung;
};

#ifdef __AVR__
Eeprom eeprom EEMEM __attribute__((used)) {5,122,1.05}; // Arduino erzeugt *.eep Datei
#endif


void setup() 
{
  Serial.begin(9600);
  EEPROM[offsetof(Eeprom,speicher)] = 9;
  
}

void loop() 
{
  byte wert = EEPROM[offsetof(Eeprom,speicher)];
  Serial.println(wert);
  delay(10000);
}

Hallo,
erstmal danke für eure Tips und Hinweise.
Dann verwerfe ich das mit dem Quertest mit dem ESP8266.
Ist nicht Sinnvoll wenn es nicht vergleichbar ist.

Die erste Frage war, wie ich schaue , was in Wert als "wert" drinnen steht.

Also ich habe wie folgendermaßen getestet, da der Tiny keinen SerialMonitor unterstützt.

  1. Ich habe einen "Sketch" geschrieben, der nur den Wert "9" erstmal reinschreibt.
    Damit wollte ich sicherstellen ,das nun der Wert = 9 ist.

  2. dann habe ich einen weiteren Sketch geschrieben, der nur der Wert an der Adresse
    ausliest und wenn der Wert = 9 geht eine LED an einem Port an. ( per If Anweisung )

So und das funktiniert eben nicht.
Wenn ich die LED am Port so direkt auf High setze ( eigenes Script) geht diese an.
Daher komme ich zum Schluß das dass reinschreiben oder auslesen nicht geht.

Danke für den Hinweis mit den Fuse Bits.
Dann brauche ich das nicht, gut .

Ich setze nacher später, oder morgen die 2 Mini- Sketche in den Topic.
Muss gleich noch ins Training.....
Das oben im ersten Post sollte nur dazu dienen, mit welchen Befehlen ich am EEprom
"hantiere"...
Vielleicht findet Ihr den Fehler , wo sich noch versteckt :slight_smile:
Das wäre schön, der soll sich nicht mehr lange verstecken :slight_smile:
Ich wollte nur kurz ein erstes Feedback geben, weil ihr auch schon Tips
gegeben habt und Fragen gestellt habt.

Grüße

Und Du bist dir sicher , dass Du den sketch, der den Wert ausliest und insbesondere der Vergleich auf 9 richtig geschriben hast? Also If (Wert == 9) digitalWrite (ledPin, HIGH); und nicht etwa geschrieben hast, if (Wert = 9)??

Du brauchst die aktivierte Fuse, damit den EEPROM Inhalt den Chip Erase überlebt, welcher zwangsweise beim Upload stattfindet.

Guten Morgen,
nach der Deiner Erklärung wäre damit mein Test erkärt warum es nicht funktioniert.
Da mein erster Sketch mit der setzen der 9 dann quasi überbügelt wird.
Ist voll plausibel.

Zu der anderen Frage: Ja, ich werte "Wert" mit " == 9" aus.

So, nun wieder zu der Fuse.
Ich lese, ich muss die auf D7 setzen , das habe ich mit einem Online Fuse
Tool zumindest so rausgelesen und meine es so verstanden zu haben.
Ich solle unter Arduino boards den Eintrag auf D7 ändern.
Arduino und boards finde ich, aber mir ist nicht ganz klar wo ich jetzt den neuen oder anderen Fuse Wert eintragen muss. Ich finde zwar in den Boards einen kleinen Hinweistext auf den ATTiny85 , aber wo und was genau ( Text, Grammatik etc.) muss ich eintragen.
Vielleicht könnt ihr mir hier mit Rat beiseite stehen.
Ich finde im Web nicht wirklich was, liegt aber villeicht auch an falschen Suchbegriffen. Ist meistens so :slight_smile:
Wenn das mit dem Fuse nicht klappt, schreib ich die sketche dann jetzt doch nochmal kurz und setze sie hier rein.
Hab soviel probiert und wieder verworfen, deswegen nicht wundern, das noch kein Richtiger Sketch hier steht.
Aber ich hole nach ....
Einen schönen Tag an alle...

Wichtig:
https://arduino.github.io/arduino-cli/0.19/platform-specification/

Lesenswert:

Ich danke dir für die Links!
Ich lese und verstehe.
Werde es dann umsetzen , testen und euch Feedback geben.

Liebe Grüsse R.

Hallo zusammen, heute möchte ich euch Feedback geben.
Eure Tips waren spitze.
Nun geht es. Auch mein "Prüfsketch" macht jetzt was er soll.

Ich habe zum prüfen jetzt einfach ein kleines Skript, welches
jedesmal nach dem Power an / aus des Tiny die LED an oder aus macht.
....quasi dass Prinzip Stromstossschalter....

Alles gut.... :slight_smile:
Schön ,das es dieses Forum und die Mittglieder gibt,
die einen auf den richtigen Weg bringen, ohne
direkt darauf zu zeigen... nur so lernt man :slight_smile:

Sodele... damit habe ich nun getestet und alles gut.
Danke euch, jetzt kann ich darauf aufbauen.


#include <EEPROM.h> 

void setup() 
{

delay(200);
pinMode(4, OUTPUT);  
byte Wert = EEPROM.read(0);
delay(200);

if ((Wert != 11) || (Wert !=22 )){
  EEPROM.write(0,11);     // erster Power on , Wert egal , setzen auf 11 = an
  delay(200);
  digitalWrite(4, LOW);}  // erster Power on = LED aus

if (Wert == 11 ){         // WENN letzter Wert 11 = an
  digitalWrite(4, HIGH);
  EEPROM.write(0,22);     // DANN nächstes mal aus, 22
  delay(200);}
 
if (Wert == 22 ){         // WENN letzter Wert 22 = aus
  digitalWrite(4, LOW);
  EEPROM.write(0,11);     // DANN nächstes mal an, 11
  delay(200);}            
}

void loop() 
{}


Hier du hast noch eine optimierungsmöglichkeit . .

if ((Wert != 11) || (Wert !=22 )){

und zwar:

if ( true ) {

Das funktioniert aber nur, wenn vorher kein anderer Sketch (oder an anderer Stelle im aktuellen Sketch) da irgendwas reingeschrieben hat. :wink:

Hää...
Was soll das für einen Unterschied machen?
Keinen!
Denn
if ((Wert != 11) || (Wert !=22 )) und if ( true ) liefern immer das identische Verhalten.
Unabhängig vom Wert.

Ja natürlich wäre es ausführlicher, wenn die mögliche Intension des TO auch noch erklärt wäre.
Aber die Frage sollte der TO stellen.

Ich weiss was ein UND ist.