'****************************************************************
'*  Name    : IN-14 Nixie klok                                  *
'*  Author  : Stijn Coenen [Stynus]  www.ElektronicaStynus.Be   *
'*  Notice  : Licenced under Creative Commons                   *
'*          : Attribution-Noncommercial 2.0 Belgium Licence     *
'*          : http://creativecommons.org/licenses/by-nc/2.0/be/ *
'*  Date    : 6/03/2010                                         *
'*  Version : 1.0                                               *
'****************************************************************
Device  16F628A
Config  INTRC_OSC_NOCLKOUT, WDT_off, PWRTE_ON, LVP_off, MCLRE_OFF, BOREN_OFF
All_Digital     TRUE 
'****************************************************************
'In en uitgangen
    'Nixies en neons
        Symbol  klok      = PORTB.6
        Symbol  ZetVast   = PORTB.5
        Symbol  Data_Pin  = PORTB.4
    'RTC
        Symbol  SDA       = PORTA.3
        Symbol  SLC       = PORTA.2
    'Temperatuursensor      
        Symbol  one_wire  = PORTA.4
    'Knoppen
        Symbol  KnopL     = PORTA.1 : TRISA.1 = 1
        Symbol  KnopM     = PORTA.0 : TRISA.0 = 1
        Symbol  KnopR     = PORTA.7 : TRISA.7 = 1
    'Leds
        Symbol  LedT      = PORTB.3 : TRISB.3 = 0
        Symbol  LedD      = PORTB.1 : TRISB.1 = 0
        Symbol  LedU      = PORTB.0 : TRISB.0 = 0
'****************************************************************       
    Dim     Seconden        As Byte
    Dim     Minuten         As Byte
    Dim     Uren            As Byte
    Dim     Datum           As Byte
    Dim     Maand           As Byte
    Dim     Jaar            As Byte
    Dim     Temperatuur     As Byte 
    Dim     TemperatuurW    As Word
    '************************************************************ 
    'Subroutine variable
    Dim     temp            As Byte
    Dim     getal           As Byte
    Dim     ZetOm           As Byte
    Dim     y               As Byte
    Dim     tot             As Byte
    '************************************************************
    Dim     index           As Byte 
    Dim     digit1          As Byte
    Dim     digit2          As Byte
    '************************************************************ 
    'De nixie aansluitingen zitten niet op de normale plaatsen van
    'de driver ic om plaats te besparen, daarom geef ik aliassen  
    'aan de cijfers die overeenkomen met de bcd code van dat cijfer
    'op mijn print
    'The nixie connections are not on the normal positions off the 
    'driver ic. I did this to safe some space on the PCB. On the 
    'following piece of code I'm giving aliases to the Dutch name
    'of the numbers that represent the bcd code from the digit on
    'my pcb
    Symbol Nul      = %00000001  
    Symbol Een      = %00001100            
    Symbol Twee     = %00000100 
    Symbol Drie     = %00001001 
    Symbol Vier     = %00000000 
    Symbol Vijf     = %00001000 
    Symbol Zes      = %00000010 
    Symbol Zeven    = %00001011 
    Symbol Acht     = %00001010 
    Symbol Negen    = %00000011                                   
    '************************************************************ 
    'Aliassen  voor de registers in de RTC
    'Aliases for the registers in the RTC
    Symbol  Reg_Seconden    =  $00            
    Symbol  Reg_Minuten     =  $01
    Symbol  Reg_Uren        =  $02
    Symbol  Reg_Dag         =  $03
    Symbol  Reg_Datum       =  $04
    Symbol  Reg_Maand       =  $05
    Symbol  Reg_Jaar        =  $06
    'Controle bytes RTC
    Symbol  Lezen           =  %11010001  'Read
    Symbol  Schrijven       =  %11010000  'Write 
'****************************************************************   
Clear  
GoTo OverSub  
'****************************************************************  
'Sub routines 
    '************************************************************
    'Deze subroutine zet een BCD getal om in een BCD getal dat 
    'overeenkomt met de aansluitingen ven de nixies op de driver ic's
    'This subroutine changes a BCD number in to another BCD number
    'that represents the connections of the nixie on the driver ic's
    Omzetten:
        'De 4 laagste bits uit getal halen
        'Get the lower 4 bits out of getal
        getal = ZetOm & %00001111
        'De nieuwe bcd waarde voor dat getal opzoeken
        'Get the new bcd value for that number   
        Select getal                
            Case 0
                getal = Nul
            Case 1
                getal = Een
            Case 2
                getal = Twee
            Case 3
                getal = Drie
            Case 4
                getal = Vier
            Case 5
                getal = Vijf
            Case 6
                getal = Zes
            Case 7
                getal = Zeven
            Case 8
                getal = Acht
            Case 9
                getal = Negen
            Case Else
                getal = %00001111 'Uit
        EndSelect
        'De 4 laagste bits in getal 4 plaatsen naar links opschuiven (De nixie drivers
        'hangen omgekeerd op de 74HC595 ic's.) Daarna in temp zetten
        'Put the 4 lowest bits in getal 4 places to the left. (The nixie drivers are 
        'reversed connected to the 74HC595 ic's.) Then put it in temp
        temp = getal << 4
        'Tientallen
        
        'De 4 hoogste bits uit getal halen
        'Get the higher 4 bits out of getal
        getal = ZetOm & %11110000
        getal = getal >> 4 
        'De nieuwe bcd waarde voor dat getal opzoeken
        'Get the new bcd value for that number   
        Select getal
            Case 0
                getal = Nul
            Case 1
                getal = Een
            Case 2
                getal = Twee
            Case 3
                getal = Drie
            Case 4
                getal = Vier
            Case 5
                getal = Vijf
            Case 6
                getal = Zes
            Case 7
                getal = Zeven
            Case 8
                getal = Acht
            Case 9
                getal = Negen
            Case Else
                getal = %00001111 'Uit
        EndSelect   
        ZetOm = temp + getal   
    Return
    '************************************************************
    UrenUit:
        SHOut Data_Pin, klok, msbfirst, [Uren \ 8]
        DelayUS 20
        SHOut Data_Pin, klok, msbfirst, [Minuten \ 8]   
        DelayUS 20
        SHOut Data_Pin, klok, msbfirst, [Seconden \ 8]   
        High ZetVast
        DelayUS 20
        Low ZetVast
    Return
    '************************************************************
    DatumUit:
        SHOut Data_Pin, klok, msbfirst, [Datum \ 8]
        DelayUS 20
        SHOut Data_Pin, klok, msbfirst, [Maand \ 8]   
        DelayUS 20
        SHOut Data_Pin, klok, msbfirst, [Jaar \ 8]      
        High ZetVast
        DelayUS 20
        Low ZetVast
    Return
    '************************************************************
    TempUit:
        SHOut Data_Pin, klok, msbfirst, [%11111111 \ 8]
        DelayUS 20
        SHOut Data_Pin, klok, msbfirst, [Temperatuur \ 8]   
        DelayUS 20
        SHOut Data_Pin, klok, msbfirst, [%11111111 \ 8]   
        High ZetVast
        DelayUS 20
        Low ZetVast
    Return
    '************************************************************
    TijdInst:
        y = 0
        'In deze subroutine blijven voor 7.5 sec nadat de laatste 
        'knop is ingedrukt
        'Stay in this sub for 7.5 seconds after the last button
        'is pressed
        While y < 50
            'Tijd inlezen
            'Read time
            I2CIN  SDA, SLC, Lezen, Reg_Uren, [Uren]     
            I2CIN  SDA, SLC, Lezen, Reg_Minuten, [Minuten]
            I2CIN  SDA, SLC, Lezen, Reg_Seconden, [Seconden] 
        
            Inc y
            If KnopR = 0 Then
                'De maximimale waarde dat de seconde variabele mag
                'worden instellen op 59
                'Set the max value that the variable may become on 59
                tot = 0x59
                '1 optellen in de sub BCD_Plus
                'Ad 1 in the sub BCD_Plus
                getal = Seconden
                GoSub BCD_Plus
                Seconden = getal
                'Waarde wegschrijven naar de RTC
                'Write the value to the RTC
                I2COUT SDA, SLC, Schrijven ,Reg_Seconden, [Seconden]
                'Teller om in de sub te blijven resetten
                'Reset the counter to stay in this sub 
                y = 0   
            EndIf
            If KnopM = 0 Then
                tot = 0x59
                getal = Minuten
                GoSub BCD_Plus
                Minuten = getal
                I2COUT SDA, SLC, Schrijven ,Reg_Minuten, [Minuten]  
                y = 0          
            EndIf
            If  KnopL = 0 Then
                tot = 0x24
                getal = Uren
                GoSub BCD_Plus
                Uren = getal
                I2COUT SDA, SLC, Schrijven ,Reg_Uren, [Uren]  
                y = 0                  
            EndIf 
            
            'De waardes op de nixies zetten
            'Put the value's on the nixies
            ZetOm = Uren     :   GoSub Omzetten  :   Uren = ZetOm    
            ZetOm = Minuten  :   GoSub Omzetten  :   Minuten = ZetOm            
            ZetOm = Seconden :   GoSub Omzetten  :   Seconden = ZetOm     
            GoSub UrenUit
            
            DelayMS 150     
        Wend
    Return
    '************************************************************
    DatumInst:
        y = 0
        'In deze subroutine blijven voor 7.5 sec nadat de laatste 
        'knop is ingedrukt
        'Stay in this sub for 7.5 seconds after the last button
        'is pressed
        While y < 50
            'Tijd inlezen
            'Read time
            I2CIN  SDA, SLC, Lezen, Reg_Jaar, [Jaar]
            I2CIN  SDA, SLC, Lezen, Reg_Maand, [Maand]
            I2CIN  SDA, SLC, Lezen, Reg_Datum, [Datum] 
        
            Inc y
            If KnopR = 0 Then
                tot = 0x99
                getal = Jaar
                GoSub BCD_Plus
                Jaar = getal
                I2COUT SDA, SLC, Schrijven ,Reg_Jaar, [Jaar]  
                y = 0      
            EndIf
            If KnopM = 0 Then
                tot = 0x12
                getal = Maand
                GoSub BCD_Plus
                Maand = getal
                I2COUT SDA, SLC, Schrijven ,Reg_Maand, [Maand]  
                y = 0          
            EndIf
            If  KnopL = 0 Then
                tot = 0x31
                getal = Datum
                GoSub BCD_Plus
                Datum = getal
                I2COUT SDA, SLC, Schrijven ,Reg_Datum, [Datum]
                y = 0                               
            EndIf 
            
            'De waardes op de nixies zetten
            'Put the value's on the nixies
            ZetOm = Jaar     :   GoSub Omzetten  :   Jaar   = ZetOm    
            ZetOm = Maand    :   GoSub Omzetten  :   Maand  = ZetOm            
            ZetOm = Datum    :   GoSub Omzetten  :   Datum  = ZetOm 
            GoSub DatumUit
            
            DelayMS 150     
        Wend
    Return
    '************************************************************
    BCD_Plus:
        temp = getal & %00001111
        Inc temp
        If temp = 10 Then
            temp = 0
            temp = getal & %11110000
            temp = temp >> 4
            Inc temp 
            If temp = 10 Then
                getal = 0
            Else
                getal = temp << 4
            EndIf
        Else
            getal = getal & %11110000
            getal = getal + temp
        EndIf 
        If getal > tot Then
            getal = 0
        EndIf       
    Return
    '************************************************************
OverSub:
    'Start Temperature sensor    
        'Zend 'Convert' opdracht (temperatuur meten) 
        'Send 'Convert' command (measure temperatuur) 
        OWrite one_wire, 1, [$CC, $44] ;
        'Zend 'Read ScratchPad' opdracht (zend temperatuurmeting) 
        'Send 'Read ScratchPad' command (send temperatuurmeasurement)     
        OWrite one_wire, 1, [$CC, $BE] ;Zend '' opdracht
        ORead  one_wire, 2, [TemperatuurW.LowByte, TemperatuurW.HighByte]
'****************************************************************  
Main:
While 1 = 1
    '************************************************************ 
    'Tijd weergeven
    'Display time
    High  LedU 
    For index = 0 To 100  
        'Tijd inlezen
        'Read time
        I2CIN  SDA, SLC, Lezen, Reg_Uren, [Uren]     
        I2CIN  SDA, SLC, Lezen, Reg_Minuten, [Minuten]
        I2CIN  SDA, SLC, Lezen, Reg_Seconden, [Seconden]
        
        'Knop ingedrukt? -> sub TijdInst 
        'Button pressed? -> sub TijdInst
        If KnopR = 0 Or KnopM = 0 Or KnopL = 0 Then
            GoSub TijdInst
        EndIf
        
        'De waardes op de nixies zetten
        'Put the value's on the nixies
        ZetOm = Uren     :   GoSub Omzetten  :   Uren     = ZetOm    
        ZetOm = Minuten  :   GoSub Omzetten  :   Minuten  = ZetOm            
        ZetOm = Seconden :   GoSub Omzetten  :   Seconden = ZetOm 
        GoSub UrenUit                
        
        DelayMS 100
    Next   
    Low  LedU
    '************************************************************  
    'Datum weergeven
    'Display date
    High  LedD  
    For index = 0 To 30 
        'Datum inlezen
        'Read date
        I2CIN  SDA, SLC, Lezen, Reg_Jaar, [Jaar]
        I2CIN  SDA, SLC, Lezen, Reg_Maand, [Maand]
        I2CIN  SDA, SLC, Lezen, Reg_Datum, [Datum] 

        'Knop ingedrukt? -> sub TijdInst 
        'Button pressed? -> sub TijdInst
        If KnopR = 0 Or KnopM = 0 Or KnopL = 0 Then
            GoSub DatumInst
        EndIf

        'De waardes op de nixies zetten
        'Put the value's on the nixies
        ZetOm = Jaar     :   GoSub Omzetten  :   Jaar   = ZetOm    
        ZetOm = Maand    :   GoSub Omzetten  :   Maand  = ZetOm            
        ZetOm = Datum    :   GoSub Omzetten  :   Datum  = ZetOm  
        GoSub DatumUit
                
        DelayMS 100
    Next
    Low LedD
    '************************************************************   
    'Temperatuur weergeven
    'Display temperature
    High LedT
    
    '********
    'DS18B20 inlezen   || Read DS18B20
    'Code van Reddevil || Code by Reddevil
    'http://www.schematheek.net/index.php?p=forum/topic&t=297&n=1#3218  
    
    'Zend 'Convert' opdracht (temperatuur meten) 
    'Send 'Convert' command (measure temperatuur) 
    OWrite one_wire, 1, [$CC, $44] ;
    'Zend 'Read ScratchPad' opdracht (zend temperatuurmeting) 
    'Send 'Read ScratchPad' command (send temperatuurmeasurement)     
    OWrite one_wire, 1, [$CC, $BE] ;Zend '' opdracht
    ORead  one_wire, 2, [TemperatuurW.LowByte, TemperatuurW.HighByte]
    '4 plaatsen opschuiven voor getal naar de comma weg te gooien
    'Shift 4 places to dispose the value after the decimal separator
    TemperatuurW = TemperatuurW >> 4   
    
    '********
    'Temperatuur in een bcd waarde opzetten
    'Convert the temperature in a bcd value
    digit1 = Dig TemperatuurW, 1
    digit2 = Dig TemperatuurW, 0
    digit1 = digit1 << 4
    Temperatuur = digit1 + digit2
     
    ZetOm = Temperatuur
    GoSub Omzetten 
    Temperatuur = ZetOm
    'Temperatuurmeting zit niet in een lus om te voorkomen dat
    'de temperatuursensor gaat opwarmen door hem teveel uit te 
    'lezen
    'The temperatuurmeasurement is not in a loop, to avoid
    'heating up the sensor trough reading it to mutch 
    GoSub TempUit
    DelayMS 3000  
    Low LedT
    '************************************************************ 
Wend
'****************************************************************  
End