Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimized the Arduino and Java code to adjust FIRST_PIN and PIN_MAX easily #70

Open
wants to merge 2 commits into
base: moppy-advanced
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 63 additions & 94 deletions Arduino/Moppy/Moppy.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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
Expand Down Expand Up @@ -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;
}
}
}

Expand Down Expand Up @@ -249,4 +218,4 @@ void resetAll(){
currentState[p+1] = 0; // Ready to go forward.
}

}
}
6 changes: 3 additions & 3 deletions Java/MoppyDesk/src/moppydesk/outputs/MoppyPlayerOutput.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ 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);
currentPeriod[message.getStatus() - 128] = 0;
} 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
Expand Down Expand Up @@ -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);

Expand Down