Science and technology

Create a countdown clock with a Raspberry Pi

For 2021, Pi Day has come and gone, leaving fond reminiscences and plenty of Raspberry Pi projects to check out. The days after any vacation could be arduous when returning to work after excessive spirits and loads of enjoyable, and Pi Day isn’t any exception. As we glance into the face of the Ides of March, we will lengthy for the thrill of the earlier, properly, day. But concern no extra, expensive Pi Day celebrant! For in the present day, we start the lengthy countdown to the subsequent Pi Day!

OK, however severely. I made a Pi Day countdown timer, and you may too!

Some time again, I bought a Raspberry Pi Zero W and not too long ago used it to figure out why my WiFi was so bad. I used to be additionally intrigued by the concept of getting an ePaper show for the little Zero W. I did not have a great use for one, however, dang it, it appeared like enjoyable! I bought a bit 2.13″ Waveshare display, which match completely on high of the Raspberry Pi Zero W. It’s straightforward to put in: Just slip the show down onto the Raspberry Pi’s GIPO headers and also you’re good to go.

I used Raspberry Pi OS for this venture, and whereas it certainly could be carried out with different working methods, the raspi-config command, used under, is most simply accessible on Raspberry Pi OS.

Set up the Raspberry Pi and the ePaper show

Setting up the Raspberry Pi to work with the ePaper show requires you to allow the Serial Peripheral Interface (SPI) within the Raspberry Pi software program, set up the BCM2835 C libraries (to entry the GPIO capabilities for the Broadcom BCM 2835 chip on the Raspberry Pi), and set up Python GPIO libraries to regulate the ePaper show. Finally, you have to set up the Waveshare libraries for working with the two.13″ show utilizing Python.

Here’s a step-by-step walkthrough of the best way to do these duties.

Enable SPI

The best technique to allow SPI is with the Raspberry Pi raspi-config command. The SPI bus permits serial information communication for use with units—on this case, the ePaper show:

$ sudo raspi-config

From the menu that pops up, choose Interfacing Options -> SPI -> Yes to allow the SPI interface, then reboot.

Install BCM2835 libraries

As talked about above, the BCM2835 libraries are software program for the Broadcom BCM2385 chip on the Raspberry Pi, which permits entry to the GPIO pins and the power to make use of them to regulate units.

As I am scripting this, the most recent model of the Broadcom BCM 2835 libraries for the Raspberry Pi is v1.68. To set up the libraries, you have to obtain the software program tarball and construct and set up the software program with make:

# Download the BCM2853 libraries and extract them
$ curl -sSL http://www.airspayce.com/mikem/bcm2835/bcm2835-1.68.tar.gz -o - | tar -xzf -

# Change directories into the extracted code
$ pushd bcm2835-1.68/

# Configure, construct, verify and set up the BCM2853 libraries
$ sudo ./configure
$ sudo make verify
$ sudo make set up

# Return to the unique listing
$ popd

Install required Python libraries

You additionally want some Python libraries to make use of Python to regulate the ePaper show, the RPi.GPIO pip bundle. You additionally want the python3-pil bundle for drawing shapes. Apparently, the PIL bundle is all however lifeless, however there’s another, Pillow. I’ve not examined Pillow for this venture, however it might work:

# Install the required Python libraries
$ sudo apt-get replace
$ sudo apt-get set up python3-pip python3-pil
$ sudo pip3 set up RPi.GPIO

Note: These directions are for Python three. You can discover Python 2 directions on Waveshare’s web site

Download Waveshare examples and Python libraries

Waveshare maintains a Git repository with Python and C libraries for working with its ePaper shows and a few examples that present the best way to use them. For this countdown clock venture, you’ll clone this repository and use the libraries for the two.13″ show:

# Clone the WaveShare e-Paper git repository
$ git clone https://github.com/waveshare/e-Paper.git

If you are utilizing a distinct show or a product from one other firm, you may want to make use of the suitable software program to your show.

Waveshare offers directions for a lot of the above on its web site:

Get a enjoyable font (non-obligatory)

You can show your timer nevertheless you need, however why not do it with a bit type? Find a cool font to work with!

There’s a ton of Open Font License fonts accessible on the market. I’m notably keen on Bangers. You’ve seen this in the event you’ve ever watched YouTube—it is used throughout. It could be downloaded and dropped into your person’s native shared fonts listing to make it accessible for any software, together with this venture:

# The "Bangers" font is a Open Fonts License licensed font by Vernon Adams (https://github.com/vernnobile) from Google Fonts
$ mkdir -p ~/.native/share/fonts
$ curl -sSL https://github.com/google/fonts/uncooked/grasp/ofl/bangers/Bangers-Regular.ttf -o fonts/Bangers-Regular.ttf

Create a Pi Day countdown timer

Now that you’ve got put in the software program to work with the ePaper show and a enjoyable font to make use of, you’ll be able to construct one thing cool with it: a timer to rely all the way down to the subsequent Pi Day!

If you need, you’ll be able to simply seize the countdown.py Python file from this venture’s GitHub repo and skip to the tip of this text.

For the curious, I am going to break down that file, part by part.

Import some libraries

#!/usr/bin/python3
# -*- coding:utf-Eight -*-
import logging
import os
import sys
import time

from datetime import datetime
from pathlib import Path
from PIL import Image,ImageDraw,ImageFont

logging.basicConfig(stage=logging.INFO)

basedir = Path(__file__).father or mother
waveshare_base = basedir.joinpath('e-Paper', 'RaspberryPi_JetsonNano', 'python')
libdir = waveshare_base.joinpath('lib')

At the beginning, the Python script imports some commonplace libraries used later within the script. You additionally want so as to add Image, ImageDraw, and ImageFont from the PIL bundle, which you may use to attract some easy geometric shapes. Finally, set some variables for the native lib listing that accommodates the Waveshare Python libraries for working with the two.13″ show, and which you should utilize later to load the library from the native listing.

Font dimension helper operate

The subsequent a part of the script has a helper operate for setting the font dimension to your chosen font: Bangers-Regular.ttf. It takes an integer for the font dimension and returns an ImageFont object you should utilize with the show:

def set_font_size(font_size):
    logging.data("Loading font...")
    return ImageFont.truetype(f"basedir.joinpath('Bangers-Regular.ttf').resolve()", font_size)

Countdown logic

Next is a small operate that calculates the meat of this venture: how lengthy it’s till the subsequent Pi Day. If it had been, say, January, it will be comparatively easy to rely what number of days are left, however you additionally want to contemplate whether or not Pi Day has already handed for the 12 months (sadface), and in that case, rely how very, very many days are forward till you’ll be able to have fun once more:

def countdown(now):
    piday = datetime(now.12 months, three, 14)

    # Add a 12 months if we're previous PiDay
    if piday < now:
        piday = datetime((now.12 months + 1), three, 14)

    days = (piday - now).days

    logging.data(f"Days till piday: days")
    return day

The primary operate

Finally, you get to the primary operate, which initializes the show and begins writing information to it. In this case, you may write a welcome message after which start the countdown to the subsequent Pi Day. But first, you have to load the Waveshare library:

def primary():

    if os.path.exists(libdir):
        sys.path.append(f"")
        from waveshare_epd import epd2in13_V2
    else:
        logging.deadly(f"not found: ")
        sys.exit(1)

The snippet above checks to ensure the library has been downloaded to a listing alongside the countdown script, after which it hundreds the epd2in13_V2 library. If you are utilizing a distinct show, you have to to make use of a distinct library. You may write your personal if you’re so inclined. I discovered it type of fascinating to learn the Python code that Waveshare offers with the show. It’s significantly simpler than I might have imagined it to be, if considerably tedious.

The subsequent little bit of code creates an EPD (ePaper Display) object to work together with the show and initializes the :

    logging.data("Starting...")
    strive:
        # Create an a show object
        epd = epd2in13_V2.EPD()

        # Initialize the displace, and ensure it is clear
        # ePaper retains it is state until up to date!
        logging.data("Initialize and clear...")
        epd.init(epd.FULL_UPDATE)
        epd.Clear(0xFF)

An fascinating apart about ePaper: It makes use of energy solely when it modifications a pixel from white to black or vice-versa. This means when the facility is faraway from the gadget or the applying stops for no matter purpose, no matter was on the display screen stays. That’s nice from a power-consumption perspective, but it surely additionally means you have to clear the show when beginning up, or your script will simply write over no matter is already on the display screen. Hence, epd.Clear(0xFF) is used to clear the show when the script begins.

Next, create a “canvas” the place you’ll draw the remainder of your show output:

    # Create a picture object
    # NOTE: The "epd.heigh" is the LONG aspect of the display screen
    # NOTE: The "epd.width" is the SHORT aspect of the display screen
    # Counter-intuitive...
    logging.data(f"Creating canvas - height: epd.height, width: epd.width")
    picture = Image.new('1', (epd.peak, epd.width), 255)  # 255: clear the body
    draw = ImageDraw.Draw(picture)

This matches the width and peak of the show—however it’s considerably counterintuitive, in that the quick aspect of the show is the width. I consider the lengthy aspect because the width, so that is simply one thing to notice. Note that the epd.peak and epd.width are set by the Waveshare library to correspond to the gadget you are utilizing.

Welcome message

Next, you may begin to attract one thing. This includes setting information on the “canvas” object you created above. This would not draw it to the ePaper show but—you are simply constructing the picture you need proper now. Create a bit welcome message celebrating Pi Day, with a picture of a bit of pie, drawn by yours really only for this venture:

Cute, huh?

    logging.data("Set text text...")
    bangers64 = set_font_size(64)
    draw.textual content((zero, 30), 'PI DAY!', font = bangers64, fill = zero)

    logging.data("Set BMP...")
    bmp = Image.open(basedir.joinpath("img", "pie.bmp"))
    picture.paste(bmp, (150,2))

Finally, lastly, you get to show the canvas you drew, and it is a bit bit anti-climactic:

    logging.data("Display text and BMP")
    epd.show(epd.getbuffer(picture))

That bit above updates the show to point out the picture you drew.

Next, put together one other picture to show your countdown timer.

Pi Day countdown timer

First, create a brand new picture object that you should utilize to attract the show. Also, set some new font sizes to make use of for the picture:

    logging.data("Pi Date countdown; press CTRL-C to exit")
    piday_image = Image.new('1', (epd.peak, epd.width), 255)
    piday_draw = ImageDraw.Draw(piday_image)

    # Set some extra fonts
    bangers36 = set_font_size(36)
    bangers64 = set_font_size(64)

To show a ticker like a countdown, it is extra environment friendly to replace a part of the picture, altering the show for less than what has modified within the information you need to draw. The subsequent little bit of code prepares the show to operate this fashion:

    # Prep for updating show
    epd.displayPartBaseImage(epd.getbuffer(piday_image))
    epd.init(epd.PART_UPDATE)

Finally, you get to the timer bit, beginning an infinite loop that checks how lengthy it’s till the subsequent Pi Day and shows the countdown on the ePaper show. If it really is Pi Day, you’ll be able to deal with that with a bit celebration message:

    whereas (True):
        days = countdown(datetime.now())
        unit = get_days_unit(days)

        # Clear the underside half of the display screen by drawing a rectangle filld with white
        piday_draw.rectangle((zero, 50, 250, 122), fill = 255)

        # Draw the Header
        piday_draw.textual content((10,10), "Days till Pi-day:", font = bangers36, fill = zero)

        if days == zero:
            # Draw the Pi Day celebration textual content!
            piday_draw.textual content((zero, 50), f"It's Pi Day!", font = bangers64, fill = zero)
        else:
            # Draw what number of days till Pi Day
            piday_draw.textual content((70, 50), f"str(days) ", font = bangers64, fill = zero)

        # Render the display screen
        epd.displayPartial(epd.getbuffer(piday_image))
        time.sleep(5)

The final little bit of the script does some error dealing with, together with some code to catch keyboard interrupts in an effort to cease the infinite loop with Ctrl+C and a small operate to print “day” or “days” relying on whether or not or not the output must be singular (for that one, single day every year when it is acceptable):

    besides IOError as e:
        logging.data(e)

    besides KeyboardInterrupt:
        logging.data("Exiting...")
        epd.init(epd.FULL_UPDATE)
        epd.Clear(0xFF)
        time.sleep(1)
        epd2in13_V2.epdconfig.module_exit()
        exit()

def get_days_unit(rely):
    if rely == 1:
        return "day"

    return "days"

if __name__ == "__main__":
    primary()

And there you might have it! A script to rely down and show what number of days are left till Pi Day! Here’s an motion shot on my Raspberry Pi (sped up by 86,400; I haven’t got almost sufficient disk house to avoid wasting a day-long video):

Install the systemd service (non-obligatory)

If you’d just like the countdown show to run each time the system is turned on and with out you having to be logged in and run the script, you’ll be able to set up the non-obligatory systemd unit as a systemd user service).

Copy the piday.service file on GitHub to $HOME/.config/systemd/person, first creating the listing if it would not exist. Then you’ll be able to allow the service and begin it:

$ mkdir -p ~/.config/systemd/person
$ cp piday.service ~/.config/systemd/person
$ systemctl --user allow piday.service
$ systemctl --user begin piday.service

# Enable lingering, to create a person session at boot
# and permit providers to run after logout
$ loginctl enable-linger $USER

The script will output to the systemd journal, and the output could be considered with the journalctl command.

It’s starting to look loads like Pi Day!

And there you might have it! A Pi Day countdown timer, displayed on an ePaper show utilizing a Raspberry Pi Zero W, and beginning on system boot with a systemd unit file! Now there are simply 350-something days till we will as soon as once more come collectively and have fun the improbable gadget that’s the Raspberry Pi. And we will see precisely what number of days at a look with our tiny venture.

But in reality, anybody can maintain Pi Day of their hearts year-round, so get pleasure from creating some enjoyable and academic initiatives with your personal Raspberry Pi!

Most Popular

To Top