[Из песочницы] MIDI плеер на восьми Floppy. Или как электронщик с ума сходил
Как-то раз посмотрел я видео о поющих флопах и на гору списанных компов. Решил сделать что-то подобное.
Делать на Arduino как остальные? Да вы что, серьёзно? F*uck the system, как говорится! Решено было делать на Atmega8A, потому что только она и была под рукой. Провода тоже для слабаков, поэтому я отыскал HC-05 (зачем лишние сопли?).
Поехали!
СхемаПервый этап, как обычно, схема. С ней проблем нет.
Она простая и без лишних наворотов.
Плата Плата тоже делается без особого напряжения при помощи фоторезиста. Раскидал за 10 минут и изготовил за час.Разводка платы Пишем код Теперь самое интересное — программирование. Писать решил на C, дабы сэкономить время. Но не успел начать, как уже грабли.Грабли заключаются в управлении флопами. Как известно, если Direct pin = 0, а на Step давать импульсы, то флоп шагает вперёд, а если Direct pin = 1, то назад, но у флопа всего 80 шагов. Мало, что делать? Решение простое. Флоп умеет делать полшага, если просто менять состояние Step, а не пульсировать его. Делать это лучше так:
Step ^= (1< 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< Да, можно и без блюпупа, это просто моя заморочка. Выбираем миди-файл иии… [embedded content] Исходники
Исходники + прошивка.