MIDI Xylophone - Arduino Mega 2560 - code expansion help

Hi
I am a newbie!
My son in law and I have built a MIDI xylophone using the instructions from this page:

I have 12 x piezo mics as inputs each connected to an acrylic bar, so far so good.
I am using Hairless MIDI and MIDI loop, Windows 10 , Ableton Live 10 Suite (DAW)

The sketch provided on the web link above (after I modified it a little from one of the builders comments) did not work (Hairless crashed) but i have verified and uploaded the following basic sketch to the Arduino (and reduced the "int threshold" from 50 to 5 as it gave a better response when hitting the bars connected to the piezos):

int noteOn = 144;
int piezo = A0;
int threshold = 5;//anything over five means we've hit the piezo

void setup(){
  Serial.begin(9600);
}

void loop(){
  int piezoVal = analogRead(piezo);
  if (piezoVal>threshold){
    MIDImessage(noteOn, 37, 127);
    delay(300);
    MIDImessage(noteOn, 37, 0);
  }
}

//send MIDI message
void MIDImessage(byte command, byte data1, byte data2) {
  Serial.write(command);
  Serial.write(data1);
  Serial.write(data2);
}

i obtained the sketch above from an Instructibles site
using Hairless MIDI (loop MIDI in out set on "Loop MIDI Port" and seriel port "Arduino Mega 2560 (COM3) and whilst LoopMIDI is running in the background when its connected to Ableton Live 10 DAW, Ableton finds the "MIDI From" Loop MIDI Port no problem and I can trigger audio from the Xylopnone! Hairless MIDI (with Baud rate 9600) shows the ports flashing when I hit the piezos

Getting there..

The issue I have is that with the above code each piezo triggers the same note - the C#1 note only , what I need to be able to do is expand the code for the 12 notes so piezo 1 only triggers C1, piezo 2 only triggers C#1 and so on up to B1

I know that if I change the value "37" to "36" in the "Note On" code above then all the piezos will trigger note C1 instead of C#1 in the DAW

I have tried expanding the code for "piezo1" "piezo2" etc but it seems to be causing multiple messages through Hairless MIDI without having to hit the piezos and nothing happens in the DAW when hitting the piezos

I have looked in libraries to find something similar and can't seem to locate anything but I am on a steep learning curve at the moment
Any advice gratefully received

Update!
I can now get 5 piezos playing the separate notes using this code, just need some tips on how to change the code for 12 x piezos. Thanks

//Xylophone

    //Adapted for an ArduinoMega 

    //from Jenna deBoisblanc and Spiekenzie Labs initial code

    //*******************************************************************************************************************

    // User settable variables

    //*******************************************************************************************************************

    int pinRead;

    char pinAssignments[5] ={'A0','A1','A2','A3','A4'};

    byte PadNote[5] = {36,37,38,39,40}; // MIDI notes from 0 to 127 (Mid C = 60)

    //53 Campana

    //69 Tarola 

    //11 Hithat cerrado

    //57 Crash

    //36 Bombo

    int PadCutOff[5] = {200,200,200,200,200}; // Minimum Analog value to cause a drum hit

    int MaxPlayTime[5] = {90,90,90,90,90}; // Cycles before a 2nd hit is allowed

    #define midichannel 1; // MIDI channel from 0 to 15 (+1 in "real world")

    boolean VelocityFlag = true; // Velocity ON (true) or OFF (false)

    //*******************************************************************************************************************

    // Internal Use Variables

    //*******************************************************************************************************************

    boolean activePad[5] = {0,0,0,0,0}; // Array of flags of pad currently playing

    int PinPlayTime[5] = {0,0,0,0,0}; // Counter since pad started to play

    byte status1;

    int pin = 0; 

    int hitavg = 0;

    //*******************************************************************************************************************

    // Setup

    //*******************************************************************************************************************

    void setup() 

    {

    Serial.begin(57600); // SET HAIRLESS TO THE SAME BAUD RATE IN THE SETTING

    }

    //*******************************************************************************************************************

    // Main Program

    //*******************************************************************************************************************

    void loop() 

    {

    for(int pin=0; pin < 5; pin++) //

    {

    //int pin = 3;

    // for (pinRead=0; pinRead < 16, pin++){

    hitavg = analogRead(pinAssignments[pin]); 

    //Serial.println(hitavg); 

    // read the input pin

    if((hitavg > PadCutOff[pin]))

    {

    if((activePad[pin] == false))

    {

    if(VelocityFlag == true)

    {

    hitavg=127;

    //hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin])); // With full range (Too sensitive ?)

    //hitavg = (hitavg / 8) -1 ; //8 // Upper range

    }

    else

    {

    hitavg = 127;

    }

    MIDI_TX(144,PadNote[pin],hitavg); //note on

    PinPlayTime[pin] = 0;

    activePad[pin] = true;

    }

    else

    {

    PinPlayTime[pin] = PinPlayTime[pin] + 1;

    }

    }

    else if((activePad[pin] == true))

    {

    PinPlayTime[pin] = PinPlayTime[pin] + 1;

    if(PinPlayTime[pin] > MaxPlayTime[pin])

    {

    activePad[pin] = false;

    MIDI_TX(144,PadNote[pin],0); 

    }

    }

    } 

    }

    //*******************************************************************************************************************

    // Transmit MIDI Message

    //*******************************************************************************************************************

    void MIDI_TX(byte MESSAGE, byte PITCH, byte VELOCITY) 

    {

    status1 = MESSAGE + midichannel;

    Serial.write(status1);

    Serial.write(PITCH);

    Serial.write(VELOCITY);

    }
char pinAssignments[5] ={'A0','A1','A2','A3','A4'};
 hitavg = analogRead(pinAssignments[pin]);

You should not be using ASCII characters for pin names. What you want is:

const byte pinAssignments[5] ={A0, A1, A2 , A3 , A4};
 hitavg = analogRead(pinAssignments[pin]);

The Ardiuno MEGA has 16 analog inputs so you could use 12 of them by making all of your arrays bigger and changing the 5 in your loops to 12.

That seems to work. Sir you are a genius. Thanks!

I have a question though
I ran this new sketch on my desktop and it works fine
But Hairless MID crashes when I move the xylophone over to my laptop (which is where I need it for live performance) using the same software DAW and settings on Hairless MIDI and LoopMIDI
I copied the Arduino sketch and loaded it into the Arduino software on the laptop and it wouldnt verify
Is it the case that the sketch isnt compatible across devices??
Thanks

andyroo66:
I copied the Arduino sketch and loaded it into the Arduino software on the laptop and it wouldnt verify

Sounds like one of the libraries the sketch is using either is not installed on the laptop or the wrong version is installed. If only we could see the errors.

this is the error code, the libraries are the same as far as I am aware

Arduino: 1.8.13 (Windows 10), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

C:\Users\user\OneDrive\Documents\Arduino\5piezos9\5piezos9.ino: In function 'loop':

C:\Users\user\OneDrive\Documents\Arduino\5piezos9\5piezos9.ino:85:43: warning: iteration 12 invokes undefined behavior [-Waggressive-loop-optimizations]

     hitavg = analogRead(pinAssignments[pin]);

                         ~~~~~~~~~~~~~~~~~~^

C:\Users\user\OneDrive\Documents\Arduino\5piezos9\5piezos9.ino:77:24: note: within this loop

     for(int pin=0; pin < 13; pin++) //

                    ~~~~^~~~

C:\Users\user\Downloads\arduino-1.8.13-windows\arduino-1.8.13\hardware\arduino\avr\cores\arduino\main.cpp: In function 'main':

C:\Users\user\OneDrive\Documents\Arduino\5piezos9\5piezos9.ino:91:31: warning: iteration 12 invokes undefined behavior [-Waggressive-loop-optimizations]

     if((hitavg > PadCutOff[pin]))

                               ^

C:\Users\user\OneDrive\Documents\Arduino\5piezos9\5piezos9.ino:77:24: note: within this loop

     for(int pin=0; pin < 13; pin++) //

                        ^

Sketch uses 2170 bytes (0%) of program storage space. Maximum is 253952 bytes.

Global variables use 294 bytes (3%) of dynamic memory, leaving 7898 bytes for local variables. Maximum is 8192 bytes.

An error occurred while uploading the sketch



avrdude: stk500v2_setparm(): failed to set parameter 0x9e

avrdude: stk500v2_command(): unknown status 0xc8

avrdude: initialization failed, rc=-1

         Double check connections and try again, or use -F to override

         this check.



avrdude: stk500v2_command(): unknown status 0x01

avrdude: stk500v2_disable(): failed to leave programming mode



This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
     for(int pin=0; pin < 13; pin++) //

You can't use the 13th element of an array with 12 elements. They are numbered 0 through 11. The error message was telling you that when 'pin' got to 12 you were going off the end of your array. Change line 77 to:

     for(int pin=0; pin < 12; pin++) //
An error occurred while uploading the sketch



avrdude: stk500v2_setparm(): failed to set parameter 0x9e

avrdude: stk500v2_command(): unknown status 0xc8

avrdude: initialization failed, rc=-1

         Double check connections and try again, or use -F to override

         this check.



avrdude: stk500v2_command(): unknown status 0x01

avrdude: stk500v2_disable(): failed to leave programming mode

But that still leaves you with this issue on the laptop,

Is it the case that the sketch isnt compatible across devices??

Shouldn't matter, mind you, if you've uploaded the sketch from the desktop, there is no real need to upload it again (those warning should be fixed though !!) But that you can't upload is a symptom of something else. Somehow the laptop is not connecting to the Arduino. Is the com port showing up in the IDE (or are you on Mac ? I hope not Ableton on a mac is just a bit much for me :wink: )

thanks,
Ableton on a PC
changing line 77 makes no difference
sketch loads ok on the desktop but not on the laptop
So the sketch is correct (at least on the desktop), somehow the laptop is not conencting with Arduino??
Dont understand why a sketch would load on a desktop but not on a laptop, they both use the same version of Ardiuno with same library, must be something to do with the laptop configuration

laptop shows "USB seriel device (COM4) in device manager and has the same drivers as the device on the desktop (usbser.sys)
On the Laptop Hairless crashes, it shows the seriel port COM4 no problem but when I connect LoopMIDI ports in and out I get:
Failed to open MIDI out port: RtMidiOut::openPort: error creating Windows MM MIDI output port.
Failed to open MIDI in port: RtMidiIn::openPort: error creating Windows MM MIDI input port.
Seems to be 2 issues, the laptop with Arduino and the Hairless not finding MIDI ports, i'm aware this is an Arduino forum only!

i changed the seriel port to COM4 in Arduino and the sketch loads on the laptop
sadly that doesnt solve the issue with Hairless crashing and not finding MIDI ports
But its one less variable!

Serial.begin(57600); // SET HAIRLESS TO THE SAME BAUD RATE IN THE SETTINGIs that the correct Baud-rate set in hairless ?

Yes 57600 set in Hairless

been at it all night- still cant seem to fix it
tried all the different settings in Hairless
even tried a quick look at Copperlan but that does not recognise the seriel device
has to be something simple, from what I gather something else might be hogging the MIDI port but i have no other devices connected , just the xylophone to the laptop, so frustrating as it works a dream on the desktop
this is the hairless midi error message
Failed to open MIDI in port: RtMidiIn::openPort: error creating Windows MM MIDI input port.

andyroo66:
this is the hairless midi error message
Failed to open MIDI in port: RtMidiIn::openPort: error creating Windows MM MIDI input port.

This has nothing to do with your Arduino code, it's a problem with either Hairless or Windows.

Pieter

Thanks
I uninstalled some older versions of Ableton and did a reboot. SeemSeems to have fixed it.
Maybe Ableton was hogging the MIDI ports

Great !! issue resolved.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.