translated

This commit is contained in:
Donkey-Hao 2022-06-12 20:31:54 +08:00
parent 6a763c4b83
commit a328549a9f
2 changed files with 384 additions and 393 deletions

View File

@ -1,393 +0,0 @@
[#]: subject: (Create a countdown clock with a Raspberry Pi)
[#]: via: (https://opensource.com/article/21/3/raspberry-pi-countdown-clock)
[#]: author: (Chris Collins https://opensource.com/users/clcollins)
[#]: collector: (lujun9972)
[#]: translator: ( Donkey-Hao )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Create a countdown clock with a Raspberry Pi
======
Start counting down the days to your next holiday with a Raspberry Pi
and an ePaper display.
![Alarm clocks with different time][1]
For 2021, [Pi Day][2] has come and gone, leaving fond memories and [plenty of Raspberry Pi projects][3] to try out. The days after any holiday can be hard when returning to work after high spirits and plenty of fun, and Pi Day is no exception. As we look into the face of the Ides of March, we can long for the joys of the previous, well, day. But fear no more, dear Pi Day celebrant! For today, we begin the long countdown to the next Pi Day!
OK, but seriously. I made a Pi Day countdown timer, and you can too!
A while back, I purchased a [Raspberry Pi Zero W][4] and recently used it to [figure out why my WiFi was so bad][5]. I was also intrigued by the idea of getting an ePaper display for the little Zero W. I didn't have a good use for one, but, dang it, it looked like fun! I purchased a little 2.13" [Waveshare display][6], which fit perfectly on top of the Raspberry Pi Zero W. It's easy to install: Just slip the display down onto the Raspberry Pi's GIPO headers and you're good to go.
I used [Raspberry Pi OS][7] for this project, and while it surely can be done with other operating systems, the `raspi-config` command, used below, is most easily available on Raspberry Pi OS.
### Set up the Raspberry Pi and the ePaper display
Setting up the Raspberry Pi to work with the ePaper display requires you to enable the Serial Peripheral Interface (SPI) in the Raspberry Pi software, install the BCM2835 C libraries (to access the GPIO functions for the Broadcom BCM 2835 chip on the Raspberry Pi), and install Python GPIO libraries to control the ePaper display. Finally, you need to install the Waveshare libraries for working with the 2.13" display using Python.
Here's a step-by-step walkthrough of how to do these tasks.
#### Enable SPI
The easiest way to enable SPI is with the Raspberry Pi `raspi-config` command. The SPI bus allows serial data communication to be used with devices—in this case, the ePaper display:
```
`$ sudo raspi-config`
```
From the menu that pops up, select **Interfacing Options** -> **SPI** -> **Yes** to enable the SPI interface, then reboot.
#### Install BCM2835 libraries
As mentioned above, the BCM2835 libraries are software for the Broadcom BCM2385 chip on the Raspberry Pi, which allows access to the GPIO pins and the ability to use them to control devices.
As I'm writing this, the latest version of the Broadcom BCM 2835 libraries for the Raspberry Pi is v1.68. To install the libraries, you need to download the software tarball and build and install the software 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, build, check and install the BCM2853 libraries
$ sudo ./configure
$ sudo make check
$ sudo make install
# Return to the original directory
$ popd
```
#### Install required Python libraries
You also need some Python libraries to use Python to control the ePaper display, the `RPi.GPIO` pip package. You also need the `python3-pil` package for drawing shapes. Apparently, the PIL package is all but dead, but there is an alternative, [Pillow][8]. I have not tested Pillow for this project, but it may work:
```
# Install the required Python libraries
$ sudo apt-get update
$ sudo apt-get install python3-pip python3-pil
$ sudo pip3 install RPi.GPIO
```
_Note: These instructions are for Python 3. You can find Python 2 instructions on Waveshare's website_
#### Download Waveshare examples and Python libraries
Waveshare maintains a Git repository with Python and C libraries for working with its ePaper displays and some examples that show how to use them. For this countdown clock project, you will clone this repository and use the libraries for the 2.13" display:
```
# Clone the WaveShare e-Paper git repository
$ git clone <https://github.com/waveshare/e-Paper.git>
```
If you're using a different display or a product from another company, you'll need to use the appropriate software for your display.
Waveshare provides instructions for most of the above on its website:
* [WaveShare ePaper setup instructions][9]
* [WaveShare ePaper libraries install instructions][10]
#### Get a fun font (optional)
You can display your timer however you want, but why not do it with a little style? Find a cool font to work with!
There's a ton of [Open Font License][11] fonts available out there. I am particularly fond of Bangers. You've seen this if you've ever watched YouTube—it's used _all over_. It can be downloaded and dropped into your user's local shared fonts directory to make it available for any application, including this project:
```
# The "Bangers" font is a Open Fonts License licensed font by Vernon Adams (<https://github.com/vernnobile>) from Google Fonts
$ mkdir -p ~/.local/share/fonts
$ curl -sSL <https://github.com/google/fonts/raw/master/ofl/bangers/Bangers-Regular.ttf> -o fonts/Bangers-Regular.ttf
```
### Create a Pi Day countdown timer
Now that you have installed the software to work with the ePaper display and a fun font to use, you can build something cool with it: a timer to count down to the next Pi Day!
If you want, you can just grab the [countdown.py][12] Python file from this project's [GitHub repo][13] and skip to the end of this article.
For the curious, I'll break down that file, section by section.
#### Import some libraries
```
#!/usr/bin/python3
# -*- coding:utf-8 -*-
import logging
import os
import sys
import time
from datetime import datetime
from pathlib import Path
from PIL import Image,ImageDraw,ImageFont
logging.basicConfig(level=logging.INFO)
basedir = Path(__file__).parent
waveshare_base = basedir.joinpath('e-Paper', 'RaspberryPi_JetsonNano', 'python')
libdir = waveshare_base.joinpath('lib')
```
At the start, the Python script imports some standard libraries used later in the script. You also need to add `Image`, `ImageDraw`, and `ImageFont` from the PIL package, which you'll use to draw some simple geometric shapes. Finally, set some variables for the local `lib` directory that contains the Waveshare Python libraries for working with the 2.13" display, and which you can use later to load the library from the local directory.
#### Font size helper function
The next part of the script has a helper function for setting the font size for your chosen font: Bangers-Regular.ttf. It takes an integer for the font size and returns an ImageFont object you can use with the display:
```
def set_font_size(font_size):
    logging.info("Loading font...")
    return ImageFont.truetype(f"{basedir.joinpath('Bangers-Regular.ttf').resolve()}", font_size)
```
#### Countdown logic
Next is a small function that calculates the meat of this project: how long it is until the next Pi Day. If it were, say, January, it would be relatively straightforward to count how many days are left, but you also need to consider whether Pi Day has already passed for the year (sadface), and if so, count how very, very many days are ahead until you can celebrate again:
```
def countdown(now):
    piday = datetime(now.year, 3, 14)
    # Add a year if we're past PiDay
    if piday &lt; now:
        piday = datetime((now.year + 1), 3, 14)
    days = (piday - now).days
    logging.info(f"Days till piday: {days}")
    return day
```
#### The main function
Finally, you get to the main function, which initializes the display and begins writing data to it. In this case, you'll write a welcome message and then begin the countdown to the next Pi Day. But first, you need to load the Waveshare library:
```
def main():
    if os.path.exists(libdir):
        sys.path.append(f"{libdir}")
        from waveshare_epd import epd2in13_V2
    else:
        logging.fatal(f"not found: {libdir}")
        sys.exit(1)
```
The snippet above checks to make sure the library has been downloaded to a directory alongside the countdown script, and then it loads the `epd2in13_V2` library. If you're using a different display, you will need to use a different library. You can also write your own if you are so inclined. I found it kind of interesting to read the Python code that Waveshare provides with the display. It's considerably less complicated than I would have imagined it to be, if somewhat tedious.
The next bit of code creates an EPD (ePaper Display) object to interact with the display and initializes the hardware:
```
    logging.info("Starting...")
    try:
        # Create an a display object
        epd = epd2in13_V2.EPD()
        # Initialize the displace, and make sure it's clear
        # ePaper keeps it's state unless updated!
        logging.info("Initialize and clear...")
        epd.init(epd.FULL_UPDATE)
        epd.Clear(0xFF)
```
An interesting aside about ePaper: It uses power only when it changes a pixel from white to black or vice-versa. This means when the power is removed from the device or the application stops for whatever reason, whatever was on the screen remains. That's great from a power-consumption perspective, but it also means you need to clear the display when starting up, or your script will just write over whatever is already on the screen. Hence, `epd.Clear(0xFF)` is used to clear the display when the script starts.
Next, create a "canvas" where you will draw the rest of your display output:
```
    # Create an image object
    # NOTE: The "epd.heigh" is the LONG side of the screen
    # NOTE: The "epd.width" is the SHORT side of the screen
    # Counter-intuitive...
    logging.info(f"Creating canvas - height: {epd.height}, width: {epd.width}")
    image = Image.new('1', (epd.height, epd.width), 255)  # 255: clear the frame
    draw = ImageDraw.Draw(image)
```
This matches the width and height of the display—but it is somewhat counterintuitive, in that the short side of the display is the width. I think of the long side as the width, so this is just something to note. Note that the `epd.height` and `epd.width` are set by the Waveshare library to correspond to the device you're using.
#### Welcome message
Next, you'll start to draw something. This involves setting data on the "canvas" object you created above. This doesn't draw it to the ePaper display yet—you're just building the image you want right now. Create a little welcome message celebrating Pi Day, with an image of a piece of pie, drawn by yours truly just for this project:
![drawing of a piece of pie][14]
(Chris Collins, [CC BY-SA 4.0][15])
Cute, huh?
```
    logging.info("Set text text...")
    bangers64 = set_font_size(64)
    draw.text((0, 30), 'PI DAY!', font = bangers64, fill = 0)
    logging.info("Set BMP...")
    bmp = Image.open(basedir.joinpath("img", "pie.bmp"))
    image.paste(bmp, (150,2))
```
Finally, _finally_, you get to display the canvas you drew, and it's a little bit anti-climactic:
```
    logging.info("Display text and BMP")
    epd.display(epd.getbuffer(image))
```
That bit above updates the display to show the image you drew.
Next, prepare another image to display your countdown timer.
#### Pi Day countdown timer
First, create a new image object that you can use to draw the display. Also, set some new font sizes to use for the image:
```
    logging.info("Pi Date countdown; press CTRL-C to exit")
    piday_image = Image.new('1', (epd.height, epd.width), 255)
    piday_draw = ImageDraw.Draw(piday_image)
    # Set some more fonts
    bangers36 = set_font_size(36)
    bangers64 = set_font_size(64)
```
To display a ticker like a countdown, it's more efficient to update part of the image, changing the display for only what has changed in the data you want to draw. The next bit of code prepares the display to function this way:
```
    # Prep for updating display
    epd.displayPartBaseImage(epd.getbuffer(piday_image))
    epd.init(epd.PART_UPDATE)
```
Finally, you get to the timer bit, starting an infinite loop that checks how long it is until the next Pi Day and displays the countdown on the ePaper display. If it actually _is_ Pi Day, you can handle that with a little celebration message:
```
    while (True):
        days = countdown(datetime.now())
        unit = get_days_unit(days)
        # Clear the bottom half of the screen by drawing a rectangle filld with white
        piday_draw.rectangle((0, 50, 250, 122), fill = 255)
        # Draw the Header
        piday_draw.text((10,10), "Days till Pi-day:", font = bangers36, fill = 0)
        if days == 0:
            # Draw the Pi Day celebration text!
            piday_draw.text((0, 50), f"It's Pi Day!", font = bangers64, fill = 0)
        else:
            # Draw how many days until Pi Day
            piday_draw.text((70, 50), f"{str(days)} {unit}", font = bangers64, fill = 0)
        # Render the screen
        epd.displayPartial(epd.getbuffer(piday_image))
        time.sleep(5)
```
The last bit of the script does some error handling, including some code to catch keyboard interrupts so that you can stop the infinite loop with **Ctrl**+**C** and a small function to print "day" or "days" depending on whether or not the output should be singular (for that one, single day each year when it's appropriate):
```
    except IOError as e:
        logging.info(e)
    except KeyboardInterrupt:
        logging.info("Exiting...")
        epd.init(epd.FULL_UPDATE)
        epd.Clear(0xFF)
        time.sleep(1)
        epd2in13_V2.epdconfig.module_exit()
        exit()
def get_days_unit(count):
    if count == 1:
        return "day"
    return "days"
if __name__ == "__main__":
    main()
```
And there you have it! A script to count down and display how many days are left until Pi Day! Here's an action shot on my Raspberry Pi (sped up by 86,400; I don't have nearly enough disk space to save a day-long video):
![Pi Day Countdown Timer In Action][16]
(Chris Collins, [CC BY-SA 4.0][15])
#### Install the systemd service (optional)
If you'd like the countdown display to run whenever the system is turned on and without you having to be logged in and run the script, you can install the optional systemd unit as a [systemd user service][17]).
Copy the [piday.service][18] file on GitHub to `${HOME}/.config/systemd/user`, first creating the directory if it doesn't exist. Then you can enable the service and start it:
```
$ mkdir -p ~/.config/systemd/user
$ cp piday.service ~/.config/systemd/user
$ systemctl --user enable piday.service
$ systemctl --user start piday.service
# Enable lingering, to create a user session at boot
# and allow services to run after logout
$ loginctl enable-linger $USER
```
The script will output to the systemd journal, and the output can be viewed with the `journalctl` command.
### It's beginning to look a lot like Pi Day!
And _there_ you have it! A Pi Day countdown timer, displayed on an ePaper display using a Raspberry Pi Zero W, and starting on system boot with a systemd unit file! Now there are just 350-something days until we can once again come together and celebrate the fantastic device that is the Raspberry Pi. And we can see exactly how many days at a glance with our tiny project.
But in truth, anyone can hold Pi Day in their hearts year-round, so enjoy creating some fun and educational projects with your own Raspberry Pi!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/raspberry-pi-countdown-clock
作者:[Chris Collins][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/clcollins
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/clocks_time.png?itok=_ID09GDk (Alarm clocks with different time)
[2]: https://en.wikipedia.org/wiki/Pi_Day
[3]: https://opensource.com/tags/raspberry-pi
[4]: https://www.raspberrypi.org/products/raspberry-pi-zero-w/
[5]: https://opensource.com/article/21/3/troubleshoot-wifi-go-raspberry-pi
[6]: https://www.waveshare.com/product/displays/e-paper.htm
[7]: https://www.raspberrypi.org/software/operating-systems/
[8]: https://pypi.org/project/Pillow/
[9]: https://www.waveshare.com/wiki/2.13inch_e-Paper_HAT
[10]: https://www.waveshare.com/wiki/Libraries_Installation_for_RPi
[11]: https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL
[12]: https://github.com/clcollins/epaper-pi-ex/blob/main/countdown.py
[13]: https://github.com/clcollins/epaper-pi-ex/
[14]: https://opensource.com/sites/default/files/uploads/pie.png (drawing of a piece of pie)
[15]: https://creativecommons.org/licenses/by-sa/4.0/
[16]: https://opensource.com/sites/default/files/uploads/piday_countdown.gif (Pi Day Countdown Timer In Action)
[17]: https://wiki.archlinux.org/index.php/systemd/User
[18]: https://github.com/clcollins/epaper-pi-ex/blob/main/piday.service

View File

@ -0,0 +1,384 @@
[#]: subject: (Create a countdown clock with a Raspberry Pi)
[#]: via: (https://opensource.com/article/21/3/raspberry-pi-countdown-clock)
[#]: author: (Chris Collins https://opensource.com/users/clcollins)
[#]: collector: (lujun9972)
[#]: translator: (Donkey-Hao)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
使用树莓派做一个倒计时闹钟
======
使用树莓派和 ePaper 显示器开始倒计时您的下一个假期。
![Alarm clocks with different time][1]
2021年[ Pi Day ][2]来了又走,留下美好的回忆以及[许多树莓派项目][3]等待我们去尝试。在任何令人精神振奋、充满欢乐的假期后回到工作中都很难, Pi Day 也不例外。当我们回望三月的时候,渴望那些天的快乐。但是不用害怕,亲爱的 Pi Day 庆祝者们,我们开始下一个 Pi Day 的漫长倒计时!
好了,严肃点。我做了一个 Pi Day 倒计时器,你也可以!
不久前,我购买了一个 [树莓派 Zero W][4] 并且用它来 [解决 WiFi 较差的原因][5] 。我也对使用 ePaper 来作为显示器十分感兴趣。而我却没有一个很好的用途,但是那看起来很有趣!我买了一个十分适合放在树莓派的顶部的 2.13 英寸的 [ WaveShare 显示器][6] 。安装很简单:只需要将显示器接到树莓派的 GPIO 上即可。
我使用 [树莓派系统][7] 来实现该项目,虽然其他的操作系统肯定也能完成。但是下面的 `raspi-config` 指令在树莓派系统上很容易使用。
### 设置树莓派和 ePaper 显示器
设置树莓派和 ePaper 显示器一起工作,需要你在树莓派上启用串行外设接口 (SPI) 软件,安装 BCM2835 C 库(来访问树莓派上的 Broadcom BCM 2835 芯片的 GPIO 函数),安装 Python GPIO 库来控制 ePaper 显示器。最后,你需要安装 WaveShare 的库来使用 Python 控制 2.13 英寸的显示器。
下面是完成这些的步骤。
#### 启用 SPI
树莓派上启用 SPI 最简单的方式是使用`raspi-config` 命令。SPI 总线允许串行数据通信与设备一起使用——在本例中ePaper 显示:
```
`$ sudo raspi-config`
```
从弹出的菜单中, 选择 **Interfacing Options** -&gt; **SPI** -&gt; **Yes** 来启用 SPI 接口,然后启动。
#### 安装 BCM2835 库
如上所述BCM2835 库是用在树莓派 Broadcom BCM2385 芯片的软件,它允许访问 GPIO 引脚来控制设备。
在我写这篇文章之时,用于树莓派的最新 Broadcom BCM2385 库版本是 v1.68 。安装此库需要下载软件压缩包然后使用 `make` 来安装:
```
# 下载 BCM2853 库并解压
$ curl -sSL <http://www.airspayce.com/mikem/bcm2835/bcm2835-1.68.tar.gz> -o - | tar -xzf -
# 进入解压后的文件夹
$ pushd bcm2835-1.68/
# 配置、检查并安装 BCM2853 库
$ sudo ./configure
$ sudo make check
$ sudo make install
# 返回上级目录
$ popd
```
#### 安装需要的 Python 库
你用 Python 控制 ePaper 显示器需要安装 Python 库 `RPi.GPIO` ,还需要 `python3-pil` 包画图。显然, PIL 包已经不行了, Pillow 可以作为代替方案。我还没有为该项目测试 Pillow ,但它可行:
```
# 安装需要的 Python 库
$ sudo apt-get update
$ sudo apt-get install python3-pip python3-pil
$ sudo pip3 install RPi.GPIO
```
_注意这些是 Python3 的指令。你可以在 WaveShare 网站查到 Python2 的指令。_
#### 下载 WaveShare 示例和 Python 库
Waveshare 维护一个 Python 和 C 的 Git 库,用于使用其 ePaper 显示器和一些展示如何使用它们的示例。对这个倒计时时钟而言,你需要克隆这个库并用于 2.13 英寸的显示器:
```
# 克隆这个 WaveShare e-Paper git 库
$ git clone <https://github.com/waveshare/e-Paper.git>
```
如果你用不同的显示器或者其他公司产品,需要使用适配软件。
Waveshare 提供了很多指导:
* [WaveShare ePaper 设置指导][9]
* [WaveShare ePaper 库安装指导][10]
#### 获得有趣的字体(选做)
你可以随心所欲的使用显示器,为什么不搞点花样?找一个炫酷的字体!
这有大量 [开放字体许可][11] 的字体可用。我十分喜爱 Bangers 字体。如果你看过 YouTube 那你见过这种字体了,它十分流行。你可以下载到本地的共享字体目录文件中,并且所有的应用都可以使用,包括这个项目:
```
# “Bangers” 字体是 Vernon Adams 用 Google 字体开放许可授权的字体
$ mkdir -p ~/.local/share/fonts
$ curl -sSL <https://github.com/google/fonts/raw/master/ofl/bangers/Bangers-Regular.ttf> -o fonts/Bangers-Regular.ttf
```
### 创建一个 Pi Day 倒计时器
现在你已经安装好了软件,可以使用带有炫酷字体的 ePaper 显示器了。你可以创建一个有趣的项目:倒计时到下一个 Pi Day
如果你想,你可以从该项目的 [GitHub repo][13] 直接下载 [countdown.py][12] 这个 Python 文件并跳到文章结尾。
为了满足大家的好奇心,我将逐步讲解。
#### 导入一些库
```
#!/usr/bin/python3
# -*- coding:utf-8 -*-
import logging
import os
import sys
import time
from datetime import datetime
from pathlib import Path
from PIL import Image,ImageDraw,ImageFont
logging.basicConfig(level=logging.INFO)
basedir = Path(__file__).parent
waveshare_base = basedir.joinpath('e-Paper', 'RaspberryPi_JetsonNano', 'python')
libdir = waveshare_base.joinpath('lib')
```
开始先导入一些标准库之后脚本中用。也需要你添加一些 PIL 的包: `Image`, `ImageDraw` ,和 `ImageFont` ,你会 用到这些包来画一些简单的图形。最后,为包含用于 2.13 英寸显示器的 Waveshare Python 库的本地 `lib` 目录设置一些变量,稍后你可以使用这些变量从本地目录加载库。
#### 字体大小辅助函数
下一部分是为你选择的字体建立一个修改大小的辅助函数: Bangers-Regular.ttf 。该函数将整型变量作为大小参数并返回一个图形字体对象来用于显示:
```
def set_font_size(font_size):
    logging.info("Loading font...")
    return ImageFont.truetype(f"{basedir.joinpath('Bangers-Regular.ttf').resolve()}", font_size)
```
#### 倒计时逻辑
接下来是计算这个项目的一个函数:距下次 Pi Day 还有多久。如果 Pi Day 在一月,那么计算剩余天数将很简单。但是你需要考虑是否今年的 Pi Day 这一天已经过去了。如果是这样的话,那么计算量将会很大:
```
def countdown(now):
    piday = datetime(now.year, 3, 14)
    # 如果错过了就增加一年
    if piday &lt; now:
        piday = datetime((now.year + 1), 3, 14)
    days = (piday - now).days
    logging.info(f"Days till piday: {days}")
    return day
```
#### 主函数
最后,到了主函数,需要初始化显示器并向它写数据。这时,你应该写一个欢迎语然后再开始倒计时。但是首先,你需要加载 Waveshare 库:
```
def main():
    if os.path.exists(libdir):
        sys.path.append(f"{libdir}")
        from waveshare_epd import epd2in13_V2
    else:
        logging.fatal(f"not found: {libdir}")
        sys.exit(1)
```
上面的代码片段检查以确保该库已下载到倒计时脚本旁边的目录中然后加载“epd2in13_V2”库。 如果你使用不同的显示器,则需要使用不同的库。 如果你愿意,也可以自己编写。我发现阅读 Waveshare 随显示器提供的 Python 代码很有趣,它比我想象的要简单得多。
下一段代码创建一个 EPD ePaper 显示器)对象以与显示器交互并初始化硬件:
```
    logging.info("Starting...")
    try:
        # 创建一个显示对象
        epd = epd2in13_V2.EPD()
        # 初始化并清空显示
        # ePaper 保持它的状态处分更新
        logging.info("Initialize and clear...")
        epd.init(epd.FULL_UPDATE)
        epd.Clear(0xFF)
```
关于 ePaper 的一个有趣之处:它仅在将像素从白色变为黑色或从黑色变为白色时才使用电源。这意味着当设备断电或应用程序因任何原因停止时,屏幕上的任何内容都会保留下来。从功耗的角度来看,这很好,但这也意味着您需要在启动时清除显示,否则您的脚本只会覆盖屏幕上已有的内容。 因此,`epd.Clear(0xFF)` 用于在脚本启动时清除显示。
接下来,创建一个“画布”来绘制剩余的显示输出:
```
    # 创建一个图形对象
# 注意:"epd.heigh" 是屏幕的长边
# 注意:"epd.width" 是屏幕的短边
    # 真是反直觉…
    logging.info(f"Creating canvas - height: {epd.height}, width: {epd.width}")
    image = Image.new('1', (epd.height, epd.width), 255)  # 255: clear the frame
    draw = ImageDraw.Draw(image)
```
这与显示器的宽度和高度相匹配——但它有点反直觉,因为显示器的短边是宽度。我认为长边是宽度,所以这只是需要注意的一点。 请注意,`epd.height` 和 `epd.width` 由 Waveshare 库设置以对应于你使用的设备。
#### 欢迎语
接下来,你将开始画一些画。这涉及在你之前创建的“画布”对象上设置数据。这还没有将它绘制到 ePaper 显示器上——你现在只是在构建你想要的图像。由你为这个项目绘制带有一块馅饼的图像,来创建一个庆祝 Pi Day 的欢迎信息:
![画一块馅饼][14]
(Chris Collins, [CC BY-SA 4.0][15])
很可爱,不是吗?
```
    logging.info("Set text text...")
    bangers64 = set_font_size(64)
    draw.text((0, 30), 'PI DAY!', font = bangers64, fill = 0)
    logging.info("Set BMP...")
    bmp = Image.open(basedir.joinpath("img", "pie.bmp"))
    image.paste(bmp, (150,2))
```
最后_最后_你可以展示你画的图画
```
    logging.info("Display text and BMP")
    epd.display(epd.getbuffer(image))
```
That bit above updates the display to show the image you drew.
接下来,准备另一幅图像展示你的倒计时:
#### Pi Day 倒计时
首先,创建一个用来展示倒计时的项目。也需要设置数字的字体大小:
```
    logging.info("Pi Date countdown; press CTRL-C to exit")
    piday_image = Image.new('1', (epd.height, epd.width), 255)
    piday_draw = ImageDraw.Draw(piday_image)
    # 设置字体大小
    bangers36 = set_font_size(36)
    bangers64 = set_font_size(64)
```
为了使它显示的时候更像一个倒计时,更新图像的一部分是更加有效的手段,仅更改已经改变的显示数据部分。下面的代码准备以这样方式运行:
```
    # 准备更新显示
    epd.displayPartBaseImage(epd.getbuffer(piday_image))
    epd.init(epd.PART_UPDATE)
```
最后,需要计时,开始一个无限循环来检查据下次 Pi Day 还有多久并显示在 ePaper上。如果到了 Pi Day ,你可以输出一些庆祝短语:
```
    while (True):
        days = countdown(datetime.now())
        unit = get_days_unit(days)
        # 通过绘制一个填充有白色的矩形来清除屏幕的下半部分
        piday_draw.rectangle((0, 50, 250, 122), fill = 255)
        # 绘制页眉
        piday_draw.text((10,10), "Days till Pi-day:", font = bangers36, fill = 0)
        if days == 0:
            # 绘制庆祝语
            piday_draw.text((0, 50), f"It's Pi Day!", font = bangers64, fill = 0)
        else:
            # 绘制距下一次 Pi Day 的时间
            piday_draw.text((70, 50), f"{str(days)} {unit}", font = bangers64, fill = 0)
        # 渲染屏幕
        epd.displayPartial(epd.getbuffer(piday_image))
        time.sleep(5)
```
脚本最后做了一些错误处理,包括捕获键盘中断,这样你可以使用 **Ctrl**+**C** 来结束无限循环,以及一个根据计数来打印 'day' 或 'days' 的函数:
```
    except IOError as e:
        logging.info(e)
    except KeyboardInterrupt:
        logging.info("Exiting...")
        epd.init(epd.FULL_UPDATE)
        epd.Clear(0xFF)
        time.sleep(1)
        epd2in13_V2.epdconfig.module_exit()
        exit()
def get_days_unit(count):
    if count == 1:
        return "day"
    return "days"
if __name__ == "__main__":
    main()
```
现在你已经拥有一个倒计时脚本并显示剩余天数!这是在我的树莓派上的显示(视频经过加速,我没有足够的磁盘空间来保存一整天的视频):
![Pi Day Countdown Timer In Action][16]
(Chris Collins, [CC BY-SA 4.0][15])
#### 安装 systemd 服务(选做)
如果你希望在系统打开时运行倒计时显示并且无需登录并运行脚本,您可以将可选的 systemd 单元安装为 [systemd 用户服务][17].
将 GitHub 上的 [piday.service][18] 文件复制到 `${HOME}/.config/systemd/user`,如果该目录不存在,请先创建该目录。然后你可以启用该服务并启动它:
```
$ mkdir -p ~/.config/systemd/user
$ cp piday.service ~/.config/systemd/user
$ systemctl --user enable piday.service
$ systemctl --user start piday.service
# Enable lingering, to create a user session at boot
# and allow services to run after logout
$ loginctl enable-linger $USER
```
该脚本将输出到 systemd 日志,可以使用 `journalctl` 命令查看输出。
### 它开始看起来很像 Pi Day
现在你拥有了一个树莓派 Zero W 显示在 ePaper显示器上的 Pi Day 倒计时器!并在系统启动时使用 systemd 单元文件启动!现在只有 350 天左右我们才可以再次相聚庆祝奇妙的设备———树莓派。通过我们的小项目,我们可以一目了然地看到确切的天数。
但事实上,任何人都可以全年都在心中举行 Pi Day因此请享受使用自己的树莓派创建一些有趣且具有教育意义的项目吧
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/raspberry-pi-countdown-clock
作者:[Chris Collins][a]
选题:[lujun9972][b]
译者:[Donkey](https://github.com/Donkey-Hao)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/clcollins
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/clocks_time.png?itok=_ID09GDk (Alarm clocks with different time)
[2]: https://en.wikipedia.org/wiki/Pi_Day
[3]: https://opensource.com/tags/raspberry-pi
[4]: https://www.raspberrypi.org/products/raspberry-pi-zero-w/
[5]: https://opensource.com/article/21/3/troubleshoot-wifi-go-raspberry-pi
[6]: https://www.waveshare.com/product/displays/e-paper.htm
[7]: https://www.raspberrypi.org/software/operating-systems/
[8]: https://pypi.org/project/Pillow/
[9]: https://www.waveshare.com/wiki/2.13inch_e-Paper_HAT
[10]: https://www.waveshare.com/wiki/Libraries_Installation_for_RPi
[11]: https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL
[12]: https://github.com/clcollins/epaper-pi-ex/blob/main/countdown.py
[13]: https://github.com/clcollins/epaper-pi-ex/
[14]: https://opensource.com/sites/default/files/uploads/pie.png (drawing of a piece of pie)
[15]: https://creativecommons.org/licenses/by-sa/4.0/
[16]: https://opensource.com/sites/default/files/uploads/piday_countdown.gif (Pi Day Countdown Timer In Action)
[17]: https://wiki.archlinux.org/index.php/systemd/User
[18]: https://github.com/clcollins/epaper-pi-ex/blob/main/piday.service