mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR Atmega16 ADC falsche Messungen


Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht 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:
#define F_CPU 16000000UL

#include <avr/io.h>
#include <util/delay.h>

//Variablen :
unsigned int adc_links=0;  //Spannung des linken Infrarottransistors
unsigned int adc_rechts=0;  //Spannung des rechten Infrarottransistors  
unsigned int adc_oben=0;  //Spannung des oberen Infrarottransistors
unsigned int adc_unten=0;   //Spannung des unteren Infrarottransistors
unsigned int result=0;        //Ausgabe der ReadChannel funktion

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;
}

int main()
{
////////////////////////////////////////////////////////////////////////////////////////////////////
    //ADC///////////////////////////////////////////////////////////////////////////////////////////////

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

 while(1)
   {
    //Auslesen der ADC Kanaele:
    adc_links=ReadChannel(1);
    adc_rechts=ReadChannel(2);
    adc_oben=ReadChannel(3);
    adc_unten=ReadChannel(4);
    
///////////////////////////////////////////////TEST
    if(adc_links>=1023)PORTB|=(1<<PIN0);
    if(adc_links>925)PORTB|=(1<<PIN1);
    if(adc_links<820)PORTB&=~(1<<PIN0);
    if(adc_links<925)PORTB&=~(1<<PIN1);

////////////////////////////////////////////////////
        }
return 0;
}



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!

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: M. G. (elch)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Starte deinen ersten Ausflug mit dem ADC mit der Routine im Tutorial. 
Die übernimmst du erstmal so wie sie ist. Wenn dann alles läuft, kannst 
du die immer noch verändern.

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diesmal habe ich mich so weit wie moeglich am Tutorial orientiert, und 
dadurch zu single-conversion gewechselt.
  uint16_t ReadChannel(uint8_t mux)
  {
    uint8_t i;
    uint16_t result;


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

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

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

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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut, das hat mich schon ein Bisschen verwirrt, da ich ja Avcc als 
Referenz nutze.
Wo koennte dann der Fehler liegen ?

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
An Aref liegt eine konstante Spannung von etwa 4,6 Volt an.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. G. schrieb:
> An Aref liegt eine konstante Spannung von etwa 4,6 Volt an.

OK.
Hardwaremässig sieht es dann so aus, als ob erst mal alles in Ordnung 
wäre.

Deine Messspannung ist nicht größer als ARef (hast du kontrolliert?)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, diesmal habe ich wirklich den Code aus dem Tutorial exakt 
uebernommen, bis auf den Vorteiler.
    uint16_t ReadChannel(uint8_t mux)
    {
      uint8_t i;
      uint16_t result;
      ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // Frequenzvorteiler
      // setzen auf 128 (1) und ADC aktivieren (1)
      ADMUX = mux; // Kanal waehlen
      ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
      /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
      also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
      ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
      while ( ADCSRA & (1<<ADSC) ) {
      ; // auf Abschluss der Konvertierung warten
      }
      result = ADCW; // ADCW muss einmal gelesen werden,
      // sonst wird Ergebnis der nächsten Wandlung
      // nicht übernommen.
      /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
      result = 0;
      for( i=0; i<4; i++ )
      {
      ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
      while ( ADCSRA & (1<<ADSC) ) {
      ; // auf Abschluss der Konvertierung warten
      }
      result += ADCW; // Wandlungsergebnisse aufaddieren
      }
      ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
      result /= 4; // Summe durch vier teilen = arithm. Mittelwert
      return result;
    }

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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?)
int main()
{
  unsigned int adc_links;

  DDRB = 0xFF;
  PORTB = 0x00;

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

Und dann am Poti drehen.
Deine LED müssen sich verändern

Autor: AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
void ADCInit(void)
{
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // Frequenzvorteiler
// setzen auf 128 (1) und ADC aktivieren (1)
ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen

}


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

int main()
{
  unsigned int adc_links;

  DDRB = 0xFF;
  PORTB = 0x00;
  DDRA = 0x00; // ADC-Pins als Eingang konfigurieren!
  PORTB = 0x00; // Ohne Pull-Ups!
  ADCInit();

  while( 1 ) {

    adc_links = ReadChannel(1);
    PORTB = adc_links / 4;     // 0 .. 1024; / 4 damit es in 8 Bit passt
  }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR schrieb:
> ADC Initialisierung hat in ReadChanel Funktion nicht verloren.

Lass uns erst mal mit einer getesteten Funktion abklären, ob ein 
Hardwareproblem vorliegt.

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: M. G. (elch)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

#define F_CPU 16000000UL

#include <avr/io.h>
#include <util/delay.h>

//Variablen :
uint16_t adc_links=0;  //Spannung des linken Infrarottransistors
uint16_t adc_rechts=0;  //Spannung des rechten Infrarottransistors  
uint16_t adc_oben=0;  //Spannung des oberen Infrarottransistors
uint16_t adc_unten=0;   //Spannung des unteren Infrarottransistors





uint16_t ReadChannel(uint8_t mux)
    {
      uint8_t i;
      uint16_t result=0;
      ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // Frequenzvorteiler
      // setzen auf 128 (1) und ADC aktivieren (1)
      ADMUX = mux; // Kanal waehlen
      ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
      /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
      also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
      ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
      while ( ADCSRA & (1<<ADSC) ) {
      ; // auf Abschluss der Konvertierung warten
      }
      result = ADCW; // ADCW muss einmal gelesen werden,
      // sonst wird Ergebnis der nächsten Wandlung
      // nicht übernommen.
      /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
      result = 0;
      for( i=0; i<4; i++ )
      {
      ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
      while ( ADCSRA & (1<<ADSC) ) {
      ; // auf Abschluss der Konvertierung warten
      }
      result += ADCW; // Wandlungsergebnisse aufaddieren
      }
      ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
      result /= 4; // Summe durch vier teilen = arithm. Mittelwert
      return result;
    }

int main()
{

    
    DDRA=0x00;
    DDRB=0xff;
    while(1)
   {
    //Auslesen der ADC Kanaele:
    adc_links=0;
    
    adc_links=ReadChannel(0);
    _delay_us(120);
    
    
///////////////////////////////////////////////TEST
    if(adc_links==1023)PORTB|=(1<<PIN0);
    if(adc_links!=1023)PORTB&=~(1<<PIN0);
    

////////////////////////////////////////////////////
  }

}

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Hast du mal die Spannung an AREF gemessen?

MfG Spess

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
    if( adc_links > 1020 )
      PORTB |= (1<<PIN0);
    else
      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.

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, kleiner Fehler meinerseits, da bin ich durcheinandergekommen.
Ich habe anfangs beide LED's benutzt um die Werte der Kanaele zu 
ermitteln(so wie im Gesamtcode).
Mittlerweile leuchtet nur noch die an B0.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK.
Wie genau sind deine LED verschaltet?

(Das ganze Sache wäre so viel einfacher, wenn man sich den tatsächlichen 
Wert vom ADC ansehen könnte und nicht über Umwege erschliessen muss)

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. G. schrieb:

> Kommt das hin ?

Kommt hin.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Kommt das hin ?

Ja.
Ich wiederhole mich ungern, aber hast du die Referenzspannung mal 
gemessen?

MfG Spess

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Jetzt liegt auf Aref keine Spannung mehr.

Das hatte ich befürchtet. Überprüfe mal, ob da nicht ein Kurzschluss von 
VREF nach Masse ist.

MfG Spess

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich konnte zwar keinen kurzschluss ausmachen , allerdings habe ich 
anscheinend trotzdem einen beseitigt.
An Aref liegen nun 2,3 Volt an , und die LED's reagieren.
Nur tun sie das schon bei Spannungen unter einem Volt.
Mit freundlichen Gruessen.

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem koennte diesmal an der Hardware liegen .
Ich werden morgen ein paar Modifizierungen vornehmen und es ernuet 
versuchen.
Allerdings scheint der ADC zu funktionieren.
Vielen Dank schonmal an alle die bis jetzt geholfen haben!

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas O. (kosmos)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas O. (kosmos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Spendier mal dem Eingang einen Pulldown-Widerstand von 10 kOhm gegen 
Masse, damit er nicht offen hängt.

Autor: Gast 10 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich habe gerade Aref nochmal nachgemessen, und die Spannung an Aref ist
>jetzt -5 Volt

Das wuerde auch erklaeren warum die test LED auch ohne Spannung leuchtet 
( 0 Volt) sind mehr als -5

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas O. (kosmos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielleicht indem man VCC und GND oder AVCC und GND vertauscht. Ist der 
Magic Smoke aus dem IC ausgetreten, den bekommt man schlecht wieder rein 
;-) und dann ist der Chip hin.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
WIe sieht eigentlich dein Aufbau aus?
Benutzt du eine fertige Platine? Ein Steckbrett?
Besonders billige Steckbretter sind dafür bekannt, dass sich die 
Wackelkontaktquote im Lauf der Zeit erhöht, um es mal freundlich 
auszudrücken.

Autor: M. G. (elch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mitlerweile liegen wieder 5 Volt an Aref an ^^
Ausserdem funktioniert der ADC nun wirklich.
Solang keine weiteren Probleme mit dem ADC mehr auftreten bedank ich 
mich schonmal herzlich bei allen die mir hier geholfen haben !

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.