Some times ago, I watched a video about singing floppy drives and a heap of written off computers, and decided to make something of the kind.

Make it on Arduino like the rest? Seriously? As they say, f*ck the system! I decided to make it on Atmega8A, as that’s what I had at hand. I also decided that wires were unnecessary, and found HC-05.

Let’s go!

The Circuit

As usual, the first stage is the circuit. No problem with that.

It is simple, without unnecessary bells and whistles.

The Board

It was no problem to make it with the help of the photoresist. Scattered everything in 1o minutes and produced it in an hour.

The Code

Now, the fun part begins — programming. To save some time, I decided to write in C. But I made the same mistake at the very beginning.

It was about controlling floppy drives. As you know, if Direct pin = 0, and we give impulses to Step, a floppy drive steps forward, and if Direct pin = 1, it makes a step back. But a floppy drive has only 80 steps. What can we do about that? The solution is simple. A floppy drive can make half a step if we change the state of Step, rather than pulsing it. It’s better to do it this way:

Step ^= (1<<pin); First problem solved! Now, let’s implement the control function.

void output(int drive) { // drive – the Floppy drive number 1 - 8 int position = drive - 1; if(currentPosition[position] >= max)direct |= 1 << position; if(currentPosition[position] <= 0)direct &= ~(1<<position); // set it to zero, if we are at 0 if(direct & (1<<position)) { //check the state back(drive); //make a step back currentPosition[position]--; //decrease the position of the current floppy drive }else{ forward(drive); //step forward currentPosition[position]++; //Increase it } }

Done! Now, let’s deal with timers. Set the timer to the CTC mode with the division by 8 and allow interrupt by Output Compare (hereinafter OC). Put 40 in the OCR. An OC event occurs approximately in 40 µs. The interrupt handler is quite large.

void Action(){ if(fr1 != 0){ currentTick[0]++; if(currentTick[0] >= fr1){ //fr* - periods of channels in µs output(1); currentTick[0]=0; } }; if(fr2 != 0){ currentTick[1]++; if(currentTick[1] >= fr2){ currentTick[1]=0; output(2); } }; if(fr3 != 0){ currentTick[2]++; if(currentTick[2] >= fr3){ output(3); currentTick[2]=0; } }; if(fr4 != 0){ currentTick[3]++; if(currentTick[3] >= fr4){ currentTick[3]=0; output(4); } }; if(fr5 != 0){ currentTick[4]++; if(currentTick[4] >= fr5){ currentTick[4]=0; output(5); } }; if(fr6 != 0){ currentTick[5]++; if(currentTick[5] >= fr6){ currentTick[5]=0; output(6); } }; if(fr7 != 0){ currentTick[6]++; if(currentTick[6] >= fr7){ currentTick[6]=0; output(7); } }; if(fr8 != 0){ currentTick[7]++; if(currentTick[7] >= fr8){ currentTick[7]=0; output(8); } }; } ISR(TIMER2_COMP_vect){ Action(); }

Now, the connection with the computer. Here we proceed as follows. Pass a string with a macro in the header (C/F) -> the body (number) -> the end of the package (‘;’). First, processing by the state machine:

void parse(){ char data = UDR; switch(data){ case 'C': tmp_int = 0; SM= data; break; // С – it’s the channel macro case 'F': tmp_int = 0; SM= data; break; // F - frequencies case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': tmp_int = tmp_int * 10 + (data -'0'); break; case ';': switch(SM){ case 'C': channel=tmp_int; break; case 'F': freq = tmp_int; break; }; play(freq, channel); break; //in play, we recount the period, taking into account the clock frequency, then write it to fr* case 'R' : resetAll(); break; default: break; } }

Second, we accept only in the Idle state:

while ( UCSRA & (1<<RXC))parse(); — Done?

— No! How do we control it?

I didn’t feel like writing the control program from scratch, so I added functionality to HETC control terminal. Its interface is quite simple, so I’m not going to write much. The only thing is to select the Floppy drive and the COM-port of the device, then Connect.

Yes, you can do it without the Bluetooth, it’s just the way I see it.

Select the Midi file and….

Source Code

Sources + firmware.