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.

Code

Arduino #1Arduino

For the left-most Arduino

byteincomingByte;bytenote;bytevelocity;intstatusLed=13;// select the pin for the LEDintaction=2;//0 =note off ; 1=note on ; 2= nada//setup: declaring iputs and outputs and begin serialvoidsetup(){pinMode(statusLed,OUTPUT);// declare the LED's pin as outputintinMin=22;// Lowest input pinintinMax=53;// Highest input pinfor(inti=inMin;i<=inMax;i++){pinMode(i,OUTPUT);}Serial1.begin(38400);digitalWrite(statusLed,HIGH);}//loop: wait for serial data, and interpret the messagevoidloop(){if(Serial1.available()>0){// read the incoming byte:incomingByte=Serial1.read();// wait for as status-byte, channel 1, note on or offif(incomingByte==144){// note on message starting startingaction=1;}elseif(incomingByte==128){// note off message startingaction=0;}elseif(incomingByte==208){// aftertouch message starting//not implemented yet}elseif(incomingByte==160){// polypressure message starting//not implemented yet}elseif((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;}elseif((action==1)&&(note==0)){// if we received a "note on", we wait for the note (databyte)note=incomingByte;}elseif((action==1)&&(note!=0)){// ...and then the velocityvelocity=incomingByte;playNote(note,velocity);note=0;velocity=0;action=0;}else{//nada}}}voidblink(){digitalWrite(statusLed,HIGH);delay(100);digitalWrite(statusLed,LOW);delay(100);}voidplayNote(bytenote,bytevelocity){intvalue=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.

byteincomingByte;bytenote;bytevelocity;intstatusLed=13;// select the pin for the LEDintaction=2;//0 =note off ; 1=note on ; 2= nada//setup: declaring iputs and outputs and begin serialvoidsetup(){pinMode(statusLed,OUTPUT);// declare the LED's pin as outputintinMin=22;// Lowest input pinintinMax=53;// Highest input pinfor(inti=inMin;i<=inMax;i++){pinMode(i,OUTPUT);}Serial1.begin(38400);digitalWrite(statusLed,HIGH);}//loop: wait for serial data, and interpret the messagevoidloop(){if(Serial1.available()>0){// read the incoming byte:incomingByte=Serial1.read();// wait for as status-byte, channel 1, note on or offif(incomingByte==144){// note on message starting startingaction=1;}elseif(incomingByte==128){// note off message startingaction=0;}elseif(incomingByte==208){// aftertouch message starting//not implemented yet}elseif(incomingByte==160){// polypressure message starting//not implemented yet}elseif((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;}elseif((action==1)&&(note==0)){// if we received a "note on", we wait for the note (databyte)note=incomingByte;}elseif((action==1)&&(note!=0)){// ...and then the velocityvelocity=incomingByte;playNote(note,velocity);note=0;velocity=0;action=0;}else{//nada}}}voidblink(){digitalWrite(statusLed,HIGH);delay(100);digitalWrite(statusLed,LOW);delay(100);}voidplayNote(bytenote,bytevelocity){intvalue=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.

byteincomingByte;bytenote;bytevelocity;intstatusLed=13;// select the pin for the LEDintaction=2;//0 =note off ; 1=note on ; 2= nada//setup: declaring iputs and outputs and begin serialvoidsetup(){pinMode(statusLed,OUTPUT);// declare the LED's pin as outputintinMin=22;// Lowest input pinintinMax=53;// Highest input pinfor(inti=inMin;i<=inMax;i++){pinMode(i,OUTPUT);}Serial1.begin(38400);digitalWrite(statusLed,LOW);}//loop: wait for serial data, and interpret the messagevoidloop(){if(Serial1.available()>0){digitalWrite(statusLed,HIGH);// read the incoming byte:incomingByte=Serial1.read();// wait for as status-byte, channel 1, note on or offif(incomingByte==144){// note on message starting startingaction=1;}elseif(incomingByte==128){// note off message startingaction=0;}elseif(incomingByte==208){// aftertouch message starting//not implemented yet}elseif(incomingByte==160){// polypressure message starting//not implemented yet}elseif((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;}elseif((action==1)&&(note==0)){// if we received a "note on", we wait for the note (databyte)note=incomingByte;}elseif((action==1)&&(note!=0)){// ...and then the velocityvelocity=incomingByte;playNote(note,velocity);note=0;velocity=0;action=0;}else{//nada}}}voidblink(){digitalWrite(statusLed,HIGH);delay(100);digitalWrite(statusLed,LOW);delay(100);}voidplayNote(bytenote,bytevelocity){intvalue=LOW;if(velocity>10){value=HIGH;}else{value=LOW;}if(note>84&&note<109){digitalWrite((note-63),value);}}