//Lštklaus Toysequenzer Firmware; Waldschuetz&Wessolek a.k.a. Loetbert Shanghai 2007 //released under GPLv3 //so far only poorly commented... volatile boolean channelOneToFour[4][128]; volatile byte pwmArray[2][128]; volatile int pwmIn[2] = {2,3}; volatile int bpmSelector = 4; volatile int pwmOut[2] = {9,10}; volatile int channelButtons[4] = {11,12,13,14}; volatile int modeButtons[3] = {7,8,15}; //REC, DEL, MUTE volatile int instrumentsOut[4] = {3,4,5,6}; volatile boolean stateChannelButtons[4] = {0,0,0,0}; volatile boolean lastStateChannelButtons[4] = {0,0,0,0}; volatile byte clickCounter = 0; volatile boolean stateMode[4] = {0,0,0,0}; // Rec (overdub) , del, mute, override volatile boolean lastStateMode[4] = {0,0,0,0}; volatile byte clickLength = 0; volatile byte bpmCount = 0; volatile int bpmLightOut = 1; volatile boolean bpmState = HIGH; volatile boolean muteChannelOneToFour[4] = {0,0,0,0}; volatile byte takt = 0; volatile byte lastPwmValue[2] = {0,0}; volatile boolean pwmMode[2] = {LOW, LOW}; volatile byte pwmValue[2]; volatile byte delayTime = 60; volatile byte overdubChannel = 255; volatile boolean pwmMute[2] = {LOW, LOW}; void rec() { for (int i = 0; i < 4; i++) { if (stateMode[0]) //mode: rec; override or overdub { if ((i<2) && pwmMode[i]) pwmArray[i][clickCounter] = pwmValue[i]; //* if ((stateMode[3]&&(i==overdubChannel)) || stateChannelButtons[i]) //wenn override oder knopf gedrźckt channelOneToFour[i][clickCounter] = stateChannelButtons[i]; } else if (stateMode[1]){ //mode: delete; if (stateChannelButtons[i]) channelOneToFour[i][clickCounter] = LOW; } } } void play() { for (int i = 0; i < 4; i++) { if (i<2) { if (!pwmMute[i]) { analogWrite(pwmOut[i], pwmArray[i][clickCounter]); } else { analogWrite(pwmOut[i], pwmValue[i]); } } if (((stateChannelButtons[i] && ((!stateMode[1]) || (!stateMode[2]))) || channelOneToFour[i][clickCounter] ) && !muteChannelOneToFour[i]) { digitalWrite(instrumentsOut[i], HIGH); } else if (!(stateChannelButtons[i] && (lastStateChannelButtons[i]==stateChannelButtons[i]))) //difference to last time... { digitalWrite(instrumentsOut[i], LOW); } } } void click() { if (bpmState) delayTime = (byte)(255-(analogRead(bpmSelector)/4)); for (int i = 0; i < 2; i++) { pwmValue[i] = (byte)(analogRead(pwmIn[i])/10); //adjust pwm value } for (int i = 0; i < 4; i++) { stateChannelButtons[i] = digitalRead(channelButtons[i]); if (overdubChannel == 255) //overdub { if (stateChannelButtons[i]) overdubChannel=i; } if (i==3) { stateMode[i] = stateMode[0] & stateMode[1]; } else { stateMode[i] = digitalRead(modeButtons[i]); } } if (stateMode[3] && !lastStateMode[3]) overdubChannel = 255; if (stateMode[0] || stateMode[1]) { for (int i = 0; i < 2; i++) { if (pwmMode[i] || (lastPwmValue[i] =! pwmValue[i])) { pwmMode[i] = HIGH; } } rec(); } else { for (int i = 0; i < 2; i++) { pwmMode[i] = 0; } if (stateMode[2]) //mute { for (int i = 0; i < 2; i++) { if (pwmMute[i] || (lastPwmValue[i] =! pwmValue[i])) { pwmMute[i] = HIGH; } } for (int i = 0; i < 4; i++) { if (!(lastStateChannelButtons[i]==stateChannelButtons[i])) { //if (!muteChannelOneToFour[i]) {muteChannelOneToFour[i] = (!(stateChannelButtons[i] & muteChannelOneToFour[i]));} //NAND*?? if (stateChannelButtons[i]) muteChannelOneToFour[i] = !muteChannelOneToFour[i]; } } } else { pwmMute[0] = LOW; pwmMute[1] = LOW; } } play(); bpmLight(); if (clickCounter<127) {clickCounter++;} else {clickCounter=0;} for (int i = 0; i < 4; i++) //copy stateChannelArray { lastStateMode[i] = stateMode[i]; lastStateChannelButtons[i] = stateChannelButtons[i]; } for (int i = 0; i < 2; i++) { lastPwmValue[i] = pwmValue[i]; //* } } void bpmLight() { if (bpmCount==0) digitalWrite(bpmLightOut, HIGH); if (bpmCount==1 && takt!=0) digitalWrite(bpmLightOut, LOW); if (bpmCount==7) digitalWrite(bpmLightOut, LOW); bpmCount++; if (bpmCount==8) bpmCount=0; takt++; if (takt==4) takt=0; } void clickInterrupt() { if (bpmState) { bpmState = LOW; } click(); } void setup() { pinMode(bpmLightOut, OUTPUT); for (int i = 0; i < 4; i++) { if (i<2) pinMode(pwmOut[i], OUTPUT); //* if (i<3) pinMode(modeButtons[i], INPUT); pinMode(channelButtons[i], INPUT); pinMode(instrumentsOut[i], OUTPUT); } pinMode(2, INPUT); attachInterrupt(0, clickInterrupt, RISING); } void loop() { if (bpmState) { delay(delayTime); click(); } }