Forum: Mikrocontroller und Digitale Elektronik ADC Text-LCD-Ausgabe


von batty m. (battyman)


Lesenswert?

Nabends allerseits,

Ich friemel derzeitig an der AD Wandlung rum und bin mit dem Tutorial 
und dem Datenblatt am Ende.
Also, benutzt wird ein ATmega2560. Wenn ich das Datenblatt jetzt richtig 
verstanden habe, ist der Port 'K' für die AD-Wandlung als Eingang 
vorgesehen, richtig? Oder muss ich das Register des PortK zusätzlich 
(vor ADC_Init())als Eingang definieren?
Als Referenzspannung habe ich die internen 2,56V deklariert und ein 
Prescaler von 64 (-> 125 kHz bei F_CPU = 8 MHz) eingestellt.

Weiterhin habe ich ein Text-LCD am PortA und 8 LEDs an PortC dran.
Mit der Einbindung und Anpassung der "lcd.h" und "lcd.c" funktioniert 
die lcd_data-, als auch lcd_string- Über-/Ausgabe einwandfrei. Eine als 
string deklarierte Zahl kann mittels "my_print_lcd()" (aus Artikel 
"Festkommazahl") mit einem Komma an der gewollten Position auch 
dargestellt werden.
Das Ansprechen der LEDs funktioniert ebenfalls wie gewünscht.

Probleme:

1.)
In dem Augenblick in der ich in der "int main (void)" meine 
"ADC_Init();" einbinde, scheint das Programm nicht durchzulaufen. Ein 
Fehler bei der Kompelierung ist nicht vorhanden. LCD zeigt nichts an, 
LEDs bleiben auch aus. :-(
Da ich n bissl Angst hab, mein µC zu zerstören habe ich noch keine 
Spannung an PortK Pin0 angelegt. Müsste der µC dann nicht einfach Null 
Volt einlesen?
Oder passiert genau aus diesem Grund nichts mit meinem Programm, da es 
auf die Beendigung der Konvertierung wartet?

2.)
Eigentlich wollte ich eine permanente AD-Wandlung laufen lassen. Wenn 
ich ins Datenblatt sehe, dann gibts dort den ADFR (Figure 26-1 S.276). 
Wenn ich dieses Bit setze und dem ADCSRA übergebe kennt der Compiler den 
Ausdruck nicht. Nun habe ich i-wo gelesen das bei den neueren ATmegas 
der Ausdruck "ADATE" mit einem Bit versehen werden muss. Muss denn noch 
was i-wo eingeschrieben werden? Kann dass
1
ADCSRA |= (1<<ADATE);
 so stehend mein "Programmaussetzer" auslösen? Als Problem 1.) auslösen?

3.)
Ich weiß leider nicht wie ich den ausgelesenen ADC-Wert an die "itoa()" 
übergebe, um daraus einen String zu generieren der dann wiederum an die 
"my_print_lcd()" übergeben wird, welches den String entsprechend zerlegt 
und anschließend ausgibt???

Bitte um Hilfestellung. Vielen Dank, denn aus den nötigen Seiten kann 
ich keine weiteren Infos zum Weiterkommen entlocken.

LG

: Bearbeitet durch User
von Uwe (de0508)


Lesenswert?

Hallo,

ohne weitere Infos wird man dir nicht helfen können!

Da ist
a) der gesamte Code - übersetzbar,
b) ein Schaltplan mit allen Details und
c) Bilder von realen Aufbau.

Das wird auch immer gefragt, denn wie soll man aus der ferne sonst 
logisch nach Fehlern suchen, meist sind sie an einer anderen Stelle, wie 
du Sie vermutest.

von batty m. (battyman)


Lesenswert?

ADC-Code:
1
#include <avr/io.h>
2
#include "lcd.h"
3
#define F_CPU 8000000UL
4
#include <util/delay.h>
5
6
void ADC_Init(void)
7
{
8
  ADMUX = (1<<REFS1) | (1<<REFS0);            //setzt die Referenzspannung als intern und mit 2,56V
9
  ADCSRA = (1<<ADPS2) | (1<<ADPS1);            //Taktfrequ.-Teilungsfaktor (Prescaler Select) = 64 für f = 125 kHz
10
  ADCSRA |= (1<<ADEN);                  //aktiviert den AD-Wandler
11
  ADCSRA |= (1<<ADATE);                  //Bit wird für Free-Running - permanente Messung - gesetzt
12
  ADCSRA |= (1<<ADSC);                  //startet die AD-Wandlung
13
  
14
  while (ADCSRA & (1<<ADSC))  {              //wartet auf Beendigung der Wandlung
15
  }
16
  
17
  (void)ADCW;
18
}
19
20
uint16_t ADC_Read(uint8_t channel)              //AD-Wandlung - Einzelmessung
21
{
22
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);      //Wahl des Kanals - Maskierung der 5 Mux-Bits
23
  ADCSRA |= (1<<ADSC);                  //startet die AD-Wandlung
24
  while (ADCSRA & (1<<ADSC))  {              //wartet auf Beendigung der Wandlung
25
  }
26
  return ADCW;                      //AD-Wandler auslesen und ausgeben
27
}
28
29
uint16_t ADC_Read_Avg(uint8_t channel, uint8_t nsamples)  //AD-Wandlung - Mehrfachmessung mit Mittelwert (engl. Average)
30
{
31
  uint32_t sum = 0;                    //32-Bit Variable für Summe
32
  for (uint8_t i = 0; i < nsamples; i++)          //von 0 bis Anzahl der Messung
33
  {
34
    sum += ADC_Read(channel);              //Aufaddierung der Einzelmessungen
35
  }
36
  return (uint16_t)(sum / nsamples);            //Ausgabe des Mittelwertes
37
}

Main-Code:
1
int main(void)
2
{
3
  uint16_t adcval;
4
  lcd_init();
5
  ADC_Init();
6
  DDRC = 0xff;
7
  
8
    while(1)
9
    {  
10
    adcval = ADC_Read(0);                //Wertübergabe aus Einzelmessung - Kanal 0
11
    //adcval = ADC_Read_Avg(0, 5);            //Mittelwertübergabeaus 5 Einzelmessungen - Kanal 0
12
    if (adcval >= 1)
13
    {
14
      PORTC |= ~(1<<PC0);
15
    } 
16
    else
17
    {
18
      PORTC |= ~(1<<PC3);
19
    }
20
    
21
    /* LCD-Überprüfung zur Probe - eigentlich soll hier der ADCW ins itoa und dann aufs LCD */
22
    char my_string[12] = "-00345678\0";
23
    LCD_Ausgabe(my_string, 3, 4, 2);
24
    lcd_string("V");
25
    _delay_ms(150);
26
    lcd_setcursor(1,2);
27
    lcd_string("puuPS");
28
    _delay_ms(50);
29
    lcd_clear();
30
    }
31
  return 0;
32
}

Bei der gesamten Kompelierung gibts kein Error, Fehler oder Meldung.

Schaltplan gibts kein. Würde nur ein Labor-Schaltnetzteil auf den Pin 
anlegen und manuell im Bereich von 0,1 - 2,4V durch drehen. Strom dabei 
auf Minimum festgestellt.
LEDs sind mit der 5V Boardsp. gespeist und liegen auf PortC. 
Text-Display ist ein EA W204B-NLW und hängt korrekt am PortA.

THX

von innerand i. (innerand)


Lesenswert?

batty man schrieb:
> ADC-Code:
>
1
>   while (ADCSRA & (1<<ADSC))  {              //wartet auf Beendigung der 
2
> Wandlung
3
>   }

Ich denke hier gibt es ein Problem. ADSC bleibt im Free-Running Mode 
immer 1, das ergibt hier also eine Endlosschleife.

von batty m. (battyman)


Lesenswert?

Mhh, ich muss doch trotzdem die 13 Umwandlungstakt abwarten, denn sonst 
erhalte ich doch Müll oder nicht?
Das erscheint mir gerade noch nicht ganz logisch.
Für mich ists so, dass ich den ADC starte, der diesen die anliegende 
Spannung misst und dann in 13 Takten in eine digitale Zahl wandelt, 
während dieser Zeit kann bzw. soll der ADC einfach die Spannungsmessung 
weiter laufen lassen. Wenn die Umwandlung abgeschlossen ist, soll sofort 
der nächste Wert eingelesen und gewandelt werden. Zumindest habe ich das 
so verstanden?!?!

Danke

von Karl H. (kbuchegg)


Lesenswert?

batty man schrieb:
> Mhh, ich muss doch trotzdem die 13 Umwandlungstakt abwarten, denn sonst
> erhalte ich doch Müll oder nicht?

Du musst dich vor allen Dingen entscheiden.
Was willst du?

Willst du, dass der ADC still und leise vor sich hinwandelt und zwar 
dauernd und du dir ein Ergebnis abholst, wann immer du es brauchst. Und 
zwar ohne Rücksicht auf Verluste, indem du einfach ADCW ausliest.

Oder willst du, dass der ADC im Standby ist und du, wenn du einen Wert 
vom ADC brauchst, den ADC dazu veranlasst und dann auf das Ergebnis 
wartest.


Das ist deine Grundsatzentscheidung.
Beides zusammen geht nicht.

Entweder der ADC läuft Free Running, dann nimmst du einfach den Wert aus 
ADCW. Das ist immer der zuletzt ermittelte. Dazu muss auch nicht auf 
irgendwas gewartet werden. Wie denn auch? Der ADC buddelt ja die ganze 
Zeit, der kann dir also nicht sagen "Juhu! Fertig! Da ist dein 
Ergebnis". Würde auch keinen Sinn machen, denn in dem Moment, in dem er 
das von sich gibt, muss gleich darauf kommen "Moment, ich bin bei der 
Arbeit"

(und genau diese Aussage macht das ADSC Flag:
* Ich tu nichts mehr, das Ergebnis steht im ADCW
* Holla, heut gehts rund, Bin bei der Arbeit einen Wert zu wandeln

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

In deiner Anwendung ist der Free-Running Modus überhaupt nicht 
notwendig. Wie in den meisten anderen Fällen auch nicht. Wenn du einen 
Wert vom ADC willst, dann startest du mittels ADSC den ADC, der arbeitet 
und wenn er fertig ist, dann meldet er das und du kannst dir das 
Ergebnis holen.

In der Zeit, in der du dieses Ergebnis aufbereitest, dreht der ADC 
einfach Däumchen. Es gibt keinen Grund, warum der in dieser Zeit weiter 
Werte wandeln soll.

: Bearbeitet durch User
von innerand i. (innerand)


Lesenswert?

> Mhh, ich muss doch trotzdem die 13 Umwandlungstakt abwarten, denn sonst
> erhalte ich doch Müll oder nicht?

Sie müssten vor allem mal das Manual lesen...

: Bearbeitet durch User
von innerand i. (innerand)


Lesenswert?

Karl Heinz schrieb:

> Der ADC buddelt ja die ganze
> Zeit, der kann dir also nicht sagen "Juhu! Fertig! Da ist dein
> Ergebnis".

Naja, einen Interrupt nach jeder abgeschlossenen Wandlung kann man schon 
haben.

von Karl H. (kbuchegg)


Lesenswert?

innerand innerand schrieb:
>> Mhh, ich muss doch trotzdem die 13 Umwandlungstakt abwarten, denn sonst
>> erhalte ich doch Müll oder nicht?
>
> Sie müssten vor allem mal das Manual lesen...

... Oder wenigstens die Tutorialsroutinen so benutzen, wie sie sind und 
nur an den gekennzeichneten Stellen die Anpassung auf die konkrete 
Situation (Referenzspannung) vornehmen.

von Karl H. (kbuchegg)


Lesenswert?

innerand innerand schrieb:
> Karl Heinz schrieb:
>
>> Der ADC buddelt ja die ganze
>> Zeit, der kann dir also nicht sagen "Juhu! Fertig! Da ist dein
>> Ergebnis".
>
> Naja, einen Interrupt nach jeder abgeschlossenen Wandlung kann man schon
> haben.

Um Gottes Willen.
Er ist nicht in der Lage, im Tutorial bzw. Datenblatt die Bedeutung von 
ADATE rauszulesen und du willst ihn in Interrupts jagen?
Mal den Teufel nicht an die Wand.

von batty m. (battyman)


Lesenswert?

Sorry das ich jetzt wohl eine Flasche Frage gestellt habe. Ich 
beschäftige mich intensiv mit den Tutorials und auch meinem Datenblatt. 
Meine Programmiervorkenntnisse beschränken sich auf Basic und das auch 
nur eingeschränkt auf die Office-Software.
Mir ist einfach einiges nicht ganz klar bzw. bewusst, denn woher auch? 
Hab ja die Vorkenntnisse nicht und deswegen beschäftige ich mich damit 
um es zu lernen und auch zu verstehen. Lesen und die Wiedergabe des 
Inhalts stellt für mich n Problem dar, dafür kann ich einfach besser 
rechnen.

Tut jetzt nicht zur Sache. Meine 3 Fragen habe ich erst nach intensiver 
Recherche (Such-Funktion auf Analogien) und mehrmaligen lesen und vor- 
zurück blättern der Tutorials/Datenblätter zum eigenen Verständnis 
gestellt.
Mein Verständnis war eben nun, das ich auf die vollständige Umwandlung 
warten muss, damit ich überhaupt einen vernünftigen Wert auslesen kann.
Und ich wollt auch den Controllereingang nicht zerblasen nur weil ich 
kein Eingang ins Register geschrieben habe oder meine Spannung an den 
völlig falschen Port hänge. Und wenn der Compiler mir sagt das ich bei 
der Übergabe was falsch mache, da ich eine Funktion einer anderen so 
nicht übergeben kann, dann stell ich mir einfach mal solche fragen. Auch 
aus Fehlern kann man lernen und das Gelernte bleibt dabei viel Öfter und 
länger hängen, nur den Controller wollte ich eben nicht zerstören.

Wenn es nun zwei Wege gibt würde ich gerne beide erlernen und für mich 
ein Beispielprogramm(e) haben, um immer wieder darauf zurückzugreifen 
und/oder Zum Verständnis der Unterschiede durch sehen zu können.

Und auch das mit dem Interrupt ist ne geile Sache, denn ich will mit der 
delay-Funktion nicht ständig mein Programm anhalten. Dachte nur daran, 
dass ich das Interrupt zum Aktualisieren der ADC-Werte und der Ausgabe 
auf dem LCD als Zeit-Zählfunktion dazu baue. Jedoch wär es dann im Free 
Running mit Interrupt immer schneller aktueller. Wird das Erfassen und 
die Ausgabe eines solchen analogen Wertes auch so praktisch gehandhabt, 
oder doch eher über ner zeitlichen Abfrage?

Ein Dank für euer Verständnis. Und n echtes sorry für triviale Fragen.

von Karl H. (kbuchegg)


Lesenswert?

batty man schrieb:

> Mein Verständnis war eben nun, das ich auf die vollständige Umwandlung
> warten muss, damit ich überhaupt einen vernünftigen Wert auslesen kann.

Ja, das ist ja auch ok.
Nur darfst du dazu eben ADATE nicht setzen. Das machen auch die 
Tutorial-Routinen nicht.

> Und ich wollt auch den Controllereingang nicht zerblasen

Keine Sorge.
Die einzige Chance, deinen Controllereingang zu 'zerblasen' ist es, wenn 
du da 230V ohne sonstige Sicherung reinknallst. Mit einem Poti, welches 
du als Spannungsteiler zwischen 5V und GND geschaltet hast, kannst du 
nichts ruinieren. Wenn du nicht mehr als 5V in der ganzen Schaltung 
hast, dann kann da auch nirgends Überspannung herkommen.

Das schlimmste was dir passieren kann ist, dass die Werte nicht stimmen. 
Aber zerstören kannst du da nichts. Oder nicht viel.

> Wenn es nun zwei Wege gibt würde ich gerne beide erlernen und für mich
> ein Beispielprogramm(e) haben, um immer wieder darauf zurückzugreifen
> und/oder Zum Verständnis der Unterschiede durch sehen zu können.

Du kommst mit den Routinen aus dem AVR-GCC-Tutorial (nach ADC suchen!) 
sehr, sehr weit. Wenn du je in die Verlegenheit kommst, mal den Free 
Running Mode wirklich zu brauchen, weil es gar nicht anders geht, dann 
bist du schon Halbprofi und weißt aus der Erfahrung heraus, wie das 
Datenblatt dazu zulesen ist, wie es in diesem Punkt zu interpretieren 
ist und was zu tun ist.

Fazit: Für dich als Anfänger sind die Tut-Routinen perfekt. Die Quelle 
der Referenspannung einstellen und abgesehen davon kannst du die 1:1 so 
nehmen wie sie sind.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

>  Jedoch wär es dann im Free Running mit Interrupt immer schneller aktueller.

Nur um das klar zu stellen.
Wir reden hier beim ADC von Zeiten im Bereich von µs (also Millionstel 
Sekunden). Alles was schneller als ein par Zehntel-Sekunden ist, kannst 
du als Mensch überhaupt nicht mehr erfassen! Das ist viel zu schnell für 
dich. Nämlich richtig viel zu schnell! Da liegen Größenordnungen 
dazwischen.

Also mach dir deswegen keinen Kopf. Für deinen µC ist alles was du als 
Mensch tust, Super-Super-Super-Zeitlupe. Und das beinhaltet auch das 
Ablesen eines Wertes von einer Anzeige. Gerade das ist um Welten 
langsamer, als der µC selbst bei ungünstigster Programmierung die Werte 
liefern kann. Ganz im Gegenteil, du wirst den µC sowieso noch künstlich 
bremsen müssen, weil kein Mensch auf Dauer das Geflackere an der Anzeige 
aushält.

: Bearbeitet durch User
von batty m. (battyman)


Lesenswert?

Einen wunderschönen guten Abend allerseits. :-)

Endlich bin ich mal wieder weiter gekommen mit der AD-Wandlung. Leider 
habe ich trotzdem immer noch leichte Verständnisprobleme.
Also ich löse mit 2^10 Bit  den analogen Eingang auf. Als 
Referenzspannung benutze ich die internen 2,56V. An meinen Port F habe 
ich ein 10pol Flachkabel dran, an dem ich an der ersten Litze PLUS und 
an der neunten Minus (GND) angeschlossen habe (Labornetzteil zur 
manuellen veränderung dran!).
Ich starte die Umwandlung, der µC rödelt zu meiner Zufriedenheit los und 
gibt mir einen digitalen Wert zurück. SUPER!!!
Den digitalen Wert übergebe ich anschließend auf die itoa() Funktion und 
lass einen 5stelligen String erzeugen, der dann an das LCD gesandt wird. 
Klappt auch soweit alles. Freut mich ja tierisch :-D

Fragen:
1.) Warum ist bei einer analogen Nullstellung des Labornetzteils 
trotzdem immer eine digitale Wertrückgabe von gut 200 vorhanden? Müsste 
doch denn auch gegen Null gehen. Komisch, aber kommt vllt. doch noch was 
vom Netzteil. Wenn ich es komplett abschalte fällt der digitale Wert 
erst auf ca 100 ab und dann mit gewisser Zeit immer etwas kleiner 
werdend??? -> Entladekurve eines Kondensators auf dem Board, welche ich 
nicht bedenke oder wat soll dit sein?

2.) MUSS oder KANN ich einen kleinen Kondensator bei der Verwendung der 
internen Referensp. zw. dem AREF und GND PIN klemmen?

3.) Wenn ich versuche meine ADCW vor der Umwandlung in ein String in 
eine Spannung (Spannungswert ohne Kommas) zurück zu rechen, kommt nur 
noch unfug am Display an. Also völlig unsinnige Werte die nicht mit 
digitalen noch analogen Werten was ähnlich hätten:
Als Deklaration habe ich uint32_t benutzt.

Für weitere hilfreiche Unterstützung dank ich abermals und hoffe das 
diesmla die Fragen nicht wieder ganz Idiota waren -.-

THX

von Karl H. (kbuchegg)


Lesenswert?

batty man schrieb:

> Also ich löse mit 2^10 Bit  den analogen Eingang auf. Als
> Referenzspannung benutze ich die internen 2,56V.

gut

> An meinen Port F habe
> ich ein 10pol Flachkabel dran, an dem ich an der ersten Litze PLUS und
> an der neunten Minus (GND) angeschlossen habe (Labornetzteil zur
> manuellen veränderung dran!).

Das sagt jetzt keinem was, weil ja niemand weiß wohin die neunte bzw. 
die erste Litze auf deinem AVR führen.

> Fragen:
> 1.) Warum ist bei einer analogen Nullstellung des Labornetzteils
> trotzdem immer eine digitale Wertrückgabe von gut 200 vorhanden?

Mal rechnen
1
    1024    .... 2.56
2
     200    ....  x
3
   -------------------
4
         200 * 2.56
5
    x = ------------ = 0.5
6
            1024

d.h. der AVR behauptet, an seinem Eingang liegen 0.5V an. Schnapp dir 
ein Multimeter und miss nach.

> Müsste
> doch denn auch gegen Null gehen.

Ja. Wenn dein Netzteil bei einer Einstellung von 0V auch wirklich 0V am 
Ausgang liefert.

> Komisch, aber kommt vllt. doch noch was
> vom Netzteil.

Ein Voltmeter würde dir das sagen.

> Wenn ich es komplett abschalte fällt der digitale Wert
> erst auf ca 100 ab und dann mit gewisser Zeit immer etwas kleiner
> werdend??? -> Entladekurve eines Kondensators auf dem Board,

Das könnte sein.
Trenn mal schlagartig das Kabel auf. Fällt die Spannung dann in einem 
Rutsch auf 0?

Wenn ja, dann ist das wohl ein Kondensator im Netzteil, der noch 
entladen wird.

> 2.) MUSS oder KANN ich einen kleinen Kondensator bei der Verwendung der
> internen Referensp. zw. dem AREF und GND PIN klemmen?

Ja.

> 3.) Wenn ich versuche meine ADCW vor der Umwandlung in ein String in
> eine Spannung (Spannungswert ohne Kommas) zurück zu rechen, kommt nur
> noch unfug am Display an. Also völlig unsinnige Werte die nicht mit
> digitalen noch analogen Werten was ähnlich hätten:
>

Rechne mal ADCW * 26500 im taschenrechner aus. Wenn dir da ein 
Zwischenergebnis größer als 65535 rauskommt, dann hast du einen 
Überlauf.

Alle Ergebnisse, auch Zwischenergebnisse(!) müssen bei einer unsigned 
int Rechnung im Bereich kleiner 65535 (also das was mit 16 Bit maximal 
geht) sein. Ansonsten hast du Overflow und die Ergebnisse stimmen nicht 
mehr.

> Als Deklaration habe ich uint32_t benutzt.

Wofür?
Für 'Spannung'?

Das ist uninteressant. ADCW ist ein uint16_t, 26500 ist ein int. Damit 
ist das eine 16 Bit Multiplikation. Wenn du das Ergebnis der kompletten 
rechten Seite nach der Berechnung auf 32 Bit aufbläst, dann ist das 
schön, interessiert aber den Compiler nicht, wenn er festlegt, mit 
welchen Operationen und Bitbreiten ADCW*25600/1024 zu rechnen ist.

: Bearbeitet durch User
von batty m. (battyman)


Lesenswert?

Karl Heinz schrieb:
> batty man schrieb:
>> An meinen Port F habe
>> ich ein 10pol Flachkabel dran, an dem ich an der ersten Litze PLUS und
>> an der neunten Minus (GND) angeschlossen habe (Labornetzteil zur
>> manuellen veränderung dran!).
>
> Das sagt jetzt keinem was, weil ja niemand weiß wohin die neunte bzw.
> die erste Litze auf deinem AVR führen.
Die erste Litze ist PF0 und damit der AD Kanal 0 und die neunte ist der 
GND-Pin des µCs

>> Fragen:
>> 1.) Warum ist bei einer analogen Nullstellung des Labornetzteils
>> trotzdem immer eine digitale Wertrückgabe von gut 200 vorhanden?

>> Wenn ich es komplett abschalte fällt der digitale Wert
>> erst auf ca 100 ab und dann mit gewisser Zeit immer etwas kleiner
>> werdend??? -> Entladekurve eines Kondensators auf dem Board,
>
> Das könnte sein.
> Trenn mal schlagartig das Kabel auf. Fällt die Spannung dann in einem
> Rutsch auf 0?
>
> Wenn ja, dann ist das wohl ein Kondensator im Netzteil, der noch
> entladen wird.
>
Ähm, ohne i-welche Anschlüsse am AD-Kanal kommt ein 800er Digitalwert 
raus! Gleicher Wert bei der Benutzung mit unbelasteteten Litzen.
Nun habe ich die Krokodilklemmen an den Litzen, ohne Kontakt zum 
Netzteil. Jetzt schwankt schon mein Wert zwischen 100 und 1023 immer 
hoch und runter. In den Grenzen gleichbleibend schwankend.
Kontaktiere ich mein Plus-Kanal vom Netzteil mit dem AD-Kanal 0 fällt 
und stabilisiert sich der Wert auf ca. 60-70. In dem Augenblick in dem 
ich den GND-µC-Pin mit dem Minus-Kanal Netzteil verbinde fällt der Wert 
nochmal auf 15-20.  ??????
Einschalten des Netzteils liefert keine Veränderung des Wertes.
Freigabe der Netzteilspannung und der Wert rauscht auf gut 200 hoch. 0,4 
bis 0,5 V gehen dabei raus. Das wäre dann zum ersten mal ein adäquater 
Wert zw. A/D

>> 2.) MUSS oder KANN ich einen kleinen Kondensator bei der Verwendung der
>> internen Referensp. zw. dem AREF und GND PIN klemmen?
>
> Ja.
Ja - Muss? oder
Ja - Kann?
Bei kann ist es nicht wichtig und sollte nur geringe Schwankungen zur 
Folge haben. Bei MUSS kann das für meine Hardwareseite ein Einfluss 
haben und ich muss diesen noch dazu Schalten.

>> 3.) Wenn ich versuche meine ADCW vor der Umwandlung in ein String in
>> eine Spannung (Spannungswert ohne Kommas) zurück zu rechen, kommt nur
>> noch unfug am Display an. Also völlig unsinnige Werte die nicht mit
>> digitalen noch analogen Werten was ähnlich hätten:
>>
>
> Rechne mal ADCW * 26500 im taschenrechner aus. Wenn dir da ein
> Zwischenergebnis größer als 65535 rauskommt, dann hast du einen
> Überlauf.
Bei der Verwendung von 25600 kann der Maximalwert auch nur <25600 sein, 
denn der Maximal-AD-Wert wäre ja auch nur 1023 und damit Faktor knapp <1

Leider ändert sich, bei der Verwendung der Formel, der ausgegebene Wert 
0-50 von allein schwankend und hat keine Änderung zur die anliegenden 
Spannung. Ohne Formelbenutzung habe ich zumindes zw. 200 und 1023 
logische D-Werte zur anliegenden Spannung


1.) und 2.) sind jedoch vorerst von Bedeutung, denn erst wenn das 
stimmig ist kann ich mir um 3.) verstärkt Gedanken machen und meine 
Funktionen nochmals überprüfen.

Danke Schön für die Unterstützung.

von batty m. (battyman)


Lesenswert?

Zu den schwankenden Zufallswerten hab ich mir noch mal Gedanken zu 
gemacht. Ich habe den Verdacht, dass durch das abklemmen des Pluskabels 
vom AD-Kanal 0 dieser eben in der Luft hängt und gar kein Bezug zu i-was 
hat. Ich probier nach her mal aus, ob ich mit AD-Kanal 0 auf GND einen 
echt Nullbezug herbekomme

von Karl H. (kbuchegg)


Lesenswert?

batty man schrieb:

>> Das könnte sein.
>> Trenn mal schlagartig das Kabel auf. Fällt die Spannung dann in einem
>> Rutsch auf 0?
>>
>> Wenn ja, dann ist das wohl ein Kondensator im Netzteil, der noch
>> entladen wird.
>>
> Ähm, ohne i-welche Anschlüsse am AD-Kanal kommt ein 800er Digitalwert
> raus!

Damn. Daran hab ich jetzt nicht gedacht.
Da hast du natürlich recht. Ein nicht beschalteter Eingang hat ja nicht 
automatisch einen Spannungswert von 0.
Mein Fehler. So gehts also nicht.
Aber die Option, die Eingangsspannung mit einem Multimeter zu messen 
bleibt ja immer noch.


> Nun habe ich die Krokodilklemmen an den Litzen, ohne Kontakt zum
> Netzteil. Jetzt schwankt schon mein Wert zwischen 100 und 1023 immer
> hoch und runter. In den Grenzen gleichbleibend schwankend.
> Kontaktiere ich mein Plus-Kanal vom Netzteil mit dem AD-Kanal 0 fällt
> und stabilisiert sich der Wert auf ca. 60-70. In dem Augenblick in dem
> ich den GND-µC-Pin mit dem Minus-Kanal Netzteil verbinde fällt der Wert
> nochmal auf 15-20.  ??????

Vergiss bitte was ich da gesagt habe.
Es ist ein Trugsschluss, dass ein unbeschalteter Eingang (nein, ein 
angeklemmter Draht zählt nicht) einen Wert von 0 aufweisen würde.

> Freigabe der Netzteilspannung und der Wert rauscht auf gut 200 hoch. 0,4
> bis 0,5 V gehen dabei raus.

Mit einem externen Multimeter gemessen?

> Das wäre dann zum ersten mal ein adäquater
> Wert zw. A/D

Wenn mit einem Multimeter gemessen, dann passt es doch!

>>> 2.) MUSS oder KANN ich einen kleinen Kondensator bei der Verwendung der
>>> internen Referensp. zw. dem AREF und GND PIN klemmen?
>>
>> Ja.
> Ja - Muss? oder
> Ja - Kann?

Ja, muss/kann.
Steht doch alles in den Datenblättern bzw. Tutorien.

> Bei kann ist es nicht wichtig und sollte nur geringe Schwankungen zur
> Folge haben. Bei MUSS kann das für meine Hardwareseite ein Einfluss
> haben und ich muss diesen noch dazu Schalten.

Was ist denn der Zweck dieses Kondensators (aller Kondensatoren dieser 
Art)?

(Achtung: das ist jetzt alles anschaulich erklärt. Die Spezialisten 
bitte weghören. Mir geht es mehr darum, dass er versteht WARUM man da 
einen Kondenstor setzt und nicht welche elektrotechnischen Feinheiten da 
jetzt dahinter stecken)

Dieser Kondensator dient als eine Art Buffer, in dem Ladung gespeichert 
wird. Sinkt die Spannung etwas ab, dann schiesst der Kondensator aus 
seinem Ladungspotential zu und hält so die Spannung aufrecht. Steigt die 
Spannung, dann greift der Kondensator zu, in dem er sich weiter auflädt 
und so vom Spannungsanstieg etwas wegnimmt.
Fazit: Der Kondensator sorgt dafür, dass die Spannung stabilisiert wird. 
Wenn die Spannung abzusinken droht, dann schiebt der Kondensator nach, 
wenn die Spannung anzusteigen droht, dann nimmt der Kondensator davon 
etwas weg.
So wie die Windlade in einer Orgel: Einfach nur ein Reservoir, dass 
Veränderungen ausgleicht und so kurze Schwankungen ausgleicht)

Das ist der Zweck des Kondensators. D.h. niemand kann dir vorschreiben, 
dass du einen derartigen Kondensator setzt. Du musst aber auch dann 
damit leben, dass du unter Umständen kleine Schwankungen auf der 
Referenzspannung haben kannst, die sich dann auch (wenn sie zu einem 
ungünstigen Zeitpunkt auftreten) in deinen Messwerten niederschlagen. 
Schaden kann so ein Kondensator nie. Das einzige was ich nicht verstehe 
ist, warum sich alle Welt immer gegen derartige Blockkondensatoren 
sträubt. Die paar Cent sind wahrlich nicht die Welt und dann hast du 
erstmal für ein bischen Absicherung im Falle des Falles gesorgt.

>> Rechne mal ADCW * 26500 im taschenrechner aus. Wenn dir da ein
>> Zwischenergebnis größer als 65535 rauskommt, dann hast du einen
>> Überlauf.
> Bei der Verwendung von 25600 kann der Maximalwert auch nur <25600 sein,
> denn der Maximal-AD-Wert wäre ja auch nur 1023 und damit Faktor knapp <1

Nein.
Vom ADCW kriegst du Werte von 0 bis 1023.
D.h. der schlimmste Fall, den du haben kannst, ist
1
   ADCW * 26500
wobei ADCW den Wert 1023 hat. Also rechne mal 1023*26500. Ist das größer 
als 65535? Doch, ja. Das will ich meinen, dass das größer ist. Also hast 
du einen Überlauf. So einfach ist das. Es gilt das, was im Programmtext 
steht und nicht das was du da hineininterpretierst. Und im Programmtext 
steht eindeutig ADCW*26500.

Es gibt keinen Faktor 'knapp <1', denn der Compiler darf
1
   ADCW * 26500 / 1024
nicht eigenmächtig zu
1
   ADCW * ( 26500 / 1024 )
verändern, weil das ein anderes Ergebnis bringt. Der Compiler muss den 
Ausdruck so
1
   ( ADCW * 26500 ) / 1024
auswerten. Und da ist nun mal die Multiplikation mit 26500 vorhanden und 
wird auch zur Laufzeit ausgeführt.


FAQ: Datentypen in Operationen

: Bearbeitet durch User
von Frank D. (Firma: Spezialeinheit) (feuerstein7)


Lesenswert?

batty man schrieb:
> ADMUX = (1<<REFS1) | (1<<REFS0);            //setzt die
> Referenzspannung als intern und mit 2,56V
>   ADCSRA = (1<<ADPS2) | (1<<ADPS1);
> //Taktfrequ.-Teilungsfaktor (Prescaler Select) = 64 für f = 125 kHz
>   ADCSRA |= (1<<ADEN);                  //aktiviert den AD-Wandler
>   ADCSRA |= (1<<ADATE);                  //Bit wird für Free-Running -
> permanente Messung - gesetzt
>   ADCSRA |= (1<<ADSC);

Ich benutze kein C, aber du solltest ADCSRA in einen Rutsch beschreiben, 
und nicht gestückelt. Ich hab noch mal eine Stelle aus einem Datenblatt 
rausgesucht (vom tiny13, wollte das vom Mega nicht extra runterladen).

The ADC is enabled by setting the ADC Enable bit, ADEN in ADCSRA. 
Voltage reference and
input channel selections will not go into effect until ADEN is set.

Vieleicht macht der C Kompiler da was Sinnvolles draus, vieleicht auch 
nicht.

von batty m. (battyman)


Lesenswert?

Karl Heinz schrieb:
> batty man schrieb:
> ...
>> Freigabe der Netzteilspannung und der Wert rauscht auf gut 200 hoch. 0,4
>> bis 0,5 V gehen dabei raus.
>
> Mit einem externen Multimeter gemessen?
 Jo, gemessen und stimmt. Netzteil kann leider nicht tiefer ausgeben, 
aber tut ja zur Funktionalität nicht bei.
...
> Das einzige was ich nicht verstehe
> ist, warum sich alle Welt immer gegen derartige Blockkondensatoren
> sträubt. Die paar Cent sind wahrlich nicht die Welt und dann hast du
> erstmal für ein bischen Absicherung im Falle des Falles gesorgt.
Ach das tut nix zur Sache. Hab ich ja zur Hand. War mir nur nicht klar 
das die interne Referen noch stärkere Schwankungen hat. Alles gut.
...
> Es gilt das, was im Programmtext
> steht und nicht das was du da hineininterpretierst. Und im Programmtext
> steht eindeutig ADCW*26500.
>
> Der Compiler muss den
> Ausdruck so
>
1
>    ( ADCW * 26500 ) / 1024
2
>
> auswerten. Und da ist nun mal die Multiplikation mit 26500 vorhanden und
> wird auch zur Laufzeit ausgeführt.

Wie Schuppen von den Augen fällt. Jap, Ich denk noch nicht wie ein 
Prozessor. Ich sehe mein ADC-Wert teil den im Kopf mit 1024 hab n Faktor 
und multiplizier den dann für mich ganz allein mit 25600. Die 
mathematische Logic bleit bei der Punktrechnung ja erhalten.
ergo für den Rechner:
oder eben
1
 Spannung = ADCW * 25;

von batty m. (battyman)


Lesenswert?

Duften Sonntag an alle.

Wie schon geshrieben funzt das jetzt so wie ich es mir auch gedacht 
habe. Vielen Danke soweit.

Um die Funktionalität und Richtigkeit zu prüfen habe ich nun mit 
Messgeräten den Spannungseingang, die Ref-Sp. und den angezeigten 
LCD-Spannungswert vergleichlichen/ gemessen.
Mich hatte nämlich der Spannungsunterschied zw Ein- und Anzeigespannung 
von ca 40mV stutzig gemacht. Bei einer Ref-sp von 2,56V und der 10bit 
Auflösung wäre ja eine Schrittweise von 2,5mV gegeben. Eine Abweichung 
von 40mV wäre dann ein Fehler von größer 6% und damit viel zu viel.
Nun habe ich ja auch die Ref-sp gemessen und dabei nicht die angegeben 
2,56V sondern 2,519V heraus bekommen. Damit wäre der Fehler erklärt.

wie bekomme ich nun die Ref-spannung auf 2,56V ???
Den Kondensator habe ich mit 100nF in Benutzung. Laut Datenblatten is ne 
Schwankung normal, jedoch wär es super die wenigsten gegen die 2,54V 
herauf zu bekommen.

Danke

von batty m. (battyman)


Lesenswert?

Kann ich die Ref-spannung gar nicht mehr erhöhen?

Bleibt die so wie sie ist und ich muss mit den Fehler dann leben?

Bzw. dann eine externe Ref-spannung anlegen die genauer ist?


THX

von Karl H. (kbuchegg)


Lesenswert?

batty man schrieb:


> wie bekomme ich nun die Ref-spannung auf 2,56V ???

Gar nicht.
Die Referenzspannung ist in erster Linie eines: unabhängig von der 
Versorgungsspannung konstant.
Aber sie ist nicht exakt 2.56V!


Daher: den bei deinem IC vorliegenden Wert ausmessen (oder rechnerisch 
ermitteln) und im Programm eine entsprechende Korrektur vornehmen.

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.