Guten Abend,
ich habe einen ADS1112 den ich über I2C im Single Ended Modus auslese.
Das Lesen der Register klappt auch.
Ich bekomme für das High Byte z.B.: 0x37 und für das Low Byte: 0xe8.
Lesen des Konfigurationsregisters klappt ebenfalls. Die Werte stimmen
also.
So, nun muss ich ja das High- und Lowbyte zusammenbringen und wie im
Datenblatt auf Seite 6 beschrieben umrechnen.
Also die zwei Bytes zusammenfassen erledige ich hiermit:
1
int highbyte = messageBuf[1];
2
int lowbyte = messageBuf[2];
3
4
long t = highbyte << 8 | lowbyte;
... umrechnen eventuell so?
1
double v = (double) t * 2.048/32768.0;
Und Ausgabe auf dem Display dann hiermit:
1
itoa( v, ausgabe,10);
2
lcd_string(ausgabe);
Leider erscheint da nur 0 bzw. 1 auf dem Display :(
Vielleicht kann mir jemand einen Tipp geben und mich auf den richtigen
Weg schupsen?
Ich arbeite mit AVR Studio und einem Attiny2313. Sprache: C.
Vielen Dank :)
Du berechnest so eine float in V, die wiederum in dein double gewandelt
wird - du wirst also eine Dezimalzahl zwischen -2 und +2 sehen, {-2; -1;
0; 1; 2;}.
Wenn du mV sehen willst, entferne den Punkt bei der 2.048, fertig.
Super, danke hat funktioniert.
Nun muss ich nur noch einen Weg finden die Zahl mit einem Komma aufs
Display zu bringen...
für 8,50V steht nun nämlich z.B. 85000 auf dem Display.
bei 15V sind es 15000.
Je nachdem, wie deine Funktion lcd_string() funktioniert, musst du das
natürlich etwas anpassen wegen Zeilenumbrüchen und ähnlichem. Ein wenig
Eigeninitiative würde da tatsächlich nicht schaden.
Danke, habe eine Lösung gefunden (wobei deine wohl die schönere ist...).
Leider passt deine Lösung nicht mehr in den Speicher. 7% zu viel, und
das schon bei bester Optimierung.
Damit geht's aber gerade so:
1
int Messwert = v;
2
int vorKomma = Messwert / 1000; // zwei Nachkommastellen "abschneiden"
3
int nachKomma = Messwert % 1000; // zwei Nachkommastellen "isolieren"
Borsty B. schrieb:> int vorKomma = Messwert / 1000; // zwei Nachkommastellen "abschneiden"> int nachKomma = Messwert % 1000; // zwei Nachkommastellen "isolieren"
und der Typische Fehler das der Kommantar lügt
Ich denke, die einfachste Variante besteht darin, auf itoa bzw utoa zu
verzichten und sich selbst eine entsprechende ASCII Konvertierung zu
schreiben.
Dann ist es nämlich einfach sicherzustellen, dass die führenden 0-en
auch tatsächlich erscheinen. Ganz im Gegenteil: führende 0-en
wegzulassen ist Aufwand. Die dann nachträglich wieder zu ergänzen ist
irgendwie doppelt gemoppelt.
Als Anhaltspunkt kann gleich der erste Punkt in der FAQ
FAQ
dienen. Dort kannst du dir ansehen, wie man so eine Konvertierung macht,
wenn man sie selbst machen muss/will.
Ich denke allerdings auch:
wenn du die double Rechnerei losgeworden bist, hast du den Speicher um
sprintf benutzen zu können. Mit den Formatiermöglichkeiten von sprintf
wirds trivial, auch wenn sprintf etliches zum Code beitragen wird. Aber
alleine das Ausrichten in einem Feld, so dass die Zahl bei wechselnden
Vor bzw. Nachkomma Ziffern Anzahlen nicht dauernd hin und her springt,
ist es schon wert. Denn auch das müsste/sollte man programmieren. Es
gibt nichts schlimmeres, als wenn einem beim Lesen von Zahlen auf einem
LCD die Zahl dauern links/rechts hin und herschwimmt, nur weil der
Zahlenwert von 10.000 auf 9.999 hin und her hüpft.
Im Zweifelsfall lieber die double loswerden und dafür sprintf einsetzen
können :-)
Karl H. schrieb:> Es> gibt nichts schlimmeres, als wenn einem beim Lesen von Zahlen auf einem> LCD die Zahl dauern links/rechts hin und herschwimmt, nur weil der> Zahlenwert von 10.000 auf 9.999 hin und her hüpft.
denn gibt man ständig
<space>9999 oder 10000 aus und fügt an der 3 Stelle von links das Komma
ein, reine Stringverarbeitung
Also egal wie ich's dreh oder wende, es funktioniert so nicht:
1
long t = highbyte << 8 | lowbyte;
2
double v = (double) t * 2048/32768.0;
3
double w = v/1000;
4
itoa( w, ausgabe,2);
5
lcd_string(ausgabe);
6
ausgabe=".";
7
lcd_string(ausgabe);
8
itoa( (v-1000*w), ausgabe,6);
9
lcd_string(ausgabe);
Mit diesem Code bekomme ich die mV ohne Punkt und Komma aufs Display:
1
t = highbyte << 8 | lowbyte;
2
v = (double) t * 2048/32768.0;
3
lcd_setcursor( 0, 4 );
4
itoa( v, ausgabe,10);
5
lcd_string(ausgabe);
Allerdings brauch ich die Anzeige ja in Volt mit Zenertrennung...
P.S. jetzt bitte nicht am Long und double aufhängen, ich versuch das
grad auf einem Controller mit ausreichend Platz und möchte es einfach
mal zum laufen bringen.
Hat denn keiner eine Idee wie ich diesen 16-Bit Hex Wert des AD1112 in
Volt umrechne?
Millivolt funktioniert ja, brauch also eigentlich nur Millivolt in Volt.
Ich steck im programmieren leider nicht tief genug drin. Auch mit
Sprintf funktioniert es nicht wie ich es möchte :(