The code begins by importing the libraries.

import time
import displayio
from adafruit_magtag.magtag import MagTag
from adafruit_display_shapes.circle import Circle

A magtag object is created to access the adafruit_magtag library. Your MagTag connects to your network with magtag.network.connect().

#  create MagTag and connect to network
magtag = MagTag()
magtag.network.connect()

Three displayio groups are used. tree_group holds the tree bitmap image. circle_group holds the circles that will either hide or show the numbers on the tree bitmap. group is the main group that will allow for tree_group and circle_group to be shown at the same time.

#  displayio groups
group = displayio.Group()
tree_group = displayio.Group()
circle_group = displayio.Group()

The tree bitmap is brought in and added to the tree_group. tree_group is added to group.

# import tree bitmap
filename = "/atree.bmp"

# CircuitPython 6 & 7 compatible
tree = displayio.OnDiskBitmap(open(filename, "rb"))
tree_grid = displayio.TileGrid(
    tree, pixel_shader=getattr(tree, 'pixel_shader', displayio.ColorConverter())
)

# # CircuitPython 7+ compatible
# tree = displayio.OnDiskBitmap(filename)
# tree_grid = displayio.TileGrid(tree, pixel_shader=tree.pixel_shader)

Each circle has a specific coordinate that corresponds with the numbers on the tree bitmap. These coordinates are brought in via a list called spots.

#  list of circle positions
spots = (
    (246, 53),
    (246, 75),
    (206, 42),
    (206, 64),
    (206, 86),
    (176, 31),
    (176, 53),
    (176, 75),
    (176, 97),
    (136, 42),
    (136, 64),
    (136, 86),
    (106, 31),
    (106, 53),
    (106, 75),
    (106, 97),
    (66, 31),
    (66, 53),
    (66, 75),
    (66, 97),
    (36, 20),
    (36, 42),
    (36, 64),
    (36, 86),
    (36, 108)
    )

The 25 circles are created using a for statement. This allows the list of coordinates to be iterated through so that each circle will be in the correct position. All of the circles have a radius of 11 and 0xFF00FF as the default color, causing them to appear as a dark grey.

Each circle is added to the circle_group as they are created. After all 25 circles are created, the circle_group is added to group, joining tree_group.

#  circles to cover-up bitmap's number ornaments

#  creating the circles & pulling in positions from spots
for spot in spots:
    circle = Circle(x0=spot[0], y0=spot[1],
                    r=11,
                    fill=0xFF00FF)
	#  adding circles to their display group
    circle_group.append(circle)

#  adding circles group to main display group
group.append(circle_group)

The MagTag gathers the current time with the function magtag.get_local_time(). time.localtime() is called to parse the time data, including the month and date, into an array that can be accessed.

#  grabs time from network
magtag.get_local_time()
#  parses time into month, date, etc
now = time.localtime()
month = now[1]
day = now[2]

Additionally, the time is pulled down as well and put into an equation to figure out how many seconds it has been since midnight. This will be used to calculate how long the MagTag should go into deep sleep for.

(hour, minutes, seconds) = now[3:6]
seconds_since_midnight = 60 * (hour*60 + minutes)+seconds
print( f"day is {day}, ({seconds_since_midnight} seconds since midnight)")

The countdown's progress is revealed on the tree with a for statement. The circle_group is iterated through with the date number acting as the range. The circles that fall in that range have their fill set to None. As a result, the numbers on the bitmap tree are shown for the dates that have passed and the current date.

#  sets colors of circles to transparent to reveal dates that have passed & current date
for i in range(day):
    circle_group[i].fill = None
    time.sleep(0.1)

The MagTag display's root_group is set to to show group, which includes the tree bitmap and the circles. This is followed by a refresh, which is necessary when updating an E-Ink display.

#  updates display with bitmap and current circle colors
magtag.display.root_group = group
magtag.display.refresh()
time.sleep(5)

Finally, the MagTag enters a deep sleep until midnight after calculating how many seconds have passed since the previous midnight. With deep sleep, you can keep this project running on a battery for a long time since the power draw is minimal. Additionally, there is no need for a loop since the entire code will run again from the beginning when the MagTag awakens.

print("entering deep sleep")
seconds_to_sleep = 24*60*60 - seconds_since_midnight + 10
print( f"sleeping for {seconds_to_sleep} seconds")
magtag.exit_and_deep_sleep(seconds_to_sleep)

#  entire code will run again after deep sleep cycle
#  similar to hitting the reset button

This guide was first published on Dec 09, 2020. It was last updated on Mar 18, 2024.

This page (CircuitPython Code Walkthrough) was last updated on Mar 08, 2024.

Text editor powered by tinymce.