powered by TinkerSpace.in
Join free
TinkerPy Tutorial ๐Ÿ“˜ Part 2 ยท Coder ยท Chapter 20 of 24

Counter & Clock

Count visitors at the door, run a quiz timer, ring an alarm at 7 oโ€™clock โ€” all while your program keeps doing other things. TinkerPyโ€™s counters and clock tick by themselves in the background!

๐Ÿ“–Key words

Counter

A number box that can count up or down by itself. TinkerPy has eight: c1 to c8. Tick Counter in Circuit Connections (import counter) โ€” no pins needed.

Background

Work the board keeps doing while your loop runs, even during wait(). Auto counters and the clock tick in the background.

Clock

A software clock: clock_start(7, 0, 0) sets it to 7:00:00 and starts it. Tick Clock in Circuit Connections (import clock).

HH, MM, SS

Three special values that always hold the clockโ€™s hour (0โ€“23), minute and second (0โ€“59). Use them like variables: if HH == 7:

Flag

A variable like rang = 0 / 1 that remembers whether something already happened, so an alarm rings once.

๐ŸŽฌSee it work

Counter c1 counts down

Press Step: c1 counts down by itself and the alarm switches on at 0.

The clock rolls over

Press Step: watch SS, MM and HH tick from 6:59:58 to 7:00:00.

๐Ÿง How it works

Counters that count by themselves

  • c1.auto_increment(1000) adds 1 every 1000 ms (every second), for ever, in the background. c1.auto_decrement(500) takes away 1 every half second.
  • c1.set(30) jumps straight to 30 โ€” use it before a countdown.
  • Use a counter like a variable: if c1 == 0:, if c1 >= 10:, oled_write(2, center, large, bold, c1).
  • Eight counters can run at once, each at its own speed: c1.auto_increment(1000) and c2.auto_increment(200).

Pausing, clearing and checking

  • c1.increment() adds 1 once and c1.decrement() takes away 1 once โ€” perfect for button presses and visitors.
  • c1.pause() freezes an auto counter where it is. Call c1.auto_increment() or c1.auto_decrement() again to restart it.
  • c1.clear() puts the counter back to 0 but does not stop auto counting: it carries on 1, 2, 3โ€ฆ
  • One press can be seen in many loops. Add a wait(300) after counting a press so one press counts once.

A clock with HH, MM and SS

  • clock_start(6, 59, 50) in setup: sets the time and starts the clock. The hour is 0โ€“23: 2 PM is 14.
  • clock_speed(100): 100 real milliseconds count as one clock second โ€” 10 times faster, great for testing. clock_speed(1000) is real time.
  • clock_pause() freezes the clock; clock_resume() starts it again.
  • if HH == 7 and MM == 0: stays true for a whole minute, so use a flag (rang) to ring once.
  • This clock starts again from clock_start() when the board restarts. In chapter 10 youโ€™ll meet the RTC module, which keeps the real time with its own battery.

๐Ÿ’ปCode

# Add the libraries you need
import oled_display
import counter

# Give your pins easy-to-remember names
i1 = set_name("door_eye")
i2 = set_name("reset_btn")

# ===== Visitor counter =====

# This code block executes only once
setup:
    oled_begin()  # starts the OLED
    o7 = set_function(SDA)  # cannot be changed
    o8 = set_function(SCL)  # cannot be changed
    door_eye = set_input(ir_sensor, active_low)
    reset_btn = set_input(push_button, active_low)
    oled_write(1, center, small, bold, "Visitors today")  # write "Visitors today" on OLED line 1 (small bold, centred)

# This code block executes forever
loop:
    if door_eye == ON:  # when door_eye is ON
        c1.increment()  # add 1 to c1
        wait(800)  # one person passing counts once
    if reset_btn == ON:  # when reset_btn is ON
        c1.clear()  # reset c1 back to 0
    oled_write(2, center, large, bold, c1)  # write the value of c1 on OLED line 2 (large bold, centred)
    wait(100)  # pause here for 100 milliseconds before continuing

An IR obstacle sensor at the door adds 1 to c1 for each visitor; the reset button clears it. The OLED shows the total in large bold numbers. Works on TinkerPy Mega and Mini.

# Add the libraries you need
import oled_display
import buzzer
import counter

# Give your pins easy-to-remember names
i1 = set_name("restart")
i2 = set_name("bonus")
o1 = set_name("beeper")

# ===== Quiz round timer =====

# This code block executes only once
setup:
    oled_begin()  # starts the OLED
    o7 = set_function(SDA)  # cannot be changed
    o8 = set_function(SCL)  # cannot be changed
    restart = set_input(push_button, active_low)
    bonus = set_input(push_button, active_low)
    beeper = set_output(buzzer)
    c1.set(30)  # set c1 straight to 30
    c1.auto_decrement(1000)  # c1 counts down by 1 on its own, every 1000ms, even while other code is running
    oled_write(1, center, small, bold, "Time left")  # write "Time left" on OLED line 1 (small bold, centred)

# This code block executes forever
loop:
    oled_write(2, center, large, bold, c1)  # write the value of c1 on OLED line 2 (large bold, centred)
    if c1 == 0:  # when c1 == 0
        c1.pause()  # stop at 0 instead of going to -1
        beeper = ON  # turn beeper ON
    if bonus == ON:  # when bonus is ON
        c1.increment()  # 1 extra second for each press
        wait(300)  # pause here for 300 milliseconds before continuing
    if restart == ON:  # when restart is ON
        beeper = OFF  # turn beeper OFF
        c1.set(30)  # set c1 straight to 30
        c1.auto_decrement(1000)  # c1 counts down by 1 on its own, every 1000ms, even while other code is running
    wait(100)  # pause here for 100 milliseconds before continuing

A 30-second quiz timer: c1 counts down by itself, pauses at 0 and the buzzer sounds. The bonus button adds a second; restart starts a new round.

# Add the libraries you need
import oled_display
import buzzer
import clock

# Give your pins easy-to-remember names
o1 = set_name("alarm")

# ===== Morning alarm clock =====

# This code block executes only once
setup:
    oled_begin()  # starts the OLED
    o7 = set_function(SDA)  # cannot be changed
    o8 = set_function(SCL)  # cannot be changed
    alarm = set_output(buzzer)
    clock_start(6, 59, 50)  # start at 6:59:50 so the test is quick
    rang = 0  # set rang to 0

# This code block executes forever
loop:
    oled_write(1, center, medium, bold, "Time")  # write "Time" on OLED line 1 (medium bold, centred)
    oled_write(3, center, medium, bold, HH + ":" + MM + ":" + SS)  # write the value of HH + ":" + MM + ":" + SS on OLED line 3 (medium bold, centred)
    if HH == 7 and MM == 0 and rang == 0:  # when HH == 7 and MM == 0 and rang == 0
        alarm = ON  # turn alarm ON
        wait(3000)  # pause here for 3000 milliseconds before continuing
        alarm = OFF  # turn alarm OFF
        rang = 1  # rang already this minute
    if MM != 0:  # when MM != 0
        rang = 0  # set rang to 0
    wait(200)  # pause here for 200 milliseconds before continuing

An alarm clock on the OLED. The time is joined into one text with + (board firmware 2.24 or newer). The flag rang makes the alarm sound once at 7:00, not for the whole minute.

# Add the libraries you need
import buzzer
import clock
import lcd_16x2

# Give your pins easy-to-remember names
i1 = set_name("hold_btn")
i2 = set_name("go_btn")
o1 = set_name("bell")

# ===== Fast-forward school day =====

# This code block executes only once
setup:
    lcd_begin(0x27)  # the LCDโ€™s I2C address (most: 0x27 or 0x3F; lcd_begin() finds it)
    hold_btn = set_input(push_button, active_low)
    go_btn = set_input(push_button, active_low)
    bell = set_output(buzzer)
    o7 = set_function(SDA)  # cannot be changed
    o8 = set_function(SCL)  # cannot be changed
    clock_start(8, 59, 0)  # start the clock at 8:59:0 and let it start ticking
    clock_speed(100)  # 1 clock second = 100 ms: 10 times faster

# This code block executes forever
loop:
    lcd_write(1, 1, "Clock " + HH + ":" + MM + ":" + SS + "  ")  # write "Clock " + HH + ":" + MM + ":" + SS + "  " on LCD line 1, from place 1
    if hold_btn == ON:  # when hold_btn is ON
        clock_pause()  # pause the clock exactly where it is
        lcd_write(2, 1, "PAUSED   ")  # write "PAUSED   " on LCD line 2, from place 1
    if go_btn == ON:  # when go_btn is ON
        clock_resume()  # let the clock start ticking again
        lcd_write(2, 1, "RUNNING  ")  # write "RUNNING  " on LCD line 2, from place 1
    if HH == 9 and MM == 0 and SS < 5:  # when HH == 9 and MM == 0 and SS < 5
        bell = ON  # the 9 oโ€™clock bell
    else:  # otherwise
        bell = OFF  # turn bell OFF
    wait(100)  # pause here for 100 milliseconds before continuing

A school day at 10 times speed on a 16x2 LCD: the hold button pauses the clock and go resumes it. The bell rings for the first 5 seconds of 9:00. The two spaces at the end wipe old digits.

Open TinkerPy Code

๐ŸŽ‰Fun examples

๐ŸCricket scoreboard

Two buttons and c1.increment() make a run counter, c2 counts wickets. Put it on the OLED for your next school match.

๐Ÿง˜Yoga timer

c1.set(60) and c1.auto_decrement(1000) give a one-minute timer that beeps when it is time to change the pose.

๐Ÿš€Super-speed day

With clock_speed(10) a whole day passes in about 14 minutes โ€” watch your school timetable fly by.

๐ŸŒWhere itโ€™s used

๐Ÿ› ๏ธProject ideas

Visitor counter

Fix an IR obstacle sensor at the classroom door and upload the visitor counter. Add c2 to count only the people who stay more than 5 seconds in front of the sensor, and show both counters on the OLED.

๐Ÿงฐ You need: TinkerPy board, IR obstacle sensor, push button, OLED display
Morning alarm clock

Set clock_start() to the real time and choose your wake-up time. Add a snooze button: pressing it switches the alarm off and rings it again 5 minutes later.

๐Ÿงฐ You need: TinkerPy board, buzzer, push button, OLED display

โญPoints to remember

  1. Tick Counter in Circuit Connections: import counter. Counters are c1 to c8.
  2. c1.auto_increment(1000) adds 1 every second in the background.
  3. c1.auto_decrement(1000) counts down every second.
  4. c1.increment() / c1.decrement() add or take away 1 once.
  5. c1.set(30) jumps to 30; c1.clear() goes back to 0.
  6. c1.clear() does not stop auto counting; c1.pause() does.
  7. Use a counter like a variable: if c1 == 0, oled_write(โ€ฆ, c1).
  8. Add a wait() after counting a press so one press counts once.
  9. Tick Clock in Circuit Connections: import clock.
  10. clock_start(h, m, s) sets the time and starts the clock; hours are 0โ€“23.
  11. HH, MM and SS hold the hour, minute and second.
  12. clock_speed(100) runs 10 times faster; clock_speed(1000) is real time.
  13. clock_pause() freezes the clock; clock_resume() starts it again.
  14. A time check stays true for a whole minute โ€” use a flag to act once.
๐Ÿคฏ
Did you know?

The countdown displays at many traffic signals work just like c1.auto_decrement(1000): a number that drops by one every second until the light changes.

โ“Mini quiz

๐Ÿ”‘
Log in to try the mini quiz

5 quick questions to check yourself โ€” free with your TinkerPy account.

Log in