Shop OBEX P1 Docs P2 Docs Learn Events
microbit softRTC — Parallax Forums

microbit softRTC

When in doubt, start from scratch. Below is a very very basic 24 hour clock. It is setup to see if it really keeps time. In the beginning of the program, you plug in your starting hour, minute and second. I have it set for 23:59:45 just to see if it rolls over correctly. I guess I can call this the main engine. If I overlooked something, please let me know.

Ray

# test_rtc.py
#
from microbit import *
import time
#, sys, os

EVENT_MS = 1000  # Runs at 1 second

# starts the tics
t_start = time.ticks_ms() 
tic_runtime = 0


# Put in your hours, minutes and seconds.
global h
h=23      # hour
global m
m=59       # minute
global s
s=45       # second

uart.init(115200)

#def menu():
#    print("       System Menu")
#    print("quit - End the program.")
#    print("ontime - Start the RTC.")
#    print("showtime - Show the RTC time.")
#    print("offtime - Stop the RTC.")


#def show_time(rt):
def show_RTC():
    global h
    global m
    global s

    h = h
    m = m
    s = s + 1

    if m == 60 and s == 59:
        m=0
        h=h+1
    #else:
    #    m=m+1
    if h == 23 and m == 59 and s == 59:
        h=0
        m=0
        s=0
    #else:
    #    h=h+1
    if s == 60:
        s=0
        m=m+1
    # Show the time elapsing at the command line
    print("%.2d:%.2d:%.2d   " % (h, m, s))

#show_time(0)
show_RTC()

#uart.write("Type help for system menu.\n>>>")
#menu()
#uart.write("\n>>>")


while True:
    #inbuff=""
    #if uart.any():
    #    inbuff=uart.read().strip().decode()
    #    if inbuff == "quit":
    #        print("RTC program has ended.")
    #        sys.exit()

    #    elif inbuff == "help":
    #        menu()
    #    elif inbuff == "ontime":
    #        tics = 1            
    #        uart.write("\n>>>") 
    #    elif inbuff == "showtime":
    #        print("%.2d:%.2d:%.2d   " % (h, m, s))
    #        uart.write("\n>>>") 
    #    elif inbuff == "offtime":
    #        tics = 0
    #        h=0
    #        m=0
    #        s=0
    #        uart.write("\n>>>") 
    #    else:
    #        uart.write("not an option")
    #        uart.write("\n>>>")  


    t_elapsed = time.ticks_ms() - t_start
    #now = time.tics_ms()

    if t_elapsed >= EVENT_MS:
        tic_runtime += EVENT_MS
        #show_time(tic_runtime)  # This runs show_time @ 0
        #show_time(tic_runtime)
        show_RTC()
        t_start += EVENT_MS  # Time tics


Comments

  • JonnyMacJonnyMac Posts: 8,998

    Here's a cleaner way to do it. The update timing is handled by Micropython. It's a good idea to keep your functions atomic: note I've separated update from display.

    # Soft RTC demo
    
    from microbit import *
    
    hr = 0
    mn = 0
    sc = 0
    
    
    @run_every(s=1)                                        # run every second
    def update_rtc():
        global hr, mn, sc 
    
        sc += 1
        if (sc == 60):
            sc = 0
            mn += 1
            if (mn == 60):
                mn = 0
                hr += 1
                if (hr == 24):
                    hr = 0
    
    
    def show_rtc():
        global hr, mn, sc
    
        print("%.2d:%.2d:%.2d" % (hr, mn, sc))
    
    
    last = sc
    show_rtc()
    
    while True:
        if sc != last:                                     # if new second
            last = sc                                      # mark new time
            show_rtc()                                     # show the clock
    

    Reference: https://microbit-micropython.readthedocs.io/en/v2-docs/microbit.html?highlight=run_every

  • RsadeikaRsadeika Posts: 3,837

    Thanks Jon. Some more stuff to think about. Talk about some tight code, this is probably as tight as it gets.

    Ray

  • JonnyMacJonnyMac Posts: 8,998

    The trick with Python is finding out what's available. I once wrote a command line tool for work. I asked a more experience colleague to review my code. He said, "You're a really good programmer... but you work too hard!" It turns out that there was a library that did what I had written, but better and more efficiently. In this case I imported microbit in the REPL than used dir() to see its contents -- that's when run_every stuck out and I did a search for docs. It's perfect for what you're doing.

  • RsadeikaRsadeika Posts: 3,837

    Below is Jon's demo code, to which I added three commands: quit, showtime, and settime. This morning I ran the clock for about an hour, and it seems to be keeping time correctly. When I get a chance, I will run this for maybe a twenty-four-hour period.

    A couple of things I have to think about, how should I handle the clock time when it rolls over. Should there be a notation, something like day-1, and increase the number, it is beyond my capabilities to add a calendar to this.

    Since this uses "@run_every(s=1) ", if I were to add tasking code, would this still run without errors.

    Ray

    # soft_rtc_jon.py
    #
    from microbit import *
    import sys
    
    uart.init(115200)
    
    hr = 0
    mn = 0
    sc = 0
    
    # This starts the clock engine immediately.
    @run_every(s=1)                                        # run every second
    def update_rtc():
        global hr, mn, sc
    
        sc += 1
        if (sc == 60):
            sc = 0
            mn += 1
            if (mn == 60):
                mn = 0
                hr += 1
                if (hr == 24):
                    hr = 0
    
    
    def show_rtc():
        global hr, mn, sc
    
        print("%.2d:%.2d:%.2d" % (hr, mn, sc))
    
    def set_time():
        global hr, mn, sc 
        inhour = input("hour(xx): ")
        inmin = input("minutes(xx): ")
        insec = input("seconds(xx): ")
        hr = int(inhour)
        mn = int(inmin)
        sc = int(insec)
        print("%.2d:%.2d:%.2d" % (hr, mn, sc))
        uart.write(">>>")
    
    def menu():
        uart.write("\n")
        print("       System Menu")
        print("quit - End the program.")
        print("settime - Set the clock.")
        print("showtime - Show the current time.")
        uart.write(">>>") 
    
    
    uart.write("Microbit softRTC.\n>>>")
    menu()
    
    
    while True:
        inbuff=""
        if uart.any():
            inbuff=uart.read().strip().decode()
            if inbuff == "showtime":
                show_rtc()
                uart.write(">>>")
            elif inbuff == "settime":
                set_time()
            elif inbuff == "quit":
                sys.exit()
    
            else:
                uart.write("not an option")
                uart.write("\n>>>")
    
    
    
Sign In or Register to comment.