Gone Fishin'- a Simple Fishing Game

by carbonmk in Circuits > Raspberry Pi

129 Views, 1 Favorites, 0 Comments

Gone Fishin'- a Simple Fishing Game

IMG_9894.jpeg
IMG_9898.jpeg
Gone Fishin': A simple raspberry pi game

This build is a simple fishing game powered by a Raspberry Pi Pico W that uses a proximity sensor and a continuous servo to play the game. It is connected to Adafruit IO, so it can easily be controlled from your computer. A user first presses the "Cast" button which spins the servo, releasing some slack so the fishing line can drop toward the proximity sensor. When the hook gets close enough, you will hear a bubbling noise, and at that point click on the "Reel" button. This means you have caught a fish, and will hear Mikey the Angler tell you what fish you just caught. Depending on the temperature of the room, the kind of fish you can potentially catch also changes!

Supplies

Electronics:

Pico W

Speaker

Adafruit APDS9960- proximity sensor

Adafruit mcp9808- temperature sensor

A continuous servo motor

A speaker that has an audio plug

2 Alligator to pin clips

9 Pin wires

Stemma QT plug with pins on the end

Stemma QT to Stemma QT wire

An Adafruit microSD SPI reader (pins already soldered on).

An SD card (32 gigabytes or less)

A USB cable (to power the microcontroller)

1 Battery pack

Other materials:

Wooden Box to hold our components

Some sort of tank on the top (here I used laser cut acrylic and glued them together)

A miniature fishing rod

Some sort of strong string like a fishing wire

SD Card reader for your computer

Additional ocean themed decorations of your choice (optional)

Some sort of weight that can be attached to your fishing wire

A spool to help wind and unwind the string.

Wire the Pico W and Speaker

IMG_9805.jpeg

1-    Take one of the alligator to pin clips and connect the pin to any ground on the Pico.

2-    Connect the alligator clip to the base of the audio jack cable. 

3-    Take the other alligator to pin clips and connect the pin to GP16 (or your preferred pin) on the Pico. 

4-    Connect the alligator clip to the tip of the audio jack cable.

5-    If applicable, make sure to turn on the speaker.

The speaker will play the audio files which are needed for the game and tells you what fish you caught.

Wire the Pico W and Adafruit SD Card Reader

IMG_9809.jpeg
IMG_9808.jpeg

1-    Using the SD card reader for your computer, make a new folder on the SD card and load any sounds you want into that folder. Make sure to remember the name of the folder as this will be the path for your sounds in the code.

2-    If applicable, make sure to solder the pins onto your Adafruit SD card reader.

3-    Take a pin-to-pin wire and connect it to 3.3 Volts on the Pico W and the 3V slot on the SD Card reader.

4-    Using another pin-to-pin wire, connect it to any ground on the Pico W and the ground slot on the SD card reader.

5-    Connect a pin-to-pin wire to GP10, which is SCK, to CLK slot on the SD Card reader.

6-    Connect a pin-to-pin wire to GP11, which is SI or TX, to the “DO SO” slot on the SD card reader.

7-    Connect a pin-to-pin wire to GP12, which is SO or RX, to the “CMD SI” slot on the SD card reader.

8-    Connect a pin-to-pin wire to GP13, which is CS, to the “DE CS” slot on the SD card reader.

9-    Finally, insert the SD card into the slot, you will hear a click when the SD Card is properly inserted. 

Wire the Pico W, Mcp9808, and APDS9960

1- Plug the Stemma QT side of the Stemma QT-to-pins wire into the mcp9808.

2- The yellow wire is SCL which is connected to GP5 on the Pico.

3- The blue wire is SDA and is connected to GP4 on the Pico.

4- The red wire is power which is connected to 3.3 Volts out, not VBUS!

5- The black wire is ground which is connected to any ground on the Pico W.

6- Now that the Stemma QT is connected to the Pico, using the Stemma QT-to-Stemma QT wire, connect the mcp9808 and APDS9960

Wire the Pico W and Servo

IMG_9893.jpeg

1- Connect a pin-to-pin wire to the red wire on the servo then connect that to VBUS.

2- Connect a pin-to-pin wire to the brown wire on the servo then connect that to any ground

3- Connect a pin-to-pin wire to the orange wire on the servo then connect that to GP15 (or any other signal pin you wish)

The finished wiring should like something the image shows.

Assembling the Box and Tank

IMG_9897.jpeg

There is no specific way how to do this, just make sure the bottom of your tank has a hole that the APDS9960 can be able to read proximity from. Make sure this hole is the same size as the one in the top of your box so you can line them up, then APDS9960 can be taped to face out of both holes.

Code

I have pasted the code and also attached a file for convenience:


import time, board, digitalio, pwmio, adafruit_mcp9808, random, os, ssl, socketpool, wifi, mount_sd

from adafruit_motor import servo

import adafruit_minimqtt.adafruit_minimqtt as MQTT

from adafruit_apds9960.apds9960 import APDS9960

from audiopwmio import PWMAudioOut as AudioOut

from audiomp3 import MP3Decoder


# Configure the servo

servo_pin = board.GP15

pwm = pwmio.PWMOut(servo_pin, frequency=50)

my_servo = servo.ContinuousServo(pwm)


# Configure the prox sensor

i2c = board.STEMMA_I2C()

multi_sensor = APDS9960(i2c)

multi_sensor.enable_proximity = True


# Configure the temp sensor

temp_sensor = adafruit_mcp9808.MCP9808(i2c)


# Confgigure the speaker:

audio = AudioOut(board.GP16) # assuming tip of Audio pin to GP16

path = "/sd/fish_sounds/"

sound_playing = False


# set up the mp3 decoder

filename = "boat.mp3"

mp3_file = open(path + filename, "rb")

decoder = MP3Decoder(mp3_file)


# function to play an mp3 file

def play_mp3(filename):

  global sound_playing

  try:

    decoder.file = open(path + filename, "rb")

    audio.play(decoder)

    sound_playing = True

  except OSError as e:

    if e.errno != 2: # If the error is not related to the file not being found, print it

      print(f"Error: {e}")


# Temperature is returned in degrees celsius. Formula for conversion to degrees fahrenheit also shown below:

tempC = temp_sensor.temperature

tempF = tempC * 9 / 5 + 32


def move_servo(throttle):

  my_servo.throttle = throttle


# variables

is_reeling = False

last_button_press_time = 0


warm = 72

warm_fish = ["Mahi-Mahi", "Tuna", "Marlin", "Sailfish", "Barracuda"]

cool_fish = ["Salmon", "Trout", "Cod", "Mackerel", "Tilapia"]


def get_random_fish(tempF, warm, warm_fish, cool_fish):

  if tempF >= warm:

    return random.choice(warm_fish)

  elif tempF < warm:

    return random.choice(cool_fish)

  else:

    return None


caught_fish = None

bubbling_start_time = None

caught_fish_during_bubbling = False


def is_proximity_minimal():

  proximity_value = multi_sensor.proximity

  print(f"Proximity value: {proximity_value}") # Debug print for distance sensor

  minimal_distance_threshold = 230 # You can change this value based on your requirements

  minimal_proximity = proximity_value >= minimal_distance_threshold


  if minimal_proximity:

    play_mp3("bubbling.mp3")

  return minimal_proximity


# Get adafruit io username and key from settings.toml

aio_username = os.getenv('AIO_USERNAME')

aio_key = os.getenv('AIO_KEY')


# Setup a feed: This may have a different name than your Dashboard

fish_feed = aio_username + "/feeds/fish-feed"


# Setup functions to respond to MQTT events

def connected(client, userdata, flags, rc):

  # Connected to broker at adafruit io

  print("Connected to Adafruit IO! Listening for topic changes in feeds I've subscribed to")

  # Subscribe to all changes on the feed.

  client.subscribe(fish_feed)


def disconnected(client, userdata, rc):

  # Disconnected from the broker at adafruit io

  print("Disconnected from Adafruit IO!")


def message(client, topic, message):

  global sound_playing, bubbling_start_time, caught_fish_during_bubbling

  print(f"topic: {topic}, message: {message}")

  if topic == fish_feed:

    if message == "cast":

      move_servo(-1.0)

      time.sleep(3) # Wait for 3 seconds

      move_servo(0) # Stop the servo


      proximity_value = multi_sensor.proximity

      if proximity_value > 230: # Check if the proximity is close

        play_mp3("bubbling.mp3")

        bubbling_start_time = time.monotonic() # Set the bubbling_start_time

        sound_playing = True


    elif message == "reel" and sound_playing:

      move_servo(1.0)

      time.sleep(3) # Wait for 3 seconds

      move_servo(0) # Stop the servo


      if sound_playing and (time.monotonic() - bubbling_start_time) <= 6.43: # Check if the sound is playing and if the reel button was pressed within the sound duration

        tempF = temp_sensor.temperature * 9 / 5 + 32 # Update the temperature value

        caught_fish = get_random_fish(tempF, warm, warm_fish, cool_fish)

        if caught_fish:

          audio.stop()

          print(f"You caught a {caught_fish}!")

          play_mp3(f"{caught_fish}.mp3")

        else:

          print("No fish caught this time. Keep trying!")

        sound_playing = False # Reset the sound_playing variable

        bubbling_start_time = None


    elif message == "0":

      move_servo(0)


# Connect to WiFi

# Connect to wifi

print("Connecting to wifi")

wifi.radio.connect(os.getenv("WIFI_SSD"), os.getenv("WIFI_PASSWORD"))

print("COnnected")


# Create a socket pool

pool = socketpool.SocketPool(wifi.radio)


# Set up a MiniMQTT Client - this is our current program that subscribes or "listens")

mqtt_client = MQTT.MQTT(

  broker=os.getenv("BROKER"),

  port=os.getenv("PORT"),

  username=aio_username,

  password=aio_key,

  socket_pool=pool,

  ssl_context=ssl.create_default_context(),

)


# Setup the "callback" mqtt methods above

mqtt_client.on_connect = connected

mqtt_client.on_disconnect = disconnected

mqtt_client.on_message = message


broker=os.getenv("BROKER")

port=os.getenv("PORT")

username=aio_username

password=aio_key

socket_pool=pool

ssl_context=ssl.create_default_context()

print(f"{aio_username}, {aio_key}, {pool}, {port}, {broker}")


# Setup the "callback" mqtt methods above

mqtt_client.on_connect = connected

mqtt_client.on_disconnect = disconnected

mqtt_client.on_message = message


# Connect to the MQTT broker (adafruit io for us)

print("Connecting to Adafruit IO...")

mqtt_client.connect()


while True:

  mqtt_client.loop()