lunedì 20 settembre 2010

How to drive a floppy with arduino

Every floppy has read/write head moved by a stepper motor.
It's easy to drive that motor using the built in interface, all you have to do is to wire some pin to ground ad power up the floppy.

Actually two pins are used to drive the motor. One controls direction (pin 18) and one controls steps (pin 20).
In my setup an arduino board controls those pins with the right timing to generate a sound of a specified frequency.

This is the wiring:


And this is the code:
//pin collegati ai floppy, due per ogni floppy, il primo è lo step_pin, il secondo il dir_pin
byte fd[] = {2, 3, 4, 5};

//sequencer
int steps = 16;
float seq_f[] = {400, 300, 200, 410, 130, 230, 270, 280, 300, 200, 100, 310, 230, 330, 370, 380};
int seq_t[] = {500, 500, 200, 500, 500, 300, 500, 500, 500, 500, 200, 500, 500, 300, 500, 500};
boolean seq_d[] = {true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false};

//------------------------------------------------------

void setup()
{
  //attiva i pin dei floppy
  for (byte i = 0; i < 4; i++)
  {
    pinMode(fd[i], OUTPUT);
  }
  //Serial.begin(9600);
}

//------------------------------------------------------

void loop()
{
  for (int i = 0; i < steps; i++)
  {
    muovi(0, seq_d[i], seq_f[i], seq_t[i]);
  }
}

//------------------------------------------------------

// fl: numero del floppy, dir: true == avanti, f: frequenza, n: numero di passi (n <= 86)
void muovi(byte fl, boolean dir, float f, int t)
{
  //setta i pin del floppy
  byte step_pin = fl * 2;
  byte dir_pin = (fl * 2) + 1;
  
  //calcola il periodo T di delay tra un passo e l'altro data la frequenza f
  float T = (1 / f) * 1000000;
  
  //alza o abbassa il dir_pin a seconda della direzione dir (true == avanti)
  if (dir == true)
  {
    digitalWrite(fd[dir_pin], HIGH); 
    digitalWrite(13, HIGH);  //led indicatore direzione
  }
  else
  {
    digitalWrite(fd[dir_pin], LOW);
    digitalWrite(13, LOW);
  }
  
  //numero di iterazioni (n) ottenuto dal tempo desiderato per una nota (t, in ms) diviso il
  //tempo richiesto per un ciclo (T per 2 passi) moltiplicato 1000 (poichè T è espresso in s)
  float n = t / (T * 2) * 1000;
  
  //alza e abbassa lo step_pin per un numero di passi n col giusto delay
  for (int i = 0; i < n; i++)
  {
    digitalWrite(fd[step_pin], HIGH);
    delayMicroseconds(T);
    digitalWrite(fd[step_pin], LOW);
    delayMicroseconds(T);
  }
  //Serial.println(n, DEC);
}
Here is a good article about floppy's motors.

Nessun commento:

Posta un commento