You are on page 1of 61

Code Next CS Ed Week Curriculum

Instructor Guide: “Raspimon Academy”

Table of Contents

Introduction
Learning Objectives
Instructions
Links + Resources

Stage 1: Meet your Raspimon ~ 1 Welcome | 2 Name |3 Makeover | 4 Moves | 5 Dance


Stage 2: Interact with your Raspimon ~ 6 Senses | 7 Tap | 8 Shakes | 9 Flip | 10 Keyboard | 11 Eats
Stage 3: Make your Raspimon smart (vision AI, APIs) ~ 12 Sees | 13 Reads | 14 Faces
Stage 4: Tie it all together into a life cycle ~ 15 Lives

######

Introduction
Hello, instructors!

The Raspimon project will take student engineers through a narrative arc where they will be
introduced to their Raspimon that, at first, is just a shy, empty shell of a creature that does
nothing. The web content will introduce the concept and lay out the roadmap for the rest of
the activities. It should be clear to the students that they will be in charge of training the
Raspimon in the “Raspimon Academy,” where a number of labs or sessions are offered that will
teach the Raspimon new tricks.

Some of the activities will be optional; however Stage 1 is required to kick everything off.
Each lab will teach one main skill, and students are free to try them all and/or only the ones they
are interested in.

Learning Objectives
Students will:
● Learn basic Python programming skills and computing concepts.
● Create original digital artifacts using RGB LEDs and data structures (lists, dictionaries,
tuples).
● Write algorithms to interact with a Raspimon using functions, conditional statements,
logic.
● Use event handlers to process user inputs.
● Use pre-trained AI models to “teach” the Raspimon to detect facial expressions, text,
and objects using a connected camera.
● Learn how to make Python HTTP requests to 3rd party APIs and handle the response
data.
● Create simple loop LED pixel animations on the Sense HAT.
● Learn how to give feedback to the user and prompt them to interact with their pet.
● Implement a game loop in Python.

Instructions
Raspimon is a virtual creature companion students will train using Python! It lives in a Sense
HAT-equipped Raspberry Pi 400, and it will be up to students to teach it some tricks.

In this lesson, students will begin by learning how to animate a simple LED matrix Raspimon by
programming the Raspberry Pi’s Sense HAT module using Python. They will use their creativity
to design and animate your own 8x8 pixel Raspimons and add behaviors, poses, and
animations. The activities will walk them through how to teach each skill separately.

What sort of skills does this activity teach?


The Raspimon Academy labs will teach basic Python and general programming skills, such as
working with variables, writing functions, responding to inputs, and making decisions with
conditional statements.

All of the activities are meant to be introductory, and we assume students have never had
experience coding in Python or other languages. We have provided all the starter files students
will need on the Raspberry Pi, as well as some solutions to help if they get stuck.

For best results


Students should try the labs in the order they appear. While it is not essential to complete
every one, students will find each lab introduces new skills that may help them out in future
labs.

Each lab also has example code that you and/or students can use. Although we provide a lot of
information, don’t be afraid to look online for help. as well. The Python and Raspberry Pi
communities are vast, and you can find lots of helpful examples to help students debug
something or to add a feature we may not have covered in the labs.

How to get started


Students should have the right equipment for these activities. (If you have the Raspimon
Academy Kit, you have all the necessary components to get started.) You should have the
following:
● A Raspberry Pi 4 or Raspberry 400 (integrated keyboard)
● A USB keyboard and mouse. Newer bluetooth or wireless options should also work, but
not guaranteed
● An HDMI monitor or TV
● A Sense HAT unit
● A USB web camera (for AI Computer Vision activities)
● An Internet connection
● An SD card with the latest version of Raspberry Pi OS

Students should connect all the components as outlined in this quickstart guide, or follow this
setup video. Make sure everything is connected and that the SD card is securely inserted into
the Pi. Then, connect the Pi to a power source (USB-C). This process will take some time if it is
the first time students are setting up the Pi.

Upon first install, the system will setup and the user will be guided through some steps, such
as:
● Updating the password. If you skip this step, the default password is raspberry. The
username is pi.
● Choosing a keyboard localization.
● Connecting to a network. You will need your local network password.
● Installing the updates. This process can take a long time, so be prepared to wait up to
a few hours depending on your network speed.

Finally, to get started with the Raspimon Academy, a student will need to get all the source
files. On Pi, they should open an Internet browser, which by default is the Chromium browser,
and navigate to this address → https://codenext.me/raspimon ← to find the Github repo for
the Raspimon Academy.

In this Github repo, students will find the README.md file detailing how to download and use
the code and resources. However all the instructions for the activities will be found on this
page, starting with Lab 1: Welcome.

Good luck and happy coding!


Links and Resources

Website ● Code Next content


● UI/UX -content
● Initial ReadMe
● Raspberry Pi content
● Educator guide

Repos and ● Github repo


Resources ○ Solution branch
● Folder w /sample Raspimon images
● Video demos (Drive folder)
● SD card image
● Raspimon Builder (Trinket.io)

Raspimon Stages

Stage 1: Meet your Raspimon

Overview Meet your Raspimon and give it a personality by making simple animations on the
Sense HAT LED matrix. Learn to run basic Python scripts on the Pi and display images
and scrolling text on the Sense HAT.

Lab 1 Goals:
● Get comfortable opening and running a Python script.
● Use the print()command to print messages.
● Understand strings and variables in Python.
Welcome!
Learn:
15 mins
Run your first Python script
1. Let’s get used to the Raspberry Pi and its programming tools. On the Desktop,
you will find a folder called Raspimon. Open the folder.

2. Inside you should see a welcome.py Python script. You can tell it is a Python
script by the file extension. Right-click on it to see how to open it and select
the Thonny Python IDE.
Thonny is a Python editor designed for beginners.

3. Click the green Run button. You should see output in the shell region of
Thonny. The shell is a text-based environment you can use to see output of
your program. It is useful for debugging. It is also where you will see errors
printed.

You can stop the program at any point if you click on the Stop button.

What’s going on?


4. Read the comments in the welcome.py file to understand what is happening.
● Comments begin with a # symbol, also known as a hashtag.
Comments are ignored by the computer at run time, but they help us
humans understand what the code is doing.

● The print()command prints text to the console, which is useful in


debugging and troubleshooting your code.

● A string is a common data type for text. Strings are defined with
quotation marks (‘I am a string!’ or “I’m also string too”). Notice how
you can combine single and double quotes, in case your text includes
apostrophes or quotes.

● A variable holds a value. You assign it a value with the = sign and can
reference its name in other parts of your code. Variables can be
named almost anything (except for a few Python keywords that are
reserved) and can also be changed as your program runs.

● input() can be used to get text input from a user. A reply can be
saved in a variable and used in a script.

● sleep(0.2) is used to pause the execution of the code for a some


amount of seconds.
Try:

🔑
● Print a new welcome message.
Change the values between the quotation marks!

print("Your message goes here!")

🔑
● Change the time intervals between messages.
Modify the sleep()function calls by editing the values in seconds.

sleep(.25) # .25 is 250 milliseconds or 1/3 4 seconds.

🔑
● Prompt the user to enter more information and print it back.

fav_color =input("what's your favorite color?")

Takeaways: You have learned how to:


● Edit and run Python scripts.
● Print text to the shell.
● Store and use data in variables.
● Pause your program with the sleep() function.

Lab 2 Goals:
● Display scrolling text on a Sense HAT.
● Modify text scrolling with parameters (color, speed).
● Display the name of your Raspimon.
Raspimon
● Change colors on the LED matrix with red, green, and blue values.
name
Learn:
25 mins. Now that you know how to run a Python program, it’s time to meet your Raspimon.
Have you thought of a good name? Raspimons are shy at first, so it will be up to you to
program their personality.

1. In the Stage1 folder in the Raspimon folder you will find the
raspimon_name.py file. Open it in Thonny and run it.
What’s going on?
2. The comments will help you understand what the code is doing:
● The first lines in Python programs usually include import statements.
These statements tell your script to load the Python packages you
have installed already. Think of these imported libraries as ingredients
and sauces you will need to cook up your recipe. Nobody wants to
make their own ketchup!

● To use the Sense HAT, we have to create an instance, or copy, in our


script. You can name it anything, but we call it sense for short. Now
we can use all of its functions.

● The raspimon_egg provides the data for the image that displays in
the Sense HAT LED matrix. You will be making more of these soon.

● sense.show_message() prints a scrolling message to the matrix. In


the parentheses is the message we want to display—a string of text
between quotation marks.

● sense.set_pixels() is a function that can set all the pixels on the


Sense Hat at once. It accepts one argument—the list of colors stored
in raspimon_egg.

3. Add a new message for your Raspimon to say:

sense.show_message("I’m ready to hatch soon!")

4. Add more messages for your Raspimon to say, like what its favorite color is, or
maybe it says: “Let me out!” This time include color information as shown
below:

sense.show_message("I love red!", text_colour=[255,0,0])

After the message in quotes, you can add more optional parameters, or
instructions, for how you want it to scroll. You can set the RGB color with the
functions below, which uses the UK English spelling for color (colour).
● text_colour=[255, 255, 0] for the text.
● back_colour=[ 0 ,0, 255] for the background.
● The default color is white.

Curious about colors? You can learn


more about RGB values here. The
Sense HAT uses the RGB color model,
which means that the three values
correspond to the red, green, and blue colors,
and have to be between 0 and 255

If you find the scrolling speed to slow (or fast), you can change the speed by
including an optional scroll_speed argument to the show_message()
function. The default value is 0.1.

sense.show_message("I can go faster or slower", scroll_speed=0.4)

Errors
5. Before we move on, let’s talk about errors. You may have already experienced
an error and probably wondered how to interpret it. Errors, besides preventing
you from running your Python script, will usually output some information to
the Shell that can help you debug your program.

Remove the import statements at the top. Save your program, then run it
again. What do you see?

Your shell gives you a few clues. You get the line number in your code that
caused the error, the name of the file and its location, and the actual error:
‘SenseHat’ is not defined. If you look at the Assistant panel, it also gives helpful
information:
The message is a bit more helpful for beginners. But why doesn’t it know what
it means? Well, we removed the import statements, so when the code gets to
line 5, it doesn’t know what that means.

Don’t forget to undo your changes and add the import statements back in.

Other errors are a bit tricker. Remove the closing parentheses from this line:

sense = SenseHat(

If you run it, you will actually see an error that flags a line below it. That’s
because Python expected something to be inside the parentheses and ran
into an error when it found other code below.

Indentation errors are also common in Python. Add a space before the
previous line, but don’t forget to close the parentheses first. You will get an
Indentation Error. You will learn how to indent in a future lesson, but for
now, just know that where your code starts is important.

Try:

🔑
1. Teach your Raspimon its name. It should scroll across the screen.
Try to declare a variable first, then pass it to the show_message()
function:

name = "Codey"
sense.show_message(name)

🔑
2. Change the image of the egg to a hatched Raspimon.
Just pass the the raspimon_hatched list of colors to the
set_pixels() function between the parentheses:
sense.set_pixels(raspimon_hatched)

3. Experiment with different color combinations as needed. FYI the LEDs in the
Sense HAT are bright, but have a hard time with darker colors.

Takeaways
You have learned how to:
● Import other code into your scripts.
● Set colors using the RGB color model.
● Scroll text on a Sense HAT.
● Change all the pixels at once.

Lab 3 Goals:
● Learn to store and get values from Python lists.
● Store RGB values as tuples in a list.
● Display colors to the LED matrix on the Sense HAT using x,y coordinates.
Raspimon
● Display colors to the LED matrix with set_pixels.
makeover
Learn:
30 mins In Lab 2 you displayed an image on the RGB LEDs, and now you'll get to create some
more images of your own to customize the look of your Raspimon. But first, let’s
understand how Python lists work, since you will be working with them to store data.

1. Open raspimon_makeover.py from your Raspimon folder. Read the


comments to get started.

Lists
2. In the script, you will see a list of Raspimon names. Python lists are defined
with square brackets as below:

names = ["Codey" , "Galbert" , "Freedy", "Voltria" ]

Go ahead and add more names to the list. Make sure to put quotes around
the name, and separate each list element with a comma. Or...

3. You can also add names with code. Use the .append() function on a list to
add another name:

names.append("Another")

4. Print out the name of your Raspimon (make sure it is in the list) as a Sense HAT
message. Each list element has an address. The first element has an index of
zero. The second has an index of 1. For example:
sense.show_message(names[1]) #scrolls the second element

Defining colors
5. Now it’s time to define a new list with colors. How do we store colors? We use
another data structure called a tuple and assign it to a variable with 3 values,
one for each color, red, green, and blue. Combine these to make many more.

r = (255, 0, 0) # red to max value, no green or blue


w = (255, 255, 255) #white is all colors maxed
k = (0, 0, 0) #RGB black, but for LED it means off

Here is a list of colors that prints out an image. The image is 8x8, so there are
64 pixels total. Each of the letters in the list below represents a color, which is
made up of three values as defined above.

raspimon = [
k, k, k, k, k, k, k, k,
k, r, r, r, r, r, r, k,
k, r, k, k, k, k, r, k,
k, r, r, k, r, k, r, k,
k, r, k, k, k, k, r, k,
k, r, r, r, r, r, r, k,
k, k, r, k, r, k, k, k,
k, k, r, k, r, k, k, k
]

sense.set_pixels(raspimon)

This method is only one way to set the pixels, but it is easier to work with the
list in this grid view.

6. Change a couple of values from red to black and see the change when you
run the script again.

Setting one pixel


7. You can also change each individual pixel with the set_pixel() command.
For this option, think of the grid above as a set of rows and columns, with
rows being x and columns being y values. The top left corner is (0,0) and the
bottom is (7, 7)
8. Give the basic Raspimon example a mouth using the following code:

sense.set_pixel(3,4, [255,0,0])

Notice how .set_pixel() accepts the color information as a list with square
brackets.

Need another way to make Raspimon or other images for your LED
Matrix?

We have developed a couple of tools for you to use. If you prefer working
on a spreadsheet, you can use the Sheets Raspimon Builder. This link will
make a copy for you which you can edit. Copy the code after you make
your image using Cmd + c or Ctrl + c, then paste in your project. You will
have to remove the quotation marks around the code.
We also built a Raspimon builder which is included in the Raspimon folder.
You can use the Sense HAT joystick to design and export your Raspimons. It
is also here as a Trinket.

Try:
● Define a few more colors to use. This link includes a list of RGB colors. Not all

🔑
colors display well on a RGB LED matrix, however.
Example: declare a variable g for green: g = (0, 255, 0)

● Make another list with 64 values (8x8) and add your own colors to create your
new Raspimon! This part might take you some time, so be patient. If you need

🔑
inspiration, search for “8x8 pixel art”:
Make sure your list is defined with square brackets. Here are some
options.

● Make different views as needed for your Raspimon including: awake, asleep,
facing_right, facing_left, mouth_open, mouth_closed..

Takeaways
You have learned how to:
● Store RGB color information in lists.
● Create your own 8x8 images on the LED matrix.
● Use a Python list to store and access data.
● Represent colors using red, green, and blue color values.

Lab 4 Goals:
● Animate Raspimon using sleep() and set_pixels()
● Create variations for your Raspimon design
● Use scrolling texts in animations to tell a short story about the Raspimon.
Raspimon
Moves

45 Mins.

Learn:
So now your Raspimon has a makeover! Before beginning the next activity, you will
need a place to store all of the Raspimon “looks” so you don’t have to rebuild them
every time you do a Lab.

The Raspimon folder has another subfolder called My_Raspimons. In this folder you
can find a mostly empty file called my_raspimon.py which is the file you will use to
store all the Raspimon images and behaviors you decide to incorporate in your
project.

There is also a file called bestiary.py and an accompanying PDF with some sample
Raspimons to get you started, if you would rather use someone else's creation.

Storing Raspimons
1. No matter how you create each Raspimon look, whether you use the
Raspimon builder on the device or the online Sheets builder, you should save
the lists for each of the views with clear names such as open_mouth or
closed_eyes, etc. Each of these will hold the pose for your Raspimon. Giving
each list a good name is important, since it is often hard to see what image is
hiding inside the list of letter-coded values in the 8x8 matrix.

2. Paste the list into the my_raspimon.py file under the comment about adding
more Raspimon views.

You can also paste them into the bestiary.py file and add them to the list of
Raspimons:

raspimons= [raspee, chirp, frankie, codey, your_raspimon]

Once you have explored these files, open raspimon_moves.py in the Stage 1
folder. You will find two Raspimon lists, open_eyes and closed_eyes. Run the
program and you will only see a still image.

Flip the image


3. The easiest way to move your raspimon is to use the flip_v and flip_h
commands. One is for a horizontal flip and the other vertical.
Add the following lines of code after the initial set_pixels() command:

sense.flip_h()
sleep(.5)
sense.flip_h()
sleep(.5)

Notice the use of sleep() to pause the program. Run the program a couple
of times, adjusting the value for a faster or slower effect. Copy and paste
these lines a few more times to make the Raspimon “shuffle” left and right for
longer.

You can also try flip_v() to see it flip upside down.

Blinking
4. One way to give your Raspimon life is to teach it to blink. With the provided
Raspimon examples, you can simply alternate between the two views, with a
brief pause in between. But remember, blinking has a distinct pattern and it’s
not as easy as opening and closing your eyes in regular intervals. You will have
to adjust the sleep() times to give it a more life-like blink.

Add more animations under your previous ones:


sense.set_pixels(open_eyes)
sleep(.9)
sense.set_pixels(closed_eyes)
sleep(.2)
sense.set_pixels(open_eyes)
sleep(.9)

To keep it blinking longer, simply add more lines. You can add hundreds of
these and keep it going for as long as you can!

Try:
● Create at least three more poses for your Raspimon. You should already have
a Raspimon from the previous activity, but feel free to start with another one

🔑
and develop those views to your liking.
Here are some suggestions:
-left_eye_closed and right_eye_closed
-smile
-hands_up or hands_down
-scared
-jump_up
-tongue_out

● In your raspimon_moves.py script, use set_pixels() and sleep() to create


🔑
an animation using your new Raspimon views!
Here is a sample:

sense.flip_v()
sleep(0.2)
sense.flip_v()
sleep(0.4)
sense.set_pixels(closed_mouth)
sleep(0.3)
sense.set_pixels(open_mouth)
sleep(0.4)
sense.set_pixels(closed_eyes)
sleep(0.3)
sense.set_pixels(open_mouth)
sleep(0.4)
sense.set_pixels(closed_mouth)
sleep(0.3)
sense.set_pixels(closed_eyes)
sleep(0.4)
sense.flip_v()
sleep(0.2)
sense.flip_v()

● Once the code works without errors and you are happy with the animation, go
ahead and paste the relevant Raspimon 8x8 lists into your my_raspimon.py
file, then paste the animation sequence. Run it and see your Raspimon go!

Takeaways
You have learned how to:
● Make your Raspimon move with simple animations using set_pixels() and
sleep().
● Use the flip_()command to show a mirror image on the LED display.
● Combine different views to create a short scene.

Lab 5 Goals:
● Use for and while loops to automate animations.
● Use nested loops to repeat animations within loops.
● Create new Raspimon poses to animate.
Raspimon
Dance Learn:
Your Raspimon can now move with simple animations, but you may wonder how to
30 mins make this more efficient. How can you make the Raspimon dance without writing 100
lines of code? This is where loops come to the rescue. Let’s automate your
Raspimon’s movement using Python loops!

There are a few types of loops, or ways to write them, however the idea is the same:
repeat an operation over and over for as long as you like.

1. Open and run this Trinket project to see how to work with loops.

What’s going on?


2. Notice that there are two types of loops featured in the file, a for loop and a
while loop.
✓ For loops are used when you want to do something for x number of
times. The Trinket example uses a range of numbers as a counter.

Note: Unlike other computer languages which use curly brackets { } to


define a loop (or functions), Python uses indentation after colons,
and everything inside the loop must be indented.

for x in range(10): # repeat ten times.


#indent this code block

✓ While loops repeat something while a condition is True. The most


basic while loop just uses while True because True is always true.

while True:
#do something "forever". Don’t forget to indent.

While loops can also be used to stop if a condition is met. The loop
below is similar to a for loop. It only runs ten times, from 0 to 9.

counter = 0
while counter < 10:
print(counter)
counter = counter + 1 # increase by one each turn

3. How do you know which loop to use? Use a while True loop when you want
to constantly repeat something “forever” (or until you quit the program). Use a
for loop if you know how many times you want to repeat something.

4. Note: if you want to exit a while True loop that runs forever, you will have to
interrupt the program by using Ctrl + Z on the Pi if running in the terminal or
the Stop button if running in Thonny.

5. Open up the raspimon_dance.py in your Pi. You will notice the script is
emptier than others we have shared thus far. You will have to fill in the details!
6. Under the for loop, but indented, add the code to move your Raspimon. All
you need are two different views and a couple of sleep() commands. Change
the value to see it happen as many times as you choose.

for i in range(20):
#animate your raspimon!

Run the code and see it in action!

7. Next, uncomment the while True loop by removing the # symbol. Add the
same or different code, for example flip_h() or flip_v(). If you leave both
loops, your for loop will execute first (as long as it appears first from top to
bottom), and then you will enter the while loop and remain there until you click
the Stop button.

8. Now that you know how basic for loops and while loops work, let’s try a few
more things to make your Raspimon dance!

Try:
Use loops provided (either or both) to make your Raspimon dance with an animation.
Your dance sequence can be as simple as two poses.

● Inside the provided loops, add the code to make your Raspimon dance. Use

🔑
set_pixels() and sleep() to create the animation.
Inside a loop add something similar to :

sense.set_pixels(open_mouth)
sleep(0.3)
sense.set_pixels(closed_mouth)
sleep(0.4)

Make sure you are using your own Raspimon lists.

Nested Loops
● Did you know you can actually combine while loops and for loops by placing
one inside the other? This lets you have more variety and control. Use for

🔑
loops inside a while True loop to create a dance routine!

while True:
for i in range(8):
sense.set_pixels(closed_mouth)
sleep(.2)
sense.set_pixels(open_mouth)
sleep(.4)
for i in range(10):
sense.flip_h()
sleep(.3)

This animation runs forever. First the Raspimon opens and closes its
mouth eight (8) times, then it shuffles ten (10) times, and so on.

● Once you have the code working in raspimon_dance.py, add the routine to
your own Raspimon in my_raspimon.py, including the whole loop. Don’t forget
to add the appropriate Raspimon lists if you have made new ones.

Takeaways:
You have learned how to:
● Use loops to repeat actions as defined by you.
● Save time by automating tasks with loops.
● Make your Raspimon move more with less code!

What’s Next?
With the skills you have, you can now animate your Raspimon and make it dance, eat,
tell a story, and so much more. Here are some ideas for you to continue, before you
move on to other stages:

● Combine scrolling text and LED images to tell a longer story about your
Raspimon.
● Make your Raspimon walk somewhere.
● Add more expressions for your Raspimon.
● Teach your Raspimon to fly, swim, jump, and complete other actions with
animations!

Want to make your Raspimon interactive? Move on to Stage 2 if you want to teach
your Raspimon to respond to various inputs. Stage 2 labs will teach you and your
Raspimon how to react based on different conditions. You will also learn to make your
own functions to automate your Raspimon’s activities and make reusable code.

Stage 3 will teach your Raspimon how to see using Artificial Intelligence. You will use
the USB camera to teach it to recognize objects, faces, and even text.
Stage 2: Interact with your Raspimon

Overview Teach your Raspimon to respond to you via different inputs and sensors. You will learn
how to write Python functions, or tricks, that your Raspimon will perform when the
conditions are met, or when certain events happen. You will teach your Raspimon to
respond to change in its environment by checking conditions with if/else statements
and computer logic. You will also learn to debug your code by testing different
threshold values to trigger events.

Lab 6 Goals:
● Test temperature and humidity with Sense HAT.
● Check for changes in humidity and temperature using conditional statements.
● Display data to the user and Raspimon animated response.
Raspimon
● Use a while loop to continuously test conditions.
senses
Learn:
50 mins So far you have been working on programming the LED matrix to display text and
images. However the Sense HAT module has more features. In this lab, you will train
your Raspimon to respond to changes in temperature and humidity.

1. Open the raspimon_senses.py file in your Pi. Surprise! It's mostly empty.

Reading temperature
2. Before loading any Raspimons or making views, let’s begin by reading the
temperature and humidity values the Sense HAT is detecting. Add the code
below after you declare the sense variable.

temperature = sense.get_temperature()

3. Try to print the temperature:

sense.show_message(temperature) #try this

What's going on? You should see an error message in your Terminal or output
in Thonny letting you know that it can’t print out the message because it is the
wrong type. The show_messages() function can only print string values.
Remember, string values represent text, while the temperature reading is
stored as a number—a special type of decimal value called a float.

Types
4. Try these lines of code to check on different data types using the Python
type() function:
print(type(temperature)) #prints <class ‘float’>
print(type("Hello!")) #prints <class ‘str’>
print(type(12)) #prints <class ‘int’>

So it seems we need to change the temperature type to a string before we


can pass it to the show_message() function. The Python str() function was
made for this purpose.

sense.show_message(str(temperature)) #a nested function

Make sure you close all open parentheses or you will get an error at runtime.

5. Run the code above and see what the temperature is. If you did it right, you
probably saw a temperature with lots of decimal places (a float ). You may
also notice the temperature is in Celsius, not Farenheith. How can we convert
it to ℉?

Recast the float as an integer (int), and it will become a nice round number:

temperature = int(temperature)

If you want to change the value to Farenheit, convert the temperature using
simple math and assign it again to the same variable.

temperature = temperature * 9/5 + 32

If you do convert, it makes sense to do it before you set the temperature as an


integer.

6. Repeat the same thing for the humidity using sense.get_humidity() and
scroll the value to the LED matrix.

7. Note: the temperature readings from the Sense HAT can run a bit hot
(especially if it is sitting directly on top of your Pi) , and may not be accurate.
But in this case it’s okay, because we are measuring your Raspimon's
temperature. Let’s teach it to change appearance if it is too hot or too cold.

How might you affect the temperature enough to make an impact? Here are
some suggestions:
● You may want to cool your Sense HAT by disconnecting it and putting
it in the refrigerator for a few minutes.
● Blow on the Sense HAT or place it near an AC unit.
● Place it near a sunny window or a space heater to warm it up. Be
careful to never expose it to a direct flame or intense heat.
● Warm the Sense HAT with your hands.
9. Open this Trinket project to learn how to use conditional statements in Python
along with the temperature data. Run the project and adjust the temperature
slider away from the 20℃ default.

If you make it hot enough or cold enough, the Raspimon changes colors:

Conditional Statements
10. The project features three raspimon images (raspimon_hot,
raspimon_cold and raspimon_fine). Inside a while loop, we continuously
check the temperature from the Sense HAT.

Here we use a conditional statement, or if/else statement, along with the


variable temperature, which is always being updated in the loop.

Note: Be careful to indent the code inside each conditional statement, also,
make sure your if/elif/else declarations are aligned.

if temperature > 40:


sense.set_pixels(raspimon_hot)
elif temperature <= 5:
sense.set_pixels(raspimon_cold)
else:
sense.set_pixels(raspimon_fine)

✓ if : the code within each of these conditionals only runs IF the


condition is true, such that the Raspimon will only change to red when
the temperature is GREATER than 40 degrees C.

✓ elif: Then the elif (short for else if ) statement checks if INSTEAD, the
temp might be LESS THAN OR EQUAL TO 5 degrees, in which case it
shows a blue Raspimon.

✓ else: IF NEITHER of these cases is true, the last case, else, is the
default, and will only run if the temperature is between 6 and 40
degrees.
11. Change the threshold values to see how this works in the Trinket before trying
on your Pi.

Try:
Now let’s add some conditional statements to our raspimon_senses.py script and
teach our Raspimon to respond to temperature and humidity changes.

● Add more of your own Raspimon images to represent it being cold, hot, or just
fine. Don’t forget to also paste and save them to your my_raspimon.py file.

● Add while loop to the raspimon_senses.py file. Inside the while True:, check

🔑
the temperature and/or humidity.

🔑
Add humidity = sense.get_humidty()
Add temperature = sense.get_temperature()

● Add a conditional statement and change the Raspimon image to reflect

🔑
changes in temperature or humidity.
See the conditional above! Make sure you have loaded the correct
Raspimon lists and colors.

● Run the app and check the temperature. Make adjustments so the Raspimon
actually responds to your local conditions. This will take some calibration and

🔑
testing.
Try taking several readings over a day and come up with an
average.Then add a few more degrees to that average to come up
with a “too hot” threshold.

● Humidity is easier to trigger by blowing or breathing on the Raspimon. Test


these values first by printing them out, then breathe on the Sense HAT to

🔑
provide a nice humid whiff of air. Your Raspimon will love it!

if humidity > some_value:


sense.show_pixels(happy_raspimon) #for example
sleep(2.0)
sense.show_message("Ahhhh")

Don’t forget to print data by converting the value to strings first using
str().

● Add the temperature code to your own Raspimon. You can check the
temperature and humidity continuously in a while True: loop, along with its
dances and other movements. If it gets too hot, make the Raspimon warn you!
Or have it continuously report the temperature. It’s up to you!

Takeaways:
You have learned how to:
● Read and display humidity and temperature values from the Sense HAT.
● Change strings into numbers and numbers into strings.
● Check if values meet certain conditions with If/elif/else statements.
● Make a Raspimon change appearance based on the conditions of its
environment!

Lab 7 Goals:
● Use the accelerometer data to detect “taps” to wake your Raspimon.
● Use accelerometer values (x, y, z acceleration) to detect taps and movement.
● Write a function to detect taps from a while loop.
Raspimon
● Calibrate tapping with debugging and testing.
tap
Learn:
50 mins Now you are going to use the motion sensors on the Sense HAT to detect when
someone touches or taps on the Raspimon to wake it up, dance, or do something else.
For this, you will use the accelerometer, which measures acceleration in 3 directions: x,
y and z.

1. Open the raspimon_tap.py script in the Raspimon Stage 2 folder. The script
contains some necessary import statements and two sample Raspimon
images.

2. Add a while True: loop and declare a variable (accel) to hold the accelerometer
data so you can print it to the shell.

while True:
accel = sense.get_accelerometer_raw()
print(accel)

3. Run the program. You should see a similar output as below:


Dictionaries with keys and values
4. The while loop is continuously checking the accelerometer values with the
get_accelerometer_raw() function. This returns 3 float values with lots of
decimal places! This data is packaged in a Python dictionary object, a very
useful way to store data using keys and values.

Look at the example below on how to define and access the values in a
dictionary:

planet = {"name": "Earth", "moons":1, "radius": 3958.8}

name = planet["name"]
moons = planet["moons"]
radius = planet["radius"]

print("Planet " + name + " has a radius " + str(radius) + " miles.")

The planet variable is a dictionary. Notice how the data is accessed using the
square brackets and the key word for the value we want. Also, to print out a
message, we have to convert some of the data to a string first with str().

5. Now that you see how dictionaries work, let’s get the accelerometer data for
the 3 axes : x, y, and z. You might be wondering what these mean on the actual
Sense HAT. Here is a diagram that might help you:
6. Inside the while loop add the following lines to get the three values with their
keys:

while True:
accel = sense.get_accelerometer_raw()
print(accel)
sense.set_pixels(rest) #replace with your own

x = accel["x"] #get each separate float value


y = accel["y"]
z = accel["z"]

If you look carefully, each of the values can be either positive or negative. We
can make things easier if we just take into account the absolute value instead.
There is a Python function for that, too:

x = abs(x) # changes all negative values to positive

7. You might also want to get rid of all of those extra decimal places. You can
round the values to a specific decimal place :

x = round(x, 3) #round x to 3 decimal places ex:0.02

8. Get the absolute value and round the other two values—y and z.

Detecting taps
9. How do we detect taps? Think of a tap as a slight movement in some
direction. This part will take some experimentation. For example, you can
detect when the Sense HAT moves on the x-axis and y axis together by
creating a new sum variable.
sum = x+y
sleep(.3)

if sum > .03:


print("Tap")
sense.set_pixels(tapped)
sleep(.5)

Debugging
10. Run the script again and check the print statements in the shell. Tap or lightly
move your Sense HAT and see what the values do, and calibrate until you have
a reliable tap gesture. Don’t forget to change the Raspimon to the tapped
image.

11. And that is it! You can, of course, add more conditions if you want to
differentiate between the movements. All of this will depend on how your
Sense HAT is positioned and how you tap it.

Notice that the acceleration raw values


look different depending on what
orientation the Sense HAT is in. If laying
flat right-side up, the Sense HAT shows the
z-value to be near 1.0, while the x and y are
much lower. That is because the
accelerometer is measuring gravitational pull.
The z index is actually measuring the earth’s
natural gravity! Flip the Sense HAT on its side
and see how this affects the values.

Try:
● Add your own Raspimon images to the script, replacing the ones provided.
● Have your Raspimon change colors or dance when tapped.
● Print out a message to the matrix when tapped to have your Raspimon say
something.

🔑
● Challenge: have your Raspimon say a random thing when tapped!

import random #at the top of the script


# before the while True loop, declare a random laugh list
laughs =["hahaha", "haaaaa!", "hohoho", "heee heee"]

#inside the tapped conditional:


random_choice = random.choice(laughs)
sense.show_message(random_choice)

● As usual, if you want to incorporate this feature into your main Raspimon, copy
the conditional code, along with the code that reads the accelerometer data,
and paste it into the my_raspimon.py file. Don’t forget to update the colors
and Raspimon lists as needed.

Takeaways:
You have learned how to:
● Detect small movements in your Sense HAT with the accelerometer.
● Debug and calibrate the sensor thresholds to meet your needs.
● Store data in Python dictionaries as key/value pairs.
● Work with the x-, y-, and z-axes in your Pi to measure acceleration.

Lab 8 Goals:
● Use accelerometer values (x, y, z acceleration) to detect shaking and
movement.
● Write a function to detect shaking from a while loop.
Raspimon
● Test and debug x, y, z values for accurate reading.
Shake ● Use a sum of values to simplify shake detection

50 min Learn:
This lab will be about detecting aggressive movement, like a shake. This should be
simple now that you already know how to detect slight movement with the
accelerometer.

1. Open raspimon_shake.py in the Stage 2 Raspimon folder. It will look very


similar to the previous lab starter script where you detected the movement
using get_accelerometer_raw().

2. Rebuild the previous project:


✓ Get the data from all three axes and store each in a variable (x, y, z).
✓ Round each value to 2 or 3 decimal places (it’s up to you).
✓ Convert to absolute values.

3. Before adding anything else, let’s get a reading on what a shake might look
like. For this, you will have to run the app and read the printed values in the
shell output.

What do you see when you shake? Try printing each value at a time to isolate
the reading:

x = accel["x"]
x = round(x, 3)
x = abs(x)
print("x : " + x)
When shaken from left to right, the x shows more dramatic changes. Normal
gravity is around 1, but with vigorous shaking, we can get higher values of 2 or
greater.

Sample output:

x : 0.248
x : 0.731
x : 2.439
x : 2.296
x : 1.447
x : 1.036
x : 0.248

Try shaking it in other directions and see if you can tell which direction is
which.

4. Add an if statement to check if any or a sum of these values reaches a certain


threshold for shaking:

sum = x+y+z

#change the value below to calibrate your shaking


if sum > 3:
print("shake")

5. Once you are happy with the shaking gestures and your ability to trigger your
if statement, it’s time to write a function! A function is defined like this:

def my_function():

print("function stuff goes here") #indent

6. Let’s declare a function called shake. It will handle animations and any other
thing you may want to do when you detect a shake motion. Somewhere above
your while loop, define a function like this and add the animation code.

def shake():
print("shaking")
sense.set_pixels(shake_left)
sleep(.1)
sense.set_pixels(shake_right)
sleep(.1)
sense.set_pixels(shake_left)
sleep(.1)
sense.set_pixels(shake_right)

Replace the Raspimon images to match your own. Your Raspimon can talk or
change colors, or animate. It is up to you.

7. Next, update your if statement inside the if statement:

if sum > 3:
print("shake")
shake()

8. You can call your function just by stating its name and the parentheses () as
shown above. This means every time you detect shaking, you will use this
function to animate your Raspimon.

Try:
● Write more conditional statements to detect different levels of shaking. You

🔑
may also want to write more functions to handle those gestures.

if sum > 3 and sum < 4:


print("shaking high!")
shake_high()

if sum > 2 and sum <= 3:


print("shaking low!")
shake_low()

● Add fun animations so your Raspimon responds to the shaking. Some options
include: waking up from sleep, dancing, or printing a message.

● Once the code is working as you want it, copy the shake() function to your
own my_raspimon.py file, along with the conditional code in the while True:
loop that calls it.

Takeaways:
In this lab you learned how to:
● Declare functions and call them from your code.
● Check if shaking is happening in your Sense HAT.
● Debug your code by focusing on isolated variables.
Lab 9 Goals:
● Use gyroscope values to make Raspimon aware of orientation.
● Respond to yaw, pitch, and roll value change.
● Define conditionals that test orientation.
Raspimon
Flip Learn:
In this lab, we are going to use another sensor, the gyroscope, which detects
30 mins orientation, that way you can trigger Raspimon behavior by turning the Sense HAT
upside down or in other directions.

Pitch, roll, and yaw


1. The gyroscope on the Sense HAT can detect the pitch, roll, and yaw, which
are rotations along the x-, y- and z-axes. To visualize these motions, watch this
video. [Video embedded in site]

So how does this translate to the Sense HAT? This diagram will help.

To get a sense of this at work on a Sense HAT, open this Trinket project and
move the Sense HAT model on the right and notice the orientation values
changing.
Open the raspimon_flip.py file in the Stage 2 Raspimon folder. The basic
import statements are there, but not much else. Inside the while loop, you will
see the function to get the orientation: get_orientation()

Run the script and move the Sense HAT around to get all the values in one
dictionary, as with acceleration in the previous labs. Read the orientation
values, which are in degrees (from 0 to 360).

Next, declare a roll variable and assign the value using the dictionary keys:

#after you declare orientation in the while Loop


roll = orientation["roll"]

Print the value of roll so you can get the correct value for the Sense HAT being
flipped upside down in the roll direction. This value will vary, but you should
see a change in roll of over one hundred degrees. If you do NOT see a big
change, you may be rotating the Sense HAT around the pitch or yaw axes.

Add an if/else statement that will trigger when the Sense HAT is flipped
upside down along the roll axis.

#inside the while loop


if roll > 120 and roll < 180:
print("rolled upside down!")

Notice the use of the and keyword. This means that the conditional statement
will only be true when the roll degrees are between 121 and 179. Your job is to
adjust the conditional values to match your Sense HAT orientation. Read more
about conditional logic here.

The Sense HAT allows you to easily flip the image by calling the flip_h
(horizontal) or flip_v (horizontal) functions. Add the code to flip the
Raspimon image if the Sense HAT is rolled:

#inside your if statement


sense.flip_v()

Using this function, you don’t have to create more Raspimons, just flip the
image to the other side!

Try:
● Replace the Raspimon with your own creation as you have done in previous
labs.
● Create more if statements to check for changes in pitch and yaw, and
change the Raspimon image to reflect those orientation changes.

● Write a flip() function to do something else when the Raspimon is flipped


over. You can add an animation in this code block.

● Once you are happy with your code and everything works, go ahead and add
the flip logic to your my_raspimon.py file.

Takeaways:
You have learned how to:
● Read gyroscope data on your Sense HAT.
● Flip your Raspimon image with a simple command.

Goal:
Lab 10 ● Use the Linux terminal to install a new Python library from a remote source
● Use the pynput library to detect key presses
● Respond to different key presses with if/else statements
Raspimon
Keyboard Learn:
So far we have mostly worked with the sense_hat library, which has given us access
50 mins to all the functions that come with it. But that library didn’t come pre-installed with
Python, it had to be added, or installed, before we could use it. In this lab, you will
teach a Raspimon how to respond to keyboard inputs by installing a new library called
pynput.

Installing new packages


1. To install a new package in Linux computers you can use the Terminal or
command line. You can find the Terminal on the top menu bar.

When you open it, you should see a screen like this:
2. Make sure you are online before entering the following command after the
dollar sign ~ $

$ pip3 install pynput

If you entered the command correctly, you should see some output and a
message of success:

3. Now you can import the pynput library just like sense_hat. In the Raspimon
Stage 2 folder, open the raspimon_keyboard.py and add the new import
statement at the top:
from pynput import keyboard

Inside the file you will find a few Raspimon images that will be animated with
key presses. The key presses will change what the Raspimon is currently
doing, shown with a simple animation.

4. To keep track of this, we first need to create a global variable, after the
Raspimon 8x8 lists are declared:

current_action = "rest"

Detecting keypresses
5. To detect presses, we will use an event listener that is part of the pynput
package. Event listeners have to be registered, or set up, so they can begin
“listening” for certain events, in this case, keypresses.

Add this code under the comment “#add your listener”

#add your listener


listener = keyboard.Listener(on_press=on_press)
listener.start()

6. The listener is now set up to run an on_press function every time a key is
pressed. But this does not yet exist. Let’s add it above the listener, under the
comment, “#add your on_press() function”

def on_press(key):
print(key)
You should see output as you type. But if you try to set a letter on the Sense
HAT with the sense.show_letter() command, you get an error.

def on_press(key):
print(key)
sense.show_letter(key)

That is because the show_letter() method only accepts one character, and
the key variable, if you look carefully, is actually three characters ‘a’ or ‘ + a + ‘

To print it to the Sense HAT, you can first convert the key variable to a string.
Since all strings are lists of characters, you can then use the address of the
second value to isolate the letter, then call show_letter().

def on_press(key):
letter = str(key) #convert to a string
#set the second list item from the letter string
sense.show_letter(letter[1])

Responding to key events


7. Now that you can detect which key is being pressed, all you have to do is use
if/else statements to react to when different keys are pressed. You don’t have
to handle all of the events. You may just want to add two or three keys.
8. What keys you respond to will have a lot to do with what you want your
Raspimon to do.

In this case, the Raspimon will be shown to hover, fly, and shuffle, so we will
only listen for the h, f, and s keys.

9. Add a statement to the on_press() function.

#inside on_press()
if letter[1] == 'h':
print("hovering...")
current_action = "hover"
elif letter[1] == 'f':
print("flying...")
current_action = "fly"
elif letter[1] == 's':
print("shuffling...")
current_action = "shuffle"
else:
current_action = "rest"

10. That is all the listener callback function needs to do. The actual animations
can take place in a while True loop, so the Raspimon can remain in that action
until another action changes its animation loop.

11. In a while True: loop, below where you start your listener, add this code:

#inside a while True: loop


if current_action == 'hover':
sense.set_pixels(rmon2)
sleep(.2)
sense.set_pixels(rmon3)
sleep(.3)

elif current_action == 'shuffle':


sense.flip_h()
sleep(.3)

elif current_action == 'fly':


sense.set_pixels(rmon5)
sleep(.3)
sense.set_pixels(rmon6)
sleep(.3)
else:
sense.set_pixels(rmon1)

The while loop can also include other code, such as in previous labs. Adding
the current_state variable allows us to maintain a resting animation while
allowing us to handle other inputs and events such as joystick movements,
which we will cover in the next lab.
Try:
● Add a keyboard listener to your my_raspimon.py file. Don’t forget to include
the pynput library.
● Create a few more views for your Raspimon and add them as well.
● Make your Raspimon scroll some text when a key is pressed.
● If you’ve already written functions to animate your Raspimon, just call that

🔑
function in the while loop as the current_action is updated:
elif current_action == 'shuffle':
shuffle() #declared elsewhere

Takeaways:
Now you can interact with your Raspimon with many more inputs! Using the keyboard
greatly expands how you can control what your Raspimon says and does.
You have learned how to:
● Use event listeners with callback functions.
● Import new libraries to your Raspberry Pi through the Terminal.
● Find the Terminal, which is an essential tool of the Linux operating system.

Lab 11 Goals:
● Take Raspimon “outside” by creating a birds-eye view (single pixel rendition).
● Use the joystick input commands to move the Raspimon to its food.
● Create an update() function to redraw the image on the LED matrix.
Raspimon
● Define functions to handle joystick events.
Eats ● Detect when the Raspimon reaches the food and animate the Raspimon.

90 mins
Learn:
In this lab, you will use the joystick to move your Raspimon around the LED Matrix and
guide it to its food. Your Raspimon will now be seen from a birds-eye-view and will
only be shown as one pixel.

1. Open the raspimon_eats.py file in Stage 2 of your Raspimon folder. You will
find some colors already defined and Raspimon 8x8 lists for a closed and open
mouth. Feel free to change to your own colors and Rasipimons.

Placing one pixel


2. Declare variables to hold the x- and y-coordinates for the Raspimon:

#two variables for the x and y position of the Raspimon.


raspimon_x = 1
raspimon_y = 1
sense.set_pixel(raspimon_x, raspimon_y, w)

raspimon_x and raspimon_y are both set to 1, but you can edit where the
Raspimon appears on the LED matrix, as long as either value is between 0 and
7

3. Next, add the code to represent the food. Let’s use a raspberry:
rberry_x = 7
rberry_y = 7
sense.set_pixel(rberry_x, rberry_y, r)

The berry should appear in the bottom right corner (7, 7) when you run the
script again. If that worked out, let’s now use the joystick to help the Raspimon
get to its food.

Joystick events
4. The joystick on the Sense HAT can tell us if we push it up, down, left, right, and
middle. It works the same way as your keyboard arrow and Enter/Return keys.
But how do we capture these events?

Every time the joystick moves, it generates information about the movement:
● The time it happened (as a timestamp)
● The action that occurred (pressed or released)
● The direction it was pressed (up, down, right, left and middle)

5. A while loop can continuously check for these changes. Add the following
code, making sure to indent the code inside the loop:

while True:

for event in sense.stick.get_events():


print(event)

Python is popular partly because it is easy to read. The lines in the while loop
above can be read like this: for every event that the Sense HAT joystick
registers, print the event.

6. Run the event and move the joystick. You can also press the joystick in the
middle direction. You should see two events fire each time you move the
joystick, one when you move it and one when you release it.

7. Now, let’s add some conditional statements to capture each input event.
Below is an example of how to detect when the joystick is moved down. Go
ahead and put this inside the for loop you just added, making sure to keep
indentation rules:

while True:

for event in sense.stick.get_events():


print(event)

if event.direction == "down" and event.action == "released":


print("Down")

Pay attention to the if statement above. It contains two conditions that need
to be met. Using the and keyword allows you to define more conditions. Also
notice that there are double equal signs. Read this line as: if the event
direction is equal to “down” (a string), AND if the event action is equal to
“released”, then print “Down”.

You can trigger this condition only when the stick is released from the down
position. Run the code and confirm you see a “Down” printed to the Shell.

8. Now we need to move the Raspimon around. One way to keep your code
efficient and clean is to define functions to handle each of the movements.

Above your while True loop, define this function that will be called when the
joystick is released from the down position:

def go_down():

global raspimon_y # tell Python this is a global variable


# only move if you y is 0-6
if raspimon_y < 7:
raspimon_y = raspimon_y + 1 #each time increase the y value.

What is the global raspimon_y statement about? A global variable means a


variable that you want to use throughout your program, not just inside a
particular function’s scope. Without this, Python would treat raspimon_y as a
new, different variable, even though they share the same name.

Also, make sure you only move down if the y-value is less than 7. Setting this
limit prevents movement to a location that does not exist on the matrix.

Add this code to your event detection code inside the if statement that
checks for a down movement on the joystick:

if event.direction == "down" and event.action == "released":


print("Down") #optional, but keep to verify it works
go_down() #call the function here

Updating the view


9. Run the program and press the joystick downwards. You should see a print
statement, but no movement yet. That is because we need a new function to
actually update the view each time we move, using the x- and y-coordinates.
We could update the view inside the go_down(), but that means we will repeat
it four times for the other directions, so making a separate function to handle
this is more efficient.

10. Add the following code above or below your previous function, but above the
while loop:

def update():

sense.clear() # clears the image each time


sense.set_pixel(raspimon_x, raspimon_y, w) #redraw in new place
sense.set_pixel(rberry_x, rberry_y, r) #food needs to reappear
too
print("updated...")

Think of this function as a redrawing of the image, but with the Raspimon’s y
location on the LED matrix increased by one value. Be careful, however, to use
the set_pixel() function and not set_pixels().

When do we call update? Well, every time you move the joystick. One place to
do it is at the bottom of your go_down() function, after you increase the y
position. Here is the code you should have now:

#this code should appear below your variables and raspimons


def go_down():
global raspimon_y
if raspimon_y < 7:
raspimon_y = raspimon_y + 1
update() #call after you update the position

def update():
global raspimon_x, raspimon_y
sense.clear()
sense.set_pixel(raspimon_x, raspimon_y, w)
sense.set_pixel(berry_x, berry_y, r)

while True:

for event in sense.stick.get_events():

if event.direction == "down" and event.action == "released":


print("Down")
go_down()

11. Add three more similar if statements below, making sure that you keep the
indentation pattern:

if event.direction == "up" and event.action == "released":


print("Up")
go_up()

#add left and right and call go_left() and go_right()

12. Define three more functions, go_left(), go_right(), and go_up(). Each
will be slightly different and will prevent you from moving outside of the
Matrix.

def go_up():
global raspimon_y
if raspimon_y >= 1:
raspimon_y = raspimon_y - 1
update()
def go_left():
global raspimon_x
if raspimon_x >= 1:
raspimon_x = raspimon_x - 1
update()

def go_right():
global raspimon_x
if raspimon_x < 7:
raspimon_x = raspimon_x + 1
update()

13. Run the app and fix any errors. You should see the Raspimon pixel move about
with the joystick!
14. Finally, let’s implement a function to detect when the Raspimon actually
reaches the raspberry.

We need to figure out how to know if the Raspimon was fed or not. The
Raspimon should continue moving until it gets to the food. For this, a boolean
will work. A boolean is a data type that can only be True or False. Add this
line below the Raspimon example views, near the other variables:

is_hungry = True

Next, change the while True loop so instead of running indefinitely, it will only
run while the Raspimon is_hungry. When it reaches the food, we can then
make this boolean False, and it won’t be able to move anymore.

while is_hungry:

Detecting collision
This while loop can also be used to check for this “collision.” Add another if
statement and make sure to match indentations:

if raspimon_x == berry_x and raspimon_y == berry_y:


print("Chomp chomp chomp") #optional
eat() #you will have to define this function next

What is going on? Read the if statement like this to make sense of it:

If the value of the Raspimon’s x-coordinate matches the berry’s x-coordinate


AND the y-coordinates also match, then run the eat() function.
This means it will only trigger when the Raspimon shares the same
coordinates.

17. Write an eat() function that shows a chewing animation. Stop the feeding by
setting the is_hungry boolean to False.

def eat():
global is_hungry
for i in range(10):
sense.set_pixels(closed_mouth)
sleep(.3)
sense.set_pixels(open_mouth)
sleep(.2)

is_hungry = False

Try:
You can now make a simple game with the joystick. Here are some suggestions:
● Add more raspberries for the Raspimon to eat and make each disappear when
the Raspimon eats it.
● Add a new global variable to count the berries. Each time you capture one,

🔑
increase the berry total by one.

berries = 0

#in the eat() function


berries = berries + 1
Make sure to declare it as global if you call it from the update function.
● Make a berry and the Raspimon appear in a random location. You will need to

🔑
import the random library.

import random

raspimon_x = random.randint(0,7) #get random integer 0-7


raspimon_y = random.randint(0,7)

#do the same for the berry...

🔑
● Add a timer to give you a challenge!
You can use the time library again.
#change from time import sleep to import time
import time

#declare a start and stop time


start_time = time.time()
stop_time = start_time + 10 #allow 10 seconds to play

#inside the while loop, check if time has run out


if time.time() > stop_time:
sense.show_message("Game Over")
break

● Add a keyboard event to enter into this feeding mode. Move all of your
joystick detection to a while loop nested inside that action. See previous lab
for how to use keyboard events.

Takeaways:
You have learned how to:

● Use the joystick to move a Raspimon around the 8x8 LED matrix.
● Write a function to update the current view.
● Detect when a “collision” happens on the matrix.
● Set clamps, or limits, on the movement about the matrix.
● Make a simple game with the joystick as input.

Stage 3: Make your Raspimon Smart

Overview Your Raspimon can respond to its environment! In these training labs your Raspimon
will learn how to “see” and use pre-trained AI models and a camera to detect objects,
movement, text and more.

Lab 12 Goals:
● Integrate a vision library to a Sense HAT Python script.
Raspimon ● Integrate the USB camera and capture images.
● Raspimon responds to objects.
Sees
60 Min Learn:
In the next few labs, you will explore the field of computer vision. Computer vision
deals with how computers analyze and understand content in images or videos.
Computer vision is used to help self-driving cars navigate. You might even use it when
you use your face to unlock your phone, or camera filters on your favorite social
media app. Can you think of more examples of computer vision in action?

In this lab, you will use computer vision to train your Raspimon to identify common
objects and react to them. Make sure you are connected to the Internet.

1. Connect your camera via USB to your Pi. Make sure it is in a good, well-lit spot.

2. Navigate to the Stage 3 folder and open the raspimon_sees.py file. Take a
look at the starter code. You will see a few import statements:

from sense_hat import SenseHat


from time import sleep
import vision_lib

You may be familiar with the first two import statements from previous labs. They
import the sense_hat and time libraries you will use in your code.

The last import, vision_lib, is a new one. We provided this so you can focus on
training your Raspimon, rather than project setup. It handles the camera and
computer vision code behind the scenes. Be careful not to remove or edit these
imports. You will need them later.

You’ll come back to reviewing the rest of the starter file in just a sec. Now it’s time to
start adding code.

3. Start by initializing the Sense Hat object and storing it in a variable.

4. Then, paste in your Raspimon and set it on the LED matrix.


Reference previous labs if you need a refresher on how to do this.

#initialize SenseHat instance and clear the LED matrix


sense = SenseHat()
sense.clear()

#import your colors and Raspimon and set the LED matrix
raspimon = [...]
sense.set_pixels(raspimon)
As mentioned, this starter file already has some camera features built-in for you. Let’s
explore how the project works so far.

5. First, let’s play with the camera feed. Run the code.

You should now see your Raspimon display on the Sense HAT.

There should now be a small window pop-up. This window is your camera feed and
will show a still image of what your camera sees. This still image is called a frame.

6. To capture a new frame in the window, click the window and press the ‘0’
(zero) key on your keyboard. If the window was blank before, it should now
show what your camera sees. You may need to press the 0 key a few times to
get a clear frame. Double-check here that your camera is in a good, well-lit
spot.
7. Shift your pose in the camera and press the 0 key a few more times, then stop
to freeze the frame window on your new pose.

If you hold down the 0 key, instead of just pressing it, your window will show a live
video feed of what your camera sees. This is because a video is just a bunch of
continuous, individual frames put together.

8. Now, try holding down the 0 key and moving around simultaneously. The feed
window should look like a live video!

9. When you’re ready to move on, click on the window and press the Q key to
quit. This will close the camera and continue with the rest of the program.

What’s going on?


This code at the bottom of the file is doing all of this. It may not look like much, but the
start_camera() function here handles the camera loop, key presses, and much more
behind the scenes in the imported library.

So it is important that you do not remove the lines below or the vision_lib.py file
itself.

#start camera loop


if __name__ == "__main__":
vision_lib.start_camera()

Google Cloud Vision


This start_camera() function also includes some computer vision features. Behind
the scenes, it uses a service called Google Cloud Vision that uses your camera to
detect objects and faces, as well as recognize text in images. In this lab, we will focus
on identifying objects.

10. Time for a scavenger hunt! Find a common object around you and run the
code again.

11. This time, hold the object up to the camera and freeze the frame on it. Try to
make it so that the frame image only shows the object.
12. When the frame image is ready, press the Y key on your keyboard to make
your Raspimon guess what the object is.

13. Printed in the console, you should see what your Raspimon guesses the object
in the frame is. Was it correct?

14. You can try this with other common objects as well. Just freeze the frame on
an image of the object and press Y again to make your Raspimon guess. When
you are ready to move on, press the Q key to quit.

What’s going on?


In the raspimon_sees.py file, go to the see_object(obj) function. This function is
automatically called by the library whenever the Y key is pressed.

The library then extracts what the object is as a string value and stores it in the
parameter obj for you to use. For now, the function only prints the obj string to the
console.

def see_object(obj):
#press y to print object
print(obj)
Next, you’ll add code that trains your Raspimon to react on the Sense HAT to the
detected object.

15. Add code to the see_object(obj) function to make your Raspimon show you
a message on the Sense HAT that tells you what the object is. If needed,
reference a previous lab to revisit showing messages.

#vision functions
def see_object(obj):
#press y to print object
print(obj)
#your code under here
sense.show_message(obj)

Try:
● Give your Raspimon some personality by adding more to the message it
shows.
● Add if and else-if statements that train your Raspimon to give specialized
responses when it detects certain objects. Example:

def see_object(obj):
print(obj)
#your code here
sense.set_pixels(raspimon)
sense.show_message('I see a...')
sleep(1)
sense.show_message(obj)
sleep(1)
if obj == 'Game controller':
sense.show_message("Let’s play!")
sense.set_pixels(raspimon_play)
elif obj == 'Apple':
sense.set_pixels(apple)
sense.show_message('nom nom nom nom')
sleep(1)
sense.show_message('Mmmmm yummy')

● Add your see_object(obj) function to your my_raspimon.py file at the top


of the file, after the import statements.

● After you’ve added the see_object(obj) function to your my_raspimon.py


file, you can call the vision_lib.start_camera() function in your while
loop whenever you want the camera frame to show. It will work just like it did
in this lab. It is already set up to look for and call a function named
see_object(obj) in your my_raspimon.py file when the Y key is pressed.
Example:

#define some functions. See sample_raspimon.py for examples.


def see_object(obj):
#your see_object(obj) code here...

#add a while loop to keep your Raspimon running...


if __name__ == '__main__':
while True:
sense.set_pixels(raspimon)
sleep(3)
sense.show_message('...blah...')
sense.show_message('Starting camera...')
vision_lib.start_camera() #pauses loop until 'q' is pressed
sense.set_pixels(raspimon)
sleep(.5)
sense.flip_v()
#more raspimon code etc...

● Note that wherever you call the vision_lib.start_camera() function, it will


pause your raspimon loop at that point in your code while you use the camera
features. You will need to press ‘q’ to quit the camera, and your raspimon loop
will then continue executing the rest of your code.

Takeaways:
Awesome! Now your Raspimon can see via the camera and respond to what you show
it. Get creative with how you want your Raspimon to react to certain items. You could
show your Raspimon different foods to “feed” it, animate it when it sees your dog, or
whatever else you can think of. The possibilities are endless!
You have learned how to:
● Integrate the USB camera into your project, using the vision library.
● Use computer vision to detect and classify objects in images.
● Train your Raspimon to react to the objects it “sees”.

Lab 13 Goals:
● Raspimon detects written text via USB camera text.

Learn:
Raspimon
Now that your Raspimon can identify objects, you will train it to read and understand
Reads
words you write to it.

40 mins 1. Write a phrase on a piece of paper for your Raspimon to read, and then run
the code when you’re ready.

2. Hold your paper up so that the phrase you wrote faces the camera. Then,
press the 0 key on your keyboard a few times until the camera frame is frozen
on a clear image of just your writing on the paper. If you need a refresher on
how to use the camera in this project, revisit the previous lab.

3. When the frame image is ready, press the W key on your keyboard to make
your Raspimon read what you wrote on the paper.

4. Printed in the console, you should see what your Raspimon read in the frame.
Was it correct?
5. You can try this with other words and phrases as well. Just freeze the frame
on an image of your writing and press W again to make your Raspimon read.
When you are ready to move on, press the Q key to quit.

What’s going on?


In the raspimon_reads.py file, go to the see_writing(text) function. This function
is automatically called by the library whenever the W key is pressed.

The library then extracts the written text it detects as a string value and stores it in the
parameter text for you to use. For now, the function only prints the text string to the
console.

def see_writing(text):
#press w to print writing
print(text)

Next, you’ll add code that trains your Raspimon to react on the Sense HAT to your
writing.

16. Add code to the see_writing(text) function to make your Raspimon repeat
what your writing says back to you as a message on the Sense HAT.

def see_writing(text):
#press w to print writing
print(text)
#your code under here
sense.show_message(text)
Try:
● Give your Raspimon some personality by adding more to the message.
● Add if and else-if statements that train your Raspimon to give specialized
responses when it recognizes a certain word or phrase. Example:

def see_writing(text):
print(text)
#your code here
sense.set_pixels(raspimon)
sense.show_message('I read...')
sleep(1)
sense.show_message(text)
greetings = ["What's good", 'Hi', 'Good Morning'],
if text in greetings:
sense.show_message('Hello')
elif text == 'dance':
raspimon_dance()

● Add your see_writing(text) function to your my_raspimon.py file at the


top, after the import statements.
● In the previous lab, you should already have called the
vision_lib.start_camera() function in your while loop whenever you
want the camera frame to show. It will work just like it did in this lab. It is
already set up to look for and call a function named see_writing(text) in
your my_raspimon.py file when the W key is pressed.
● It will also still detect objects when the Y key is pressed as well, so you don’t
need to call the vision_lib.start_camera() function more than once
(unless you want to, of course).

Takeaways:
You have learned how to:
● Use computer vision to decipher what text in images says.
● Train your Raspimon to respond to the words and phrases it recognizes.

Lab 14 Goals:
● Raspimon learns to detect and respond to emotions.

Learn:
Raspimon
Faces In the last lab of this stage, you’ll train your Raspimon to respond to your emotions.

30 mins 1. Selfie time! Face the camera and run the code when you’re ready.

2. Give the camera a big smile :). Press the 0 key on your keyboard a few times
to freeze the frame on your selfie.

3. When the frame image is ready, press the E key on your keyboard to make
your Raspimon detect your emotion.

4. Printed in the console, your Raspimon should have detected ‘happy’.

5. Your Raspimon can detect happy, angry, sad, and surprised. You can try
these out by making faces for any of these emotions, but we find that happy
and angry are the easiest for it to detect successfully. Just freeze the frame
on an image of you and press E again to make your Raspimon detect your
emotion. When you are ready to move on, press the Q key to quit.
What’s going on?
In the raspimon_faces.py file, go to the see_emotion(emotion) function. This
function is automatically called by the library whenever the E key is pressed.

The library then extracts the emotion it detects as a string value and stores it in the
parameter emotion for you to use. For now, the function only prints the emotion
string to the console.

def see_emotion(emotion):
#press e to print emotion
print(emotion)

Next, you’ll add code that trains your Raspimon to react on the Sense HAT to your
emotion.

6. Add code to the see_emotion(emotion) function to make your Raspimon


show you a message on the Sense HAT that tells you what it sees.

def see_emotion(emotion):
#press e to print emotion
print(emotion)
#your code under here
sense.show_message(emotion)

Try:
● Add if and else-if statements that train your Raspimon to react with its own
faces based on the emotion it detects, instead of a message. Example:

def see_emotion(emotion):
print(emotion)
#your code here
if emotion == 'happy':
sense.set_pixels(raspimon_happy)
elif emotion == 'angry':
sense.set_pixels(raspimon_angry)
else:
sense.set_pixels(raspimon)

● Add your see_emotion(emotion) function to your my_raspimon.py file at


the top of the file, after the import statements.
● In the previous lab, you should already have called the
vision_lib.start_camera() function in your while loop whenever you
want the camera frame to show. It will work just like it did in this lab. It is
already set up to look for and call a function named see_emotion(emotion)
in your my_raspimon.py file when the E key is pressed.
● It will also still detect objects when the Y key is pressed and writing when the
W key is pressed, so you don’t need to call the vision_lib.start_camera()
function more than once (unless you want to).

Takeaways:
You have learned how to:
● Use computer vision to find a face in an image and identify the emotion it
expresses.
● Train your Raspimon to react to your emotions with its own.

Stage 4 : Putting it all Together

Overview Congratulations! If you have made it this far, your Raspimon has now learned to do
many new tricks! If you have been following along, you should have built up your own
my_raspimon.py file with all the tricks and interactions you wanted to keep.

In this final Stage, it will be up to you to decide where to take your Raspimon from
here. We have some suggestions and ideas on how to get started, but it will really be
up to you to decide what to do with it.

Happy coding!

Lab 15 Goals:
● Use your creativity to develop next steps for your Raspimon.
● Have fun!
Raspimon
Lives
Your new Raspimon
So what can you do with all of these skills? How do you improve what you already
30 min have? That depends on what you want to do next. Below are some ideas to get you
started. Feel free to try one or all of them.

Life cycle
1. In most of the prior labs, you made use of a while loop to keep your Raspimon
waiting for input, or simply animating it non-stop until a condition changed. In
this version, you will keep your loop, but the goal is to have your Raspimon
evolve into new forms of being—like a butterfly! How can this happen?

Use a global variable to keep track of your current_state, much like you did
in Lab 10, Raspimon Keyboard. When the program begins, your Raspimon can
be in egg or larva form, for example. Then, as you interact with it, by shaking it,
moving the joystick, or showing it a banana, it can increase the value stored in
a variable. Open raspimon_evolves.py to see an example using shaking.

This script uses variables to store current state and amount of food.

current_state = 'egg'
food = 0

A while loop to detects shaking

while True:
#as done in raspimon_shakes.py
accel = sense.get_accelerometer_raw()
x = accel["x"]
y = accel["y"]
z = accel["z"]

x = abs(x)
y = abs(y)
z = abs(y)

shaking = x+y+z

if shaking > 3.5 and shaking < 6:


feed(shaking) # pass in the amount of shaking

if current_state == 'egg':
sense.set_pixels(raspimon_egg)
elif current_state == 'hatched':
sense.set_pixels(raspimon_hatched)

Notice that if shaking is between two values, we trigger a function call to


feed(), which looks like this:

def feed(amt):
global food, current_state
food = food + amt #increase by the amount of shaking.
if food > 50:
current_state = 'hatched'
print("hatched")

You can then add more life_cycle stages: baby, beast_mode, sick, old, who
knows!

Store data
2. So far, all of your programs run, but don’t store any persistent data, which
means that every time you start the program, it runs as if it were the first time.
This makes it difficult to have a long-living Raspimon that evolves and
changes. Wouldn’t it be great if you could run the program and have your
Raspimon at the “current_stage” you left it at?

Storing data also allows you to keep track of temperature and other values.

While you can use fancy databases to do this, a much simpler way to just save,
read, and write a single value is to store it in a text file.

The Raspimon Stage 4 folder already contains a mostly empty file called
current_state.txt, and a raspimon_save_data.py file that will
communicate with it. This script is an almost exact a copy of the previous
example, raspimon_evolves.py

The goal is for the text file to be also updated when the current_state changes
in the main program. To make it easier, the file is already in the same directory
as the main script. To open the file, use this command:

saved_state_file = open("current_state.txt","r")

The “r” specifies that we want to read the file only. This is okay, as the script
first initializes all the variables, but we will need to write to it later, as well.

Instead of declaring the current_state as ‘egg’, we will actually read what the
state is with the readlines() function. This returns a list, but our list will only
have one value at any given point, so it is okay to access the first and only
value, index zero:

current_state = saved_state_file.readlines()[0]
saved_state_file.close()

This way, when your Raspimon enters the while loop, it will look its age—
already hatched, for example.

Now update the state when it manages to evolve:

def save_current_state():
global current_state
file = open("current_state.txt", "w")
file.write(current_state) # will overwrite
file.close() #close the file.

print("saving...")

Keep in mind, the file will be opened with the “write” permission and will
simply overwrite the data.

Read more about file permissions and accessing data with text files here.

You can use append permissions to add new lines to the text file, in case you
wanted to log data, or temperature readings, etc.

Random things
3. Here are a few more ideas to try:
○ Fortune teller Raspimon. Use some form of input (keyboard,
shaking) to have your Raspimon say a random fortune. How? Declare
a list of fortunes:

fortunes = ["you will prosper",


"you will meet someone new",
"love is near"]

print(random.choice(fortunes)) # print a random choice

random.choice() accepts a list argument. It returns a random item


from the list. However you must import random at the top of your
script.
○ Raspimon games. You can use the joystick to create more advanced
games, similar to Raspimon eats. Here are some examples you can
learn from.
○ Raspimon workout. Your Raspimon can lead you on a workout
routine by telling you how many pushups, reps, jumping jacks or other
activities to complete. It could model the actions on the 8x8 screen,
and give you encouragement with scrolling text.
○ Share your Raspimon! Loading the Raspimon into a Trinket project
will allow you to publish and share your Raspimon with others.
However you will not be able to use the camera or store data.

Moving on with the Raspberry Pi


This Raspimon project is just the beginning! Head over to the official Raspberry Pi
website for ideas and projects you can do at any level, with or without the Sense HAT.

Here is a good starting point or here.

Happy coding!

You might also like