initial commit
This commit is contained in:
commit
4e8ded22bb
114
Arduino/Moppy.pde
Normal file
114
Arduino/Moppy.pde
Normal file
|
@ -0,0 +1,114 @@
|
|||
boolean firstRun = true; // Used for one-run-only stuffs;
|
||||
|
||||
const byte FIRST_PIN = 2;
|
||||
const byte PIN_MAX = 9;
|
||||
|
||||
byte MAX_POSITION[] = {
|
||||
0,0,79,0,79,0,79,0,49,0};
|
||||
byte currentPosition[] = {
|
||||
0,0,0,0,0,0,0,0,0,0};
|
||||
boolean stepDirection[] = {
|
||||
false,false,false,false,false,false,false,false,false,false}; // false = forward, true=reverse (i.e. true=HIGH)
|
||||
unsigned int currentPeriod[] = {
|
||||
0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
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 5
|
||||
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
|
||||
void loop(){
|
||||
if (firstRun)
|
||||
{
|
||||
firstRun = false;
|
||||
resetAll();
|
||||
delay(2000);
|
||||
//runOnce();
|
||||
}
|
||||
|
||||
if (Serial.available() > 2){
|
||||
if (Serial.peek() == 100) {
|
||||
resetAll();
|
||||
Serial.flush();
|
||||
}
|
||||
else{
|
||||
currentPeriod[Serial.read()] = (Serial.read() << 8) | Serial.read();
|
||||
}
|
||||
}
|
||||
|
||||
voice();
|
||||
}
|
||||
|
||||
void voice()
|
||||
{
|
||||
if (currentPeriod[2] > 0 && micros()%currentPeriod[2] < 100){
|
||||
stepPin(2,3,4);
|
||||
}
|
||||
if (currentPeriod[4] > 0 && micros()%currentPeriod[4] < 100){
|
||||
stepPin(4,5,4);
|
||||
}
|
||||
if (currentPeriod[6] > 0 && micros()%currentPeriod[6] < 100){
|
||||
stepPin(6,7,4);
|
||||
}
|
||||
if (currentPeriod[8] > 0 && micros()%currentPeriod[8] < 100){
|
||||
stepPin(8,9,4);
|
||||
}
|
||||
}
|
||||
|
||||
void stepPin(byte pin, byte control_pin, byte wait) {
|
||||
if (currentPosition[pin] >= MAX_POSITION[pin]) {
|
||||
stepDirection[pin] = true;
|
||||
}
|
||||
if (currentPosition[pin] <= 0) {
|
||||
stepDirection[pin] = false;
|
||||
}
|
||||
if (stepDirection[pin]){
|
||||
digitalWrite(control_pin,HIGH);
|
||||
currentPosition[pin]--;
|
||||
}
|
||||
else {
|
||||
digitalWrite(control_pin,LOW);
|
||||
currentPosition[pin]++;
|
||||
}
|
||||
digitalWrite(pin,HIGH);
|
||||
delayMicroseconds(wait);
|
||||
digitalWrite(pin,LOW);
|
||||
}
|
||||
|
||||
void blinkLED(){
|
||||
digitalWrite(13, HIGH); // set the LED on
|
||||
delay(250); // wait for a second
|
||||
digitalWrite(13, LOW);
|
||||
}
|
||||
|
||||
void reset(byte pin)
|
||||
{
|
||||
digitalWrite(pin+1,HIGH); // Go in reverse
|
||||
for (byte s=0;s<MAX_POSITION[pin];s++){
|
||||
digitalWrite(pin,HIGH);
|
||||
digitalWrite(pin,LOW);
|
||||
delay(5);
|
||||
}
|
||||
currentPosition[pin] = 0; // We're reset.
|
||||
stepDirection[pin] = false; // Ready to go forward.
|
||||
}
|
||||
|
||||
void resetAll(){
|
||||
for (byte p=FIRST_PIN;p<=PIN_MAX;p+=2){
|
||||
reset(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
BIN
Java/lib/RXTXcomm.jar
Normal file
BIN
Java/lib/RXTXcomm.jar
Normal file
Binary file not shown.
BIN
Java/lib/themidibus.jar
Normal file
BIN
Java/lib/themidibus.jar
Normal file
Binary file not shown.
26
Java/src/moppydesk/MIDINotes.java
Normal file
26
Java/src/moppydesk/MIDINotes.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package moppydesk;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sam
|
||||
*/
|
||||
public class MIDINotes {
|
||||
|
||||
public static int[] microPeriods = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,21622,20409,19263,18182,17161,16198, //C1 - B1
|
||||
15289,14436,13621,12856,12135,11454,10811,10205,9632,9091,8581,8099, //C2 - B2
|
||||
7645,7218,6811,6428,6068,5727,5406,5103,4816,4546,4291,4050, //C3 - B3
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
}
|
105
Java/src/moppydesk/Main.java
Normal file
105
Java/src/moppydesk/Main.java
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package moppydesk;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sam
|
||||
*/
|
||||
import gnu.io.NoSuchPortException;
|
||||
import gnu.io.PortInUseException;
|
||||
import gnu.io.UnsupportedCommOperationException;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.sound.midi.InvalidMidiDataException;
|
||||
import javax.sound.midi.MidiSystem;
|
||||
import javax.sound.midi.MidiUnavailableException;
|
||||
import javax.sound.midi.Sequence;
|
||||
import javax.sound.midi.Sequencer;
|
||||
|
||||
public class Main {
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
MoppyBridge mb = null;
|
||||
MoppyPlayer mp = null;
|
||||
|
||||
try {
|
||||
mb = new MoppyBridge("COM3");
|
||||
mp = new MoppyPlayer(mb);
|
||||
|
||||
mb.resetDrives();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Sequence sequence = MidiSystem.getSequence(new File("songs/ImperialMarch.mid"));
|
||||
|
||||
final Sequencer sequencer = MidiSystem.getSequencer(false);
|
||||
|
||||
new Thread(){
|
||||
@Override
|
||||
public void run(){
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
|
||||
while (true){
|
||||
try {
|
||||
if (br.readLine().equalsIgnoreCase("exit")) {
|
||||
System.exit(0);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
sequencer.open();
|
||||
sequencer.setSequence(sequence);
|
||||
sequencer.setTempoInBPM(110);
|
||||
System.out.println(sequence.getTracks().length);
|
||||
sequencer.getTransmitter().setReceiver(mp);
|
||||
|
||||
sequencer.start();
|
||||
while (sequencer.isRunning()){
|
||||
Thread.sleep(3000);
|
||||
}
|
||||
sequencer.close();
|
||||
|
||||
} catch (MidiUnavailableException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (InvalidMidiDataException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (NoSuchPortException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (PortInUseException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (UnsupportedCommOperationException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
|
||||
if (mb != null){
|
||||
mb.resetDrives();
|
||||
mb.close();
|
||||
}
|
||||
if (mp != null){
|
||||
mp.close();
|
||||
}
|
||||
}
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
85
Java/src/moppydesk/MoppyBridge.java
Normal file
85
Java/src/moppydesk/MoppyBridge.java
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package moppydesk;
|
||||
|
||||
import gnu.io.CommPortIdentifier;
|
||||
import gnu.io.NoSuchPortException;
|
||||
import gnu.io.PortInUseException;
|
||||
import gnu.io.SerialPort;
|
||||
import gnu.io.UnsupportedCommOperationException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sam
|
||||
*/
|
||||
public class MoppyBridge {
|
||||
|
||||
int SERIAL_RATE = 9600;
|
||||
OutputStream os;
|
||||
SerialPort com;
|
||||
|
||||
public MoppyBridge(String portName) throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException, IOException {
|
||||
CommPortIdentifier cpi = CommPortIdentifier.getPortIdentifier(portName);
|
||||
com = (SerialPort) cpi.open("MoppyDesk", 2000);
|
||||
com.setSerialPortParams(SERIAL_RATE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
|
||||
os = com.getOutputStream();
|
||||
}
|
||||
|
||||
public void sendEvent(byte pin, int periodData){
|
||||
sendEvent(pin, (byte)((periodData >> 8) & 0xFF), (byte)(periodData & 0xFF));
|
||||
}
|
||||
|
||||
public void sendEvent(byte pin, byte b1, byte b2){
|
||||
sendArray(new byte[] {pin, b1, b2});
|
||||
}
|
||||
|
||||
private void sendArray(byte[] message){
|
||||
try {
|
||||
os.write(message);
|
||||
os.flush();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(MoppyBridge.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void silenceDrives(){
|
||||
// Stop notes
|
||||
for (int d=2;d<=6;d+=2){
|
||||
sendArray(new byte[] {(byte)d,(byte)0,(byte)0});
|
||||
}
|
||||
}
|
||||
|
||||
public void resetDrives(){
|
||||
silenceDrives();
|
||||
//Send reset code
|
||||
sendArray(new byte[] {(byte)100,(byte)0,(byte)0});
|
||||
try {
|
||||
Thread.sleep(1500); // Give the drives time to reset
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(MoppyBridge.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void close(){
|
||||
silenceDrives();
|
||||
if (os != null){
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(MoppyBridge.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (com != null){
|
||||
com.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
52
Java/src/moppydesk/MoppyPlayer.java
Normal file
52
Java/src/moppydesk/MoppyPlayer.java
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package moppydesk;
|
||||
|
||||
import gnu.io.SerialPort;
|
||||
import javax.sound.midi.MidiMessage;
|
||||
import javax.sound.midi.Receiver;
|
||||
/**
|
||||
*
|
||||
* @author Sam
|
||||
*/
|
||||
public class MoppyPlayer implements Receiver {
|
||||
|
||||
public static int[] microPeriods = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
30578,28861,27242,25713,24270,20409,21622,20409,19263,18182,17161,16198, //C1 - B1
|
||||
15289,14436,13621,12856,12135,11454,10811,10205,9632,9091,8581,8099, //C2 - B2
|
||||
7645,7218,6811,6428,6068,5727,5406,5103,4816,4546,4291,4050, //C3 - B3
|
||||
3823,3609,3406,3214,3034,2864,2703,2552,2408,2273,2146,2025, //C4 - B4
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
MoppyBridge mb;
|
||||
SerialPort com;
|
||||
|
||||
public MoppyPlayer(MoppyBridge newMb) {
|
||||
mb = newMb;
|
||||
}
|
||||
|
||||
public void close(){
|
||||
mb.close();
|
||||
}
|
||||
|
||||
public void send(MidiMessage message, long timeStamp) {
|
||||
if (message.getStatus() > 127 && message.getStatus() < 144){ // Note OFF
|
||||
byte pin = (byte)(2*(message.getStatus() - 127));
|
||||
//System.out.println("Got note OFF on pin: " + (channel & 0xFF));
|
||||
mb.sendEvent(pin, 0);
|
||||
}
|
||||
else if (message.getStatus() > 143 && message.getStatus() < 160){ // Note ON
|
||||
byte pin = (byte)(2*(message.getStatus() - 143));
|
||||
int period = microPeriods[(message.getMessage()[1] & 0xff)];
|
||||
//System.out.println("Got note ON on pin: " + (pin & 0xFF) + " with period " + period);
|
||||
mb.sendEvent(pin, period);
|
||||
}
|
||||
}
|
||||
}
|
67
Java/src/moppydesk/MoppyPlayer1.java
Normal file
67
Java/src/moppydesk/MoppyPlayer1.java
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package moppydesk;
|
||||
|
||||
import gnu.io.CommPortIdentifier;
|
||||
import gnu.io.NoSuchPortException;
|
||||
import gnu.io.PortInUseException;
|
||||
import gnu.io.SerialPort;
|
||||
import gnu.io.UnsupportedCommOperationException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.sound.midi.ControllerEventListener;
|
||||
import javax.sound.midi.InvalidMidiDataException;
|
||||
import javax.sound.midi.MidiMessage;
|
||||
import javax.sound.midi.Receiver;
|
||||
import javax.sound.midi.ShortMessage;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sam
|
||||
*/
|
||||
public class MoppyPlayer1 implements Receiver {
|
||||
|
||||
OutputStream os;
|
||||
SerialPort com;
|
||||
|
||||
public MoppyPlayer1(String portName) throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException, IOException {
|
||||
CommPortIdentifier cpi = CommPortIdentifier.getPortIdentifier(portName);
|
||||
com = (SerialPort) cpi.open("MoppyDesk", 2000);
|
||||
com.setSerialPortParams(31250, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
|
||||
os = com.getOutputStream();
|
||||
}
|
||||
|
||||
public void close(){
|
||||
if (os!=null){
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(MoppyPlayer1.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
if (com!=null){
|
||||
com.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void send(MidiMessage message, long timeStamp) {
|
||||
if (message.getStatus() > 127 && message.getStatus() < 160){
|
||||
try {
|
||||
ShortMessage sm = (ShortMessage) message;
|
||||
//System.out.println(sm.getChannel());
|
||||
//TODO Channels start at 0??
|
||||
sm.setMessage(sm.getStatus()+1, sm.getData1(), sm.getData2()); //Try shifting channel
|
||||
os.write(sm.getMessage());
|
||||
} catch (InvalidMidiDataException ex) {
|
||||
Logger.getLogger(MoppyPlayer1.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(MoppyPlayer1.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user