Adafruit has a CircuitPython library called adafruit_floppy for working with raw flux and with MFM-encoded data.

In this example using the library, information about the raw flux on track 0 of the inserted floppy is printed.

To use with CircuitPython, you need to first install a few libraries, into the lib folder on your CIRCUITPY drive. Then you need to update code.py with the example script.

Thankfully, we can do this in one go. In the example below, click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, open the directory examples/ and then click on the directory that matches the version of CircuitPython you're using and copy the contents of that directory to your CIRCUITPY drive.

Your CIRCUITPY drive should now look similar to the following image:

folder
# 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 or Adafruit Feather RP2040 with Floppy Featherwing,
# do some track-to-track seeking and flux reading.

import board
import adafruit_floppy

D24 = getattr(board, "D24") or getattr(board, "A4")
D25 = getattr(board, "D25") or getattr(board, "A5")

floppy = adafruit_floppy.MFMFloppy(
    densitypin=board.A1,
    indexpin=D25,
    selectpin=board.A0,
    motorpin=board.A2,
    directionpin=board.A3,
    steppin=D24,
    track0pin=board.D10,
    protectpin=board.D11,
    rddatapin=board.D9,
    sidepin=board.D6,
    readypin=board.D5,
)

floppy.selected = True
floppy.spin = True
print("Seek track 8")
floppy.track = 8
print("Seek track 0")
floppy.track = 0
print("Read partial track raw flux data")
buf = bytearray(30000)
n_read = floppy.flux_readinto(buf)
print("read", n_read)
buckets = [0] * 256
for b in buf:
    buckets[b] += 1
oi = -1
for i, bi in enumerate(buckets):
    if bi > 10:
        if i != oi + 1:
            print("---")
        oi = i
        print(f"{i:3} {bi:5}")

First, necessary modules are imported. Then, some conditional lines are used to adapt between boards that call the pins "A4/A5" and boards that call the pins "D24/D25". After that, an MFMFloppy object is created that refers to all of the appropriate pins:

import board
import adafruit_floppy

D24 = getattr(board, "D24") or getattr(board, "A4")
D25 = getattr(board, "D25") or getattr(board, "A5")

floppy = adafruit_floppy.MFMFloppy(
    densitypin=board.A1,
    indexpin=D25,
    selectpin=board.A0,
    motorpin=board.A2,
    directionpin=board.A3,
    steppin=D24,
    track0pin=board.D10,
    protectpin=board.D11,
    rddatapin=board.D9,
    sidepin=board.D6,
    readypin=board.D5,
)

The next steps are to select and spin the floppy disk:

floppy.selected = True
floppy.spin = True
print("Seek track 8")
floppy.track = 8
print("Seek track 0")
floppy.track = 0

Finally, raw flux data can be captured and printed:

print("Read partial track raw flux data")
buf = bytearray(30000)
n_read = floppy.flux_readinto(buf)
print("read", n_read)
buckets = [0] * 256
for b in buf:
    buckets[b] += 1
oi = -1
for i, bi in enumerate(buckets):
    if bi > 10:
        if i != oi + 1:
            print("---")
        oi = i
        print(f"{i:3} {bi:5}")

Typical output:

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Seek track 8
Seek track 0
Read partial track raw flux data
read 30000
---
 94   121
 95  1122
 96  3999
 97  8439
 98  7044
 99  2403
100   713
101   299
102    80
103    15
---
141    47
142   110
143   221
144   376
145   559
146   726
147   761
148   833
149   682
150   441
151   172
152    55
153    14
---
194    22
195    32
196    61
197    91
198   113
199   110
200    93
201    75
202    51
203    24
204    19

This guide was first published on Feb 28, 2023. It was last updated on Mar 27, 2024.

This page (Using CircuitPython: adafruit_floppy) was last updated on Mar 27, 2024.

Text editor powered by tinymce.