BASCOM ADC Spannung in mV berechnen mit Kalibrierung ohne Fließkomma

OP #4930765
Lesenswert?

Hallo zusammen,

Ausgangssituation: Controller wird mit 3,3V versorgt.
Spannungsteiler mit 220K und 68K, um bei der anliegenden LiPo-Spannung 
von 3,35V bis 4,25V unter die interne Referenzspannung von 1,1V zu 
kommen.
Die LiPo-Spannung soll permanent überwacht werden und mit dem Wert in mV 
intern weitergerechnet werden.

Gewünschte Messgenauigkeit: 4 Stellen, Ausgabe und interne 
Weiterverarbeitung in mV

Code-Idee:
1
Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1
2

3
Dim N As Byte
4
Dim Adc_messergebnis As Word                                'Der ADC liefert 10 Bit, die passen nicht in 1 Byte (8 Bit), von daher Word (= 2 Byte, 16 Bit)
5
Dim Millivolt As Single                                     'Gegen LONG austauschen!
6

7
Const Adc_multipli = 1.07421875                             'interne Referenzspannung 1100 Millivolt / 1024
8
Const Rvh = 3.235294117647059                               'Verhältnis der Widerstände am Spannungsteiler. R1 (in kOhm) / R2 (in kOhm)    220(K) / 68(K)
9
'Const Kalibrierung = 1.288                                  'Kalibrierung: Wert multiplizieren ->ANPASSEN! Wert solange anpassen, bis das Ergebnis dem Wert am Multimeter entspricht
10
Const Kalibrierung = 830                                    'Kalibrierung: Wert in mV addieren -> ANPASSEN! Wert solange anpassen, bis das Ergebnis dem Wert am Multimeter entspricht
11

12
Do
13

14
    Adc_messergebnis = Getadc(0)
15
    Millivolt = Adc_messergebnis * Adc_multipli
16
    'STATT ADC_MULTIPLI: Millivolt = Adc_messergebnis * 1100                     'ADC-Messergebnis * interne Referenzspannung (1100 mV)  -> Ergebnis würde in eine LONG Variable passen
17
    'STATT ADC_MULTIPLI:Millivolt = Millivolt / 1024
18
    Millivolt = Millivolt * Rvh
19
    'Millivolt = Millivolt * Kalibrierung
20
    Millivolt = Millivolt + Kalibrierung
21

22
   Print N ; " ADC-Wert: " ; Adc_messergebnis
23
   Print "Spannung: " ; Millivolt ; " mV"
24

25
   Incr N
26
   Wait 1
27

28
Loop

Berechnung zu Fuß:
Bei (laut Multimeter) 3,73 V am Spannungsteiler liegen am ADC Pin (laut 
Multimeter) 0,88V an.
Ausgegebener ADC Wert: 835 * 1.07421875 = 896.97265625 (Millivolt)
* Verhältnis der Widerstände 3.235294117647059 = 2901.970358455883
+ Kalibrierwert 830 = 3731.970358455883 = ~ 3731mV (= ~ 3,73V)

Stimmt das grundsätzlich so vom Ablauf?

Passt das mit der Kalibrierung? Besser multiplizieren oder addieren 
(oder egal!?).

Ich möchte vollständig auf Fließkommaberechnungen verzichten und die 
Single Variable durch Long oder noch besser Word ersetzen. Wie muss ich 
hierbei vorgehen? Mach das mit den Const FestKOMMAwerten dann überhaupt 
noch Sinn bei Long/Word?

Wie werde ich die Nachkommastellen los? Wenn ich Single durch Long 
ersetze, sind die Nachkommastellen verständlicherweise weg aber der Wert 
stimmt natürlich auch nicht mehr.


Danke vorab!
#4930787
Lesenswert?

@Robert G. (petrock)

>Meinst du damit ich soll als erstes die Festkommawerte so erhöhen, dass
>bei denen das Komma verschwindet?

Ja. Man rechnet einfach alles in mV.

>Aus "Const Adc_multipli = 1.07421875" würde 1074 und aus "Const Rvh =
>3.235294117647059" würde 3235.

Bingo!
OP #4930812
Lesenswert?

OK, Festkommawerte in normale Integerzahlen (ganzzahlig ohne 
Kommastellen) umgewandelt.

Nochmal zu Fuß:
ADC-Wert 835 * 1074 = 896790
/ 100, da sonst zu lang beim nächsten Rechenschritt (würde 2901115650 
ergeben) = 8967
8967 * 3235 = 29008245 <- passt in LONG rein
/ 10000, um auf mV zu kommen = 2900
2900 + Kalibrierwert von 830 = 3730 mV

Passt das so? Die zusätzlichen Teilungs-Rechenschritte sind immer noch 
besser als Fließkommazahlen? Macht der Controller das per "Shift"?

Ist das grundsätzlich mit der Kalibrierung so korrekt (mal abgesehen von 
eventuellen Temperaturanpassungen in Zukunft...)? 830mV als 
Kalibrierwert erscheint mir sehr hoch.
Gast #4930825
Lesenswert?

Hast Du Dir mal die Genauigkeit der internen Referenzspannung 
angeschaut? Beim ATmega168 z.B. kann sie laut Datenblatt eine Toleranz 
von +/- 100mV haben; da ist die Messgenauigkeit entsprechend fragwürdig.

Für genaue Ergebnisse im mV-Bereich muss entweder das System mit einer 
bekannten genauen Eingangs-Spannung (software-)kalibriert werden, oder 
man verwendet eine sehr genaue externe Referenzspannungsquelle.
OP #4930836
Lesenswert?

AVR-User schrieb im Beitrag #4930825:
> Für genaue Ergebnisse im mV-Bereich muss entweder das System mit einer
> bekannten genauen Eingangs-Spannung (software-)kalibriert werden, oder
> man verwendet eine sehr genaue externe Referenzspannungsquelle.

Meinst du damit, die Berechnung ist in Ordnung und der happige 
Kalibrierwert aufgrund von Bauteiltoleranzen ebenfalls?


Adc_messergebnis = Getadc(0)
Millivolt = Adc_messergebnis * Adc_multipli
Millivolt = Millivolt / 100                             '/ 100, da sonst 
beim nächsten Rechenschritt zu lang für LONG
Millivolt = Millivolt * Rvh
Millivolt = Millivolt / 100                             'statt / 10000, 
um auf mV zu kommen
Millivolt = Millivolt / 100                             'nochmal (statt 
10000)
Millivolt = Millivolt + Kalibrierung
Gast #4930895
Lesenswert?

Hallo,

dein Spannungsteiler ist sehr Hochohmig: 220K und 68K

verwende einen Puffer OPV mit vu = 1, so dass die Quellimpendanz unter 
dem Wert im Datenblatt liegt.
Verwende mehrere Messungen um einen Mittelwert zu bilden.
Gast #4930907
Lesenswert?

Robert G. schrieb:
> Berechnung zu Fuß:
> Bei (laut Multimeter) 3,73 V am Spannungsteiler liegen am ADC Pin (laut
> Multimeter) 0,88V an.
> Ausgegebener ADC Wert: 835 * 1.07421875 = 896.97265625 (Millivolt)
> * Verhältnis der Widerstände 3.235294117647059 = 2901.970358455883
> + Kalibrierwert 830 = 3731.970358455883 = ~ 3731mV (= ~ 3,73V)


Also gilt für deine realisierte Schaltung:
Multimeter = 3,73V,  ADC-Wert   = 835

Rückwärts gerechnet unter Einbeziehung von Spannungsteiler und Referenz:
3730mV / 835ADC-Schritte = 4,467065  mV/ADC-Schritt

Berechnung mit Bascom:

Const Adc_multipli = 4,467065

Adc_messergebnis = Getadc(0)
Millivolt = Adc_messergebnis * Adc_multipli

Fertig, aber vielleicht habe auch ich dein Ziel nicht verstanden.

Gruß Alex
OP #4930943
Lesenswert?

Die interne Referenzspannung liefert übrigens 1085mV und nicht 1100mV.
Durch die Anpassung auf 1085 passt es soweit mit der Kalibrierung über 
den gesamten Spannungsbereich, wenn der Wert multipliziert wird.

Const Adc_multiplikator = 10595                             'AREF = 1085 
Millivolt / 1024 = 1.0595703125
Const Rvh = 3235                                            'Verhältnis 
der Widerstände am Spannungsteiler. 220(K) / 68(K) = 3.235294117647059
Const Kalibrierung = 130

Adc_messergebnis = Getadc(0)
Millivolt = Adc_messergebnis * Adc_multiplikator
Millivolt = Millivolt / 100                             '/ 100, da sonst 
beim nächsten Rechenschritt zu lang für LONG
Millivolt = Millivolt * Rvh
Millivolt = Millivolt / 100
Millivolt = Millivolt * Kalibrierung
Millivolt = Millivolt / 1000                            'statt / 10000, 
um auf mV zu kommen
Millivolt = Millivolt / 100                             'nochmal (statt 
/10000)
OP #4930998
Lesenswert?

Allu schrieb:
> Berechnung mit Bascom:
>
> Const Adc_multipli = 4,467065
>
> Adc_messergebnis = Getadc(0)
> Millivolt = Adc_messergebnis * Adc_multipli
>
> Fertig, aber vielleicht habe auch ich dein Ziel nicht verstanden.
>
> Gruß Alex

Tjoa, so einfach kann es sein. Danke für den Rechenweg! Ich probier 
beide Wege in der Liveschaltung aus.
#4931010
Lesenswert?

Karl M. schrieb:
> dein Spannungsteiler ist sehr Hochohmig: 220K und 68K
>
> verwende einen Puffer OPV mit vu = 1, so dass die Quellimpendanz unter
> dem Wert im Datenblatt liegt.
> Verwende mehrere Messungen um einen Mittelwert zu bilden.

Ein OPV ist unnötig, eine 100nF Pille reicht völlig aus, um den kurzen 
ADC-Samplepuls zu puffern.
Einen OPV brauchst Du nur für sehr schnelle Wandlungen, wie z.B. 
Audioaufzeichnung.
Gast #4931077
Lesenswert?

33Kund 11K ergibt einen Spannungsteiler von 1 zu 4.
Nurmal so...

Btw.
77K (75K+2.0K) und 11K ergibt einen Spannungsteiler von 1 zu 8.

150K und 10K dann 1 zu 16.

Dann muss man nicht mit "krummen Werten" rumzirkeln...

StromTuner
Gast #4931207
Lesenswert?

Robert G. schrieb:
> 4 Stellen, Ausgabe und interne
> Weiterverarbeitung in mV

Möglich sind immer viele Wege, einer könnte in deine Struktur eingesetzt 
sein:

'  +++  Vorgaben hier Eintragen   +++++++
Const U_multimeter = 3730               ' in mV
Const Adc_wert = 835                    ' in Schritten von 0 bis 1023


'  Vorbereitung für Berechnung
Const Adc_multipli = U_multimeter / Adc_wert       ' = 4 . 467065

'  Variablen
Dim N As Byte
Dim Adc_messergebnis As Word
Dim Millivolt_single As Single
Dim Millivolt As Word


'  Hauptprogramm
Do

'  Messen und Ergebnis berechnen
Adc_messergebnis = Getadc(0)
Millivolt_single = Adc_messergebnis * Adc_multipli

'   4-stellig in mV
Millivolt_single = Millivolt_single + 0.5       ' +0,5 zum Runden in mV
Millivolt = Int(millivolt_single)


Print N ; " ADC-Wert: " ; Adc_messergebnis
   Print "Spannung: " ; Millivolt ; " mV"

   Incr N
   Waitms 1
Loop

Peter D. schrieb:
> Ein OPV ist unnötig, eine 100nF Pille reicht völlig aus, um den kurzen
> ADC-Samplepuls zu puffern.

Finde ich auch besser als einen niederohmigen Spannungsteiler, schont 
die Batterie.

Gruß  Alex
Gast #4931245
Lesenswert?

Paul B. schrieb:
> Das Datenblatt findet aber normalerweise niederohmige Quellen besser.

Peter D. schrieb:
> Ein OPV ist unnötig, eine 100nF Pille reicht völlig aus, um den kurzen
> ADC-Samplepuls zu puffern.
> Einen OPV brauchst Du nur für sehr schnelle Wandlungen, wie z.B.
> Audioaufzeichnung.

Nach meiner Meinung ist unter diesen Betriebsbedingugen ein 100nF eine 
niederohmige Quelle.

Gruß  Alex
Gast #4931315
Lesenswert?

Robert G. schrieb:
> Also die Kalibrierung geht so nicht. Bei angelegten 3,73V passt es (da
> der Kalibrierwert darauf angepasst wurde) aber bei 4,2V oder 3,3V
> driftet der angezeigte Wert in mV total ab.
Ich verstehe den gesamten Ablauf nicht. Die Rechnerei mit 
Spannungsteiler und Referenz macht keinen Sinn, da alle Komponenten 
Toleranzen haben.

Wenn ich eine Spannung messen will, lasse ich mir den AD-Wert auf die 
serielle Schnittstelle oder das Display ausgeben. Ich lege Spannung an, 
z.B. 4,3Volt. Kommt dann als Digitalwert 1015 raus, ergibt sich 
4300/1015=4,2365. Das machst Du an mindestens zwei Punkten und nimmst 
ggfs. den Mittelwert daraus.

Also ist meine Spannung Digitalwert mal 4,236: Bei einem Wert von 600 
wären das 2,54Volt.

Robert G. schrieb:
> Gewünschte Messgenauigkeit: 4 Stellen,
Das ist fernab jeglicher Realität. Du hast 4,25V auf 1024 Schritte, also 
eine Quantisierung auf rund 4mV. Ein bischen Rauschen und dazu 
Rundungsfehler - wenn Du die zweite Stelle hinter dem Komma halbwegs 
halten kannst, 20mV Ablage, bist Du schon gut bedient. Mal etwas suchen, 
das Thema Meßgenauigkeit war erst vor wenigen Tagen hier im Forum.

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