Forum: Mikrocontroller und Digitale Elektronik int in Arduino-EEPROM speichern / lesen


von noch ein Gast (Gast)


Lesenswert?

Hallo
bei meiner Arduinoreference habe ich für das Speichern im EEPROM nur die 
Möglichkeit für byte gefunden.

Also muß ich wohl den int-Wert in kleinere byte-Stücke zerteilen (ich 
werde meine Versuche mit lowByte und highByte beginnen, vielleicht 
funktioniert das) und dann in aufeinanderfolgenden Zellen ablegen.

Was mir aber unklar ist: wie verfahre ich mit dem Minuszeichen, das bei 
manchen Werten vorkommen kann?

Gruß
noch ein Gast

von EGS (Gast)


Lesenswert?

Hi,

genau so wie es die Referenz von Arduino angibt. Da ist ein Bit, welches 
die Zahl als negativ  markiert, wenn es nicht gesetzt ist, isse eine 
positive Zahl.

Zitat arduino.cc:

"On the Arduino Uno (and other ATMega based boards) an int stores a 
16-bit (2-byte) value. This yields a range of -32,768 to 32,767 (minimum 
value of -2^15 and a maximum value of (2^15) - 1).
On the Arduino Due, an int stores a 32-bit (4-byte) value. This yields a 
range of -2,147,483,648 to 2,147,483,647 (minimum value of -2^31 and a 
maximum value of (2^31) - 1).


int's store negative numbers with a technique called 2's complement 
math. The highest bit, sometimes referred to as the "sign" bit, flags 
the number as a negative number. The rest of the bits are inverted and 1 
is added."

Also bloss auf das Sign-Bit achten,das ergibt das Vorzeichen.

MfG EGS

von Thomas E. (thomase)


Lesenswert?

noch ein Gast schrieb:
> Hallo
> bei meiner Arduinoreference habe ich für das Speichern im EEPROM nur die
> Möglichkeit für byte gefunden.
>
> Also muß ich wohl den int-Wert in kleinere byte-Stücke zerteilen (ich
> werde meine Versuche mit lowByte und highByte beginnen, vielleicht
> funktioniert das) und dann in aufeinanderfolgenden Zellen ablegen.
>
> Was mir aber unklar ist: wie verfahre ich mit dem Minuszeichen, das bei
> manchen Werten vorkommen kann?

Das ist nichts Ungewöhnliches. Das EEPROM kann nur Bytes. Auch eine 
vorhandene Funktion schreibt/liest für int_16 2 Bytes. Ist beim RAM 
nicht anders.

Das Minus ist das oberste Bit. Also Bit 15 bei 16-Bit-Integer. Mach dir 
da keinen Kopf drum. Speicher das einfach ab. Wichtig ist, daß beim 
Lesen wieder in den richtigen Datentyp zurückgelesen wird. Sonst wird 
aus -1(int) plötzlich 65535(unsigned int).

Und natürlich in der richtigen Reihenfolge. Mach das immer auf die 
gleiche Weise.

mfg.

von Peter D. (peda)


Lesenswert?

Int hat keine 17 Bit, sondern nur 16, d.h. 2 Byte reichen.
Ob diese nun signed oder unsigned interpretiert werden, hängt ganz von 
Dir ab, dem EEPROM ist das piepegal.

Ich vermute mal, es gibt auch Routinen, um Arrays zu speichern.
1
void save_int( int addr, int val )
2
{
3
  eeprom_write_block( addr, &val, sizeof(int));
4
}

von Karl H. (kbuchegg)


Lesenswert?

Ich denke aber, der springende Punkt ist, dass du dich im Grunde darum 
gar nicht kümmern musst.

Du zerlegst den int einfach in die beiden Bytes, aus denen er aufgebaut 
ist (oder wenn du auf einem 32 Bit Arudino Due bist in die 4 Bytes) und 
speicherst die nacheinander.
Beim Lesen des Wertes holst du dir wieder die beiden Bytes und setzt 
daraus den int zusammen.
Wenn alle Bits genau wieder an der gleichen Stelle im resultierenden int 
dort auftauchen, wo sie ursprünglich waren, dann hast du auch die 
Original-Zahl wieder, egal ob die positiv oder negativ war. Diese 
Zerlegung bzw. Aufteilung ist nicht weiter wild, du musst nur auf die 
Datentypen aufpassen, so dass es sich dabei tatsächlich einfach nur um 
eine Zerlegung in Einzelbytes handelt und nicht zusätzliche 
Konvertierschritte eingefügt werden.

Anstatt der Arduino EEPROM Klasse steht dir natürlich auch noch der Weg 
offen, wie man das ganze auf nicht Arudino Systemen auf einem AVR 
mittels gcc machen würde. Da gibt es ganz banale Funktionen dafür, die 
sich um die Details kümmern.

: Bearbeitet durch User
von noch ein Gast (Gast)


Lesenswert?

EGS schrieb:
> Also bloss auf das Sign-Bit achten,das ergibt das Vorzeichen.

Also einfach (wenn es hoffentlich funktioniert), highByte und lowByte 
nacheinander ins EEPROM schreiben?

von Karl H. (kbuchegg)


Lesenswert?

noch ein Gast schrieb:
> EGS schrieb:
>> Also bloss auf das Sign-Bit achten,das ergibt das Vorzeichen.
>
> Also einfach (wenn es hoffentlich funktioniert), highByte und lowByte
> nacheinander ins EEPROM schreiben?

Genau.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> noch ein Gast schrieb:
>> EGS schrieb:
>>> Also bloss auf das Sign-Bit achten,das ergibt das Vorzeichen.
>>
>> Also einfach (wenn es hoffentlich funktioniert), highByte und lowByte
>> nacheinander ins EEPROM schreiben?
>
> Genau.

Die Umkehrung davon müsste dann meiner Recherche nach die word() 
Funktion sein.

Ich würd mir da gleich mal 2 Funktionen machen, die eine kümmert sich um 
das Schreiben eines int, die andere um das Lesen.

von noch ein Gast (Gast)


Lesenswert?

Karl Heinz schrieb:
> Die Umkehrung davon müsste dann meiner Recherche nach die word()
> Funktion sein.

naseweise Bemerkung eines Anfängers: word hat lt. Arduinoreference 
positive Werte bis 65535 (wie unsigned int).

>
> Ich würd mir da gleich mal 2 Funktionen machen, die eine kümmert sich um
> das Schreiben eines int, die andere um das Lesen.

Ja, ist mir schon deshalb wichtig, weil ich die ausgelesenen 
EEPROM-Werte via Terminal mit OpenOffice weiter verarbeiten will und mir 
deshalb gehäckselte int-Werte in nacheinderfolgenden EEPROMzellen gar 
nicht gefallen.

Gruß

von Karl H. (kbuchegg)


Lesenswert?

noch ein Gast schrieb:
> Karl Heinz schrieb:
>> Die Umkehrung davon müsste dann meiner Recherche nach die word()
>> Funktion sein.
>
> naseweise Bemerkung eines Anfängers: word hat lt. Arduinoreference
> positive Werte bis 65535 (wie unsigned int).

Jau. Und die kann man dann wieder auf einen int zurecht-casten. Deshalb 
ja (unter anderem) die speziellen Funktionen für int.

von Thomas E. (thomase)


Lesenswert?

noch ein Gast schrieb:
> Ja, ist mir schon deshalb wichtig, weil ich die ausgelesenen
> EEPROM-Werte via Terminal mit OpenOffice weiter verarbeiten will und mir
> deshalb gehäckselte int-Werte in nacheinderfolgenden EEPROMzellen gar
> nicht gefallen.
>
Via Terminal? Also über UART. Da kannst du auch nur Bytes übertragen. 
Und wenn man es richtig macht, überträgt man Nibble als ASCII-Zeichen. 
Ein richtiges Gemetzel also.

mfg.

von noch ein Gast (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Via Terminal? Also über UART. Da kannst du auch nur Bytes übertragen.
> Und wenn man es richtig macht, überträgt man Nibble als ASCII-Zeichen.
> Ein richtiges Gemetzel also.

Ach du namenloses Elend, daran hatte ich noch gar nicht gedacht. 
Insbesondere deshalb nicht, weil mein Hyperterminal bisher auch Werte 
wenigstens bis 1023 als unverstümmelte Zahlen klaglos übertragen hatte.

mfg

von noch ein Gast (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Via Terminal? Also über UART. Da kannst du auch nur Bytes übertragen.
> Und wenn man es richtig macht, überträgt man Nibble als ASCII-Zeichen.
> Ein richtiges Gemetzel also.

Hmmm,
letzten Endes geht doch  j e d e r  Datenaustausch zwischen PC und 
Arduino oder auch ATmega über solche Verbindung.
Müßte es da nicht massenweise "Empfangsprogramme" für Windows und Linux 
geben, die aus den bytes wieder die gewünschten Formate erzeugen (nicht 
nur int, sondern auch andere)?

Vielleicht gibt es dies tatsächlich und ich weiß nur nicht, wonach ich 
suchen sollte?

mfg

von Karl H. (kbuchegg)


Lesenswert?

noch ein Gast schrieb:

> Müßte es da nicht massenweise "Empfangsprogramme" für Windows und Linux
> geben, die aus den bytes wieder die gewünschten Formate erzeugen (nicht
> nur int, sondern auch andere)?

Das Problem ist, dass du ja nicht nur EINEN int zu übertragen hast, 
sondern meistens ein komplexeres Protokoll in dem sich die diversen 
Datentypen in einem Datensatz bunt gemischt abwechseln.
Protokolle gibt es auf dieser Ebene so viele wie es Sterne am Himmel 
gibt. Das macht jeder anders.

> Vielleicht gibt es dies tatsächlich und ich weiß nur nicht, wonach ich
> suchen sollte?

Selber schreiben.
Wenn du dir die Sache erst mal einfacher machen willst UND die 
Übertragung nicht besonders zeitkritisch ist, dann übertrage deine Werte 
in Form von Text und nicht als 2 Binärbytes.
Text bedeutet, dass der AVR zb den Text
"A2345\n"
an den PC übertragt. Der Buchstabe ist dabei so etwas wie eine 
Einleitung und kennzeichnet, welche Bedeutung der nachfolgende Wert hat. 
Das \n am Zeilende (der Zeilenvorschub) kennzeichnet das Ende des Wertes 
und das dazwischen ist der WErt selber.
Sowas ist einfach zu erzeugen, einfach auf der anderen Seite wieder 
auseinander zu nehmen und funktioniert hinreichend gut. Ok. Es sind 6 
Bytes zu übertragen und nicht nur 3 wie im Falle einer rein binären 
Übertragung, bei der du den 2-Byte int in 2 Bytes zerteilst und die auf 
den Weg schickst, dafür hast du aber mit der Textform dann aber auch 
Möglichkeiten für eine rudimentäre Fehlerbehandlung, keine 
Protokollprobleme durch Mehrdeutigkeiten und das Testen während der 
Entwicklung ist auch einfacher. Denn am Anfang reicht ein ganz 
gewöhnliches Textterminal aus, um dir anzeigen zu lassen, was der AVR so 
eigentlich von sich gibt.

: Bearbeitet durch User
von noch ein Gast (Gast)


Lesenswert?

Karl Heinz schrieb:
> Selber schreiben.
> Wenn du dir die Sache erst mal einfacher machen willst UND die
> Übertragung nicht besonders zeitkritisch ist, dann übertrage deine Werte
> in Form von Text und nicht als 2 Binärbytes.
> Text bedeutet, dass der AVR zb den Text
> "A2345\n"

Und das geht? Nicht nur, wie Thomas Erdmann schrieb, Byte um Byte?

Dann werde ich mich morgen durch die hoffentlich vorhandenen Tutorials 
wühlen.
Zeitkritisch ist bei diesem Projekt übrigens nichts, zwischen zwei 
Einträgen habe ich 10 min (!) Zeit.

mfg
noch ein Gast

von Thomas E. (thomase)


Lesenswert?

noch ein Gast schrieb:
> Ach du namenloses Elend, daran hatte ich noch gar nicht gedacht.
> Insbesondere deshalb nicht, weil mein Hyperterminal bisher auch Werte
> wenigstens bis 1023 als unverstümmelte Zahlen klaglos übertragen hatte.

Jetzt geht's ans Eingemachte.

Das Hyperterminal hat nicht die Zahl 1023 übertragen. Das kann es gar 
nicht. Sondern nacheinander 0x31, 0x30, 0x32, 0x33. Oder in 
Dezimalzahlen 49, 48, 50, 51. Das sind die ASCII-Codes für '1', '0', '2' 
und '3'.

Das wirst du auch machen müssen. Wobei es dabei noch einen Schritt 
weiter geht.
1023 ist in Hex 0x3FF. Genau genommen 0x03FF. Das steht in deinem int 
drin.
Das sind dann 2 Bytes. 0x03 und 0xFF.

Diese 2 Bytes  überträgst du jeweils als 2 ASCII-Zeichen: 0x30, 0x33, 
0x46, 0x46. Davor kannst du eine Einleitung setzen z.B. irgendein 
Zeichen ausser den folgenden:

0x30 - 0x39 sind die Codes für '0' - '9', 0x41 - 0x46 für 'A' - 'F' und 
0x61 - 0x66 für 'a' - 'f'.

Also z.B.: 'X', '0', '3', 'F', 'F', '\n'.
Das wird zu einem String: "X03FF\n".

Zum Senden eines Strings über UART gibt es 100%ig in Arduino eine 
Funktion. Genauso wie es eine Funktion gibt, die dir eine Integerzahl in 
einen String umwandelt. Den schickst du dann auf die Reise und kannst im 
Hyperterminal in Klarschrift deine Zahl lesen. In diesem Falle in Hex:
1
X03FF
2
_

Und Open Office wird auch ein Makro haben, mit dem die Hexzahl, die in 
diesem String steckt in eine Dezimalzahl umgewandelt wird. Weil eine 
derartige Übertragung ist die normalste Sache der Welt.

Du kannst statt Hex auch Dezimalzahlen übertragen. Aber immer zerlegt in 
ASCII-Zeichen. Hat beides seine Vor- und Nachteile. Ist auch ein 
bisschen Geschmackssache. Ich bevorzuge Hex.

mfg.

: Bearbeitet durch User
von noch ein Gast (Gast)


Lesenswert?

Eine Anmerkung bzw. Frage noch:
Zum Rückverwandeln der übertragenen Texte hilft dann aber kein 
C-Programm mehr, sondern eines, das auf dem PC, in meinem Fall unter 
Windows-XP, laufen muß?

mfg


PS
[vielleicht bietet OpenOffice, Excel oder Mathcad die Möglichkeit, Texte 
in Zahlen zu verwandeln]

von noch ein Gast (Gast)


Lesenswert?

noch ein Gast schrieb:
> Eine Anmerkung bzw. Frage noch:
> Zum Rückverwandeln der übertragenen Texte hilft dann aber kein
> C-Programm mehr, sondern eines, das auf dem PC, in meinem Fall unter
> Windows-XP, laufen muß?

Das war meine Antwort auf den Beitrag von Karl-Heinz, hat sich mit dem 
Beitrag von Thomas überkreuzt.

Auf jeden Fall werde ich morgen weiter an dem Problem knabbern.

mfg
noch ein Gast

von Philipp K. (philipp_k59)


Lesenswert?

ich habe die abgelegten Daten, kommt natürlich auf die Anwendung an 
gleich via csv als Serialtext übertragen und muss diese Dann nur noch in 
OO öffnen.

Zum ablegen und auslesen habe ich einen eigenen EEPrombasierten 
Multi-Array benutzt.

: Bearbeitet durch User
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.