Simon Says Game
A Python-based Simon Says memory game that uses an SMD Red gateway with the RGB LED Module and Buzzer Module for visual and audio feedback. The game presents an ever-growing sequence of colors that the player must repeat correctly to advance to the next round.
About Tools and Materials:
SMD USB Gateway (Purchase Here)
Arduino Gateway Module (Purchase Here)
RGB LED Module (Purchase Here)
Step 1: Hardware and Software Overview
SMD Red The SMD acts as a bridge between the script and the modules. It is responsible for interpreting the commands the script sends and translating them into actions that actuate the RGB LED Module and the Buzzer Module.
RGB LED Module Depending on the game sequence, this module lights up in Red, Green, or Blue. It helps the player visually memorize the pattern.
Buzzer Module Emits a short beep along with the LED flash for audio feedback. This pairing enhances the userβs memory and reaction.
SMD Libraries The official Acrome SMD Python library handles low-level serial communication, device scanning, and module control, letting you focus on the Simon Says logic and GUI.
Project Key Features
Visual + Audible Feedback
Each color is accompanied by a synchronized flash and beep.
Growing Memory Challenge
The sequence grows with each successful round, increasing difficulty.
Tkinter Graphical Interface
Simple UI with buttons for Red, Green, and Blue, a start button, and a status message.
Built-in Hardware Warm-Up
The RGB LED is initialized once before gameplay to bypass any first-flash issues.
Step 2: Assemble
Getting Started
Hardware Setup
Connect the SMD to the PC or Arduino board using the USB Gateway Module or the Arduino Gateway Module.
Connect the RGB LED Module and the Buzzer Module to the SMD using an RJ-45 cable.
Make sure that the SMD is powered and all connections are correct.
Project Wiring Diagram
Step 3: Run & Test
Install Libraries and Run the Script
Install necessary libraries such as Tkinter, serial, and acrome-smd.
Execute the script, initiating the Simon Says project and opening the Tkinter UI where you can enter your text.
Play the Simon Says Game
Click Start to begin.
Watch the color sequence.
Repeat the sequence using the buttons.
If correct, the game adds one more color and continues.
If wrong, the game ends and can be restarted.
Codes:
import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
import time
import random
import tkinter as tk
from tkinter import ttk, messagebox
from serial.tools.list_ports import comports
from platform import system
from smd.red import Master, Red
# βββ Hardware Layer βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def find_usb_port():
ports = list(comports())
os_name = system()
usb_names = {
"Windows": ["USB Serial Port"],
"Linux": ["/dev/ttyUSB"],
"Darwin": ["/dev/tty.usbserial", "/dev/tty.usbmodem", "/dev/cu.usbserial"]
}
for port, desc, hwid in sorted(ports):
if any(name in port or name in desc for name in usb_names.get(os_name, [])):
return port
return None
class Device:
def __init__(self, port, baud=115200, smd_id=0, led_id=5, buzzer_id=5):
self.master = Master(port, baud)
self.master.attach(Red(smd_id))
self.master.scan_modules(smd_id)
self.smd_id = smd_id
self.led_id = led_id
self.buzzer_id = buzzer_id
def led_color(self, r, g, b):
self.master.set_rgb(self.smd_id, self.led_id, r, g, b)
def led_off(self):
self.led_color(0, 0, 0)
def beep(self, duration=0.2):
ms = int(duration * 1000)
self.master.set_buzzer(self.smd_id, self.buzzer_id, ms)
time.sleep(duration)
self.master.set_buzzer(self.smd_id, self.buzzer_id, 0)
def close(self):
ser = getattr(self.master, 'serial', None)
if ser and hasattr(ser, 'close'):
ser.close()
# βββ Simon Says GUI ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
COLORS = [
("Red", (255, 0, 0)),
("Green", (0, 255, 0)),
("Blue", (0, 0, 255))
]
class SimonSaysApp(tk.Tk):
def __init__(self, device):
super().__init__()
self.title("Simon Says Game")
self.resizable(False, False)
self.device = device
self.sequence = []
self.user_index = 0
self.device.led_color(*COLORS[0][1])
self.device.beep(0.8)
self.device.led_off()
time.sleep(1.0)
self._build_ui()
def _build_ui(self):
btn_frame = ttk.Frame(self)
btn_frame.pack(pady=10)
self.buttons = []
for i, (name, color) in enumerate(COLORS):
hexc = "#%02x%02x%02x" % color
btn = tk.Button(btn_frame, text=name, bg=hexc, width=8,
command=lambda i=i: self._user_press(i))
btn.grid(row=0, column=i, padx=5)
self.buttons.append((btn, color))
control = ttk.Frame(self)
control.pack(pady=5)
self.status = ttk.Label(self, text="Press Start to play")
self.status.pack(pady=(0,5))
self.start_btn = ttk.Button(control, text="Start", command=self._start_game)
self.start_btn.pack()
def _start_game(self):
self.sequence.clear()
self._next_round()
def _next_round(self):
self.start_btn.config(state="disabled")
self.user_index = 0
self.sequence.append(random.randrange(len(COLORS)))
self.status.config(text=f"Round {len(self.sequence)} β watch...")
# schedule playback on main thread
self.after(500, self._play_sequence, 0)
def _play_sequence(self, idx):
if idx < len(self.sequence):
color_idx = self.sequence[idx]
self._flash(color_idx)
# schedule next flash
self.after(700, self._play_sequence, idx+1)
else:
self.status.config(text="Your turn")
def _flash(self, idx):
_, color = self.buttons[idx]
self.device.led_color(*color)
self.device.beep(0.2)
# turn off after short delay
self.after(200, self.device.led_off)
def _user_press(self, idx):
if not self.sequence:
return
self._flash(idx)
if idx == self.sequence[self.user_index]:
self.user_index += 1
if self.user_index == len(self.sequence):
# correct full sequence
self.status.config(text="Correct! Next round...")
self.after(500, self._next_round)
else:
self.status.config(text="Wrong! Game Over")
self.start_btn.config(state="enabled")
self.sequence.clear()
# βββ Main βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
if __name__ == '__main__':
port = find_usb_port()
if not port:
print("No USB gateway detected.")
sys.exit(1)
device = Device(port)
app = SimonSaysApp(device)
app.protocol("WM_DELETE_WINDOW", lambda: (device.close(), app.destroy()))
app.mainloop()
Last updated