Search code examples
pythonraspberry-pigpio

Raspberry Pi game crashes out when button is pressed


I have this Python program which I'm running on Raspberry Pi:

import RPi.GPIO as GPIO
import time
from random import randint

# Setup GPIO pins
# Set the BCM mode
GPIO.setmode(GPIO.BCM)

# Outputs
GPIO.setup(4, GPIO.OUT)
GPIO.setup(17, GPIO.OUT)
GPIO.setup(27, GPIO.OUT)

# Ensure all LED's are off
GPIO.output(4, GPIO.LOW)
GPIO.output(17, GPIO.LOW)
GPIO.output(27, GPIO.LOW)

# Inputs
GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

global player
player = 0

# Setup the callback functions
def rock(channel):
    global player
    player = 1 # magic number 1 = rock, pin 12

def paper(channel):
    global player
    player = 2 # magic number 2 = paper, pin 16

def scissors(channel):
      global player
      player = 3 # magic number 3 = scissors, pin 21

def quit_game(channel):
    GPIO.cleanup()
    exit() # pin 20, immediate exit of game

# Add event detection and callback assignments
GPIO.add_event_detect(12, GPIO.RISING, callback=rock)
GPIO.add_event_detect(16, GPIO.RISING, callback=paper)
GPIO.add_event_detect(21, GPIO.RISING, callback=scissors)
GPIO.add_event_detect(20, GPIO.RISING, callback=quit_game)

# Computer random pick
computer = randint(1, 3)

while True:

    if player == computer:
        # This is a tie condition
        GPIO.output(27, GPIO.HIGH)
        time.sleep(5)
        GPIO.output(27, GPIO.LOW)
        player = 0
    elif player == 1:
        if computer == 2:
            # Player loses, paper covers rock
            GPIO.output(17, GPIO.HIGH)
            print "Player = rock, Computer = paper\n"
            time.sleep(5)
            GPIO.output(17, GPIO.LOW)
            player = 0
        else:
            # Player wins, rock dulls paper
            GPIO.output(4, GPIO.HIGH)
            print "Player = rock, Computer = scissors\n"
            time.sleep(5)
            GPIO.output(4, GPIO.LOW)
            player = 0
    elif player == 2:
        if computer == 3:
            # Player loses, scissors cut paper
            GPIO.output(17, GPIO.HIGH)
            print "Player = paper, Computer = scissors\n"
            time.sleep(5)
            GPIO.output(17, GPIO.LOW)
            player = 0
        else:
            # Player wins, paper covers rock
            GPIO.output(4, GPIO.HIGH)
            print "Player = paper, Computer = rock\n"
            time.sleep(5)
            GPIO.output(4, GPIO.LOW)
            player = 0
    elif player == 3:
        if computer == 1:
            # Player loses, rock dulls scissors
            GPIO.output(17, GPIO.HIGH)
            print "Player = scissors, Computer  = rock\n"
            time.sleep(5)
            GPIO.output(17, GPIO.LOW)
            player = 0
        else:
            # Player wins, scissors cut paper
            GPIO.output(4, GPIO.HIGH)
            print "Player = scissors, Computer = paper\n"
            time.sleep(5)
            GPIO.output(4, GPIO.LOW)
            player = 0

    # Another random pick for the computer
    computer = randint(1, 3)

It is a rock, paper, scissors game which is to be played on a circuit created on a breadboard. I built the circuit based on this diagram:

Diagram of circuit for Rock, Paper, Scissors game

This is an image of the actual circuit I built:

Actual circuit for Rock, Paper, Scissors game

When I run the program on my Raspbery Pi, it starts without issue but if I press a button the program crashes. I can see that the print statement is printed to the console before the application crashes. E.g. Player = rock, Computer = paper. This should happen after the LED switches on but the LED never lights up.

Can anybody suggest possible courses of investigation?

Update

OK, the buttons were supposed to be connected to pins 12, 16, 20 and 21 but were actually connected to GND, 20, 21 and nothing. Once I corrected that the program stopped crashing. The issue still seems to exist though.

I've now added print "Quit game" to my quit function and noticed that it seems to get called no matter which buttin I press:

def quit(channel):
    print "Quit game"
    GPIO.cleanup()
    exit() # pin 20, immediate exit of game

$ python rock_paper_scissors/prs_with_LEDs_and_switches.py 
Player = scissors, Computer = rock
Quit game

Solution

  • There was a problem with my breadboard. When I created the circuit on a new one there was no issue.