interface with floppy and play melody

has anyone done this before: - YouTube

it is a floppy drive being interfaced with an arduino + playing "music" from midi sent over serial.

ive searched for a while and PM'd/Email'd the creators of such contraptions , but not much luck on responses.

i found a few websites, but no arduino code applicable to me:
Michael Kohn - floppy music (has Assembly for mega168, but i dont know assembly, and would rather stick with what i know: arduino and C#)
http://georgewhiteside.net/projects/diskette-organ/

thanks

it is a floppy drive being interfaced with an arduino + playing "music" from midi sent over serial.

Just a minor point... Mike Kohn isn't using an Arduino. He is using a ATmega168, but it is stand alone (and doesn't appear to be using an Arduino boot loader.)

yes i realized that and he is using Assembley. i have decided to redo his project in arduino, first starting simply with putting the music notes directly in the code, not using serial.

floppy pins 12, 18, and 20 are the bare minimum to play music on the floppy.
pin 12(Drive Select) is simple low or high. pin 18(Direction Select of stepper in drive) is again a simple low or high, but im not sure about pin 20(head step) which is the note frequency like 440 from the note A440. how do i send that to the floppy? also on the arduino there are digital pins and then digital PWM(for servos right?) pins, does it matter what i use?

digital for arduino digitalWrite(pinhere, HIGH); for pins 12 and 18

im guessing i have to use PWM for the frequency stuff(pin20) but as you see here : Arduino Playground - TimerPWMCheatsheet
or
Arduino Playground - PwmFrequency
arduino has crappy ability to set frequencies and the frequencies available aren't any where close to the musical notes:

note frequency(Hz)
C 261.63Hz
C# 277.18
D 293.66
D# 311.13
E 329.63
F 349.23
F# 369.99
G 392
G# 415.3
A 440
A# 466.16
B 493.88

whatdya think?

is this what im looking for? http://arduino.cc/en/Tutorial/Tone
it plays notes on a speaker on a digital pin. could i hook up floppy pin 20(head step) to make it play the notes, or am i completely off?

Yes, it looks like tone() on pin 20 would work as you describe.

You've done a lot of research, why don't you just give it a go and let us know how you got on?
T.

with the code below i managed to get the floppy to trun the DC motor(turns the actual floppy disk) but not the stepper:

int DrvSel = 2;              
int Stp = 3;
int mDir = 4;
int Dens = 5;
int MtOen = 6;


void setup() 
{
  pinMode(DrvSel, OUTPUT);      
  pinMode(mDir, OUTPUT);     
  pinMode(Dens, OUTPUT);      
  pinMode(MtOen, OUTPUT); 
  pinMode(Stp, OUTPUT); 
  
 // digitalWrite(DrvSel, LOW);   // sets the dirve select
 // digitalWrite(Dens, HIGH);
  //digitalWrite(MtOen, LOW);
  //digitalWrite(mDir, LOW);     
}

void loop() 
{  
  // DC floppy MOTOR--- wont run without this
  digitalWrite(mDir, LOW);
  digitalWrite(mDir, HIGH);
  delay(10);
}

my second attempt, yet again i can move the motor but not the stepper.

#include <stdint.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define stepDir 3 //which direction to step the read/write head
#define stepPulse 6 //when we pulse this the stepper moves one step
#define motorOn 4 //turn the platter motor on

#define STEPS 75 //maximum steps the stepper can make
#define MINSPEED 1
#define MAXSPEED 30
#define FORWARD false
#define BACKWARD true

void setup() 
{
  pinMode( stepDir, OUTPUT );
  pinMode( stepPulse, OUTPUT );
  pinMode( motorOn, OUTPUT );
  
  digitalWrite( motorOn, false );
}

void loop() 
{  
  {
    int speed = map(analogRead(0),0,1024,MINSPEED,MAXSPEED);
    
    if( true )
    {
      #ifdef PLATTER_INT
      if( startPoint )
      {
        startPoint = false;
      #endif
        doSteps(FORWARD, STEPS, speed); //random(MINSPEED,MAXSPEED));
        doSteps(BACKWARD, STEPS, speed ); //random(MINSPEED,MAXSPEED));
      #ifdef PLATTER_INT
      }
      #endif
    }
  }
}

  void doSteps( boolean dir, int steps, int stepDelay )
  {
    digitalWrite( stepDir, dir );
    for( int i = 0; i < steps; i ++ )
    {
      digitalWrite( stepPulse, LOW );
      _delay_ms( stepDelay );
      digitalWrite( stepPulse, HIGH );
      _delay_ms( stepDelay );
    }
  }

and timer:

#define TRUE 1
#define FALSE 0

/* timer interrupt
ISR(TIMER1_COMPA_vect)
{
   cli();
   PORTD |= _BV(motorPulse);
   PORTD &= ~_BV(motorPulse);
   sei();
}
*/

void setupTimer( void )
{
//  uint8_t i;


 /*
   * Set up the 16-bit timer 1.
   *
   * Timer 1 will be set up as a 10-bit phase-correct PWM (WGM10 and
   * WGM11 bits), with OC1A used as PWM output.  OC1A will be set when
   * up-counting, and cleared when down-counting (COM1A1|COM1A0), this
   * matches the behaviour needed by the STK500's low-active LEDs.
   * The timer will runn on full MCU clock (1 MHz, CS10 in TCCR1B).
   */
  TCCR1A = 0; //_BV(COM1A0);
  TCCR1B = _BV(WGM12) | _BV(CS10); // ctc mode / no prescaler
  OCR1A = 120;			/* count up to this */

  TIMSK1 = _BV(OCIE1A);

  sei(); /* global interrupt enable */
//  Serial.begin(9600);

  //Serial.println("running");
}

Seems like you are just copy-pasting 'random' code. You should try to understand how this works, and then make your own code.

Actually it's very easy, I've done this today: http://dl.dropbox.com/u/37290556/VID_20111007_195955.m4v
Sorry for the crappy camera app (CyanogenMod).

Tomorrow I will help you with the basics. :wink:

at first, yes, i did just copy and paste, but i understand what im trying to do yet it doesnt work:

GND->i need a ground from any odd floppy pin to both the power supply and the arduino.

arduino digital 4->floppy pin 10 is for turning on the platter motor, and i need to set that to LOW

GND->drive select 0(floppy pin 14) to LOW which selects the last floppy connector on the cable. i just hooked this up directly to ground as other people have done to get LOW.

arduino digital 3->floppy pin 18 is for the direction of the stepper depending on which direction i want the stepper to go, LOW or HIGH.

arduino digital 6->floppy pin 20 is for how many "steps" i want to move the stepper motor.

floppy cable pinout i used for arduino->floppy cable connections:

this is a simple program i wrote, all i wanted to do was move the stepper...:frowning:

#define stepDir 3 //which direction to step the read/write head
#define stepPulse 6 //when we pulse this the stepper moves one step
#define motorOn 4 //turn the platter motor on
//drive select is already taken to 0V LOW by GND so no pin for that

void setup() 
{
  pinMode( stepDir, OUTPUT );
  pinMode( stepPulse, OUTPUT );
  pinMode( motorOn, OUTPUT );
  
 // digitalWrite( motorOn, LOW ); 
}

void loop() 
{

    digitalWrite( motorOn, LOW );  
    
    digitalWrite( stepDir, LOW);
    digitalWrite( stepPulse, LOW );
    delay(50);
    digitalWrite( stepPulse, HIGH );
    delay(50);

}

some people say that the platter motor has to be on for the step head to move. is this right?

do i have to declare the platter motor pin as LOW in the loop so it happens repeatedly or just once in setup?

Ok, let me add some info. You just need 4 wires:

1 GND (yeah, to Arduino GND; common GND)
14 Drive Select 0 (the easy way, to GND as you said. But you could connect it to an output if you want to make FDD LED on/off)
18 Direction Select (LOW: move forward, HIGH: move backward)
20 Head Step (falling edge flank makes it move 1 step)

There's no need to make the platter motor move, and even there's no need to have a Floppy inserted. But maybe that depends on the FDD manufacturer/model, or it's just for more fun xD, so it's up to you.

So the latest code you wrote, should work and move the header forward. Does it?
You connect pin 14 directly to GND, so FDD LED should be always on. Is it?

About the musical stuff, there are 2 different ways for this:

  • Move the header one direction at certain speed (move 1 step forward, delay, move 1 step forward, delay, ...)
  • Make the header vibrate at certain frequency (move 1 step forward, delay, 1 step backward, delay, ...)

The first one is intuitive and visually cool, but there's a 80 step limit movement from start to end positions (affects duration of notes).

The second one is the preferred (and I think it sounds louder). You move the header half way, and make it vibrate. Try this:

#define Dir 3
#define Step 6

void setup() {
  pinMode(Dir, OUTPUT); pinMode(Step, OUTPUT);
  initHead();  // move header half way
}

void initHead() {
  digitalWrite(Step, HIGH);
  digitalWrite(Dir, HIGH); doSteps(80, 1911);  // move header to start position wherever it is, 80 steps at ~261 step/s
  digitalWrite(Dir, LOW); doSteps(40, 1911);
  delay(1000);
}

void doSteps(int steps, int stepDelay) {
  for(int i=0;i<steps; i++) {
    digitalWrite(Step,LOW); delayMicroseconds(stepDelay);
    digitalWrite(Step,HIGH); delayMicroseconds(stepDelay);
  }
}

void loop() {
  while(true);
}

Does it work?

yes it works:)
so did mine.

at first i thought the pins on the floppy connector went 1, 2, 3... all the way across one row then the next(wasted couple of hours messing around), then i figured out the real pinout and put wire for pin 20 in the pin 22 spot(wasted couple more hours messing around)... dang.

now i got it right, and it moves :slight_smile: yay!

using arduino tone(); doesnt work with the head step by the way

EDIT: i take that back

int DrvSel = 6;              
int Step = 5;
int Dir = 3;

void setup() 
{
  pinMode(DrvSel, OUTPUT);      
  pinMode(Dir, OUTPUT);
  pinMode(Step, OUTPUT);  
  
  digitalWrite(DrvSel, LOW);
}

void loop() {
   // turn off tone function for pin 5:
   noTone(5);		
   digitalWrite(Dir, HIGH);	
  // play a note on pin 5 for 200 ms:
 //tone(pin, frequency, duration)
  tone(5, 440, 200);
  delay(200);

  // turn off tone function for pin 5:
  digitalWrite(Dir, LOW);
  noTone(5);
  // play a note on pin 5 for 500 ms:
  tone(5, 494, 500);
  delay(500);
  
  // turn off tone function for pin 5:
  digitalWrite(Dir, HIGH);
  noTone(5);  
  // play a note on pin 5 for 400 ms:
  tone(5, 523, 400);
  delay(400);
  
    digitalWrite(Dir, LOW);
  noTone(5);  
  // play a note on pin 5 for 300 ms:
  tone(5, 440, 300);
  delay(300);

}

but it takes for ever to set up the notes and doesnt work very well(stepper going to far on track)

Hi,
it took me a couple of hours to get this up and running....including ripping out the floppy drive from my PC :grin:

// D4 to pin 14
// D3 to pin 16 
// D6 to pin 18
#define Dir 3
#define Step 6
#define Sel 4
void setup() {
  pinMode(Dir, OUTPUT); 
  pinMode(Step, OUTPUT);
  pinMode(Sel, OUTPUT);
  digitalWrite(Sel, HIGH);
  initHead();  // move header half way
}

void initHead() {
  digitalWrite(Step, HIGH);
  digitalWrite(Dir, HIGH); 
  doSteps(80, 1911);  // move header to start position wherever it is, 80 steps at ~261 step/s
  digitalWrite(Dir, LOW);
  doSteps(40, 1911);
  delay(1000);
}

void doSteps(int steps, int stepDelay) {
  digitalWrite(Sel, LOW);
  for(int i=0;i<steps; i++) {
    digitalWrite(Step,LOW); 
    delayMicroseconds(stepDelay);
    digitalWrite(Step,HIGH); 
    delayMicroseconds(stepDelay);

  }
  digitalWrite(Sel, HIGH);
}

void vibe(int count, int period) {
  for(int l=0;l<count; l++) {
    digitalWrite(Dir, HIGH);
    doSteps(1, period);
    digitalWrite(Dir, LOW);
    doSteps(1, period);
  }
}
void loop() {
  vibe(100, 851);
  delay(250);
  vibe(110, 756);
  delay(250);
  vibe(85, 955);
  delay(250);
  vibe(30, 3822);
  delay(250);
  vibe(90, 1275);
  delay(250);
  while(true);
}

Texy

what does void vibe function do? is that for music?

i found this code: GitHub - Sammy1Am/Moppy2: The evolution of the Musical flOPPY controller for playing MIDIs from my PC through JAVA to the arduino.

Yes I created that function to play 1 note, at frequency 'period' for 'count' length of time.

Texy

sirbow2:
what does void vibe function do? is that for music?

i found this code: GitHub - Sammy1Am/Moppy2: The evolution of the Musical flOPPY controller for playing MIDIs from my PC through JAVA to the arduino.

..interesting, but I,m already lost with tis bit :

"and open up the included Java code in your favorite IDE. This code includes a NetBeans project for your convenience, so you should be able to open the project directly in NetBeans."

...but I,m looking into it now!

Texy

download this IDE: http://www.oracle.com/technetwork/java/javase/downloads/jdk-7-netbeans-download-432126.html

isntall it, open the project files from the download button in git hub change the COM port in the main.java file in the java ide and in the folder you downloaded there are KirbysTheme and Tetris, you can get more to play. put the new MIDIs in that folder (samplesongs i believe inside the Java folder of the downloaded stuff from git hub.)
put the arduino sketch on the arduino(also form github)

in main.java change: Sequence sequence = MidiSystem.getSequence(new File("samplesongs/powerhouse.mid"));

mb = new MoppyBridge("COM1");

COM1 to your COM port(serial port) COM2 etc

"samplesongs/powerhouse.mid" change powerhouse to name of your midi file that you placed in the samplesongs folder inside the folder from github)

Doesn't seem to be as simple as described. There is no main.java file, and I,m getting errors regarding rxtxserial.

Texy