Forum: Mikrocontroller und Digitale Elektronik Frequenzmessung per ADC beim mega48


von Sebi (Gast)


Lesenswert?

Hallo,

ich hab ein etwas ungewöhnliches Problem und keine richtige Idee wie ich 
das anpacke.
Es geht um einen Lichtsensor, der das Flackern von Leuchmitteln erkennen 
soll. Dafür verwende ich einen 08/15-Fototransistor. Mit nem Oszi klappt 
das auch wunderbar, aber ich brauch das Ding tragbar.

Der Plan ist es, per Poti und Fototransistor nen Spannungsteiler zu 
basteln, das über den ADC einzulesen und Stärke der "Welligkeit" des 
Lichts und die Frequenz auf ein LCD zu schieben. Leider hängt die 
Spannung am ADC sehr stark von den Lichtverhältnissen ab, das pendelt 
über den ganzen Bereich.

Problem ist folgendes: Der ADC tut sich schwer, brauchbare Werte zu 
liefern, da sich der interessante Spannungsbereich ständig verschiebt. 
Dazu kommt, dass das Signal kein schönes Sinus sondern ziemlich verhunzt 
ist. Ich möchte die Amplitude rauslesen und ausgeben. Leider bekomm ich 
die Minima/Maxima nicht richtig erfasst, weil die sich stänig 
verschieben. Im Moment bilde ich aus 6 ADC-Messungen einen Mittelwert 
und logge die letzten 4 Werte mit. Sind der 1. und der 2. Wert 
größer/kleiner als der 3. und 4. gehe ich von einem Maximum/Minimum aus 
und zähle eine Variable hoch. Alle 250ms lese ich die Variable aus und 
rechne auf die Frequenz zurück. Leider ist das sehr ungenau, und ich 
habe keine Ahnung wie man Frequenz- und Amplitudenmessung unter einen 
Hut bekommt, wenn man so ein komisches Signal hat.

Kann mir da jemand helfen?

Viele Grüße,
Sebi

von J. S. (harry_2)


Lesenswert?

Hallo,
hört sich interessant an, aber das wird wohl so einfach nicht gehen.
Du solltest mal Deine Vorstellung von Deiner Elektronik, die dem
ADC vorgeschaltet ist hier zugänglich machen.
Nach den wenigen Informationen würde ich sagen, das geht so nicht.
Begründung: Dein Fototransitor liefert bei mehr Helligkeit einen
höheren Wert über Deinen Spannungsteiler, genau wie eine höhere
Frequenz, woher soll Dein ADC wissen durch was jetzt der Wert
verändert wird.

von Timmo H. (masterfx)


Lesenswert?

Ich würde nicht das Minimum und Maximum versuchen zu erfassen, sondern 
einfach den Abstand von Nulldurchgang zu Nulldurchgang. Am besten 
entkoppelst du das ganze mit einem Kondensator um den 
Gleichspannungsteil rauszufiltern. Dann ggf. noch über nen 
Impedanzwandler oder kleinen Verstärker (je nachdem wie klein die Pegel 
sind) und das "Ruhepotential" auf VCC/2 bringen.

von Sebi (Gast)


Lesenswert?

Hallo,

die Frequenz ist ja durch die Lichtquelle vorgegeben, die ändert sich 
nicht. Was sich mit dem Abstand ändert, ist der Spannungsbereich, in dem 
das Signal reinkommt, also zb bei 5m zwischen 1,4 und 1,8V, bei 3m 
zwischen 2,5V und 3,0V etc.
Für den Grobabgleich (Tag/Nacht zb) reicht das Poti, aber eben nicht für 
den "normalen" Bereich. Das muss der µC kompensieren.

Das Hauptproblem ist das zuverlässige Erkennen der Maxima/Minima. Ich 
brauche etwas, was mir unabhängig vom Spannungsbereich sagt, wann ich 
eine Periode des Eingangssignal hinter mir habe. Leider sind meine 
bisherigen Versuche entweder zu ungenau oder zu träge.

Was die externe Beschaltung angeht: Da ich im Idealfall auch die 
Differenz zwischen dem maximalen und minimalen ADC-Wert auslesen will, 
kann ich keine Vorverstärker verwenden. Auch ein Schmitttrigger fällt 
deshalb flach. Und außerdem macht der schwankende Spannungsbereich 
Schmitttrigger etc ziemlich kompliziert.

Im Moment reichts mir schon, wenn ich die Frequenz zuverlässig auslesen 
könnte.
Die Amplitudenmessung wäre insofern interessant, als dass man das Gerät 
an einem festen Punkt aufstellen und dann die Auswirkungen verschiedener 
Beleuchtungen messen könnte. Das ist aber zweitrangig, die 
Frequenzmessung ist wichtiger.

Viele Grüße,
Sebi

von Anja (Gast)


Lesenswert?

Sebi schrieb:
> die
> Frequenzmessung ist wichtiger.

Verstehe ich nicht. Die Frequenz ist doch konstant 50 oder 60 Hz bzw das 
doppelte davon.
Ich würde einfach Timer-Getriggert z.B. alle 1ms für 100 ms messen und 
aus den 100 Werten Minima und Maxima für die Amplitude herauslesen.

Gruß Anja

von Sebi (Gast)


Lesenswert?

Hallo,

ich muss auch die Frequenz einer (schlechten) LED-PWM mit rausmessen 
können, daher die variable Frequenz.

Ich hab jetzt mal versucht eine gewisse Zeit mitzuloggen und dann 
auszuwerten: Das produziert leider nur Datenmüll, weil mir entsprechende 
Filter fehlen. Da harperts dann mit der Mathematik ;)
Ich bekomm die Min/Max nicht zuverlässig erkannt, weil oft kleine 
Schwankungen in den Werten sind, die zwar mathematisch gesehen kleine 
min/max darstellen, aber eben nicht die absoluten.

Hat jemand eine Idee für einen geeigneten Filter? Einfach mehrere Werte 
hintereinander zu betrachten und zu vergleichen reicht nicht aus, man 
müsste irgendwie den gesamten Kurvenverlauf erfassen und nur die Punkte 
rausrechnen, an denen sich das Steigungsverhalten "dauerhaft" ändert, 
also all die kleinen Messfehler gekonnt ignorieren. Ich wüsste aber 
nicht, wie sich das mit vertretbarem Aufwand machen lässt. Hilfe?


Viele Grüße,
Sebi

von Anja (Gast)


Lesenswert?

Sebi schrieb:
> Ich bekomm die Min/Max nicht zuverlässig erkannt, weil oft kleine
> Schwankungen in den Werten sind, die zwar mathematisch gesehen kleine
> min/max darstellen, aber eben nicht die absoluten.

Wie machst Du das denn mit dem Auge auf dem Oszi?

ungefähr so:

Absolutes Maximum und minimum ermitteln und Strahl in die Mitte stellen.
An der Mittellinie die Nulldurchgange ausmessen ggf. mit etwas Hysterese 
von 10-20 % der Maximalamplitude falls kleine Störungen da sind.

Oder ?

Gruß Anja

von Sebi (Gast)


Lesenswert?

Hallo,

alles schön und gut, in der Theorie und mit Testwerten klappt das auch 
ganz toll. Nur leider bekomm ich bei echten Messungen weiterhin 
Datenmüll. Das Problem ist ein geeigneter Filter. Ich bin mathematisch 
nicht fit genug, dass ich da irgendwelchen komplexen Verrenkungen 
anstelle und das weiß der Teufel wie rausrechnen könnte, es muss also 
irgendwas simples sein.

Was ich bisher (ohne Erfolg) versucht hab:

- Min/Max erkennen über die Werte in der Nachbarschaft: zu Ungenau, 
Werte schwanken zu stark.
- nur Max suchen, da als Spitze im Signal: Selbes Problem, Signal 
schwankt zu stark für ne Erkennung mit meinen Mitteln
- Absolute Min/Max suchen, Nulldurchgang berechnen und den zählen: 
kompletter Datenmüll, warum ist mir nicht klar. Mit nem Testprogramm und 
vorgegeben Werten funktioniert das gut, aber mit dem echten Signal geht 
nichts. Werde den Code etwas umstellen und dann mal mit einem schönen 
Sinus testen.

Was ich gerne testen würde, wozu mir aber das Wissen fehlt:
Flankenerkennung (soweit man das Flanken nenne kann) des Signals und 
daraus dann Min/Max bestimmen. Leider hab ich keinen Plan wie man das 
macht ohne, dass auch kleine Spitzen/Wackler im Signal miterfasst 
werden.

Viele Grüße,
Sebi

von Reinhard Kern (Gast)


Lesenswert?

Hallo,

was du brauchst ist eine Fourier-Analyse des Spannungsverlaufs. Das 
berechnete Spektrum hätte dann bei einer Leuchtstoffröhre die grösste 
Leistung bei 100 Hz.

Kannst ja mal danach googeln, ist heute immerhin in jedem besseren Oszi 
eingebaut.

Gruss Reinhard

PS natürlich kannst du dir auch ein digitales 100Hz-Filter 
programmieren. Aber wenn du vorher schon weisst, das es 100Hz sind, 
kannst du dir auch gleich die Messung sparen.

von nur ein Gast (Gast)


Lesenswert?

Du könntest zB mal einen gemessenen Verlauf hier reinstellen. Kann man 
sich ja sonst gar nichts drunter vorstellen.

Warum geht denn keine Nulldurchgangerkennung?

von MarioT (Gast)


Lesenswert?

Ist das immer nur eine Lichtquelle oder mehrere z.B.Leuchtstoffröhre und 
LED. Vieleicht noch an unterschiedlichen Phasen?

von Joachim (Gast)


Lesenswert?

Moin,

also eine einfache art der Filterung wird gemacht, indem du ein Array 
mit z.B. 16 Elementen hast. Wenn ein neuer Messwert reinkommt verwirfst 
du das älteste Array-Element und speicherst dafür den neuen Messwert ab. 
Dann aufaddieren und durch die Anzahl teilen. Ist ein einfacher 
Tiefpassfilter.

Minima und Maximaerkennung gehen dann eigentlich auch nicht so schwer. 
Der Code sähe quasi so aus:
1
gemittelter_Wert = 0;
2
minima = 0xFF;
3
maxima = 0;
4
5
for(char x = 0; x < 16; x++)
6
{
7
gemittelter_Wert += array[x];
8
9
if(array[x] > maxima)
10
{
11
maxima = array[x];
12
}
13
14
if(array[x] < minima)
15
{
16
minima = array[x];
17
}
18
}
19
20
gemittelter_Wert >>= 4;

Damit kriegst du aber nur die Extremwerte innerhalb deines Arrays. 
Schöner (und sinnvoller) wäre es eigentlich, wenn du das mit der 
Nulldurchgangsbestimmung machst und dann die Mittelung und die Suche 
nach den Extremwerten mit allen Messwerten durchführst, die du innerhalb 
einer Periode gesammelt hast.
Gruß

von Anja (Gast)


Lesenswert?

Sebi schrieb:
> Nulldurchgang berechnen und den zählen:
> kompletter Datenmüll, warum ist mir nicht klar.

Hast Du auch eine Hysterese mit eingerechnet oder "nur" die 
Nulldurchgänge ohne Hysterese verwendet?

Gruß Anja

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.