- LiTime Speicher und Akkus         
Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 37

Thema: Problem mit ADC

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    01.07.2005
    Beiträge
    64

    Problem mit ADC

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,

    ich versuche gerade mit meinem Atmega8 auf meinem Pollin-Board eine Spannung über den ADC zu erfassen. Ziel ist es, dann einen Temperatursensor anzuschließen und die Temperatur zu messen, leider scheitere ich schon an einer einfachen Spannungsmessung. Von der Schaltung her hab ich zwei 1,5K Widerständer in Reihe geschaltet, die an einer externen 5V Spannung anliegen, dazwischen greif ich am ADC0 die Spannung ab, die ja 2,5V betragen müsste. Wenn ich das ganze jetzt laufen lasse und mir die ADC-Werte ausgeben lasse, schwanken die ganz schön:

    Code:
    6.000e+02 6.000e+02 5.000e+02 5.000e+02 5.000e+02 5.000e+02 5.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 5.000e+02 5.000e+02 5.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 4.000e+02 5.000e+02 5.000e+02 5.000e+02 1.000e+03 7.000e+02 1.000e+03 6.000e+02 1.000e+03 6.000e+02 1.000e+03 6.000e+02 1.000e+03 7.000e+02 1.000e+03
    Mein Quellcode für die ADC-Abfrage sieht wie folgt aus:

    Code:
    uint16_t readADC(uint8_t mux)
    {
    	uint16_t result;
    	uint8_t i;
    
    	ADMUX=mux;
    	ADMUX|=(1<<REFS0);//|(1<<REFS1);
    
    	ADCSRA|=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS2);	//(ADSC<<1)|(ADATE<<1)|
    	ADCSRA|=(1<<ADSC);
    	while(ADCSRA & (1<<ADSC));
    	result=ADCW;
    	result=0;
    
    	for(i=0;i<4;i++)
    	{
    		ADCSRA|=(1<<ADSC);
    		while(ADCSRA & (1<<ADSC));
    		result+=ADCW;
    	}
    
    	ADCSRA&=~(1<<ADEN);
    	result/=4;
    	return result;
    
    
    }
    
    double getTemp(uint8_t channel)
    {
    	uint16_t adc;
    	double U=0, step=0,T=0;
    
    	adc=readADC(channel);
    	step=(((double)5.00)/((double)1024.00));	
    	U=((double)step)*((double)adc);
    	//T=(((double)118.321)*((double)U))-((double)215.583);
    
    	return (double)(adc);
    }
    Da das mein erster Versuch mit dem ADC ist, bin ich mir auch nicht ganz sicher, ob ich das so richtig mache bzw. weiß ich nicht, warum die ADC-Werte so schwanken.
    Ich lasse mir das ganze dann über RS232 ausgeben:

    Code:
    int main()
    {
    double temp;
    char buf[20];
    
    uart_init();
    
    	while(1)
    	{
    		temp=(double)getTemp(0);		
    		send(dtostre((double)temp,buf,3,0));
    		send(" ");
    		buf[0]='\0';
    		wait_sec(1);
    	}
    }
    Wenn das dann funktioniert möchte ich den einen widerstand an der Masse mit einem KTY 81-120 ersetzen, um dann die Temperatur zu ermitteln, hab ich mir mit ein paar Messadaten aus dem Datenblatt eine lineare Funktion ermitteln lassen, in die ich dann bloß noch die gemessene Spannung einzusetzen brauche und die Temperatur erhalte. Leider weiß ich nicht, ob es da evtl. eine bessere Möglichkeit gibt, da diese Variante ziemlich viel Speicher verschlingt...

    Gruß
    cesupa

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.05.2005
    Ort
    Rott am Inn
    Alter
    36
    Beiträge
    373
    Hi,
    also so weit ich das sehe fängst du sofort nach dem einschalten des ADC mit der Messung an. Der ADC braucht aber eine Zeit bis er sich eingeschwungen hat. Das heißt du müsstest den ersten Wert den du einliest einfach verfallen lassen und nicht beachten, dann müssten die Schwankungen zurückgehen.
    Hoffe das hilft dir weiter.
    mfg franz

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    01.07.2005
    Beiträge
    64
    Mache ich das nicht schon mit:

    Code:
    //...
    
    ADCSRA|=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS2);   
       ADCSRA|=(1<<ADSC);
       while(ADCSRA & (1<<ADSC));
       result=ADCW;
       result=0; 
    
    //...
    ?

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.05.2005
    Ort
    Rott am Inn
    Alter
    36
    Beiträge
    373
    Ja, machst du damit. Hat ich übersehen. Es könnte allerdings auch an der Beschaltung des AVCC Pins liegen. Weiß jetzt nicht ob der beim Pollin-Board so wie im Datenblatt beschrieben beschalten ist. Mit 10µH nach +5V und mit 100nF nach GND.
    mfg franz

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    01.07.2005
    Beiträge
    64
    Okay, ich habs hingekriegt, es lag einfach daran, dass ich eine externe Versorgungsspannung für die Widerstandsschaltung verwendet habe und nicht die Spannung vom Pollinboard, die auch am Atmega anliegt.

    Gruß
    cesupa

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    29.04.2008
    Beiträge
    49
    hi ich habe auch eine externe spannungsquelle und bei mir lasse ich mir den wert per LED's anzeigen (mein quellcode is der von oben) nur bei mir spielen die LED's vollkommen verrückt

    kann das auch an der externen spannungsquelle liegen?

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    09.02.2006
    Beiträge
    57
    @Grandalf: Hast du die Masse der externen Spannungsquelle mit der von der Versorgungsspannung verbunden?

    Gruß
    Jonas
    Gruß
    Jonas

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    29.04.2008
    Beiträge
    49
    jo hab ich und das andere kabel am pin0 vom porta

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    09.02.2006
    Beiträge
    57
    Naja, dann sollte es nicht daran liegen, dass die Spannungsquelle extern ist. Zur Sicherheit kannst du ja mit dem Multimeter an dem ADC-Pin die Spannung gegen den AGND pin messen. Wenn da die richtige Spannung ansteht, dann muss der Fehler woanders liegen
    -> Code (+ Schaltplan, wenn vorhanden) posten
    Gruß
    Jonas

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    29.04.2008
    Beiträge
    49
    ne stimmt wohl anscheinend alles mit der spannungsquelle
    in ordnung

    hier mein code

    Code:
    #include <avr/io.h>
    #include <avr/iom16.h>
    #include <inttypes.h>
    
    uint16_t ReadChannel(uint8_t mux)
    {
     uint8_t i;
     uint16_t result;
     ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0); 	// Frequenzvorteiler
     												// setzen auf 8 (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;
    }
    
    void ShowByte(uint16_t wert)
    {
     PORTC = wert;
    }
    
    int main (void)
    {
     DDRC = 0;
     PORTC = 0;
     uint16_t adcval = 0;
     
     while(1)
     {
      adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 */
      ShowByte(adcval);
     }
     return 0;
    }
    und schaltplan is eigendlich nur das PORT C an jedem pin ne LED hat
    AVCC und VCC sowie AGND und GND sind verbunden und von meiner 2ten spannungsquelle wie gesagt das eine an GND das andere an PORTA pin0
    von nem atmega16 welcher auf dem evaluationboard von pollin sitzt und wo das addonboard noch dabei is www.pollin.de (für die datenblätter)

    angeschlossen is also wie ich glaube alles richtig. komisch finde ich nur das am PORTC 3 LED's dauerhaft leuchten (3, 5 und 6) egal was am analogpin anliegt (selbst wenn reset gedrückt wird
    die gehen einfach nicht mehr aus)

    led 7 und 8 verhalten sich normal und led 1 und 2 flackern wie wild
    led 4 is immer aus....

    eigendlich sollte dort wenn ich das richtig gemacht hab einfach der ADC wert ausgegeben werden indem die 8 leds als byte leuchten

    gruß Grandalf

Seite 1 von 4 123 ... LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus