Making Music with Stepper Motors

There are many You-tube videos like this one which all appear to be reading MIDI files to obtain the note envelope info and translating that into stepper drive signals that all seem to use Step & Dir. Unfortunately, almost none of them have any code for an arduino. The brother of the guy who did Phantom of the Floppera got interested in it and did this
webpage. At the bottom is a link to download the source code but it used a PIC18F14K50 instead of an arduino so I couldn't use that code. I tried to read his source code and it gave me a headache. I have Ramps A4988 stepper drivers that accept STEP & DIR inputs and two stepper motors. I have absolutely no experience with MIDI. I made a music synthesizer using a sound chip and a motorola 6800 programmed in ASM for my Devry Junior Class project but it predated MIDI. ( I used timing loops for freq and duration. There was no "envelope" per se.
FYI, I also have an SD Card shield for my UNO.
So what's my question ?
How difficult would it be to write a program for an UNO to read a Midi file from and SD card and play music with two stepper motors (since that's all I have at the moment) ? How much would I need to learn about Midi before I could even attempt it ? How does one obtain a Midi file ? If it is possible to download Midi files, the file I would want to use for this project is the Theme from the TV series Star Trek Deep Space 9
DS9 Theme

I tried the following code (setting maxpin to 2 and using only one RAMPS A4988 driver) but it didn't work. (probably because I didn't have the Java with Netbeans installed) but maybe because his code is written specifically for floppy drives and not for free-standing steppers, like I am using. It was worth a try. I don't know why it is so easy to find videos of people making music with free-standing steppers but impossible to find the code.

I know (some of) my limitations. I keep away from Threads involving music.

...R

But you need not only the stepper motors, you need to have them in 5 inch floppy drives. That's the whole point!

Otherwise it will not sound right (if at all)!

(I have a decent collection in the garage ...)

There are several Youtube videos of people using other kinds of "free-standing" steppers on a table top.

@Paul_B,
You have an advantage because the link I posted shows how to interface to the IDE cable.
Like this.
He modified it so it doesn't read data at all. The S/W reads a MIDI file and outputs the profile to the motor driver as "Step" pulses = to note frequency for [ duration] milliseconds , followed by next note.

How much would I need to learn about Midi before I could even attempt it ? How does one obtain a Midi file ? If it is possible to download Midi files, the file I would want to use for this project is the Theme from the TV series Star Trek Deep Space 9

MIDI is just a sequence of 8 bit characters and the protocol is pretty simple. You can ignore many parts of it, and just get the note on/off and pitch values.

The pitch can then be used to set the step rate appropriately. There are lots of free MIDI parser examples, e.g. GitHub - LenShustek/miditones: Convert MIDI files to a simplified time-ordered sequence of note commands

I had a scanner that would play music while it was positioning the light source.

Thanks. I'll read that.

Here is a preliminary sound test. I still have to figure out the MIDI stuff but this sketch will make sound with a stepper placed on a resonating surface (like a wood table top etc)

byte directionPin = 7;
byte stepPin = 8;
int dlyuS = 0;

void setup() 
{ 

   pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
 
}

void loop() 
{ 
  digitalWrite(directionPin, HIGH);
  
   for(int dlyuS=20;dlyuS<80;dlyuS ++)
  {
    for(int i=0; i<1000;i++)
    {
     
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(dlyuS);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(dlyuS);
     }
   }
  
     for(int dlyuS=80;dlyuS>0;dlyuS --)
       {
        for(int i=0; i<1000;i++)
         {
          digitalWrite(stepPin, HIGH);
          delayMicroseconds(dlyuS);
          digitalWrite(stepPin, LOW);
          delayMicroseconds(dlyuS);
         }
       }
}

The problem I am having now is that when I Google "download Midi file" I get links to *.MID files that
automatically open with Windows Media Player or Realplayer. They are not text files with hex values or whatever that could be parsed by a uC. I need to know how to get Midi files that can be read, (by a human or uC) not played . I have not been able to view the midi file source code so maybe some special software is necessary or I am looking for the wrong kind of file. I could find nothing on the internet explaining how to view the midi file information.

MIDI files are binary files and have to be read and interpreted with appropriate software. Of course they can be read by a uP running the proper code.

To prevent Windows Media Player from automatically opening a .MID file, change the .MID extension to something else. Open and inspect it with a hex editor, like this one.

This link tells you about the MIDI file format:-
http://www.ccarh.org/courses/253/handout/smf/

This is a pdf giving more information:-
PDF

There is also this:-
http://www.fileformat.info/format/midi/corion.htm

Can anyone tell me what obvious mistake I made with this sketch ? (for some reason it doesn't work:
it should calculate dlyuS using freq . The period is the reciprocal of the freq. To convert to uS I multiply by 1E+6 (1,000,000)

byte directionPin = 7;
byte stepPin = 8;
float freq =220;
unsigned long dlyuS = 0;
float period;
unsigned long duration;

void setup() 
{ 
  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  Serial.begin(9600);
}

void loop() 
{ 
  digitalWrite(directionPin, HIGH);
  note;
  //Serial.println("test");   
  
}

void note()
    {
      float  period = (1/freq) ;
      period = period * 1E+6;
     // Serial.println("test");
      Serial.println(period);  //THIS LINE DOESN'T DO ANYTHING OR PRINTS "0"
      delay(1000);
      dlyuS = period/2;
      
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(dlyuS);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(dlyuS);
    }

@jremington,
I downloaded both of those apps FrHed & HexEdit and couldn't figure out how to open them. They are both zip files. There were no files of the "Application" type in either of the sets of folders that were unpacked. If there is no "Application" file I don't know how I am supposed to open them. Isn't there a Hex Editer with a Windows installer that creates and icon on the desktop that can be used to open the app ?

 note;

I've spare pair of "()" you can have.

ha ha ! :smiley:
(boy do I feel stupid !)

Test-2 (bare bones sketch for making music without midi files.
Requires note freq values and duration can be set with FOR LOOP counters. Admittedly , this is very crude but there is no question that it generates musical notes with a freestanding stepper motor placed on some resonate surface.

 byte directionPin = 7;
byte stepPin = 8;

unsigned long dlyuS = 0;
float period;
unsigned long duration;

void setup() 
{ 
  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  Serial.begin(115200);
}

void loop() 
{ 
  digitalWrite(directionPin, HIGH);
 for (int i=0; i<50;i++)
     {
        note(493.88);
     }
    digitalWrite(directionPin, LOW); 
     for (int i=0; i<50;i++)
     {
        note(523.25);
     } 
     digitalWrite(directionPin, HIGH);
     for (int i=0; i<50;i++)
     {
       note(587.33);
     } 
      digitalWrite(directionPin, LOW); 
   for (int i=0; i<50;i++)
     {
       note(659.25);
     } 
      digitalWrite(directionPin, HIGH);
    for (int i=0; i<50;i++)
     {
        note(698.46);
     }
       digitalWrite(directionPin, LOW); 
     for (int i=0; i<50;i++)
     {
        note(783.99);
     } 
      digitalWrite(directionPin, HIGH);
     for (int i=0; i<50;i++)
     {
       note(880.0);
     } 
       digitalWrite(directionPin, LOW); 
   for (int i=0; i<50;i++)
     {
       note(987.77);
     } 
    
     
      
  //Serial.println("test");   
  
}

void note(float freq)
    {
      float  period = (1/freq) ;
      period = period * 1E+6;
     // Serial.println("test");
     // Serial.println(period);
     //delay(1000);
      dlyuS = period/2;
       Serial.println(dlyuS);
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(dlyuS);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(dlyuS);
    }

Ok , I got a Hex Editor with a Windows installer HxD and I opened the DS9 MIDI file. I could read the instrument type (like French Horn (in the opening part) but now I have to figure out how to parse it.

I opened the MIDI file attached and copy and pasted the hex values into Notepad by chunks.
The first chunk starts with MThd (header) , and the rest start with MTrk (track files).
I have to read up more on Midi file format to figure out what the values mean. I'll read the PDF file you linked to try to decypher it.

DS9_midi_file_chunks.txt (10.7 KB)