Falscher Spannungswert aus ADC

Gast #2858799
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!
#2858807
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.
Gast #2858819
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!
Gast #2858824
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
Gast #2858827
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
#2858832
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.
#2858847
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.
Gast #2858856
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.
#2858859
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.
Gast #2858869
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^^

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