Skip to content

Instantly share code, notes, and snippets.

@jburgess777
Created September 16, 2016 22:11
Show Gist options
  • Save jburgess777/8c39781f55fe64a6e938a37ec3a01f50 to your computer and use it in GitHub Desktop.
Save jburgess777/8c39781f55fe64a6e938a37ec3a01f50 to your computer and use it in GitHub Desktop.
Tilda SNES controller
import pyb
# SNES Connector pinout:
#
# -----------------
# | 1 2 3 4 | 5 6 7 >
# -----------------
#
# 1 +5V - Connect to vBAT
# 2 Clock } Connect to any unused data pin and specify
# 3 Latch } when creating the SNESpad object
# 4 Data }
# 5 unused
# 6 unused
# 7 Ground - Connect to 0v
SNES_B=1<<0
SNES_Y=1<<1
SNES_SELECT=1<<2
SNES_START=1<<3
SNES_UP=1<<4
SNES_DOWN=1<<5
SNES_LEFT=1<<6
SNES_RIGHT=1<<7
SNES_A=1<<8
SNES_X=1<<9
SNES_L=1<<10
SNES_R=1<<11
class SNESpad:
"""Read buttons from SNES game controllers
For a single controller the latch, clock and data pins must be specified.
When using multiple controllers there is one data pin per controller
specified in a list. The latch and clock pins are shared.
Usage:
c = SNESpad(latch="X8", clock="X7", data=["X1", "X2", "X3", "X9"])
print("Press some buttons on the controller")
last=None
while True:
state = c.read()
for i in range(len(state)):
if last is None or state[i] != last[i]:
pressed = c.buttons(state[i])
print("Controller %d buttons: %s" % (i+1, pressed))
last=list(state)
"""
def __init__(self, latch, clock, data):
self.pin_latch = pyb.Pin(latch, pyb.Pin.OUT_PP)
self.pin_clock = pyb.Pin(clock, pyb.Pin.OUT_PP)
self.pin_data = []
if type(data) is str:
data = [ data ]
for p in data:
self.pin_data.append(pyb.Pin(p, pyb.Pin.IN))
self.data_count = len(self.pin_data)
def read(self):
# Latch current button state into buffer
self.pin_latch.high()
self.pin_latch.low()
# Clear initial state for all data pins
state = []
for i in range(self.data_count):
state.append(0)
# Read 12 bits of button data
for i in range(12):
# Read button bit for each controller
# Buttons are active low
for j in range(self.data_count):
if not self.pin_data[j].value():
state[j] |= 1 << i
# Clock in next button bit from buffer
self.pin_clock.high()
self.pin_clock.low()
return state
def buttons(self, state):
# Decode the bitmap into a list of buttons
pressed=[]
if (state & SNES_A):
pressed.append("A")
if (state & SNES_B):
pressed.append("B")
if (state & SNES_X):
pressed.append("X")
if (state & SNES_Y):
pressed.append("Y")
if (state & SNES_L):
pressed.append("L")
if (state & SNES_R):
pressed.append("R")
if (state & SNES_SELECT):
pressed.append("SELECT")
if (state & SNES_START):
pressed.append("START")
if (state & SNES_UP):
pressed.append("UP")
if (state & SNES_DOWN):
pressed.append("DOWN")
if (state & SNES_LEFT):
pressed.append("LEFT")
if (state & SNES_RIGHT):
pressed.append("RIGHT")
return pressed
if __name__ == '__main__':
c = SNESpad(latch="X8", clock="X7", data="X9")
print("Press some buttons on the controller")
last=None
while True:
state = c.read()
for i in range(len(state)):
if last is None or state[i] != last[i]:
pressed = c.buttons(state[i])
print("Controller %d buttons: %s" % (i+1, pressed))
last=list(state)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment