ADC mit Poti

Gast #3841115
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
#3841132
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.

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