Forum: Mikrocontroller und Digitale Elektronik Flankenerkennung am ADC


von Henrik E. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich möchte die Intensität von zwei hintereinander getakteten 
Leuchtdioden messen. Im Anhang habe ich mal die Spannungsverläufe dazu 
gemessen.

Kanal 1: Spannung über die beiden Leuchtdioden (sie leuchten abwechselnd 
mit Dunkelphase, Leuchtdioden sind antiparallel geschaltet)
Kanal 2: Fotodiode 1 (mit Verstärker dazwischen)
Kanal 3: Fotodiode 2 (mit Verstärker dazwischen)

Ich möchte mit den gemessenen Intensitäten noch ein paar Berechnungen 
durchführen, deshalb zwei unterschiedliche Fotodioden.

Ich habe die beiden Fotodioden an jeweils einen ADC des XMega128A1 
angeschlossen. Ich kann auch schon prima die Messwerte am ADC auslesen.
Mein problem ist jedoch das Timing. Ich möchte, dass für jede 
Leuchtdiode extra etwa 5 Messwerte aufnehmen. Dazu habe ich mir gedacht, 
dass ich steigende und fallende Flanken erkenne und die beiden 
Leuchtdioden so voneinander trenne. Meine Frage ist jetzt, kann der ADC 
diese Flanken erkennen und einen Interrupt auslösen oder gilt das nur 
für high und low Level? Wenn der ADC diese Flanken nicht erkennt, wie 
kann ich das ganze System sonst noch triggern?

Vielen Dank schonmal im Vorraus!
Hendrik

von Uwe (de0508)


Lesenswert?

Hallo Hendrik,

mir fällt dazu nur ein, laufend messen und die Messwerte je Kanal in 
einem (Ring-)Puffer schreiben. Ein weiterer Prozess verarbeitet 
(analysiert) diese Messwerte und detektiert auf eine "Flanke". Daraus 
generierst Du dann ein Event / Tigger, der vom HP (main()) verarbeitet 
wird.

von Michael (Gast)


Lesenswert?

Hendrik E. schrieb:
> Meine Frage ist jetzt, kann der ADC diese Flanken erkennen und einen
> Interrupt auslösen oder gilt das nur für high und low Level?

Der ADC ist strohdoof und kann überhaupt nichts erkennen. Der kann 
einfach nur auf Befehl die analog anliegende Spannung in einen 
Digitalwert umwandeln. Das steht aber auch im Datenblatt.

Du kannst das Signal deiner Photodiode aber mit einem Hochpaß 
differenzieren, in ein Digitalsignal umwandeln und mit den Peaks bei 
schnellem Helligkeitswechsel einen Interrupt auslösen.

von Henrik E. (Gast)


Lesenswert?

Uwe S. schrieb:
> mir fällt dazu nur ein, laufend messen und die Messwerte je Kanal in
> einem (Ring-)Puffer schreiben. Ein weiterer Prozess verarbeitet
> (analysiert) diese Messwerte und detektiert auf eine "Flanke".

Aber wie detektiere ich in dem Ringbuffer die Flanke?
Ich möchte außerdem mit den Flanken zeitgleich ein Signal wieder 
ausgeben, wenn ich es aber mit Ringbuffer mache, dann ist es auf jeden 
Fall "zeitverzögerter" als mit direkten Interrupt.

Michael schrieb:
> Der ADC ist strohdoof und kann überhaupt nichts erkennen. Der kann
> einfach nur auf Befehl die analog anliegende Spannung in einen
> Digitalwert umwandeln. Das steht aber auch im Datenblatt.

Ja der ADC selber nicht, war vielleicht etwas falsch von mir formuliert. 
Aber an dem Pin selber kann man doch Flanken erkennen oder?

Michael schrieb:
> Du kannst das Signal deiner Photodiode aber mit einem Hochpaß
> differenzieren, in ein Digitalsignal umwandeln und mit den Peaks bei
> schnellem Helligkeitswechsel einen Interrupt auslösen.

Differenzieren und ein Hochpass würden meinen Messwert ja leider 
verändern, den ich ja benötige. Das einzige was mir noch fehlt sind ja 
eben die Zeitpunkte.

von h_ (Gast)


Lesenswert?

Hallo Hendrik,

warum benutzt du nicht einen I/O pin und lässt dir einen Interrupt/Event 
generieren, was die ADC-Conversion triggert. Alternativ könnte man auch 
den Analogcomparator verwenden um ein Interrupt/Event zu generieren.

Viele Grüße

von oldmax (Gast)


Lesenswert?

Hi
Abgesehen davon, das du diese Frage auch an andere Foren stellst, hier 
mal meine Antwort
Welche Flanke soll der ADC erkennen. Er liest "analog"-Signale. 
Natürlich kannst du über den Vergleich alter Wert-> neuer Wert erkennen, 
ob das Signal steigt oder fällt. Mir scheint aber, du vermischt da 
Analogeingang mit Digitaleingang. Die interruptfähigen Eingänge 
(digital) sind so parametrierbar, das sie auf steigende oder fallende 
Flanken reagieren. Wo ist bei einem Analogwert der Punkt, wo er auf eine 
Flanke reagieren soll....
Da wirst du schon selbst tätig werden müssen.
Gruß oldmax

von Michael (Gast)


Lesenswert?

Hendrik E. schrieb:
> Differenzieren und ein Hochpass würden meinen Messwert ja leider
> verändern, den ich ja benötige. Das einzige was mir noch fehlt sind ja
> eben die Zeitpunkte.

Das Differenzieren liefert dir gerade die Umschaltzeitpunkte als 
Flanken. Damit kannst du also deinen Interrupt auslösen und dann mit dem 
ADC den Pegel bestimmen. Wegen der Zeitkonstanten, die in deinen 
Signalen zu sehen sind, kannst du die Helligkeit sowieso nicht direkt 
nach der Flanke bestimmen.

von Henrik E. (Gast)


Lesenswert?

oldmax schrieb:
> warum benutzt du nicht einen I/O pin und lässt dir einen Interrupt/Event
>
> generieren, was die ADC-Conversion triggert. Alternativ könnte man auch
>
> den Analogcomparator verwenden um ein Interrupt/Event zu generieren.

Erkennt der IO Pin die Flanken nur ab einen bestimmten Schwellwert?
Die Möglichkeit mit dem Komparator werde ich nachher mal ausprobieren 
und mit durch den Kopf gehen lassen.

oldmax schrieb:
> Welche Flanke soll der ADC erkennen. Er liest "analog"-Signale.
>
> Natürlich kannst du über den Vergleich alter Wert-> neuer Wert erkennen,
>
> ob das Signal steigt oder fällt. Mir scheint aber, du vermischt da
>
> Analogeingang mit Digitaleingang. Die interruptfähigen Eingänge
>
> (digital) sind so parametrierbar, das sie auf steigende oder fallende
>
> Flanken reagieren. Wo ist bei einem Analogwert der Punkt, wo er auf eine
>
> Flanke reagieren soll....

Ich hätte es gerne so wie bei einem Oszilloskop, welches auch Flanken 
detektieren kann. Leider muss man da ja auch einen Schwellwert angeben.

Michael schrieb:
> Das Differenzieren liefert dir gerade die Umschaltzeitpunkte als
>
> Flanken. Damit kannst du also deinen Interrupt auslösen und dann mit dem
>
> ADC den Pegel bestimmen. Wegen der Zeitkonstanten, die in deinen
>
> Signalen zu sehen sind, kannst du die Helligkeit sowieso nicht direkt
>
> nach der Flanke bestimmen.

Die Zeitkonstanten sind noch so hoch, weil ich keine kleineren 
Kondensatoren habe. Die sind aber bestellt.
Ansich hast du aber recht ich muss auf das Plataeu warten und dann 
messen, aber ich benötige die Flanken noch als Trigger für etwas 
anderes.

von Henrik E. (Gast)


Lesenswert?

Ich habe jetzt den Ansatz mit dem Komparator verfolgt.
Ich habe mir gedacht der Komparator löst jedes mal einen Interrupt aus, 
wenn die eine LED mehr Strom liefert als die andere.

Ich habe in einem ersten Versuch probiert den Komparator über die 
gleichen Pins laufen zu lassen wie den ADC.
Dabei habe ich festgestellt, dass es aufgrund des Multiplexers nicht 
geht.
Jetzt habe ich die beiden Spannungen jeweils einmal zum ADC des Port A 
und zum AC des Port B geführt.

1. Ich habe folgende Initialisierung des Ganzen und der Interrupt wird 
einfach nicht ausgelöst. Eine Anzeige des Komparatorergebnisses über 
PIN0 kommt auch nicht zustande. Ich habe die Atmel Library zum AC 
verwendet.
1
void Trigger_init(){
2
  /* Enable Analog comparator submodule 0. */
3
  AC_Enable(&AC, ANALOG_COMPARATOR0, false);
4
5
  /* By defalut the Analog comparators interupt flag triggers on changes on
6
   * both edges. If another trigger setting (INTMODE) is preferd use the
7
   * AC_ConfigInterrupt function to change the settings. */
8
  
9
  AC_ConfigInterrupt(&AC, ANALOG_COMPARATOR0, AC_INTMODE_BOTHEDGES_gc, AC_INTLVL_MED_gc);
10
  
11
  /* Set up MUXes to sense pin 4 and 1. */
12
  AC_ConfigMUX(&AC, ANALOG_COMPARATOR0, AC_MUXPOS_PIN4_gc, AC_MUXNEG_PIN1_gc);
13
14
  /* Set up AC with a no hysteresis. */
15
  AC_ConfigHysteresis(&AC, ANALOG_COMPARATOR0, AC_HYSMODE_NO_gc); 
16
  
17
  AC_EnableComparator0_Output(&AC);
18
}
19
ISR(AC_COMP0_vect){
20
  
21
}

2. Mein ADC zeigt schon relativ hohe Werte an, obwohl keine Spannung 
anliegt. Liegt es daran, dass der AC von Port B mit den ADC von Port A 
sozusagen kurzgeschlossen ist? Was kann ich dagegen tun? Sobald der 
Transimpedanzverstärker angeschlossen ist geschieht dies nichtmehr.

von Henrik E. (Gast)


Lesenswert?

Problem ist gelöst.
Der Interruptvector ist im Datenblatt und im Atmel Beispielcode 
fehlerhaft.

Der Vecter heißt "ACA_AC0_vect" und NICHT "ACA_COMP0_vect".


Danke für eure Hilfe!
Hendrik

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.