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?
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?!?
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.
>Hier wird der Kontakt zwischen die Versorgungsspannung und den >Eingangspin geschaltet. Wo ?
Deine Hardware oder Deine Software hat vermutlich mindestens einen Fehler... ...
Korrigiere: Deine Hardware UND/oder Deine Software hat vermutlich mindestens einen Fehler... ...
ahhh danke :) man ich depp hab nicht dran gedacht batterie minus an masse zu legen....
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;
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.
wie? adc is ne variable da steht ein wert zwischen 0 - 1023 drin also ist es ja nicht immer 0
ne, aber 0,irgendwas und damit 0 in einer integer variable. deshalb solltest du auch zuerst multiplizieren und dann dividieren...
0/1024 = 0 1023/1024=0 alle Ergebnisse kleiner 1 ergeben bei "Nicht Kommaformaten" immer NULL
> 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.
Mach doch
1 | int u = ADC / 4; |
Dann ist u in hundertsten von Volt ausgedruckt, also 120 für eine 1,2V Zelle
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. ...
Walizer wrote:
> ok, was muss ich dann für einen datentyp nehmen? float?
Char dürfte reichen...
;-)
...
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.
>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
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...
Dann musst du dich halt darum kümmern, dass an die richtige Stelle auch ein Komma hin kommt.
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?
AD-Ref ist wirklich 2,56V ??? ...oder ausversehen an +5V angeschlossen? (ist mir auch mal passiert, ich hatte dann immer nur den halben Messwert)
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?
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. ...
doch natürlich, ich hab dort eingestellt das die interne 2,56 V ref Spannung benutzt werden soll
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
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
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 |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.