PROBLEMA DRUM MIDI PIEZO BUZZER AIUTOOOO!!!

Salve a tutti, vi ringrazio in anticipo per l'aiuto che ci date a noi noooooooobbbssss dell'arduino. Premetto che è il mio primo post... cercherò di essere chiaro.

Seguendo questa guida
Spooky Arduino Projects

ho collegato due piezo e un connettore midi alla dashboard, con un cavo da midi a usb sono passato al pc e con cubase e un vst ho fatto suonare il tutto. Fin qui tutto bene!!

Funziona tutto a meraviglia, se non chè, se suono un piezo per volta tutto bene, riporduce il suono del vst, ma se li suono insieme uno dei due si annulla. Praticamente si annulla sempre il piezo che sta sull' analogico 0, mentre suona quello sull'analogico 1.

Prima di postarvi il codice vi elenco un altro problema riferito a quest'ultimo.. In pratica, sarà che non sono molto pratico, non riesco a settare i canali separati per strumento del vst. Anche se do 0x90-0x91-0x92 ecc su arduino una volta caricato in cubase suona tutto dallo stesso canale sia del vst che della traccia audio di cubase.

posto il codice che è un sunto di vari codici trovati su siti.. so che magari è una porcata ma abbiate pietà :smiley: please..

#define drumchan 1
#define drumchan2 2

#define switchAPin 11
#define PIEZOTHRESHOLD 40
#define PIEZOTHRESHOLD1 40

#define piezoAPin 0
#define piezoBPin 1

int val, val1,t,c;

int ledPin = 13;
byte note = 0;

int switchAState = LOW;
int currentSwitchState = LOW;

int sensorValue;
int sensorPin = 0;

void setup() {

pinMode(switchAPin, INPUT);

digitalWrite(switchAPin, HIGH);
Serial.begin(31250);
}

void loop() {

val = analogRead(piezoAPin);
if( val >= PIEZOTHRESHOLD ) {
t=0;
while(analogRead(piezoAPin) >= PIEZOTHRESHOLD/2) {
t++;
}
noteOn(0x90| (drumchan2) ,38, 0x45);
delay(t);
noteOff(0x90 | (drumchan2),38,0);
}

val1 = analogRead(piezoBPin);
if( val1 >= PIEZOTHRESHOLD1 ) {
c=0;
while(analogRead(piezoBPin) >= PIEZOTHRESHOLD1/2) {
c++;
}
noteOn(0x91,36, 0x40);
delay(100);
noteOff(0x91,36,0);

}

currentSwitchState = digitalRead(switchAPin);
// Check to see that the switch is pressed:
if (currentSwitchState == 1) {
// check to see that the switch wasn't pressed last time
// through the main loop:
noteOn(0x92, 60, 0x45);
delay (100);
if (currentSwitchState == 0) {
// set the note value based on the analog value, plus a couple octaves:
// note = note + 60;
// start a note playing:
noteOff(0x92, 60, 0x00);

// save the note we played, so we can turn it off:
switchAState = currentSwitchState;

}
}
}

void noteOn(byte cmd, byte data1, byte data2) {
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
}
// Send a MIDI note-off message. Like releasing a piano key
void noteOff(byte channel, byte note, byte velocity) {
midiMsg( (0x80 | channel), note, velocity);
}

// Send a general MIDI message
void midiMsg(byte cmd, byte data1, byte data2) {
digitalWrite(ledPin,HIGH); // indicate we're sending MIDI data
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
digitalWrite(ledPin,LOW);
}

Se qualcuno ha qualche idea vi faccio un monumento!! grazie a tutti!!

Ciao
a parte il fatto che quando si mette insieme del codice facendo un collage da altri sorgenti non sarebbe male COMMENTARE! ... vediamo come poterti aiutare:

Guardando alla svelta il codice dopo aver letto la descrizione del tuo problema (ovvero solo in quelle parti dove hai diversificato il controllo dei due piezo) mi è saltato all'occhio subito una differenza che non comprendo:

   noteOn(0x90 | (drumchan2) ,38, 0x45);
   delay(t);
   noteOff(0x90 | (drumchan2),38,0);
.
.
.
   noteOn(0x91,36, 0x40);
   delay(100);
   noteOff(0x91,36,0);

puoi spiegare il motivo di queste sostanziali differenze??

Per mettere mano così al codice, tu hai capito cosa significa il simbolo | tra 0x90 e (drumchan2) , vero??
...per non parlare poi dell'uso della variabile c senza poi averla messa la posto della t ... :-/

@stefano00: beh.. così gli hai proprio dato una "gran" mano... :-?
peccato che se poi gli funziona non guarderà neppure perchè, e "domani" sarà già qui a chiedere qualcos'altro... (e come lui potranno fare anche "decinaia" e "decinaia" di nuovi utenti...) :-/

P.S. quando posti del codice sarebbe meglio tu lo mettessi nel tag apposito, e non serve ri postare anche tutto il "cappello"...

ok prossima volta starò più attento e sarò più vago nelle spiegazioni..........
la parte iniziale l'ho copiata per sbaglio..
qual'è il tag per il codice?

ciao stefan00, il problema non è essere vaghi, anzi...
penso che più vago di così non potevi essere :slight_smile:
almeno potevi commentare (in italiano) le parti di codice modificate e (ancora più chiaro) spiegare il perchè delle modifiche. :slight_smile:
comunque benvenuto nel forum.
P.S.
il tag per inserire il codice è (code) (/code) quello con il cancelletto #
Con le parentesi quadre al posto delle tonde però.

Ok allora facciamo tutto da capo....scusate per la mia inesperienza

Fabrizio per risolvere il problema della lettura di entrambi i piezi contemporaneamente penso che dovresti fare un programma multitasking con la funzione millis().
Vedi questo link Vittorio Zuccalà: Multitasking Arduino: millis() -- PARTE 1

Allora la mia modifica fa si che il programma legga il primo piezo ogni 150 millisecondi e il secondo piezo ogni 200 millisecondi.

#define drumchan           1
#define drumchan2          2

#define switchAPin 11
#define PIEZOTHRESHOLD 40
#define PIEZOTHRESHOLD1 40

#define piezoAPin  0
#define piezoBPin  1


int val, val1,t,c;

int ledPin = 13;
byte note = 0;  

int switchAState = LOW;
int currentSwitchState = LOW;

int sensorValue;
int sensorPin = 0;

unsigned long tempo=0; //variabile che immagazzina il valore di millis()
unsigned long tempopiezo1=0;
unsigned long tempopiezo2=0;

void setup() {

  pinMode(switchAPin, INPUT);

    digitalWrite(switchAPin, HIGH);
Serial.begin(31250);  

    }
 
void loop() {  
tempo=millis(); //attribuisci allla variabile temp il valora di millis()

val = analogRead(piezoAPin);
val1 = analogRead(piezoBPin);

if(tempo>tempopiezo1+150){ //ogni 150 millisecondi controlla il //valora della variabile val

if( val >= PIEZOTHRESHOLD ) {
 t=0;
 while(analogRead(piezoAPin) >= PIEZOTHRESHOLD/2) {
   t++;
 }
 noteOn(0x90| (drumchan2) ,38, 0x45);
 delay(t);
 noteOff(0x90 | (drumchan2),38,0);
}
tempopiezo1=millis(); //questo serve per fare in modo che il controllo avvenga ad ogni ciclo
}

if(tempo>tempopiezo2+200){  //ogni 200 millisecondi controlla il valora della variabile val1  
if( val1 >= PIEZOTHRESHOLD1 ) {
 c=0;
 while(analogRead(piezoBPin) >= PIEZOTHRESHOLD1/2) {
   c++;
 }
 noteOn(0x91,36, 0x40);
 delay(100);
 noteOff(0x91,36,0);

}
tempopiezo2=millis();  //questo serve per fare in modo che il //controllo avvenga ad ogni ciclo
}

currentSwitchState = digitalRead(switchAPin);

if (currentSwitchState == 1) {
 
    noteOn(0x92, 60, 0x45);
    delay (100);
  if (currentSwitchState == 0) {
   octaves:
   
  noteOff(0x92, 60, 0x00);

switchAState = currentSwitchState;

  }
 }
}

if(tempo=34359738-1000){ //quando la variabile temp raggiunge il //valore 34359738(valore massimo salvabile in una variabile long) //riporta la variabile a 0 altrimenti il programma si interrompe
tempo=0;
}
if(tempopiezo1=34359738-1000){//leggi commento precedente
tempopiezo1=0;
}
if(tempopiezo2=34359738-1000){//leggi commento precedente
tempopiezo2=0;
}


void noteOn(byte cmd, byte data1, byte  data2) {
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
}

void noteOff(byte channel, byte note, byte velocity) {
midiMsg( (0x80 | channel), note, velocity);
}

// Send a general MIDI message
void midiMsg(byte cmd, byte data1, byte data2) {
digitalWrite(ledPin,HIGH);
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
digitalWrite(ledPin,LOW);
}

 void noteOn(byte cmd, byte data1, byte  data2) {
 Serial.print(cmd, BYTE);
 Serial.print(data1, BYTE);
 Serial.print(data2, BYTE);
}

void noteOff(byte channel, byte note, byte velocity) {
midiMsg( (0x80 | channel), note, velocity);
}


void midiMsg(byte cmd, byte data1, byte data2) {
digitalWrite(ledPin,HIGH);  // indicate we're sending MIDI data
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
digitalWrite(ledPin,LOW);
}

millis è una funzione che conta ogni microsecondo che passa.Quindi la variabile temp aumenta di 1 al passare di un microsecondo.
quando temp è superiore a 150(ogni 150 millisec) legge il piezo 1.
Lo stesso procedimento accade per la secondo piezo solo che avviene ogniu 200 millisecondi

i due intervalli di lettura 150 e 200 gli ho buttati giù così nn so se sono esatti in caso aumanta il loro intervallo (tipo 150 e 300 ecc).

Spero di essere stato chiaro e di aiuto

SPERO CHE QUESTA SIA LA VOLTA BUONA >:( >:(

@stefano00:
Beh, questa non è andata male :wink: cosa ne dici ora di cancellare gli altri due post praticamente uguali??
Così impari anche questa funzione del forum .. ricorda però che la cancellazione e la modifica hanno un determinato tempo dopo il quale non funzionano più (non chiedermi quanto, perchè non lo so, ma questione di ore o pochissimi giorni)

ECCO FATTO ;D ;D ;D ALLELUIA!!!!!!

ciao stefano00 grazie per l'aiuto!! davvero.

per quanto riguarda il codice ebbene si, ho lasciato 100 al posto di C, per errore ovviamente e per quanto riguarda drumchan 2 ho trovato due codici praticamente uguali con solo quella differenza ma proandoli tutti e due non c'è stata differenza (definidre drumchan 2 o lasciare solo 0x91).

Del multitasking ne ho una vaga anzi vaghissima nozione che per caso ho letto girand osu qualche forum.. cmq verdo se funziona e spero di poter mettere risolto sul post.

ciao stefano00 prima grazie ancora per l'aiuto, allora: purtroppo non posso mettere risolto sul post perchè se copio e faccio aprtire il codice scritto da stefano00 mi da:

error: expected unqualified-id before 'if

che ho risolto mettendo tutta la parte if

if(tempo=34359738-1000){
//quando la variabile temp raggiunge il //valore 34359738(valore massimo salvabile in una variabile long) //riporta la variabile a 0 altrimenti il programma si interrompe
tempo=0;
}
if(tempopiezo1=34359738-1000){//leggi commento precedente
tempopiezo1=0;
}
if(tempopiezo2=34359738-1000){//leggi commento precedente
tempopiezo2=0;
}

mettendo tutto all'interno di loop e non fuori.

invece per quanto riguarda i problema principale purtroppo se suono un piezo in contemporanea con l'altro si annullano e continua a suonare solo uno.. :frowning:

domani do un occhiata al link mulittasking che mi hai passato. Comunque se la variazione che hai fatto riguarda già il multitasking purtroppo non funziona.. grazie ancora!!!

ricontrolla la sintassi

Allora prova a fare così:
Togli la parte che ho aggiunto io e torna al tup codice originario e aggiundi questo sotto if(val1>= PIEZOTHRESHOLD1){ ecc

if(val>= PIEZOTHRESHOLD && val1>= PIEZOTHRESHOLD1){
e qui metti il codice per ottenere una nota che è uguale alla somma delle note del primo piezo e del secondo
}

cosi solo quando entrambe le condizioni dell if sono vere arduino esegue quello che c'è all'interno dell'if

ho provato a inserire l'IF come hai segnalato tu, ma ora il problema è che scusate lignoranza in tema non so come far suonare due note assieme.

la stringa è composta così:

if(val>= PIEZOTHRESHOLD && val1>= PIEZOTHRESHOLD1){

noteOn(0x90 ,38, 0x45);
// 0x90 è il canale, 38 è la nota, 0x45 è la velocity
}

non so come far suonare due note (a livello di codice)

se scrivo
noteOn(0x90 ,38 && 54, 0x45);

oppure

noteOn(0x90 ,(38 && 54), 0x45);

oppure

noteOn((0x90 ,38 , 0x45) && (0x90 ,54 , 0x45) );

suona sempre e comunque una nota sola

anceh se provo a usare lo stesso metodo con un piezo solo come in questo caso:

if( val >= PIEZOTHRESHOLD ) {
t=0;
while(analogRead(piezoAPin) >= PIEZOTHRESHOLD/2) {
t++;
}
noteOn(0x90 ,38, 0x45);
delay(t);
noteOff(0x90 ,38,0);
}

eppure se suoni più note su una tastiera il vst le riconosce mentre le suoni assieme.. com'è possibile che con un piezo o due non gli piaccia suonare due note assieme? sicuramente c'è qualcosa che non so o che non seguo nel codice..

grazie ancora resto in attesa!!

Guarda qui e ragionaci:

noteOn(0x90 ,38, 0x45); //attivi la nota
delay(t); //aspetti t tempo
noteOff(0x90 ,38,0); //disattivi la nota

Come fa un'altra nota ad iniziare se prima deve finire questa?

Se fai una programmazione sequenziale è normale che tu abbia solo una nota alla volta, devi ragionare per eventi per avere la polifonia...

La programmazione per eventi non è così semplice da implementare, e per ottenerla serve che tu capisca a fondo quello che fai perchè per risolvere il tuo problema si possono seguire due strade:

Mettere in un ciclo gli eventi noteOn e noteOff legandoli a rispettivi ingressi, facendo in modo che si attivino in conseguenza dello stato di ciascun ingresso, tipo se 0 -> noteOff, se 1 -> noteOn, e togliendo il ritardo;

Oppure utilizzare gli interrupt per gestire i tempi e caricando dei timer per ogni nota da suonare (e questo è certamente un po più difficilotto :wink: )

Insomma, se vuoi riuscire a fare qualcosa di efficace prima mi sa che devi studiare un pochino di programmazione strutturata e per oggetti, quindi approfondire il C++ in ambiente Arduino. Altrimenti devi accontentarti della programmazione lineare (sequenziale) che stai già facendo... (e quindi niente polifonia.. :stuck_out_tongue: )

puoi farmi un esempio rispetto al primo punto?

perchè riguardo ai canali audio separati ho provato a dividerli (per sempio così, un pezzo di codice)

if( val >= PIEZOTHRESHOLD ) {
t=0;
while(analogRead(piezoAPin) >= PIEZOTHRESHOLD/2) {
t++;
}
noteOn(0x90 ,38, 0x45);
delay(t);
noteOff(0x90 ,38,0);
}
tempopiezo1=millis(); //questo serve per fare in modo che il controllo avvenga ad ogni ciclo
}

if(tempo>tempopiezo2+200){ //ogni 200 millisecondi controlla il valora della variabile val1
if( val1 >= PIEZOTHRESHOLD1 ) {
c=0;
while(analogRead(piezoBPin) >= PIEZOTHRESHOLD1/2) {
c++;
}
noteOn(0x91,36, 0x40);
delay(c);
noteOff(0x91,36,0);

}

dici che questo è comunque sequenziale?^

i piezo pin sono due ovviamente e noteOn(0x90) e noteOn (0x91) dovrebbe separare i due suoni dei due pin su due canali channel 1 e 2 ma questo non avviene.. probabilmente hai ragione tu, dovrei sapere qualcosa di più..

e per curiosità a sto punto come funziona una tastiera midi? non dovrebbe avere lo stesso procedimento?

hai qualche soluzione? qualche link utile?

hai qualche soluzione?

:cry:

Con Arduino non è come giocare con la PalyStation dove per i più pigri si possono trovare in rete "soluzioni" ai giochi, se si vuol progettare prima si deve studiare...

qualche link utile?

http://arduino.cc/en/Tutorial/HomePage
http://it.wikibooks.org/wiki/C

Semplicemente mi interessa sapere se ci sono dei siti o dei link che riguardano la programmazione ad eventi per capire bene cosa riguarda..

Visto che mi embra una cosa abbastanza complicata..

Dai link che mi hai passato non mi sembra che ne sai molto anche tu,
Sono quelli di base che abbiamo letto tutti prima di comprarci un arduino o fare musica con il pc...

Dai link che mi hai passato non mi sembra che ne sai molto anche tu,
Sono quelli di base che abbiamo letto tutti prima di comprarci un arduino o fare musica con il pc...

Per scrivere questa "cavolata" si vede proprio che non hai letto i vari interventi che ho fatto in questo forum (deve essere una tua abitudine quella di non documentarti prima...) :-/

Auguri per la tua ricerca di "aiuto" ... :-X