Einleitung

Es geht darum eine temperaturgesteuerte Lüftersteuerung zu bauen. Die Grundidee ist vorhandene Bauteile zu verwenden und folgenden Aufbau zu realisieren:

Project

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.

Netzteil-rechts

Netzteil-oben

Netzteil-hinten

7-Segmentanzeige ansteuern

Mit dem 8 Bit Shift Register 74HC595 lassen sich die digitalen Ports vom Arduino sparen.

7SegmentAnzeige

7SegmentAnzeigeSchaltplan

NetzteilLCD

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:

LuefterSteckplatine

LuefterSchaltplan

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.

TemperaturSteckplatine

Programm

Alles als Download

  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:

SchrankFertig

SchrankFertig2

Wer dazu Fragen hat, oder einfach etwas dazu schreiben möchte, kann dies gerne in diesem Beitrag im offiziellen Arduino Forum machen.