Raspberry Pi Zero unique motivational quote bot project

As an Amazon Associate I earn from qualifying purchases.

4 Min Read

The Covid-19 pandemic has been hard for everyone. Why not give yourself a break and create this unique Raspberry Pi Zero project. This motivational quote bot will display a new quote every hour. It sits on my desk and gets me through the day.

Photo by ConorJOHanlon

Parts you will need

For this project you will need the following items:

Photo by ConorJOHanlon
Raspberry Pi Zero WI recommend getting the Raspberry Pi Zero WH (Zero W with Headers) @ Amazon as it already includes the header need for the Waveshare screen. No soldering required!
Waveshare e-paper 2.13 inch e-Paper Display HatI used the Waveshare 2.13 inch e-Paper Display Hat @ Amazon for this project.
Micro SD cardI used a Sandisk 16GB Micro SD card for this project.
Power SupplymicroUSB power supply.
3D Printed caseYou can download the 3D files below or buy the case from me here Raspberry Pi Zero Case (With e-paper cutout) @ Etsy.

You will also need an installation of Raspberry Pi OS on your micro SD card. If you are unsure of how to do this, please read the post How to Install an OS on the Raspberry Pi.

Inserting the Raspberry Pi into the case

Start by pushing your Raspberry Pi Zero into the provided case. Note: Please make sure your SD card is removed before trying to fit the Raspberry Pi into this case. Failure to do this will damage the card

Photo by ConorJOHanlon

Your Raspberry Pi should fit snugly into the case. If you printed this case yourself and it does not fit, try increasing the print size by 1 or 2%.

Installing the Waveshare e-Paper screen

If you have already have a Raspberry Pi Zero and you don’t have header pins, you will need to solder these pins to your board. Otherwise, the Waveshare e-Paper screen should fit right on top of your Raspberry Pi. Getting the screen into place inside the case can be a little tricky. Do not force the screen on the Pi as you will bend the pins

Photo by ConorJOHanlon

Installing the cover

Place the cover on top of the case and push firmly into place. After this, carefully insert the micro SD card back into the Raspberry Pi. The final assembly should look like below:

Photo by ConorJOHanlon

Writing the Python code

Cloning the Repository

Power up the Raspberry Pi. You will now need to clone my Pi-Motivator repository. This repository includes the necessary Waveshare libraries, fonts and a file named quotes.json which is used to store the quotes:

git clone https://github.com/ConorJOHanlon/Pi-Motivator.git

Now change directory to the Pi-Motivator folder:

cd Pi-Motivator

Your directory structure should look like the following:

pi@mypi:~/Pi-Motivator $ ls
fontawesome-webfont.tff  Font.ttc  lib  quotes.json  README.md

Importing the libraries

Create a new Python file named motivator.py in the current folder:

touch motivator.py

You will also need to install the pillow library for Python. This can be done using pip install:

pi@mypi:~/Pi-Motivator $ pip install pillow

Open motivator.py in the editor of your choice. I will be using vim for this tutorial. Start by importing json, random and textwrap. You will be using these imports to load in the quotes.json file, picking a random quote and wrapping the text to make sure that it fits on the screen,

import json
import random
import textwrap

Next, import epd2in13_V2 from lib, Image, ImageDraw, ImageFont from PIL and time:

from lib import epd2in13_V2
from PIL import Image,ImageDraw,ImageFont
import time

Now, you need to define the font you will be using to display the text. Make a reference to the font provided in the repository with the size as 16:

base_font = ImageFont.truetype('Font.ttc', 16)

Getting the quotes from quote.json

Create a method named get_quotes with no arguments. This method will open the quotes.json file, pick a random quote and return the title and message:

def get_quote():
	filename = "quotes.json"
	with open(filename, encoding="utf8") as json_file:
		data = json.load(json_file)
		r = random.randint(0,len(data))
		title = data[r]['from']
		message = data[r]['text']
		return title, message

Rendering the text to the Waveshare e-Paper screen:

Now that you have a way to get your quote, you need to print it to the screen. Initialize the module and print a white box which covers the entire screen. This will clear the frame:

epd = epd2in13_V2.EPD()
epd.init(epd.FULL_UPDATE)
image = Image.new('1', (epd.height, epd.width), 255)  # 255: clear the frame
draw = ImageDraw.Draw(image)
epd.display(epd.getbuffer(image))

The motivational quote bot displays a new quote every hour. To do this let’s go ahead and create a while loop. When a message gets printed, you will want to draw a white rectangle first to clear the screen:

while True:
	epd.init(epd.PART_UPDATE)
	draw.rectangle((0, 0, epd.height, epd.width), fill = 255)

Go ahead and get a random quote by using the method created earlier. You will also want to break this text into multiple lines using textwrap.fill . In my case I chose to break after 30 characters which made the text fit the screen perfectly. Note: I am only using the message variable here but if you had a bigger screen you could use both:

	title, message = get_quote()
	message = textwrap.fill(message,30)

Once you have your quote, print it to the screen using draw.text and epd.displayPartial. After this, sleep for 60 minutes before displaying a new quote:

	draw.text((10,20), message, font = base_font, fill = 0)
	epd.displayPartial(epd.getbuffer(image))
	time.sleep(60*60)

Finally, run your code with the following command:

pi@mypi:~/Pi-Motivator $ python3 motivator.py

And that’s it for creating this unique Raspberry Pi Zero project! As always, if you have any questions or comments please feel free to post them below. Additionally, if you run into any issues please let me know

7 thoughts on “Raspberry Pi Zero unique motivational quote bot project”

  1. Avatar

    Hi there. I got to the final step and am getting an error. I think I followed the steps right but could have surely done something wrong…

    It appears like it can’t see the /lib folder or something for importing `spidev`? I checked `/boot/config.txt` to make sure it’s enabled and rebooted and it still doesn’t seem to work.

    pi@raspberrypi:~/Pi-Motivator $ sudo python3 motivator.py
    Traceback (most recent call last):
    File “motivator.py”, line 5, in
    from lib import epd2in13_V2
    File “/home/pi/Pi-Motivator/lib/epd2in13_V2.py”, line 32, in
    from . import epdconfig
    File “/home/pi/Pi-Motivator/lib/epdconfig.py”, line 149, in
    implementation = RaspberryPi()
    File “/home/pi/Pi-Motivator/lib/epdconfig.py”, line 50, in __init__
    self.SPI = spidev.SpiDev(0, 0)
    FileNotFoundError: [Errno 2] No such file or directory

    Any ideas? Appreciate any input you may have. Also, nice tutorial! This is a really neat little project. =)

    1. Conor O'Hanlon

      I will look into this for you. Appreciate the support! Can you send me your full code and directory structure? Thanks!

      1. Avatar

        Sure! Thanks for the response! Hopefully this turns out readable…

        It feels like the traceback is saying an import is missing or I have a bad path reference? Guessing it’s simple as I’m a Python newbie.

        “`pi@raspberrypi:~ $ ls
        Bookshelf Desktop Documents Downloads Music Pictures Pi-Motivator Public Templates Videos
        pi@raspberrypi:~ $ cd Pi-Motivator/
        pi@raspberrypi:~/Pi-Motivator $ ls
        fontawesome-webfont.tff Font.ttc lib motivator.py quotes.json README.md
        pi@raspberrypi:~/Pi-Motivator $ cat motivator.py“`

        “`
        import json
        import random
        import textwrap

        from lib import epd2in13_V2
        from PIL import Image,ImageDraw,ImageFont
        import time

        base_font = ImageFont.truetype(‘Font.ttc’, 16)

        def get_quote():
        filename = “quotes.json”
        with open(filename, encoding=”utf8″) as json_file:
        data = json.load(json_file)
        r = random.randint(0,len(data))
        title = data[r][‘from’]
        message = data[r][‘text’]
        return title, message

        epd = epd2in13_V2.EPD()
        epd.init(epd.FULL_UPDATE)
        image = Image.new(‘1’, (epd.height, epd.width), 255) # 255: clear the frame
        draw = ImageDraw.Draw(image)
        epd.display(epd.getbuffer(image))

        while True:
        epd.init(epd.PART_UPDATE)
        draw.rectangle((0, 0, epd.height, epd.width), fill = 255)

        title, message = get_quote()
        message = textwrap.fill(message,30)

        draw.text((10,20), message, font = base_font, fill = 0)
        epd.displayPartial(epd.getbuffer(image))
        time.sleep(60*60)
        pi@raspberrypi:~/Pi-Motivator $
        “`

        1. Avatar

          Figured it out. Apparently in `/boot/config.txt` the `dtparam=spi=on` was commented out & I thought I uncommented it, but I opened `vi` in read only so then it never activated…

          Sorry – user error. Thanks again for the great tutorial & stay safe!

Leave a Comment

Your email address will not be published. Required fields are marked *

Subscribe to my newsletter to keep up to date with my latest posts

Holler Box