Forum: Analoge Elektronik und Schaltungstechnik Spannung mit ADC Messen


von Walizer (Gast)


Lesenswert?

Hallo,

würde gerne die Spannung einer 1,2 V Batterie Messen,
ADC einlesen klappt auch schon hab ich mit Poti getestet,
nun also ich zieh den Input Pin auf Masse, und dazwischen klemm ich dann 
den Plus Pol eine 1,2 Batterie an, dann müsste es doch einen Wert 
ausgeben,
bei mir liest er immer nur 0 aus was könnte da falsch sein?
muss ich noch etwas beachten?

von Magnus Müller (Gast)


Lesenswert?

Walizer wrote:
> Hallo,
>
> würde gerne die Spannung einer 1,2 V Batterie Messen,
> ADC einlesen klappt auch schon hab ich mit Poti getestet,

...schön...

> nun also ich zieh den Input Pin auf Masse,

...wozu das denn?

> und dazwischen klemm ich dann den Plus Pol eine 1,2 Batterie an,

"dazwischen"...    ...zwischen WAS?!?

von Walizer (Gast)


Lesenswert?

Hier wird der Kontakt zwischen die Versorgungsspannung und den 
Eingangspin geschaltet.

Damit bei offener Schalterstellung kein undefiniertes Signal am 
Controller ansteht, wird zwischen den Eingangspin und die Masse ein 
Pull-Down Widerstand geschaltet. Dieser dient dazu, den Pegel bei 
geöffneter Schalterstellung auf logisch 0 zu halten.

von Dummy (Gast)


Lesenswert?

>Hier wird der Kontakt zwischen die Versorgungsspannung und den
>Eingangspin geschaltet.

Wo ?

von Walizer (Gast)


Lesenswert?

ist das falsch? oder wie funktioniert das sonst?

von Hannes L. (hannes)


Lesenswert?

Deine Hardware oder Deine Software hat vermutlich mindestens einen 
Fehler...

...

von Michael (Gast)


Lesenswert?

Korrigiere:

Deine Hardware UND/oder Deine Software hat vermutlich mindestens einen
Fehler...

...

von Michael (Gast)


Lesenswert?

batterie minus an masse
batterie plus an den ADC

von Walizer (Gast)


Lesenswert?

ahhh danke :)
man ich depp hab nicht dran gedacht batterie minus an masse zu legen....

von Walizer (Gast)


Lesenswert?

also jetzt liefert er mir einen Wert :)

nun klappt jedoch die Umrechnung in V nicht so richtig:
die Berechnung müsste doch so stimmen oder?
int u = adc / 1024 * 2.56;

von m_bedded (Gast)


Lesenswert?

Wenn Du so was mit C programmierst, achte drauf, dass erst multipliziert 
und dann dividiert wird. Denn der Compliler hat Zwischenergebnisse auch 
als int, und da geht die Genauigkeit verloren.

Machmal hilft es, long int Variablen zu deklarieren, und ganz am Ende 
wieder zu int gehen.

von Dummy (Gast)


Lesenswert?

adc / 1024 ist immer 0 :(

von Walizer (Gast)


Lesenswert?

wie?
adc is ne variable da steht ein wert zwischen 0 - 1023 drin also ist es 
ja nicht immer 0

von Werner A. (homebrew)


Lesenswert?

ne, aber 0,irgendwas und damit 0 in einer integer variable.
deshalb solltest du auch zuerst multiplizieren und dann dividieren...

von Der T. (Gast)


Lesenswert?

..als int schon..

von MichiB (Gast)


Lesenswert?

0/1024 = 0
1023/1024=0

alle Ergebnisse kleiner 1 ergeben bei "Nicht Kommaformaten" immer NULL

von Magnus Müller (Gast)


Lesenswert?

> int u = adc / 1024 * 2.56;

Selbst wenn du die Reihenfolge umdrehst...

    int u = adc * 2.56 / 1024;

wirst du damit nicht glücklich werden, da dann als mögliche Ergebnisse 
nur die Zahlen 0, 1 und 2 in Frage kommen.

von m_bedded (Gast)


Lesenswert?

Mach doch
1
int u = ADC / 4;

Dann ist u in hundertsten von Volt ausgedruckt, also 120 für eine 1,2V 
Zelle

von Hannes L. (hannes)


Lesenswert?

Gabs dazu nicht ein Tutorial Festkommaaritmetik?

...

von Walizer (Gast)


Lesenswert?

ok, was muss ich dann für einen datentyp nehmen? float?

von Hannes L. (hannes)


Lesenswert?

m_bedded wrote:
> Mach doch
>
>
1
int u = ADC / 4;
>
> Dann ist u in hundertsten von Volt ausgedruckt, also 120 für eine 1,2V
> Zelle

Die Division kann man sich sparen, wenn man den ADC 8-bittig ausliest.

...

von Hannes L. (hannes)


Lesenswert?

Walizer wrote:
> ok, was muss ich dann für einen datentyp nehmen? float?

Char dürfte reichen...

;-)

...

von Walizer (Gast)


Lesenswert?

jetzt bin ich verwirrt :)
kapier jetzt garnix mehr,
ich kann doch nicht einfach den Wert den der AD Wandler einliest durch 4 
teilen?
ich möchte ja den AD wert in V umrechnen.

von Walizer (Gast)


Lesenswert?

gibts für sowas ein Tutorial?

von holger (Gast)


Lesenswert?

>ich möchte ja den AD wert in V umrechnen.

Ja klar, aber denk doch mal nach !

>int u = adc / 1024 * 2.56;

Setz doch einfach mal Werte ein:

0 / 1024 * 2.56 = 0 => integer 0
512 / 1024 * 2.56 = 1.28 => integer 1
1023 / 1024 * 2.56 = 2.55 => integer 2

integer hat keine Nachkommastellen !
Wenn du Nachkommastellen haben möchtest
musst du einen Skalenfaktor benutzen.
Für zwei Stellen hinter dem Komma ist das 100.
Dann sparst du dir auch die float Multiplikation.

512 / 1024 * 256 = 128 => integer 128

Das stellst du dann günstig um:

adc * 256 / 1024

und das ist

adc / 4

von Walizer (Gast)


Lesenswert?

ahh ok das check ich jetzt,
ok gut nur ich möchte den Messwert dann gerne auf einem LCD ausgeben
da ist es halt bissl blöd wenn die Werte dann ohne Komma angezeigt 
werden...

von Magnus Müller (Gast)


Lesenswert?

Dann musst du dich halt darum kümmern, dass an die richtige Stelle auch 
ein Komma hin kommt.

von Walizer (Gast)


Lesenswert?

ok, danke für die hilfe,

von Walizer (Gast)


Lesenswert?

melde mich nochmal, das ganze klappt wohl doch noch nicht so wie es 
sollte...
 habe jetzt ein paar Messungen durchgeführt und es kam immer nur so ca 
0,4 - 0,6 V raus dann dacht ich mir das kann nicht sein und hab mit dem 
Multimeter nachgemessen dort waren es dann 1,2 was könnte die 
Fehlerursache sein?

von Bastler (Gast)


Lesenswert?

AD-Ref ist wirklich 2,56V ???
...oder ausversehen an +5V angeschlossen?
(ist mir auch mal passiert, ich hatte dann immer nur den halben 
Messwert)

von Walizer (Gast)


Lesenswert?

ich benutz das myavr board

von Walizer (Gast)


Lesenswert?

aber wenn ich so überleg könnte das durchaus sein, denn ich bekam ja als 
Messwert 0,6 raus und mit multimeter 1,2 aber es ist doch egal wo aref 
angeschlossen ist wenn man im AD-Wandler einstellt das er die interne 
2,56 Ref  Spannung nehmen soll oder?

von Hannes L. (hannes)


Lesenswert?

Walizer wrote:
> aber wenn ich so überleg könnte das durchaus sein, denn ich bekam ja als
> Messwert 0,6 raus und mit multimeter 1,2 aber es ist doch egal wo aref
> angeschlossen ist wenn man im AD-Wandler einstellt das er die interne
> 2,56 Ref  Spannung nehmen soll oder?

Na weißt Du denn nicht, was Du in ADMUX als Messquelle, Referenzquelle 
und Resultatausrichtung eingestellt hast? Der ADC würfelt seine 
Referenz-Quelle nicht aus, sondern nimmt exakt das, was Du ihm per 
Programm vorgegeben hast. Siehe Datenblatt -> ADMUX

An AREF gehört übrigens (bei neueren AVRs) nur ein Glättungskondensator 
angeschlossen. Die Auswahl der Referenz intern oder AVcc erfolgt über 
ADMUX. Nur wenn eine externe Referenz benötigt wird, darf diese an AREF 
angeschlossen werden, dann ist aber darauf zu achten, dass mit ADMUX 
nicht versehentlich auf intern oder AVCC umgeschaltet wird.

...

von Walizer (Gast)


Lesenswert?

doch natürlich, ich hab dort eingestellt das die interne 2,56 V ref 
Spannung benutzt werden soll

von Magnus Müller (Gast)


Lesenswert?

Walizer wrote:
> doch natürlich, ich hab dort eingestellt das die interne 2,56 V ref
> Spannung benutzt werden soll

...wir wollen / müssen Code sehen.

Gruß,
Magnetus

von Murmel64 (Gast)


Lesenswert?

c

' Die an den ADC-Ports 0 und 1 anliegende Spannung wird in eine digitale 
Zahl
' zwischen 0 und 1023 umgewandelt. Der diesem Wert ensprechende 
Spannungswert
' wird auf dem LCD Display angezeigt. Bei einem Überlauf wird " HHHH V" 
ange-
' zeigt.


Dim wert1, wert2 As Single                      ' Deklaration der 
globalen
Dim zeile1(10) As Char                  ' Variablen
Dim zeile2(10) As Char

'----------------------------------------------------------------------- 
--------
' Hauptprogramm
'
Sub main()
    LCD_Init()                          ' Display wird initialisiert
    LCD_ClearLCD()                      ' Display wird gelöscht
    LCD_CursorOff()                     ' Cursor wird ausgeschaltet

    zeile1=" 0.00"                      ' default Wert für Zeile1
    zeile2=" 0.00"                      ' default Wert für Zeile2
    Do While (True)                     ' Endlosschleife wird gestartet
    ADC_Set(ADC_VREF_VCC,0)                     ' Port 0 des A/D 
Wandlers wird initialisiert
                                                                ' Vcc 
(5V) ist Referenzspannung
    wert1 = ADC_Read()*5.0/1024.0       ' Der analoge Zahlenwert des ADC 
Portes 0
                                    ' wird in die Variable "wert1" 
gespeichert
                                    ' "5.0/1024.0" dient zur Umrechnung 
in den
                                    ' ensprechenden Spannungswert
    ADC_Set(ADC_VREF_VCC,1)             ' Port 1 des A/D Wandlers wird 
initialisiert
                                        ' Vcc (5V) ist Referenzspannung
    wert2 = ADC_Read()*5.0/1024.0       ' Der analoge Zahlenwert des ADC 
Portes 1
                                    ' wird in die Variable "wert1" 
gespeichert
                                    ' "5.0/1024.0" dient zur Umrechnung 
in den
                                    ' ensprechenden Spannungswert
    Ausgabe()                       ' Durch diesen Funktionsaufruf 
werden die
                                                                ' 
Messwerte auf dem Display ausgegeben.
    AbsDelay(500)                   ' 500ms Verzögerung bis zur nächsten 
Messung
    End While
End Sub

' Displayausgabe des 2 Kanal Voltmeters
' erforderliche Library: IntFunc_Lib.cc, LCD_Lib.cc

'----------------------------------------------------------------------- 
--------
' Displayausgabe
'
Sub Ausgabe()
        Dim einheit(3) As Char          ' Deklaration der globalen
        einheit = " V"                  ' Festlegung der angezeigten 
Einheit
    If wert1>4.99 Then              ' Bei zu großen Messwerten an ADC0 
wird
        zeile1=" HHHH"              ' " HHHH" in Zeile1 angezeigt.
    Else
        Str_WriteFloat(wert1,2,zeile1,1)        ' Die Floatvariable 
"wert1" wird in
    End If                                  ' einen Text mit 2 
Dezimalstellen
                                            ' und einem Offset von 1 
umgewandelt
    If wert2>4.99 Then                  ' Bei zu großen Messwerten an 
ADC1 wird
        zeile2=" HHHH"                  ' " HHHH" in Zeile2 angezeigt.
    Else
        Str_WriteFloat(wert2,2,zeile2,1)    ' Die Floatvariable "wert2" 
wird in
    End If                                  ' einen Text mit 2 
Dezimalstellen
                                            ' und einem Offset von 1 
umgewandelt
    LCD_CursorPos(0x00)                 ' Der Cursor wird an den Anfang 
der ersten
                                                                ' Zeile 
gesetzt.
    LCD_WriteText(zeile1)               ' Variable "zeile1" wird 
ausgegeben
    LCD_WriteText(einheit)              ' Einheit wird ausgegeben
    LCD_CursorPos(0x40)                 ' Der Cursor wird an den Anfang 
der zweiten
                                        ' Zeile gesetzt.
        LCD_WriteText(zeile2)           ' Variable "zeile1" wird 
ausgegeben
        LCD_WriteText(einheit)          ' Einheit wird ausgegeben
End Sub

/C

Hier hast Du mal Code zum austoben allerdings in Basic und für 
CC-Control

Lies dir mal das Tuturial durch.

Gruß Murmel

von Murmel64 (Gast)


Lesenswert?

1
' Die an den ADC-Ports 0 und 1 anliegende Spannung wird in eine digitale
2
Zahl
3
' zwischen 0 und 1023 umgewandelt. Der diesem Wert ensprechende
4
Spannungswert
5
' wird auf dem LCD Display angezeigt. Bei einem Überlauf wird " HHHH V"
6
ange-
7
' zeigt.
8
9
10
Dim wert1, wert2 As Single                      ' Deklaration der
11
globalen
12
Dim zeile1(10) As Char                  ' Variablen
13
Dim zeile2(10) As Char
14
15
'-------------------------------------------------------------------------------
16
' Hauptprogramm
17
'
18
Sub main()
19
    LCD_Init()                          ' Display wird initialisiert
20
    LCD_ClearLCD()                      ' Display wird gelöscht
21
    LCD_CursorOff()                     ' Cursor wird ausgeschaltet
22
23
    zeile1=" 0.00"                      ' default Wert für Zeile1
24
    zeile2=" 0.00"                      ' default Wert für Zeile2
25
    Do While (True)                     ' Endlosschleife wird gestartet
26
    ADC_Set(ADC_VREF_VCC,0)                     ' Port 0 des A/D
27
Wandlers wird initialisiert
28
                                                                ' Vcc
29
(5V) ist Referenzspannung
30
    wert1 = ADC_Read()*5.0/1024.0       ' Der analoge Zahlenwert des ADC
31
Portes 0
32
                                    ' wird in die Variable "wert1"
33
gespeichert
34
                                    ' "5.0/1024.0" dient zur Umrechnung
35
in den
36
                                    ' ensprechenden Spannungswert
37
    ADC_Set(ADC_VREF_VCC,1)             ' Port 1 des A/D Wandlers wird
38
initialisiert
39
                                        ' Vcc (5V) ist Referenzspannung
40
    wert2 = ADC_Read()*5.0/1024.0       ' Der analoge Zahlenwert des ADC
41
Portes 1
42
                                    ' wird in die Variable "wert1"
43
gespeichert
44
                                    ' "5.0/1024.0" dient zur Umrechnung
45
in den
46
                                    ' ensprechenden Spannungswert
47
    Ausgabe()                       ' Durch diesen Funktionsaufruf
48
werden die
49
                                                                '
50
Messwerte auf dem Display ausgegeben.
51
    AbsDelay(500)                   ' 500ms Verzögerung bis zur nächsten
52
Messung
53
    End While
54
End Sub
55
56
' Displayausgabe des 2 Kanal Voltmeters
57
' erforderliche Library: IntFunc_Lib.cc, LCD_Lib.cc
58
59
'-------------------------------------------------------------------------------
60
' Displayausgabe
61
'
62
Sub Ausgabe()
63
        Dim einheit(3) As Char          ' Deklaration der globalen
64
        einheit = " V"                  ' Festlegung der angezeigten
65
Einheit
66
    If wert1>4.99 Then              ' Bei zu großen Messwerten an ADC0
67
wird
68
        zeile1=" HHHH"              ' " HHHH" in Zeile1 angezeigt.
69
    Else
70
        Str_WriteFloat(wert1,2,zeile1,1)        ' Die Floatvariable
71
"wert1" wird in
72
    End If                                  ' einen Text mit 2
73
Dezimalstellen
74
                                            ' und einem Offset von 1
75
umgewandelt
76
    If wert2>4.99 Then                  ' Bei zu großen Messwerten an
77
ADC1 wird
78
        zeile2=" HHHH"                  ' " HHHH" in Zeile2 angezeigt.
79
    Else
80
        Str_WriteFloat(wert2,2,zeile2,1)    ' Die Floatvariable "wert2"
81
wird in
82
    End If                                  ' einen Text mit 2
83
Dezimalstellen
84
                                            ' und einem Offset von 1
85
umgewandelt
86
    LCD_CursorPos(0x00)                 ' Der Cursor wird an den Anfang
87
der ersten
88
                                                                ' Zeile
89
gesetzt.
90
    LCD_WriteText(zeile1)               ' Variable "zeile1" wird
91
ausgegeben
92
    LCD_WriteText(einheit)              ' Einheit wird ausgegeben
93
    LCD_CursorPos(0x40)                 ' Der Cursor wird an den Anfang
94
der zweiten
95
                                        ' Zeile gesetzt.
96
        LCD_WriteText(zeile2)           ' Variable "zeile1" wird
97
ausgegeben
98
        LCD_WriteText(einheit)          ' Einheit wird ausgegeben
99
End Sub

von Murmel64 (Gast)


Lesenswert?

Ein weiteres Beispiel in C- Compact.

Auslesen eines Drucksensors mit Ausgabe auf Display und 
Datenübertragung.

Die Doku ist nicht aktuell!!!
1
float Vmess1, Vmess2;
2
float wert1, wert2, wert3, wert4, wert5, wert6, wert7, wert8, wert9;                                     // Deklaration der globalen
3
char zeile1[40];                                // Variablen
4
char zeile2[10];
5
char zeile3[40];
6
char zeile4[40];
7
char zeile5[40];
8
char zeile6[40];
9
//char Buffer[82];
10
//byte data;
11
//byte Buf_Index;
12
//-------------------------------------------------------------------------------
13
// Hauptprogramm
14
//
15
void main(void)
16
{
17
18
    // Initialisiere Schnittstelle mit 9600baud, 8 Bit, 1 Stop Bit, keine Parität
19
    Serial_Init(0,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD9600);
20
21
    LCD_Init();                         // Display wird initialisiert
22
    //LCD_ClearLCD();                     // Display wird gelöscht
23
    //LCD_CursorOff();                    // Cursor wird ausgeschaltet
24
    //Buf_Index=0;
25
26
27
28
29
    while (true)                        // Endlosschleife wird gestartet
30
    {
31
32
        LCD_ClearLCD();
33
        LCD_CursorOff();
34
35
        Sensoren();
36
37
        Ausgabe();                  // Durch diesen Funktionsaufruf werden die
38
                                   // Messwerte auf dem Display ausgegeben.
39
        //Daten();
40
        AbsDelay(30000);              // 500ms Verzögerung bis zur nächsten Messung
41
42
43
    //Daten();
44
    }
45
}
46
47
48
//Sensoren------------------------------------------------------------------------------------
49
void Sensoren(void)
50
{
51
        ADC_Set(ADC_VREF_VCC,0);        // Port 0 des A/D Wandlers wird initialisiert
52
                                                        // Vcc (5V) ist Referenzspannung
53
        Vmess1=ADC_Read()*5.0/1024.0;  // Der analoge Zahlenwert des ADC Portes 0
54
55
                                    // wird in die Variable "wert1" gespeichert
56
                                    // "5.0/1024.0" dient zur Umrechnung in den
57
                                    // ensprechenden Spannungswert
58
       //ADC_Set(ADC_VREF_VCC,1);        // Port 1 des A/D Wandlers wird initialisiert
59
                                        // Vcc (5V) ist Referenzspannung
60
       //wert3=ADC_Read()*5.0/1024.0;  // Der analoge Zahlenwert des ADC Portes 1
61
                                    // wird in die Variable "wert1" gespeichert
62
                                    // "5.0/1024.0" dient zur Umrechnung in den
63
                                    // ensprechenden Spannungswert
64
65
}
66
67
68
//-------------------------------------------------------------------------------
69
// Displayausgabe
70
//
71
72
void Ausgabe(void)
73
{
74
75
        char einheit[21];                        // Deklaration der globalen
76
        char SV[21];
77
        char Vcc[10];
78
        char einheit1[21];
79
        char sep1[8];
80
        char sep2[8];
81
        char sep3[8];
82
        char sep[8];
83
84
85
        einheit= " hPa";                 // Festlegung der angezeigten Einheit
86
        SV= " Drucksensor";
87
        Vcc= " Vcc";
88
        einheit1= " hPa";
89
90
    sep ="|V1|";
91
    sep1 ="|D1|";
92
    sep2 ="|D2|";
93
    sep3 ="||";
94
95
96
    Str_WriteFloat(wert8,0,zeile2,0);
97
    Str_Copy(zeile2,sep,STR_APPEND);
98
    Serial_WriteText(0, zeile2);
99
100
101
    Str_WriteFloat(Vmess1,3,zeile1,0);
102
    Str_Copy(zeile1,sep1,STR_APPEND);
103
    Serial_WriteText(0, zeile1);
104
105
106
    wert2 =(Vmess1/5.0+0.1518)/0.01059*10;
107
    Str_WriteFloat(wert2,0,zeile3,0);
108
    Str_Copy(zeile3,sep2,STR_APPEND);
109
    Serial_WriteText(0, zeile3);
110
111
    wert4 =(Vmess1/5.0+0.1518)/0.01059*10+16.375;
112
    Str_WriteFloat(wert4,0,zeile4,0);
113
    Str_Copy(zeile4,sep3,STR_APPEND);
114
    Serial_WriteText(0, zeile4);
115
116
    //Msg_WriteText(zeile5);
117
118
    Str_WriteFloat(Vmess1,3,zeile1,0);
119
    LCD_CursorPos(0x00);
120
    LCD_WriteText(zeile1);
121
    LCD_WriteText(SV);
122
123
    Str_WriteFloat(wert2,0,zeile3,0);
124
    LCD_CursorPos(0x14);
125
    LCD_WriteText(zeile3);
126
    LCD_WriteText(einheit);
127
128
    Str_WriteFloat(wert4,0,zeile4,0);
129
    LCD_CursorPos(0x54);
130
    LCD_WriteText(zeile4);
131
    LCD_WriteText(einheit1);
132
133
134
}

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
Noch kein Account? Hier anmelden.