Hallo, Möchte Zwei Papst Lüfter 12V 5,3 Watt Multifan 4212 2GH über ein Atmel ein und ausschalten, dafür nutze ich ein BC und lass diesen dann die 12V Durchschalten, wenn der Atmel 0V oder +5V liefert das klappt. Aber wie kann ich nun vom Gelben Kabel (Schwarz Masse, Rot Plus, Gelb Tacho) die Drehzahl messen und auf meinem LCD anzeigen lassen? Kann mir jemand vielleicht paar Beispiele nennen? Hab zwar schon gesucht, aber ich will ja nicht den Lüfter Steuern sondern lediglich die Drehzahl herausfindren. Wäre super Nett Danke! Daniel
Ich bin mir da zwar nicht ganz sicher, aber ich glaube pro Umdrehung bekommst du ein 12V Puls auf die Tacholeitung. Dann musst du das ganze nur noch über ein 20k-Widerstand auf ein Pin deines µC-legen. Und die Anzahl der Pulse innerhalb einer Zeit auswerten und danach das ganze auf einem LCD-Ausgeben. Gruß Steven
Prima, danke.. Hab ich ne Chance mit nem Multimeter das auf der Leitung ohne Oszi zu messen? Die Pulsabstände lassen sich ja bestimmt mit nem Timer lösen oder hat mir da jemand ein Vorschlag?
>Hab ich ne Chance mit nem Multimeter das auf der Leitung ohne Oszi zu >messen? Mit einer Frequenzmessung und einer kleinen Umrechnung ist das wohl möglich. Ja Timer ist wohl das beste. Also ich würde Vorschlagen eine Sek. lang die Pulse zählen und danach mal kurz ausgeben (LCD). MfG Steven
Der Tacho-Pin bei PC-Lueftern ist Open-Collector, für die Papst Teile sollte ein Blick in das Datenblatt helfen. Es wird also immer gegen GND geschaltet und Pegel mit einem Pullup-Widerstand "erzeugt", ein paar kilo-Ohm gegen 5V zum Beispiel. Ein Standard PC-Lüfter macht zwei Impulse pro Umdrehung. Und wenn man zählt, wie viele Impulse pro 0,3 Sekunden kommen, hat man direkt die Umdrehungen pro Minute. 22 Impulse pro 0,3 Sekunden bei 2 Impulsen pro Umdrehung = 2200 Umdrehungen pro Minute Nochmal filtern durch Mittelwert-Bildung und die Anzeige wird stabil.
schaue dir einmal den Anhang Seite 90 an, dort ist alle beschrieben was du suchst.
Danke, Also ich Hänge an mein Tachosignal Kabel (Gelb) 1x 20k Widerstand dran, klemme diesen dann ein einen bebliebig freien Port eines Atmega, ich nehme wohl an das der Ground vom Lüfter ebenfalls mit dem GND des Atmels beschaltet werden muss.. richtig?
Prima Danke ;-) So Nun klappt die Ausgabe bereits per UART, nur stellt sich mir die Frage wie ich die Funktion Realisiere, gibts irgendwo einen Verwendbarencode oder ansätze für avr-gcc? Danke
Kann mir denn niemand einen Anstoss geben oder Infos wo Ich diesbezügl. was finde? Brauch ich den ADC um die Impulse zu messen oder wie mess ich denn das generell?
Mein Lüfter hängt nun an einem ATMega 16, Meine Tacholeitung an einem 20K Widerstand an PA6 mit aktiviertem Pull Up Widerstand. Wie kann ich nun weiter machen oder PA6 auslesen??
Daniel wrote: > Mein Lüfter hängt nun an einem ATMega 16, Schön, da habe ich auch zwei Stück dran. > Meine Tacholeitung an einem 20K Widerstand an PA6 mit aktiviertem Pull > Up Widerstand. Was meinst Du damit? 20k in Reihe? Das wäre dann nicht so geschickt. > Wie kann ich nun weiter machen oder PA6 auslesen?? An PAx gibt es nicht viele Möglichkeiten. Analog macht keinen Sinn, also bleibt nur, den Port zu pollen. Das habe ich vor Jahren mal so gemacht: [code] while(1) { data_new = PIND; // read data from PORTD // count pulses per 0.3s to determine the RPM of fan0 if(data_new & (1<<PIND5)) // check if PD5 is high { if((data_old & (1<<PIND5)) == 0) // if it was low before ... { data_old |= (1<<PIND5); fan0_counter++; // ...we detected a new pulse } } else { data_old &= ~(1<<PIND5); } ... [code] Dazu gehört noch ein Timer-Interrupt der alle 300 ms den Wert von fan0_counter in einen 8-Byte Ringpuffer kopiert und fan0_counter wieder auf Null setzt. Aus diesem Ringpuffer wird dann im weiteren Verlauf ein Mittelwert gebildet und ausgegeben, sowie für eine einfache Regelung benutzt. Naja, das habe ich gemacht, weil ich zwei Lüfter und einen Drehimpulsgeber mit Taster habe, zusammen fünf digital I/O's die ich in der Hauptschleife so schnell sie eben durchläuft immer wieder einlese. Mit nur einem Lüfter kannst Du auch die Input-Capture Einheit von Timer 1 benutzen. Alternativ könnte man auch INT0...INT2 benutzen um Ereignisse zu zählen, dann bräuchte man aber wiederrum einen Timer um diesen Ereignissen eine Zeitbasis zu geben.
Hallo, Danke für deine antwort ;-) An welchen Port wäre es den am besten das Tacho Signal anzuschließen? Der atmega bietet ja schon viel ;-) leider kenn ich mich in dem Thema mit Tachosignal und so nich wirklich so gut aus :( Ja sind 2x 10K Widerstände hintereinander gelötet. Daniel
>An welchen Port wäre es den am besten das Tacho Signal anzuschließen? Kommt darauf an, wie Du das Problem lösen möchtest. >Der atmega bietet ja schon viel ;-) leider kenn ich mich in dem Thema >mit Tachosignal und so nich wirklich so gut aus :( Naja, ist ein Rechteck, 2 Impulse pro Umdrehung meistens. >Ja sind 2x 10K Widerstände hintereinander gelötet. Macht mal ein Bild wie Du das angeschlossen hast.
So, Hab nun mal flüchtig in Eagle gezeichnet wie ich aktuell den Lüfter und das Signal an den ATmega16 angeschlossen habe. Oder muss ich mein Signal mittels 1x 10k auf GND setzen und dann mit 1x10K an den PA7 ?
Hab aktuell folgenden Code gebastelt:
1 | #include <stdlib.h> |
2 | #include <avr/interrupt.h> |
3 | #include <avr/io.h> |
4 | #include <avr/pgmspace.h> |
5 | #include "lcd_lib.h" |
6 | #include "debounce_keys.h" |
7 | |
8 | volatile uint8_t time = 0; //time = Zeit zwischen 2 impulsen |
9 | volatile uint8_t i = 0; //zähler |
10 | char buffer[20]; //buffer |
11 | |
12 | int main(void) |
13 | {
|
14 | TCCR0 |= (1<<CS00) | (1<<CS02); // Timer CPU-Takt / 1024 |
15 | |
16 | /* initialize display, cursor off */
|
17 | lcd_init(LCD_DISP_ON); |
18 | |
19 | KEY_DDR &= ~ALL_KEYS; // konfigure key port for input |
20 | KEY_PORT |= ALL_KEYS; // and turn on pull up resistors |
21 | |
22 | TCCR0 = (1<<CS02)|(1<<CS00); // divide by 1024 |
23 | TIMSK = 1<<TOIE0; // enable timer interrupt |
24 | |
25 | LED_PORT = 0xFF; |
26 | LED_DDR = 0xFF; |
27 | |
28 | sei(); |
29 | |
30 | lcd_clrscr(); |
31 | lcd_puts("Willkommmen!\n"); |
32 | |
33 | lcd_puts("Drehzahl: "); |
34 | |
35 | |
36 | DDRA &= ~ (1 << DDA6); |
37 | PORTA |= (1 << PA6); |
38 | |
39 | for (;;) { /* loop forever */ |
40 | loop_until_bit_is_set(PINA, PA6); |
41 | TCNT0 = 0; |
42 | loop_until_bit_is_clear(PINA, PA6); |
43 | loop_until_bit_is_set(PINA, PA6); |
44 | time = TCNT0; |
45 | i++; //zähler + 1 |
46 | |
47 | if(i > 50) |
48 | {
|
49 | i = 0; |
50 | |
51 | itoa(time, buffer, 10); |
52 | lcd_gotoxy(5,3); |
53 | lcd_puts(buffer); |
54 | }
|
55 | |
56 | |
57 | |
58 | }
|
59 | }
|
Nun erhalte ich die Ausgabe auf dem LCD von: 74 oder 75, halte ich den Lüfter per Hand an schnellt die Zahl auf 248... was gibt er mir da aus?
Nochmal, im Lüfter ist ein Transistor der gegen GND geschaltet wird. Eventuell kommt man ohne nur mit den internen Pullup's hin. Edit: die verwendeten LCD Funktionen sind mit ziemlicher Sicherheit für die Anwendung ungeeignet, da diese ordentlich Zeit verbrennen durch den Aufruf von _delay_ms() - Zeit in der Du keinen Impuls messen kannst.
Muss der Ventilator so angeschlossen wie in deinem Schaltplan? Sorry, sagte ja hab bisher nicht mit sowas gearbeitet, dafür mit ADC etc.. Wie schauts den mit dem Capturing (ICP1) vom Atmega aus könnte man da was basteln?
Daniel Steiner wrote: > Muss der Ventilator so angeschlossen wie in deinem Schaltplan? Ja, der mittlere Pin ist noch der Versorgungs-Anschluss des Lüfters. Und die 33nF sind so aus "Gefühl" mit drin um das Signal ein wenig runder zu machen. > Sorry, sagte ja hab bisher nicht mit sowas gearbeitet, dafür mit ADC > etc.. > > Wie schauts den mit dem Capturing (ICP1) vom Atmega aus könnte man da > was basteln? Sicher, davon hat der Mega16 aber - und auch wohl sonst jeder Mega - nur einen. Das habe ich aber auch bereits geschrieben... Du kannst ja auch mal nach einem Frequenz->Spannungs Umsetzer IC suchen, wenn Du da was passendes findest, kannst Du den ADC benutzen.
hi daniel, dein programm ist ja schon mal gar nicht so schlecht. ich wuerde das ganye mal so versuchen: * Timer initalisieren auf Overflow nach 0,3s und den Overflow interrupt aktivieren * globale volatile variable in der du dir die ticks per Interval und eine fuer ein flag 'data ready' * in der main schleife pins pollen und mit jeder high->low flanke variable incrementieren. Wenn data ready interrupts disablen und count variable * 100 anzeigen. data ready flag loeschen und count variable 0. interrupts aktivieren. falls noch andere interrupts im spiel sind natuerlich nur den timer overflow interrupt disablen * im timer overflow data ready setzen und eventuell timer count register initialisieren wenn du willst kannst du das intervall auch nach oben oder nach unten aendern musst dann halt den multiplikator anpassen. zum stabilisieren des wertes koenntest du auch noch eine mittelwertsbildung ueber mehrere intervalle machen. in c sieht das dann ungefaehr so aus:
1 | /* includes etc hier */
|
2 | |
3 | #define CNT_OFFSET (timer offset)
|
4 | |
5 | volatile uint8_t rpm1; |
6 | volatile uint8_t dataready; |
7 | |
8 | ISR (TIMER0_OVF_vect) { |
9 | dataready = 1; |
10 | TCNT0 = CNT_OFFSET; |
11 | }
|
12 | |
13 | int
|
14 | main (void) { |
15 | uint8_t tmp; |
16 | |
17 | /* set counter prescaler und enable timer interrupt
|
18 | ....
|
19 | */
|
20 | |
21 | /* init PORT pullup enable, input
|
22 | ....
|
23 | */
|
24 | |
25 | TCNT0 = CNT_OFFSET; |
26 | |
27 | sei(); |
28 | |
29 | while (1) { |
30 | if (((PINX & (1 << PX0)) ^ tmp)) && (!(PINX & (1 << PX0)))) { |
31 | /* sollte ein high->low transit sein */
|
32 | rpm1++; |
33 | }
|
34 | if (dataready) { |
35 | cli(); |
36 | |
37 | /* lcd ausgabe hier */
|
38 | |
39 | dataready = 0; |
40 | rpm1 = 0; |
41 | sei(); |
42 | }
|
43 | tmp = PINX & (1 << PX0); |
44 | }
|
45 | }
|
koennte funktionieren, habs nicht ausprobiert. gruss marc
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.