Forum: Mikrocontroller und Digitale Elektronik Falscher Spannungswert aus ADC


von adcfail (Gast)


Lesenswert?

Hallo zusammen!

Kann mir jemand sagen, warum der Spannungswert meines ADC`s nicht 
richtig berechnet wird?

Benutze eine 10bit ADC!

void get_adc_data(void)
{
  int i;
  unsigned int Vref = 5000; // 1/1000V (mV)
  unsigned int max_voltage = 2000; // mV
  unsigned long int v_in_ADC;
  unsigned long int sum;
  unsigned long int average_ADC;


  sum=0;
  average_ADC=0;

  for(i=0; i<32; i++)
  {
    ADCSRA |=(1<<ADSC);//ADC_starting_conversation
    while( ADCSRA & (1<<ADSC)); //waiting_for_conversation_end
    sum = sum+ADCW;
  }

    average_ADC = (sum/32);
    v_in_ADC = ((average_ADC * Vref)/1024); //result in mV

    DAC = average_ADC;
    DACON |= (1<<DALA)|(1<<DAOE);(1<<DAEN); //DAC_starting_conversation




  if(v_in_ADC <= max_voltage)
  {
      PCTL2 |= (1<<PCCYC2)|(1<<PRUN2); // PWM_Output_enable

  }
  else
  {
      PCTL2 &= (0<<PCCYC2)|(0<<PRUN2); // PWM_Output_disable

  }


}

Bin über jede Hilfe dankbar!

von Karl H. (kbuchegg)


Lesenswert?

adcfail schrieb:
> Hallo zusammen!
>
> Kann mir jemand sagen, warum der Spannungswert meines ADC`s nicht
> richtig berechnet wird?

Was heißt nicht 'richtig berechnet'?
Hast du mal ein paar Zahlenwerte?

Ansonsten: lass dir sum ausgeben. lass dir average_ADC ausgeben. lass 
dir v_in_ADC ausgeben.

Durch nachvollziehen der einzelnen Werte findet man dann auch was.

Extrem unschlau ist es, sich eine Schaltung aufzubauen, bei der man 
keine Möglichkeit für Ausgaben hat.

von Walleby (Gast)


Lesenswert?

Hey,

welchen Chip verwendest du denn?
Bekommst du denn überhaupt richtige AD-Werte von einer Messung?
Hast du auch deine Referenzspannung korrekt und an den richtigen Pin 
gelegt?

MfG Walleby

von adcfail (Gast)


Lesenswert?

Hallo!

Habe leider keine Möglichkeit mir die Werte ausgeben zu lassen, kein 
Debugger und kein Display.

Ich überprüfe die Funktion indem ich über die eingestellte Grenze (max 
Voltage) mit dem ADC pendel.

Stimmen meine Variablendeklarationen?

DANKE!

von adcfail (Gast)


Lesenswert?

Ich verwende den AT90PWM.
Referenzspannung ist auch in Ordnung. Da ich den ADC wieder direkt auf 
den DAC lege, kann ich gut die Funktion des ADC`s überwachen. Dies 
funktioniert auch relativ gut.

Es entstehen lediglich Problem bei der Berechnung des Spannungswertes 
und dessen Weiterverarbeitung.

Gruss

von Walleby (Gast)


Lesenswert?

Naja

Int durch Int teilen und das Ergebnis in einen Int packen ist nicht 
besonders sinnvoll. Da können durchaus mal Fehler reinrutschen. Deswegen 
würde ich einen Puffer, z.b. als double verwenden und diesen danach 
runden.

MfG Walleby

von Karl H. (kbuchegg)


Lesenswert?

Öh.

Moment mal

  else
  {
      PCTL2 &= (0<<PCCYC2)|(0<<PRUN2); // PWM_Output_disable

  }

Quatsch !


Ich dachte, die Sache mit den Bitmanipulationen sei schon längst 
gegessen!

Bit setzen

   irgendwas |= ( 1 << BitNummer );

Bit löschen

   irgendwas &= ~( 1 << Bitnummer );

Bei mehreren Bits dann eben

   irgendwas |= ( 1 << BitNummer1 ) | ( 1 << BitNummer2 );

bzw.

   irgendwas &= ~( ( 1 << BitNummer1 ) | ( 1 << BitNummer2 ) );


Ein Konstrukt  0<<irgendwas  ist NIEMALS sinnvoll. Denn eine 0 kannst du 
verschieben sooft du lustig bist. Das Ergebnis wird immer 0 bleiben. 
Oder mathematisch ausgedrückt: 0 mal irgendeine andere Zahl ergibt 
wieder 0. Egal was die andere Zahl auch sei.

von Karl H. (kbuchegg)


Lesenswert?

Walleby schrieb:
> Naja
>
> Int durch Int teilen und das Ergebnis in einen Int packen ist nicht
> besonders sinnvoll. Da können durchaus mal Fehler reinrutschen.

Können.
Aber nicht bei seiner Rechnerei.

  1024 * 5000 / 1024

läuft nicht über wenn man unsigned long rechnet.

>  als double verwenden und diesen danach runden.

Ich würd die ganze Rechnerei umdrehen.
Wozu jedesmal den ADV Wert in eine Spannung umrechnen und dann mit einer 
Grenze vergleichen, wenn ich genausogut einmalig die Grenze von Volt in 
ADC-Einheiten umrechnen kann.

Dann brauch ich in der Hauptschleife überhaupt nichts rechnen sondern 
nur Werte vergleichen.

von Walleby (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Walleby schrieb:
>> Naja
>>
>> Int durch Int teilen und das Ergebnis in einen Int packen ist nicht
>> besonders sinnvoll. Da können durchaus mal Fehler reinrutschen.
>
> Können.
> Aber nicht bei seiner Rechnerei.
>
>   32768 * 5000 / 1024
>
> läuft nicht über wenn man unsigned long rechnet.

Ich dachte da ehr an die unterschlagenen Kommazahlen :)

Aber stimmt schon, die sind wahrscheinlich so unbedeutend, dass man sich 
das auch schenken kann.

von Karl H. (kbuchegg)


Lesenswert?

Walleby schrieb:
>
> Aber stimmt schon, die sind wahrscheinlich so unbedeutend, dass man sich
> das auch schenken kann.

Er rechnet sowieso in Millivolt. Was ja grundsätzlich gut ist.




Sein Hauptfehler war die Annahme, dass das alles pipifax wäre und er 
keine Ausgabemöglichkeit (und sei es nur temporär verfügbar) brauche. 
Gerade als Anfänger braucht man IMMER eine Möglichkeit, wo man 
Zwischenwerte ausgeben kann. Und wenn es nur 8 LED an einem Port sind, 
an die man mal ein Byte ausgeben kann. Ohne ... ist das alles Stochern 
im Nebel. Gerade für einen Anfänger das Schlimmste was passieren kann.

von Walleby (Gast)


Lesenswert?

Jo, ohne diese Möglichkeit wirds ein schönes Ratespiel ohne Ergebnis.

@adcfail
Bau dir doch einen USART-Adapter zusammen, oder verwende den von deinem 
Flashtool (falls vorhanden). Dann brauchst du nur zwei Pins am 
Controller und du kannst dir die Werte wunderbar ausgeben. Und das ganze 
ist auch noch adaptierbar^^

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.