$regfile "m328pdef.dat" '$regfile "m8adef.dat" $crystal = 8000000 '$hwstack = 32 ' default use 32 for the hardware stack '$swstack = 10 ' default use 10 for the SW stack '$framesize = 40 Config Portb.1 = Output Config Portc.5 = Input 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 Lcdbus = 4 Config Timer1 = Pwm , Pwm = 8 , Compare_A_PWM = Clear_Up , Prescale = 1 Start Timer1 Config Adc = Single , Prescaler = Auto , Reference = Avcc Start Adc Deflcdchar 0 , 2 , 5 , 2 , 32 , 32 , 32 , 32 , 32 ' °C Cursor Off Noblink '--------- 1-Wire START ------------------------------------------------------ Config 1wire = Portc.5 'Eingang für 1-Wire Sensor DS18x20 '--------- Subroutinen ------------------------------------------------------- Declare Sub Ds18xauslesen ' Temperatur auslesen Declare Sub Ds18xSuchen ' Sensor am Bus Suchen + CRC Prüfen Declare Sub Temp_ds1820 ' Temperatur ermitteln und umrechnen Declare Sub Regulator ' PID Regler Declare Sub Hauptschleife ' Hautpprogramm-Schleife Declare Sub Ausgabe ' Ausgabe setzen Declare Sub Sollwert ' Sollwert ermitteln (ADC) '--------- Variabeln --------------------------------------------------------- Dim Dsid1(8) As Byte '1. Sensor ID 64 bits (8Bytes) incl CRC als array Dim Dsid1scratchpad(9) As Byte 'Scratchpad 72 Bits (9 Bytes) incl CRC als array sind die Temperatur Daten Dim Anzahlsensoren As Byte ' Wie viele Sensoren wurden am Bus gefunden Dim I As Byte ' Variable für schleifen (ID Ausgabe) Dim Dg As Integer 'Variable1 zur Temp. Berechnung DeziGrad Dim Dg1 As Integer 'Variable2 zur Temp. Berechnung DeziGrad Dim Dg2 As Single Dim Index(3) As Byte ' Variable für Tabelle welcher Sensortyp gefunden wurde Dim Temp1 As String * 5 ' Temperaturwert aus DS18xx als String für Displayausgabe Dim Max1 As Byte ' Ausgelesener Max-Wert von Sensor 1 Dim Min1 As Byte ' Ausgelesener Min-Wert von Sensor 1 Dim Config1 as Byte Dim Auto_mode As Bit ' Regulator on ? Dim Manual_value As Byte ' Output if not regulating Dim Spx As Single ' Setpoint Dim Pv As Single ' Process Value Dim Cv As Single ' PID output Dim First_execution As Byte ' First start recognition Dim Initial_error As Single ' Startup difference Dim A As Byte ' Tmp for random Dim B As Single ' Tmp for random Dim AdcWert as Word ' Variable für ADC wert (veränderung sollwert) Dim CvByte as Byte '--------- Start Werte setzten ----------------------------------------------------- Auto_mode = 1 ' Permanent running choosen First_execution = 0 ' Set permanent running algorithm Manual_value = 40 ' Output if not regulating = on cls Locate 1 , 1 Lcd "POWER Kuehlbox" Locate 2 , 1 Lcd "Version 0.9" wait 5 '--------- 1Wire 1. Sensor suchen ------------------------------------------------------ Ds18xSuchen: Cls Locate 1 , 1 LCD "Suche Sensor" Anzahlsensoren = 1wirecount() ' Übergebe die Anzahl gefundene Sensoren in Variable If Anzahlsensoren = 0 Then Locate 2 , 1 Lcd "kein Sensor !" wait 3 gosub DS18XSUCHEN Else Cls Dsid1(1) = 1wsearchfirst() ' Suche den ersten Sensor und Speicher im array ab der ersten stelle die 8 Bytes der ID ab If Err = 0 Then ' wenn kein fehler (Sensor gefunden) aufgetreten dann Locate 1 , 1 Lcd "Sensor ID:" Locate 2 , 1 For I = 1 To 8 Lcd Hex(dsid1(i)) ' gebe die 8 Bytes der Sensor ID auf dem LCD aus Next I wait 2 cls Locate 1 , 1 Index(1) = Lookdown(dsid1(1) , Data2 , 3) ' suche nach dem ersten Byte aus dsid1 in Tabelle Data2 die aus 3 Daten besteht und speicher die Position in index(1) Lcd "Typ: "; Lookupstr(index(1) , Data1) ' Zeige Text aus Tabelle Data1 von Stelle index(1) Locate 2 , 1 If Dsid1(8) = Crc8(dsid1(1) , 7) Then ' Überprüfe ob die Empfangene Checksumme = der Berechneten ist. wenn das 8 Byte aus dsid1(8) = crc berechnet dann mache weiter Lcd "CRC OK" Wait 4 Else Lcd "CRC BAD !!!" Wait 2 gosub DS18XSUCHEN End If End If Cls End If '--------- Hauptprogramm ------------------------------------------------------ Hauptschleife: Gosub Ds18xauslesen ' Ermittlung Ist-Wert Gosub Sollwert ' Ermittlung Soll-Wert WaitmS 250 ' PID must run deterministic time slices Gosub Regulator ' Call the PID allgorithm Gosub Ausgabe ' Werte Ausgeben Gosub Hauptschleife '-------------- Ermittlung Sollwert ------------------------------------------------- Sollwert: Adcwert = getADC(0) / 100 ' 10Bit (0-1023 / 100) SPx = 25 + Adcwert Locate 1 , 1 Lcd "SOLL: " ; SPx ; Chr(0) ; "C" Return '-------------- Ausgabe der Werte ------------------------------------------------- Ausgabe: 'If Cv >= 254 Then ' Cv = 254 'End If 'If Cv <= 0 Then ' Cv = 0 'End If CvByte = Cv Compare1A = CvByte Return ' -----[ Start of PID Regulator]--------------------------------------------- Regulator: ' -----[ Constant ]---------------------------------------------------------- Const Kp = 5.00 ' Proportional factor Const Ki = 0.70 ' Integration factor Const Kd = 0.50 ' Derivation factor Pv = dg2 ' -----[ Variables ]--------------------------------------------------------- Dim Last_pv As Single ' Last PV Dim Last_sp As Single ' Last SP Dim Sum_error As Single ' Summed error value Dim D_pv As Single ' Derrivated delta PV Dim sError As Single ' Difference between SP and PV Dim Pterm As Single ' Proportional calculated part Dim Iterm As Single ' Integrated calculated part Dim Dterm As Single ' Derivated calculated part ' -----[ Code ]-------------------------------------------------------------- If Auto_mode = 1 Then ' -------- Regulating modus sError = Spx - Pv 'sError = sError * -1 ' Zeile wird für Kühlen benötigt Sum_error = Sum_error + sError Iterm = Ki * Sum_error ' Integrated CV part ' -------- First time startup If First_execution = 0 Then Sum_error = Manual_value / Ki First_execution = 1 Initial_error = sError Pterm = 0 Dterm = 0 Last_sp = Spx ' -------- Normal calculation loop Else D_pv = Last_pv - Pv Last_pv = Pv Dterm = Kd * D_pv ' Derivated CV part If Spx = Last_sp Then ' -------- Normal loop when setpoint not changed Pterm = Kp * sError ' Proportional CV part ' -------- Loop when setpoint changed Else Pterm = 0 Dterm = 0 If Spx > Last_sp And Pv > Spx Then Last_sp = Spx Last_pv = Pv End If If Spx < Last_sp And Pv < Spx Then Last_sp = Spx Last_pv = Pv End If End If ' Enf of SP change seperation ' End If ' Enf of first time running seperation ' Cv = Pterm + Iterm ' Summing of the tree Cv = Cv + Dterm ' calculated terms ' -------- Forced modus Else ' When running in non regulationg modus Compare1A = Manual_value ' Set output to predefined value First_execution = 0 ' restart bumpless End If Return '--------- Temp Sensor auslesen (Ist-Wert) ------------------------------------ Ds18xauslesen: 1wreset ' Bus reseten damit alle Sensoren hören 1wwrite &HCC ' &HCC = alle Sensoren am Bus werden angesprochen / &H55 einen bestimmten Baustein ansprechen mit 1wverify Dsid1-3(1) oder 1wwrite &H55 ' 055H = Match ROM command, also Baustein auswählen For I = 1 To 8 : 1wwrite Dsid(i) : Next I 1wwrite &H44 ' Sensoren veranlassen die Temperatur zu messen Waitms 750 ' den Sensoren Zeit geben um Temperatur zu messen 1wverify Dsid1(1) 'Spreche den ersten Sensor an If Err = 1 Then cls Locate 1 , 1 Lcd "Sensor nicht am Bus " 'Err = 1 dann stimmt etwas nicht GoSub DS18XAUSLESEN Elseif Err = 0 Then Gosub Temp_ds1820 ' wenn Sensor ein DS1820 oder DS18S20 ist dann Berechnung Temp_ds1820 Max1 = Dsid1scratchpad(3) ' Sensor Interne Alarm Max Temperatur Min1 = Dsid1scratchpad(4) ' Sensor Interne Alarm Min Temperatur Config1 = Dsid1scratchpad(5) ' Sensor Internes Configurationsregister Bit 5 und 6 geben die Messauflösung der Temp. an. Locate 2 , 1 Temp1 = Fusing(dg2 , "#.#") 'Ergebnis in Temp1 als String ablegen und ab der zweiten kommastellen abschneiden Lcd "IST : " ; Temp1 ; Chr(0) ; "C" ' Zeige Text aus Tabelle Data1 von Stelle index(1) Lcd "Sensor 1: " ; Temp1 ; Chr(0) ; "C " End If return '--------- Temperatur ermitteln DS1820 ---------------------------------------- Temp_ds1820: 1wwrite &HBE ' Kommando READ SCRATCHPAD Dsid1scratchpad(1) = 1wread(9) ' lese 9 bytes in das Array (byte9=checksumme) If Dsid1scratchpad(9) = Crc8(dsid1scratchpad(1) , 8) Then ' überprüfe Checksumme (9 Byte) wenn OK dann I = Dsid1scratchpad(1) And 1 If I = 1 Then Decr Dsid1scratchpad(1) Dg = Makeint(dsid1scratchpad(1) , Dsid1scratchpad(2)) 'Byte 1 = Temp / Byte 2 = Vorzeichen (0=+ ; 255=-) Dg = Dg * 50 Dg = Dg - 25 Dg1 = Dsid1scratchpad(8) - Dsid1scratchpad(7) Dg1 = Dg1 * 100 Dg1 = Dg1 / Dsid1scratchpad(8) Dg = Dg + Dg1 Dg2 = Dg / 100 End If Return '--------- Tabellen ------------------------------------------------------ Data1: ' 0 1 2 3 Data " " , "DS1822 " , "DS18S20" , "DS18B20" Data2: ' 1 2 3 Data 34 , 16 , 40