mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timing Problem bei ADC-Wandlung


Autor: Jannik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jungs (und Mädels [gibt es die hier überhaupt?]),

ich habe ein Problem mit meinem Programm auf einem AVR µC.

Ich habe am Eingang eine Blinkspannung (300ms on, 300ms off) mit einer 
Lampe/LED am Ausgang. Sobald die Lampe an ist( Interrupt bei positiver 
Flanke am Eingang), messe ich an einem weiteren Analogeingang die 
Blinkspannung (über ADC, Taktfrequenz 125kHz). Sobald die Spannung unter 
2V fällt (während off) soll die Lampe am Ausgang ausgehen.
Als Resultat hätte ich gerne kontinuierliches Blinken, jedoch setzt das 
Blinken schonmal aus und ich habe unregelmäßiges Blinken.

Ich habe schon folgendes versucht:
* Spannung variiert um zu sehen ob der Vergleichswert 2V richtig ist -> 
funktioniert
* Anstatt Spannungsmessung: feste Zeit eingestellt um die Lampe 
auszuschalten (100ms, 500 ms) -> funktioniert
* Sobald ich die Spannungsmessung über ADC "dazu schalte" funktionierts 
nicht mehr.
uint16_t Messung(uint8_t kanal)  
{
aus Tutorial AVR_GCC ADC
Taktfrequenz 125kHz

Dummy-Readout

Messung (4mal) mit Mittelwertbildung

return mittelwert
}

void main(void){
[...]
 if (Blinker == ein)     // Wenn Blinker eingeschalten ist
      {                  // abgefragt über Interrupt
      timer_init();      // Timer initialisieren und starten
      LED = on;          // LED/Lampe einschalten
        }
//if (t0_zaehler >= Zeit_100ms) // Versuch über Zeit --> geht
//  LED = off;

if ( Messung(2) < Spg_2V )  // Wenn Blink-Spannung kleiner 2 Volt
  {
      Blinker = aus;     
      TCCR0B = 0x00;          // Timer anhalten
      t0_zaehler = 0;         // Zaehler zuruecksetzen
      }
[...]

Hat da jemand ne Idee?

Autor: Jannik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir denn niemend helfen? (Push)

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, mir erschließt sich der Sinn des Ganzen nicht so wirklich...
Hast Du mal ermittelt wie lange Deine ADC-Messung inkl. Mittelung 
dauert?
Aber warum so kompliziert?
Wenn Du "Blink-On" per Interrupt (pos. Flanke) erfasst, warum machst Du 
das gleiche nicht auch mit "Blink-off" (neg. Flanke) ?

Autor: Jannik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hmm, mir erschließt sich der Sinn des Ganzen nicht so wirklich...

Das ist ja nur ein Ausschnitt aus meinem Code. Ich messe beim On-Impuls 
auch den Strom der in der angehängten Schaltung und werte diesen 
entsprechend aus. (Ist aber im Moment auskommentiert wegen des 
Timing-Problems.)

>Hast Du mal ermittelt wie lange Deine ADC-Messung inkl. Mittelung
>dauert?

Nein, wie mach ich das am günstigsten? Habe einen ATTiny45, also alle 
Pins belegt.

>Aber warum so kompliziert?
>Wenn Du "Blink-On" per Interrupt (pos. Flanke) erfasst, warum machst Du
>das gleiche nicht auch mit "Blink-off" (neg. Flanke) ?

Ich muss während des On-Impulses die Spannung auswerten und entsprechend 
der Spannungshöhe reagieren. Da habe ich mir die Messung zu Nutze 
gemacht und gesagt: wenn die Spannnung unter 2 V liegt beginnt der 
Off-Impuls.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Hast Du mal ermittelt wie lange Deine ADC-Messung inkl. Mittelung
>>dauert?
>Nein, wie mach ich das am günstigsten? Habe einen ATTiny45, also alle
>Pins belegt.
Benutze den LED-Pin, den Du ja eh' schon hast. Vor der ADC-Messung LED 
an, nach der Messung + Mittelung LED wieder aus. Am Oszi die LED-On-Zeit 
messen

Autor: Jannik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine Messung dauert 720 µs. Einstieg in die Messroutine bis Ende 
Messroutine:
uint16_t Messung(uint8_t kanal)    
{
  uint8_t i;           // Zählvariable
  uint16_t ergebnis=0;   // ergebnisvariable
  LED = on; 
// ADC aktivieren und Taktfrequenz einstellen
// Kanal wählen
// Dummy-readout
// 4 Messungen
// Mittelwert
  LED = off;
// return Mittelwert
}

--> 720 µs zwischen on und off

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>720 µs zwischen on und off
Dann passt ja zumindest mal das ADC-Timing (<300ms)

Aus den rudimentären Code-Schnipseln jetzt den Fehler zu finden, ist 
sehr schwer. Aber:
if ( Messung(2) < Spg_2V )  // Wenn Blink-Spannung kleiner 2 Volt
{
  Blinker = aus;     
  TCCR0B = 0x00;          // Timer anhalten
  t0_zaehler = 0;         // Zaehler zuruecksetzen
}
kann irgendwie ja nicht funktionieren. Da wird die Spannung ja nur 
einmal abgefragt. Da fehlt doch eine Schleife, in der die Spannung 
kontinuierlich abgefragt wird, bis sie <2V ist, um die LED abzuschalten!

Ich würde Dir immer noch zur Interruptsteuerung (pos./neg. Flanke) 
raten.
Nach der pos. Flanke LED an, Spannung messen und was-auch-immer damit 
machen und per neg. Flanke die LED aus... feddich!

Autor: Jannik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also die Schleife war so:

ISR(INT0_vect)    // Interrupt Vector INT0
{
    Blinker = ein;  // Information: High-Signal liegt an
}

void main(void)
{

Hauptschleife
{

sei();
 if (Blinker == ein)     // Wenn Blinker eingeschalten ist
      {                  // abgefragt über Interrupt
      timer_init();      // Timer initialisieren und starten
      LED = on;          // LED/Lampe einschalten
        }
 else
 {
  LED = off;
  }

  if ( Messung(2) < Spg_2V )  // Wenn Blink-Spannung kleiner 2 Volt
  {
      Blinker = aus;     
      TCCR0B = 0x00;          // Timer anhalten
      t0_zaehler = 0;         // Zaehler zuruecksetzen
      }
[...]
}Hauptschleife Ende
}// Ende main

Mit meinen ganzen auskommentierungen im Moment ist das oben mein ganzes 
Programm

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich nehme doch mal an, "Hauptschleife" ist for(;;) oder while(1), oder 
was vergleichbares???
Ich würde mal sagen, Dein Problem liegt in [...]
Was wenn Du dort (manchmal) mehr als 300ms verbrätst...
...dann wirst Du nicht immer die <2V detektieren können!

INTERRUPTSTEUERUNG !!!!

Autor: Jannik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, schon mal vielen Dank für Deine Hilfe. Einige Tipps haben mich 
weitergebracht. Ich melde mich wenn das Problem gelöst ist...

Autor: Jannik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also nach einigen Tests habe ich festgestellt, dass das Problem nicht 
das ausschalten sondern das Einschalten der LED ist.
 Wie oben zu sehen ist in der Hauptschleife eine Abfrage Wenn Blinker 
ein und  else

Danach die generelle Spannungsabfrage unabhängig von Blinker 
(Hilfsvariable)

Wenn ich das Einschalten der LED im Messprogramm (also ständig) mache 
oder ausserhalbe der IF/ELSE Anweisung ist alles OK. Sobald ich die LED 
aber in der Abfrage: if Blinker == ein; einschalte wird dies schon mal 
ausgelassen bzw (das vermute ich eher) wird sie sofort wieder 
ausgeschaltet, weil die Hilfsvariable Blinker im Interrupt-Modus gesetzt 
wird

Wenn ich die Spannungsmessung (kleiner 2V) in die Abfrage reinschiebe 
(if Blinker == ein) dann blinkt es wieder regelmäßig.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.