Porting the Windows portion was too much work, so I hacked a version of the original sketch to work entirely through the serial monitor. It's not much, but it was enough to realign a track 0 sensor on a Teac FD-155GF.
Edit: Also, I don't really know much about disk drives at the low level, so some of the code is probably misleading if not entirely wrong.
I would put it on Github, but I don't know how free the original poster's source is. Surely free enough to post tinkerings in the same place... I hope.
Some notes:
The main loop() lights the onboard LED when Track 0 is sensed.
A physical oscilloscope isn't entirely necessary. I was able to use a free software oscilloscope (iSpectrum for OSX) by hooking drive pin 30 and Arduino +3.3v to a 1/8" audio jack.
I found track 0 by first moving the sensor as far outward as it would go and stepping the drive head out as far as it would go. With the spindle still going, I manually turned the stepper screw slowly until the first track appeared in the oscilloscope.
At that point, I moved the track 0 sensor until the Arduino light just barely lit up and tightened the screws.
I switched to the Kryoflux board and ran "dtc -c2" to calibrate the head at "track 0". I went back to the Arduino and oscilloscope and measured how far off it was. I adjusted the track 0 sensor to compensate for the difference.
After going back and forth a couple times, "dtc -c2" seemed to hit track 0, and I was able to record floppies.
YMMV.
Code: Select all
#define _HD 2 // Arduino 2 -> 2 drive
#define _MOTOR 3 // Arduino 3 -> 10/16 drive
#define _DSEL 4 // Arduino 4 -> 14/12 drive
#define _DIR 5 // Arduino 5 -> 18 drive
#define _STEP 6 // Arduino 6 -> 20 drive
#define _SIDE 7 // Arduino 7 -> 32 drive
#define _INDEX 8 // Arduino 8 <- 8 drive
#define _TRACK0 9 // Arduino 9 <- 26 drive
#define _READ 10 // Arduino 10 <- 30 drive (unused)
int input_delta = 0;
int current_track = 0;
// Low-level drive line manipulation.
void dir_up(void) { digitalWrite(_DIR, LOW); }
void dir_down(void) { digitalWrite(_DIR, HIGH); }
void motor_on(void) {
digitalWrite(_MOTOR, LOW);
digitalWrite(_DSEL, LOW);
}
void motor_off(void) {
digitalWrite(_MOTOR, HIGH);
digitalWrite(_DSEL, HIGH);
}
void step_start(void) { digitalWrite(_STEP, LOW); }
void step_stop(void) { digitalWrite(_STEP, HIGH); }
void step(void) {
step_start();
delay(2);
step_stop();
delay(5);
}
void step_up(void) {
Serial.print("stepping up.\n");
dir_up();
step();
}
void step_down(void) {
Serial.print("stepping down.\n");
dir_down();
step();
}
void drive_a(void) { digitalWrite(_DSEL, LOW); }
void drive_b(void) { digitalWrite(_DSEL, HIGH); }
void density_hd(void) { digitalWrite(_HD, LOW); }
void density_dd(void) { digitalWrite(_HD, HIGH); }
void side_1(void) { digitalWrite(_SIDE, LOW); }
void side_0(void) { digitalWrite(_SIDE, HIGH); }
void led_off(void) { digitalWrite(13, LOW); }
void led_on(void) { digitalWrite(13, HIGH); }
// Woot.
void setup() {
pinMode(_HD, OUTPUT);
pinMode(_INDEX, INPUT_PULLUP);
pinMode(_MOTOR, OUTPUT);
pinMode(_DSEL, OUTPUT);
pinMode(_DIR, OUTPUT);
pinMode(_STEP, OUTPUT);
pinMode(_TRACK0, INPUT_PULLUP);
pinMode(_READ, INPUT_PULLUP);
pinMode(_SIDE, OUTPUT);
pinMode(13, OUTPUT);
led_off();
drive_a();
side_0();
density_hd();
dir_up();
step_stop();
motor_off();
led_on();
input_delta = 0;
Serial.begin(9600);
Serial.print("input?\n");
}
void move_head(int how_much) {
Serial.print("stepping ");
Serial.println(how_much);
int new_track = current_track + how_much;
if (new_track == 0) {
if (current_track < 0) {
// Step forward until the current track is zero.
// TODO
}
// Step forward until track-zero is false.
// TODO
// Step backward until track-zero is true.
// TODO
}
else if (how_much > 0) {
// Step forward by how_much.
// TODO
while (how_much-- > 0) {
step_up();
}
}
else if (how_much < 0) {
// Step backward by how_much.
// TODO
while (how_much++ < 0) {
step_down();
}
}
else {
// Nothing changed.
}
current_track = new_track;
Serial.print("new position: ");
Serial.println(current_track);
return;
}
void loop() {
//Serial.print("ping\n");
//delay(1000);
if (digitalRead(_TRACK0)) {
digitalWrite(13, LOW);
}
else {
digitalWrite(13, HIGH);
}
}
void serialEvent() {
while (Serial.available()) {
unsigned char input = Serial.read();
switch (input) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
input_delta *= 10;
input_delta += input - '0';
break;
case '+':
move_head(input_delta);
input_delta = 0;
Serial.print("input?\n");
return;
case '-':
move_head(-input_delta);
input_delta = 0;
Serial.print("input?\n");
return;
case '=':
move_head(input_delta - current_track);
input_delta = 0;
Serial.print("input?\n");
return;
// low-level wheela
case 'd':
digitalWrite(_DSEL, LOW);
Serial.print("dsel low\n");
break;
case 'D':
digitalWrite(_DSEL, HIGH);
Serial.print("dsel high\n");
break;
case 's':
digitalWrite(_STEP, LOW);
Serial.print("step low\n");
break;
case 'S':
digitalWrite(_STEP, HIGH);
Serial.print("step high\n");
break;
case 'h':
digitalWrite(_HD, LOW);
Serial.print("hd low\n");
break;
case 'H':
digitalWrite(_HD, HIGH);
Serial.print("hd high\n");
break;
case 'm':
digitalWrite(_MOTOR, LOW);
Serial.print("motor low\n");
break;
case 'M':
digitalWrite(_MOTOR, HIGH);
Serial.print("motor high\n");
break;
case 'r':
digitalWrite(_DIR, LOW);
Serial.print("dir low\n");
break;
case 'R':
digitalWrite(_DIR, HIGH);
Serial.print("dir high\n");
break;
case 'e':
digitalWrite(_SIDE, LOW);
Serial.print("side low\n");
break;
case 'E':
digitalWrite(_SIDE, HIGH);
Serial.print("side high\n");
break;
}
}
}