Skip to content

Instantly share code, notes, and snippets.

@jepler
Created February 25, 2022 23:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jepler/16cdb13d8c3298c392d789772a56d177 to your computer and use it in GitHub Desktop.
Save jepler/16cdb13d8c3298c392d789772a56d177 to your computer and use it in GitHub Desktop.
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: Copyright (c) 2022 Jeff Epler for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense
# On an Adafruit Feather M4 with Floppy Featherwing, do some track-to-track seeking.
import time
import wait_serial
import digitalio
import board
import array
import adafruit_ticks
import microcontroller
import ulab.numpy as np
import adafruit_pioasm
import rp2pio
PHASE_A = board.A2
PHASE_B = board.D13
PHASE_C = board.D12
PHASE_D = board.D11
ENABLE = board.D6
# stepping FORWARD through phases steps OUT towards SMALLER track numbers
# stepping BACKWARD through phases steps IN towards BIGGER track numbers
phases = [
[1, 0, 0, 0],
[1, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 1, 0],
[0, 0, 1, 1],
[0, 0, 0, 1],
[1, 0, 0, 1],
]
STEP_OUT_QUARTER = -1
STEP_OUT_HALF = -2
STEP_IN_HALF = 2
STEP_IN_QUARTER = 1
class AppleDrivePositioner:
def __init__(self, a, b, c, d):
self._io = [digitalio.DigitalInOut(p) for p in (a, b, c, d)]
for p in self._io:
p.switch_to_output(False)
self._position = None
def home(self):
self._position = 160
self.step(STEP_OUT_HALF, 80)
@property
def track(self):
if self._position & 3 == 0:
return self._position // 4
return self._position / 4
@track.setter
def track(self, new_position):
if new_position is None:
self._position = None
return
if self._position is None:
self.home()
if new_position >= 40 or new_position < 0:
raise ValueError(f"Invalid track {new_position}")
quarter_track = round(new_position * 4)
diff = quarter_track - self._position
if diff < 0:
# step OUT to SMALLER track numbers
diff = -diff
self.step(STEP_OUT_HALF, diff // 2)
if diff & 1:
self.step(STEP_OUT_QUARTER, 1)
else:
# step IN to BIGGER track numbers
self.step(STEP_IN_HALF, diff // 2)
if diff & 1:
self.step(STEP_IN_QUARTER, 1)
assert self._position == quarter_track, (self._position, quarter_track)
def step(self, delta, n, delay=.016):
print(f"Step by {delta} x {n}")
position = self._position
for i in range(n):
position += delta
phase = position % len(phases)
if phase > len(phases):
phase -= len(phases)
print(f"set phases to {phase} = {phases[phase]}")
for io, value in zip(self._io, phases[phase]):
io.value = value
time.sleep(delay)
self._position = position
print(f"new position is {position}")
if __name__ == '__main__':
enable = digitalio.DigitalInOut(ENABLE)
enable.switch_to_output(False)
positioner = AppleDrivePositioner(PHASE_A, PHASE_B, PHASE_C, PHASE_D)
while True:
positioner.home()
for _ in range(8):
for i in (2, 3, 7, 11, 2, 2.5, 3.75, 5, 6.25, 39, 20):
print(f"**** step to {i}")
positioner.track = i
print()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment