'****************************************************************************** 'PWM Lueftersteuerung 17.07.2009 'Luefter_V3 - Erweiterungen: Matthias Foth ' 'Sollwert wird im EEPROM gespeichert ' 'Atmel Controller ATmega8 'AVCC Pin20 an +5V 'AREF Pin21 an +5V 'AGND Pin22 an GND ' 'Temperatur- Sensor LM35 an PC1 'Taster "Down" an PC5 'Taster "UP" an PC4 'LCD 16x2 an Port D 'LED grün an PD0 'LED rot an PD1 'IRF510 an PB1 '****************************************************************************** '$sim $regfile = "m8def.dat" ' ATMega8 $crystal = 8000000 ' 8 MHz intern '$crystal = 1000000 ' 1 MHz intern Const Const5 = 0.0048828125 ' 5V / 1024 (10-Bit-ADC) Dim Adc1 As Word ' Wert vom LM35 Dim Volt1 As Single ' Volt vom LM35 Dim Templm35 As Single ' Temperatur (celsius) von LM35 Dim Isttemp As Single ' aktuelle Temperatur in Celsius Dim Letzter_isttemp As Single ' Messwert davor Dim Disp_volt1 As String * 10 ' zur LCD-Anzeige Dim Disp_templm35 As String * 10 ' zur LCD-Anzeige Dim Adc3 As Word ' Wert vom ADC vom IRF510 Dim Volt3 As Single ' Volt vom IRF510 Dim Strom As Single ' Strom vom IRF510 Dim Disp_strom As String * 10 ' zur LCD-Anzeige Dim Solltemp As Single ' Vorgabe der maximal zulässigen Temperatur Dim Disp_solltemp As String * 10 ' zur LCD-Anzeige Dim I As Integer ' Zähler / Schleife Dim E_solltemp As Eram Single 'EEPROM Variable Dim Eramempty As Eram Byte 'Flag wenn EEPROM noch leer ist Declare Sub Adc_in Declare Sub Regeln Declare Sub Anzeigen Declare Sub Tasten Config Lcdbus = 4 Config Lcd = 16 * 2 Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2 Config Portb = Output Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Prescale = 1 Taste_up Alias Pinc.4 Taste_dn Alias Pinc.5 Dim Tasteup As Integer Dim Tastedn As Integer Config Pinc.0 = Input Config Pinc.1 = Input Config Pinc.2 = Input Config Pinc.3 = Input Config Pinc.4 = Input Set Portc.4 Config Pinc.5 = Input Set Portc.5 Config Adc = Single , Prescaler = Auto , Reference = Avcc Set Sfior.adhsm 'ADC high speed mode ATmega8 Config Portd.0 = Output Config Portd.1 = Output Ledgruen Alias Portd.0 Ledrot Alias Portd.1 Deflcdchar 1 , 14 , 10 , 14 , 32 , 32 , 32 , 32 , 32 ' creating ° Symbol for Degree Centigrade 'Deflcdchar 1 , 24 , 24 , 3 , 4 , 4 , 4 , 4 , 3 'creating "°C" character (1) 'Deflcdchar 1 , 24 , 24 , 32 , 3 , 4 , 4 , 4 , 3 'creating "°C" character (1) Deflcdchar 2 , 4 , 10 , 21 , 4 , 4 , 4 , 4 , 4 'creating "arrow top" char (2) Deflcdchar 3 , 4 , 4 , 4 , 4 , 4 , 21 , 10 , 4 'creating "arrow down" char (3) Cursor Off Waitms 100 Dim Dynamikgrenze_oben As Single Dim Dynamikgrenze_unten As Single Dim Toleranzgrenze_oben As Single ' in den Toleranzgrenzem wired nicht geregelt Dim Toleranzgrenze_unten As Single Dim Pausenzeit As Single ' Pause zwischen den Regelungen Dim Pausenzeit_int As Integer Dim Pausenzeit_max As Single ' max. zulässige Pausenzeit Dim Pausenzeit_faktor As Single Dim Schrittweite As Single ' um diesen Betrag wird PWM korrigiert Dim Schrittweite_int As Integer Dim Schrittweite_faktor As Single Dim Pwmwert As Integer ' 10-Bit PWM (0...1023) Dim Differenz As Single Const Eramemptymask = 255 'If EEprom is empty it contains 255 Const Eramfilledmask = 170 'If EEprom is filled it contains 170 ' ------------------------------------------------------------------------------ ' ----------------------- Initialisierung der Variablen ------------------------ ' ------------------------------------------------------------------------------ Pausenzeit = 25 ' zu Beginn mittlere Pausenzeit einstellen (2 Sek.) Pausenzeit_faktor = 1 ' Multiplikator für die Bestimmung der Pausenzeit Pausenzeit_max = 50 ' z.B. 50 * 1/10 Sek. = 5 Sekunden Schrittweite = 50 ' Anfangswert Schrittweite_int = 50 ' Anfangswert Schrittweite_faktor = 10 ' '------------------------------------------------------------------------------- ' EEprom operations '------------------------------------------------------------------------------- If Eramempty = Eramemptymask Then 'Default settings E_solltemp = 30 'Solltemp im EEPROM speichern Eramempty = Eramfilledmask End If Solltemp = E_solltemp 'Daten aus EEPROM lesen Waitms 500 'warte 500ms Disable Interrupts ' ------------------------------------------------------------------------------ ' Beginn Programm ' ------------------------------------------------------------------------------ Set Ledgruen ' grüne LED aus Set Ledrot 'rote LED aus Call Adc_in 'Analogwerte erstmals abfragen Pwmwert = 500 Pwm1a = Pwmwert ' Lüfter halbe Kraft voraus Cursor Off Cls Locate 1 , 2 Lcd "Luefter PWM V3" Wait 5 Cls Do Set Ledgruen 'LED grün aus Call Adc_in Call Tasten Call Anzeigen Call Regeln Reset Ledgruen 'LED grün an Waitms 100 Loop End 'end program '------------------------------------------------------------------------------- Sub Adc_in ' ADC lesen Start Adc Letzter_isttemp = Isttemp ' letzten Messwert merken Adc1 = Getadc(1) ' LM35 Adc3 = Getadc(3) ' für Strom IRF510 Volt1 = Adc1 * Const5 ' LM35 Templm35 = Volt1 * 100 ' in Celsius umrechnen (10mV je Grad über Null) Isttemp = Templm35 ' aktuelle Temperatur am LM35 Volt3 = Adc3 * Const5 ' Strom durch den IRF510 berechnen Strom = Volt3 / 1.2 ' I = U / R R=1,2 Ohm Strom = Strom * 1000 ' Ampere in mA Stop Adc End Sub Sub Regeln ' Pausenzeit außerhalb Dynamikbereichs einstellen If Isttemp > Dynamikgrenze_oben Then Pausenzeit = 0 ' kürzest mögliche Pause End If ' dann schnell regeln ' Temperatur unterhalb Solltemperatur If Isttemp <= Solltemp Then ' Temp ist kälter als erlaubt Locate 1 , 9 Lcd Chr(3) If Isttemp < Toleranzgrenze_unten Then ' unterhalb Toleranzgrenze ? Pwmwert = Pwmwert - Schrittweite_int ' versuchen, ob Lüfter leiser werden kann If Pwmwert < 0 Then Pwmwert = 0 End If End If Pwm1a = Pwmwert End If ' endif isttemp < solltemp ' Bereich oberhalb Solltemperatur If Isttemp > Toleranzgrenze_oben Then ' Temp zu hoch, PWM-Wert steigern Locate 1 , 9 Lcd Chr(2) ' Schrittweite berechnen, um die der PWM-Wert korrigiert wird Schrittweite = Isttemp - Solltemp Schrittweite = Schrittweite * Schrittweite_faktor Schrittweite_int = Round(schrittweite) If Schrittweite_int < 1 Then Schrittweite_int = 1 End If If Isttemp > Letzter_isttemp Then Pwmwert = Pwmwert + Schrittweite_int End If If Isttemp < Letzter_isttemp Then Pwmwert = Pwmwert - Schrittweite_int End If If Isttemp = Letzter_isttemp Then Pwmwert = Pwmwert + 10 End If If Pwmwert > 1023 Then Pwmwert = 1023 End If If Pwmwert < 0 Then Pwmwert = 0 End If Pwm1a = Pwmwert ' PWM des Motors steuern If Isttemp < Dynamikgrenze_oben Then ' im Regelbereich, in dem die Pausenzeit angepasst wird Set Ledrot ' rote LED aus ' Pausenzeit berechnen für (Toleranzgrenze oben < x < Dynamikgrenze oben) Differenz = Dynamikgrenze_oben - Isttemp Pausenzeit = Pausenzeit_max / Differenz Pausenzeit = Pausenzeit * Pausenzeit_faktor If Pausenzeit > Pausenzeit_max Then Pausenzeit = Pausenzeit_max End If ' nun steht in Pausenzeit die Pausenzeit 1/10 Sekunden End If End If ' if Toleranzgrenze_oben < Isttemp If Isttemp > Dynamikgrenze_oben Then ' Ist > als Dynamikgrenze oben, also SEHR hoch Reset Ledrot ' warnen Pausenzeit = 0 End If Pausenzeit_int = Round(pausenzeit) ' Pausenzeit (SINGLE) in INTEGER wandeln If Pausenzeit_int > 0 Then ' Pausenzeit vergehen lassen For I = 0 To Pausenzeit_int Waitms 100 ' Zeit verplempern in Einheiten von 1/10 Sekunde Call Tasten Next I End If End Sub Sub Anzeigen Disp_templm35 = Fusing(templm35 , "##.#") Disp_strom = Fusing(strom , "###.#") Disp_solltemp = Fusing(solltemp , "###.#") Locate 1 , 1 ' LCD 2x16 Lcd "I:" ; Disp_templm35 ; Lcd Chr(1) ; "C"; Locate 1 , 10 Lcd " S:" ; Disp_solltemp ; " " Locate 2 , 1 Lcd Disp_strom ; "mA " Locate 2 , 9 Lcd "Pwm:" ; Pwmwert ; " " End Sub Sub Tasten Tasteup = Taste_up Tastedn = Taste_dn If Tasteup = 0 Then Incr Solltemp E_solltemp = Solltemp Reset Ledrot Waitms 300 Set Ledrot End If If Tastedn = 0 Then Decr Solltemp E_solltemp = Solltemp Reset Ledrot Waitms 300 Set Ledrot End If If Solltemp < 1 Then Solltemp = 1 End If If Solltemp > 99 Then Solltemp = 99 End If Toleranzgrenze_oben = Solltemp + 1 Toleranzgrenze_unten = Solltemp - 1 Dynamikgrenze_oben = Toleranzgrenze_oben + 4 Dynamikgrenze_unten = Toleranzgrenze_unten - 4 End Sub