diff --git a/Arduino/Moppy/Moppy.ino b/Arduino/Moppy/Moppy.ino index 75575dc..5b53318 100644 --- a/Arduino/Moppy/Moppy.ino +++ b/Arduino/Moppy/Moppy.ino @@ -2,9 +2,14 @@ boolean firstRun = true; // Used for one-run-only stuffs; -//First pin being used for floppies, and the last pin. Used for looping over all pins. -const byte FIRST_PIN = 2; -const byte PIN_MAX = 17; +/*First pin being used for floppies, and the last pin. Used for looping over all pins. + Depending on your Arduino microcontroller you can adjust FIRST_PIN and PIN_MAX value. + If you want to use more or less than 8 midi channels or if you want to start with a + different pin than pin 2. If you want to use different values than 2 and 17 you must + adjust your Java code too and implement a offset functionality. + */ +const byte FIRST_PIN = 2; //Possible values: 2,4,6,... +const byte PIN_MAX = 17; //Possible values: 3,5,7,... (MUST be higher than FIRST_PIN) #define RESOLUTION 40 //Microsecond resolution for notes @@ -14,58 +19,69 @@ const byte PIN_MAX = 17; for pin 2 will be stored in index 2, and information for pin 4 will be stored in index 4.*/ - /*An array of maximum track positions for each step-control pin. Even pins are used for control, so only even numbers need a value here. 3.5" Floppies have 80 tracks, 5.25" have 50. These should be doubled, because each tick is now - half a position (use 158 and 98). + half a position (use 158 and 98). If you want to use just 3.5" Floppies, set + FDD_TYPE to 158 and if you want to use just 5.25" Floppies, set it to 98. In the + special case of a mixed environment with 3.5" and 5.25" Floppies, some additional + adjustments are needed. Then you need to remove 'byte MAX_POSITION[PIN_MAX + 1];', + 'const byte FDD_TYPE = 158;' and the whole MAX_POSITION if-else block in the setup() + method. Plus you need to add 'byte MAX_POSITION[] = {0,0,158,0,...,98,0};' right + here with MAX_PIN + 1 entries where all numbers smaller than FIRST_PIN must be 0, + all even numbers must be filled with 158 (3.5" Floppy) or 98 (5.25" Floppy). */ -byte MAX_POSITION[] = { - 0,0,158,0,158,0,158,0,158,0,158,0,158,0,158,0,158,0}; +byte MAX_POSITION[PIN_MAX + 1]; +const byte FDD_TYPE = 158; //Possible values: 158 (3.5" Floppies) and 98 (5.25" Floppies) //Array to track the current position of each floppy head. (Only even indexes (i.e. 2,4,6...) are used) -byte currentPosition[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +byte currentPosition[PIN_MAX + 1]; /*Array to keep track of state of each pin. Even indexes track the control-pins for toggle purposes. Odd indexes track direction-pins. LOW = forward, HIGH=reverse */ -int currentState[] = { - 0,0,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW -}; +int currentState[PIN_MAX + 1]; //Current period assigned to each pin. 0 = off. Each period is of the length specified by the RESOLUTION //variable above. i.e. A period of 10 is (RESOLUTION x 10) microseconds long. -unsigned int currentPeriod[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; +unsigned int currentPeriod[PIN_MAX + 1]; //Current tick -unsigned int currentTick[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; +unsigned int currentTick[PIN_MAX + 1]; - -//Setup pins (Even-odd pairs for step control and direction void setup(){ - pinMode(13, OUTPUT);// Pin 13 has an LED connected on most Arduino boards - pinMode(2, OUTPUT); // Step control 1 - pinMode(3, OUTPUT); // Direction 1 - pinMode(4, OUTPUT); // Step control 2 - pinMode(5, OUTPUT); // Direction 2 - pinMode(6, OUTPUT); // Step control 3 - pinMode(7, OUTPUT); // Direction 3 - pinMode(8, OUTPUT); // Step control 4 - pinMode(9, OUTPUT); // Direction 4 - pinMode(10, OUTPUT); // Step control 5 - pinMode(11, OUTPUT); // Direction 5 - pinMode(12, OUTPUT); // Step control 6 - pinMode(13, OUTPUT); // Direction 6 - pinMode(14, OUTPUT); // Step control 7 - pinMode(15, OUTPUT); // Direction 7 - pinMode(16, OUTPUT); // Step control 8 - pinMode(17, OUTPUT); // Direction 8 + + // Initialize all arrays dynamically based on FIRST_PIN and PIN_MAX values. + for (int i = 0; i <= PIN_MAX; i++){ + + // Initialize every pin with 0 + currentPosition[i] = 0; + currentPeriod[i] = 0; + currentTick[i] = 0; + + // Initialize every pin used for floppies with LOW and all others with 0. + if(i < FIRST_PIN){ + currentState[i] = 0; + } + else { + currentState[i] = LOW; + } + + // Initialize every step control pin with a value and all others with 0. + if((i >= FIRST_PIN) && (i % 2 == 0)){ + MAX_POSITION[i] = FDD_TYPE; + } + else { + MAX_POSITION[i] = 0; + } + + } + + // Setup pins (Even-odd pairs for step control and direction) + for (int i = FIRST_PIN; i <= PIN_MAX; i++){ + pinMode(i, OUTPUT); + } Timer1.initialize(RESOLUTION); // Set up a timer at the defined resolution Timer1.attachInterrupt(tick); // Attach the tick function @@ -102,68 +118,21 @@ void loop(){ /* -Called by the timer inturrupt at the specified resolution. +Called by the timer interrupt at the specified resolution. */ void tick() { /* - If there is a period set for control pin 2, count the number of + If there is a period set for control pin 2 (4,6,8...), count the number of ticks that pass, and toggle the pin if the current period is reached. */ - if (currentPeriod[2]>0){ - currentTick[2]++; - if (currentTick[2] >= currentPeriod[2]){ - togglePin(2,3); - currentTick[2]=0; - } - } - if (currentPeriod[4]>0){ - currentTick[4]++; - if (currentTick[4] >= currentPeriod[4]){ - togglePin(4,5); - currentTick[4]=0; - } - } - if (currentPeriod[6]>0){ - currentTick[6]++; - if (currentTick[6] >= currentPeriod[6]){ - togglePin(6,7); - currentTick[6]=0; - } - } - if (currentPeriod[8]>0){ - currentTick[8]++; - if (currentTick[8] >= currentPeriod[8]){ - togglePin(8,9); - currentTick[8]=0; - } - } - if (currentPeriod[10]>0){ - currentTick[10]++; - if (currentTick[10] >= currentPeriod[10]){ - togglePin(10,11); - currentTick[10]=0; - } - } - if (currentPeriod[12]>0){ - currentTick[12]++; - if (currentTick[12] >= currentPeriod[12]){ - togglePin(12,13); - currentTick[12]=0; - } - } - if (currentPeriod[14]>0){ - currentTick[14]++; - if (currentTick[14] >= currentPeriod[14]){ - togglePin(14,15); - currentTick[14]=0; - } - } - if (currentPeriod[16]>0){ - currentTick[16]++; - if (currentTick[16] >= currentPeriod[16]){ - togglePin(16,17); - currentTick[16]=0; + for(int i = FIRST_PIN; i < PIN_MAX; i+=2){ + if (currentPeriod[i]>0){ + currentTick[i]++; + if (currentTick[i] >= currentPeriod[i]){ + togglePin(i,i+1); + currentTick[i]=0; + } } } @@ -249,4 +218,4 @@ void resetAll(){ currentState[p+1] = 0; // Ready to go forward. } -} +} diff --git a/Java/MoppyDesk/src/moppydesk/outputs/MoppyPlayerOutput.java b/Java/MoppyDesk/src/moppydesk/outputs/MoppyPlayerOutput.java index d4904ea..8bf96ac 100644 --- a/Java/MoppyDesk/src/moppydesk/outputs/MoppyPlayerOutput.java +++ b/Java/MoppyDesk/src/moppydesk/outputs/MoppyPlayerOutput.java @@ -57,7 +57,7 @@ public void send(MidiMessage message, long timeStamp) { if (message.getStatus() > 127 && message.getStatus() < 144) { // Note OFF //Convert the MIDI channel being used to the controller pin on the //Arduino by multipying by 2. - byte pin = (byte) (2 * (message.getStatus() - 127)); + byte pin = (byte) (2 * (message.getStatus() - 127) + MoppyCOMBridge.FIRST_PIN - 2); //System.out.println("Got note OFF on pin: " + (pin & 0xFF)); mb.sendEvent(pin, 0); @@ -65,7 +65,7 @@ public void send(MidiMessage message, long timeStamp) { } else if (message.getStatus() > 143 && message.getStatus() < 160) { // Note ON //Convert the MIDI channel being used to the controller pin on the //Arduino by multipying by 2. - byte pin = (byte) (2 * (message.getStatus() - 143)); + byte pin = (byte) (2 * (message.getStatus() - 143) + MoppyCOMBridge.FIRST_PIN - 2); //Get note number from MIDI message, and look up the period. //NOTE: Java bytes range from -128 to 127, but we need to make them @@ -93,7 +93,7 @@ public void send(MidiMessage message, long timeStamp) { if (currentPeriod[message.getStatus() - 224] != 0) { //Convert the MIDI channel being used to the controller pin on the //Arduino by multipying by 2. - byte pin = (byte) (2 * (message.getStatus() - 223)); + byte pin = (byte) (2 * (message.getStatus() - 223) + MoppyCOMBridge.FIRST_PIN - 2); double pitchBend = ((message.getMessage()[2] & 0xff) << 8) + (message.getMessage()[1] & 0xff);