Skip to the content.

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

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