'****************************************************************
'*  Name    : Schakelklok                                       *
'*  Author  : Coenen Stijn [Stynus]                             *
'*  Notice  : Copyright (c) 2009 ElektronicaStynus.be           *
'*          : All Rights Reserved                               *
'*  Date    : 01/02/2009                                        *
'*  Version : 1.2                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
Device 16F648A
Config INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
All_Digital TRUE 
'****************************************************************
    'Algemeen
    Symbol knop_up          = PORTA.4: TRISA.4 = 1
    Symbol knop_enter       = PORTA.5: TRISA.5 = 1
    Symbol knop_down        = PORTA.3: TRISA.3 = 1
    Symbol ldr              = PORTA.7: TRISA.7 = 1
    Symbol triac            = PORTB.1: TRISB.1 = 0
    '************************************************************
    'Lcd
    Declare LCD_DTPin       PORTB.4
    Declare LCD_ENPin       PORTB.3
    Declare LCD_RSPin       PORTB.2
    Declare LCD_Interface   4 
    Declare LCD_Lines       2
    Print $FE,$40,$0E,$0A,$0E,$00,$00,$00,$00,$00     ' 
    Symbol  Grad            = 0
    Symbol  M               = 1
    Symbol  e               = 2
    Symbol  n               = 3
    Symbol  u               = 4
    '************************************************************
    'RTC
    Symbol  DS_SDA          = PORTA.0
    Symbol  DS_SLC          = PORTA.1
    Symbol  DS_Reset        = PORTA.2        
    Dim     Seconden        As Byte
    Dim     Minuten         As Byte
    Dim     Uren            As Byte
    Dim     Temperatuur     As Byte
    Symbol  Reg_Seconden    =  $00 
    Symbol  Reg_Minuten     =  $01
    Symbol  Reg_Uren        =  $02
    Symbol  Reg_Temp        =  $11
    'Ram registers
    Symbol  Reg_ldr         = $14
    Symbol  Reg_TijdAanU1   = $15
    Symbol  Reg_TijdAanM1   = $16
    Symbol  Reg_TijdUitU1   = $17
    Symbol  Reg_TijdUitM1   = $18
    Symbol  Reg_Tijd2Gebr   = $19
    Symbol  Reg_TijdAanU2   = $20
    Symbol  Reg_TijdAanM2   = $21
    Symbol  Reg_TijdUitU2   = $22
    Symbol  Reg_TijdUitM2   = $23
    Symbol  Reg_ldr2        = $24
    Symbol  Lezen           =  %11010000
    Symbol  Schrijven       =  %11010001
    '************************************************************
    'Subroutine
    Dim     BCD_In          As Byte
    Dim     Byte_Uit        As Byte
    Dim     Hbits           As Byte
    Dim     Lbits           As Byte
    Dim     BCD_Uit         As Byte
    Dim     Byte_In         As Byte   
    Dim     Uur_sub         As Byte
    Dim     Min_sub         As Byte  
   '************************************************************
   'Instellen 
    Dim     temp            As Byte 
    
    Dim     teller          As Byte
    
    Dim     Ldr_insch       As Byte
    Dim     AanTijdu1       As Byte
    Dim     AanTijdm1       As Byte
    Dim     UitTijdu1       As Byte
    Dim     aan2            As Byte
    Dim     UitTijdm1       As Byte
    Dim     AanTijdu2       As Byte
    Dim     AanTijdm2       As Byte
    Dim     UitTijdu2       As Byte
    Dim     UitTijdm2       As Byte
    Dim     Ldr_uitsc       As Byte     
    
    Dim     lezen_reg       As Byte
    Dim     lezen_uit       As Byte
    
    Dim     schrv_reg       As Byte
    Dim     schrv_in        As Byte
    
    Dim     triac_bit       As Bit
    Dim     dagnacht        As Bit
'****************************************************************
Opstarten:
    Clear
    Cls
    DelayMS 100
    Print At 1,1, "Schematheek.net"
    Print At 2,1, "LDR-schakelklok"
    DelayMS 1500
    Cls
    triac = 0
    GoTo Hoofdprogramma
'****************************************************************
'Subroutines
    Inlezen:
        lezen_reg = Reg_Seconden: GoSub DS_lezen: Seconden      = lezen_uit
        lezen_reg = Reg_Minuten : GoSub DS_lezen: Minuten       = lezen_uit   
        lezen_reg = Reg_Uren    : GoSub DS_lezen: Uren          = lezen_uit
        lezen_reg = Reg_Temp    : GoSub DS_lezen: Temperatuur   = lezen_uit
    Return
    Omzetten:
        'Seconden   
        BCD_In = Seconden : GoSub BCD_To_Byte: Seconden = Byte_Uit   
        'Minuten
        BCD_In = Minuten  : GoSub BCD_To_Byte: Minuten  = Byte_Uit   
        'Uren  
        Uren.7 = 0 
        Uren.6 = 0
        BCD_In = Uren     : GoSub BCD_To_Byte: Uren     = Byte_Uit   
        'Temperatuur    
        Temperatuur.7 = 0
    Return
    BCD_To_Byte:
        'Hoogste 4 bits omzetten (Tientallen)
        Byte_Uit    = 0
        Byte_Uit.0  = BCD_In.4
        Byte_Uit.1  = BCD_In.5
        Byte_Uit.2  = BCD_In.6
        Byte_Uit.3  = BCD_In.7
        Byte_Uit    = Byte_Uit * 10 
        'Laagste 4 bits omzetten (Eenheden)
        BCD_In.4    = 0
        BCD_In.5    = 0
        BCD_In.6    = 0
        BCD_In.7    = 0
        Byte_Uit    = BCD_In + Byte_Uit
    Return
    Byte_To_BCD:    
        'Hoge bits
        Hbits = Byte_In / 10                
        'Lagebits
        Lbits = Byte_In - (Hbits * 10)  
        'Hoge bits doorschuiven               
        Hbits = Hbits << 4
        'Samenvoegen
        BCD_Uit = Lbits + Hbits               
    Return
    AU_inst:  
       Print At 2,12,   "Uur"        
        While 1 = 1
            If knop_up = 0 Then                
                If Uur_sub < 23 Then
                    Inc Uur_sub
                EndIf
                Print At 2,1, Dec2 Uur_sub 
                While knop_up = 0 : Wend
            EndIf
            If knop_down = 0 Then        
                If Uur_sub > 0 Then
                    Dec Uur_sub
                EndIf
                Print At 2,1, Dec2 Uur_sub 
                While knop_down = 0 : Wend
            EndIf
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200 
                Break
            EndIf  
        Wend         
        Print At 2,12,   "Min"            
        While 1 = 1
            If knop_up = 0 Then                
                If Min_sub < 60 Then
                    Inc Min_sub
                EndIf
                Print At 2,4, Dec2 Min_sub 
                While knop_up = 0 : Wend
            EndIf
            If knop_down = 0 Then        
                If Min_sub > 0 Then
                    Dec Min_sub
                EndIf
                Print At 2,4, Dec2 Min_sub 
                While knop_down = 0 : Wend
            EndIf
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200 
                Break
            EndIf  
        Wend  
    Return
    DS_lezen:
        I2CIN  DS_SDA, DS_SLC, Lezen, lezen_reg, [lezen_uit]
    Return
    DS_schrijven:
        I2COUT DS_SDA, DS_SLC, Schrijven ,schrv_reg, [schrv_in]
    Return   
'****************************************************************
Hoofdprogramma:
    lezen_reg = Reg_ldr      : GoSub DS_lezen: Ldr_insch = lezen_uit
    lezen_reg = Reg_TijdAanU1: GoSub DS_lezen: AanTijdu1 = lezen_uit
    lezen_reg = Reg_TijdAanM1: GoSub DS_lezen: AanTijdm1 = lezen_uit
    lezen_reg = Reg_TijdUitU1: GoSub DS_lezen: UitTijdu1 = lezen_uit
    lezen_reg = Reg_TijdUitM1: GoSub DS_lezen: UitTijdm1 = lezen_uit    
    lezen_reg = Reg_Tijd2Gebr: GoSub DS_lezen: aan2      = lezen_uit
    lezen_reg = Reg_TijdAanU2: GoSub DS_lezen: AanTijdu2 = lezen_uit
    lezen_reg = Reg_TijdAanM2: GoSub DS_lezen: AanTijdm2 = lezen_uit
    lezen_reg = Reg_TijdUitU2: GoSub DS_lezen: UitTijdu2 = lezen_uit  
    lezen_reg = Reg_TijdUitM2: GoSub DS_lezen: UitTijdm2 = lezen_uit  
    lezen_reg = Reg_ldr2     : GoSub DS_lezen: Ldr_uitsc = lezen_uit                                            
While 1 = 1
    
    GoSub Inlezen
    GoSub Omzetten

    Print At 1,1, Dec2 Uren, ":", Dec2 Minuten, ":", Dec2 Seconden, "    ", Dec2 Temperatuur, Grad, "C"
            
    
    'triac = triac_bit
    
    If triac_bit = 1 Then
                      '1234567890123456
        Print At 2,1, "Lamp: aan -Menu-"
        High triac
    Else
                      '1234567890123456
        Print At 2,1, "Lamp: uit -Menu-"
        Low triac   
    EndIf   
     
    'S avonds aandoen
    If triac_bit = 0 And Uren > 15 Then
        If Ldr_insch = 1 Then
            If ldr = 0 And dagnacht = 0 Then
                triac_bit = 1
                dagnacht = 1
            EndIf    
        Else
            If Uren = AanTijdu1 And Minuten = AanTijdm1 Then
                triac_bit = 1 
            EndIf
        EndIf
    EndIf
    'S avonds uitdoen
    If triac_bit = 1 Then
        If Uren = UitTijdu1 And Minuten = UitTijdm1 Then
            triac_bit = 0 
        EndIf
    EndIf
    
    'nacht gedaan:
    If ldr = 1 Then
        dagnacht = 0
    EndIf
    
    'Smorgens aandoen
    If triac_bit = 0 And aan2 = 1 Then
        If Uren = AanTijdu2 And Minuten = AanTijdm2 Then
            triac_bit = 1
        EndIf
    EndIf 
    'Smorgens uitdoen
    If triac_bit = 1 And aan2 = 1 Then
        If Ldr_uitsc = 1 Then
            If ldr = 1 Then
                triac_bit = 0
            EndIf    
        Else
            If Uren = UitTijdu2 And Minuten = UitTijdm2 Then
                triac_bit = 0 
            EndIf
        EndIf
    EndIf   
    
    If knop_enter = 0 Then
        GoTo Hoofd_Menu
    EndIf

    DelayMS 300
Wend
'****************************************************************
Hoofd_Menu:                        
    While knop_enter = 0: Wend
    '************************************************************
    Tijd_instellen:
        Cls
        DelayMS 50    '1234567890123456
        Print At 1,1, "* Tijd instellen"
        Print At 2,1, "  Lichttijd inst"
        teller = 0
        While 1 = 1
            If knop_down = 0 Then
                While knop_down = 0 : Wend
                GoTo Lichttijd_inst
            EndIf
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200
                GoTo Tijd_instellen_enter
            EndIf   
            DelayMS 50
            Inc teller
            If teller = 255 Then
                GoTo Hoofdprogramma
            EndIf  
        Wend   
    '************************************************************  
    Lichttijd_inst:
        Cls
        DelayMS 50
        Print At 1,1, "  Tijd instellen"
        Print At 2,1, "* Lichttijd inst"
        teller = 0
        While 1 = 1
            If knop_up = 0 Then
                While knop_up = 0 : Wend
                GoTo Tijd_instellen
            EndIf    
            If knop_down = 0 Then
                While knop_down = 0 : Wend
                GoTo LDR_inst
            EndIf    
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200 
                GoTo Lichttijd_instellen
            EndIf   
            DelayMS 50
            Inc teller
            If teller = 255 Then
                GoTo Hoofdprogramma
            EndIf   
        Wend
    '************************************************************  
    LDR_inst:
        Cls
        DelayMS 50
        Print At 1,1, "* LDR afstellen "
        Print At 2,1, "  Exit          "
        teller = 0
        While 1 = 1
            If knop_up = 0 Then
                While knop_up = 0 : Wend
                GoTo Lichttijd_inst
            EndIf    
            If knop_down = 0 Then
                While knop_down = 0 : Wend
                GoTo Exit
            EndIf    
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200 
                GoTo LDR_afst
            EndIf   
            DelayMS 50
            Inc teller
            If teller = 255 Then
                GoTo Hoofdprogramma
            EndIf   
        Wend
    '************************************************************  
    Exit:
        Cls
        DelayMS 50
        Print At 1,1, "  LDR afstellen "
        Print At 2,1, "* Exit          "
        teller = 0
        While 1 = 1
            If knop_up = 0 Then
                While knop_up = 0 : Wend
                GoTo LDR_inst
            EndIf    
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200 
                GoTo Hoofdprogramma
            EndIf   
            DelayMS 50
            Inc teller
            If teller = 255 Then
                GoTo Hoofdprogramma
            EndIf   
        Wend 
    '************************************************************  
    Tijd_instellen_enter:  'Tijd instellen
        Cls
        GoSub Inlezen
        GoSub Omzetten
        Print At 2,1, Dec2 Uren, ":", Dec2 Minuten, ":", Dec2 Seconden 
        'uren instellen
                        '1234567890123456
        Print At 1,1,   "Tijd:       Uren"
        While 1 = 1
            If knop_up = 0 Then                
                If Uren < 23 Then
                    Inc Uren
                EndIf
                Print At 2,1, Dec2 Uren 
                While knop_up = 0 : Wend
            EndIf
            If knop_down = 0 Then        
                If Uren > 0 Then
                    Dec Uren
                EndIf
                Print At 2,1, Dec2 Uren 
                While knop_down = 0 : Wend
            EndIf
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200 
                Break
                'GoTo Minuten_instellen
            EndIf  
        Wend                                 
        'Minuten instellen
                        '1234567890123456
        Print At 1,1,   "Tijd:    Minuten"  
        While 1 = 1
            If knop_up = 0 Then                
                If Minuten < 60 Then
                    Inc Minuten
                EndIf
                Print At 2,4, Dec2 Minuten 
                While knop_up = 0 : Wend
            EndIf
            If knop_down = 0 Then        
                If Minuten > 0 Then
                    Dec Minuten
                EndIf
                Print At 2,4, Dec2 Minuten 
                While knop_down = 0 : Wend
            EndIf
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200 
                Break
            EndIf                                   
        Wend  
        'Seconden instellen
                        '1234567890123456
        Print At 1,1,   "Tijd:   Seconden"        
        While 1 = 1
            If knop_up = 0 Then                
                If Seconden < 60 Then
                    Inc Seconden
                EndIf
                Print At 2,7, Dec2 Seconden 
                While knop_up = 0 : Wend
            EndIf
            If knop_down = 0 Then        
                If Seconden > 0 Then
                    Dec Seconden
                EndIf
                Print At 2,7, Dec2 Seconden 
                While knop_down = 0 : Wend
            EndIf
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200 
                Break
            EndIf                                   
        Wend        
        'Omzetten en wegschrijven
            'Seconden
                Byte_In = Seconden : GoSub Byte_To_BCD : Seconden  = BCD_Uit
                schrv_reg = Reg_Seconden: schrv_in = Seconden: GoSub DS_schrijven 
            'Minuten
                Byte_In = Minuten : GoSub Byte_To_BCD : Minuten  = BCD_Uit
                schrv_reg = Reg_Minuten: schrv_in = Minuten: GoSub DS_schrijven 
            'Uren
                Byte_In = Uren : GoSub Byte_To_BCD : Uren  = BCD_Uit
                schrv_reg = Reg_Uren :schrv_in = Uren: GoSub DS_schrijven               
    GoTo Hoofdprogramma
    '************************************************************  
    Lichttijd_instellen:
        Cls
                        '1234567890123456
        Print At 1,1,   " LDR gebruiken? "    
        Print At 2,1,   "      Ja        " 
        temp = 1
        While 1 = 1
            If knop_up = 0 Then                
                Print At 2,1,   "      Ja        "
                temp = 1
                While knop_up = 0 : Wend
            EndIf
            If knop_down = 0 Then        
                Print At 2,1,   "      Nee       "
                temp = 0
                While knop_down = 0 : Wend
            EndIf
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200 
                Break
            EndIf  
        Wend
        I2COUT DS_SDA, DS_SLC, Schrijven ,Reg_ldr, [temp]  
        If temp = 0 Then
            Cls
                            '1234567890123456
            Print At 1,1,   "Aanschakeltijd1:"  
            lezen_reg = Reg_TijdAanU1: GoSub DS_lezen: Uur_sub = lezen_uit         
            Print At 2,1, Dec2 Uur_sub, ":"    
            lezen_reg = Reg_TijdAanM1: GoSub DS_lezen: Min_sub = lezen_uit            
            Print At 2,4, Dec2 Min_sub
            GoSub AU_inst           
            schrv_reg = Reg_TijdAanU1 :schrv_in = Uur_sub: GoSub DS_schrijven 
            schrv_reg = Reg_TijdAanM1 :schrv_in = Min_sub: GoSub DS_schrijven              
        EndIf 
        'Uitschakeltijd
        Cls
                        '1234567890123456
        Print At 1,1,   "Uitschakeltijd1:"    
            lezen_reg = Reg_TijdUitU1: GoSub DS_lezen: Uur_sub = lezen_uit     
            Print At 2,1, Dec2 Uur_sub, ":"      
            lezen_reg = Reg_TijdUitM1: GoSub DS_lezen: Min_sub = lezen_uit            
            Print At 2,4, Dec2 Min_sub
            GoSub AU_inst 
            schrv_reg = Reg_TijdUitU1 :schrv_in = Uur_sub: GoSub DS_schrijven 
            schrv_reg = Reg_TijdUitM1 :schrv_in = Min_sub: GoSub DS_schrijven                         
        'Smorgens licht? 
        Cls
                        '1234567890123456
        Print At 1,1,   "S'morgens licht?"    
        Print At 2,1,   "      Ja        " 
        temp = 1
        While 1 = 1
            If knop_up = 0 Then                
                Print At 2,1,   "      Ja        "
                temp = 1
                While knop_up = 0 : Wend
            EndIf
            If knop_down = 0 Then        
                Print At 2,1,   "      Nee       "
                temp = 0
                While knop_down = 0 : Wend
            EndIf
            If knop_enter = 0 Then
                While knop_enter = 0 : Wend
                DelayMS 200 
                Break
            EndIf  
        Wend 
        schrv_reg = Reg_Tijd2Gebr :schrv_in = temp: GoSub DS_schrijven 
        If temp = 1 Then
            'Inschakeltijd
            Cls
                            '1234567890123456
            Print At 1,1,   "Inschakeltijd2:"     
            lezen_reg = Reg_TijdAanU2: GoSub DS_lezen: Uur_sub = lezen_uit     
            Print At 2,1, Dec2 Uur_sub, ":"   
            lezen_reg = Reg_TijdAanM2: GoSub DS_lezen: Min_sub = lezen_uit               
            Print At 2,4, Dec2 Min_sub
            GoSub AU_inst  
            schrv_reg = Reg_TijdAanU2 :schrv_in = Uur_sub: GoSub DS_schrijven 
            schrv_reg = Reg_TijdAanM2 :schrv_in = Min_sub: GoSub DS_schrijven             
            Cls       
            Print At 1,1,   "Uit met LDR?"    
            Print At 2,1,   "      Ja        " 
            While 1 = 1
                If knop_up = 0 Then                
                    Print At 2,1,   "      Ja        "
                    temp = 1
                    While knop_up = 0 : Wend
                EndIf
                If knop_down = 0 Then        
                    Print At 2,1,   "      Nee       "
                    temp = 0
                    While knop_down = 0 : Wend
                EndIf
                If knop_enter = 0 Then
                    While knop_enter = 0 : Wend
                    DelayMS 200 
                    Break
                EndIf  
            Wend 
            schrv_reg = Reg_ldr2 :schrv_in = temp: GoSub DS_schrijven 
            If temp = 0 Then
                Cls
                                '1234567890123456
                Print At 1,1,   "Uitschakeltijd2:" 
                lezen_reg = Reg_TijdUitU2: GoSub DS_lezen: Uur_sub = lezen_uit         
                Print At 2,1, Dec2 Uur_sub, ":"   
                lezen_reg = Reg_TijdUitM2: GoSub DS_lezen: Min_sub = lezen_uit              
                Print At 2,4, Dec2 Min_sub
                GoSub AU_inst      
                schrv_reg = Reg_TijdUitU2 :schrv_in = Uur_sub: GoSub DS_schrijven 
                schrv_reg = Reg_TijdUitM2 :schrv_in = Min_sub: GoSub DS_schrijven        
            EndIf
        EndIf         
    GoTo Hoofdprogramma
    LDR_afst:
        Cls
                        '1234567890123456
        Print At 1,1,   " LDR afstellen  "  
        While 1 = 1
                If ldr = 1 Then   
                                    '1234567890123456             
                    Print At 2,1,   "      licht     "
                Else
                                    '1234567890123456       
                    Print At 2,1,   "     donker     "
                EndIf
                If knop_enter = 0 Then
                    While knop_enter = 0 : Wend
                    DelayMS 200 
                    Break
                EndIf  
            Wend          
    GoTo Hoofdprogramma
End