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