Smart Glasses
The Smart Glasses uses object recognition and text to speech which lets the user recognize the object without seeing it. The Raspberry Pi and camera module work together to recognize the object using pretrained models. Then, the Raspberry Pi reads the object into earbuds attached to the Raspberry Pi and glasses.
Engineer | School | Area of Interest | Grade |
---|---|---|---|
Derek Y | Los Gatos High School | Electrical Engineering | Incoming Junior |
Final Milestone
Summary
For this milestone, I enabled text to speech within the object recognition system. I simply turned the volume up and the text to speech started working. I used the festival python wrapper which enabled text to speech directly from the object recognition code. When the Pi camera detects an object, the user will hear it through the earbuds. I also assembled the glasses for this milestone. I made it portable by attaching a power bank instead of using a power outlet. I also replaced my short camera flex cable with a long one, so I can hold onto the Raspberry Pi while the camera is attached to the glasses. Then, I hotglued the camera to the glasses. Since I didn’t want to put hot glue directly on the PCB, I built the camera mount without the legs. This made a clear protective box for the camera, which I could put hot glue on and attach to the glasses.
After that, I tested my object recognition with the newly assembled glasses, and it worked. Another thing I worked on for this milestone was color recognition. First, I defined each color through the RGB numbers in the detection script. For example, if the color was r > 200, g < 80, and b < 80, the script would return red. Then it would read the object out loud, followed by “color is {color_name}”. In the bottom right corner, I also made a little rectangle which shows what color the camera was detecting. The color recognition works by making a box in the center of the screen, and finding the average color of each row. The color was always lighter than it should be, so I made a highlight filter by excluding all color values greater than 230. After doing this, the value of the color gets stored and read out loud through text to speech. The color is also shown on the UI.
Challenges
The challenges I had for the third milestone all came from the color recognition. At first, I used RGB values and the color was very inaccurate. THe system would get the avearge color in a box in the middle of the screen, and it always included other colors that weren’t the objects colors. This would ruin the average and make the output wrong. Also, holding the object would include my skin color in the average, and the output would be inaccurate. THe glare from the lights was also a problem since the bright light increased the average of the RGB values. I added filters that removed these extra values, and the system only averaged the objects color inside the box.
Triumphs
The most rewarding thing was assembling the glasses and making my final product. Adding the text to speech made the object detection accessible to blind people, and doing this felt like I had accomplished the last step of the project. After, I had to assemble the glasses by attaching the camera to the glasses. Then I plugged in earbugs and a power bank to make the machine portable. When I wore the glasses and heard the object I was holding up, I felt like I had achieved a lot from the beginning of making the smart glasses.
What I Learned
I have learned many things in Bluestamp, starting with soldering. I practiced soldering until I had a good joint. A good joint will look like a concave cone shape. I also learned about bad joints like a cold joint, which is when there wasn’t enough heat. I used soldering and made the Retro Arcade Console, and all the buttons worked on the Console which meant my joints were good. Next, I learned how to use a Raspberry Pi. Before this camp, I didn’t know what a Raspberry Pi was and what it was used for. Now I know it’s a single board computer that can run code and can be connected to various attachments. The attachment I used was the camera, which allowed the Raspberry Pi to see. Then I learned how to run code through the terminal. I learned many commands for the terminal, like creating a virtual environment and downloading github repositories straight onto the Pi with the wget command. I did this with SSH or through a remote control of the Pi. I learned how to use TigerVNC to connect to the Pi from my computer, so I wouldn’t need to plug in a keyboard and mouse into the Raspberry Pi everytime I use it. I also learned what Tensorflow is and how to use it for object recognition. Tensorflow powers the object recognition in my Pi, which uses the MobileNetV2 model. It processes each frame and outputs the detected object. Overall, I learned the basics of using a Raspberry Pi and how to use models for object recognition.
Future Plans
In the future, I hope to learn how to write scripts myself rather than getting prewritten ones from github. For example, I can write my own script that can run object recognition and make my own user interface that looks better. I also want to learn how to use AI to improve my projects and make it more user friendly. If I used an AI voice assistant within my smart glasses project, it would be much easier for the user to communicate with the Raspberry Pi. Then the user can ask the AI to play the music they want, and the AI will automatically search the song and play it. The user can also ask whether or not shops are open, or other questions the AI might know the answer to. Learning how to implementing an AI assistant in projects can make the product more helpful and easier to use.
Second Milestone
Summary
For this milestone, I downloaded Tensorflow and rpi-vision for object recognition. Rpi-vision uses the MobileNet V2 model for object detection, and Tensorflow loads a pretrained model to detect and recognize objects. By installing these two programs, running a script can utilize both programs to recognize objects. The script will detect an object, and if the confidence level is above 60%, it will output the object in the terminal and on the screen. In the end, this object recognition system will get the objects detected and read it out loud. The Raspberry Pi camera will be attached to the front of the glasses and detect/read the objects in front to the user.
Challenges
I had a lot of challenges during this step including difficulties installing Tensorflow and running the script. At first, the code didn’t work because of a virtual environment problem. In the new Raspberry Pi OS, many commands were disabled because of package interference prevention. I had to find another way to install the virtual environment, which was not using the sudo command. After, I had to install Blinka. This didn’t work because many commands used a sudo pip install, which the new Raspberry OS does not allow. I had to do the same thing and not use the sudo command.
My next challenge was installing Tensorflow. When I followed the tutorial, there would always be a problem importing libcamera, even though I already had it installed. Because of this problem, I tried a different object recognition tutorial, but that also didn’t work. I needed to downgrade my python and numpy. When I downgraded my python to 3.9 rather than 3.11, and my numpy to 1.26.4 rather than 2.0.2. The terminal commands started working, but the script only worked for USB cameras, not a picamera. I then moved onto a different tutorial that used a pretrain google model, but that didn’t work either. I kept trying different tutorials on the internet and none of them worked for me. I went back to the original tutorial and tried again on python versions 3.10 and 3.9. Libcamera still wasn’t detected. Then I decided to put my python back into version 3.11, and changed the configuration. It turns out that the use system wide packages was set to false, which made the virtual environment not detect the libcamera that was installed on the home directory. After turning this on, the object recognition window popped up and I could start detecting various objects.
Future steps
Next, I have to get text to speech working. I will have to make Raspberry Pi convert the images it sees into audio feedback. After that works, I will combine the Raspberry Pi, camera module, and glasses together to get the final Smart glasses project. I will use the power bank to make the Raspberry Pi portable with the glasses. I will attach the camera to the front of the glasses, which would allow object recognition for the object the user is looking at. Then I will be ready to finish my third milestone.
First Milestone
Summary
For this milestone, I set up the Raspberry Pi. I downloaded Raspberry Pi OS onto the SD card and put it in the Raspberry Pi. Then I attached the heatsinks and the fan to cool the main components running the Pi. Since SSH wasn’t working, I used a video capture card, mouse, and keyboard to control the Raspberry Pi. For the software, I installed OpenCV so I can use the Pi camera module. I took a picture to make sure it was working, and I finished setting up my Pi for the next part of my project.
Components
My project is the Smart Glasses and there are many different parts that work together to make the glasses function. The Raspberry Pi and camera module will run the object recognition. The Raspberry Pi will get information from the camera and process it, turning the pictures into text. Then the text will be read through the earbuds which will allow the user to hear it. Finally, this technology will be attached to the glasses, allowing the user to look at an object and get audio feedback.
Challenges
The most reccurent challenge I have faced is the remote connection not working. Normally, I would run SSH and TigerVNC, and I can directly connect to the Raspberry Pi without needing a HDMI cable. Sometimes, the connection doesn’t work and it forces me to use OBS, which is highly inefficient because I need to use a different keyboard and mouse to control the Raspberry Pi. By using TigerVNC and getting the SSH to work, I can directly control the Raspberry Pi from my computer without needing external devices. This challenge can be fixed by power cycling, but it only works sometimes.
Build Plan
First, I set up my Raspberry Pi which was what I did for this milestone. I got the camera working and took a picture with the Raspberry Pi. Next, I have to install Tensorflow and other programs for object recognition. I will make the Raspberry Pi convert the object recognized into text to speech, which will be played through the earbuds connected to the Raspberry Pi. The audio allows the user to recognize the object without needing to see the object. This feature will be especially useful for blind people, who I am building this project for. Lastly, I will attach all the technology to the glasses and power bank to power the Raspberry Pi. This will allow the device to be portable. For my modifications, I want to add voice control. Voice control will allow the user to take a picture when the command is given, and recognize an object when prompted. Also, I can add music to the Smart Glasses.
Code
# SPDX-FileCopyrightText: 2021 Limor Fried/ladyada for Adafruit Industries
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import logging
import argparse
import pygame
import os
import subprocess
import sys
import numpy as np
import signal
import cv2
import openai
import json
import queue
import threading
import sounddevice as sd
import difflib
# Load OpenAI API key from environment variable
openai.api_key = "KEY"
# Initialize Vosk speech recognition variables
voice_queue = queue.Queue()
vosk_model = None
vosk_recognizer = None
def audio_callback(indata, frames, time, status):
if status:
print(f"Vosk status: {status}")
voice_queue.put(bytes(indata))
# Shared variable for latest command
voice_cmd = None
voice_lock = threading.Lock()
# Shared state: whether assistant is listening for a prompt after wake word
assistant_active = False
def listen_loop():
global voice_cmd
with sd.RawInputStream(samplerate=16000, blocksize=8000,
dtype='int16', channels=1,
callback=audio_callback):
while True:
data = voice_queue.get()
if vosk_recognizer.AcceptWaveform(data):
result = json.loads(vosk_recognizer.Result())
text = result.get("text", "").strip()
if text:
print(f"Heard: {text}")
with voice_lock:
# Fuzzy match for wake word "glasses"
if difflib.get_close_matches(text.lower(), ["bill"], n=1, cutoff=0.7):
print("Wake word 'bill' detected")
voice_cmd = "wake"
# Special commands and assistant logic
if "take a picture" in text.lower():
voice_cmd = "take_picture"
elif "record" in text.lower():
voice_cmd = "start_recording"
elif "stop recording" in text.lower():
voice_cmd = "stop_recording"
elif assistant_active:
voice_cmd = text
def get_chatgpt_response(prompt):
response = openai.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are an AI voice assistant built into smart glasses. Respond in a friendly tone and limit your answers to 1-2 sentences."},
{"role": "user", "content": prompt}
]
)
return response.choices[0].message.content.strip()
def speak(text):
subprocess.call(f'echo "{text}" | festival --tts', shell=True)
CONFIDENCE_THRESHOLD = 0.6 # at what confidence level do we say we detected a thing
PERSISTANCE_THRESHOLD = 0.25 # what percentage of the time we have to have seen a thing
def dont_quit(signal, frame):
print('Caught signal: {}'.format(signal))
signal.signal(signal.SIGHUP, dont_quit)
def get_color_name(r, g, b):
hsv = cv2.cvtColor(np.uint8([[[b, g, r]]]), cv2.COLOR_BGR2HSV)[0][0]
h, s, v = hsv
if v < 50:
return "black"
elif s < 50 and v > 200:
return "white"
elif s < 50:
return "gray"
elif h < 10 or h >= 170:
return "red"
elif 10 <= h < 25:
return "orange"
elif 25 <= h < 35:
return "yellow"
elif 35 <= h < 85:
return "green"
elif 85 <= h < 125:
return "cyan"
elif 125 <= h < 150:
return "blue"
elif 150 <= h < 170:
return "magenta"
else:
return "unknown color"
# App
from rpi_vision.agent.capturev2 import PiCameraStream
from rpi_vision.models.mobilenet_v2 import MobileNetV2Base
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)
# Suppress INFO-level logs from mobilenet_v2, tensorflow, and picamera2 modules
logging.getLogger("rpi_vision.models.mobilenet_v2").setLevel(logging.WARNING)
logging.getLogger("tensorflow").setLevel(logging.ERROR)
logging.getLogger("picamera2.picamera2").setLevel(logging.WARNING)
last_snapshot_time = {}
SNAPSHOT_COOLDOWN = 10 # seconds
# initialize the display
pygame.init()
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
capture_manager = None
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('--include-top', type=bool,
dest='include_top', default=True,
help='Include fully-connected layer at the top of the network.')
parser.add_argument('--tflite',
dest='tflite', action='store_true', default=False,
help='Convert base model to TFLite FlatBuffer, then load model into TFLite Python Interpreter')
parser.add_argument('--rotation', type=int, choices=[0, 90, 180, 270],
dest='rotation', action='store', default=0,
help='Rotate everything on the display by this amount')
parser.add_argument('--voice', action='store_true', help='Enable voice assistant')
args = parser.parse_args()
return args
last_seen = [None] * 10
last_spoken = None
def main(args):
global last_spoken, capture_manager, voice_cmd, vosk_model, vosk_recognizer
if args.voice:
from vosk import Model, KaldiRecognizer
vosk_model = Model("/home/purple/rpi-vision/tests/model")
vosk_recognizer = KaldiRecognizer(vosk_model, 16000)
threading.Thread(target=listen_loop, daemon=True).start()
capture_manager = PiCameraStream(preview=False)
if args.rotation in (0, 180):
buffer = pygame.Surface((screen.get_width(), screen.get_height()))
else:
buffer = pygame.Surface((screen.get_height(), screen.get_width()))
pygame.mouse.set_visible(False)
screen.fill((0,0,0))
try:
splash = pygame.image.load(os.path.dirname(sys.argv[0])+'/bchatsplash.bmp')
splash = pygame.transform.rotate(splash, args.rotation)
# Scale the square image up to the smaller of the width or height
splash = pygame.transform.scale(splash, (min(screen.get_width(), screen.get_height()), min(screen.get_width(), screen.get_height())))
# Center the image
screen.blit(splash, ((screen.get_width() - splash.get_width()) // 2, (screen.get_height() - splash.get_height()) // 2))
except pygame.error:
pass
pygame.display.update()
scale = max(buffer.get_height() // capture_manager.resolution[1], 1)
scaled_resolution = tuple([x * scale for x in capture_manager.resolution])
smallfont = pygame.font.Font(None, 24 * scale)
medfont = pygame.font.Font(None, 36 * scale)
bigfont = pygame.font.Font(None, 48 * scale)
model = MobileNetV2Base(include_top=args.include_top)
capture_manager.start()
while not capture_manager.stopped:
if capture_manager.frame is None:
continue
buffer.fill((0,0,0))
frame = capture_manager.read()
# Handle AI assistant voice commands with state transitions
global assistant_active
with voice_lock:
cmd = voice_cmd
voice_cmd = None
if args.voice and cmd:
if cmd == "wake":
assistant_active = True
print("Voice assistant activated. Listening for command...")
speak("I'm listening.")
continue
if cmd == "take_picture":
timestamp_str = time.strftime("%Y%m%d-%H%M%S")
filename = f"voice_capture_{timestamp_str}.jpg"
save_dir = "snapshots"
os.makedirs(save_dir, exist_ok=True)
save_path = os.path.join(save_dir, filename)
cv2.imwrite(save_path, cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
print(f"[Voice snapshot saved]: {save_path}")
speak("Picture taken.")
continue
elif assistant_active:
print(f"Voice command: {cmd}")
reply = get_chatgpt_response(cmd)
print(f"Assistant: {reply}")
speak(reply)
assistant_active = False
continue
# Skip object detection and color analysis if assistant is active
if assistant_active:
# Skip object detection while assistant is active
continue
# Always show the center color
h, w, _ = frame.shape
cx, cy = w // 2, h // 2
crop_size = 35
x1, x2 = max(0, cx - crop_size), min(w, cx + crop_size)
y1, y2 = max(0, cy - crop_size), min(h, cy + crop_size)
roi = frame[y1:y2, x1:x2]
roi = cv2.cvtColor(roi, cv2.COLOR_RGB2BGR)
hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
lower_skin = np.array([0, 48, 80], dtype=np.uint8)
upper_skin = np.array([20, 255, 255], dtype=np.uint8)
skin_mask = cv2.inRange(hsv, lower_skin, upper_skin)
pixels = roi.reshape(-1, 3)
non_skin = pixels[skin_mask.reshape(-1) == 0]
if non_skin.size == 0:
non_skin = pixels # fallback
filtered = non_skin[np.all(non_skin < 200, axis=1)]
if filtered.size == 0:
filtered = non_skin
average_color = np.mean(filtered, axis=0)
b, g, r = average_color.astype(int)
# get the raw data frame & swap red & blue channels
previewframe = np.ascontiguousarray(capture_manager.frame)
# make it an image
img = pygame.image.frombuffer(previewframe, capture_manager.resolution, 'RGB')
img = pygame.transform.scale(img, scaled_resolution)
cropped_region = (
(img.get_width() - buffer.get_width()) // 2,
(img.get_height() - buffer.get_height()) // 2,
buffer.get_width(),
buffer.get_height()
)
# draw it!
buffer.blit(img, (0, 0), cropped_region)
# Draw RGB color box and text overlay after video frame
color_box = pygame.Surface((50, 50))
color_box.fill((r, g, b)) # Note: pygame uses RGB order
buffer.blit(color_box, (10, buffer.get_height() - 60))
color_name = get_color_name(r, g, b)
rgb_text = f"RGB: ({r}, {g}, {b}) - {color_name}"
rgb_surface = smallfont.render(rgb_text, True, (255, 255, 255))
buffer.blit(rgb_surface, (70, buffer.get_height() - 50))
timestamp = time.monotonic()
if args.tflite:
prediction = model.tflite_predict(frame)[0]
else:
prediction = model.predict(frame)[0]
delta = time.monotonic() - timestamp
# add FPS & temp on top corner of image
fpstext = "%0.1f FPS" % (1/delta,)
fpstext_surface = smallfont.render(fpstext, True, (255, 0, 0))
fpstext_position = (buffer.get_width()-10, 10) # near the top right corner
buffer.blit(fpstext_surface, fpstext_surface.get_rect(topright=fpstext_position))
try:
temp = int(open("/sys/class/thermal/thermal_zone0/temp").read()) / 1000
temptext = "%d\N{DEGREE SIGN}C" % temp
temptext_surface = smallfont.render(temptext, True, (255, 0, 0))
temptext_position = (buffer.get_width()-10, 30) # near the top right corner
buffer.blit(temptext_surface, temptext_surface.get_rect(topright=temptext_position))
except OSError:
pass
for p in prediction:
label, name, conf = p
if conf > CONFIDENCE_THRESHOLD:
print("Detected", name)
persistant_obj = False # assume the object is not persistant
last_seen.append(name)
last_seen.pop(0)
inferred_times = last_seen.count(name)
if inferred_times / len(last_seen) > PERSISTANCE_THRESHOLD: # over quarter time
persistant_obj = True
detecttext = name.replace("_", " ")
detecttextfont = None
for f in (bigfont, medfont, smallfont):
detectsize = f.size(detecttext)
if detectsize[0] < screen.get_width(): # it'll fit!
detecttextfont = f
break
else:
detecttextfont = smallfont # well, we'll do our best
detecttext_color = (0, 255, 0) if persistant_obj else (255, 255, 255)
if persistant_obj:
now = time.monotonic()
last_time = last_snapshot_time.get(detecttext, 0)
if now - last_time > SNAPSHOT_COOLDOWN:
timestamp_str = time.strftime("%Y%m%d-%H%M%S")
filename = f"{detecttext}_{timestamp_str}.jpg"
save_dir = "snapshots"
os.makedirs(save_dir, exist_ok=True)
save_path = os.path.join(save_dir, filename)
cv2.imwrite(save_path, cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
print(f"[Snapshot saved]: {save_path}")
last_snapshot_time[detecttext] = now
# else:
# print(f"[Skipped snapshot] {detecttext} was saved less than {SNAPSHOT_COOLDOWN} seconds ago.")
h, w, _ = frame.shape
cx, cy = w // 2, h // 2
crop_size = 35
x1, x2 = max(0, cx - crop_size), min(w, cx + crop_size)
y1, y2 = max(0, cy - crop_size), min(h, cy + crop_size)
buffer_h, buffer_w = buffer.get_height(), buffer.get_width()
frame_h, frame_w = frame.shape[:2]
scale_x = buffer_w / frame_w
scale_y = buffer_h / frame_h
rx1 = int(x1 * scale_x)
ry1 = int(y1 * scale_y)
rw = int((x2 - x1) * scale_x)
rh = int((y2 - y1) * scale_y)
pygame.draw.rect(buffer, (255, 255, 255), (rx1, ry1, rw, rh), 2)
roi = frame[y1:y2, x1:x2]
roi = cv2.cvtColor(roi, cv2.COLOR_RGB2BGR)
hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
lower_skin = np.array([0, 48, 80], dtype=np.uint8)
upper_skin = np.array([20, 255, 255], dtype=np.uint8)
skin_mask = cv2.inRange(hsv, lower_skin, upper_skin)
pixels = roi.reshape(-1, 3)
non_skin = pixels[skin_mask.reshape(-1) == 0]
if non_skin.size == 0:
non_skin = pixels # fallback
filtered = non_skin[np.all(non_skin < 200, axis=1)]
if filtered.size == 0:
filtered = non_skin
# 5) Compute average color
average_color = np.mean(filtered, axis=0)
b, g, r = average_color.astype(int)
# Use median instead of average
color_name = get_color_name(r, g, b)
#print(f"Average color (RGB): ({r}, {g}, {b}) - {color_name}")
# Add a rectangle showing detected color in bottom-left corner
color_box = pygame.Surface((50, 50))
color_box.fill((r, g, b)) # Note: pygame uses RGB order
buffer.blit(color_box, (10, buffer.get_height() - 60))
if persistant_obj:
color_name = get_color_name(r, g, b)
label_text = f"{detecttext} - {color_name}"
else:
label_text = detecttext
detecttext_surface = detecttextfont.render(label_text, True, detecttext_color)
detecttext_position = (buffer.get_width()//2,
buffer.get_height() - detecttextfont.size(label_text)[1])
buffer.blit(detecttext_surface, detecttext_surface.get_rect(center=detecttext_position))
if persistant_obj and last_spoken != detecttext:
color_name = get_color_name(r, g, b)
spoken_text = f"That is a {color_name} {detecttext} "
subprocess.call(f"echo \"{spoken_text}\" | festival --tts &", shell=True)
last_spoken = detecttext
break
else:
last_seen.append(None)
last_seen.pop(0)
if last_seen.count(None) == len(last_seen):
last_spoken = None
screen.blit(pygame.transform.rotate(buffer, args.rotation), (0,0))
pygame.display.update()
if __name__ == "__main__":
args = parse_args()
try:
main(args)
except KeyboardInterrupt:
capture_manager.stop()
Bill of Materials
Part | Note | Price | Link |
---|---|---|---|
Power Bank | Powers the Raspberry Pi | $17.99 | Link |
Respberry Pi 4 | Runs the camera module and object recognition | $55.00 | Link |
Earbuds | Allows user to hear TTS feedback of an object | $14.01 | Link |
Raspberry Pi Camera Module | Lets the Raspberry Pi see for object recognition | $6.99 | Link |
Glasses | Base which the Raspberry Pi and camera is going to be mounted on | $6.99 | Link |
Raspberry Pi Camera Flex Cable | Longer cable that connects the camera to the Raspberry Pi | $2.95 | Link |
Microphone | Allows the user to talk to the AI assistant | $22.99 | Link |
Other Resources
- https://learn.adafruit.com/running-tensorflow-lite-on-the-raspberry-pi-4/tensorflow-2-setup
Retro Arcade Console
Summary
The Retro Arcade Console is my starter project and has many games ranging from tetris to slots. There are 5 games in total. While playing the games on the console, different sound effects play that matches up to the game. I can use 7 buttons-up, down, left, right, pause, start, and on/off-to control the console. My favorite game is space invaders, because I can shoot beams of lasers with cool sound effects. To play tetris, you can use the left and right buttons to control the orientation, and the down button to make the block go down faster. The LED display shows the game and the display board counts the score for each game. To build the Retro Arcade Console, I had to solder many parts to the PCB.
Challenges
Some challenges I faced were soldering and a bug in the console. Soldering was difficult for me and sometimes I would get a cold joint. The joint would be flaky and not concave. After practicing many joints on the console, I was able to solder with good joints. Another challenge I faced was a bug in the console. When I fully assembled my game console, the button’s controls were flipped, so when I would start it would pause, and if I would pause it would start. I thought this was a soldering error, so I unassembled everything to resolder my joints. Even after that, it wasn’t fixed and I realized the code was wrong in the board. This would explain why only on some games the pause button would work, but on others it wouldn’t do anything. Because I took apart my console many times trying to fix this, it took away a lot of time and was one of my biggest challenges.
Bill of Materials
Part | Quantity |
---|---|
Buzzer | x1 |
Electric Capacitor | x1 |
Digitron Display | x1 |
Self-Switch | x1 |
Button | x6 |
PCB | x1 |
LED dot matrix module | x2 |
Battery Case | x1 |
Schematics/Images