PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 6 Tachosignale von Compüterlüftern messen



Andy1988
08.08.2006, 12:27
Hallo!
Ich will mir eine Überwachung meines Servers bauen. Da will ich die Drehzahlen von den 6 Gehäuselüftern messen. Nur hab ich keine Ahnung, wie. Bei einem wär es kein Problem.

Ein Timer und nen Externen Interrupt, die Zeit zwischen 2 Interrupts messen, die vom Lüfter ausgelöst werden und dann is der Rest nur noch rechnen.

Aber wie kann ich das bei 6 Lüftern machen? Es kann auch ruhig ein paar Sekunden dauern, bis ein Lüfter wieder eine aktuelle Drehzahl anzeigt. So schnell muss das nicht aktualisiert werden. Geht nur darum das ganze ein bischen zu loggen und überwachen.
Hat jemand vielleicht schon Code dafür?
Ich habe hier Assemblercode gefunden, aber ich kann kein Stück Assembler...
http://www.stefan-moench.de/pc/avr_lueftersteuerung/avr_lueftersteuerung.htm

Den Prozessor, den ich nutzen möchte ist entweder ein ATMega 16 oder ATMega 32.
Zusätzlich soll noch ein Display (evtl. sogar ein GLCD... hab ich noch rumfliegen ;) ) mit 2-3 Tastern, ein Watchdog (falls sich der Server aufhängen SOLLTE, wird der Resettaster betätigt) und ein UART zur Kommunikation benutzt werden

linux_80
08.08.2006, 12:46
Hallo,
dann könnte man es so machen, den Timer auf eine Sekunde, und alle Eingänge müssten IRQ fähig sein, wie zB. beim M168 oder M644 der ist Pinkompatibel zu M32.
Bei jedem IRQ nur die entsprechende Variable hochzählen, und nach der Sekunde ausrechnen wie oft das war und wieder auf null zurücksetzen.

M16 bzw 32 haben nur 3 ext. IRQ, da könnte man evtl. den ICP des Timer zuhilfe nehmen, ist aber auch nur einer da.
Oder evtl. mal mit T0 und T1 probieren, da zählt der Timer selber,
wären aber dann insgesamt 6 verschiedene Möglichkeiten.
Und den 3. Timer für die Zeitmessung einstellen.

Andy1988
08.08.2006, 13:00
Bei der oben geposteten Lüftersteuerung wird es auch ohne spezielle Anschlüsse gemacht. Der misst immer in einer Schleife. In jedem Schleifendurchlauf einen der 4 Lüfter. Das heisst jeder Lüfter wird immer erst nach 4 Durchläufen gemessen. Das ist allerdings auch das einzige, was ich bisher in dem Code verstanden hab.
Ich kann zu wenig ASM dafür :-k

linux_80
08.08.2006, 14:29
In diesem Programm wird alles per Software gemacht, also Software-PWM, und der Tachoeingang wird auch gepollt, so wie er schreibt alle 50ns.

Laut diesem Schaltplan wären sogar noch 4 Pins frei, da könnte man noch 2 weitere Lüfter dran hängen und das Programm erweitern, mit dem 2313, müsste sich evtl. vom timing auch noch ausgehen.
Da muss man nicht unbedingt einen M16 verwenden, wenn der sonst nix machen soll, reicht der 2313.
Jetzt gibts ja den Tiny2313.

Andy1988
08.08.2006, 14:47
Jaja...
Ich hab aber nur nen M16/32 da ^^

Und da ich die 2 Lüfter noch brauch, den Watchdog und das GLCD haben will, will ich das in C schreiben. Problem is, das ich kein ASM kann und ich nur extrem grob verstehe, wie der Kram da funktioniert.
Evtl. kann mir das einer Übsersetzen? Ein Programmablaufplan oder menschliche Sprache reicht schon ;)
Ich will ja nichtmal regeln... Das ist ein Server, der brauch nicht leise sein. Evtl. wird mir irgendwann mal langweilig und ich mach das auch nochmal, aber jetzt reicht erstmal das rausfinden der Drehgeschwindigkeit.

Reeper
08.08.2006, 14:57
Nun komme ich wieder mit meinem Lieblingsbauteil :cheesy: ----> einen Transistor.

Wenn ich zb. mehrer Servo's per PWM steuern will, unterbreche ich die PWM Leitung mit Transistoren, die ich wiederum mit anderen Ports steuere.
So kann ich beliebig viele Servo's steuern (aber nicht gleichzeitig und mit kurzer Unterbrechung in der "Standkontrolle").
Das gleiche habe ich bei meiner IR-Bake gemacht. So schicke ich 5 verschiedene RC5-Codes zu 5 versch. IR-Led's über nur einen PWM-Ausgang.

Das könnte doch bei dir auch funktionieren, da ja nicht auf ununterbrochene Kontrolle setzt.
Also deinen Code so lassen und nur vorher den entsprechenden Transistor schalten, dann messen. Nun einen anderen Transistor schalten und die anderen "öffnen" und wieder messen lassen usw. O:)

Hanni
08.08.2006, 15:19
Naja .. dafür hab ich doch nen Mikrocontroller ...

Defakto reicht für seine Lüfter nen Mega 48 vollkommen aus. Genügend Interuptfähige Eingänge sind ja vorhanden.

Bluesmash
08.08.2006, 15:40
eventuell könnte es so funktionieren: alle tachosignale mit dioden an den selben interrupt schalten und zusätzlich die tachosignale auf je einen einganspin. und wenn jetzt ein interrupt reinkommt in der isr gucken welches tachosignal den interrupt ausgelöst hat und die jeweilige variable hochzählen...
könnte aber eventuell überschneidungen geben wenn 2 signale gleichzeitig reinkommen... müsste man halt ausprobieren...

gruss bluesmash

dennisstrehl
08.08.2006, 15:50
Ich würde sagen, die Idee von Bluesmash geht schon in die richtige Richtung. Obwohl es doch sauberer ist, den Port dauernd zu pollen...
Man muss dann ja nicht dauernd den Port abfragen, man kann einfach einmal / Sekunde messen, der Rest der Zeit wird zum schreiben der Werte in den SPeicher verwendet.
(Edit: Nächste Idee: Man hängt einfach einen Frequenzteiler 1:16 oder sowas in der Gegend davor, dann kann man schön langsam pollen.)

Dann lässt man nen Timer mitlaufen (am besten wohl 16bit) und schreibt sich am Anfang und nach 10 Pulsen jeweils den Timerwert in den Speicher. Die Differenz aus den Werten kann dann weiterverarbeitet werden.

MfG

Andy1988
11.08.2006, 12:19
Ich habs jetzt mit ner Softwarelösung gebacken bekommen. Allerdings sind die Werte etwas utopisch und auch irgendwie bei jedem Lüfter gleich (einer soll 1100rpm, der andere 1800rpm haben).
Mir ist klar, dass es mehr als einen Impuls pro Umdrehung gibt. Aber das, was ich hier hab is irgendwie ganz komisch. Alle Werte liegen so bei 14500. Schwankt ein wenig, aber das war es auch schon.

Hier ist mein Code:

#include <stdlib.h>
#include <avr/io.h>
#include "lcd.h"

#include <util/delay.h>
#include <avr/interrupt.h>

uint32_t fan1 = 0;
uint32_t fan2 = 0;
uint32_t updated = 0;
uint32_t polled = 0;


/*uint8_t gotSignal(uint8_t pin)
{
if(bit_is_clear(PIND, pin))
{
unsigned char di, dj; // debounce
//for(di = 0; di < 255; di++)
for(dj = 0; dj < 255; dj++);

if(bit_is_clear(PIND, pin))
return 1;
}

return 0;
}*/

uint8_t gotSignal(uint8_t pin)
{
return bit_is_clear(PIND, pin);
}

void update_display(void)
{
updated++;

lcd_clrscr();

lcd_gotoxy(0,0);
lcd_puts("Luefter1: ");
lcd_put_d(fan1);

lcd_gotoxy(0,1);
lcd_puts("Luefter2: ");
lcd_put_d(fan2);

lcd_gotoxy(0,2);
lcd_puts("Updated: ");
lcd_put_d(updated);

lcd_gotoxy(0,3);
lcd_puts("Polled: ");
lcd_put_d(polled);
}

ISR(TIMER2_OVF_vect)
{
polled++;

if(gotSignal(7))
fan2++;

if(gotSignal(6))
fan1++;

if(polled >= 30000) //jede sekunde
{
update_display();
polled = 0;
fan2 = 0;
fan1 = 0;
}

TCNT2 = 0xFA;
}

void start_timer(void)
{
//Polling der Lüfter alle 0,002 sek.
TCCR2 |= (1<<CS21) | (1<<CS20); // Prescaler = 64
TCNT2 = 0xFA; //Counter-Wert auf 250 setzen (vorladen, overflow bei 255)
TIMSK |= (1<<TOIE2); //Interrupt bei Overflow
}

void init_ports(void)
{
DDRD = 0x00; //Eingang
}

int main(void)
{
start_timer();
init_ports();
lcd_init(LCD_DISP_ON); // LCD initialisieren

sei(); //Interrupts an

while(1) {}
}
Ich hab auch mal versucht zu entprellen, aber das geht gar nicht. Dauert viel zu lange. War auch nur ein Verzweiflungsversuch ;)