Tastiera MIDI su arduino UNO

Ciao a tutti. Sto cercando di utilizzare arduino come scheda "generatrice" di output MIDI da inviare a un'altro software su PC. L'idea di base è di avere una serie di pulsanti che quando vengono premuti generano l'evento MIDI, che si interrompe solo quando il pulsante non è più premuto. Quello che mi aspetto, cioè, è di ricevere il segnale "NotaOn" quando premo e "NotaOff" quando smetto di premere.

Ho provato a scrivere il seguente codice:

int input1 = 0;
int input2 = 0;

void setup() {
  // Set MIDI baud rate:
  Serial.begin(9600);//cambiare se con jack midi su 31250
  pinMode(8,INPUT);
  pinMode(9,INPUT);
}

void loop() {
  input1 = digitalRead(8);
  input2 = digitalRead(9);

  if (input1 == HIGH){
    noteOn(0x90, 0x2A, 0x45);
  }  
  if (input2 == HIGH){
    noteOn(0x90, 0x3A, 0x45);
  }  
}

void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

Il codice così scritto in se funziona. Se collego una tastiera esterna le note suonano. Il problema è che quando premo il pulsante non viene generato un unico segnale "NotaOn", ma una infinità di segnali, come se continuassi a premere e mollare molto velocemente, che quindi mi generano un suono "martellato". Io invece ho bisogno che venga generato un unico segnale "NotaOn" fintanto che non mollo il tasto. Ho pensato che una soluzione potrebbe essere quella di interrompere il loop fin che il tasto è premuto, ma questo mi impedirebbe di gestire più tasti contemporaneamente.

Qualcuno sa darmi qualche suggerimento? Spero di essermi spiegato in modo chiaro.

Grazie a tutti!!

Sembra il classico problema del debounce. Si può risolvere sia via software che via hardware. Per il lato software potresti verificare se con una delay() poco dopo la pressione o meno del tasto risolvi. Ricordati che delay() è "bloccante", quindi il micro si "ferma" per il tempo impostato e poi riprende. La soluzione hardware consiste nella "classica" coppia resistenza e condensatore.

beh no, non si tratta solo di debounce, qui la nota deve essere mantenuta fino al rilascio del pulsante, quindi il programma deve ricordare lo stato in cui era da un ciclo all'altro nel loop

Implementare una macchina a stati finiti?

Credo anche io che il problema non sia di debounce ma del fatto che arduino manda il segnale a ogni ciclo del loop. Correttamente Patrick_M dice che il programma deve ricordare lo stato in cui è da un ciclo all'altro, ma non ho idea di come farlo.

Una macchina a stati finiti cosa è? Grazie!

Tecnicamente si chiama automa a stati finiti. Vedi se la definizione che trovi cercando su google ti basta.

speedyant: Implementare una macchina a stati finiti?

Ma no, non esageriamo...

A parte l'eventuale debounce (da risolvere via hardware con condensatore) il fatto è che deve mandare NoteON quando il pulsante va da LOW a HIGH, e poi un NoteOFF quando va da HIGH a LOW. Quindi non c'è bisogno di nessuna macchina a stati finiti o altre cose complicate, basta sapere il precedente valore di ogni input, come si fa generalmente...

Una cosa del tipo:

  if (input1 == HIGH && input1old == LOW){
    // Transizione LOW - HIGH -> NOTE ON
    noteOn(0x90, 0x2A, 0x45);
  }
  if (input1 == LOW && input1old == HIGH){
    // Transizione HIGH - LOW -> NOTE OFF
    noteOff(0x90, 0x2A);
  }
  input1old = input1;
  if (input2 == HIGH && input2old == LOW){
    // Transizione LOW - HIGH -> NOTE ON
    noteOn(0x90, 0x3A, 0x45);
  }
  if (input2 == LOW && input2old == HIGH){
    // Transizione HIGH - LOW -> NOTE OFF
    noteOff(0x90, 0x3A);
  }
  input2old = input2;

Grazie docdoc, era proprio questo quello che cercavo. Effettivamente la chiave è stata quella di verificare il passaggio da LOW a HIGH piuttosto che analizzare il solo stato HIGH sul pin. Così funziona esattamente come mi aspettavo, senza nemmeno bisogno di condensatori.

Grazie!!