I have done Arduino projects before, like making lightbulbs blink in different sequences to make signs, making stepper motors with adjustable speed with a dial, and some other beginner projects. MostlyI I have been modified other peoples code.
The physical machine has been completely tested. I used 5 volts the closest circuit to test each the MOSFET Button IRF520, to close the circuit to the 12 V to each solenoid to strike each metal bar.
Music is a type of program, and I have a little bit more experience with, I put the viola in high school. There are seven whole notes in each octave. Essentially want to start at an F on the third 2nd or 3rd octave of a piano. I am not not familiar with pianos.
Original cold below, but to be quick, there are three basic problems.
- My xylophone has 32 notes. The xylophone in the OG code had less nose. But the author extended the playable notes by having an octave higher and lower play at the same pins. EX) a F note an octave higher than what the instrument had physically available, would use a pin at the same piece of metal and octave lower/Higher.
*Is there an easier way to do this with an existing library?
- If I change int mF = 37; //2 to my understanding MIDI 37 is the C#/Db of the first octave, which was changed via wiring, just to lower the scale.
If I change it to hit the actual physical metal bar, that vibrates when struck to produce the sound wave of a F note in the octave, int mF = 41; //2 would this work ?
ALSO, the output from the Arduino would be from Pin 2?
If so, I think I could change all the code to hit the keys I want.
/*
MIDI Xylophone
This program runs on an Arduino Mega and listens for midi signals to be sent over the USB cable from a midi instrument or digital audio workstation application.
When the Arduino recieves a 'note on' byte, it writes the corresponding pin LOW, triggering the connected relay and solenoid.
Download the required library at http://fortyseveneffects.github.io/arduino_midi_library/index.html
This is not the same MIDI libraries found in the library manager.
Circuit: GPIO pins on Mega (see below) are connected to the inputs of two 16 relay module boards.
GND from the Arduino Mega is connected to ground on the relay modules.
The Arduino is powered by the attached USB cable.
The relay modules are powered by a 12V ACDC switching power supply.
A separate 10A 5V power supply is used for the 25 solenoids.
GND from the power supply is connected in parallel to the NO terminal of each relay.
The common of each each relay is connected to its own solenoid.
The outputs of all the solenoids join together and connect to 5V on the power supply.
This is based on the MidiUSB example included with the library
Modified by Johnny Devine 2020
*/
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
// -----------------------------------------------------------------------------
//Declare and define variables
//Pins numbers on Mega and the note they play (relay pin is second number). h for high, m for middle, and l for low
int hG = 23; //16
int hFs = 4; //4
int hF = 22; //15
int hE = 25; //14
int hDs = 5; //5
int hD = 24; //13
int hCs = 6; //6
int hC = 27; //12
int hB = 26; //11
int hAs = 7; //7
int hA = 29; //10
int mGs = 8; //8
int mG = 28; //9
int mFs = 13; //13
int mF = 37; //2
int mE = 34; //3
int mDs = 12; //12
int mD = 35; //4
int mCs = 11; //11
int mC = 32; //5
int mB = 33; //6
int mAs = 10; //10
int mA = 30; //7
int lGs = 9; //9
int lG = 31; //8
//There are 128 notes in MIDI. 43 is the low G on the xylophone
//Midi for lG (or G2, I think) starts on 43 and goes to 67 for hG (or G4)
int baseNote = 32 //The G on the xylophone is actually 43, but I started an octave lower so more notes not on the xylophone still make sound, just an octave lower;
//This is the array of notes that can be played on the xylophone
//Notice that there are two sets of the lowest and highest octaves to catch MIDI notes that are not on the keys.
// -----------------------------------------------------------------------------
//Define what action to take when a 'note on' byte is received
void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity)
{
//Only pluck if the midi note is in the range we can play:
if(inNumber >= baseNote && inNumber < (baseNote + 49)){ //there are actually only 25 keys, but with the extra octave above and below, the total is 49
byte stringnote = noteList[inNumber - baseNote];
pluck(stringnote,8);
}
//In setup() we are only listening to channel 1, so that info is not used here. Neither is velocity, since that is defined as a constant in pluck()
}
void pluck(int stringnote, int velocity)
{
digitalWrite(stringnote,LOW);
delay(velocity); //set to a constant 8ms above, which seems to sound nice on the xylophone keys.
digitalWrite(stringnote,HIGH);
}
// -----------------------------------------------------------------------------
void setup()
{
pinMode(hG,OUTPUT);
pinMode(hFs,OUTPUT);
pinMode(hF,OUTPUT);
pinMode(hE,OUTPUT);
pinMode(hDs,OUTPUT);
pinMode(hD,OUTPUT);
pinMode(hCs,OUTPUT);
pinMode(hC,OUTPUT);
pinMode(hB,OUTPUT);
pinMode(hAs,OUTPUT);
pinMode(hA,OUTPUT);
pinMode(mGs,OUTPUT);
pinMode(mG,OUTPUT);
pinMode(mFs,OUTPUT);
pinMode(mF,OUTPUT);
pinMode(mE,OUTPUT);
pinMode(mDs,OUTPUT);
pinMode(mD,OUTPUT);
pinMode(mCs,OUTPUT);
pinMode(mC,OUTPUT);
pinMode(mB,OUTPUT);
pinMode(mAs,OUTPUT);
pinMode(mA,OUTPUT);
pinMode(lGs,OUTPUT);
pinMode(lG,OUTPUT);
//On the relay module, HIGH is the NC closed state of the relays
digitalWrite(hG,HIGH);
digitalWrite(hFs,HIGH);
digitalWrite(hF,HIGH);
digitalWrite(hE,HIGH);
digitalWrite(hDs,HIGH);
digitalWrite(hD,HIGH);
digitalWrite(hCs,HIGH);
digitalWrite(hC,HIGH);
digitalWrite(hB,HIGH);
digitalWrite(hAs,HIGH);
digitalWrite(hA,HIGH);
digitalWrite(mGs,HIGH);
digitalWrite(mG,HIGH);
digitalWrite(mFs,HIGH);
digitalWrite(mF,HIGH);
digitalWrite(mE,HIGH);
digitalWrite(mDs,HIGH);
digitalWrite(mD,HIGH);
digitalWrite(mCs,HIGH);
digitalWrite(mC,HIGH);
digitalWrite(mB,HIGH);
digitalWrite(mAs,HIGH);
digitalWrite(mA,HIGH);
digitalWrite(lGs,HIGH);
digitalWrite(lG,HIGH);
MIDI.begin(); // Launch MIDI, by default listening to channel 1.
//Defines what to do when a 'note one' byte is detected during the read in the main loop
MIDI.setHandleNoteOn(handleNoteOn);
//Note the higher baud rate than is often used (9600)
Serial.begin(115200);
}
void loop()
{
MIDI.read();
//Some relays were not being written back HIGH at the a strike, putting the soelnoids at risk of being burned out.
//I was afraid these digitalWrites() would destroy the latency, but it still seems to move quickly enough.
digitalWrite(hG,HIGH);
digitalWrite(hFs,HIGH);
digitalWrite(hF,HIGH);
digitalWrite(hE,HIGH);
digitalWrite(hDs,HIGH);
digitalWrite(hD,HIGH);
digitalWrite(hCs,HIGH);
digitalWrite(hC,HIGH);
digitalWrite(hB,HIGH);
digitalWrite(hAs,HIGH);
digitalWrite(hA,HIGH);
digitalWrite(mGs,HIGH);
digitalWrite(mG,HIGH);
digitalWrite(mFs,HIGH);
digitalWrite(mF,HIGH);
digitalWrite(mE,HIGH);
digitalWrite(mDs,HIGH);
digitalWrite(mD,HIGH);
digitalWrite(mCs,HIGH);
digitalWrite(mC,HIGH);
digitalWrite(mB,HIGH);
digitalWrite(mAs,HIGH);
digitalWrite(mA,HIGH);
digitalWrite(lGs,HIGH);
digitalWrite(lG,HIGH);
}