Go Down

Topic: Pianola con Arduino (Read 3605 times) previous topic - next topic

IngHooch


Funziona facendo così!!!

Code: [Select]
if(ValueDo==HIGH)
{   tone(Buzzer,262);
delay(10);
noTone(Buzzer);
}


IngHooch come dici tu però senza impostare il tempo alla funzione tone.

Però ora si tratta solo di trovare il delay giusto perchè a 10 è troppo basso e distorce... Però a 100 si sente il buzzer staccare e attaccare velocemente.


Qui devi fare un po' di prove. Leggi il post precedente e guarda di capire bene la logica del duration + delay  :%
The brightest flame burns quickest

francescobonassi

Non riesco a capire...
if(digitalRead(Do) == HIGH){
tone(Buzer, 262, duration);
delay(duration);
noTone(Buzer);
}
Inizia a suona Do per duration, aspetta duration e poi spegne... Poi ricomincia... Non capisco l'utilità di impostare duration anche a tone.

IngHooch

Scusa hai ragione sono del tutto equivalenti le due istruzioni

Code: [Select]


tone(Buzer, 262, duration);



e

Code: [Select]

tone(Buzer, 262);
delay(duration);
noTone();



Tuttavia come ho già detto se usi la prima istruzione è buona norma mettere un delay di duration dietro in modo che non ti suoni due note insieme.

Per esempio:

Code: [Select]


tone(Buzer, 262, duration); //suona le due note insieme per duration
tone(Buzer, 565, duration);



se invece fai

Code: [Select]


tone(Buzer, 262, duration); //suona il DO
delay(duration); //aspetta che finisce il Do
tone(Buzer, 565, duration); //Suona un'altra nota


The brightest flame burns quickest

Testato

io pero' ritornerei ai while, l'unica cosa che devi fare e' che all'interno del while ci deve essere anche il controllo per vedere se il tasto e' ancora premuto o no.
Perche' quando entri nel while sei in un loop chiuso, fai solo quello che c'e' nel while, non altro.
Il loop stesso di arduino e' un while (l'ho imparato da leo  :))
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

leo72


io pero' ritornerei ai while, l'unica cosa che devi fare e' che all'interno del while ci deve essere anche il controllo per vedere se il tasto e' ancora premuto o no.
Perche' quando entri nel while sei in un loop chiuso, fai solo quello che c'e' nel while, non altro.
Il loop stesso di arduino e' un while (l'ho imparato da leo  :))

E' un ciclo for. Cmq è un ciclo infinito da cui non se ne esce. E' un "raggiro" fatto per imbrogliare il compilatore perché in un programma in C che gira sul computer esiste il caso che, al termine del programma, il controllo sia reso al sistema operativo. Ma su un micro non esiste tale ambiente superiore, una "cosa" cioè a cui rendere il controllo, per cui nel core dell'Arduino all'interno del file main.c è stato inserito lo spezzone di codice contenuto in loop() all'interno di un ciclo infinito.

@Francesco:
esistono infinite combinazioni di casi che portano ad uno stesso risultato, ti sono state suggerite molte di esse. A questo punto prendi ed inizia a studiarti le varie casistiche altrimenti passi più tempo qui sul forum a chiedere questo o quello piuttosto che ad imparare a programmare per conto tuo  ;)

Testato

il loop di arduino e' un for ?
ci avrei giurato che tu mi avessi detto fosse un while,
cmq va bene cosi'  :)
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

francescobonassi

#36
Apr 11, 2012, 10:44 pm Last Edit: Apr 11, 2012, 11:26 pm by francescobonassi Reason: 1
Comunque sia... Il codice finale che ho è questo:
Code: [Select]
int Buzzer=13; //Collego il Buzzer al pin D13
int Do=12; //Collego il pulsante Do al pin D12
int Re=11; //Collego il pulsante Re al pin D11
int Mi=10; //Collego il pulsante Mi al pin D10
int Fa=9; //Collego il pulsante Fa al pin D9
int Sol=8; //Collego il pulsante Sol al pin D8
int La=7; //Collego il pulsante La al pin D7
int Si=6; //Collego il pulsante Si al pin D6

int ValueDo; //Valore del pulsante Do
int ValueRe; //Valore del pulsante Re
int ValueMi; //Valore del pulsante Mi
int ValueFa; //Valore del pulsante Fa
int ValueSol; //Valore del pulsante Sol
int ValueLa; //Valore del pulsante La
int ValueSi; //Valore del pulsante Si

void setup() //Azioni da eseguire solo all'avvio
{
 pinMode(Buzzer,OUTPUT); //Imposto in uscita il pin D13
 pinMode(Do,INPUT); //Imposto in ingresso il pin D12
 pinMode(Re,INPUT); //Imposto in ingresso il pin D11
 pinMode(Mi,INPUT); //Imposto in ingresso il pin D10
 pinMode(Fa,INPUT); //Imposto in ingresso il pin D9
 pinMode(Sol,INPUT); //Imposto in ingresso il pin D8
 pinMode(La,INPUT); //Imposto in ingresso il pin D7
 pinMode(Si,INPUT); //Imposto in ingresso il pin D6
}

void loop() //Azioni da ripetere all'infinito
{
 ValueDo=digitalRead(Do); //Associo al valore del pulsante Do la lettura al pin D12
 delayMicroseconds(10); //Aspetta 10us
 ValueRe=digitalRead(Re); //Associo al valore del pulsante Re la lettura al pin D11
 delayMicroseconds(10); //Aspetta 10us
 ValueMi=digitalRead(Mi); //Associo al valore del pulsante Mi la lettura al pin D10
 delayMicroseconds(10); //Aspetta 10us
 ValueFa=digitalRead(Fa); //Associo al valore del pulsante Fa la lettura al pin D9
 delayMicroseconds(10); //Aspetta 10us
 ValueSol=digitalRead(Sol); //Associo al valore del pulsante Sol la lettura al pin D8
 delayMicroseconds(10); //Aspetta 10us
 ValueLa=digitalRead(La); //Associo al valore del pulsante La la lettura al pin D7
 delayMicroseconds(10); //Aspetta 10us
 ValueSi=digitalRead(Si); //Associo al valore del pulsante Si la lettura al pin D6
 delayMicroseconds(10); //Aspetta 10us
 
 if(ValueDo==HIGH) //Se il valore del pulsante Do è alto...
 {
   tone(Buzzer,262); //...fai suonare il Buzzer a 262Hz...
   delay(10); //...aspetta 10ms...
   noTone(Buzzer); //...e poi spegni il Buzzer
 }
 
 if(ValueRe==HIGH) //Se il valore del pulsante Re è alto...
 {
   tone(Buzzer,294); //...fai suonare il Buzzer a 294Hz
   delay(10); //...aspetta 10ms...
   noTone(Buzzer); //...e poi spegni il Buzzer
 }
 
 if(ValueMi==HIGH) //Se il valore del pulsante Mi è alto...
 {
   tone(Buzzer,330); //...fai suonare il Buzzer a 330Hz
   delay(10); //...aspetta 10ms...
   noTone(Buzzer); //...e poi spegni il Buzzer
 }
 
 if(ValueFa==HIGH) //Se il valore del pulsante Fa è alto...
 {
   tone(Buzzer,349); //...fai suonare il Buzzer a 349Hz
   delay(10); //...aspetta 10ms...
   noTone(Buzzer); //...e poi spegni il Buzzer
 }
 
 if(ValueSol==HIGH) //Se il valore del pulsante Sol è alto...
 {
   tone(Buzzer,392); //...fai suonare il Buzzer a 392Hz
   delay(10); //...aspetta 10ms...
   noTone(Buzzer); //...e poi spegni il Buzzer
 }
 
 if(ValueLa==HIGH) //Se il valore del pulsante La è alto...
 {
   tone(Buzzer,440); //...fai suonare il Buzzers a 440Hz
   delay(10); //...aspetta 10ms...
   noTone(Buzzer); //...e poi spegni il Buzzer
 }
 
 if(ValueSi==HIGH) //Se il valore del pulsante Si è alto...
 {
   tone(Buzzer,494); //...fai suonare il Buzzers a 349Hz
   delay(10); //...aspetta 10ms...
   noTone(Buzzer); //...e poi spegni il Buzzer
 }
}

Funziona... Solamente che il tempo di delay impostato a 10ms (la miglior soluzione a mio parere comprata alle altre) crea un leggero disturbo in uscita sul buzzer.

Ringrazio tutti quanti per la collaborazione  :D

Testato

sei un musicista ?
facci sentire qualcosa  :)
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

IngHooch



Funziona... Solamente che il tempo di delay impostato a 10ms (la miglior soluzione a mio parere comprata alle altre) crea un leggero disturbo in uscita sul buzzer.

Ringrazio tutti quanti per la collaborazione  :D


L'importante è che tu sia soddisfatto del risultato, sono sicuro che con un po' d'impegni riuscirai a risolvere anche il disturbo che hai adesso.
The brightest flame burns quickest

leo72

@Francesco:
io nutro dei dubbi.... a ripensarci, vedendo il tuo sketch, tu manderesti in riproduzione per 10 millisecondi il tono di una nota, poi lo stacco ecc....Quindi sarebbe un continuo suona per 10 ms/stacca/suona per 10 ms/stacca/suona per 10 ms ecc... se io tengo premuto un pulsante. E' giusto?
Uhm, non mi sembra il modo corretto, però. Tu devi attivare la riproduzione di un tono in base al tasto premuto e poi disattivarlo al rilascio del pulsante, non continuare a fare suona/stacca/suona/stacca mentre vedi il tasto premuto

IngHooch

Code: [Select]

  while(ValueDo==HIGH) //Se il valore del pulsante Do è alto...
  {
    tone(Buzzer,262); //...fai suonare il Buzzer a 262Hz...
    valueDo = digitalRead(Do); //aggiorna lo stato del DO
    delay(10); //...aspetta 10ms...
  } //Se diventa basso
   noTone(Buzzer); //spegni il Buzzer e continua col codice




Potrebbe andare meglio?
The brightest flame burns quickest

dab77

No, aspetta. intanto perliamo di logica. una nota non deve essere suonata migliaia di volte ogni 10ms, che senso ha?
quindi -> while!
E io scusami, Leo, ma non sono daccordo con te, il while fa suonare la nota "mentre" Do==True. appena Do != True (quindi stacco il dito dal bottone) esce da solo dal ciclo while. o no?
tant'è che se prendi gli esempi dell'IDE e carichi lo sketch del ciclo while, c'è una routine di calibrazione che avviene mentre tieni premuto un bottone, e quando lo lasci, va avanti col programma!
Quindi, direi di riprovare il tuo primo sketch e modificare l'= con ==. comprendi la logica di ciò che scrivi e vedrai che funziona. Poi sicuramente dovrai aggiungere u8n pò di codice per il debounce, ma quello viene dopo.
Altro problema invece è che con l'uso dei while suoni una nota per volta, e so che non è questo quello che vuoi..(sono musicista anch'io...)

dab77


Code: [Select]

  while(ValueDo==HIGH) //Se il valore del pulsante Do è alto...
  {
    tone(Buzzer,262); //...fai suonare il Buzzer a 262Hz...
    valueDo = digitalRead(Do); //aggiorna lo stato del DO
    delay(10); //...aspetta 10ms...
  } //Se diventa basso
   noTone(Buzzer); //spegni il Buzzer e continua col codice




Potrebbe andare meglio?

la riga valueDo = digitalRead(Do); non serve, proprio perchè c'è già il while che controlla, e forse neanche il delay.
il noTone(Buzzer); invece serve, alla fine di tutti i 7 while per zittire la pianola!.
Fai funzionare il tutto così, poi lo facciamo diventare polifonico (secondo me con una serie di if per settare dei flag e una funzione che suona le note impostate dai flag.

leo72


Code: [Select]

  while(ValueDo==HIGH) //Se il valore del pulsante Do è alto...
  {
    tone(Buzzer,262); //...fai suonare il Buzzer a 262Hz...
    valueDo = digitalRead(Do); //aggiorna lo stato del DO
    delay(10); //...aspetta 10ms...
  } //Se diventa basso
   noTone(Buzzer); //spegni il Buzzer e continua col codice



Potrebbe andare meglio?

Ma così, finché il pulsante è premuto, continui a mandare il comando a tone ogni 10 ms. E' inutile. Il comando tone(pin, frequenza), non specificando la durata, riproduce in continua finché non viene dato un noTone. Giusto? Quindi perché far fare cose che vengono fatte in automatico?  ;)
Code: [Select]

if (digitalRead(Do)) {
  tone(Buzzer, 262);
  do {
  } while (digitalRead(Do));
  noTone(Buzzer);
}

Attivo il tono, entro nel loop, che non deve far nulla se non ciclare finché il pulsante è premuto. Una volta che viene staccato il pulsante, spengo il tono.

IngHooch

Eh sì! Decisamente meglio   :smiley-red:
The brightest flame burns quickest

Go Up