MIDI Xilophone (over serial) to Ableton

You only have one last state variable and you are over writing it every times round the for loop.
Make the last state and current state variables arrays and access then with the index of the for loop.

Yesterday when i read you message

Make the last state and current state variables arrays and access then with the index of the for loop.

i didn't understand what it meant.
Well, to be honest, i am not sure i already do!!! But, anyway, today when i woke up i had an idea of what it could mean.
So i changed the code like this:

bool currentState [4] = { HIGH, HIGH, HIGH, HIGH };
bool lastState [4] = { HIGH, HIGH, HIGH, HIGH };
int buttonPins[4] = { 8, 9, 10, 11 };

void setup() {
  for (int i=0; i<4; i++) {
    pinMode(buttonPins[i], INPUT);
    digitalWrite(buttonPins[i], HIGH);
  }
  Serial.begin(9600);
}

void loop() {
  for (int button=0; button<4; button++) {
    currentState[button] = digitalRead(buttonPins[button]);
      if (currentState[button] != lastState[button]) {
        if (currentState[button] == LOW) {
        //REMEMBER TO CHANGE SERIAL WITH MIDI_TX!!!!!!!!!!
        Serial.println (button);
      }
    }
    lastState[button] = currentState[button];
  }
}

It seems to work ok, but sometimes i still get 2 or 3 values for just 1 button push!
Is there still something missing from the code?
Should there be some kind of debouncing?

When i try to fit this code to the full Xylophone code i get the error:

Xilophone_with_Buttons.cpp: In function 'void setup()':
Xilophone_with_Buttons:57: error: a function-definition is not allowed here before '{' token
Xilophone_with_Buttons:186: error: expected `}' at end of input

I looked for { } missing somewhere but i can't find any. If it works when it is on it's own sketch, why doesn't it work when i copy and past it into to Xylophone sketch?

i can't find any duplicates, i have put each part of the code to it's right place, but still i get the same error...

HAPPY EASTER!!! =)

It dosn't work because you are not doing it right.
The error message tells you where the compiler gets mixed up.
It sounds like the compiler thinks you are trying to define a function in the wrong place.
The number 57 is the line number where it got confused, the error is likely to be a line or two before this.
The line numberyou are at is shown in the bottom left corner of the window with your code in.
Tip - if you click so your cursor is just to one side of a { or a ( then the matching one will be highlited. Use this to work out where you are going wrong.

ai, ai, ai... maybe i have been eating to much chocolate eggs!!! There was, of course, a missing { quite in the beginning. :astonished:

I found it and then everything worked fine.
i change a couple of lines so the signal from the buttons comes from the MIDI_TX, so now it looks like this:

void buttons() {
    for (int button=0; button<4; button++) {
    currentState[button] = digitalRead(buttonPins[button]);
      if (currentState[button] != lastState[button]) {
        if (currentState[button] == LOW) {
          MIDI_TX(0xB0, 80+button, 127);
        }
      }
      lastState[button] = currentState[button];
    }
  }

It seams to be working ok. When i check from the MIDI Monitor (running the serial <> midi converter also) i get this:

*** ZERO ***	From Xilof OUT	Control	1	General Purpose 5	127
*** ZERO ***	From Xilof OUT	Control	1	General Purpose 6	127
*** ZERO ***	From Xilof OUT	Control	1	General Purpose 7	127
*** ZERO ***	From Xilof OUT	Control	1	General Purpose 8	127

one General Purpose button for each of my 4 buttons.

I think it is time to go on to the next stage: adding the 4 potentiometers!
=)

Have you thought that while those buttons set the CC to 127 what resets this value?
Think about how you want to operate your buttons and what you want them to do.

i had thought that the buttons would be assignable to commands inside Ableton, like for instance Play, Stop or trigger a sample.
In this case the buttons would work fine because one button would be Play and another Stop.
But now that i think of it, if i wanted to assign it for instance to effect On/Off now that wouldn't work.
Hmmm...

i saw that there is a library that allows us to use clicks, double clicks, triple,...
Any experience with it? Do you think i would be able to use to send for instance 127 on a click and 0 on a double click?

Well, today i was trying to get the 4 pots to work. I tries to follow the advices you gave for the last few pieces of code.
I made them into array and i created a "if (potOutput[potnumber] != potLastOutput[potnumber])".
And i was then quite happy when it actually worked!!! =)
But there is one problem...
i am mapping the 0-1023 from the pot to 0-127 of MIDI. I think sometimes the pot gets "stuck" in a place where the conversion "jumps" between two values. So in the MIDI monitor it happens (not so often) then i turn the knob and even after i stop turning it the value for that pot are changing.
I don't think this would be a big problem, but still, if there is a way to fix it it would be nicer to have things clean.
Do you think making some kind of average would fix it?

This is the code i have now...

for (int potnumber=0; potnumber<4; potnumber++) {
  potVal[potnumber] = analogRead(potPins[potnumber]);
  potOutput[potnumber] = map(potVal[potnumber], 0, 1023, 0, 127);
  if (potOutput[potnumber] != potLastOutput[potnumber]) {
    MIDI_TX(0xB0, 7+potnumber, potOutput[potnumber]);
    potLastOutput[potnumber] = potOutput[potnumber];
  }
}
}

In this case the buttons would work fine because one button would be Play and another Stop.

Are you sure?
Push play - it starts push stop - now play and stop are both on, how do you play again?
Sure it depends on how you system responds to it but is sounds to me like it will be on all the time.

And i was then quite happy when it actually worked

Well done. :slight_smile:

sometimes the pot gets "stuck" in a place where the conversion "jumps" between two values

Yes this is what happens with any A/D converter, it is called dithering and happens due to the natural noise in a system.
I think the best way round it is to test for any change on the raw value you read. But not only that only when a change is greater than say 4. To do this you would use a test like this:-

if(abs(oldValue - newVlaue) > 4) .....

In other words you subtract the two and remove any negative sign by using the abs() function, abs stands for absolute value.
Of course you would do it with arrays if you are doing four in one loop.
Only then map the newValue to the MIDI range and send it.

i was looking at the library ClickButton.
Maybe this would be a nice solution and with 4 buttons i could actually control thing better that with just one simple click per button.
i have never used a library before, but i think thing didn't go so bad.

i wrote something like this...

#include "ClickButton.h"

int buttonPin1=8;
int ledPin=13;

ClickButton button1(buttonPin1, LOW, CLICK_PULLUP);
int lastClickCode1=0;

void setup() {
pinMode(buttonPin1, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}

void loop() {
button1.Update();
if(button1.click == CLICK_SINGLECLICKED && button1.click != lastClickCode1){
Serial.println("1");}

else if(button1.click == CLICK_SINGLEHOLD && button1.click != lastClickCode1){
Serial.println("2");}
lastClickCode1 = button1.click;
}

Nothing too complicated. for each button two options: simple click or click+hold.
simple click i could then assign to cc and 127 and click+hold to 0. Like this i could have On AND Off in just one button.

The problem is that when i try to get it done for the four buttons with arrays i get all mixed up!!!! Maybe i eat too much easter chocolate eggs!!! :roll_eyes:
It starts already in the beginning with "ClickButton button1(buttonPin1, LOW, CLICK_PULLUP);"...

ai, ai, ai...

i was looking at the library ClickButton.

The problem with using libraries like this for simple functions is that you are not in control of what is happening and when it doesn't do what you want you are stuck.
What is wrong with sending the 127 value when you press the button and 0 when you release it?

well, i think you are right. Maybe it is smarter to have a way to send also value 0.
I played around with the ClickButton library and manage to make to buttons work so that 1 click sends 127 and Click+Hold sends value 0.
i didn't manage to make it into an array yet, but i'll still give it another go.
putting the "ClickButton button1(buttonPin1, LOW, CLICK_PULLUP);" from the beginning into the arrays is confusing me, but there is no hurry, the "firmware" can always be updated when i know enough coding to do it! :wink:

So, let me recall what is working so far:
the 8 piezos,
the 4 assignable buttons (with click and click+hold),
the 4 potenciometers;

But now i have one other question for a 5th button.
There is a defined array of notes for the piezos

unsigned char PadMajor[8] = {60,62,64,65,67,69,71,72};

what i would like to do, would be to have 3 Scales (or modes) that i can chose with a button.
To have a major scale, a minor scale, and maybe a Pentatonic Scale or a Prhygian Mode.
It would start with Scale1 (major). Each button click would make it to the next scale. Each button Hold would change it into the previous scale.

Finding the midi note numbers is no problem. (maybe not so easy to decide which mode i want to have!!! 8) )

i imagine it could work like this:
i make a new button than can control a "mode" variable.
when mode is equal to 1 the scale to be played is PadMajor. mode 2 = PadMinor and mode 3 = PadPentatonic.

But now imagining it and doing it are very different things...
Is an array "loopable"?
Let's say
for (int mode=0; mode<3; mode++) - when mode is equal to 3 if i would use something like "mode++) would it go back to 1 or would it continue to 4?

How can i connect two separate parts of the code, the one with the button defining the "mode" with the one that is telling which notes to play?

Ahhhh... :~ i think i am at a stage now where i can understand some of the concepts involved with programing, but i cannot use them yet. i can understand for instance that with variables we can connect things, but then when i try to use them everything get's mixed up along the way...
well, i guess i cannot ask to learn it all in two weeks! With time i'll get there.
Until then, i am lucky to have this form to push me in the right directions! Thanks!
=)

Let's get this last button working... then it's time to start building everything! =)
And PLAY!!! =)

would it go back to 1 or would it continue to 4?

It would be 4.

Is an array "loopable"?

No idea what you mean. I like to think of an array as being a variable with a name that is a variable. That is it allows the same code to operate on different variables.

Getting to know what you want to do is half the battle. You have done very well so far, you should be very pleased with yourself. There is always more to learn, that's the fun. :slight_smile:

by "loopable" i meant if if will continue to four or if after the last value in the array it will "loop" back to the first. So if we add always (++) it would "loop" through the values inside the array.
But i made a couple of experiments and it seems it's not like that.

Well, anyway, i have good news!!!
I think now EVERYTHING is working! 8)

Surely it is not the most elegant nor the most genial code, but hey, it is getting the job done!
This will be the V1.0 of (maybe) several to come... :wink:

Now the piezos are working, the buttons and the pots also and the button is also enabling us to choose from Ionian (major), Aeolian (minor) and Major Pentatonic Modes.

Now it is time to try to plug it to some music software and get some sound from it!!!
Also time to start thinking about building a nice "real music instrument" (maybe out of wood).

== = = = == === ==== == = = =
i have still one more question that just came to my mind.
i thought a couple of times that it could be useful to have a little led somewhere blinking whenever there is some "communication", like the TX led in the Arduino Board.
How could i do this?
I noticed that there is a pin in the board (digital pin 1) where it also reads TX. Could i use it?

Thank you!
=)

a pin in the board (digital pin 1) where it also reads TX. Could i use it?

Yes you could but as it has to drive the USB to serial converter chip then don't load it too much. An LED with a 1K would be best.

So if we add always (++) it would "loop" through the values inside the array.

Still not sure but:-

index = 0;
while(conditionIsTrue){
array[index++] = // something
if(index > indexLimit) index = 0;
// do something else
}

Would work. The index++ is called post incrementing, that is the operation is performed and then the value index is incremented. The inverse is pre indexing

array[++index] = // something

Here the value index is incremented before doing the operation with array.

hmmm, i have been looking on information on how to make the "external TX indicator" work (i mean, an LED that blink as the onboard TX LED), but i don't seem to find it...

When i connect an LED with a 1k resistor to the pin1 on the Arduino, the LED is ALWAYS on (but not the onboard TX one). i didn't even add it to the sketch, i just connected it and it came on.

Any ideas where i can find information on how to do this?

= = = = = =

Another question...

Every time i have built something with the Arduino i have used breadboards.
Now that the MIDI Xylophone is getting ready i start to think on the "building it" side of things to make a more defenitive version that i can actually play, take with me to rehearsals,....
The design, what wood to use and what kind of "enclosure" i want to make, ...
But then it came to my mind: do i need to solder things to the ARDUINO?
If i am using some kind of protoboard where i solder/connect all the components in the project, how do i then connect them to the Arduino's pins?
Should i use the same kind of jumper wires that plug in the pins and then solder the other end to the protoboard?

Thank you
=)

When i connect an LED with a 1k resistor to the pin1 on the Arduino, the LED is ALWAYS on

Yes it will be. That is because the normal state of the logic line on a serial port is a logic one. Therefore you will see the LED lit. If you want it the other way round then you must connect the LED and resistor between +5V and the pin1. In that way you sink the current ( as opposed to sourcing it ) and when something is transmitted the LED is lit up. As you had it the LED is turned off when something is sent and it is hard to see any change in a lit LED going briefly off, where it is easy to see an unlit LED going briefly on.

But then it came to my mind: do i need to solder things to the ARDUINO?

Yes, or at least solder things to pin headers that you plug into the arduino.

So i have been waiting (IMPATIENTLY) for some parts to arrive in the post...

Meanwhile, and because this project keeps popping in my head, i decided to try to draw a schematic of the whole thing. (Who knows, maybe one day someone wants to build something like it...).

I had already fritzing, so i gave it a go making a Breadboard representation of what i have.
I came to this:

But then i decided to try to make areal schematic!!!
Ai, ai, ai...
I think i cannot even READ a schematic properly, much less draw one...
Anyway, i thought this would be a good way to learn a couple more things. I looked around the net and it seemed that Eagle was a choice many people make so, i decide to try it out (it helped that they have a freeware version!).
But, of course, soon in the process the problems/doubts started.

At the moment i have this:

Would this be the right way to draw the schematic for the diode/res/piezo part?
(i made only two, so then i don't need to delete them all again and remake them the right way... :wink: )

Do you know any "exercises" site to learn how to read/draw schematics?

= = =
I have now wired the TX LED as you suggested (to +5v instead of ground) and it is working fine. Thanks!!!

=)

There is no right way of drawing a schematic but there are a number of conventions that make reading one easier.
Ground at the bottom, positave at the top, signal flow from left to right.
Drawn with the minimum number of crossing wires. Eagle makes this hard because of the fixed pin distribution of a chip's outline. Better packages allow you to change where abouts each pin appeares on a package.

On your example it is hard to see that the 1M is across the sensor and ground, and the diode looks the wrong way round.

So, it is now almost 2 months since i started this project but i am now happy to tell you that it's completed!
Yesterday i had some time and i finished it, tried it, and enjoyed a nice project done! =)

I have to thank you all for the help you gave me. In many of the steps of this project i felt quiet lost, but there was here always some one ready to point me in the right direction.
THANKS!!! :slight_smile:

Here are some pictures of the final thing.
I call it PöPö (MIDI Xylophone)

There are, surely, many things that could be improved. The code could be much tidier and elegant (but i still need to learn a lot before i can do it), some practical things could be improved (i would now maybe put 8 buttons and 8 pots, i would like to make the piezos more sensitive,...), it would be cool to have a small LCD showing in which mode/scale we are playing (now there is just a LED showing mode 1, 2 or 3), and, many more...
But this is Version 1.0, maybe more to come one day...

I will now try to make a PDF with the "instructions" on how to build it, schematic, code,... Who knows, maybe one day someone else will be interested in making he's own...
:wink:

I have made a little website talking about this project.
It was just for me to try a couple of webdesign ideas i had, but still, now i kind of like it, do i decided to put it online.

You can check it out here: http://popo.webatu.com

There you can see some photos, read about the main characteristics of the Xylophone, and see how to make your own (there is list of materials, schematics, code and explanation,...)

Hope you enjoy it.

And, once again, thank you for all the help you guys gave me with this project!
=)