PIC Nixie Clock project


Results 1 to 32 of 32

Threaded View

  1. #2
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Default Re: PIC Nixie Clock project

    Hey Group (again),

    I have a pretty decent beta version of the code up and running.
    My clock will now...
    > auto set the time via wifi from the esp module (ntp time source) on initial power up
    and every day at 0500
    > blanks the display between 2200 and 0600
    > cycle through all nixie digits to prevent cathode poisioning (every 15 minutes for 5 sec)
    probably overkill but it looks cool
    > you can choose 12 hr, 24 hr or a mode where the hours alternate between 12/24 hr
    for those who can't read 24 hr time but want to learn
    > can display room temperature (but I haven't actually added this to the code yet)

    here are some pics...
    Name:  2016-02-14 17.08.21.jpg
Views: 10414
Size:  104.9 KB

    Name:  2016-02-14 17.08.47.jpg
Views: 10734
Size:  82.3 KB

    Name:  2016-02-14 17.09.48.jpg
Views: 10354
Size:  79.8 KB

    Name:  2016-02-14 17.10.06.jpg
Views: 10620
Size:  157.2 KB

    Name:  2016-02-14 17.06.23.jpg
Views: 10217
Size:  224.7 KB

    Name:  2016-02-14 17.10.56.jpg
Views: 10557
Size:  216.7 KB

    here is my beta version of the code...
    It runs on an 16F1828 or 16F1829 and with minor mods will run on an 16f690
    Code:
    '****************************************************************
    '*  Name    : MSP to PIC Nixie clock.BAS                        *              *
    '*  Author  : [Dwight Merkley]                                  *
    '*  Notice  : Copyright (c) 2016 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 1/2/2016                                          *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
    #CONFIG
        __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
        __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_25 & _LVP_OFF
    #endconfig
    
    DEFINE OSC 8
    include "ALLDIGITAL.Pbp"
    '==================================================
    
    H10  VAR PortC.0    'hours tens digit enable
    H1   var PortC.1    'hours ones digit enable
    M10  var PortC.2    'minutes tens digit enable
    M1   var PortC.3    'minutes ones digit enable
    symbol PORT_PIN = PORTC  'used to sequentially enable portC.0-3 nixie tubes
    
    res  var PortC.4    '0-9 digit reset
    clk  var PortC.6    '0-9 digit counter input
    ena  var PortC.7    'ENA on nixie decade counter
    
    led  var LATC.5     'pwm led backlight
    sw1  var portA.2     'input upper switch
    sw2  var portA.1     'input lower corner switch
    swflg var bit        'bit used to debounce switch pushes
    
    ts   var portB.4     'OneWire Temperature sensor
    rxE  var portB.5     'input rx data from esp8266 
    txE  var portB.7     'tx data to esp8266
    fet  var portB.6     'High Voltage shutdown
    
    tube var byte       'refrence tube 0-3 [hh h mm m]
    hh   var byte         'variable holding hours 
    h12  var byte
    mm   var byte         'variable holding minutes 
    ss   var byte         'variable holding seconds
    d1   var byte
    d2   var byte
    d3   var byte
    d4   var byte
    s1   var byte
    s0   var byte
    mode var byte    '12 to 24 hour conversion flag'
    num  var byte    'current digit's pulse count
    x    var byte      'general purpose variable
    y    var byte      'counter to track time between esp serial request output
    dgt  var byte
    temp     var byte   'temporary lcd display data
    IntCnt   var word
    IntFlag  var bit
    dispflag var bit  'flag to indicate if display should be off
    temptime var byte 'var to determine if time to check temperature
    'the following var's are used in the anti-cathode poisoning routine
    position var byte
    numx     var byte
    cath     var byte
    index    var byte
    '-------------[variables and constants for temperature routine]--------------
    DS18B20_9bit  CON %00011111   ' set resolution on DS18B20 93.75ms, 0.5 C
    DQ            VAR   PortB.4   ' One-wire Data-Pin "DQ" on PortB.4
    Busy          VAR BIT         ' Busy Status-Bit
    Raw           VAR   WORD      ' RAW Temperature readings
    TempF         VAR WORD        ' Temp in deg F
    Cold_Bit      VAR Raw.BIT11   ' Sign-Bit for +/- Temp. 1 = Below 0 deg C
    Sign          VAR BYTE[1]     ' +/- sign for temp display
    TempH         var word        ' var for highest temp
    TempL         var word        ' var for lowest temp
    SignH         var byte[1]
    SignL         var byte[1]
    C             VAR WORD     ' Celsius 
    F             VAR WORD     ' Fahrenheit
    
    INCLUDE  "Temp_Convert.pbp"
    '===================================================
    '===================================================
        TRISA = %00000110     
        TRISB = %00100000     
        TRISC = %00000000
        WPUA  = %00000110     
      OSCCON  = %01110000   'set internal osc to 8 mhz
    '====================================================
    espbaud con 84
    hh = 99
    mm = 00
    ss = 00
    mode = 2    'modes
                '0=24 hour only display
                '1=12 hour only display
                '2=24 hour with alternating 12 hour
                '     for dummies who don't know 24 hour time
    
    IntCnt = 0
    temp = 0
    
    ' -----[ Timer setup ]------------------------------
    disable interrupt
    On Interrupt goto MyInt    'define where interrupts should go
    INTCON     = %11000000     'now enable GIE,PEIE,x,x,GPIE,x,x,x
    T1CON =  %00110101 'Enable Timer1 with 1:8 prescaler
    PIE1  =  %00000001 'Enable Timer1 overflow interrupt
    PIE2  =  %00000000
    PIR1.0=0 'clear the timer1 interupt flag
    txe=1     'high the serial output pin, needs to start high
    
    '***************************************************
    '========            MAIN                ===========
    '***************************************************
    Enable Interrupt
    
    Main:
    if swflg = 1 and sw1=1 then swflg = 0  '(sw debounce) clear swflg when switch released
    
    if swflg = 0 and sw1=0 then 
        swflg = 1
        if mode = 0 then
            mode = 1  'switch to 12 hr mode
            goto SkipSw
        endif
        if mode = 1 then
            mode = 2  'switch to 24 hrr mode with 12 hr flash
            goto SkipSw
        endif
        if mode = 2 then 
            mode = 0  'switch to 24 hr mode
        endif
    endif 
    SkipSw:    
    
    'an interrupt is generated every .005 sec 
    'so clear the IntFlag and cycle to the next nixie tube
    if  IntFlag=1 then
        IntFlag=0
        IntCnt = IntCnt + 1
        gosub Tubes
    endif
    
    if  IntCnt > 199 then gosub NextSec 'time to increment seconds
    
    'this next routine fires every 15 minutes between 55 and 58 seconds
    'it causes all digits in each nixie to be cycled to prevent
    'cathode poisioning
    if mm//15=0 and (ss >54 and ss<58) then
        if intcnt//10 = 0 then gosub NixieBurn
    endif
    
    'this routine blanks the display between 2200 and 0600 
    if (hh>21) or (hh<6) then 'turn display off between 2200 and 0600
        dispflag = 0
    else 
        dispflag = 1
    endif
    
    'this routine only runs on startup and waits for 30 sec
    'then it goes and reads the time from the ESP module
    if hh = 99 then
        d1=s0
        d2=s1
        dispflag = 1
        if ss=30 then gosub GetTime
    endif
    
    'this routine sets the clock once a day at 0500
    if hh=5 and mm=0 and ss=0 then gosub GetTime 
    
    toggle led   'for backlight brigtness at 50% 
                 ' use O-Scope to determine Main loop timing
    goto Main
    
    '***************************************************
    '  interrupt every 5 msec
    '***************************************************
    disable interrupt
    MyInt:
        IntFlag=1    ' INT has fired so set this flag for Main code usage
        '>H & L size determine INT timing, INT every .005 seconds
        TMR1H = $FB  ' reset timer1h   
        TMR1L = $1F  ' reset timer1l   
        PIR1.0 = 0   ' clear timer1 overflow flag 
    resume    'to Main
    enable interrupt
    '=============================================================
    '          increment seconds and trickle down time
    '=============================================================
    NextSec:
    intCnt = 0
    ss = ss +1
    if  ss = 60 then 
        ss = 00
        mm = mm + 1
    endif
    if  mm = 60 then
        mm = 0
        hh = hh + 1
    endif
    if  hh = 24 then
        hh = 0 
    endif
    
    if hh>12 then 
        h12=hh-12
        else 
        h12=hh
    endif
            
    d1=mm//10
    d2=mm/10
    d3=hh//10
    d4=hh/10
    s1=ss/10
    s0=ss//10
    if mode=1 then      '12 hr only mode
        d3=h12//10
        d4=h12/10
    endif
    
    'this routine causes the display to alternate between 24 and 12 hr display 
    if mode = 2 and (s0=0 or s0=5) then  '24 hr mode with 
       d3=h12//10                        '12 hr overlay at 0 & 5 sec
       d4=h12/10
    endif
    
    return
    '=================================================
    '--- Routine to cycle all digits on all tubes  ---
    '--- to prevent cathode poisoning (look it up) ---
    '=================================================
    NixieBurn:
    numx=numx+1
    if numx=10 then numx=0    
    for position=0 to 3
        index=numx+position
        if index>9 then
           index=index-10
        endif
        lookup2 index,[1,6,2,7,5,0,4,9,8,3],cath        
        if position = 0 then d1=cath
        if position = 1 then d2=cath
        if position = 2 then d3=cath
        if position = 3 then d4=cath       
    next position    
    return
    '=============================================================
    '          display next NIXIE digit
    '=============================================================
    Tubes:
    PORT_PIN.0[tube] = 0        'Turn OFF the current tube
    if dispflag = 0 then 
        led = 1
        return                  'display is off so skip tubes
    endif
    tube=tube + 1
    if tube > 3  then tube = 0
    
    Digit:
        high res                'reset the decade counter
    @   nop
        low res                 'release the reset
    lookup2 tube,[d4,d3,d2,d1],num
    for x = 1 to num            'pulse the clock for "num" counts
        high clk                
    @   nop
        low clk
    next x
    
        PORT_PIN.0[tube] = 1    'Turn ON the next tube
    return
    '=============================================================
    '          Get TIME from ESP8266-01 NTP Time Server
    '=============================================================
    Disable Interrupt
    SerTmout:
        led=0
        pause 200
        led=1
        pause 200
        led=0
        pause 200
        led=1
        pause 200
    GetTime:
        PORT_PIN.0[tube] = 0   'Turn OFF the current tube
                ' Wait for >,CR,LF from ESP module
        serin2  rxe,espbaud,3000,SerTmout,[wait(">"),wait(13),wait(10)]
                ' ESP module expects "Time?" before it will give hhmmss
                ' to change this modify the ESP code
        serout2 txe,espbaud,["Time?"]
        serin2 rxe,espbaud,3000,SerTmout,[dec2 hh,dec2 mm, dec2 ss]
                ' set NIXIE tube positions for their 
                ' respective h h m m, d4,d3,d2,d1 
        d4=hh/10
        d3=hh//10
        d2=mm/10
        d1=mm//10
        s1=ss/10  ' s0 & s1 only gets used when displaying seconds
        s0=ss//10 ' untill time retreval from ESP module at 30 sec
    Return
    Enable Interrupt
    '=============================================================
    '           Read Temp Sensor and convert to deg F
    '=============================================================
    disable interrupt
    GetTemp:
        PORT_PIN.0[tube] = 0   'Turn OFF the current tube
        OWOUT  DQ,%001,[$CC, $4E, 0, 0, DS18B20_9bit]  'set resolution of sensor
    Start_Convert:
        OWOUT  DQ,%001,[$CC, $44]           ' Skip ROM search & do temp conversion
    
    Wait_Convert:
        OWIN   DQ,%100,[Busy]               ' Read busy-bit
        IF     Busy = 0 THEN Wait_Convert   ' Still busy..?, Wait_Convert..!
        OWOUT  DQ,%001,[$CC, $BE]           ' Skip ROM search & read scratchpad memory
        OWIN   DQ,%010,[Raw.byte0, Raw.byte1]' Read two bytes / end comms
    
        '--------------  Convert_Temp: -----------------------
        Sign="+"
        IF Cold_Bit = 1 THEN                'it's below zero Celsius
          C=(ABS Raw>>4)*-10                'so shift the ABS value right and mult X -10
          ELSE
          C=(Raw>>4)*10                     'else shift value right and mult X 10
        ENDIF
    
    @   CtoF _C, _F            ; Convert Celsius to Fahrenheit
            'converted value will be X 10, ie. 756=75.6 deg F
            'so devide by 10 to get whole degrees
        IF f.15=1 THEN Sign="-"         'if converted value is below zero F then sign is "-"
        TempF = (ABS f)/10              'take tha ABS value and /10
        IF f//10 >4 THEN TempF=TempF+1  'check remainder, if >4 then round up
        PIR1.0 = 0                  ' clear timer1 overflow flag 
    return                              'with TempF containing current temperature
    enable interrupt
    
    '===========================================
    end
    and here is the code that runs on the ESP8266-01 module

    Code:
    memclear
    cls
    timesetup(-7,0)
    baudrate 9600
    serialtimeout 2000
    delay 1000
    button "Exit " [Exit]
    [Main]
    timer 100 [PicSer]
    wait
    '
    [PicSer]
    serialflush
    input picIN
    picIN = mid(picIN,1,5)
    if picIN == "Time?" then gosub [gettime]
    wait
    '
    [gettime]
    bla = time()
    hh = mid(bla,12,2) 'hour
    mm = mid(bla,15,2) 'min
    ss = mid(bla,18,2) 'sec
    '
    picOUT = hh & mm
    picOUT = picOUT & ss
    serialprint picOUT
    '
    return
    '
    [Exit] 
    end
    this has been fun and a real challenge
    IF anyone would like to build one let me know and I'd be glad to help you out with parts procurement, etc for the little adapter board.
    Last edited by Heckler; - 15th February 2016 at 01:07.
    Dwight
    These PIC's are like intricate puzzles just waiting for one to discover their secrets and MASTER their capabilities.

Similar Threads

  1. Color GLCD Project, Analog clock
    By DaveC3 in forum Code Examples
    Replies: 5
    Last Post: - 14th May 2011, 03:24
  2. pic16f887 clock project, need help
    By lockjawz in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 13th April 2011, 11:45
  3. Digital clock project
    By astouffer in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 27th February 2009, 03:00
  4. Help with PIC project
    By davekav in forum General
    Replies: 3
    Last Post: - 17th April 2008, 23:15
  5. pic project help
    By dizzy1 in forum General
    Replies: 2
    Last Post: - 5th February 2006, 18:30

Members who have read this thread : 4

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts