Einleitung
Es geht darum eine temperaturgesteuerte Lüftersteuerung zu bauen. Die Grundidee ist vorhandene Bauteile zu verwenden und folgenden Aufbau zu realisieren:
Das ATX-Netzteil liefert die benötigten Spannungen (+5V Standby, +12V Zuschaltbar). Arduino liest die Daten vom Temperatursensor und stellt sie auf der 7-Segmentanzeige immer dar. Bei Bedarf (eingestellte Temperatur) wird das Netzteil und die Lüfter eingeschaltet.
Gesamtprojekt
Zuerst werden die einzelnen Komponenten Arduino-Fähig gemacht. D. h. das Netzteil wird so umgebaut, dass es gesteuert werden kann. Für die 7-Segmentanzeige bräuchte man 14 Anschlüsse. Deswegen wird auch dieses Element anders angesteuert. Die Lüfter laufen mit 12V und wir wollen sie mit 5 Volt ein/ausschalten. Auch hier brauchen wir etwas Elektronik. Zu guter Letzt soll der Temperatursensor auch irgendwie ausgelesen werden können.
Das Projekt ist mit einem Arduino Uno entwickelt worden aber darauf ausgelegt auf einem Atmega8 zu laufen, weil es kostengünstiger ist.
Netzteil umbauen
Wie man ein ATX-Netzteil mit dem Arduino ein- und wieder ausschalten kann, werde ich hier nicht näher beschreiben. Dafür gibt es unzählige Anleitungen um Internet. Im Prinzip sucht man nach dem “Power Supply On”-Draht und schliesst es direkt an einen digitalen Ein-/Ausgang. An dieser Leitung fliesst sehr kleiner Strom, deswegen kann man dies so einfach machen. Wer sich absichern möchte, kann noch ein Widerstand dazwischen legen. Gespeist wird der Arduino über die +5V Standby-Leitung des Netzteils. Wie der Name schon sagt, liegen dort immer (aus im ausgeschaltetem Zustand) +5V an.
In den meisten Netzteilen gibt es genug Platz um neue Anschlüsse legen zu können. In meinem Fall habe ich auch die ganze Platine dort untergebracht. Das serielle Kabel habe ich für die LCD-Anzeige nach aussen verlegt. Für die Lüfter gibt es zwei separate Anschlüsse und einen digitalen Ausgang habe ich direkt nach Aussen gebracht um vielleicht spätere Erweiterungen leicht realisieren zu können.
7-Segmentanzeige ansteuern
Mit dem 8 Bit Shift Register 74HC595 lassen sich die digitalen Ports vom Arduino sparen.
Die Funktionsweise werde ich nicht näher erläutern, da es dafür etliche Informationen im Internet gibt. Folgende kann ich empfehlen:
Lüfter schalten
Die Lüfter sollen über BC547 Transistoren separat geschaltet werden. Die Transistoren werden als Schalter und nicht als Verstärker verwendet. Dafür folgender Aufbau:
Für mehrere Lüfter entweder weitere Digitalausgänge benutzen und die Schaltung kopieren oder einen TIP120 Darlington Transistor benutzen.
Temperatur auslesen
DS18B20 Digitalthermometer über 1-Wire auslesen. Dieser Chip kann sehr günstig aus Fernost bestellt werden und ist sehr leicht auszulesen. Der Pullup Widerstand ist 4,7kOhm.
Programm
1/********************************************************
2** Fan-Controll
3** Download from: http://wissensdurst.homeip.net
4*********************************************************
5** Reads temperature value from sensor
6** Optinal setting the switching level with a potentiometer
7** If the temperature rises over the switching level,
8** turns on the power supply and fans 1-3
9** Under the switching level turns the power supply and fans off
10** Display actual temperature value all the time
11*********************************************************/
12#include <AH_74HC595.h>
13#include <DallasTemperature.h>
14#define FAN_PIN3 13
15#define FAN_PIN2 12
16#define FAN_PIN1 11
17#define PWR_ON 10
18#define ONE_WIRE_BUS 9
19#define LED1 5
20#define POTI 1
21#define DEFAULT_TEMP 20
22
23// Setup a oneWire instance to communicate with any OneWire devices
24OneWire oneWire(ONE_WIRE_BUS);
25
26// Pass our oneWire reference to Dallas Temperature.
27DallasTemperature sensors(&oneWire);
28/*
29#define SER_Pin 4 //Serial data input
30#define RCLK_Pin 3 //Register clock
31#define SRCLK_Pin 2 //Shift register clock
32*/
33
34DeviceAddress term1 = { 0x28, 0x2C, 0x79, 0x09, 0x04, 0x00, 0x00, 0x46 };
35static byte sollTemp=DEFAULT_TEMP;
36const static byte hysterese=40;
37static boolean fan_old=false;
38static boolean editMode=false;
39static unsigned long timer[2];
40static boolean timerState[3];
41static int potiVal_last=0;
42
43//Initialisation
44//AH_74HC595 seven_segment1(SER_Pin, RCLK_Pin, SRCLK_Pin);
45AH_74HC595 seven_segment1(4, 3, 2, true);
46AH_74HC595 seven_segment2(8, 7, 6, true);
47
48// Timer - Functions -----------------------
49// taken from: <a href="http://arduino.cc/playground/Code/DelaySeconds">http://arduino.cc/playground/Code/DelaySeconds</a>
50int delayMilliSeconds(int timerNumber,unsigned long delaytime){
51 unsigned long timeTaken;
52 if (timerState[timerNumber]==0){
53 timer[timerNumber]=millis();
54 timerState[timerNumber]=1;
55 }
56 if (millis()> timer[timerNumber]){
57 timeTaken=millis()+1-timer[timerNumber];
58 }else{
59 timeTaken=millis()+2+(4294967295-timer[timerNumber]);
60 }
61 if (timeTaken>=delaytime) {
62 timerState[timerNumber]=0;
63 return 1;
64 }else{
65 return 0;
66 }
67}// -----------------------------------------
68
69void displayNumber(byte nr) {
70 // divide the value in two peaces and show them
71 byte stelleX = nr % 10;;
72 seven_segment1.showNumber(stelleX);
73 stelleX = nr / 10;
74 seven_segment2.showNumber(stelleX);
75}
76
77void setup(){
78 pinMode(FAN_PIN1, OUTPUT);
79 pinMode(FAN_PIN2, OUTPUT);
80 pinMode(FAN_PIN3, OUTPUT);
81 digitalWrite(FAN_PIN1, LOW);
82 digitalWrite(FAN_PIN2, LOW);
83 digitalWrite(FAN_PIN3, LOW);
84 pinMode(LED1, OUTPUT);
85 pinMode(PWR_ON, OUTPUT);
86 digitalWrite(PWR_ON, HIGH);
87 digitalWrite(2, LOW);
88 digitalWrite(4, LOW);
89 digitalWrite(6, LOW);
90 digitalWrite(7, LOW);
91 digitalWrite(8, LOW);
92 seven_segment1.clear();
93 seven_segment2.clear();
94 sensors.begin();
95 // set the resolution to 12 bit
96 sensors.setResolution(term1, 12);
97 // timer reset
98 timerState[0] = 0;
99 timerState[1] = 0;
100}
101
102void loop(){
103 // Read Poti value and map it
104 delay(100);
105 int potiVal = analogRead(POTI);
106 // if no poti found use 23 grad celsius as default
107 if ( potiVal < 1010 ) {
108 sollTemp = map(potiVal, 0, 1023, 10, 35);
109 // set Editmode
110 if ( potiVal_last != potiVal ) {
111 // avoid jumping values
112 int v_min=potiVal-hysterese;
113 int v_max=potiVal+hysterese;
114 if( (potiVal_last>v_max)||(potiVal_last<v_min) ) {
115 editMode = true;
116 potiVal_last = potiVal;
117 // reset Timer
118 timerState[1]=0;
119 }
120 }
121 }else{
122 sollTemp=DEFAULT_TEMP;
123 }
124
125 if ( editMode == true ) {
126 if (delayMilliSeconds(1,3000)) {
127 // leave editmode if 5 seconds nothing happens
128 editMode = false;
129 }else{
130 // show sollWert
131 displayNumber(sollTemp);
132 }
133 }
134
135 // wait for the slow sensor
136 if (delayMilliSeconds(0,10000)){
137 // Request temperature
138 sensors.requestTemperatures();
139 // get the value
140 byte tempC = sensors.getTempC(term1);
141 if (tempC < -100) {
142 // show the fail of the sensor
143 seven_segment1.showNumber(15);
144 seven_segment2.showNumber(15);
145 // default turn the fans on
146 fan_now = true;
147 }else{
148 if ( editMode == false ) {
149 displayNumber(tempC);
150 }
151 if ( tempC > sollTemp ) {
152 // its hot, turn fans on
153 fan_now = true;
154 }else{
155 // debounce jumping value
156 if ( fan_now == true ) {
157 if ( tempC > (sollTemp - 1) ) {
158 fan_now = true;
159 }else{
160 fan_now = false;
161 }
162 }
163 }
164 }
165 }
166
167 // do the action, if neccessary
168 if ( fan_now != fan_old ) {
169 if (fan_now) {
170 // turn power supply on
171 digitalWrite(PWR_ON, LOW);
172 // wait for stabilized power supply
173 delay(3000);
174 }else{
175 // turn power supply off
176 digitalWrite(PWR_ON, HIGH);
177 }
178 digitalWrite(FAN_PIN1, fan_now);
179 digitalWrite(FAN_PIN2, fan_now);
180 digitalWrite(FAN_PIN3, fan_now);
181 digitalWrite(LED1, fan_now);
182 fan_old = fan_now;
183 }
184}
Und so sieht das fertige Produkt aus:
Wer dazu Fragen hat, oder einfach etwas dazu schreiben möchte, kann dies gerne in diesem Beitrag im offiziellen Arduino Forum machen.