Forum: Compiler & IDEs need help AVR Atmel eeprom STRING oder array of char


von Joachim B. (jar)


Lesenswert?

und bitte keine so "hilfreichen" Kommentare wie:

"was lässt der Artikel für Fragen offen?"
Diese habe ich zu Hauf gefunden aber keine Lösung!

habe gefühlt auch ganz guggel durchsucht und kein funktionierendes 
Beispiel gefunden.

Ich denke doch der avr-gcc sollte nicht nur sizeof(var) kennen

sondern auch deren Adresse im EEPROM
1
#include <avr/eeprom.h>
2
3
uint8_t EEMEM tach[]="tach auch....";
4
//char EEMEM tach[]="tach auch....";
5
uint8_t EEMEM i2c_found[]="I2C device found at address 0x";
6
7
8
void setup() 
9
{ 
10
  char setup_loc[41];
11
  
12
  Serial.begin(19200);
13
  delay(200);
14
15
while (!eeprom_is_ready()); // ob's noetig ist keine Ahnung, man versucht ja alles wenns nicht klappt
16
 cli(); // ob's noetig ist keine Ahnung, man versucht ja alles wenns nicht klappt
17
  eeprom_read_block(setup_loc, tach, sizeof(tach));
18
//  eeprom_read_block((void *)setup_loc, (const void *)tach, sizeof(tach));
19
 sei(); // ob's noetig ist keine Ahnung, man versucht ja alles wenns nicht klappt
20
21
  Serial.print(F("\n\n sizeof(tach):")); Serial.println(sizeof(tach));
22
  // klappt
23
  //  sizeof(tach):14
24
  
25
  Serial.print(F(" sizeof(i2c_found):")); Serial.println(sizeof(i2c_found));
26
  // klappt auch, zumindest sizeof() wird richtig erkannt
27
  //  sizeof(i2c_found):31
28
29
  Serial.print(F("\n aus EEPROM:")); Serial.println(setup_loc);
30
  Serial.print(F(" aus EEPROM:")); Serial.println((char *)setup_loc);
31
  Serial.print(F(" aus EEPROM:")); Serial.println(*setup_loc);
32
  Serial.print(F(" aus EEPROM:")); Serial.println(*(char *)setup_loc);
33
// aber hier kommt nur Muell raus warum?
34
// aus EEPROM:ÿÿÿÿÿÿÿÿÿÿÿÿÿ)­ä?
35
 //aus EEPROM:ÿÿÿÿÿÿÿÿÿÿÿÿÿ)­ä?
36
 //aus EEPROM:ÿ
37
 //aus EEPROM:ÿ  
38
  
39
}
40
41
void loop(void)
42
{
43
  ;
44
}

von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:

> // aber hier kommt nur Muell raus warum?

vielleicht, weil noch niemand etwas ins EEPROM geschrieben hat?

Bist du sicher, dass die Arduino UMgebung nicht nur das Programm 
überträgt, sondern auch das EEPROM programmiert?

von Joachim B. (jar)


Lesenswert?

Karl H. schrieb:
> Bist du sicher, dass die Arduino UMgebung nicht nur das Programm
> überträgt, sondern auch das EEPROM programmiert?

bin ich nicht, aber wäre es nicht sinnlos im Arduino EEMEM zu belegen 
und Arduino trägt es nicht ein?

von Joachim B. (jar)


Lesenswert?

aha, ein eep File wird zwar aktuell erzeugt, nach Datum und Uhrzeit aber 
da ist kein Text drin (lt. Hexeditor)

wie doof ist das denn?

von Joachim B. (jar)


Lesenswert?

Lösung?

If you want to set EEPROM when using Optiboot, there is a simple 
workaround - and this works on the original Arduino bootloader too. 
Upload a sketch that writes the EEPROM as you want it, let it execute, 
then upload the second sketch with the code you really want.

und wie kommen die Adress Tables ins Programm welche auf die Adressen im 
EEPROM verweisen?

ich verstehe es nicht, die Arduino IDE benutzt avr-gcc und schaft es 
nicht in der x-ten Arduino Version ein eep zu erzeugen und in das EEPROM 
zu bringen?

w a h ...................

keiner meckert?
nix wird korrigiert?

: Bearbeitet durch User
von chris (Gast)


Lesenswert?

Joachim B. schrieb:
> ich verstehe es nicht, die Arduino IDE benutzt avr-gcc und schaft es
> nicht in der x-ten Arduino Version ein eep zu erzeugen und in das EEPROM
> zu bringen?

Wie denn auch, wenn über den Bootloader geflasht wird?
Der kann wohl nur den Flash beschreiben.

von Joachim B. (jar)


Lesenswert?

chris schrieb:
> Joachim B. schrieb:
>> ich verstehe es nicht, die Arduino IDE benutzt avr-gcc und schafft es
>> nicht in der x-ten Arduino Version ein eep zu erzeugen und in das EEPROM
>> zu bringen?
>
> Wie denn auch, wenn über den Bootloader geflasht wird?
> Der kann wohl nur den Flash beschreiben.

ach und der Bootloader ist kein Proggi was läuft?
Ein laufendes Proggi kann nichts ins EEPROM eingeben? (von mir aus in 
500 Byte Schritten)

vielleicht erklärst du mal was du sagen wolltest?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:

> Ein laufendes Proggi kann nichts ins EEPROM eingeben? (von mir aus in
> 500 Byte Schritten)

Das hat keiner gesagt.

Machs halt nicht gar so kompliziert
Nimm dein Programm her und modifiziere die setup()
1
uint8_t EEMEM tach[]="tach auch....";
2
//char EEMEM tach[]="tach auch....";
3
uint8_t EEMEM i2c_found[]="I2C device found at address 0x";
4
5
6
void setup() 
7
{ 
8
  char setup_loc[41];
9
10
...
11
12
  strcpy( setup_loc, "tach auch...." );
13
  eeprom_write_block( setup_loc, tach, sizeof(tach) );
14
15
  strcpy( setup_loc, "I2C device found at address 0x" );
16
  eeprom_write_block( setup_loc, i2c_found, sizeof(i2c_found) );
17
18
...

das lässt du einmal laufen und danach kommentierst du die 4 Zeilen 
wieder aus.

Im Normalfall willst du sowieso nicht haben, dass dir bei jedem mal 
Programmübertragen das EEPROM zerstört bzw. wieder überschrieben wird. 
Der Sinn des EEPROMS besteht darin, Dinge wie zb Konfigurationsdaten, 
die sich zur Laufzeit ändern können, permanent speichern zu können. Und 
die willst du nicht verlieren, nur weil du ein Programmupdate machst.

Du kannst dir auch gefinkeltere Strategien ausdenken. Denn es ist 
bekannt, dass eine jungfräuliche EEPROM Speicherzelle den Wert 0xFF 
liefern wird. D.h du kannst auch lesen - abfragen ob 0xFF gekommen ist - 
default Wert im Programm benutzen und den gleichzeitig ins EEPROM 
schreiben. Dann initialisiert sich das Programm quasi selbst den EEPROM 
wenn es auf einen jungfräulichen AVR übertragen wird und du musst gar 
nicht mehr daran denken, dass du auch ein EEP File brennen müsstest.

Im übrigen wirst du dich hier
1
uint8_t EEMEM tach[]="tach auch....";
2
//char EEMEM tach[]="tach auch....";
3
uint8_t EEMEM i2c_found[]="I2C device found at address 0x";
eher auf eine vorgegebene Byteanzahl einschiessen, als auf eine Größe, 
so dass deine Texte da gerade reinpassen.
1
uint8_t EEMEM tach[20];
2
uint8_t EEMEM i2c_found[30];

d.h. wenn du schon Texte ins EEPROM legen willst (wegen zb 
Übersetzungen). Denn der nächste will anstelle von "tach auch...." 
lieber "** Buenos dias **" am LCD stehen haben. Nur passt das dann 
leider nicht in den für diesen Text reservierten Speicherplatz im 
EEPROM.

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

Karl H. schrieb:
> Machs halt nicht gar so kompliziert
> Nimm dein Programm her und modifiziere die setup()
Karl H. schrieb:
> das lässt du einmal laufen und danach kommentierst du die 4 Zeilen
> wieder aus.

wenns nur 4 Zeilen wären, momentan ist mein flash beim 328p am Ende, die 
Texte belegen 1k was prima ins EEPROM passen würde und mir 1k flash 
(fast) freischaufelt.

Karl H. schrieb:
> Im Normalfall willst du sowieso nicht haben, dass dir bei jedem mal
> Programmübertragen das EEPROM zerstört bzw. wieder überschrieben wird.

ich weiss grad nicht ob im Arduino die ee save fuse gesetzt ist, kann 
ich aber auslesen oder ändern.

Karl H. schrieb:
> Der Sinn des EEPROMS besteht darin, Dinge wie zb Konfigurationsdaten,
> die sich zur Laufzeit ändern können, permanent speichern zu können.

ist das so?

für mich wäre der Sinn das EEPROM für Texte zu nutzen wenns im flash eng 
wird.

Für alles mag ich nicht zum Mighty m1284p oder Arduino mega2560 greifen, 
wobei letzterer wieder weniger RAM hat und beim flash hatte ich 
Zugriffsprobleme bei Pictures oberhalb von 64k, irgendwie war der 
Zugriff auf Speicher >64k nicht sauber.
Dito ist mir ja schon bei der fastLED LIB Arduino passiert, ein Update 
dauerte 33µs statt der von der WS2812 LED geforderten 30µs weil die 
Herren Programmierer nicht im Timing das dritte Adressbyte 
berücksichtigt hatten.

Abhilfe für den Mighty in fastLED LIB bei delay.h
1
// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L)))
2
#if F_CPU < 96000000
3
#if defined(__AVR_ATmega1284P__) && (F_CPU==16000000)
4
  #define NS(_NS) ( (_NS * ( (F_CPU*9L/10L) / 1000000L))) / 1000
5
  #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / ((F_CPU*9L/10L) / 1000000L)
6
#else
7
  #define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000
8
  #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L)
9
#endif

macht für den m1284p an dieser Stelle -10% Timing und aus 33µs werden 
wieder 30µs und die WS2812 ist happy.

Nur die Ausrede der LIB Ersteller schockt, der mighty m1284p ist kein 
ordentlicher Arduino deswegen müssen sie nicht tätig werden, nur wie ist 
das dann mit dem m2560? Dieser ist ein ordentlicher Arduino und benötigt 
auch drei Adressbytes für Speicher und Jump, läuft das da? hatte ich nie 
probiert.
m2560
SRAM (Kbytes): 8

m1284p
SRAM (Kbytes): 16

von Joachim B. (jar)


Lesenswert?

Joachim B. schrieb:
> #if defined(_AVR_ATmega1284P_) && (F_CPU==16000000)

ich sehe gerade, das && (F_CPU==16000000) könnte man rauswerfen war noch 
aus der Zeit als ich konstante 1,6 MHz abgezogen hatte (-10% bei 16 MHz)

mit F_CPU * 9L/10L passt es aber nun für alle Taktfrequenzen auch wenn 
ich mal Baudratenqurze einsetze.

von Paul B. (paul_baumann)


Lesenswert?

Die Arduino-Oberfläche soll also für Laien und Programmieranfänger 
gedacht sein?! Ich kann mir nicht vorstellen, daß ein Anfänger diesen 
Rotz nicht nach 2-3 Tagen mit Schwung in die Ecke feuert und sich eine 
andere Oberfläche installiert. Wenn ich hier so manche Frage dazu lese, 
habe ich den Eindruck, daß das ein Urwald mit verfilztem Unterholz 
voller Schlangen und Skorpione ist.

Das mußte ich mal sagen und nun: Malträtiert von mir aus die 
Minus-Schaltfläche

MfG Paul

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

Paul B. schrieb:
> Die Arduino-Oberfläche soll also für Laien und Programmieranfänger
> gedacht sein?! Ich kann mir nicht vorstellen, daß ein Anfänger diesen
> Rotz nicht nach 2-3 Tagen mit Schwung in die Ecke feuert und sich eine
> andere Oberfläche installiert.

oh wie wahr.......

Paul B. schrieb:
> Das mußte ich mal sagen und nun: Malträtiert von mir aus die
> Minus-Schaltfläche

diesmal nicht paul!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.