Project in progress

Bluetooth MIDI-Operated Antique Reed Organ © GPL3+

Antique reed organ + solenoids + custom driver boards + 3 Arduino Megas + Bluetooth = MIDI-driven reed organ

  • 3,759 views
  • 1 comment
  • 15 respects

Components and supplies

Ardgen mega
Arduino Mega 2560 & Genuino Mega 2560
×3
ZYE1-0530 Solenoid
×88
Custom Solenoid Driver Board
Design files attached. I manufactured 15@ FirstPCB.com for a total cost of $50 shipped.
×1
IRLZ-44N MOSFET
×1
Resistor 220 Ohm
×1
HC-06 Bluetooth Serial COM Reciever
×1

Apps and online services

Hairless MIDI < - > Serial Bridge
This software allows us to send MIDI data from any application on your computer to a serial port, in this case the Bluetooth reciever, which the Arduinos then respond to.

About this project

This page was used for a brief description of the project before I published it on Instructables.com. Please view the much more detailed Instructable here: https://www.instructables.com/id/MIDI-Controlled-88-Key-Reed-Organ/

For my high-school senior project, I was going to convert an upright piano to be a MIDI-controlled player piano. However, I by chance ran across a reed organ, and knowing nothing about them became very interested in their sound and history. So I instead converted an Estey Reed organ to be MIDI operated. This is the result.

For now, just the keys are MIDI controlled. I plan on adding a vacuum motor so it doesn't have to be foot pumped, as well as control of the stops on the cheekblocks.

I am currently writing a very detailed Instructable. For now, here are some photos and some demo videos.

Demo playlist here: https://www.youtube.com/watch?v=36Er-6ZRR6Q&list=PLbli1gTIi5kp9_iqoVi0sN5cbYPDn0naH

Suggest a song or upload a MIDI file for it to play here: http://bit.ly/2wR3QUE

Schematics

16-Channel MOSFET Solenoid Driver Board
Please note that using this file you can't actually solder in the MOSFETs; the holes are just big enough to jam them in. This makes them easier to replace.
solenoid_driver_board_v4_LbLvMU6CF4.fzz

Code

Arduino #1Arduino
For the left-most Arduino
byte incomingByte;
byte note;
byte velocity;

int statusLed = 13;   // select the pin for the LED

int action = 2; //0 =note off ; 1=note on ; 2= nada

//setup: declaring iputs and outputs and begin serial
void setup() {
  pinMode(statusLed, OUTPUT);  // declare the LED's pin as output

  int inMin = 22; // Lowest input pin
  int inMax = 53; // Highest input pin
  for (int i = inMin; i <= inMax; i++) {
    pinMode(i, OUTPUT);
  }

  Serial1.begin(38400);
  digitalWrite(statusLed, HIGH);
}

//loop: wait for serial data, and interpret the message
void loop () {
  if (Serial1.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial1.read();

    // wait for as status-byte, channel 1, note on or off
    if (incomingByte == 144) { // note on message starting starting
      action = 1;
    } else if (incomingByte == 128) { // note off message starting
      action = 0;
    } else if (incomingByte == 208) { // aftertouch message starting
      //not implemented yet
    } else if (incomingByte == 160) { // polypressure message starting
      //not implemented yet
    } else if ( (action == 0) && (note == 0) ) { // if we received a "note off", we wait for which note (databyte)
      note = incomingByte;
      playNote(note, 0);
      note = 0;
      velocity = 0;
      action = 2;
    } else if ( (action == 1) && (note == 0) ) { // if we received a "note on", we wait for the note (databyte)
      note = incomingByte;
    } else if ( (action == 1) && (note != 0) ) { // ...and then the velocity
      velocity = incomingByte;
      playNote(note, velocity);
      note = 0;
      velocity = 0;
      action = 0;
    } else {
      //nada
    }
  }
}

void blink() {
  digitalWrite(statusLed, HIGH);
  delay(100);
  digitalWrite(statusLed, LOW);
  delay(100);
}


void playNote(byte note, byte velocity) {
  int value = LOW;
  if (velocity > 10) {
    value = HIGH;
  } else {
    value = LOW;
  }

  if (note > 20 && note < 55) {
    digitalWrite((note + 1), value);
  }
}
Arduino #2Arduino
Center Arduino code. All Arduinos are running essentially the same code, they just respond to different MIDI note ranges.
byte incomingByte;
byte note;
byte velocity;

int statusLed = 13;   // select the pin for the LED

int action = 2; //0 =note off ; 1=note on ; 2= nada

//setup: declaring iputs and outputs and begin serial
void setup() {
  pinMode(statusLed, OUTPUT);  // declare the LED's pin as output

  int inMin = 22; // Lowest input pin
  int inMax = 53; // Highest input pin
  for (int i = inMin; i <= inMax; i++) {
    pinMode(i, OUTPUT);
  }

  Serial1.begin(38400);
  digitalWrite(statusLed, HIGH);
}

//loop: wait for serial data, and interpret the message
void loop () {
  if (Serial1.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial1.read();

    // wait for as status-byte, channel 1, note on or off
    if (incomingByte == 144) { // note on message starting starting
      action = 1;
    } else if (incomingByte == 128) { // note off message starting
      action = 0;
    } else if (incomingByte == 208) { // aftertouch message starting
      //not implemented yet
    } else if (incomingByte == 160) { // polypressure message starting
      //not implemented yet
    } else if ( (action == 0) && (note == 0) ) { // if we received a "note off", we wait for which note (databyte)
      note = incomingByte;
      playNote(note, 0);
      note = 0;
      velocity = 0;
      action = 2;
    } else if ( (action == 1) && (note == 0) ) { // if we received a "note on", we wait for the note (databyte)
      note = incomingByte;
    } else if ( (action == 1) && (note != 0) ) { // ...and then the velocity
      velocity = incomingByte;
      playNote(note, velocity);
      note = 0;
      velocity = 0;
      action = 0;
    } else {
      //nada
    }
  }
}

void blink() {
  digitalWrite(statusLed, HIGH);
  delay(100);
  digitalWrite(statusLed, LOW);
  delay(100);
}


void playNote(byte note, byte velocity) {
  int value = LOW;
  if (velocity > 10) {
    value = HIGH;
  } else {
    value = LOW;
  }

  if (note > 52 && note < 85) {
    digitalWrite((note - 31), value);
  }
}
Arduino #3Arduino
Right Arduino. All Arduinos are running essentially the same code, they just respond to different MIDI note ranges.
byte incomingByte;
byte note;
byte velocity;

int statusLed = 13;   // select the pin for the LED

int action = 2; //0 =note off ; 1=note on ; 2= nada

//setup: declaring iputs and outputs and begin serial
void setup() {
  pinMode(statusLed, OUTPUT);  // declare the LED's pin as output

  int inMin = 22; // Lowest input pin
  int inMax = 53; // Highest input pin
  for (int i = inMin; i <= inMax; i++) {
    pinMode(i, OUTPUT);
  }

  Serial1.begin(38400);
  digitalWrite(statusLed, LOW);
}

//loop: wait for serial data, and interpret the message
void loop () {
  if (Serial1.available() > 0) {
    digitalWrite(statusLed, HIGH);
    // read the incoming byte:
    incomingByte = Serial1.read();

    // wait for as status-byte, channel 1, note on or off
    if (incomingByte == 144) { // note on message starting starting
      action = 1;
    } else if (incomingByte == 128) { // note off message starting
      action = 0;
    } else if (incomingByte == 208) { // aftertouch message starting
      //not implemented yet
    } else if (incomingByte == 160) { // polypressure message starting
      //not implemented yet
    } else if ( (action == 0) && (note == 0) ) { // if we received a "note off", we wait for which note (databyte)
      note = incomingByte;
      playNote(note, 0);
      note = 0;
      velocity = 0;
      action = 2;
    } else if ( (action == 1) && (note == 0) ) { // if we received a "note on", we wait for the note (databyte)
      note = incomingByte;
    } else if ( (action == 1) && (note != 0) ) { // ...and then the velocity
      velocity = incomingByte;
      playNote(note, velocity);
      note = 0;
      velocity = 0;
      action = 0;
    } else {
      //nada
    }
  }
}

void blink() {
  digitalWrite(statusLed, HIGH);
  delay(100);
  digitalWrite(statusLed, LOW);
  delay(100);
}


void playNote(byte note, byte velocity) {
  int value = LOW;
  if (velocity > 10) {
    value = HIGH;
  } else {
    value = LOW;
  }

  if (note > 84 && note < 109) {
    digitalWrite((note - 63), value);
  }
}

Comments

Author

Img 0090 le0uxpbogy
Willem Hillier
  • 1 project
  • 3 followers

Additional contributors

  • Original midi decoding arduino code. i adapted this code for my purposes. by leKuk

Published on

August 23, 2017

Members who respect this project

19554588 1057217297743471 4511343257016951103 n ldhz05imngDefault12540590 741555235974555 3535889509737692135 n u3tbvajh6h10929194 1382483805394361 4703421211523115453 nDefault25 04 2012  10 23 18   foto 2Johan ha

and 8 others

See similar projects
you might like

Similar projects you might like

Integrate Node-Red with RAK811 LoRA node using the TTN

Project tutorial by Naresh krish

  • 245 views
  • 0 comments
  • 4 respects

In Servo We Trust!

Project tutorial by Maya

  • 1,319 views
  • 0 comments
  • 7 respects

Flying Drone Mjolnir With Hacked RC Transmitter

Project in progress by Allen Pan

  • 7,150 views
  • 0 comments
  • 30 respects

Fox Advisor

Project tutorial by Celia Garrido Hidalgo

  • 1,306 views
  • 0 comments
  • 7 respects

Remote System Monitor

Project tutorial by Stephen Harrison

  • 2,776 views
  • 0 comments
  • 7 respects

[App Inventor IoT ]LED fading (PWM)

Project tutorial by CAVEDU Education

  • 328 views
  • 0 comments
  • 5 respects
Add projectSign up / Login