Sauna Regelung mit HYT Sensor, RTC DS1307 und Drehencoder Vorstellung

hage

Mitglied
12. Sep. 2010
41
0
6
Sprachen
Hallo AVR User,
ich war lange nicht aktiv im Forum, nun ist aber endlich wieder Herbst und damit Zeit um ein wenig mit Bascom zu programmieren.
Im Folgenden vorab ein Teil von einem kleinem Projekt für die Regelung eines Saunaofens.
Es beinhaltet in erster Linie 4 Punkte
Einsatz eines
- Drehencoders mit Taster v. haupt+schuler Typ 427
- Feuchte und Temp. Sensor HYT 271 per I2C
- RTC DS 1307 per I2C
- Menuestruktur mit Drehencoder

Drehencoder
Ich habe zuerst versucht den Bascom 'enc' Befehl zu nutzen.
Das funktioniert leider nur sehr mäßig. Im Datenblatt des Encoder gibt es zwei Ablauf Diagramme für die Auswertung des Encoders. Mit und ohne Nutzung eines Interrupt.
Ich habe mich für die Nutzung mit Interrupt und Umschaltung der Flanke entschieden. Es funktioniert in allen Situationen absolut betriebssicher! (Auszug aus Datenblatt als pdf-Anlage).

HYT bzw. DS 1307
Ich habe einen Teil der Routine aus dem Internet übernommen, da das Datenblatt nicht sehr aussagekräftig ist.
Mit dem untenstehenden Quellcode funktionieren HYT und RTC sehr zuverlässig. Die RTC verliert etwa 1 Sec. in 24 Std, ein Quarz mit 10ppm und der von Maxim geforderten 12,5pF ist bestellt. Ich werde später berichten ob die Genauigkeit sich verbessert. Das I2T Handling ist in dem angefügten Quellcode noch nicht für die Nutzung von 2 Teilnehmern am Bus optimiert, es geht aber hauptsächlich um die prinziepelle Funktion.

Menuestruktur
Da meine früheren Projekte auf 4 Taster Steuerung basierten - links / rechts zum blättern und rauf / runter zum ändern der Werte - mußte für den Encoder etwas Neues her.
Ich hoffe es gibt einige Leser im Forum, die hierzu eine Aussage machen werden. Evtl. auch Vorschläge wie man das ganze vereinfachen kann. Es ist sicher nicht ganz einfach, den Ablauf und die Sprünge in einem fremden Quellcode nachzuvollziehen. Wenn gewünscht verkürze ich das gerne noch auf ein Minimum.
Die Uhreinstellung läßt sich sicher noch verbessern, aber auch hier war das Ziel eine Menuestruktur mit einem Untermenue aufzubauen.

Ausblick
Im Augenblick ist das System 'quick and dirty' zusammengelötet. Die Dimmerfunktion und die Regelung sind hier nicht aufgeführt weil
a. der Platz im Flash nicht reicht und b. es das ganze noch unüersichtlicher machen würden. Es gibt aber beides schon in einem vorherigem Projekt. Für den Dimmer sei noch einmal an dem hier im Forum vorgestellten 'Norkadosendeimmer' von Cassio erinnert!
Ich warte zur Zeit auf einen 168er mit mehr Flash und auf ein 4-zeiliges Display. Ich werde dann das Programm noch einmal
umstricken und mit den fehlenden Routinen vervollständigt hier einstellen.

Viele Grüße
hage

Dank der Begrenzung auf max. 15.000 Zeichen pro Beitrag folgt der Quellcode im näachsten....:)
 
So, hier nun der Quellcode....


Code:
'
'
'*****************************************************************************
'
' Sauna-Steuerung
' - Temperatur 2 Punktregler
' - Temperatur auf Feuchte Regler,
'      d.h. die Ofentemperatur wird so geregelt das die Summe aus
'      dem  Wert der relat. Luftfeucht und der Temperatur dem eingestellten
'      Wert entspricht. Bsp. T + W Wert auf 100 eingestellt und die
'      Luftfeuchte hat einen Wert von 30% wird die Ofentemperatur auf 70°C
'      eingestellt
' - Dimmer für die Saunabeleuchtung
' - Ofenabschaltung einstellbar max. 6 Stunden nach einschalten
' - Saunaofen wird autom. beim Einschalten der Steuerung eingeschaltet
' - RTC mit Pufferakku
'
' November 2011
'
'*****************************************************************************
'
'Bascom Ver. 2.0.1.0
'
$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 100                                               ' default use 32 for the hardware stack
$swstack = 100                                               ' default use 10 for the SW stack
$framesize = 40                                              ' default use 40 for the frame space

' $prog &HFF , &HE4 , &HD9 , &H00                             ' standard, ausser 8 Mhz inerner Oszillator
$eeprom

' I2C und Port konfigurieren
Config Scl = Portc.4
Config Sda = Portc.5
Config I2cdelay = 10
Portd = &B11111111

' LC-Display konfigurieren
Config Lcdbus = 4                                            ' LCD konfigurieren
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.4 , Rs = Portb.5
Config Lcd = 16 * 2
Cursor Off

' Interrupt konfigurieren
Config Int0 = Rising                                         'X=1 Rising X=0 Falling
On Int0 Enc                                                  'Interrupt Sub definieren
Enable Int0                                                  'Interrupt freigeben
Enable Interrupts                                            'Interrupt freigeben

' Encoder Variablen usw.
Dim A As Byte                                                ' Spur A Encoder
Dim B As Byte                                                ' Spur B Encoder
Dim S As Integer                                             ' Encoder Switch
Dim Enc_wert As Byte                                         'Rotation Zaehler
Dim X As Bit                                                 ' Flag t. toggeln INT Rising / Falling

' HYT-Variable etc.
Dim Lbyte1 As Byte
Dim Hbyte1 As Byte
Dim Lbyte2 As Byte
Dim Hbyte2 As Byte
Dim Bstatus As Byte
Dim Timeintervall As Byte
Dim Answer1 As Word
Dim Answer2 As Word
Dim Humidity As Single
Dim Temperature As Single
Dim Ha As String * 8
Dim Ta As String * 8

' Dimmer Variablen
Dim Licht As Byte

' Ablauf Variablem
Dim Menue As Byte                                            ' Hauptmenue Select Case
Dim Y As Byte                                                ' Werte sichern
Dim T_enc As Byte                                            ' Wert vom Encoder
Dim Sau_temp As Byte                                         ' Saunatemp. Wert
Dim Hyst As Byte                                             ' Schalthyterese
Dim Ths As Byte                                              ' T+H Regler Ein / Aus
Dim Tht As String * 5                                        ' Text "Ein o. Aus"
Dim Thw As Byte                                              ' T + W Wert
Dim Auto_aus As Byte                                         ' Saunaofen Autu Aus Timer
Dim Ein_zeit As Byte                                         ' Einschaltzeitpunkt für Auto Aus Timer

' Uhr Einstellung
Config Clock = User
Config Date = Dmy , Separator = .

' Addresse HYT Sensor
Const Hyt_w = &H50
Const Hyt_r = &H51
' Address des DS1307 $D0=schreiben $D1=lesen
Const Ds1307w = &HD0
Const Ds1307r = &HD1

' Nur zum stellen beim ersten initalisieren
Date$ = "07.04.88"                                           ' Geburtstag und
Time$ = "00:04:00"                                           ' Stunde meiner Tochter Maike
Cls                                                          ' LCD putzen
T_enc = 0                                                    ' Untermenue ausschalten
Menue = 1                                                    ' LCD Startmenue
X = 1                                                        ' def. InterruptRising

Readeeprom Sau_temp , 1                                      ' Werte laden
Readeeprom Hyst , 2
Readeeprom Licht , 3
Readeeprom Ths , 4
Readeeprom Thw , 5
Readeeprom Auto_aus , 6

'============================================================================
' Main Loop:

Do

 Select Case Menue                                           ' Hauptmenue

          Case 1
            Locate 1 , 1 : Lcd "    " ; Date$ ; "    "
            Locate 2 , 1 : Lcd "    " ; Time$ ; "    "

          Case 2
            Locate 1 , 1 : Lcd "Feuchte / Temp. "
            Locate 2 , 1 : Lcd Ha ; "%H  " ; Ta ; "ßC  "

          Case 3
            Locate 1 , 1 : Lcd "Uhr/Dat.stellen?"
            Locate 2 , 1 : Lcd "Taste drücken   "
            Debounce Pind.3 , 0 , Taste , Sub

          Case 4
            Locate 1 , 1 : Lcd "Sauna Temp einst"
            Locate 2 , 1 : Lcd "akt.  " ; Sau_temp ; "ßC      "
            Debounce Pind.3 , 0 , Taste , Sub

          Case 5
            Locate 1 , 1 : Lcd "Hyst. Sauna Temp"
            Locate 2 , 1 : Lcd "akt.  " ; Hyst ; "ßC      "
            Debounce Pind.3 , 0 , Taste , Sub

          Case 6
            Locate 1 , 1 : Lcd "Dimmer einst.   "
            Locate 2 , 1 : Lcd "akt.  " ; Licht ; "      "
            Debounce Pind.3 , 0 , Taste , Sub


          Case 7
            Locate 1 , 1 : Lcd "T + H Regler    "
            Locate 2 , 1 : Lcd "akt.  " ; Tht ; "        "
            Debounce Pind.3 , 0 , Taste , Sub

          Case 8
            Locate 1 , 1 : Lcd "T + H Wert einst"
            Locate 2 , 1 : Lcd "akt.  " ; Thw ; "          "
            Debounce Pind.3 , 0 , Taste , Sub

          Case 9
            Locate 1 , 1 : Lcd "Auto. Sauna Aus "
            Locate 2 , 1 : Lcd "akt.  " ; Auto_aus ; "          "
            Debounce Pind.3 , 0 , Taste , Sub


         Case Else
        '  Case 99
        '    'dummy case, keine Anzeige wenn Untermenue aktiv
 End Select


 Select Case T_enc                                           '1. Untermenue

         Case 0                                              ' kein Untermenue ausgewaehlt
            Menue = Enc_wert
            If Menue > 9 Then Enc_wert = 1                   ' Zaehler Menue begrenzen
            If Menue < 1 Then Enc_wert = 9

         Case 1                                              ' Uhrzeit Stunden stellen
            If Y = 0 Then
               Y = 1                                         ' Flag um Uhrzeit auf Enc Wert beim
               Enc_wert = _hour                              ' ersten Duchlauf zu uebernehmen
               Menue = 99                                    ' Hauptmenue ausblenden
            Else
               If Enc_wert > 23 Then Enc_wert = 1            ' 23 Stunden einschraenken
               If Enc_wert < 1 Then Enc_wert = 23
               _hour = Enc_wert
               Locate 1 , 1 : Lcd "Stunden stellen"
               Locate 2 , 1 : Lcd "     " ; _hour ; "         "
            End If

         Debounce Pind.3 , 0 , Taste , Sub                   ' weiter mit Minuten stellen

         Case 2                                              ' Uhrzeit Minuten stellen
            If Y = 1 Then
               Y = 2
               Enc_wert = _min
            Else
               If Enc_wert > 59 Then Enc_wert = 1            ' auf 59 Minuten begrenzen
               If Enc_wert < 1 Then Enc_wert = 59
               _min = Enc_wert
               Locate 1 , 1 : Lcd "Minuten stellen"
               Locate 2 , 1 : Lcd "     " ; _min ; "         "
            End If

         Debounce Pind.3 , 0 , Taste , Sub


          Case 3                                             ' Datum Tag stellen
            If Y = 2 Then
               Y = 3
               Enc_wert = _day
            Else
               If Enc_wert > 31 Then Enc_wert = 1
               If Enc_wert < 1 Then Enc_wert = 31
               _day = Enc_wert
               Locate 1 , 1 : Lcd "Tag stellen     "
               Locate 2 , 1 : Lcd "     " ; _day ; "         "
            End If

          Debounce Pind.3 , 0 , Taste , Sub

          Case 4                                             'Datum Monat stellen
            If Y = 3 Then
               Y = 4
               Enc_wert = _month
            Else
               If Enc_wert > 12 Then Enc_wert = 1
               If Enc_wert < 1 Then Enc_wert = 12
               _month = Enc_wert
               Locate 1 , 1 : Lcd "Monat stellen   "
               Locate 2 , 1 : Lcd "     " ; _month ; "         "
            End If

          Debounce Pind.3 , 0 , Taste , Sub


         Case 5                                              ' Datum Jahr stellen
            If Y = 4 Then
               Y = 5
               Enc_wert = _year
            Else
               If Enc_wert > 99 Then Enc_wert = 1
               If Enc_wert < 1 Then Enc_wert = 99
               _year = Enc_wert
               Locate 1 , 1 : Lcd "Jahr stellen      "
               Locate 2 , 1 : Lcd "     " ; _year ; "         "
            End If

          Debounce Pind.3 , 0 , Taste , Sub

         Case 6                                              ' Untermenue verlassen
            _sec = 0                                         ' Sekunden auf Null
            T_enc = 0                                        ' wenn Null wieder Hauptmenue
            Y = 0                                            ' Anzeige Startmenue
            Menue = 1
            Gosub Settime
            Gosub Setdate

         Case 7                                              ' Sauna Temperatur vorgabe
            If Y = 0 Then
               Y = 1
               Enc_wert = Sau_temp
               Menue = 99
            Else
               If Enc_wert > 120 Then Enc_wert = 30
               If Enc_wert < 30 Then Enc_wert = 120
               Sau_temp = Enc_wert
               Locate 1 , 1 : Lcd "Sauna Temp.wahl  "
               Locate 2 , 1 : Lcd "neu  " ; Sau_temp ; "         "
            End If

           Debounce Pind.3 , 0 , Taste , Sub

         Case 8                                              ' Untermenue verlassen
             Writeeeprom Sau_temp , 1
             Y = 0
             T_enc = 0
             Menue = 1

          Case 9                                             ' Hysterse einstellen
            If Y = 0 Then
               Y = 1
               Enc_wert = Hyst
               Menue = 99
            Else
               If Enc_wert > 10 Then Enc_wert = 1
               If Enc_wert < 1 Then Enc_wert = 10
               Hyst = Enc_wert
               Locate 1 , 1 : Lcd "   Hysterese    "
               Locate 2 , 1 : Lcd "neu  " ; Hyst ; "         "
            End If

           Debounce Pind.3 , 0 , Taste , Sub

         Case 10                                             ' Untermenue verlassen
             Writeeeprom Hyst , 2
             Y = 0
             T_enc = 0
             Menue = 1

         Case 11                                             ' Dimmer einstellen
            If Y = 0 Then
               Y = 1
               Enc_wert = Licht
               Menue = 99
            Else
               If Enc_wert > 100 Then Enc_wert = 100
               If Enc_wert < 1 Then Enc_wert = 1
               Licht = Enc_wert
               Locate 1 , 1 : Lcd "    Dimmer      "
               Locate 2 , 1 : Lcd "neu  " ; Licht ; " %       "
            End If

           Debounce Pind.3 , 0 , Taste , Sub

         Case 12                                             ' Untermenue verlassen
             Writeeeprom Licht , 3
             Y = 0
             T_enc = 0
             Menue = 1

          Case 13                                            ' T&H Regler An / Aus
            If Y = 0 Then
               Y = 1
               Enc_wert = Ths
               Menue = 99
            Else
               If Enc_wert > 1 Then Enc_wert = 0
               If Enc_wert < 0 Then Enc_wert = 1
               Ths = Enc_wert
                If Ths = 0 Then
                Tht = "Aus"
                Else
                Tht = "An"
                End If
               Locate 1 , 1 : Lcd "  T & H Regler  "
               Locate 2 , 1 : Lcd "     " ; Tht ; "         "
            End If

           Debounce Pind.3 , 0 , Taste , Sub

         Case 14                                             ' Untermenue verlassen
              Writeeeprom Ths , 4
             Y = 0
             T_enc = 0
             Menue = 1

         Case 15                                             ' T&H wert einstellen
            If Y = 0 Then
               Y = 1
               Enc_wert = Thw
               Menue = 99
            Else
               If Enc_wert > 150 Then Enc_wert = 50
               If Enc_wert < 50 Then Enc_wert = 150
               Thw = Enc_wert
               Locate 1 , 1 : Lcd "T + H Temp.wert "
               Locate 2 , 1 : Lcd "     " ; Thw ; " ßC       "
            End If

           Debounce Pind.3 , 0 , Taste , Sub

         Case 16                                             ' Untermenue verlassen
             Writeeeprom Thw , 5
             Y = 0
             T_enc = 0
             Menue = 1

         Case 17                                             ' Saunaofen Auto Aus
            If Y = 0 Then
               Y = 1
               Enc_wert = Auto_aus
               Menue = 99
            Else
               If Enc_wert > 6 Then Enc_wert = 1
               If Enc_wert < 1 Then Enc_wert = 6
               Auto_aus = Enc_wert
               Locate 1 , 1 : Lcd "Sauna autom. aus"
               Locate 2 , 1 : Lcd "in " ; Auto_aus ; " Stunden    "
            End If

         Debounce Pind.3 , 0 , Taste , Sub


          Case 18                                            ' Untermenue verlassen
               Writeeeprom Auto_aus , 6
               Y = 0
               Menue = 1
               T_enc = 0

 End Select

 Gosub Hyt_auslesen                                          ' HYT Sensor auslesen


 ' Saunaofen 2 Punkt Regler
 '
 '
 ' Saunaofen T & H Regeler
 '
 '
 ' Dimmer
 '
 '
 ' Auto Aus

Loop

'==============================================================================
 
Teil2 Quellcode

Code:
' HYT-Sensor auslesen - teils aus Robo-netz kopiert

Hyt_auslesen:
   I2cstart
   I2cwbyte Hyt_w
   I2cstop
   ' Routine testet, ob der Messvorgang abgeschlossen ist (55-70 ms)
   Do
      Err = 0
      I2cstart
      I2cwbyte Hyt_r
      I2crbyte Hbyte1 , Ack

      Bstatus = Hbyte1 And &HC0
      Shift Bstatus , Right , 6
      ' only if it is 0 the result is valid
      If Bstatus = 0 Then Exit Do
      ' If error leave  also
      ' If Errstatus > 0 Then Exit Do
      I2cstop
   Loop

   ' Dann kann ausgelesen werden
   ' Die restlichen 3 Bytes auslesen (Das 1. wurde schon ausgelesen)
   I2crbyte Lbyte1 , Ack
   I2crbyte Hbyte2 , Ack
   I2crbyte Lbyte2 , Nack
   I2cstop

   ' Berechnung der Werte aus den 4 ausgelesenen Bytes
   ' 1. Luftfeuchte (Hbyte1 und Lbyte1)
   ' Zuerst die Status-Bits loeschen
   Hbyte1 = Hbyte1 And &H3F
   Answer1 = Hbyte1
   Shift Answer1 , Left , 8
   Answer1 = Answer1 Or Lbyte1
   Humidity = Answer1 / 163.84
   Ha = Fusing(humidity , "#.#")
   '
   ' 2. Temperatur (Hbyte2 und Lbyte2)
   Answer2 = Hbyte2
   Shift Answer2 , Left , 8
   Lbyte2 = Lbyte2 And &HFC
   Answer2 = Answer2 Or Lbyte2
   Temperature = Answer2
   Temperature = Temperature / 65536
   Temperature = Temperature * 165
   Temperature = Temperature - 40
   Ta = Fusing(temperature , "#.#")
Return



 ' Benutzer definierte Routinen die von der datetime.lib im BASCOM genutzt werden
 ' teils aus AVR Praxis kopiert

Dim Weekday As Byte
Getdatetime:
  I2cstart                                                   ' Start
  I2cwbyte Ds1307w                                           ' DS1307 schreiben
  I2cwbyte 0                                                 ' DS1307 Adresszeiger auf 0 stellen

  I2cstart                                                   ' Start
  I2cwbyte Ds1307r                                           ' DS1307 lesen (ab vorher eingestellter Adresse 0)
  I2crbyte _sec , Ack                                        ' Sekunden
  I2crbyte _min , Ack                                        ' Minuten
  I2crbyte _hour , Ack                                       ' Stunden
  I2crbyte Weekday , Ack                                     ' Wochentag (in Dummy gelesen da von date$/time$ nicht genutzt)
  I2crbyte _day , Ack                                        ' Tag
  I2crbyte _month , Ack                                      ' Monat
  I2crbyte _year , Nack                                      ' Jahr
  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                                                   ' Start
  I2cwbyte Ds1307w                                           ' DS1307 schreiben
  I2cwbyte 4                                                 ' DS1307 Adresszeiger auf 4 (Byte 5) stellen
  I2cwbyte _day                                              ' Tag schreiben
  I2cwbyte _month                                            ' Monat schreiben
  I2cwbyte _year                                             ' Jahr schreiben
  I2cstop
Return

Settime:
  _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
  I2cstart                                                   ' Start
  I2cwbyte Ds1307w                                           ' DS1307 schreiben
  I2cwbyte 0                                                 ' DS1307 Adresszeiger auf 0 stellen
  I2cwbyte _sec                                              ' Sekunden schreiben
  I2cwbyte _min                                              ' Minuten schreiben
  I2cwbyte _hour                                             ' Stunden schreiben
  I2cstop
Return


'Interrupt vom Encoder

Enc:
 A = Pind.1                                                  ' Encoder Spur A
 B = Pind.2                                                  ' Encoder Spur B

 If A = B Then                                               ' Encoder Dreh-Richtung erkennen
    Decr Enc_wert                                            ' Wert von R -1
  Else
   Incr Enc_wert                                             ' Wert von R +1
 End If

 If X = 1 Then                                               ' Toggeln INT0 Rising / Falling
  Config Int0 = Falling                                      ' sondt wird nur jeder 2, Schritt erkannt
  X = 0
 Else
  Config Int0 = Rising
  X = 1
 End If

Return

' Encoder switch

Taste:
 Select Case Menue                                           ' Achtung T_enc am Ende  immer +1

      Case 3
         T_enc = 0                                           ' T_Enc 1 bis 6 Uhr/Datum stellen

      Case 4
         T_enc = 6                                           ' T_Enc 7 bis 8 Sauna Temp einstellen

      Case 5
         T_enc = 8                                           ' T_enc 8 bis 10 Hysterese einstellen

      Case 6
         T_enc = 10                                          ' T_enc 10 bis 12 Dimmer

      Case 7
         T_enc = 12                                          ' T_enc 12 bis 14  T+H Regler Ein/Aus

      Case 8
         T_enc = 14                                          ' T_enc 14 bis 16  T+H Regler Wert

      Case 9
         T_enc = 16                                          ' T_enc 16 bis 18 Sauna Auto Aus

    End Select

 Incr T_enc                                                  ' T_enc +1

Return

'wird z.Zt. nicht benutzt

Sectic:
Return


End
 

Anhänge

  • HYT-321 und Encoder und DS1307-003.bas
    20,1 KB · Aufrufe: 54

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)