MIDI плеер на восьми Floppy. Или как электронщик с ума сходил

Как-то раз посмотрел я видео о поющих флопах и на гору списанных компов. Решил сделать что-то подобное.

готовый девайс

Делать на Arduino как остальные? Да вы что, серьёзно? F*ck the system, как говорится! Решено было делать на Atmega8A, потому что только она и была под рукой. Провода тоже для слабаков, поэтому я отыскал HC-05 (зачем лишние сопли?).

Поехали!

Схема


Первый этап, как обычно, схема. С ней проблем нет.

схема

Она простая и без лишних наворотов.

Плата


Плата тоже делается без особого напряжения при помощи фоторезиста. Раскидал за 10 минут и изготовил за час.

Разводка платы



Пишем код


Теперь самое интересное — программирование. Писать решил на C, дабы сэкономить время. Но не успел начать, как уже грабли.

Грабли заключаются в управлении флопами. Как известно, если Direct pin = 0, а на Step давать импульсы, то флоп шагает вперёд, а если Direct pin = 1, то назад, но у флопа всего 80 шагов. Мало, что делать? Решение простое. Флоп умеет делать полшага, если просто менять состояние Step, а не пульсировать его. Делать это лучше так:

Step ^= (1<<pin);

Первая проблема решена! Дальше реализация всей функции управления.

void output(int drive){                                                     // drive - номер флопа 1 - 8
	int position = drive - 1;                                            //пересчёт на позицию в массивах и байтах 0-7
			if(currentPosition[position] >= max)direct |= 1 << position; // direct - переменная char (8 бит). Ставим нужный бит, если в крае
			if(currentPosition[position] <= 0)direct &= ~(1<<position);     //обнуляем его, если мы в нуле
					if(direct & (1<<position)){                                      //проверка состояния
						back(drive);                     //шагаем назад
						currentPosition[position]--; //уменьшаем позицию текущего флоппи
					}else{
			 		forward(drive);                        //шагаем вперёд
					currentPosition[position]++;   //увеличиваем её
				}
}

Сделали! Теперь таймеры. Таймер ставим в CTC mode с делением на 8 и разрешаем прерывание по Output Compare (далее OC). В OCR кладём 40. Примерно раз в 40 мкс наступает событие OC. Обработчик прерываний довольно ёмкий.

Для любознательных
void Action(){

		if(fr1 != 0){
		currentTick[0]++;                     //считаем тики таймера
			if(currentTick[0] >= fr1){ //fr* - периоды каналов в мкс
			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();
}


Теперь связь с компом. Здесь поступим так. Передаётся строка с макросом в заголовке (C/F) ->тело (число)->окончание пакета (';'). Во-первых, обработка через машину состояний:

void parse(){
char data = UDR;
	switch(data){
		case 'C': tmp_int = 0; SM= data; break;   // С - Это макрос канала
		case 'F': tmp_int = 0; SM= data; break;   // F - частоты
		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;  //в play пересчитывается период с учётом тактовой частоты и записывается в fr*
					case 'R' : resetAll(); break;
		default: break;
	}
}

Во-вторых, приём только в состоянии Idle:

while ( UCSRA & (1<<RXC))parse();

— Ну, всё уже?
— Нет! А чем управлять?

Программу управления писать с нуля было влом, поэтому я добавил функционал в свою программу управления катушкой Теслы (HETC control terminal). Наркомания? Конечно. С её интерфейсом можно разобраться самому, писать много не буду. Единственное, что надо в начале выбрать Floppy и COM-порт устройства, далее Connect.

Да, можно и без блюпупа, это просто моя заморочка.

Выбираем миди-файл иии…



Исходники


Исходники + прошивка.
Метки:
Поделиться публикацией
Комментарии 25
  • +4
    За описание граблей спасибо, обычно эти моменты пропускают.
    • +4
      Он немного фальшивит, начиная с минуты :) А вообще — восторг!
      Несмотря на то, что уже много подобных проектов видел, никогда не надоедает посмотреть/послушать новую версию!
      • +2
        Я ожидал что это всё к MIDI выходу подключится, а тут облом.
        • +2
          на финальном соло флопики должны были задымиться
          • +4
            Это такая вещь, из разряда «я знаю как ее сделать, но никогда в жизни не соберусь». Как умный дом и квадрокоптер. Круто.
            • +16
              F*uck the system

              здесь надо отметить фееричное цензурирование
              • 0
                Интересно, а если такому симфоническому оркестру скормить night of nights (которая impossible piano version), что получится?
                • 0
                  этой штуке еще можно вокал скормить как здесь (начало трека со второй минуты)
                  • 0
                    Я так понимаю, что флоппики можно заменить шаговыми моторами с тем же эффектом?
                    • +1
                      На чистых шаговиках немножко не то. Тут, видимо, играет роль еще железный обвес резонирующий.

                    • 0
                      У вас скорее Apocalyptica получилась.
                      www.youtube.com/watch?v=weStzJV8ZTo
                        • +3
                          Просто отсавлю это здесь
                        • +4
                          Ждем Бетховена на матричный принтерах ;)
                        • +3
                          Более всего при прочтении заинтересовал вопрос: а не согласился ли бы автор опубликовать туториал, как за час склепать в домашних условиях двустороннюю печатную плату, причем еще и с паяльной маской, и с шелкографией? Думаю, хабрасообществу это было бы интересно — например, мой навык общения с фоторезистом пока еще недостаточно прокачан.
                          • 0
                            С шёлком и маской? Никак.
                            • 0
                              Рендереная картинка с изображением желаемой платы меня дезориентировала. Эх, а я так надеялся, что существует некий дзен, с помощью которого можно вывести производство печаток в домашних условиях на качественно новый уровень :(
                          • 0
                            А звучит так же тяжело, как и в оригинале :3
                            • +1
                              Вот бы еще такое сыграть на бензопилах и динамитных шашках…

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.