Problemen met midi-out

Hallo,

op school voer ik met een paar andere leerlingen (vwo5) een project uit waarbij we gebruik maken van arduino.
We gaan namelijk een les voorbereiden en uitvoeren bij een basisschool. Deze les zal gaan over muziek en geluid. Omdat het ons leuk leek om de kinderen zelf instrumenten te laten maken, hebben we ervoor gekozen om dit idee na te bouwen http://musicink.co/

Kinderen kunnen met een speciale geleidende verf instrumenten verven, en zodra dit wordt aangesloten op de arduino, hoor je muziek.

Het is mij al gelukt om een arduino Uno R3 als een midi-apparaat te laten verschijnen en een output te creëren, alleen de code klopt nog niet helemaal.

we werken ook met touch capacitieve sensors, wat lijkt op dit: Paper piano with arduino - YouTube

De situatie is als volgt:
als je op een touchcapacitieve sensor drukt, wordt er een bijbehoorde midi noot met velocity (luidheid) naar de pc gestuurd.
er is een delay van 0,5s
vervolgens wordt de midi noot weer uitgezet doordat de arduino een velocity van 0 uitzendt.

in de code ziet dat er zo uit.

#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
}

bij deze situatie, de de lengte van noot dus afhankelijk van de delay. Maar we willen eigenlijk een situatie creëren waarin de lengte van de noot samenhangt met de tijd dat iemand de touchcapacitieve sensor indrukt/vasthoudt. En dat het eventueel mogelijk is om meerdere noten tegelijk aan te verzenden naar de pc.

weet iemand of dit mogelijk is of wat ik moet veranderen aan de code om dit te laten werken?

met vriendelijke groet, Bas van Straaten

Hoi Bas, welkom.

De oplossing van je vraag zit in de "blink without delay" sketch die meegeleverd werd met de IDE.
Die sketch is een les, en leert je hoe je een bepaalde actie een bepaalde tijd kan laten duren zonder delay te gebruiken.
Het komt er in het heel kort op neer dat een delay(xx) betekent: wacht tot te klok xx milliseconden verder is.
En je wil wel op de klok kijken om te zien of de gewenste tijd verlopen is, maar ondertussen ook nog iets anders doen.
Dat andere is dus kijken of er nog andere toetsten zijn ingedrukt, en daar iets mee doen.
Je moet je realiseren dat je Arduino een hartslag heeft die net ietsje sneller slaat als dat van een mens (te weten 16 miljoen keer per seconde).
Dat betekent dat je in een seconde ontzettend veel kan doen.

Kijk dus eens in de blink without delay oefening en of je dat snapt.
Je zal dan een handvat hebben om al die delays dis je nu hebt, overboord te gooien.
Dat is de basis van de oplossing van jullie probleem.

Oh, en Bas,
Het is niet slim om dezelfde vraag op meerdere plaatsen tegelijkertijd te stellen, ook niet als je dat in verschillende talen doet.
Antwoorden zullen door elkaar gaan lopen en het word er voor jezelf niet duidelijker op.
En voor degenen die je helpen is het ook niet zo netjes dat je je elders ook laat helpen en de antwoorden je dan dus voor piep worden getypt.

bedankt voor de reactie.

Ik heb even gekeken naar de code blinkwithoutdelay, maar volgens (ik weet het niet zeker) lukt het daarmee niet.

is het ook mogelijk om zo'n soort code te laten uitvoeren door arduino? deze is versimpeld maar het gaat om het idee:

was de input in de vorige loop < 500 en nu > 500;
midi noot = aan
was de input in de vorige loop > 500 en nu > 500;
doe niets

was de input in de vorige loop > 500 en nu < 500;
midi noot = uit
was de input in de vorige loop < 500 en nu < 500;
doe niets

want als dit mogelijk zou zijn, wordt er dus maar een midi noot= aan verzonden bij het eenmalig aanraken van de sensor in plaats van elke 0,5 seconde een i]midi noot= aan[/i]
dit zou ook de delays overbodig maken.

met vriendelijke groet, Bas.

ps: ik zal er volgende keer rekening mee houden om niet dezelfde vraag 2x te posten, sorry hiervoor.

basboy12:
is het ook mogelijk om zo'n soort code te laten uitvoeren door arduino? deze is versimpeld maar het gaat om het idee:

was de input in de vorige loop < 500 en nu > 500;

midi noot = aan
was de input in de vorige loop > 500 en nu > 500;
doe niets

was de input in de vorige loop > 500 en nu < 500;
midi noot = uit
was de input in de vorige loop < 500 en nu < 500;
doe niets



tuurlijk. Ik geef een voorzet (niks gecontroleerd gewoon hier getypt)
void loop()
{
static int VorigeInput=0; //door static blijft de waarde behouden bij elke loop call
int input= GetInput; //hoe je dat doet weet je vast beter dan ik

if( (VorigeInput < 500) && (input> 500) )
{
midi noot = aan
};
.....

VorigeInput=input; //zeg dat de vorige input de huidige is.
}

Heel makkelijk dus;
Met vriendelijke groet
Jantje

Harstikke bedankt!

nu werkt het zoals ik het had voorgesteld in het vorige bericht. Het is alleen nog niet mogelijk om 2 of meer noten tegelijk te laten spelen, maar dit heeft me in ieder geval al erg veel geholpen!

mvg, Bas van Straaten