Problema di inserimento bottone in una melodia

Salve. ho un problema non riesco a fare in modo che quando io premo il bottone parta la melodia e quando lo rilascio si fermi.
Questo e il mio codice:

#define NOTE_C5  523
#define NOTE_D5  587
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_G5  784
#define puls 6
  

int buzzerPin =  13;    
int melodia[] = {NOTE_G5, NOTE_E5, NOTE_C5, NOTE_C5, NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_G5, NOTE_G5, NOTE_E5};
int durataNote[] = {8,8,4,4,8,8,8,8,4,4,4,4};
int numeroNote = 12;
int val = 0; 
 

void setup() {
  pinMode(buzzerPin, OUTPUT);
  pinMode(puls,INPUT);
  
}

void loop() {

  for(int i = 0; i < numeroNote; i++){
  int durata = 1300 / durataNote[i];
  tone(buzzerPin, melodia[i], durata);
  delay(durata * 1.3);
    
  }
  
    val=digitalRead(puls); 
  if(val==HIGH){ 
   digitalWrite(buzzerPin,HIGH);
  }
  else {
  digitalWrite(buzzerPin,LOW); 
  }}

In allegato vi lascio anche il file:

clasconino.ino (764 Bytes)

Buongiorno, :slight_smile:
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

Questo è il tuo programma al quale ho apportato "al volo" qualche correzione e adattamento (non l'ho provato...) ma vedi tu se fa qualcosa di simile a quello che vuoi fare.
Ovviamente non per darti la "pappa pronta" ma per darti alcune indicazioni anche generali che ti potranno essere utili anche in futuro. Vedi in particolare i commenti, ed ovviamente se hai domande o dubbi chiedi pure.

#define NOTE_C5  523
#define NOTE_D5  587
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_G5  784
// i simboli per convenzione si scrivono tutti in maiuscolo per 
// distinguerli dalle variabili
#define PULS 6
// Anche il numero del pin meglio definirlo come simbolo e 
// non come variabile (visto che non varia...)
#define BUZZER 13

// Il numero di note è costante, definiscila come costante o, meglio, simbolo
#define NUM_NOTE 12
int melodia[NUM_NOTE] = {NOTE_G5, NOTE_E5, NOTE_C5, NOTE_C5, NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_G5, NOTE_G5, NOTE_E5};
int durataNote[NUM_NOTE] = {8,8,4,4,8,8,8,8,4,4,4,4};

// Se un valore ti serve solo per un test non serve memorizzarlo
//int val = 0;

// Questo flag indica se sta suonando o meno
bool playing = false;

// Questa variabile rappresenta la nota da suonare nel successivo loop()
// (togliendo di mezzo il ciclo for faciamo fare tutto al loop)
byte i = 0;

void setup() {
  pinMode(BUZZER, OUTPUT);
  pinMode(PULS,INPUT);
  playing = false; // Aspetto che prema il pulsante
}

void loop() {
  // Verifico se ho premuto il pulsante
  playing = ( digitalRead(PULS) == HIGH );
  // Se devo suonare, suono la prossima nota
  if ( playing ) {
    int durata = 1300 / durataNote[i];
    tone(BUZZER, melodia[i], durata);
    delay(durata * 1.3);
    // Incremento il puntatore alla prossima nota da suonare
    ++i
  }
  // Se non devo suonare o se ho finito il brano
  if ( !playing || i >= NUM_NOTE ) {
    // Spengo il suono
    noTone();
    // e riporto il puntatore alla prima nota
    i = 0;
  }
}

PS: abituati anche ad indentare decentemente il listato, vedi le modifiche che ti ho fatto. Ma nell'IDE stesso se premi Ctrl-T te lo indenta tutto lui automaticamente!

Ciao innanzitutto grazie, ho sistemato quale errore di graffe e punti e virgola (:wink: però mi da un altro errore che non riesco a capire :

exit status 1
too few arguments to function 'void noTone(uint8_t)'

Vedi qui:
noTone()

Ok sono riuscito a sistemare e non mi da più errori:). adesso provo a collegarli e ti so dire, grazie.

va tutto senza errori ma non esce nessun suono può essere che ho cablato male ? :confused:

Eh, si. Il pulsante non va collegato in quel modo.

Se vuoi che il pin vada HIGH quando premi il pulsante (vedi "digitalRead(PULS) == HIGH") devi mettere una resistenza di pull-down ossia tra il pin e GND, e non deve essere da 220 Ohm solamente (quella si usa per i led...) ma un valore alto, diciamo 10k, ed il pulsante tra il pin e 5V. A quel punto quando non premi il pulsante la resistenza terrà il pin a GND, e quando lo premi andrà a +5V quindi HIGH.

Se per semplicità vuoi evitare la resistenza esterna, puoi usare la resistenza di "pull-up" interna ad Arduino ma questo comporta quella che si chiama "logica inversa" ossia devi considerare come "tasto premuto" non più HIGH ma LOW.
Per farlo, metti il pulsante semplicemente tra pin e GND (e non più verso +5V), e nel setup usa INPUT_PULLUP invece di INPUT:

pinMode(PULS,INPUT_PULLUP);

e quindi nel test fai:

playing = ( digitalRead(PULS) == LOW );

OK ho messo le resistenze da 10k e ora funziona ma non fa la melodia fa solo un bip bip continuo :frowning: penso sia perché non rileva le note può essere
?

Non so, dipende da cosa intendi con "bip bip continuo".
Ma come sempre, quando c'è qualcosa che non va bisogna "isolare" il problema facendo na prova per volta.

Tu quindi fà una cosa intanto, modifica il programma facendo partire la riproduzione da subito (metti "bool playing = true;") e per ora ignora la pressione del pulsante (commenta la riga "playing = ( digitalRead(PULS) == HIGH );") e vedi se accendendo Arduino inizia a suonare correttamente o meno. Se suona, allora il problema è nella gestione della pressione del pulsante (es. debounce: se non hai nulla, cerca "arduino debounce" con Google e troverai qualche centinaio di post sull'argomento), ed invece se non suona allora il problema è nella gestione del suono (che tipo di buzzer è? Hai un link all'esatto buzzer che hai acquistato?).

Non lo sto facendo fisicamente per ora lo sto virtualizzando tramite https://www.tinkercad.com quindi no penso centri il buzzer. Ho provato a isolare il bottone ma facendo solo il buzzer non emette nemmeno un suono, mentre se lo faccio con il bottone quando vado a premere e tengo premuto continua a fare "bip bip" finché non rilascio il bottone.

Sono riuscito a farlo partire togliendo NUM_NOTE come costante cioè così

#define NOTE_C5  523
#define NOTE_D5  587
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_G5  784
// i simboli per convenzione si scrivono tutti in maiuscolo per
// distinguerli dalle variabili
#define PULS 6
// Anche il numero del pin meglio definirlo come simbolo e
// non come variabile (visto che non varia...)
#define BUZZER 13

// Il numero di note è costante, definiscila come costante o, meglio, simbolo

int melodia[] = {NOTE_G5, NOTE_E5, NOTE_C5, NOTE_C5, NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_G5, NOTE_G5, NOTE_E5};
int durataNote[] = {8, 8, 4, 4, 8, 8, 8, 8, 4, 4, 4, 4};

// Se un valore ti serve solo per un test non serve memorizzarlo
//int val = 0;

// Questo flag indica se sta suonando o meno
bool playing = false;

// Questa variabile rappresenta la nota da suonare nel successivo loop()
// (togliendo di mezzo il ciclo for faciamo fare tutto al loop)
byte i = 0;

void setup() {
  pinMode(BUZZER, OUTPUT);
  pinMode(PULS, INPUT);
  playing = false; // Aspetto che prema il pulsante
}

void loop() {
  // Verifico se ho premuto il pulsante
 playing = ( digitalRead(PULS) == HIGH );
  // Se devo suonare, suono la prossima nota
  if ( playing ) {
    int durata = 1300 / durataNote[i];
    tone(BUZZER, melodia[i], durata);
    delay(durata * 1.3);
    // Incremento il puntatore alla prossima nota da suonare
    ++i;
  }
    // Spengo il suono
    noTone(13);
  }

Però appena premo funziona ma appena finisce la melodia fs un bip continuo penso sia perchè ho tolto questo:
// Se non devo suonare o se ho finito il brano
if ( !playing || i >= NUM_NOTE )

Oppure lasciando tutto come hai fatto tu ma togliendo l'ultima riga ovvero quella che riporta il puntatore alla prima nota :
// e riporto il puntatore alla prima nota
i = 0;

Funziona ma finisce con un bip continuo, non ci sono altri metodi per far finire il suono e farlo ricominciare?

daniel_03_128:
appena finisce la melodia fs un bip continuo penso sia perchè ho tolto questo:
// Se non devo suonare o se ho finito il brano
if ( !playing || i >= NUM_NOTE )
Oppure lasciando tutto come hai fatto tu ma togliendo l'ultima riga ovvero quella che riporta il puntatore alla prima nota :
// e riporto il puntatore alla prima nota
i = 0;

Beh intanto per favore non togliere righe di codice "a caso": o capisci cosa stai facendo (ma hai capito cosa fa quella if?), oppure fai esattamente tutte e sole le prove con ciò che ti si consiglia.

Comunque non ho mai simulato dei buzzer su Thinkercad, non so come funzioni, per cui o provi con un circuito "vero" e quindi ci dici cosa usi e come si comporta, oppure non so cosa altro dirti, mi spiace.

Ok Grazie lo stesso.