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
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
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.
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.
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.
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?
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.
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.
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ß
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.
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.
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
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
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.
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
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.
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]
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
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.