AVR Atmega16 ADC falsche Messungen

OP #1634555
Lesenswert?

Hallo nochmal ;)
Ich versuche zur Zeit eine Spannung von Phototransistoren an meinem 
Atmega16 mit dem ADC auszulesen.Dazu habe ich den folgenden code 
geschrieben.
Das Problem ist, das der ADC mir wenn die Phototransistoren nicht 
angeschlossen sind schon einen Wert von 1023 ausgibt.
Den Atmega habe ich nach dieser 
(http://www.kreatives-chaos.com/images/38.png) Schaltung aufgebaut, 
allerdings ohne den reset widerstand.
Hier der Code:
1
#define F_CPU 16000000UL
2

3
#include <avr/io.h>
4
#include <util/delay.h>
5

6
//Variablen :
7
unsigned int adc_links=0;  //Spannung des linken Infrarottransistors
8
unsigned int adc_rechts=0;  //Spannung des rechten Infrarottransistors  
9
unsigned int adc_oben=0;  //Spannung des oberen Infrarottransistors
10
unsigned int adc_unten=0;   //Spannung des unteren Infrarottransistors
11
unsigned int result=0;        //Ausgabe der ReadChannel funktion
12

13
int ReadChannel(unsigned int mux)
14
{  
15
  
16
  result=0;
17
  ADMUX=mux;    //kanal waehlen 
18
  _delay_us(40);  //40 mikrosekunden warten zum einstellen des Kanals
19
  result=ADCL;
20
  result+=(ADCH<<8);  
21
  return result;
22
}
23

24
int main()
25
{
26
////////////////////////////////////////////////////////////////////////////////////////////////////
27
    //ADC///////////////////////////////////////////////////////////////////////////////////////////////
28

29
  ADCSRA|=(1<<ADEN);//ADC Enable !
30
  SFIOR=0x00;        //freilaufender Modus
31
  ADCSRA|=(1<<ADATE);//freilaufender Modus
32
  ADCSRA|=(1<<ADSC);//Messung aktivieren
33
  ADCSRA|=(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);// Vorteiler 128 -> F=125Khz -> 9615 Messungen die Sekunde
34
  ADMUX|=(1<<REFS0); //AVCC als Referenzspannung
35
  _delay_us(120);    //120 microsekunden warten zum einstellen
36
  result=ADCW; //Testdurchlauf
37

38
 while(1)
39
   {
40
    //Auslesen der ADC Kanaele:
41
    adc_links=ReadChannel(1);
42
    adc_rechts=ReadChannel(2);
43
    adc_oben=ReadChannel(3);
44
    adc_unten=ReadChannel(4);
45
    
46
///////////////////////////////////////////////TEST
47
    if(adc_links>=1023)PORTB|=(1<<PIN0);
48
    if(adc_links>925)PORTB|=(1<<PIN1);
49
    if(adc_links<820)PORTB&=~(1<<PIN0);
50
    if(adc_links<925)PORTB&=~(1<<PIN1);
51

52
////////////////////////////////////////////////////
53
        }
54
return 0;
55
}

Die Werte bei denen bei PortB etwas ausgegeben wird sind nur zum Testen 
gedacht.
Ich beschaeftige mich zum ersten Mal mit dem ADC und vermute das es sich 
um einen einfachen Anfaengerfehler handelt.
Allerdings finde ich meinen Fehler nicht, und auch die Forensuche hat 
nichts ergeben.
Vielen Dank schonmal im Voraus!
Gast #1634567
Lesenswert?

Hi

>Den Atmega habe ich nach dieser
>(http://www.kreatives-chaos.com/images/38.png) Schaltung aufgebaut,
>allerdings ohne den reset widerstand.

Da fehlt ein Kondensator (100n) von VCC nach GND).

>int ReadChannel(unsigned int mux)
>{
>  result=0;
>  ADMUX=mux;    //kanal waehlen
>  _delay_us(40);  //40 mikrosekunden warten zum einstellen des Kanals
>  result=ADCL;
>  result+=(ADCH<<8);
>  return result;
>}

An welcher Stelle startest du den ADC?

MfG Spess
OP #1635092
Lesenswert?

Den Kondensator von Vcc nach Gnd gibt es bei mir natürlich auch.
Ich dachte die Messung wird hier aktiviert:
1
  ADCSRA|=(1<<ADEN);//ADC Enable !
2
  SFIOR=0x00;        //freilaufender Modus
3
  ADCSRA|=(1<<ADATE);//freilaufender Modus
4
  ADCSRA|=(1<<ADSC);//Messung aktivieren
Mit freundlichen Grüßen!
OP #1635723
Lesenswert?

Diesmal habe ich mich so weit wie moeglich am Tutorial orientiert, und 
dadurch zu single-conversion gewechselt.
1
  uint16_t ReadChannel(uint8_t mux)
2
  {
3
    uint8_t i;
4
    uint16_t result;
5

6

7
    ADCSRA|=(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN);// Vorteiler 128 -> F=125Khz -> 9615 Messungen die Sekunde 
8
                      //ADC aktivieren
9
    ADMUX = mux; // Kanal waehlen
10
    _delay_us(40);  //40 mikrosekunden warten um Kanal einzustellen
11
    ADMUX|=(1<<REFS0); //AVCC als Referenzspannung
12

13
  ////////////////////Dummy Readout:
14
    ADCSRA |= (1<<ADSC);       // eine ADC-Wandlung
15
    while ( ADCSRA & (1<<ADSC)){}   // auf Abschluss der Konvertierung warten
16
    result = ADCW;           // ADCW auslesen
17
    result = 0;            //Dummy readout loeschen
18
  /////////////////
19

20
    ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
21
    while ( ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
22
    result=ADCL;          //ADC auslesen
23
    result+=(ADCH<<8);
24
    ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
25
    return result;
26
  }

Den Prescaler musste ich aendern, da mein Mega16 mit 16 Mhz arbeitet.
Ausserdem habe ich Avcc als Referenz eingestellt, da ich fast 5 volt 
messen muss, wozu die interne Referenzspannung meines Achtens nicht 
ausreicht.
Ich habe auch schon einen andern Mega16 ausprobiert, aber es 
funktioniert nicht so wie es soll.
Das Programm gibt mit jetzt fuer Kanal 1 1023 aus, obwohl kaum eine 
Spannung anliegt.
Mit freundlichen Gruessen.
#1635742
Lesenswert?

M. G. schrieb:
> Diesmal habe ich mich so weit wie moeglich am Tutorial orientiert, und
> dadurch zu single-conversion gewechselt.

Gut.
Der _delay_us ist zwar sinnlos, aber was solls. Er tut auch nichts

> Den Prescaler musste ich aendern, da mein Mega16 mit 16 Mhz arbeitet.

ok

> Ausserdem habe ich Avcc als Referenz eingestellt,

OK. Und an Avcc ist bei dei deinem µC auch eine Spannung angeschlossen?

> Das Programm gibt mit jetzt fuer Kanal 1 1023 aus

1023 bedeutet:
Die Spannung am Messeingang ist gleich oder größer als die eingestellte 
Referenz.
Welche Spannung misst du den an ARef?
#1635765
Lesenswert?

M. G. schrieb:
> Sieht so aus als haette ich Avcc und Aref fuer das selbe gehalten ^^
> Wie gesagt , das ist mein erstes ADC Programm.
> Ich versuch dann wohl am besten mein Glueck gleich nochmal wenn Aref
> auch beschaltet ist.

Nein!

Lies bitte das Tutorial. Dazu habe ich dir den Link gepostet.
An ARef keine Spannung anschliessen ist ok. Ganz im Gegeteil.
Aber dort kannst du nachmessen, welche Referenzspannung tatsächlich 
eingestellt und benutzt wird.

Du hast ja interne Referenzspannung benutzt, in deinem Fall AVcc. Das 
ist ja ok. Aber miss doch mal nach, ob das auch alles stimmt. Dazu hast 
du ja den ARef Ausgang, damit du dort
  * mit dem Kondensator die Spannung stabiliseren kannst
  * Die Spannung nachmessen kannst.
#1635817
Lesenswert?

Und nimm bitte die ADC_Routine aus dem Tut 1:1 so wie so dort drinnen 
ist. Einzig an den Vorteiler-Bits spielen um den höheren Vorteiler zu 
erhalten. Sonst alles so wie da drinn angegeben.

Hintergrund: Ich will mir jetzt ehrlich nicht aus dem Datenblatt 
zusammensuchen, in welcher Reihenfolge Vorteiler, Referenzspannung und 
'ADC ein' eingestellt werden müssen, damit alles klappt. Vielleicht gibt 
es da keinen Zusammenhang, vielleicht auch schon.

Was ist so schwer drann, die Routine erst mal 1:1 zu übernehmen und erst 
hinterher den Optimierstift anzusetzen?
Wie heißt es so schön: Vorzeitige Optimierung ist die Wurzel allen 
Übels.
OP #1636848
Lesenswert?

Ok, diesmal habe ich wirklich den Code aus dem Tutorial exakt 
uebernommen, bis auf den Vorteiler.
1
    uint16_t ReadChannel(uint8_t mux)
2
    {
3
      uint8_t i;
4
      uint16_t result;
5
      ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // Frequenzvorteiler
6
      // setzen auf 128 (1) und ADC aktivieren (1)
7
      ADMUX = mux; // Kanal waehlen
8
      ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
9
      /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
10
      also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
11
      ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
12
      while ( ADCSRA & (1<<ADSC) ) {
13
      ; // auf Abschluss der Konvertierung warten
14
      }
15
      result = ADCW; // ADCW muss einmal gelesen werden,
16
      // sonst wird Ergebnis der nächsten Wandlung
17
      // nicht übernommen.
18
      /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
19
      result = 0;
20
      for( i=0; i<4; i++ )
21
      {
22
      ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
23
      while ( ADCSRA & (1<<ADSC) ) {
24
      ; // auf Abschluss der Konvertierung warten
25
      }
26
      result += ADCW; // Wandlungsergebnisse aufaddieren
27
      }
28
      ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
29
      result /= 4; // Summe durch vier teilen = arithm. Mittelwert
30
      return result;
31
    }

Die Messspannung betraegt im Moment noch etwa 0,9 Volt. Aber selbst wenn 
ich die Fototransistoren , die die 0,9 Volt durchlassen nicht 
anschliesse, geben mir alle vier Kanaele 1023 aus.
#1636879
Lesenswert?

Hast du eine Möglichkeit, dir die Zahlenwerte genau anzusehen?
Ein LCD, UART oder vielleicht 8 LED am PortB auf die man den ADC Wert 
direkt ausgeben kann?

(Und noch einmal abspecken: Nimm nur einen Kanal und häng statt dem 
Transistor einen als Spannungsteiler verschaltetetes Poti drann, damit 
du die Messspannung gezielt einstellen kannst)

Mit LED zb so
(Wo stellst du eigentlich bei deinem Programm den Port B auf Ausgang?)
1
int main()
2
{
3
  unsigned int adc_links;
4

5
  DDRB = 0xFF;
6
  PORTB = 0x00;
7

8
  while( 1 ) {
9
    adc_links = ReadChannel(1);
10
    PORTB = adc_links / 4;     // 0 .. 1024; / 4 damit es in 8 Bit passt
11
  }
12
}

Und dann am Poti drehen.
Deine LED müssen sich verändern
Gast #1637007
Lesenswert?

ADC Initialisierung hat in ReadChanel Funktion nicht verloren.
Eine ADCinit Funktion wo Prescaler und Referenzspannung  initialisiert 
sind und ADC aktiviert ist, ist viel sinnvoller.
Außerdem braucht du den ADC nicht immer wieder deaktivieren.
Messen möchtest du ständig, oder?
Beispiel:
1
void ADCInit(void)
2
{
3
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // Frequenzvorteiler
4
// setzen auf 128 (1) und ADC aktivieren (1)
5
ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
6

7
}
8

9

10
uint16_t ReadChannel(uint8_t mux)
11
{
12
 ADMUX &=~(1<<MUX0)|(1<<MUX1)|(1<<MUX2)|(1<<MUX3)|(1<<MUX4)); // nur MUX0 bis MUX4 löschen, REFS0 und REFS1 bleibt unberührt!
13
 ADMUX |= mux; // Kanal waehlen
14
 ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
15
      while ( ADCSRA & (1<<ADSC) ) {
16
      ; // auf Abschluss der Konvertierung warten
17
      }
18
      result = ADCW; 
19
}
20

21
int main()
22
{
23
  unsigned int adc_links;
24

25
  DDRB = 0xFF;
26
  PORTB = 0x00;
27
  DDRA = 0x00; // ADC-Pins als Eingang konfigurieren!
28
  PORTB = 0x00; // Ohne Pull-Ups!
29
  ADCInit();
30

31
  while( 1 ) {
32

33
    adc_links = ReadChannel(1);
34
    PORTB = adc_links / 4;     // 0 .. 1024; / 4 damit es in 8 Bit passt
35
  }
36
}
OP #1637102
Lesenswert?

Ich habe zwar gerade keinen solchen Aufbau da (und auch kein Display) , 
aber am Wochenende werd ich mir sowas mal bauen.
Port B war zwar anscheinend nicht als Ausgang eingestellt, aber 
geleuchtet haben die LED's trotzdem ^^
Ich hab den Port jetzt eingestellt und der einzige Unterschied ist die 
Helligkeit der LED's
Koennte es sein das sich der ADC mit dem PWM in die quere kommt?
Ich versuche naemlich zwei Servos mit den Werten aus dem ADC zu steuern.
Mit freundlichen Gruessen
#1637108
Lesenswert?

M. G. schrieb:
> Ich habe zwar gerade keinen solchen Aufbau da (und auch kein Display) ,
> aber am Wochenende werd ich mir sowas mal bauen.
> Port B war zwar anscheinend nicht als Ausgang eingestellt, aber
> geleuchtet haben die LED's trotzdem ^^
> Ich hab den Port jetzt eingestellt und der einzige Unterschied ist die
> Helligkeit der LED's

Klar.
Du hast am Port, der als Eingang geschaltet ist, die Pullups 
eingeschaltet. Und über diese Pullups wurden dann die LED versorgt.

> Koennte es sein das sich der ADC mit dem PWM in die quere kommt?

Wo kommt da jetzt plötzlich eine PWM her?

> Ich versuche naemlich zwei Servos mit den Werten aus dem ADC zu steuern.

Hör mal.
Ich spiel mich da jetzt nicht stundenlang, nur damit ich überlege, 
welche Fehler in Code sein könnten, den ich nicht sehen kann.

Ist das der Code den du laufen lässt, oder ist er es nicht?
Woher weißt du, dass der ADC immer 1023 liefert?
OP #1638446
Lesenswert?

Tut mir leid , da die PWM ohne Probleme funktioniert dachte ich es waere 
nicht wichtig fuer mein Problem.
Im Anhang befindet sich der komplette Code den ich momentan zum Laufen 
bringen will, allerdings habe ich auch folgenden Code ausprobiert.
Hier habe ich wirklich NUR die ADC Funktion kompiliert , mit dem selben 
Ergebnis. Demnach muss der Fehler am ADC liegen.
Das der ADC 1023 ausgibt habe ich durch Annaeherungen erreicht.
Beim ausfuehren des folgenden Codes leuchten beide LED's die an PB0 und 
PB1 sind, auch wenn nichts an den entsprechenden ADC kanal angeschlossen 
ist.

1
#define F_CPU 16000000UL
2

3
#include <avr/io.h>
4
#include <util/delay.h>
5

6
//Variablen :
7
uint16_t adc_links=0;  //Spannung des linken Infrarottransistors
8
uint16_t adc_rechts=0;  //Spannung des rechten Infrarottransistors  
9
uint16_t adc_oben=0;  //Spannung des oberen Infrarottransistors
10
uint16_t adc_unten=0;   //Spannung des unteren Infrarottransistors
11

12

13

14

15

16
uint16_t ReadChannel(uint8_t mux)
17
    {
18
      uint8_t i;
19
      uint16_t result=0;
20
      ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // Frequenzvorteiler
21
      // setzen auf 128 (1) und ADC aktivieren (1)
22
      ADMUX = mux; // Kanal waehlen
23
      ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
24
      /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
25
      also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
26
      ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
27
      while ( ADCSRA & (1<<ADSC) ) {
28
      ; // auf Abschluss der Konvertierung warten
29
      }
30
      result = ADCW; // ADCW muss einmal gelesen werden,
31
      // sonst wird Ergebnis der nächsten Wandlung
32
      // nicht übernommen.
33
      /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
34
      result = 0;
35
      for( i=0; i<4; i++ )
36
      {
37
      ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
38
      while ( ADCSRA & (1<<ADSC) ) {
39
      ; // auf Abschluss der Konvertierung warten
40
      }
41
      result += ADCW; // Wandlungsergebnisse aufaddieren
42
      }
43
      ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
44
      result /= 4; // Summe durch vier teilen = arithm. Mittelwert
45
      return result;
46
    }
47

48
int main()
49
{
50

51
    
52
    DDRA=0x00;
53
    DDRB=0xff;
54
    while(1)
55
   {
56
    //Auslesen der ADC Kanaele:
57
    adc_links=0;
58
    
59
    adc_links=ReadChannel(0);
60
    _delay_us(120);
61
    
62
    
63
///////////////////////////////////////////////TEST
64
    if(adc_links==1023)PORTB|=(1<<PIN0);
65
    if(adc_links!=1023)PORTB&=~(1<<PIN0);
66
    
67

68
////////////////////////////////////////////////////
69
  }
70

71
}
Angehängte Dateien:
#1638473
Lesenswert?

M. G. schrieb:

> Das der ADC 1023 ausgibt habe ich durch Annaeherungen erreicht.
> Beim ausfuehren des folgenden Codes leuchten beide LED's die an PB0 und
> PB1 sind,

Beide?

Die an PB1 schaltest du nie auf 1.
D.h. deine LED leuchten, wenn der Ausgangspin auf 0 steht.

Den Ausgangspin für PB0 setzt du aber dann auf 0, wenn der ADC einen 
Wert ungleich 1023 liefert. Und damit ist doch alles in Ordnung.
Du hast einfach nur die Bedeutung deiner Kontrolleds fehlinterpretiert.

Wenn der ADC einen Wert von 1023 liefert, dann geht die LED aus und 
nicht ein!

Leg mal +5V an den ADC Eingang (ändere im Programm noch die 1023 auf 
1020, damit sich kleine Abweichungen nicht auswirken) und du wirst 
sehen, dass die LED dann ausgeht.

Und mach die Abfrage besser so
1
    if( adc_links > 1020 )
2
      PORTB |= (1<<PIN0);
3
    else
4
      PORTB &= ~(1<<PIN0);
dann hast du den Grenzwert nur an einer Stelle im Programm und musst 
nicht aufpassen, dass 2 if auf den selben Wert prüfen.
AUch solltest du mit == sehr vorsichtig sein. Es ist völlig normal, dass 
der ADC Wert immer ein klein wenig schwankt. Und damit ist == eine 
schlechte Wahl.
#1638493
Lesenswert?

M. G. schrieb:
> Die LED's sind mit dem positiven Fuss direkt an den Amega angeschlossen,
> der negative geht ueber einen widerstand zum negativen Anschluss der
> Spannungsquelle (Spannungsregulator).

Hmm.
Das ist schlecht.
Jetzt weiß ich auch nicht mehr weiter.
Die ADC Routine aus dem Tut ist getestet und in Ordnung.
Das einzige was mir jetzt noch einfällt ist der Frequenzvorteiler. Den 
hab ich nicht nachgerechnet, ob du damit im erlaubten Bereich bist.
OP #1638506
Lesenswert?

Laut Tutorial benoetigt der ADC eine Frequenz zwischen 50 und 200 kHz,
also 50000 und 200000 Hz.
Mein Atmega arbeitet mit 16Mhz also 16000000 Hz.
16000000/50000  = 320
16000000/200000 = 80
Also ein Prescaler zwischen 80 und 320.
Das Einzige was da in Frage kommt ist 128 also die Bits ADPS2, ADPS1 und 
ADPS0.
Kommt das hin ?
OP #1638521
Lesenswert?

Mit dem Code von gestern hatte ich ja eine normale Referenzspannung, als 
ich gerade eben nochmal nachgemessen habe nicht mehr.
Jetzt liegt auf Aref keine Spannung mehr.
Ausserdem gibt mein Spannungsregulator nur noch 4,86 Volt her ...
Ich werd mal Versuchen diesen zu wechseln.
OP #1639520
Lesenswert?

Ok, der ADC scheint wirklich zu funktionieren.
An Aref liegt nun entweder 2,5 Volt oder 5 volt an, je nachdem ob die 
interne Referenzspannung oder Avcc als Referenzspannung eingestellt ist.
Wenn die Sensoren (Phototransistoren) nicht an den Atmega angeschlossen 
sind, dann bleibt die LED, beim Ausfuehren des oberen Codes , aus.
Wenn ich den Phototransistor anschliesse faengt die LED an wild zu 
blinken, als wuerde sie ein PWM Signal ausgeben.
Woran koennte das liegen?
Es scheint als blinkt die LED langsamer wenn eine hoehere Spannung am 
Phototransistor anliegt.
#1639522
Lesenswert?

es wurde ja schon gesagt das der ADC Wert schwank, 5V mit 10bit 
aufgelöst sind knapp 5mV Genauigkeit.

Du kannst die Wandlerfrequenz verringern, Mittelwerte aus mehreren 
Messungen verwenden oder halt die Schaltschwelle anderst 
programmieren.Dann wirken sich die Schwankungen der ADC Messung bzw. 
deines zugeführten Signals nicht so stark aus.

z.B.
Wenn Wert 1 > 1019 und Wert 2 >1019 prüfe auf Differenz...
Wert 1 =1022 und Wert 2 =1024; Differenz < 5 also LED nicht einschalten
Wert 1 =1018 und Wert 2 =1024; Differenz > 5 also LED einschalten.
Im Bereich über 1019 wird also nur auf eine Wertänderung > 5 bzw. >25mV 
reagiert.

Probiere es mal wie folgt. Poti an ADC und 10 LEDs an an 2 Port, nach 
der Wandlung gibts du das ADCL Register an Port 2 und ADCH Register an 
Port 1 aus und siehst wie die letzen Bits wackeln jetzt kann du deine 
Glättungsroutine verfeinern.
OP #1639599
Lesenswert?

Wie gesagt, das mit dem Poti werde ich wohl morgen oder uebermorgen mal 
probieren.
Allerdings ist der ADC im Moment komischer Weise sehr sensibel.
Wenn ich das Kabel das zum ADC pin fuehrt nur beruehre , leuchtet die 
LED.
Und das auch wenn keine Spannung auf dem Kabel ist, und das Kabel eine 
Isolierung hat. Also reagiert der ADC auf wenige millivolt, obwohl die 
LED erst bei 5 Volt leuchten sollte, oder?

Ich habe gerade Aref nochmal nachgemessen, und die Spannung an Aref ist 
jetzt -5 Volt , obwohl ich AVCC als Referenz eingestellt habe, wo + 5 
Volt anliegen.
Ist das normal?
Wenn nicht dann liegt da warscheinlich das Problem.
#1639614
Lesenswert?

M. G. schrieb:
> Wie gesagt, das mit dem Poti werde ich wohl morgen oder uebermorgen mal
> probieren.

Solltest du unbedingt.
Und su solltest dir auch eine Möglichkeit schaffen, wie du den 
Zahlenwert direkt sichtbar machen kannst. 8 LED, LCD, UART
Auf Dauer ist nämlich dieses 1 Led schaltet bei einem Grenzwert ziemlich 
mühsam um daraus im Umkehrschluss den ADC Wert zu erraten

> Allerdings ist der ADC im Moment komischer Weise sehr sensibel.
> Wenn ich das Kabel das zum ADC pin fuehrt nur beruehre , leuchtet die
> LED.
> Und das auch wenn keine Spannung auf dem Kabel ist, und das Kabel eine
> Isolierung hat. Also reagiert der ADC auf wenige millivolt, obwohl die
> LED erst bei 5 Volt leuchten sollte, oder?

Wenn 5V in 1024 Stufen aufgelöst werden, dann hat jede Stufe 5/1024 V. 
Das ist etwas weniger als 5mV. Und 5mV sind nicht viel.

> Ich habe gerade Aref nochmal nachgemessen, und die Spannung an Aref ist
> jetzt -5 Volt , obwohl ich AVCC als Referenz eingestellt habe, wo + 5
> Volt anliegen.
> Ist das normal?

Du hast dein Voltmeter falsch rum angeschlossen
OP #1639624
Lesenswert?

Ich bin mir ziemlich Sicher , ich habe extra nochmal nachgemessen.
Wenn ich das Kabel der Positiven Buchse des Voltmeters(V) an Aref halte, 
und das andere Kabel (COM) an GND, wird keine Spannung gemessen.
Wenn ich V allerdings an +5Volt halte und das andere Kabel(COM) an Aref, 
messe ich 5 Volt.
Gast #1639652
Lesenswert?

Miss mit einem Oszi mal die Referenz-Spannung. In einem Fall mußte
ein Kananl mit Uref = AVcc, ein anderer mit Uref = 1,2V (interne Ref)
arbeiten. Umschalten von "kleiner" nach "großer" Uref problemlos,
1..2 ms warten reichte locker. Beim Umschalten von Uref=AVcc nach 
interner
Ref. mehr als 10ms...20ms! Sehr interessante Messergebnisse in dieser 
Zeit!

Schau auch mal dieses "Eck" an.
#1639667
Lesenswert?

Wie bitte soll sich der Mega intern eine Referenzspannung von -5V 
generieren?
Das kann er nicht. Er hat die dazu nötige Ladungspumpe nicht mit an 
Bord. Physik lässt sich nicht überlisten.

> Wenn ich das Kabel der Positiven Buchse des Voltmeters(V) an Aref
> halte, und das andere Kabel (COM) an GND, wird keine Spannung
> gemessen.

Also 0V

> Wenn ich V allerdings an +5Volt halte und das andere Kabel(COM)
> an Aref, messe ich 5 Volt.

d.h. du hast von Aref zu +5V eine Spannungsdifferenz von 5V.
5 - 5 ist 0. Dein Aref ist 0V. In Übereinstimmung zur ersten Messung
#1639685
Lesenswert?

> Wenn ich das Kabel das zum ADC pin fuehrt nur beruehre ,
> leuchtet die LED.
> Und das auch wenn keine Spannung auf dem Kabel ist, und das
> Kabel eine Isolierung hat.

Ein Kabel, dessen Ende frei in der Luft hängt wirkt wie eine Antenne. 
Rund um uns schwirren jede Menge elektromagnetische Wellen durch die 
Luft, die in einer Antenne eine Spannung induzieren. Eine noch viel 
bessere Antenne ist aber der menschliche Körper. Du, als Person, fängst 
die 50Hz der ganzen 230V Leitungen rund um dich auf und wenn du das 
Kabel berührst, wird diese induzierte Spannung auf das Kabel 
weitergegeben. Und der ADC misst das dann.
Wenn du mit deinem Mega irgendwann einmal einen Frequenzzähler 
programmierst, wirst du sehen, dass das Berühren des offenen Eingangs 
ein wunderschönes 50Hz Signal liefert.
#1639692
Lesenswert?

M. G. schrieb:

> Ausserdem gibt mein Spannungsregulator nur noch 4,86 Volt her ...

Das ist schon ok.
Den 7805 kannst du ruhig nehmen, so lange die Spannung stabil ist.
Wie heißt es so schön: Wer misst, misst auch viel Mist.

Dein Messgerät wird einen kleinen Fehler haben, der 7805 wird nicht 
genau 5V haben. Du hast Übergangswiderstände. etc.

die 0.14V Abweichung können ein paar Ursachen haben, die nicht 
bedenklich sind. Und 0.14V sind in der Digitaltechnik praktisch gar 
nichts.

Wichtig ist, dass die Spannung stabil ist.

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