LED Clock Code

lpsarsam

Member
Hi :D
I am just starting to learn basic for pic after using logicator.
I am building an LED clock that uses shift registers and a ring of LEDs around the edge of the clock for the seconds and four 7 segment displays for the hours and minutes (controlled by 4026 chips). The chip I am using is an 18m2 so pretty much, every time I send a pulse out of C.1, a new LED will light to show an extra second. A pulse from C.0 clears the LEDs. B.7 advances the minutes, B.6 clears the minutes. B.5 increments the hours and B.4 clears the hours. The time is read from a time keeping chip over I2C.
As I am just starting with basic, could someone please check over my code and point out my errors and if possible, help me optimise it.
Thanks :D

Code:
#picaxe 18m2

start0:
i2cslave %11010000,i2cslow, i2cbyte
readi2c 0, (b0,b1,b2)

;spam pulses to set up the second hand
b10=0
looping:
if b1<>b10 then
high C.1
pause 1
low C.1
inc b0
goto looping
endif

;spam pulses to set up the minute digits on 7 seg
b10=0
looping1:
if b2<>b10 then
high B.7
pause 1
low B.7
inc b0
goto looping1
endif

;spam pulses to set up the hour digits on 7 seg
b10=0
looping2:
if b3<>b10 then
high B.5
pause 1
low B.5
inc b0
goto looping2
endif
stop

;increment leds every second by sending pulse out of C.1
start1:
secondsmainloop:

i2cslave %11010000,i2cslow, i2cbyte
readi2c 0, (b0)

b10=b0+1
if b10 = 60 then
high C.0
pause 1
low C.0
goto secondsmainloop
endif

secondincloop:
if b0<>b10 then
goto secondincloop
endif
high C.1
pause 1
low C.1
goto secondsmainloop:

;increment 7 seg count every minute by sending pulse out of B.7
start2:
minutesmainloop:

i2cslave %11010000,i2cslow, i2cbyte
readi2c 0, (b1)

b10=b1+1
if b11 = 60 then
high B.6
pause 1
low B.6
goto minutesmainloop
endif

minuteincloop:
if b1<>b11 then
goto minuteincloop
endif
high B.7
pause 1
low B.7
goto minutesmainloop


;increment 7 seg count every hour by sending pulse out of B.5
start3:
hoursmainloop:

i2cslave %11010000,i2cslow, i2cbyte
readi2c 0, (b2)

b12=b2+1
if b10 = 12 then
high B.4
pause 1
low B.4
goto hoursmainloop
endif

hourincloop:
if b2<>b12 then
goto hourincloop
high B.5
pause 1
low B.5
endif
goto hoursmainloop:
 

nick12ab

Senior Member
An easy optimization to do is to replace the high - pause - low sequences with pulsout commands. Doing this alone reduces program memory usage from 182 to 162 bytes. I've also added white spacing to improve readability.
Code:
#picaxe 18m2

start0:
    i2cslave %11010000,i2cslow, i2cbyte
    readi2c 0, (b0,b1,b2)

;spam pulses to set up the second hand
    b10=0
looping:
    if b1<>b10 then
        pulsout C.1,1
        inc b0
        goto looping
    endif

;spam pulses to set up the minute digits on 7 seg
    b10=0
looping1:
    if b2<>b10 then
        pulsout B.7,1
        inc b0
        goto looping1
    endif

;spam pulses to set up the hour digits on 7 seg
    b10=0
looping2:
    if b3<>b10 then
        pulsout B.5,1
        inc b0
    goto looping2
    endif
    stop

;increment leds every second by sending pulse out of C.1
start1:
secondsmainloop:

    i2cslave %11010000,i2cslow, i2cbyte
    readi2c 0, (b0)
    
    b10=b0+1
    if b10 = 60 then
        pulsout C.0,1
        goto secondsmainloop
    endif

secondincloop:
    if b0<>b10 then
        goto secondincloop
    endif
    pulsout C.1,1
    goto secondsmainloop:

;increment 7 seg count every minute by sending pulse out of B.7
start2:
minutesmainloop:

    i2cslave %11010000,i2cslow, i2cbyte
    readi2c 0, (b1)
    
    b10=b1+1
    if b11 = 60 then
        pulsout B.6,1
        goto minutesmainloop
    endif

minuteincloop:
    if b1<>b11 then
        goto minuteincloop
    endif
    pulsout B.7,1
    goto minutesmainloop


;increment 7 seg count every hour by sending pulse out of B.5
start3:
hoursmainloop:
    
    i2cslave %11010000,i2cslow, i2cbyte
    readi2c 0, (b2)
    
    b12=b2+1
    if b10 = 12 then
        pulsout B.4,1
        goto hoursmainloop
    endif

hourincloop:
    if b2<>b12 then
        goto hourincloop
        pulsout B.5,1
    endif
    goto hoursmainloop:
 

nick12ab

Senior Member
Ah, Thanks :D
But can you see any major errors here that would prevent my code from working as it should?
In this section of code:
Code:
hourincloop:
    if b2<>b12 then
        goto hourincloop
        pulsout B.5,1
    endif
    goto hoursmainloop
if b2 <> b12 then it will be stuck in an endless loop and nothing can be done about it.
 

lpsarsam

Member
Yes, but I don't see how it could get stuck, as just before that section, it tells the chip to read the time, add 1 hour/minute/second, then loop until that the time = the time + 1 second, where as 1 second has passed, the next LED will light up. Can you think of a more reliable/more efficient method without having it run loops constantly.
Thanks :)
 

nick12ab

Senior Member
Yes, but I don't see how it could get stuck, as just before that section, it tells the chip to read the time, add 1 hour/minute/second, then loop until that the time = the time + 1 second, where as 1 second has passed, the next LED will light up. Can you think of a more reliable/more efficient method without having it run loops constantly.
Thanks :)
Unless I've missed some magical update, on PICAXE you need to manually read in the time using i2c if you want to check whether the time has been updated - or use the inbuilt timer (which you wouldn't want to do when i2c is fine).
 

nick12ab

Senior Member
By the way you also have it here: (and why is there a stop command?)
Code:
looping2:
    if b3<>b10 then
        pulsout B.5,1
        inc b0
        goto looping2
    endif
    stop
And here:
Code:
secondincloop:
    if b0<>b10 then
        goto secondincloop
    endif
And here:
Code:
looping:
    if b1<>b10 then
        pulsout C.1,1
        inc b0
        goto looping
    endif
 

lpsarsam

Member
Very nice!!! I was going to use 7 segment displays, but are those LED matrix displays for the hours and minutes? Looks a bit more complex but way cooler :)
 
Nope, just a whole bunch of LEDS (60 seconds + 12 five mins + (4 digits * 7 segments *3 LEDs per segment) + 2 colon LEDS = 158 LEDs The seconds are driven by one MAX2719 and the rest by a second (operating in 4 decoded, 4 not decoded mode).

I drilled holes in a piece of black perspex (I can supply a template for you if you wish) glued LEDs in the holes (test them first!!! I forgot! They all worked PHEW!) and wire them up mostly by bending the leads and soldering. Connect with a few ribbon cables to the main circuit board. Program. Done. It even ticks :)
 

Buzby

Senior Member
7129 ?, 7219, 2719 ?

Another advantage of Charliplexing, you have no part numbers to get wrong.:)
 
Top