Forum: Mikrocontroller und Digitale Elektronik Computerlüfter Steuern und Drehzahl messen mit ATmega und Bascom


von Peter K. (pker)


Lesenswert?

Hallo!
Dies ist mein erster Beitrag hier.
Ich möchte 2 12V Computer Lüfter (3 Pol.) mit einem ATmega8 oder 16 
Steuern und deren Drehzahl messen.
Die Lüfter werden über die PWM gesteuert, da ist auch alles klar.
Jetzt hängt es nur noch an der Drehzahl?

Hier die Schaltung die ich anwenden möchte für die Drehzahlmessung:

      VCC vom uC
          |
         10k
          |
Lüfter ---+--- uC-Eingang

Ist das so Korrekt wen das Lüftersignal gegen GND zieht?

Ich habe in einem anderen Beitrag gelesen das ich diese Schaltung zur 
Drehzahlermittlung nur anwenden kann, wenn ich eine "Hi Side PWM" nutze.


Meine eigentliche Frage:
Wie kann ich das Software-technisch mit Bascom Realisieren?
Das Programmieren fällt mir noch ein wenig schwer.
Ich weis das ich die Impulse pro Sekunde zählen muss, Aber wie?

Ein kleines Beispiel währe mir sehr Willkommen!!!

Danke schon mal im voraus!!!

Gruß Peter

von asthelfer (Gast)


Lesenswert?


von sBronco (Gast)


Lesenswert?

Interrupt

von sBronco (Gast)


Lesenswert?

1
' ********  FAN Interrupts
2
   On Int3 FANISR Nosave : Config Int3 = Falling                                ': Enable Int3
3
   On Int2 FANISR Nosave : Config Int2 = Falling                                ': Enable Int2
4
   On Int1 FANISR Nosave : Config Int1 = Falling                                ': Enable Int1
5
   On Int0 FANISR Nosave : Config Int0 = Falling                                ': Enable Int0
6
   On Int7 FANISR Nosave : Config Int7 = Falling                                ': Enable Int7
7
   On Int6 FANISR Nosave : Config Int6 = Falling                                ': Enable Int6

in der FANISR musst Du dann rechnen, 1 Umdrehung 2 Pulse.
Entweder die Zeit zwischen n Umdrehungen oder n Sekunden lang Pulse 
zählen.

von Peter K. (pker)


Lesenswert?

Ist die Schaltung nun i.O. oder nicht ???

von troll (Gast)


Lesenswert?

Ist OK wenn du Highside (Plusleitung) schaltest.

von bb45 (Gast)


Lesenswert?

Hast du getestet ob die Lüfter überhaupt PWM mögen? Ich hab damit keine 
guten Erfahrungen gemacht, die Lüfter haben laute Geräusche von sich 
gegeben.

von Peter K. (pker)


Lesenswert?

#Hast du getestet ob die Lüfter überhaupt PWM mögen?
ja aber ein kondensator hat da abhilfe geschaffen


1
' ********  FAN Interrupts
2
   On Int3 FANISR Nosave : Config Int3 = Falling                                ': Enable Int3
3
   On Int2 FANISR Nosave : Config Int2 = Falling                                ': Enable Int2
4
   On Int1 FANISR Nosave : Config Int1 = Falling                                ': Enable Int1
5
   On Int0 FANISR Nosave : Config Int0 = Falling                                ': Enable Int0
6
   On Int7 FANISR Nosave : Config Int7 = Falling                                ': Enable Int7
7
   On Int6 FANISR Nosave : Config Int6 = Falling                                ': Enable Int6

Das ist für ein Anfänger ziemlich viel wirres zeug was da steht!
Gibt es jemand der mir das etwas genauer erklären kann?

hier schon mal mein bisheriger code:
1
$regfile = "m16def.dat"
2
$crystal = 8000000
3
4
'LCD Config
5
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
6
Cursor Off
7
Cls
8
9
'Port Config
10
Config Pinb.0 = Input
11
Portb.0 = 1
12
Fan1 Alias Pinb.0
13
14
Config Pinb.1 = Input
15
Portb.1 = 1
16
Fan2 Alias Pinb.1
17
18
'Timer und Interupts
19
Config Timer1 = Timer , Prescale = 256
20
Enable Timer1
21
On Timer1 Isr_von_timer1
22
Enable Interrupts
23
Timer1 = 34285
24
25
'Variablen
26
Dim Rpm1 As Word
27
28
'Hauptprogramm
29
Do
30
31
Cls
32
33
Locate 1 , 1
34
Lcd Rpm1 ; " RPM   "
35
Locate 2 , 1
36
Lcd Rpm2 ; " RPM   "
37
38
Wait 1
39
40
Loop
41
42
'ISR von timer1
43
Isr_von_timer1:
44
Timer1 = 34285
45
'#############################
46
'#hier komme ich nicht weiter#
47
'#############################
48
Return
49
End

mir fehlt einfach nur der ansatz wie man das lösen kann!!


gruß
peter

von sBronco (Gast)


Lesenswert?

man kann mit einem Interrupt die Flanke detektieren, das willst du.
so konfiguriert man die Int's bei einem zB Mega128.
was ist da wirr ?

von Hackes (Gast)


Lesenswert?

Wirr ist da z.B., daß er einen Mega16 hat und keinen Mega128. Und der 
hat auch keine 6 Ints.

Prima, nun weiß er, wie beim 128er ganze 6 Ints so definiert werden, daß 
sie sogar in die gleiche ISR führen. Wo liegt da der Sinn?????? Würde 
ich als Anfänger auch nicht verstehen.

@Peter:

Ob deine 34285 für den Timer stimmen, habe ich gerade nicht 
nachgerechnet, kommt mir aber nicht bekannt vor.

Was Du machen solltest, denn Deinem Programm fehlt doch so einiges:

Du willst RPM2 auf das LCD schreiben, hast aber RPM2 nie 
dimensioniert!!!

Da sollte aber der Compiler schon gemeckert haben.

- Lege Deine beiden Tachoimpulse auf INT-Eingänge.
- Dimensioniere zwei Variablen, die bei den entsprechenden INTs 
hochzählen.
- Lege einen Timer an, der z.B. jede Sekunde ausgelöst wird.
- Wenn der Timer auslöst, speicher Dir den Inhalt der beiden Variablen 
weg zum Berechnen.
- Setze die Variablen und den Timer zurück.
- Setze eine Merker-Variable, daß der Timer ausgelöst war.
- Frage die Merker-Variable im Hauptprogramm ab, um die RPM-Berechnung 
auszuführen.
- Lösche die Merker-Variable wieder.
- Durch die beiden Variablen kennst du nun die Anzahl der Lüfterimpulse 
pro Sekunde und damit die Drehzahl.

Versuchs mal!!

von Peter K. (pker)


Lesenswert?

Hallo
Das hört sich sehr amdängerfreundlich an! Danke!
Ich werde es heute Nachmittag gleich ausprobieren!

Gruss
peter

von Peter K. (pker)


Lesenswert?

Hallo!
ich habe das jetzt mal so gemacht wie oben beschrieben.
Und es funktioniert!

Danke Hackes :-)

und natürlich ein dank an alle anderen

hier mein fertiger code:
1
$regfile = "m16def.dat"
2
$crystal = 8000000
3
4
5
'LCD Config
6
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portb.4 , Rs = Portb.3
7
Cursor Off
8
Cls
9
10
11
'Port Config
12
Config Pind.2 = Input
13
Portd.2 = 1
14
Fan1 Alias Pind.2
15
16
Config Pind.3 = Input
17
Portd.3 = 1
18
Fan2 Alias Pind.3
19
20
21
'Timer und interupts
22
Config Timer1 = Timer , Prescale = 256
23
Enable Timer1
24
On Timer1 Isr_timer1
25
Timer1 = 34285
26
27
Config Int0 = Falling
28
Config Int1 = Falling
29
On Int0 Isr_int0
30
On Int1 Isr_int1
31
Enable Int0
32
Enable Int1
33
Enable Interrupts
34
35
36
'Variablen
37
Dim Rpm1 As Word
38
Dim Rpm2 As Word
39
Dim Rpm1_temp As Word
40
Dim Rpm2_temp As Word
41
Dim X As Byte
42
43
44
'Hauptprogramm
45
Do
46
47
If X = 1 Then
48
'werte berechnen
49
Rpm1 = Rpm1 * 30                                            'rpm * 30sek. (weil 2 imputse pro umdrehung)
50
Rpm2 = Rpm2 * 30                                            'rpm * 30sek. (weil 2 imputse pro umdrehung)
51
'werte anzeigen
52
Cls
53
Locate 1 , 1
54
Lcd Rpm1
55
Locate 2 , 1
56
Lcd Rpm2
57
X = 0
58
Wait 1
59
End If
60
61
Loop
62
63
64
'isr von timer1
65
Isr_timer1:
66
67
If X = 1 Then
68
Return
69
End If
70
71
Timer1 = 34285
72
Rpm1 = Rpm1_temp
73
Rpm2 = Rpm2_temp
74
Rpm1_temp = 0
75
Rpm2_temp = 0
76
X = 1
77
Return
78
79
80
'isr von int0
81
Isr_int0:
82
Rpm1_temp = Rpm1_temp + 1
83
Return
84
85
86
'isr von int1
87
Isr_int1:
88
Rpm2_temp = Rpm2_temp + 1
89
Return
90
91
92
'Ende
93
End

Ist wahrscheinlich nicht der Übersichtlichste code aber er funktioniert.
Für Verbesserungsvorschläge habe ich immer ein offenes Ohr!

Gruß Peter

von Hackes (Gast)


Lesenswert?

Hallo Peter,

prima, wenn es geklappt hat. Das freut mich. Habe es wirklich nur 
überflogen, aber grundsätzlich ist es das, was ich meinte.

Unübersichtlich trifft es in der Tat etwas. Mache reichlich Gebrauch von 
der TAB-Taste!
1
'Hauptprogramm
2
Do
3
4
     If X = 1 Then
5
          X = 0                                  'Merker SOFORT löschen
6
7
          'werte berechnen
8
          Rpm1 = Rpm1 * 30                       'rpm * 30sek. (weil 2 imputse pro umdrehung)
9
          Rpm2 = Rpm2 * 30                       'rpm * 30sek. (weil 2 imputse pro umdrehung)
10
          'werte anzeigen
11
          
12
          Cls
13
          Locate 1 , 1
14
          Lcd Rpm1
15
          Locate 2 , 1
16
          Lcd Rpm2
17
          
18
          Wait 1
19
     End If
20
21
Loop

Das ist z.B. MEIN Stil. Muß man nicht zwingend so machen. Man erkennt 
welches LOOP zu welchem DO gehört und welches ENDIF zum IF. Bei den IFs 
finde ich das wichtig. Man erkennt sofort wo mal ein ENDIF fehlt.

Den Merker sollte man direkt löschen, wenn er gesetzt wurde. Habe ich 
mal korrigiert.

Dann ist es sehr unschön, daß es in der Timer-ISR zwei RETURNS gibt. 
Sowas macht man nicht. Zu einem Aufruf sollte es immer genau EIN Return 
geben. Im übrigen ist die Abfrage ob X=1 ist da überflüssig. Die ISR 
wird immer nach genau einer Sekunde aufgerufen. In der Zeit ist X im 
Hauptprogramm ganz sicher schon wieder gelöscht, also null.

Oder ich sehe gerade den Haken nicht.

Wenn Du Timer und INT-ISRs hast, dann ist es wichtig sich klar zu 
machen, wann wird mein Hauptprogramm "unterbrochen". WANN kann WAS 
überhaupt passieren.

So, das war dann die konstruktive Kritik.

Viel Spaß noch beim Programmieren lernen und hier im Forum.

Gruß Hackes

von Peter K. (pker)


Lesenswert?

Hallo!

Danke werde ich mir zu herzen nehmen!

Das mit "if x = 1" habe ich auch schon erkannt!

Das Return aus "timer1_isr" habe ich raus genommen!

Und dein Programmierstil ist sehr Übersichtlich, genau so steht es 
eigentlich auch in meinem Buch.
Aber ich war wahrscheinlich zu faul.

gruß
peter

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.