Forum: Mikrocontroller und Digitale Elektronik Temperaturgesteuerte Lüfterregelung mit ATtiny24 für PC-Gehäuselüfter


von Christian W. (christian_w)


Angehängte Dateien:

Lesenswert?

Hallo zusammen, wie der Titel schon aussagt, entwerfe ich gerade eine 
Temperaturgesteuerte Lüfterregelung für den PC. Und ja, ich weiß solche 
Steuerungen gibt es fertig zu kaufen, aber es geht um die Lust am 
selbermachen :-)

Nun zum Punkt: Ich will mir durch die PWM möglichst keine Störungen auf 
dem Mikrocontroller einfangen, bzw. auch keine Störungen an das 
PC-Netzteil abgeben, und nun wäre die Frage, wie ich das ganze 
Bauteilmäßig dimensionieren sollte. Sinn der ganzen späteren Platine 
soll sein, dass der Lüfter bis zu einer gewissen Gehäusetemperatur, 
meinetwegen 25 oder 30 Grad, auf einem voreingestelltem Wert 
dahinsäuselt, und dann der PWM duty cycle mit steigender Temperatur bis 
100 % erhöht wird.

Ich habe in mühevoller Kleinarbeit das ganze mal auf dem Steckbrett 
aufgebaut, aber da zeigt sich, dass sich zwar der Trimmer ohne Fehler 
auslesen lässt, der für die Grunddrehzahl des Lüfters verantwortlich 
ist, aber der Onboard-Temperatursensor (Philips KTY81-210) macht da 
anscheinend etwas Probleme, offensichtlich fängt sich der ADC-Eingang, 
an dem der Temperatursensor hängt, viele PWM-Störungen ein. Warum auch 
immer. Wenn ich den Lüfter mit dem Finger anhalte, sind die Störungen 
immer noch da. Störungen heißt: Bei Raumtemperatur sollte der ADC-Wert 
um die 510 liegen, wenn ich aber zur Kontrolle den ADCW-Wert auf einem 
freien Portpin ausgebe und nachzähle, liegt der Wert bei einigen 
Tausend. Der Temp-Sensor lässt sich nur dann vernünftig auslesen, wenn 
ich den PWM-Ausgang (OC0A) komplett abschalte, und der Lüfter nicht 
läuft. Am Testpin habe ich dann zwischen 500 und 520 Impulse, je nach 
dem ob ich den Finger auf den Sensor lege, oder nicht... Die Schaltung 
an sich scheint also schonmal zu klappen. Sobald der Lüfter dann 
eingeschaltet ist, kommt nur Rotz und Müll am ADC vom Temperatursensor 
an. Aber: Ist jedoch der PWM-Ausgang auf 100 %, und laut Oszi keine 
"PWM" sondern ein durchgehendes Signal erkennbar, lässt sich der 
Onboardsensor wieder ohne Probleme auslesen und die Störungen am ADC 
Eingang sind weg. Aber es betrifft eben nur den Temp-Sensor-ADC-Pin, 
nicht den Trimmer-ADC-Pin, nur warum...?

Nun die Frage aller Fragen: Verschwinden diese Probleme dann mal später 
auf der fertigen Platine, oder gibt's da ein grundlegendes Problem? Die 
Leitungen sind eh schon sehr kurz.

Wo soll ich mit suchen/verbessern anfangen?

Anbei mal zwei Fotos vom Schaltplan und vom Board-Entwurf.

Danke,

Christian

von Henny (Gast)


Lesenswert?

Hast du schon mal probiert dem ADC eine Stützkapazität zu geben? sagen 
wir mal ein paar hundert nF ?

Mit welcher Frequenz läuft deine PWM?

von Henny (Gast)


Lesenswert?

Christian W. schrieb:
> und dann der PWM duty cycle mit steigender Temperatur bis
> 100 % erhöht wird

verschaltet hast du es so, dass die am ADC gemessene Spannung sinkt, 
wenn die Temperatur steigt. ist das gewollt?

von Thomas D. (thomasderbastler)


Lesenswert?

Mir scheint es so, daß einige Lötpads sehr klein sind.

von Christian W. (christian_w)


Lesenswert?

Henny schrieb:
> Hast du schon mal probiert dem ADC eine Stützkapazität zu geben? sagen
> wir mal ein paar hundert nF ?
Ja, habe ich eben mit verschiedenen Werten getestet, leider keine 
Veränderung


Henny schrieb:
> Mit welcher Frequenz läuft deine PWM?
Der Timer läuft mit einem Prescaler von 2, das wären dann 15625 Hz.


Henny schrieb:
> verschaltet hast du es so, dass die am ADC gemessene Spannung sinkt,
> wenn die Temperatur steigt. ist das gewollt?
Nein eigentlich nicht gewollt, aber das lässt sich ja Softwareseitig 
einfach auswerten.


Thomas der Bastler schrieb:
> Mir scheint es so, daß einige Lötpads sehr klein sind.
Bei den Widerständen usw. meinst du? Bisher hat das Löten mit kleiner 
Lötspitze immer gut geklappt.

Grüße,

Christian

von tom69 (Gast)


Lesenswert?

Hallo,
R2 ist zu klein, mach da mal >200 Ohm rein

von Henny (Gast)


Lesenswert?

Was passiert, wenn du den KTY mal durch einen 2kOhm Widerstand ersetzt?

Wie sieht die Software zum Einstellen des ADC's aus?

von Karl H. (kbuchegg)


Lesenswert?

> wenn ich aber zur Kontrolle den ADCW-Wert auf einem freien Portpin ausgebe und 
nachzähle, liegt der Wert bei einigen Tausend.

Bei einigen Tausend?

Das kann nicht sein.
Da hast du einen Programmfehler.
Der Wert kann nicht größer als 1023 werden.

von Christian W. (christian_w)


Lesenswert?

Ich habe den Gatewiderstand mal von 10 Ohm auf 220 Ohm vergrößert, und 
siehe da, die Störungen sind schon deutlich geringer, und der KTY-Sensor 
lässt sich, zumindest jetzt schon jedes 2. Mal, fehlerfrei auslesen. Ich 
probier gleich noch mal einen 470er.

Hier mal der Entwurf vom kompletten Programm.
1
// Definitionen
2
// ------------
3
#define FAN_PORT  PORTB
4
#define FAN_PIN    PB2
5
#define F_CPU    8000000UL
6
7
8
#include <avr/io.h>
9
#include <util/delay.h>
10
11
12
// ADC initialisieren
13
// ------------------
14
void Init_ADC(void)
15
{
16
  // ADC Prescaler 2
17
  ADCSRA |= (1<<ADPS0);
18
  
19
  // ADC einschalten
20
  ADCSRA |= (1<<ADEN);
21
  
22
  // Erste Konvertierung starten
23
  ADCSRA |= (1<<ADSC);
24
  
25
  // Warten, bis Konvertierung beendet
26
  while(ADCSRA & (1<<ADSC))
27
  {
28
    // ...
29
  }
30
}
31
32
33
// PWM-Ausgang PB2 initialisieren
34
// ------------------------------
35
void Init_PWM(void)
36
{
37
  // OC0A bei Compare Match aus
38
  TCCR0A |= (1<<COM0A1);
39
  
40
  // Waveform Generation Mode 7, Fast PWM
41
  TCCR0A |= (1<<WGM00);
42
  TCCR0A |= (1<<WGM01);
43
  TCCR0A |= (1<<WGM02);
44
  
45
  OCR0A = 0;
46
  TCNT0 = 0;
47
}
48
49
50
// PWM on/off
51
// ----------
52
void Status_PWM(unsigned char status)
53
{
54
  // Timer/Counter 0 Prescaler, einschalten/ausschalten
55
  if (status)  TCCR0B |= (1<<CS00);
56
  if (!status) TCCR0B &=~(1<<CS00);
57
}
58
59
60
// Lüfter initialisieren
61
// ---------------------
62
void Init_FAN(void)
63
{
64
  // Kurzzeitig auf Vollgas als Anlaufhilfe und Staubbeseitigung
65
  FAN_PORT |= (1<<FAN_PIN);
66
  for (uint16_t pause=0; pause<5000; pause++) _delay_ms(1);
67
  FAN_PORT &=~(1<<FAN_PIN);
68
}
69
70
71
// ADC abfragen (Temperatursensor extern)
72
// --------------------------------------
73
uint16_t Read_Ext_Temp_Sens(void)
74
{
75
  // VCC-Referenz und PA0
76
  ADMUX = 0b00000000;
77
  
78
  // Mehrere Konvertierungen durchführen, um Störungen auszubügeln
79
  uint16_t adcsumme = 0;
80
    
81
  for(unsigned char i=0; i<10; i++)
82
  {
83
    // Konvertierung starten
84
    ADCSRA |= (1<<ADSC);
85
    
86
    // Warten, bis Konvertierung beendet
87
    while(ADCSRA & (1<<ADSC))
88
    {
89
      // ...
90
    }
91
    
92
    // Ergebnis zum Gesamtwert hinzufügen
93
    adcsumme += ADCW;
94
  }
95
96
  // Durchschnittswert bilden, umkehren, und zurückgeben
97
  return 1023 - (adcsumme / 10);
98
}
99
100
101
// ADC abfragen (Temperatursensor intern)
102
// --------------------------------------
103
uint16_t Read_Int_Temp_Sens(void)
104
{
105
  // Interne 1.1-V-Referenz und ADC8
106
  ADMUX = 0b10100010;
107
  
108
  // Mehrere Konvertierungen durchführen, um Störungen auszubügeln
109
  uint16_t adcsumme = 0;
110
  
111
  for(unsigned char i=0; i<10; i++)
112
  {
113
    // Konvertierung starten
114
    ADCSRA |= (1<<ADSC);
115
    
116
    // Warten, bis Konvertierung beendet
117
    while(ADCSRA & (1<<ADSC))
118
    {
119
      // ...
120
    }
121
    
122
    // Ergebnis zum Gesamtwert hinzufügen
123
    adcsumme += ADCW;
124
  }
125
  
126
  // Durchschnittswert bilden, und zurückgeben
127
  return (adcsumme / 10);
128
}
129
130
131
// ADC abfragen (Trimmer)
132
// ----------------------
133
uint16_t Read_Trimmer(void)
134
{
135
  // VCC-Referenz und ADC5
136
  ADMUX = 0b00000101;
137
138
  // Mehrere Konvertierungen durchführen, um Störungen auszubügeln
139
    uint16_t adcsumme = 0;
140
  
141
    for(unsigned char i=0; i<10; i++)
142
    {
143
      // Konvertierung starten
144
      ADCSRA |= (1<<ADSC);
145
      
146
      // Warten, bis Konvertierung beendet
147
      while(ADCSRA & (1<<ADSC))
148
      {
149
        // ...
150
      }
151
      
152
      // Ergebnis zum Gesamtwert hinzufügen
153
      adcsumme += ADCW;
154
    }
155
  
156
  // Durchschnittswert bilden, umkehren, und zurückgeben
157
  return 1023 - (adcsumme / 10);
158
}
159
160
161
// PWM Duty Cycle festlegen 
162
// ------------------------
163
void Set_PWM_Duty_Cycle(unsigned char n)
164
{
165
  // Output Compare Register beschreiben (0 - 255)
166
  OCR0A = n;
167
}
168
169
170
// Hauptprogramm
171
// -------------
172
int main(void)
173
{
174
  // Ausgang PB2 MOSFET
175
  // Ausgang PB0 Testpin (Ticks)
176
  // Ausgang PB1 Testpin (Reset)
177
  DDRB = 0b00000111;
178
    
179
  // Pause...
180
  for (uint16_t pause=0; pause<1000; pause++) _delay_ms(1);
181
  
182
  // Lüfter initialisieren
183
  Init_FAN();
184
  
185
  // ADC initialisieren
186
  Init_ADC();
187
  
188
  // PWM initialisieren, einschalten
189
  Init_PWM();
190
  Status_PWM(1);
191
  
192
  while(1)
193
    {    
194
    // Einfluss des OnBoardTempSens auf PWM-Regelung
195
    
196
      // Temperatur  ADCW  
197
      // ab 20    501    
198
      // ab 30    522    
199
      // ab 40    541    
200
      // ab 50    560    
201
      
202
      // Bis zu einem ADC-Wert von 511 (unter 25 °C) holt sich die PWM-Regelung die "Drehzahl" von der Trimmereinstellung, und der OnBoardTempSens hat keinen Einfluss. 
203
      // Ab einem ADC-Wert von 512 (25 °C) "übernimmt" der OnBoardTempSens die PWM-Regelung.
204
      // Ab 25 °C: Dem gemessenen ADC-Wert werden 512 abgezogen, und die Differenz mit 2 multipliziert, und dieser Wert dem Trimmerwert aufaddiert. 
205
      
206
      // Beispiel: ADC-Wert 522. 30 °C. 522 - 512 = 10. 10 * 2 = 20. Minimal-Trimmerwert = 5 %. 5 + 20 = 25. PWM-Wert bei 30 °C = 25 % (oder höher, je nach Trimmerposition). 
207
      // Beispiel: ADC-Wert 541. 40 °C. 541 - 512 = 29. 29 * 2 = 58. Minimal-Trimmerwert = 5 %. 5 + 58 = 63. PWM-Wert bei 40 °C = 63 % (oder höher, je nach Trimmerposition). 
208
      // Beispiel: ADC-Wert 560. 50 °C. 560 - 512 = 48. 48 * 2 = 96. Minimal-Trimmerwert = 5 %. 5 + 96 entspricht 100. PWM-Wert bei 50 °C = 100 %.
209
    
210
    // Trimmer auslesen
211
    uint16_t trimmerwert = Read_Trimmer();
212
    
213
    // Mindestdrehzahl festlegen (5 % PWM), da ansonsten der Fan bei Trimmer-Linksanschlag stehenbleibt 
214
    if(trimmerwert < 51) trimmerwert = 51;
215
    
216
    // Update von OCR, "umwandeln" von 10 auf 8 bit (1023 entspricht 255)
217
    Set_PWM_Duty_Cycle(trimmerwert / 4);
218
    
219
    // Warten, um nervöse Drehzahländerungen zu eliminieren...
220
    for (uint16_t pause=0; pause<2000; pause++) _delay_ms(1);
221
    
222
        // Debug: Reset des externen Impulszählers
223
        PORTB &=~(1<<PB1); _delay_ms(10);
224
        PORTB |= (1<<PB1); _delay_ms(10);
225
        
226
        // Debug: Ausgabe auf den externen Impulszähler
227
        uint16_t tempsens = Read_Ext_Temp_Sens();
228
        for(uint16_t ausgabe=0; ausgabe < tempsens; ausgabe++)
229
        {
230
          PORTB &=~(1<<PB0); _delay_us(10);
231
          PORTB |= (1<<PB0); _delay_us(10);
232
        }
233
        
234
    // Pause...
235
    for (uint16_t pause=0; pause<2000; pause++) _delay_ms(1);
236
        
237
    }
238
}

von Christian W. (christian_w)


Lesenswert?

Update: Eben einen 470-Ohm Widerstand am Gate probiert, bringt leider 
auch nix. Hat das eventuell was damit zu tun, dass am ADC0 vom ATtiny24 
zugleich auch AREF liegt? Ist zwar intern ausgeschaltet, aber würde 
eventuell erklären, warum der Trimmer an ADC5 einwandfrei ausgelesen 
werden kann... Ich habe jetzt mal den KTY Sensor von ADC0 auf ADC1 
gelegt, und die Störungen wurden wieder etwas weniger, nun sind nur noch 
bei jeder 10. Messung Fehler, da springt der Wert plötzlich von 510 auf 
261 oder sonstwas runter. Hab auch noch einen KTY81-220 probiert, 
derselbe Fehler.

Mal eine ganz andere Idee: Würde es etwas bringen, wenn ich die 
Gate-Ansteuerung durch einen Optokoppler vom Controller-Pin trenne?

: Bearbeitet durch User
von tom69 (Gast)


Lesenswert?

Christian W. schrieb:
> Mal eine ganz andere Idee: Würde es etwas bringen, wenn ich die
> Gate-Ansteuerung durch einen Optokoppler vom Controller-Pin trenne?

Normal bringt das nichts.

Wie hoch ist deine PWM-Frequenz?

Kommt der Mess-Fehler auch, wenn du R2 raus nimmst?

von Karl H. (kbuchegg)


Lesenswert?

Christian W. schrieb:

> Hat das eventuell was damit zu tun, dass am ADC0 vom ATtiny24
> zugleich auch AREF liegt?


Ist im Datenblatt etwas versteckt. Aber
1
Internal voltage reference options may not be used if an external
2
voltage is being applied to the AREF pin.

und im Anhang
1
AREF: External Analog Reference for ADC. Pullup and output driver
2
      are disabled on PA0 when the pin is used as an external
3
      reference or Internal Voltage Reference with external
4
      capacitor at the AREF pin by setting (one) the bit REFS0
5
      in the ADC Multiplexer Selection


> werden kann... Ich habe jetzt mal den KTY Sensor von ADC0 auf ADC1
> gelegt,

und jetzt hängst du noch 100nF gegen Masse an AREF.

: Bearbeitet durch User
von Christian W. (christian_w)


Lesenswert?

tom69 schrieb:
> Wie hoch ist deine PWM-Frequenz?

Die Frequenz liegt um die 32 kHz. Geringere Werte habe ich auch schon 
getestet, aber da gibt der Lüfter ein ekelhaftes Pfeifen von sich. Der 
Fehler bleibt aber.


Karl Heinz schrieb:
> und jetzt hängst du noch 100nF gegen Masse an AREF.

...und siehe da, es gibt keine Auslesefehler mehr.

Danke :-)

von Harald (Gast)


Lesenswert?

Zu deinen aktuellen EMV Problemen möchte ich nichts beitragen, aber 
vielleicht darf ich ja eine Anregung für ein Redesign machen.

1. Verwendung eines 4-pin Lüfters, diese sind wesentlich gedeihlicher 
anzusteuern als die klassische PWM Grütze
http://www.formfactors.org/developer%5Cspecs%5CREV1_2_Public.pdf

2. Verwendung eines besseren Temperatursensors, entweder analog der LM75 
oder digital so etwas wie der DS18B20

EMV-Probleme wirst Du mit diesem Ansatz kaum haben, darüber hinaus wird 
die Gesamtschaltung etwas kleiner.

von Christian W. (christian_w)


Lesenswert?

Harald schrieb:
> 1. Verwendung eines 4-pin Lüfters, diese sind wesentlich gedeihlicher
> anzusteuern als die klassische PWM Grütze
> http://www.formfactors.org/developer%5Cspecs%5CREV1_2_Public.pdf
Werd ich mal im nächsten Projekt testen. Danke.
Warum besser anzusteuern? Laufen ja auch mit PWM...

von Harald (Gast)


Lesenswert?

Bei einem klassischen 2(3)-Pin Lüfter erzeugt man eine variable 
Spannung, die den Lüfter "irgendwie" undefiniert langsamer laufen lässt. 
Wann der Lüfter tatsächlich anläuft oder stehen bleibt ist nicht nur 
modellabhängig sondern unterliegt auch noch der Serienstreuung, 
Alterung, Dreck, Temperatur, etc.

Bei einem 4-pin Lüfter gibt man über die (unbelastete) 25kHz PWM nur die 
Solldrehzahl vor, die Ansteuerung des eigentlichen Motors macht die 
Lüfterelektronik. Das Verhalten ist dabei recht genau und vor allem 
reproduzierbar unabhängig von obigen Einflüssen. Man braucht auch hier 
keinen MOSFET, die PWM kann man direkt per Portpin ausgeben.

von Christian W. (christian_w)


Lesenswert?

Achso...

Übrigens: Ich habe den Prescaler vom ADC nochmal angepasst, und statt 
einem Vorteiler von 2 verwende ich jetzt 128, damit sind jetzt praktisch 
keine Störungen mehr feststellbar und die Analogwerte werden einwandfrei 
ausgelesen.

von tom69 (Gast)


Angehängte Dateien:

Lesenswert?

Habe mir vor längerer Zeit auch wegen nerviger Lüfter Lautstärke ein 
neues  „Silent PC-Netzteil“ zugelegt.  Mein PC (i5 ohne extra GK) 
benötigt im Leerlauf ~25W unter Volllast ca. ~100W.
Die Lüfter Regelung bläst wie ein Föhn und ist trotz 140mm Lüfter gut 
hörbar.
Bei der Überprüfung hab ich festgestellt, dass der Lüfter beim 
einschalten und 20°C schon 9,5V bekommt. Nach weiteren 5 min.  sind es 
dann schon 11V. Der Messfühler ist in einer der Netzteil Sek.-Drossel / 
5V Zweig eingeklebt. Diese wurde in meinem Fall nicht wärmer als 24°C.
Hab ein paar Messungen zum Lüfter angestellt. Unhörbar ist er bis ca. 
6V, wobei er schon ordentlich Luft schaufelt.
Meine Temperatursteuerung regelt hinunter bis 4V bei <=23°C und hoch bis 
12V bei 45°C. Beim Einschalten bekommt der Lüfter für 5 sec. 12V (Das 
soll mich an das ursprüngliche Geräusch erinnern;-) , dann wird 
innerhalb von 2 min. Auf den Sollwert ab-geregelt.
Bin jetzt mit der neuen Geräuschsituation voll zufrieden.
Zu Einsatz kam ein PIC mit PWM → Analog OP Mosfet Regelung

Im Anhang noch ein paar Daten / Messwerte zum 140mm NT-Lüfter wenn es 
jemanden Interessieren sollte.

MfG

von Christian W. (christian_w)


Angehängte Dateien:

Lesenswert?

tom69 schrieb:
> Die Lüfter Regelung bläst wie ein Föhn und ist trotz 140mm Lüfter gut
> hörbar.

Bei mir auch, ich bin nach etwas Suchen auch dahintergekommen, dass den 
meisten Lärm der Fan produziert, der eigentlich aufgrund der Größe am 
leisesten sein sollte. Ist aber nicht so. Der im Vergleich dazu winzige 
CPU-Fan ist im Leerlauf so gut wie unhörbar.

Ich habe die letzten zwei Tage noch etwas am Schaltplan herum-designt, 
und das Layout von der Platine nochmal komplett überarbeitet. Unter 
anderem gibt es jetzt drei getrennte Masseflächen, damit mir der 
EMV-Geist nicht herum-spuken kann, und die MOSFET-Ansteuerung ist über 
einen Optokoppler realisiert, da mir laut Oszi der µC-Pin zu sehr 
gelitten hat, das Signal war da ziemlich verzerrt.

Anbei mal der neue Schaltplan und das Boardlayout, mit der Bitte um 
Beurteilung. Danke!

Frage 1: Wie verbinde ich die Masseflächen GND und AGND? (Am Pin 14 von 
Controller, rechts oben) Ich habe das durch eine kurze Brücke auf dem 
Top-Layer gelöst, ist aber wahrscheinlich auch nicht das gelbe vom Ei, 
weil wenn ich beim Ausdrucken den Top-Layer vergesse, ist auch die 
Brücke nicht da. Gibt's da elegantere Lösungen zum Masseflächen 
verbinden?

Frage 2: Muss an AREF VCC? Ich hab Pin 1 und 13 gebrückt.

Grüße,

Christian

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.