Creating an interrupt every second on 20M2

IndiaJim

New Member
I am playing around with a huge digital clock and using a Picaxe 20M2.
I need to create an interrupt every second for the counter.
Can I use Timer to do this?
Any ideas? many thanks IndiaJim


(Moved from Finished Projects.)
 
Last edited by a moderator:

nick12ab

Senior Member
I need to create an interrupt every second for the counter.
Can I use Timer to do this?
Yes you can. See the setintflags command and the settimer command. You will need to have a timer interval of 1/65536 seconds in order to get the timer to overflow once a second and trigger an interrupt.

ADDED: I wouldn't recommend this method unless you have a 16.7775MHz crystal due to the error from the desired interval.



I'd recommend using the timer set to a one second interval, using the timer value for seconds and poll this value after each display refresh (for multiplexing) or constantly otherwise.

If you use a ds1307 for the time it has a 1 second pulsed output for flashing an led on what is otherwise a spare pin.
In that case IndiaJim might as well just use the DS1307 instead of the internal timer.

This was a clock that I made using the DS1307 which included the ability to have its time synchronised with a computer:
Code:
#no_data
#picaxe 40X2
#no_end
#terminal off
symbol vardisplay = b0
symbol sl1 = b1
symbol sl2 = b2
symbol sl3 = b3
symbol sl4 = b4
symbol sl5 = b5
symbol sl6 = b6
symbol speed = b8
symbol mode = b9
symbol time1 = b10
symbol time2 = b11
symbol time3 = b12
symbol time4 = b13
symbol time5 = b26
symbol time6 = b27

symbol buttonvar = b18
symbol tempvar = b19
symbol buttonvar2 = b20
symbol runvar = b21
symbol nodp = b22
symbol displayselect = b23
symbol i2cin = b24
symbol cvarA = b25
symbol blanking = b26
symbol ds1 = b27
symbol ds2 = b28
symbol ds3 = b29
symbol ds4 = b30
symbol loopcounter = b31
eeprom 0,(0,1,0,6,0,0,0,0)
eeprom 8,(10)
table 0,($3F,$06,$5B,$4F,$66,$6D,$7C,$07,$7F,$67,$00,$40,$00,$06,$5B,$4F,$66,$6D,$7C,$07,$7F,$67,$00,$40)
    read 8,speed
    let dirsA = 000000
    let dirsB = 111111
    let dirsD = 001111
    goto synchronise
main:    setfreq em64
    settimer t1s_8
    disablebod
    reconnect
    let buttonvar = 1
    goto mode4

mode4:
    hi2csetup i2cmaster,010000,i2cslow_16,i2cbyte
mode4display:
    hi2cin 2,(i2cin)
    let cvarA = bcdtobin i2cin
    let vardisplay = cvarA dig 1 + 12
    readtable varDisplay,pinsB                    'Get segment pattern
    high D.0
    pause speed
    low D.0
    let cvarA = i2cin & 001111
    readtable cvarA,pinsB                        'Get segment pattern
    pinB.7 = 1                                'Set decimal point
    high D.1
    pause speed
    low D.1
    hi2cin 1,(i2cin)
    let cvarA = bcdtobin i2cin
    let varDisplay = cvarA dig 1
    readtable varDisplay,pinsB                    'Get segment pattern
    high D.2
    pause speed
    low D.2
    let cvarA = i2cin & 001111
    readtable cvarA,pinsB                        'Get segment pattern
    pinB.7 = 1                                'Set decimal point
    high D.3
    pause speed
    low D.3
    hi2cin 0,(i2cin)
    let cvarA = bcdtobin i2cin
    let varDisplay = cvarA dig 1
    readtable varDisplay,pinsB                    'Get segment pattern
    high A.6
    pause speed
    low A.6
    let varDisplay = i2cin & 001111
    readtable varDisplay,pinsB                    'Get segment pattern
    high A.7
    pause speed
    low A.7
    if buttonvar = 2 then
        inc speed
        if speed > 16 then
            speed = 0
        end if
        write 8,speed
        buttonvar = 1
    end if
    if pinD.7 = 0 and pinD.6 = 0 and pinD.4 = 0 and pinD.5 = 0 then
        buttonvar = 0
        let timer = 0
        goto mode4display
    end if
    if pinD.5 = 1 then
        if timer > 10 then
            goto synchronise
        elseif timer > 1 then
            speed = speed + 1
            if speed = 30 then : speed = 0 : end if
            write 8,speed
        end if
        buttonvar = 3
    end if
    if pinD.4 = 1 then
        hi2cout 0,(0)
    end if
    if pinD.7 = 1 then
        if buttonvar = 0 or timer > 5 then
            hi2cin 1,(i2cin)
            let buttonvar = 1
            let cvarA = bcdtobin i2cin
            inc cvarA
            if cvarA > 59 then : let cvarA = 0 : end if
            let cvarA = bintobcd cvarA
            hi2cout 1,(cvarA)
        end if
    end if
    if pinD.6 = 1 then
        if buttonvar = 0 or timer > 5 then
            hi2cin 2,(i2cin)
            let buttonvar = 1
            let cvarA = bcdtobin i2cin
            inc cvarA
            if cvarA > 23 then : let cvarA = 0 : end if
            let cvarA = bintobcd cvarA
            hi2cout 2,(cvarA)
        end if
    end if
    goto mode4display

synchronise:
    pinsB = 128
    low A.6
    high A.7
    low D.1
    low D.2
    low D.3
    low D.4
    setfreq m16
getcmd:
    serrxd [15000,main],sl1
    if sl1 = "t" or sl1 = "T" then
        serrxd sl1,sl2,sl3,sl4,sl5,sl6
        sl1 = sl1 - 48
        sl2 = sl2 - 48
        sl3 = sl3 - 48
        sl4 = sl4 - 48
        sl5 = sl5 - 48
        sl6 = sl6 - 48
        sl1 = sl1 << 4
        sl3 = sl3 << 4
        sl5 = sl5 << 4
        ds1 = sl1 + sl2
        ds2 = sl3 + sl4
        ds3 = sl5 + sl6
        hi2csetup i2cmaster,010000,i2cslow_64,i2cbyte
        hi2cout 0,(ds3,ds2,ds1)
        for loopcounter = 0 to 14
            lookup loopcounter,("New time saved."),sl2
            toggle B.7
            sertxd (sl2)
        next loopcounter
        high B.7
        goto main
    end if
    high B.7
    goto getc
There might be some unused variables defined at the top since this code was cut from an even bigger project.
 

Attachments

Last edited:

mrburnette

Senior Member
An external, $1, way of doing it which I have successfully utilized:
one_second_timebase

These things are everywhere... my wife had an old "drug company logo" one at the doctor office that I got for free.
My implementation using the timebase: http://www.picaxeforum.co.uk/entry.php?38-IR-time-set-OLED-digital-clock-w-08M2-and-old-wall-clock-quartz-module

Caveats:
- When using this technique, you are limited to around 950mS of processing time before you must be back in the loop to "catch" the external clock pulse. I'm not using interrupts, but it could be done... I have my reasons at the moment.
- Using an external I2C or serial clock chip would have been a better design choice, but I opted for the external quartz module because I wanted to abstract the time component from the software; again I have like something like 10 RTC chips in my parts bin, I wanted to be different and work through the external pulse timing for experience with handling the OLED display (I implemented an abstract 2-line buffer from non-named memory and I wanted to concentrate on this code, not the timer stuff.)

Clock/Calendar:
RTC are cheap and easily interfaced if you just want a "clock"... plenty of forum code here.
http://www.picaxe.com/Circuit-Creator/I2C-UNIO-SPI/I2C-Real-Time-Clock-DS1307/

If you are crazy-like-me, you can deviate and have some fun working through the issues caused by being off-road!

- Ray

Raw pictures: OLED clock
 

Attachments

Last edited:

womai

Senior Member
>> Yes you can. See the setintflags command and the settimer command.

No, you can't. Timer interrupts are only available on X1/X2 Picaxes, not M2 ones. The M2's do have the time variable (read through the Basic commands enabletime and disabletime) which you could poll (check frequently) in your main program, and update the clock display whenever it changes. Very doable for once-per-second actions.
 

nick12ab

Senior Member
No, you can't. Timer interrupts are only available on X1/X2 Picaxes, not M2 ones. The M2's do have the time variable (read through the Basic commands enabletime and disabletime) which you could poll (check frequently) in your main program, and update the clock display whenever it changes. Very doable for once-per-second actions.
Okay then. Just remember that using an M2 part prevents use of a crystal so any timer made using one will be very inaccurate.
 

kranenborg

Senior Member
Hello,

I think that the M2 series allow a watch crystal (32.768 kHz) to be attached to the LP oscillator input to create a very accurate clock. Similar successful attempts have been created with the 18X and 08M earlier as reported by hippy, using a combination of the LP oscillator and Timer1 (you should take a look at the corresponding Microchip datasheet) . I have code versions that were published some years ago by hippy, including a simulation of (most of the) functionality of a DS1307 using just a 08M and a watch crystal and 2 33pf caps.

EDIT 1: This is the thread by hippy I refer to: http://www.picaxeforum.co.uk/showthread.php?t=7142
Hippy lost his website so the links in that thread do not work anymore. I could send all code to him (contained in a single ZIP-file)

EDIT 2: Guess what: the links do work and the code examples can be downloaded ... . Hippy's root pages seem to be corrupted though.

EDIT 3: Regarding the usage of timers, the following info may be useful background information: http://www.picaxeforum.co.uk/showthread.php?17815-18M2-touch(16)-command-and-timer1-use&p=163479&viewfull=1#post163479

/Jurjen
http://www.kranenborg.org/electronics
 
Last edited:

geezer88

Senior Member
Just used a broken quartz clock for a timebase in my home made digital clock, as suggested above in #4. I substituted an optical isolator, salvaged from an old telephone, for the transistor. See the attached schematic. The broken clock circuit has plenty of drive power to the input led of the optical isolator, and the output can be directly connected to a Picaxe input with no other external parts required so long as the weak pull ups on the Picaxe are enabled.

Anyway, the clock went from loosing 5 or 10 seconds per day (best software tweaking) to a second or two per day with the old clock oscillator.clock_mod.jpg
 

geezer88

Senior Member
Cute little robot. I like the sound of "boots on the ground" What display are you using on your stopwatch?
tom
 
Top