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.
1 | void save_int( int addr, int val ) |
2 | {
|
3 | eeprom_write_block( addr, &val, sizeof(int)); |
4 | }
|
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
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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.
:
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.