ADS1112 ADC Wert in Spannung rechnen

OP #4210294
Lesenswert?
• ▲
▼
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 :)
#4210631
Lesenswert?
• ▲
▼
Das ist doch ab hier trivial?
1
double v = (double) t * 2048/32768.0; 
2
double w = v/1000;
3
itoa( w, ausgabe,2); 
4
lcd_string(ausgabe); 
5
ausgabe="."; 
6
lcd_string(ausgabe);
7
itoa( (v-1000*w), ausgabe,6); 
8
lcd_string(ausgabe);

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.
OP #4210641
Lesenswert?
• ▲
▼
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"
4
      
5
lcd_string("Solar ");
6
itoa( vorKomma, ausgabe,10);
7
lcd_string(ausgabe);
8
lcd_string(",");
9
itoa( nachKomma, ausgabe,10);
10
lcd_string(ausgabe);
11
lcd_string("  ");

Danke für deine Unterstützung!
#4214690
Lesenswert?
• ▲
▼
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 :-)
OP #4217201
Lesenswert?
• ▲
▼
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.
Gast #4219087
Lesenswert?
• ▲
▼
Formatiert ausgeben kannst du deine Spannung z.B. so...
1
void AdcValOut (uint16_t AdcValue)
2
{
3
    uint8_t AdcValArray [5];                                      // Integer Array
4
    uint8_t m = 4;                                                // Schleifenzähler für Ausgabe
5

6
    do  {
7
        AdcValArray [m] = '0' + AdcValue %10;                     // Berechnung der einzelnen Stellen sowie
8
        AdcValue /= 10;                                           // Wandlung nach ASCII und abspeichern im
9
    } while (m--);                                                // Array
10
    while (m != 3) {                                              // Anzahl der auszugebenden Stellen = 4
11
        lcd_string (AdcValArray [++m]);                           // ADC Wert ausgeben
12
        if (m == 0) lcd_string ('.');                             // Dezimalpunkt setzen
13
    }
14
}
OP #4219370
Lesenswert?
• ▲
▼
... irgendwie komme ich auch damit nicht klar. :(

Das Display liefert mir dabei nur wirre Zeichen.

... hab's jetzt so gelöst:

1
unsigned char val_array[4];
2
val_array[3] = v / 1000;
3
val_array[2] = v % 1000 / 100;
4
val_array[1] = v % 100 / 10;
5
val_array[0] = v % 10;
6
  
7
sprintf(ausgabe,"%d%d,%d%dV",val_array[3],val_array[2],val_array[1],val_array[0]);
8
lcd_string(ausgabe);

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren