Tamagotchi (Year 8 Digital Design)
- SOI: Designers enhance the form of a product to meet the needs of communities
- Key concept: Communities
- Related concept: Form
- Context: Identities and relationships (adaptation, form)
- Assessed criteria: A
- Key technology: Shaper3D, ESP32, LCD, Wifi / BLE, MicroPython
Using the form of a wearable or a keychain for your school bag, create a community of interactive STC Tamagotchis. Use wifi / BLE to meet/socialise with other Tamagotchis nearby to earn life points. Design and 3D print your protective case to your own style and needs.
- Watch the trailer
- Video 1: Connect your device
- Video 2: Text, colours, coordinates
- Video 3: Variables, loops, timers
- Video 4: More loops, detect touch, increase counters
- Video 5: If statements, touch coordinates, multiple variables
- Video 6: Creating functions to organise your code
- Video 7: Converting and displaying images
- Video 8: Connect to wifi, download and display data
- Video 9: Start your project, connect to Virtual Pet API
- Video 10: Show the weather
- Video 11: Show your timetable
- Video 12: Feed your pet a virtual meal
- Video 13: Navigation menu
- Video 14: Say hello to other pets
- Video 15: Paper rock scissors
- Video 16: Screensaver mode (inactivity timer)
- Video 17: Error handling (wifi issues etc)
Watch the trailer
Video 1: Connect your device
Download the all the files you need as a ZIP file
Or download them individually:
Video 2: Text, colours, coordinates

Video 3: Variables, loops, timers
Video 4: More loops, detect touch, increase counters
Video 5: If statements, touch coordinates, multiple variables
Video 6: Creating functions to organise your code
Video 7: Converting and displaying images
Code to convert PNG/JPG images to RAW
# Utility to convert images to raw RGB565 format.
from PIL import Image
from struct import pack
from os import path
import os
import sys
def convert_file(in_file, out_file):
# Sha Tin's CYD devices require BGR format RAW files
print('Converting: ' + in_file)
img = Image.open(in_file).convert('RGB')
pixels = list(img.getdata())
with open(out_file, 'wb') as f:
for pix in pixels:
r = (pix[2] >> 3) & 0b00011111 # 5 bits
g = (pix[1] >> 2) & 0b00111111 # 6 bits
b = (pix[0] >> 3) & 0b00011111 # 5 bits
f.write(pack('>H', (r << 11) + (g << 5) + b))
print('Saved: ' + out_file)
def convert_all_images_in_folder(folder=None):
if not folder:
folder = os.getcwd()
files = os.listdir()
for ssource_file in files:
if ssource_file.lower().endswith(".png") or ssource_file.lower().endswith(".jpeg") or ssource_file.lower().endswith(".jpg"):
target_file = ssource_file.split(".")[0]+".raw"
convert_file(ssource_file, target_file)
convert_all_images_in_folder()
Video 8: Connect to wifi, download and display data
Video 9: Start your project, connect to Virtual Pet API
POST https://api.pbaumgarten.com/pets/register
headers = {
"X-API-KEY": "PROVIDED BY YOUR TEACHER",
"Content-Type": "application/json"
}
data = {
"pet_name": "NAME FOR THE SYSTEM TO REMEMBER FOR YOUR PET"
}
response = {
"pet_name": "YOUR PET NAME",
"owner_name: "YOUR NAME",
"pet_id": "YOUR PET ID NUMBER",
"points_balance": 0 // balance of points earnt so far
}
Video 10: Show the weather
GET https://api.pbaumgarten.com/pets/weather
headers = {
"X-API-KEY": "PROVIDED BY YOUR TEACHER"
}
response = [
{
"Day": "Name of today",
"Info": "Weather description",
"Max": "Maximum temperature",
"Rain": "Likelihood of significant rain":
},{
"Day": "Name of tomorrow",
"Info": "Weather description",
"Max": "Maximum temperature",
"Rain": "Likelihood of significant rain":
}
]
Video 11: Show your timetable
start_dates = {
(2025, 8, 11): 0,
(2025, 10, 13): 0,
(2025, 11, 17): 0,
(2026, 1, 5): 0,
(2026, 2, 23): 0,
(2026, 4, 13): 5
}
timetable = [
["12 CS", "10 CS", "11 CS", "13 CS", "9 DD 7"],
["13 CS HL", "13 CS HL", "7 DD 3", "", "9 DD 1"],
["", "9 DD 3", "12 CS", "9X2 WB", ""],
["11 CS", "", "10 CS", "", "12 CS"],
["12 CS", "10 CS", "13 CS", "", "8 DD 2"],
["11 CS", "", "13 CS HL", "9 DD 3", ""],
["12 CS", "12 CS", "", "10 CS", "11 CS"],
["", "7 DD 3", "", "9X2 WB", ""],
["13 CS", "9 DD 1", "", "11 CS", "10 CS"],
["12 CS", "9 DD 7", "8 DD 2", "", "13 CS"]
]
Video 12: Feed your pet a virtual meal
POST https://api.pbaumgarten.com/pets/meal
headers = {
"X-API-KEY": "PROVIDED BY YOUR TEACHER"
}
response if successful = {
"status": "success",
"points_balance": 999,
}
response if too soon = {
"status": "too soon"
}
Video 13: Navigation menu
Video 14: Say hello to other pets
POST https://api.pbaumgarten.com/pets/hello
headers = {
"X-API-KEY": "PROVIDED BY YOUR TEACHER"
}
response if successful = {
"status": "success",
"responder": "their pet name",
}
response if waiting for another player = {
"status": "acknowledged"
}
POST https://api.pbaumgarten.com/pets/hello-check
headers = {
"X-API-KEY": "PROVIDED BY YOUR TEACHER"
}
response if successful = {
"status": "success",
"responder": "their pet name",
}
response no other player = {
"status": "no responses"
}
Video 15: Paper rock scissors
POST https://api.pbaumgarten.com/pets/prs
headers = {
"X-API-KEY": "PROVIDED BY YOUR TEACHER"
}
response if successful = {
"status": "match",
"result": "win", "tie", or "lose"
"your_choice": "rock", "paper" or "scissors",
"their_choice": "rock", "paper" or "scissors",
"opponent": "their pet name"
}
response if waiting for someone else = {
"status": "waiting for opponent"
}
POST https://api.pbaumgarten.com/pets/prs-check
headers = {
"X-API-KEY": "PROVIDED BY YOUR TEACHER"
}
response if successful = {
"status": "match",
"result": "win", "tie", or "lose"
"your_choice": "rock", "paper" or "scissors",
"their_choice": "rock", "paper" or "scissors",
"opponent": "their pet name"
}
response no response = {
"status": "no opponent found""
}