# Revinyl

## Walkthrough of the code

``````#!/usr/bin/python

import atexit
import signal
import RPi.GPIO as GPIO
import time

# Activate GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(True)

# Variables
steps = 1500 # Steps per sequence - keep this high for perfect speed control, and low for immediate control over speed from the toggler
staging = 100 # How many steps do we need to accelerate the stepper motor?
delay = 0 # Current delay
previous = 0.01 # This just makes sure we're staging the stepper motor
microsteps = 1 # How many micro-steps per step should we take?
current = 0 # Store our current
offset = 0 # Store the offset in time between what we're trying to achieve and what we actually achieved according to the Pi-clock. Paramount for perfect timing!
speed = 0 # What speed are we at?
death = 0 # At what time should we die?
speed_1 = 33.3 # First level speed
speed_2 = 45 # Second level speed
time_1 = 22 # How many minutes are in an LP?
time_2 = 15 # How many minutes are in a Single?
status = False # Record player status

# GPIO pins we're using
enable_a = 21 # Stepper driver enable pins
enable_b = 13
a1 = 20 # Stepper driver pins, for each coil
a2 = 16
b1 = 26
b2 = 19
toggle_speed_1 = 17 # Toggle button pins
toggle_speed_2 = 27

# Set pin states
GPIO.setup(enable_a, GPIO.OUT) # Make stepper pins output pins!
GPIO.setup(enable_b, GPIO.OUT)
GPIO.setup(a1, GPIO.OUT)
GPIO.setup(a2, GPIO.OUT)
GPIO.setup(b1, GPIO.OUT)
GPIO.setup(b2, GPIO.OUT)
GPIO.setup(toggle_speed_1, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Make ground detected, so the pin isn't floating
GPIO.setup(toggle_speed_2, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Function for step sequence
# Get how many steps we're taking per step
calc = int(microsteps*step)

# If less than two, one step is just a step. Take that step, and then sleep
if calc<2:
GPIO.output(pin, state)
time.sleep(delay)

# Otherwise, we'll go ahead and bit-bang a micro-stepping sequence
else:
# What's the delay we need per step?
microdelay = float(delay)/float(calc)

# Go through each microstep
for a in range(0, calc):
# How far into the stepping sequence are we?
percentage = float(a)/float(calc)

# Unset the pin
GPIO.output(pin, not state)

# Sleep a bit
time.sleep(float(microdelay)*(1-percentage))

# Set the pin
GPIO.output(pin, state)

# Sleep a bit more
time.sleep(float(microdelay)*(percentage))

# Handle abortions safely, if this program fails, we don't want the stepper motor to keep drawing current
def abort():
GPIO.output(enable_a, False)
GPIO.output(enable_b, False)

atexit.register(abort)
signal.signal(signal.SIGTSTP, abort)

# Loop through step sequence based on number of steps
while True:
# Store current time
io_timer = time.clock()
death_timer = time.time()

# Check toggle state. If it's on, reset all variables
if (GPIO.input(toggle_speed_1) and GPIO.input(toggle_speed_2)) or not (GPIO.input(toggle_speed_1) or GPIO.input(toggle_speed_2)):
status = False
death = 0
previous = 0.01
offset = 0
speed = 0
delay = 0

# Otherwise, pins are on
else:
# If we're running at lower speed
if GPIO.input(toggle_speed_1):
# We've changed speed since last time!
if speed != speed_1:
speed = speed_1

# Set a death timer, for when the record is finished
death = (time_1*60)+death_timer

# Otherwise, we're running at the higher speed
else:
# We've changed speed since last time
if speed != speed_2:
speed = speed_2

# Set a death timer, for when the record is finished
death = (time_2*60)+death_timer

# If we're still allowed to run, record isn't finished
if death_timer < death:
# Define current time, and activate runner
current = 1/float((30.0/7.0)*200*2/60.0*float(speed))

# Set the record to running!
status = True

# Do we have a sample time?
if offset:
# What's the error (i.e. how slow is the Pi compared to our wished benchmark?
error = offset/float(steps)/4.0

# If it's obscenely high, we need to set it to a reasonable level. The Pi still needs its sleep
if current<error:
current = 0.00010

#Otherwise, it's all good! Adjust accordingly
else:
current -= error

# Otherwise, let's deactivate motor. The record is finished!
else:
status = False

# If we've got green light, run
if(status):
# Enable the stepper motor!
GPIO.output(enable_a, True)
GPIO.output(enable_b, True)

# Go through motor in X steps
for i in range(0, steps):
# If we're not up to speed, stage the speed
if delay != current:
if i<staging:
delay = current
delay -= ((current-previous)/(staging))*(staging-i)
else:
delay = current

# Move to step