'********************************************************** '** Datenlogger mit 1Wire - Bus für DS18S20 ** '** und USB-Interface STI 100 an RS232-Port PD.0 / PD.1 ** '** by KHZ Februar 2009 : 9.9.2011 84% ** '** Messuhrerweiterung Aktuell :12.6.2013 53% ** '********************************************************** '** DS18S20 1 wire PD.7 1Wire ** '** DS1307 PD.5 Sda / PD.6 Scl I2C für die Uhr DS1307 ** '********************************************************** '** PC.0 - PC.5 für Eingänge vorgesehen ** '** PD.4 für LCD Backlight vorgesehen ** '** ACHTUNG: ins EEPROM schreiben !! ** '********************************************************** '** Wärmemengenmessung, Wasseruhr am 17.5.13 eingebaut ** '** IRQ0 PinD.2 für Litermessung ** '** IRQ1 PinD.3 für PowerDown Routine Datenrettg. Zähler** '********************************************************** $regfile = "m168def.dat" 'der 88 wurde zu klein '$regfile = "m88def.dat" $crystal = 20000000 '********************************************************** Baud = 9600 $hwstack = 128 ' default use 32 for the hardware stack $swstack = 128 ' default use 10 for the SW stack $framesize = 128 ' default use 40 for the frame space '********************************************************** Config 1wire = Portd.7 Config Lcd = 16 * 2 Config Lcdpin = Pin , Db7 = Portb.0 , Db6 = Portb.1 , Db5 = Portb.2 , Db4 = Portb.3 , E = Portb.4 , Rs = Portb.5 Config Sda = Portd.5 ' I2C Bus konfigurieren Config Scl = Portd.6 Const Ds1307w = &HD0 ' Addresse der Ds1307 Uhr Const Ds1307r = &HD1 Config Portc = Input Config Portd.4 = Output Config Portd.2 = Input 'Eingang Liter Config Clock = User ' Interne Time/Date Routinen für Bascom konfigurieren Config Date = Dmy , Separator = . '++++++++++++++++++++++++++++++ Dim Eramok As Eram Byte '123 kommt rein Dim Rom(8) As Byte 'aus 1Wire Dim Weekday As Byte 'DatumsVar Dim Minute As String * 1 Dim Tag As String * 2 Dim Wtage As String * 14 Dim Datzeit As String * 17 Dim Y As Byte 'einige Hilfsvar Dim Punkt As Bit Dim I As Byte Dim J As Byte Dim Anz As Byte Dim Pos As Integer Dim Dateien As Integer 'Dateienzahl Dim Licht As Integer 'An Aus Dim Sensor As Integer Dim Temp As Single Dim Hilfsvar As Single Dim Hilfstr As String * 8 Dim Joule As Single Dim Send As String * 40 'String zum USB Dim File(2) As String * 12 Dim Zeit As String * 8 Dim Heute As String * 8 Dim T As Integer Dim K As Byte Dim Liter As Long 'Liter Dim Eliter As Eram Long 'im ERAM Dim Literbit As Bit 'wird im IRQ ges. Dim Halbliter As Bit Dim Q_warm As Single 'Wärmemenge Dim Eq_warm As Eram Single 'ERAM Wärmemenge Dim Adress As Byte Dim Kopf(8) As String * 6 Dim Temperaturen(6) As Single Const C = 4.187 / 2 'KJ in KWh weil '1/2 Liter Impuls '**** Unterprogramme deklariern Declare Sub Messen Declare Sub Warte '**** Interrupt einstellen **** Config Int0 = Falling 'wenn PD.2 Null On Int0 Zaehlen_isr Enable Int0 Config Int1 = Falling On Int1 Speichern_isr Enable Int1 '****************************** Restore Kopfbez For I = 1 To 9 Read Kopf(i) Next '**** Wochentag- und Dateinamen vergeben *** Wtage = "MoDiMiDoFrSaSo" '******* Uhr stellen ******** 'Stellen Der Uhr , Muss Nur Einmal Ausgeführt Werden 'Time$ = "14:44:30" 'Date$ = "13.06.13" 'End '##################################### Initlcd Cursor Off Cls Set Portd.4 'Licht ein Licht = 0 'Lichtzähler Lcd "1Wire TempLogger" Lowerline Lcd "by KHZ 13.6.2013" Wait 5 Cls Print "ECS" ; Chr(13); 'ASCI Zeichensatz Lcd "ECS " Wait 1 Print "IPA" ; Chr(13); 'ASCII Zahlendarstellung Lcd "IPA" Wait 1 'Daten aus ERAM holen Waitms 10 If Eramok <> 123 Then Eramok = 123 Eliter = 0 Eq_warm = 0 End If Waitms 100 Liter = Eliter Q_warm = Eq_warm Waitms 10 'Sensoren festlegen Sensor = 6 'Messstellen festl. '****** in Datei Tabellenkopf schreiben ******* File(1) = "Tmp10min.CSV" 'Dateinamen File(2) = "Tmp60min.CSV" 'festlegen '( Print "DIR NeueZeit.DAT" ; Chr(13); 'UhrStellDatei Punkt = 0 Cls Inputbin Y Inputbin Y Inputbin Y Do Inputbin Y Lcd Chr(y) If Y = 36 Then Punkt = 1 'ein'$' gefunden End If 'dann 'DAT' vorhanden Loop Until Y = 13 'warte auf 'Cr' 'wenn ein '.' mit zurückkommt ist *.DAT vorhanden 'Datenformat "*DD.MM.YY mm:SS:ss* If Punkt = 1 Then Lcd "stelle Uhr" Print "RD NeueZeit.DAT" ; Chr(13); Do Cls Inputbin Y Lcd Chr(y) 'Datzeit = Datzeit + Chr(y) Loop Until Y = 65 'warte auf '@' Datzeit = "" Do 'Warte auf 2.'@' Inputbin Y Datzeit = Datzeit + Chr(y) Loop Until Y = 64 Warte Locate 1 , 1 Lcd Left(datzeit , 8 ) Locate 2 , 1 Lcd Mid(datzeit , 10 , 8) Date$ = Left(datzeit , 8 ) 'Datum stellen Time$ = Mid(datzeit , 10 , 8) 'Zeit stellen Print "REN NEUEZEIT.DAT NEUEZEIT.OK" ; Chr(13); 'Datei umbenennen Warte Wait 1 End If ') 'Date$ = "11.06.13" 'Time$ = "14:41:30" For I = 1 To 2 'Schreibe Kopf Print "OPW " ; File(i) ; Chr(13); 'Öffne Datei Warte Print "WRF 3" ; Chr(13) ; "WT;"; 'schreibe WoTag Warte Print "WRF 6" ; Chr(13) ; "Datum;"; 'schreibe Datum Warte Print "WRF 5" ; Chr(13) ; "Zeit;"; 'schreibe Zeit Warte Upperline Lcd File(i) For J = 1 To 9 'Kopfdaten aus EEPROM lesen Print "WRF 7" ; Chr(13) ; Kopf(j) ; ";"; 'Tabellenkopf in Datei Warte Locate 2 , 1 Lcd Kopf(j) Next Print "WRF 17" ; Chr(13) ; "C5;C4;C3;C2;C1;C0"; Warte Print "WRF 2" ; Chr(13) ; Chr(13) ; Chr(10); 'Schreibe Zeilenumbruch Warte Print "CLF " ; File(i) ; Chr(13); 'Datei Close Warte Wait 1 Next I '************ Hauptschleife ******************************* Enable Interrupts Do Disable Int0 'IRQ aus Zeit = Time$ 'Zeit und Datum in Heute = Date$ 'Zwischenvariable Enable Int0 'IRQ ein Minute = Mid(zeit , 4 , 1) '10er Minuten merken Anz = 1 For J = 1 To Sensor 'alle Sensoren Messen 'messen lassen Next Do Disable Int0 Zeit = Time$ Heute = Date$ Enable Int0 If Literbit = 1 Then 'ISR war aufgerufen Literbit = 0 Liter = Liter + Halbliter '1/2 L aufsummieren Hilfsvar = Temperaturen(2) - Temperaturen(3) 'Delta K Joule = Hilfsvar * C '1l X DeltaK X C Hilfsvar = Joule / 3600 '= KWh Q_warm = Hilfsvar + Q_warm 'Summieren End If Pos = Weekday * 2 'Wochentag Pos = Pos - 1 'berechnen und aus Tag = Mid(wtage , Pos , 2) 'String filtern Upperline Lcd Left(zeit , 5) Lcd " " ; Tag Lcd Date$ Lowerline Select Case Anz Case 1 To 6 'Temperaturen der Messen 'Sensorsoren abfragen If Temperaturen(anz) > 100 Then 'da stimmt was nicht Lcd "*Leitungsbruch* " Else Lcd Kopf(anz) 'Überschrift Lcd " = " Lcd Fusing(temperaturen(anz) , "#.#") 'Temp formatieren Lcd Chr(223) 'Grad Zeichen Lcd "C " Lcd Tag Lcd " " End If Case 7 Lcd "Q = " Lcd Fusing(joule , "#.#") Lcd " kJ " Wait 1 Case 8 Lcd "A = " Lcd Fusing(q_warm , "#.#") Lcd " kWh " Wait 1 Case 9 Lcd "L = " Lcd Liter Lcd " l " Wait 1 End Select If Licht > 200 Then 'Leuchtdauer abgelaufen? Reset Portd.4 'dann Licht aus Anz = Anz + 1 'Sensoren Durchlauf Else 'sonst Set Portd.4 'Licht ein und Incr Licht 'Zeitzähler hoch End If If Anz > 9 Then Anz = 1 'Sensor von vorne If Pinc.5 = 0 Then 'Taste gedrückt? Do : Loop Until Pinc.5 = 1 Incr Anz 'Sensorzähler hoch Licht = 0 'Licht ein End If Loop Until Minute <> Mid(zeit , 4 , 1) 'Warte bis 10min um Pos = Weekday * 2 'Wochentag Pos = Pos - 1 'berechnen und aus Tag = Mid(wtage , Pos , 2) 'String filtern ' File(1) = "Tmp10min.CSV" ' File(2) = "Tmp60min.CSV" If Mid(zeit , 4 , 2) = "00" Then 'volle Sunde? Dateien = 2 'dann 2 Dateien Else 'schreiben Dateien = 1 End If For I = 1 To Dateien 'Dateien schreiben Print "OPW " ; File(i) ; Chr(13); 'Öffne Datei Warte Wait 1 Print "WRF 3" ; Chr(13) ; Tag ; ";"; 'schreibe WoTag Warte Print "WRF 9" ; Chr(13) ; Heute ; ";"; 'schreibe Datum Warte Print "WRF 6" ; Chr(13) ; Left(zeit , 5) ; ";"; 'schreibe Zeit Warte For J = 1 To Sensor 'alle Sensoren ' Messen 'messen Send = Fusing(temperaturen(j) , "#.#") + "; " Y = Len(send) For Pos = 1 To Y 'Komma für If Mid(send , Pos , 1) = "." Then 'Punkt Mid(send , Pos , 1) = "," 'einsetzen End If Next Print "WRF " ; Asc(y) ; Chr(13) ; Send ; 'schreibe Wert Warte Upperline Lcd "D:" Lcd File(i) 'Dateiname Lowerline Lcd J ; ": " ; Send ; Chr(223) ; "C " Next J Hilfstr = Str(joule) Y = Len(hilfstr) For Pos = 1 To Y 'Komma für If Mid(hilfstr , Pos , 1) = "." Then 'Punkt Mid(hilfstr , Pos , 1) = "," 'einsetzen End If Next Hilfstr = Hilfstr + ";" Send = Str(q_warm) Y = Len(send) For Pos = 1 To Y 'Komma für If Mid(send , Pos , 1) = "." Then 'Punkt Mid(send , Pos , 1) = "," 'einsetzen End If Next Send = Hilfstr + Send 'zusammensetzen Send = Send + ";" Send = Send + Str(liter) 'Litermenge Send = Send + ";" Send = Send + Str(pinc.5) Send = Send + ";" 'Digi Eingänge Punkt = Not Pinc.4 'pc.5 = Lichttaster Send = Send + Str(punkt) 'Eingänge der Reihe Punkt = Not Pinc.3 'nach negieren und Send = Send + ";" 'als String Send = Send + Str(punkt) 'zusammensetzen Punkt = Not Pinc.2 Send = Send + ";" Send = Send + Str(punkt) Punkt = Not Pinc.1 Send = Send + ";" Send = Send + Str(punkt) Punkt = Not Pinc.0 Send = Send + ";" Send = Send + Str(punkt) Y = Len(send) Print "WRF " ; Str(y) ; Chr(13) ; Send; 'Digi-String schreiben Warte Print "WRF 2" ; Chr(13) ; Chr(13) ; Chr(10); 'Schreibe Zeilenumbruch Warte Print "CLF " ; File(i) ; Chr(13); 'Datei Close Warte Next Loop End '************** UP's ********************* 'wartet auf 0D vom Stick Sub Warte Do Inputbin Y Loop Until Y = 13 Waitms 50 End Sub '******************* Int1 ********************** 'Daten sichern bei Spannungsausfall Speichern_isr: Eliter = Liter 'Zählerstände Eq_warm = Q_warm 'retten Cls Lcd "Daten gesichert" Return '******************** Int0 ********************* 'Wasseruhr hat halben Liter gemessen Zaehlen_isr: Toggle Halbliter '0 uder 1 Literbit = 1 'berechnen in Main Return '***************************************** 'Sensor J messen Sub Messen Select Case J Case 1 Restore Sensor1 Case 2 Restore Sensor2 Case 3 Restore Sensor3 Case 4 Restore Sensor4 Case 5 Restore Sensor5 Case 6 Restore Sensor6 End Select 1wreset 1wwrite &HCC 'SKIP ROM 1wwrite &H44 Ddrd.7 = 1 Waitms 800 Ddrd.7 = 0 1wreset 1wwrite &H55 For Pos = 1 To 8 Read Adress 1wwrite Adress Next I 1wwrite &HBE Rom(1) = 1wread(8) K = Rom(1) And 1 If K = 1 Then Decr Rom(1) T = Makeint(rom(1) , Rom(2)) T = T * 50 T = T - 25 Temp = Rom(8) - Rom(7) Temp = Temp * 100 Temp = Temp / Rom(8) Temp = Temp + T Temp = Temp / 100 Temperaturen(j) = Temp End Sub '########################################################### ' Unterprogramme für die Bascom Date/Time-Funktionen Getdatetime: I2cstart I2cwbyte Ds1307w I2cwbyte 0 I2cstart I2cwbyte Ds1307r I2crbyte _sec , Ack I2crbyte _min , Ack I2crbyte _hour , Ack I2crbyte Weekday , Ack I2crbyte _day , Ack I2crbyte _month , Ack I2crbyte _year , Nack I2cstop _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour) _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year) Return Setdate: _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year) I2cstart I2cwbyte Ds1307w I2cwbyte 4 I2cwbyte _day I2cwbyte _month I2cwbyte _year I2cstop Return Settime: _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour) I2cstart I2cwbyte Ds1307w I2cwbyte 0 I2cwbyte _sec I2cwbyte _min I2cwbyte _hour I2cstop Return '################################################################## '***** Sensoren-Adressen und Tabellenkopf ins EEPROM ****** '$eeprom Sensor1: 'Aussen Data &H10 , &HC0 , &HFC , &H33 , &H00 , &H08 , &H00 , &H55 Sensor2: 'SolVor Data &H10 , &H66 , &H45 , &HA9 , &H01 , &H08 , &H00 , &H56 Sensor3: 'SolRue Data &H10 , &H9E , &H8F , &HB5 , &H01 , &H08 , &H00 , &H30 Sensor4: 'Speich Data &H10 , &HB9 , &H31 , &HA9 , &H01 , &H08 , &H00 , &HC4 Sensor5: 'LadePu Data &H10 , &HBD , &HA0 , &HB5 , &H01 , &H08 , &H00 , &H48 Sensor6: 'HeizVL Data &H10 , &HBB , &H60 , &HB5 , &H01 , &H08 , &H00 , &HD8 Kopfbez: Data "Aussen" , "SolVor" , "SolRue" , "Speich" , "LadePu" , "HeizVL" , "kJoule" , "Q_kWh " , "Liter " '$data