Forum: Mikrocontroller und Digitale Elektronik ADC mit Poti


von Alex (Gast)


Lesenswert?

Hallo,

ich habe ein Programm geschrieben mit dem ich lediglich den Wert eines 
Potis einlesen will und damit die Blinkgeschwindigkeit einer LED steuern 
möchte.(Arduino Nano V3.0; ATmega328P)

Nach vielen probieren und suchen hier im Forum habe ich leider keine 
Lösung gefunden. Bis jetzt blinkt die LED mit konstanter 
Geschwindigkeit, egal wie ich das Poti einstelle.
Ich wäre sehr dankbar für Hilfe. Hier ist mein Code:


void ADC_Init(void){

  uint16_t result;

  ADMUX |= (1<<REFS1) | (1<<REFS0);  //internal Reference Voltage

  ADCSRA |= (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);     // enable ADC, 
Prescaler (8)
//  ADCSRB|=(1<<ADTS0);
//  ADCSRA |= (1<<ADEN);                  // enable ADC


  //'Dummy-Readout', single conversion to 'warm up'
  ADCSRA |= (1<<ADSC);                  //ADC Conversion
  while(ADCSRA & (1<<ADSC));    //wait for end of Conversion
  result=ADCL+ADCH*256;
}

uint16_t ADC_read(uint8_t channel)
{
  ADMUX = (ADMUX & ~(0x1F))  | (channel & 0x1F); //select channel 
without changing other Bits
  ADCSRA |= (1 << ADSC);            //single conversion
  while (ADCSRA & (1<<ADSC));   //wait for end of conversion

  return ADCL+ADCH*256; // read and return ADC
}

void delay_ms(uint16_t x)
{
   for(uint16_t i=0; i<x; i++)
   {
      _delay_ms(1);
   }
}

int main(void)
{
  uint16_t val=0;
  ADC_Init();
  DDRB = (1 << DDB5);  //LED Pin Output
//  DDRC = (0 << PC0);  //ADC Pin Input


    while(1)     //FOREVER
    {

  val = ADC_read(0);  //Read analog Value at Pin A0
  PORTB = (1 << DDB5);     //LED (Pin 17) On
  delay_ms(val);
  PORTB = 0;     //LED (Pin 17) Off
  delay_ms(val);

    } //end FOREVER loop

} //end main


Vielen Dank schonmal,

Alex

von Ulrich H. (lurchi)


Lesenswert?

Um einen Poti einzulesen sollte man eher AVCC als Ref. Spannung wählen - 
halt die Spannung wo der Poti auch dran ist.
Ein Prescaler von 8 dürfte beim Arduino mit 16 MHz Takt etwas wenig 
sein.

Auch wenn das hier kein echter Fehler ist, sollte man bei der 
Initialisierung des ADCs alle Bits beschreiben, also mit ADCSRA = .... 
und ADCMMUX = ..., nicht mit |= ... . So ist man unabhängig von dem was 
vorher drin steht, und muss nicht suchen, zurückverfolgen was da vorher 
eingestellt war.

Den ADC wert kann man auch direkt als 16 Bit wert Auslesen, als ADC. Für 
das zusammensetzen und richtige Reihenfolge bei Zugriff sorgt dann schon 
der Compiler.

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.