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


von Jannik (Gast)


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.
1
uint16_t Messung(uint8_t kanal)  
2
{
3
aus Tutorial AVR_GCC ADC
4
Taktfrequenz 125kHz
5
6
Dummy-Readout
7
8
Messung (4mal) mit Mittelwertbildung
9
10
return mittelwert
11
}
12
13
void main(void){
14
[...]
15
 if (Blinker == ein)     // Wenn Blinker eingeschalten ist
16
      {                  // abgefragt über Interrupt
17
      timer_init();      // Timer initialisieren und starten
18
      LED = on;          // LED/Lampe einschalten
19
        }
20
//if (t0_zaehler >= Zeit_100ms) // Versuch über Zeit --> geht
21
//  LED = off;
22
23
if ( Messung(2) < Spg_2V )  // Wenn Blink-Spannung kleiner 2 Volt
24
  {
25
      Blinker = aus;     
26
      TCCR0B = 0x00;          // Timer anhalten
27
      t0_zaehler = 0;         // Zaehler zuruecksetzen
28
      }
29
[...]

Hat da jemand ne Idee?

von Jannik (Gast)


Lesenswert?

Kann mir denn niemend helfen? (Push)

von Stefan (Gast)


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) ?

von Jannik (Gast)


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.

von Stefan (Gast)


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

von Jannik (Gast)


Lesenswert?

Meine Messung dauert 720 µs. Einstieg in die Messroutine bis Ende 
Messroutine:
1
uint16_t Messung(uint8_t kanal)    
2
{
3
  uint8_t i;           // Zählvariable
4
  uint16_t ergebnis=0;   // ergebnisvariable
5
  LED = on; 
6
// ADC aktivieren und Taktfrequenz einstellen
7
// Kanal wählen
8
// Dummy-readout
9
// 4 Messungen
10
// Mittelwert
11
  LED = off;
12
// return Mittelwert
13
}

--> 720 µs zwischen on und off

von Stefan (Gast)


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:
1
if ( Messung(2) < Spg_2V )  // Wenn Blink-Spannung kleiner 2 Volt
2
{
3
  Blinker = aus;     
4
  TCCR0B = 0x00;          // Timer anhalten
5
  t0_zaehler = 0;         // Zaehler zuruecksetzen
6
}
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!

von Jannik (Gast)


Lesenswert?

Also die Schleife war so:
1
ISR(INT0_vect)    // Interrupt Vector INT0
2
{
3
    Blinker = ein;  // Information: High-Signal liegt an
4
}
5
6
void main(void)
7
{
8
9
Hauptschleife
10
{
11
12
sei();
13
 if (Blinker == ein)     // Wenn Blinker eingeschalten ist
14
      {                  // abgefragt über Interrupt
15
      timer_init();      // Timer initialisieren und starten
16
      LED = on;          // LED/Lampe einschalten
17
        }
18
 else
19
 {
20
  LED = off;
21
  }
22
23
  if ( Messung(2) < Spg_2V )  // Wenn Blink-Spannung kleiner 2 Volt
24
  {
25
      Blinker = aus;     
26
      TCCR0B = 0x00;          // Timer anhalten
27
      t0_zaehler = 0;         // Zaehler zuruecksetzen
28
      }
29
[...]
30
}Hauptschleife Ende
31
}// Ende main

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

von Stefan (Gast)


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 !!!!

von Jannik (Gast)


Lesenswert?

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

von Jannik (Gast)


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.

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.