Go Down

Topic: Midi-Out does not work well (Read 4648 times) previous topic - next topic

basboy12

Hi, I'm building a midi-keyboard based on this idea for a schoolproject: http://www.youtube.com/watch?v=_4cIv6qLaM8

but instead of getting a sound directly out of the arduino, I want it to produce midi-notes so I can link any instrument to it.

I wrote an IDE-code that produces the midi-signals, but It's still not working as I want it to.

this is an example of the code:
Code: [Select]
#include <CapacitiveSensor.h>

CapacitiveSensor   cs_2_3 = CapacitiveSensor(2,3);        
CapacitiveSensor   cs_2_4 = CapacitiveSensor(2,4);

int velocity = 100;//velocity of MIDI notes, must be between 0 and 127
//(higher velocity usually makes MIDI instruments louder)

int noteON = 144;//144 = 10010000 in binary, note on command

void setup() {
 //  Set MIDI baud rate:
 Serial.begin(31250);

}

void loop() {
 
 long total1 =   cs_2_3.capacitiveSensor(30);
 long total2 =   cs_2_4.capacitiveSensor(30);

if (total1 > 500) {

   for (int note=48;note<49;note++) {//from note 50 (D3) to note 69 (A4)
   MIDImessage(noteON, note, velocity);//turn note on
   delay(500);
   MIDImessage(noteON, note, 0);}}//turn note off
   
if (total2 > 500) {
   for (int note=49;note<50;note++) {//from note 50 (D3) to note 69 (A4)
   MIDImessage(noteON, note, velocity);//turn note on
   delay(500);//hold note for 300ms
   MIDImessage(noteON, note, 0);}}//turn note off  

}
//send MIDI message
void MIDImessage(int command, int MIDInote, int MIDIvelocity) {
 Serial.write(command);//send note on or note off command
 Serial.write(MIDInote);//send pitch data
 Serial.write(MIDIvelocity);//send velocity data
}


The problem is: It can not send 2 or more midi-notes at the same time. Probably it's because of the delay function. And when I hold/press the touchcapacitive sensor, it will sent out midi notes every 0,5s instead just one.

Is there a way the arduino can only sent out one midi-note if you press the capacitive sensor once, instead of sending out the midi-note every 0,5s?

I hope someone could help me..

Thanks!

Grumpy_Mike


basboy12

It wasn't that easy. When I 'just' remove the delays, the arduino would be continue triggering the notes. You will get a stutter effect.

But someone helped me with the code, now I'm able to play the notes without using a delay or millis.



Grumpy_Mike

Did it by any chance involve edges rather than levels I wonder?

basboy12

What do you exactly mean? sorry, my english is not that great..

bildakid

I believe you'll need to add a variable to store the last sent note, then when you go to play a new note you compare and decide weather or not to play the note.

int lastNote = 0;
playedKey = sensor input.


if(playedKey != lastNote){  /if the note is different from the last
   PlayMidi note;
  lastNote = playedKey;
}

!BEST OF LUCK.

marco_c

#6
Jan 24, 2014, 09:50 pm Last Edit: Jan 25, 2014, 07:44 pm by marco_c Reason: 1
The probem is that you need to detect the transition from off to on and on to off, only sending the MIDI message when you see the transition (this is the EDGE detection mentioned). As has already been suggested, you need to remember the last state of the input and only act when the state is different from what it was before.
Arduino libraries http://arduinocode.codeplex.com
Parola for Arduino http://parola.codeplex.com

basboy12

you mean something like this?

Code: [Select]
static int lastInput1 = 0;
int newInput1 = total1;
if((lastInput1 < 500) && (newInput1 > 500)) {
    for (int note=48;note<49;note++) {//from note 50 (D3) to note 69 (A4)
    MIDImessage(noteON, note, ON); }};//turn note on
if((lastInput1 > 500) && (newInput1 < 500)) {
    for (int note=48;note<49;note++) {//from note 50 (D3) to note 69 (A4)
    MIDImessage(noteON, note, OFF); }};
lastInput1 = newInput1;


this is just an little bit of the whole code, but so far it makes me able to play one note at the time. So first note C, when that's off, note D, etc..

marco_c

That's the idea. If it now works then that is all you need!
Arduino libraries http://arduinocode.codeplex.com
Parola for Arduino http://parola.codeplex.com

basboy12

yeah it's working. But I can't play 2 or more notes at the same time for some reason..

Grumpy_Mike

The reason is your code. It needs to be able to cope with more than one note down at a time.
You need a list of times when each note up event will be triggered.

basboy12

Hi, a while ago I finished this project and I made a little instruction. You can check it out here: http://www.instructables.com/id/Arduino-Touch-capacitive-Midi-keyboard/

vanakaru

I have been playing with these sensors. I am surprised that you got so many pads working. Only 3 will work for me, after that there will be so much crosstalk and loss of sensitivity that the 4th is useless most of the time. I am using 10M resistors. Do you have a hint what you did different.

PolyKrome

I too have the same problem as vanakaru, yet, I can only play two notes of the scale. Could you possibly post the reworked code for this as the code you posted on the instructables website is only half there!

Thanks!

assemblyworker

So glad I found this thread, been struggling with the repeated note triggers for a few days now and this has solved the problem. Thanks!

Just one question, I'm having problems understating part of the code...

Code: [Select]
{
    for (int note=60;note<61;note++) {
 


Does this mean that it plays note 60 if the note is less than note 61?

I'm trying to simplify the code but this has me confused. Can anyone explain?


Many thanks.

Go Up