Single digit 7 Seg LED clock - PIC16F88


+ Reply to Thread
Results 1 to 5 of 5
  1. #1
    Join Date
    Jun 2006
    Posts
    12

    Default Single digit 7 Seg LED clock - PIC16F88

    Hi All,

    I've been wanting to do this project for a while now and have finally gotten around to it.

    I've built a single digit clock using a 2.3" 7 segment LED (green in this case). The clock flashes each digit in the time for one second before displaying the next. It also lights the DP on the second hour digit.

    There are 2 push buttons for setting the time as well.

    Here is the code and a couple of photos of the boards.

    Code:
    '****************************************************************
    '*  Name    : Large_LED_Clock.BAS                                      
    '*  Author  : Tony Hirst  [email protected]                   
    '*  Date    : 14/07/2009                                        
    '*  Version : 1.0                                               
    '*  Notes   : Program to drive a 7 segment LED single digit clock.
    '*          : Utilises Darrel Taylor's Instant Interrupt routines.
    '*          : The program should be self explanatory but here are
    '*          : the basics:
    '*          :       Program simply checks to see if seconds have 
    '*          :       changed and, if so, displays the next number
    '*          :       sequence on the single LED display.
    '*          :       Firstly the first hours digit is displayed,
    '*          :       pause for 1 second, then display the second
    '*          :       hour digit with the dp and so on.  Display is
    '*          :       blanked for one second after the second minute
    '*          :       has been displayed.
    '*          :
    '*          :       There is also a fade in routine that brings the
    '*          :       digits on "gently" over a few milliseconds to 
    '*          :       make the display a bit easier on the eye.
    '*          :       The clock is in 24hour mode and if the hour is
    '*          :       only one digit the program only displays one digit.
    '*
    '*          :       There are two buttons connected to RA2 and 3.
    '*          :       RA2 when pressed increments the minutes and RA3
    '*          :       the hours.  
    '*          :       To set the time initially hold down mbtn while
    '*          :       powering on.  This puts device into setup mode.
    '*          :       Pressing mbtn and hbtn increments the hours and
    '*          :       minutes respectively.  No btn presses for 2 secs
    '*          :       will start program proper.
    '*          :
    '*          :       Hardware:
    '*          :                PIC16F88
    '*          :                4MHz Xtal (XT) 30ppm accuracy preferred
    '*          :                UDN2981 for CC LED's or ULN2003 for CA LED's
    '*          :                2.3" 7 Segment LED from Futurlec
    '*          :                12V for UDN/ULN
    '*          :                78L05 V reg for Pic
    '****************************************************************
    
    
    INCLUDE "DT_INTS-14.bas"
    INCLUDE "ReEnterPBP.bas"
    INCLUDE "Elapsed_INT.bas"  ; Elapsed Timer Routines
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,  _ClockCount,   PBP,  yes
        endm
        INT_CREATE            ; Creates the interrupt processor
    
        INT_ENABLE  TMR1_INT  ; Enable Timer 1 Interrupts  
    ENDASM
    
    TRISB = %00000000         'ALL OUTPUTS
    TRISA = %00001100         '2 and 3 are inputs
    ANSEL = %00000000         'PortA all digital
    
    TEMP    var byte          ' last digit displayed ie h1, h2, m1, m2, or pause 1s
                              '                          0   1   2   3            4
    pulse   var byte          'Holds value for display in fade in routine
    i       var word          '
    x       var word          'General purpose vars used in fade in routine
    y       var word          '
    h       var byte          'used in initial time setup
    m       var byte          '  "                "
    init    var bit           'flag to indicate initial time setup
    
    NUM     var byte          ' number to display
    
    mbtn var porta.2          'button to set minutes
    hbtn var porta.3          'button to set hours
    
    GOSUB ResetTime           ' Reset Time to  0d-00:00:00.00
    
    h = 0
    m = 0
    init = 0
    
    '******************************************************************************
    ' to set time initially mbutton must be pressed for at least 1 sec while      *
    ' powering on.                                                                * 
    ' Prog stays in this loop until 2ish seconds has passed without a button being*
    ' pushed.                                                                     *
    '******************************************************************************
    if mbtn = 0 then    'if mbtn pushed
        pause 1000
        while mbtn = 0  'wait 'til button released
        wend
    setup:
        if mbtn = 0 then
            pause 30 'debounce
            if mbtn = 0 then gosub mbtn_handler
            GOSUB ResetTime 'reset the clock to keep track of the 2 seconds wait
            gosub StartTimer 'start timer
        endif
        if hbtn = 0 then
            pause 30 'debounce
            if hbtn = 0 then gosub hbtn_handler
            GOSUB ResetTime 'reset the clock to keep track of the 2 seconds wait
            gosub StartTimer 'start timer
        endif
        if seconds < 2 then goto setup 'if we're within the 2ish seconds then wait
    endif
    
    gosub ResetTime 'reset the timer
    
    init = 1        ' reset init flag
    hours = h       ' allocate initial times from setup
    minutes = m     ' these will be zero if setup was skipped
    
    GOSUB StartTimer          ' Start the Elapsed Timer
    
    temp = 4                  'init display routine to blank
    
    goto display
    
    '***************************
    '* Handle minutes btn push *
    '***************************
    mbtn_handler:
        
        if init = 1 then 
            Minutes=Minutes + 1
            IF Minutes=60 THEN
                Minutes=0
            ENDIF
        else
            m = m + 1
            if m = 60 then m = 0
        endif
        pause 200
        seconds = 0
        return
        
    '***************************
    '* Handle hours btn push   *
    '***************************
    hbtn_handler:
        
        if init = 1 then
            Hours=Hours+1
            IF Hours=24 THEN
                Hours=0
            ENDIF
        else
            h = h + 1
            if h = 24 then h = 0
        endif
        pause 200
        seconds = 0
        return
        
    '************************************************
    '* Display routine                              *
    '*                                              *
    '* Output hours and minutes one digit at a time.*
    '* Light the dp with the second hours number    *
    '************************************************
    display:
        'check if a button has been pushed
        if mbtn = 0 then
            pause 30 'debounce
            if mbtn = 0 then
                gosub mbtn_handler
            endif
        endif
        if hbtn = 0 then
            pause 30 'debounce
            if hbtn = 0 then
                gosub hbtn_handler
            endif
        endif
        
        ' Now work out which digit to display next.  1 second between changes
        if secondschanged = 1 then 
            secondschanged = 0
            
            if Hours < 10 then 'if no 1st hour digit then skip it and go to 2nd dig
                if temp = 0 then temp = 1
            endif
            select case temp
            case is = 0 
                temp = 1
                'output first hour digit
                num = hours dig 1
                goto led_driver
            case is = 1
                temp = 2
                'output second hour digit
                if hours < 10 then 
                    num = Hours
                else
                    num = hours dig 0
                endif
                goto led_driver
            case is = 2
                temp = 3
                'output first minute digit
                if minutes < 10 then
                    num = 0
                else
                    num = minutes dig 1
                endif
                goto led_driver
            case is = 3
                temp = 4
                'output second minute digit
                if minutes < 10 then
                    num = minutes
                else
                    num = Minutes dig 0
                endif
                goto led_driver    
            case is = 4
                temp = 0
                'blank display
                num = 99
                goto led_driver
            end select
        else
            goto display 'second hasn't changed so wait in this function
        endif        
    
        'now fall thru to led display
    
    '************************************
    '* LED driver routine               *
    '* Uses NUM variable set in Display *
    '* routine to display number        *
    '************************************
    led_driver:
        pulse = 0
        select case num
        case is = 0
            pulse = %11110101
        case is = 1
            pulse = %11000000
        case is = 2
            pulse = %10111100
        case is = 3
            pulse = %11101100
        case is = 4
            pulse = %11001001
        case is = 5
            pulse = %01101101
        case is = 6
            pulse = %01111101
        case is = 7
            pulse = %11000100
        case is = 8
            pulse = %11111101
        case is = 9
            pulse = %11101101
        case is = 99
            portb = 0
        end select
        
        ' Fade in routine - pulse is value of number on LED
        if pulse > 0 then 
            if temp = 2 then ' if dp is needed
                pulse = pulse + %00000010
            endif        
            x = 0
            y = 20
            for i = 1 to 10
                portb = pulse
                pause x     ' turn on LED
                portb = 0
                pause y     ' turn off LED
                y = y - 2 
                x = x + 2   
            next 
            portb = pulse   ' turn LED on for final time
        endif
            
        goto display 'go back and wait for seconds to change over
    
    END
    Attached Images Attached Images    

  2. #2
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    907


    Did you find this post helpful? Yes | No

    Default

    Tony

    First impressions, you seem to be doing a pretty neat job at coding. We don't know if you're a PC side programmer, but your style shows the way a good program code should be written with self documentation.

  3. #3
    Join Date
    Jun 2006
    Posts
    12


    Did you find this post helpful? Yes | No

    Default

    Hi Jerson,

    Yep I'm a programmer (amongst other things) in the PC world and like to keep my progs neat and tidy.

    I'm sure the code could be made smaller and more "clever" but I like to keep it understandable and I'm no PBP expert.

    I've also posted a video of the clock running on youtube here -

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    That's different. Neat.

    I noticed in the video it goes from 13.39 to 13.30 to 13.40, when the minute changed in the middle of displaying the time.

    Maybe if you saved the time before displaying it, it wouldn't do that.

    Seems like it could go a little faster too, but maybe it would be too fast for some people.

    Nice work,
    DT

  5. #5
    Join Date
    Jun 2006
    Posts
    12


    Did you find this post helpful? Yes | No

    Default

    Thanks Darrel.

    I've already fixed the time problem you mentioned and I did it exactly as you suggested! I'll need to post the new code soon as I also removed one of the buttons - I stole another idea I saw on youtube where a press of the btn will increment the digit currently displayed. A lot more elegant and works well.

    I've got the clock running in the lounge along with my nixie tube clock and it's actually very easy to read at the current speed. It's not at all annoying either which is nice.

    Making up a nice wood housing for it now.

Similar Threads

  1. Conway's Game Of Life
    By wellyboot in forum mel PIC BASIC Pro
    Replies: 45
    Last Post: - 28th May 2020, 06:14
  2. Free Project - 245 LED Display
    By T.Jackson in forum Code Examples
    Replies: 221
    Last Post: - 16th August 2009, 04:59
  3. Help with sound command in 2 programs
    By hyperboarder in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 5th July 2007, 20:36
  4. LCD will not start
    By btaylor in forum mel PIC BASIC Pro
    Replies: 49
    Last Post: - 24th May 2007, 02:30
  5. 7 segment digit problem (using Mister E's code)
    By jmgelba in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 9th September 2005, 20:25

Posting Permissions

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