PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PWM-Lüfterreglungssignal vom Mainboard auslesen



Dunuin
14.10.2011, 14:26
Moin,

Ich versuche den Duty-Cycle (in 1%-Schritten) vom PWM-Steuersignal des Mainboards auszulesen, welches normal per 4-Pin-Molexstecker an den PWM-geregelten CPU-Lüfter gesendet wird. Abhängig von dem gemessenen Duty-Cycle möchte ich dann später einen Lüfter (der kein PWM-Steuersignal unterstützt) über die Spannung drosseln.

Hier die Spezifikationen (http://www.formfactors.org/developer%5Cspecs%5CREV1_2_Public.pdf) zu dem PWM-Signal:



PWM Control Input Signal
The following requirements are measured at the PWM (control) pin of the fan cable connector:

PWM Frequency: Target frequency 25 kHz, acceptable operational range 21 kHz to 28 kHz
Maximum voltage for logic low: VIL = 0.8 V
Absolute maximum current sourced: Imax = 5 mA (short circuit current)
Absolute maximum voltage level: VMax = 5.25 V (open circuit voltage)

Da hatte ich jetzt 2 Ansätze, wo mir aber keine brauchbare Lösung zu einfällt:

1.) PWM-Signal direkt per Atmega uC auslesen.
Eine Idee war es, dass ich den Duty-Cycle direkt per 16bit-Timer per Input Capture Interrupt auswerte. 28kHz Frequenz * 100 Schritte Auflösung = Flankenwechsel im bis zu 2,8 MHz Intervall. Selbst wenn ich da einen 20MHz Quarz an den Atmega hänge, hätte ich nur 7 Takte, um den Flankenwechsel auszulesen und auszuwerten, bevor der nächste Flankenwechsel kommen würde. Das bekomme ich aber so schnell nicht hin.

2.) PWM-Signal per Tiefpass 1. oder 2. Grades glätten und dann dessen Spannung per ADC auslesen
Hier wollte ich gerne das PWM-Signal vom Mainboard per Optokoppler abzweigen, damit ich mir nicht ausversehen das Mainboard zerstöre und das ungeglättete PWM-Signal weiterhin funktioniert.

Da stehe ich jetzt aber vor dem Problem, dass so ein Optokoppler meist gute 10 bis 30mA für die LED verbraucht, man das Signal aber nur mit bis zu 5mA belasten kann (wo der CPU-Lüfter sicher auch noch etwas verbraucht). Optokoppler mit ca. 1mA Stromverbrauch konnte ich zwar auch finden, aber die arbeiten dann mit Darlington Phototransitoren, da sonst der Stromverstärkungsfaktor nicht reichen würde und dann sind die so langsam, dass die nur mit ein paar kHz zurecht kommen, ich ja aber 2,8 MHz brauche. Optokoppler mit Photodiode sollen angeblich mit mehreren MHz klar kommen, aber die brauchen dann auch wieder so viel Strom am Eingang.


Hat da noch jemand eine Idee, wie man das hinbekommen könnte?

Hubert.G
14.10.2011, 15:34
Zu 1: Musst du jeden Flankenwechsel auswerten? Wenn du es bei jedem ~20. Wechsel machst ist es doch auch gut.

Dunuin
31.10.2011, 23:37
Naja, ich brauche ja immer die Zeit zwischen steigender Flanke und fallender Flanke und direkt darauf wieder die Zeit zur steigenden Flanke, wenn ich den Duty Cycle haben will. Oft muss ich die Messung nicht machen. So einmal die Sekunde würde reichen, aber ich brauche halt eben die Zeit zwischen diesen 3 Flanken, und die kommen beim Duty Cycle von 99% mit 2,8MHz an.
Bei meinem 16MHz Quarz sind das also keine 6 Takte zwischen den 2 Flankenwechseln.

Ich hatte da jetzt eine Idee, die ich wohl mal versuchen werde, welche darauf basiert, dass sich der Duty Cycle nicht sehr schnell ändert (unter 1 Dutzend mal pro Sekunde).

Als Erstes messe ich die Frequenz, also die Zeit zwischen 2 fallenden Flanken. Bei 30kHz wären das gut 571 Takte.
Wenn da in einem bestimmten Zeitraum keine Flanken gemessen werden, kann ich davon ausgehen, dass der Duty Cycle bei 100% oder 0% liegt. Dann Messe ich Pegel um zu entscheiden, was von beidem es ist.
Wenn da jedoch eine Frequenz gemessen wurde, dann mache ich mit dem Messen des Intervalls zwischen steigender und fallender Flanke weiter. Entweder kommt da dann ein Wert heraus, der kleiner als die Frequenz ist, oder die Zeit war zu kurz und der uC konnte den Timerwert aus dem Input Capture Register nicht rechtzeitig lesen, bevor dieser durch einen neuen Überschrieben wurde. In dem Fall wäre der Intervall dann ja größer als die Frequenz.
Das gleiche danach dann nochmal umgekehrt für den Intervall zwischen fallender und steigender Flanke.
Wenn der eine Intervall zu kurz zum Messen war, dann muss der andere lang genug gewesen sein. Sollte es da also einen Messfehler gegeben haben (einer der Intervalle größer als die Frequenz), dann wird einfach der richtig gemessene Intervall von der Frequenz subtrahiert und der zu kurze Intervall daraus berechnet.

Oder gibt es da noch andere Wege?

markusj
01.11.2011, 00:20
Oder gibt es da noch andere Wege?
Klingt alles sehr praktikabel, aber auch sehr aufwändig gemessen an der Aufgabe. Rein gefühlsmäßig hätte ich einfach einen RC-Tiefpass rangeklebt und das Signal dann über den ADC eingelesen, das wäre deutlich weniger "tricky".

A propos "tricky", mir kommt gerade noch ein schmutziger kleiner Gedanke: Du kannst ja auch über mehrere Periodendauern messen:
1. Frequenz ermitteln, das geht für Tastgrade != 0%/100% recht einfach und genau.
2. Trigger auf steigende Flanke einstellen
3. Nach Auslösung Input Capture für eine halbe Periodendauer ausschalten
4. Trigger auf fallende Flanke einstellen
(Nach der Umschaltung jeweils zuerst das Interrupt-Flag zurücksetzen)

Warum hilft das?
Fall a) Tastgrad <= 50%: Du "verpasst" die fallende Flanke des (vielleicht zu) kurzen HIGH-Anteils und erfasst erst mit der nächsten fallenden Flanke insgesamt die Zeit einer Periode + Länge des (zweiten) HIGH-Anteils, zieht man die Periodendauer ab, bleibt nur noch der HIGH-Anteil übrig
Fall b) Tastgrad > 50%: Du misst direkt die Zeit des HIGH-Anteils, da er länger als eine halbe Periode dauert.

Relativ einfache Logik, keine zusätzliche Hardware nötig, ich glaube die Variante solltest du Mal ausprobieren.

mfG
Markus

Dunuin
01.11.2011, 11:29
Auch keine schlechte Idee.


3. Nach Auslösung Input Capture für eine halbe Periodendauer ausschalten
Kann ich das per Output Compare Unit und dessen Interrupt machen? Also nach Auslösung den aktuellen Wert vom Timer nehmen, die halbe Periodendauer hinzu addieren und den Wert dann ins Compare Register schreiben, damit der Interrupt dann kommt, wenn die halbe Periodendauer vorbei ist? Weil die anderen beiden Timer sind schon für PWM reserviert und für die Zeitmessung habe ich nur den Watchdog mit seinen 16ms Schritten.

markusj
01.11.2011, 11:37
Kann ich das per Output Compare Unit und dessen Interrupt machen? Also nach Auslösung den aktuellen Wert vom Timer nehmen, die halbe Periodendauer hinzu addieren und den Wert dann ins Compare Register schreiben, damit der Interrupt dann kommt, wenn die halbe Periodendauer vorbei ist?
Ja, so in der Art war das gedacht, die OC-Einheiten lassen sich ja normalerweise unabhängig von der Input Capture Funktionalität verwenden.

mfG
Markus