Progetto 8 Clessidra - Variante

Ciao a tutti, come da presentazione, la mia lacuna maggiore è la poca conoscenza della programmazione.
Detto questo, ho Arduino Uno e ho realizzato il progetto 8 dello starter kit. Siccome vorrei realizzarlo come progetto autonomo, al progetto base ho aggiunto delle varianti, o almeno ci provo.
Sono riuscito a farlo lampeggiare al raggiungimento dei 60 secondi, ma contemporaneamente vorrei che un buzzer emettesse un suono di avviso o melodia, per poi riavviarlo grazie al sensore tilt.
Nel mio caso accade questo, tutto funziona, lampeggiano i led, al termine del primo lampeggio, parte la melodia, ma io vorrei che il lampeggio e la melodia siano attivati contemporaneamente. Sicuramente ho sbagliato qualcosa e spero in un vostro aiuto.
Grazie a tutti. :smiley: :blush:

const int switchPin = 8;
unsigned long previousTime = 0;
int switchState = 0;
int prevSwitchState = 0;
int led = 7;
int pinCicalino = 10;
int melodia[] = {262, 262, 392, 392, 440, 440, 392, 349, 349, 330, 330, 294, 294, 262};
int durataNota[] = {500, 500, 500, 500, 500, 500, 1000, 500, 500, 500, 500, 500, 500, 1000};

long interval = 10000;

void setup() {
  
  for(int x=7; x>1; x--){
    pinMode(x, OUTPUT);
  }
  pinMode(switchPin, INPUT);
}

void loop(){
  unsigned long currentTime = millis(); 

  if(currentTime - previousTime > interval) { 
    previousTime = currentTime;
   
    if(led < 1)
    {
    lampeggio();
    }
    if(led < 1)
    {
    cicalino();
    }
    else
    {
    digitalWrite(led, HIGH); 
    led--;   
    }
  }

  switchState = digitalRead(switchPin);
  
  if(switchState != prevSwitchState){
    for(int x=7; x>1; x--){    
      digitalWrite(x, LOW);
    }  
    led = 7;
    previousTime = currentTime;
  }
  prevSwitchState = switchState;
}

void lampeggio()
{
  for(int x=7; x>1; x--)
  {
    digitalWrite(x, LOW);
  }
  delay(200);
  for(int x=7; x>1; x--)
  {
    digitalWrite(x, HIGH);
  }
}

void cicalino() {
  for(int nota = 0; nota < 14; nota++) {
    tone(pinCicalino, melodia[nota],durataNota[nota]);
    delay(durataNota[nota]);
    noTone(pinCicalino);
  }
}

Facendo altre prove mi sono reso conto di aver sbagliato qualcos'altro nel codice sopra, in quanto quando parte la melodia, non si resetta più. Faccio altre prove :wink:

Sbattendoci le corna, ho trovato questa soluzione… Provo a ricontrollare dove avevo sbagliato precedentemente ]:smiley:

const int switchPin = 8;
unsigned long previousTime = 0;
int switchState = 0;
int prevSwitchState = 0;
int led = 7;
int pinBuzzer = 10;
int nota;

long interval = 10000;

void setup() {
  
  for(int x=7; x>1; x--){
    pinMode(x, OUTPUT);
  }
  pinMode(switchPin, INPUT);
  pinMode(pinBuzzer, OUTPUT);
}

void loop(){
  unsigned long currentTime = millis();

  if(currentTime - previousTime > interval) {
    previousTime = currentTime;
   
    if(led < 1)
    {
    lampeggio();
    }
    if(led < 1)
    {
    buzzer();
    }
    else
    {
    digitalWrite(led, HIGH); // Accendi il LED 
    led--;    
    }
  }

  switchState = digitalRead(switchPin);
  
  if(switchState != prevSwitchState){
    for(int x=7; x>1; x--){    
      digitalWrite(x, LOW);
    }  
    
    led = 7;
    
    previousTime = currentTime;
  }
  prevSwitchState = switchState;
}

void lampeggio() {
  for(int x=7; x>1; x--)
  {
    digitalWrite(x, LOW);
  }
  delay(200);
  for(int x=7; x>1; x--)
  {
    digitalWrite(x, HIGH);
  }
  delay(150);
}

void buzzer() {
  tone(pinBuzzer,1500,500);
  }

Ciao a tutti, conosco i miei enormi limiti sulla programmazione, e mi sono reso conto, che ho un problema. Praticamente quando ho inserito il messaggio, effettuavo le prove con l'intervallo tra un led e un altro di 1 secondo, ora lo stavo trasferendo sul progetto definitivo, mi sono fatto anche una scatolina, e lo programmo per i 10 secondi a led, e mi rendo conto che anche il lampeggio e il tono del buzzer vengono imposati sui 10 secondi. Aiutatemi :wink: :*

const int switchPin = 8;

unsigned long previousTime = 0;
int switchState = 0;
int prevSwitchState = 0;
int led = 7;
int pinBuzzer = 10;
int nota;

long interval = 10000;

void setup() {
  
  for(int x=7; x>1; x--){
    pinMode(x, OUTPUT);
  }
  pinMode(switchPin, INPUT);
  pinMode(pinBuzzer, OUTPUT);
}

void loop(){
  unsigned long currentTime = millis(); 

  if(currentTime - previousTime > interval) { 
    previousTime = currentTime;
   
    if(led == 2)
    {
    lampeggio();
    }
    if(led == 2)
    {
    buzzer();
    }
    else
    {
    digitalWrite(led, HIGH);
    led--;  
    }
  }

  switchState = digitalRead(switchPin);
  
  if(switchState != prevSwitchState){
    for(int x=7; x>1; x--){    
      digitalWrite(x, LOW);
    }  
    
    led = 7;
    
    previousTime = currentTime;
  }
  prevSwitchState = switchState;
}

void lampeggio() {
  for(int x=7; x>1; x--)
  {
    digitalWrite(x, LOW);
  }
  delay(200);
  for(int x=7; x>1; x--)
  {
    digitalWrite(x, HIGH);
  }
  delay(150);
}

void buzzer() {
  tone(pinBuzzer, 392, 500);
  delay(200);
  tone(10, 660, 160);
  delay(200);
  }

Forse dico una cavolata, potrebbe essere che nel loop, sia i led che il buzzer prendano il tempo dall'unsigned long?

Scusate se rompo le scatole, ma ad ogni tentativo, vi scrivo i miei risultati, in modo tale da riuscire a capire dove ho sbagliato ]:slight_smile:
Forse ho capito il mio orrore :smiley:

Prima:

void loop(){
  unsigned long currentTime = millis(); 

  if(currentTime - previousTime > interval) { 
    previousTime = currentTime;
   
    if(led == 2)
    {
    lampeggio();
    }
    if(led == 2)
    {
    buzzer();
    }
    else
    {
    digitalWrite(led, HIGH);
    led--;  
    }
  }

Dopo:

void loop(){
  unsigned long currentTime = millis();

  if(currentTime - previousTime > interval) {
    previousTime = currentTime;
    
    digitalWrite(led, HIGH);
    led--;
  }
  else {
    if(led < 2) {
      lampeggio();
      }
    if(led < 2) {
      buzzer();
      }
  }

Grazie a tutti per il supporto :wink:

P.S. Un ringraziamento particolare al Prof. Menniti, grazie alla sua guida, sono riuscito a realizzare il mio programmatore per il BootLoader e cavetto ISP :smiley:

Ciao Angelus, cambio un poco il tuo nick perché secondo me sei candidato alla Santità XD Scusa ma leggendo ora il tuo Topic ho visto che sei stato come la famosa particella di sodio nella bottiglia di acqua Lete; ma apprezzo moltissimo il fatto che tu alla fine abbia ringraziato tutti per il supporto, probabilmente c’è un po’ di sarcasmo in quella frase o forse stai ringraziando in anticipo per il supporto che speri di avere ma lo hai espresso con tanto di quel garbo da fare quasi tenerezza :slight_smile: Quindi mi complimento con te, soprattutto vedendo gli atteggiamenti di alcuni che pur ricevendo aiuto ti pigliano quasi a ceffoni o pretendono che si cambino le leggi dell’Elettronica e della Fisica pur di poter continuare una discussione sul “giusto” binario o di quelli che chiedono consigli e poi li ignorano, convinti che siano sbagliati. Mi complimento con te per la realizzazione del tuo programmatore e ti ringrazio per il feedback.
Riguardo il tuo Topic devi considerare che pubblicare uno sketch e chiedere al Forum di verificarlo non trova facilmente riscontro perché ci vuole tempo e pazienza ed in pieno agosto in genere mancano l’uno o l’altro o entrambi :sweat_smile: però bisogna anche considerare che usare così il Forum significa crescere poco e sprecare inutilmente energie di chi vuole aiutare; il fatto che nessuno sia intervenuto ti ha “costretto” a studiare e cercare la soluzione, sei arrivato certamente ad un punto ottimale; è quello che bisognerebbe fare sempre PRIMA di ricorrere al Forum: fare l’impossibile per trovare una soluzione e chiedere solo quando le proprie conoscenze si fermano, a quel punto si sottopone un lavoro funzionante soltanto da ritoccare e diventa molto più semplice.
Detto questo e premesso che io non sono un esperto mi limito a dirti che se crei due funzioni e le esegui l’una dopo l’altra non puoi pretendere che operino assieme. A mio modesto parere dovresti ricorrere ad un altro timer per gestire il lampeggio del LED in modo indipendente e soprattutto impostando una frequenza senza ricorrere al delay per i tempi, il delay interrompe ogni altra operazione della CPU del micro e quindi anche usando due timer la pausa di lampeggio del LED bloccherebbe la melodia.
In definitiva, ma ora speriamo che intervengano gli esperti a darti il giusto aiuto, ti consiglierei di modificare la funzione della melodia sostituendo il delay con il millis e ricorrere ad un altro timer del micro per il lampeggio del LED.
Finché non interviene qualcuno vai sul sito di Leo e cerca nelle sue Guide, dovrebbe aver scritto su entrambi gli argomenti. :wink:

Grazie Prof. ti ringrazio per tutto ciò che hai scritto e provvederò da subito a seguire i tuoi consigli, sia riguardo l'utilizzo del forum, sia per l'utilizzo dei timer, anche se devo ammettere che non saprei dove mettere le mani, ma proverò a pasticciare qualcosa :smiley:
Ci tendo a precisare, che i miei ringraziamenti non sono sarcastici, tutt'altro, apprezzo moltissimo il lavoro della comunità e capisco che ognuno di noi ha una vita privata e non sempre si ha il tempo di seguire tutte le richieste di aiuto, soprattutto su richieste come la mia, che magari ai più esperti può sembrare banale, lungi da me dal voler fare polemiche che non servirebbero a nessuno.
Purtroppo è un mio grande limite, la non conoscenza di linguaggi di programmazione, che sto cercando di arginare leggendo qualcosa, ma lavorando spesso 12h al giorno, mi sta rallentando, ma non demordo.
Smanettando a destra e sinistra, avevo intuito che dipendeva dalle funzioni eseguite in sequenza, ma non conoscendo bene l'utilizzo dei timer, mi ha mandato nel panico :cold_sweat:
Non pretendo che si risponda ai miei quesiti, nulla mi è dovuto ovviamente, ma se qualcuno riuscirebbe a darmi qualche dritta, ne sarei grato :wink: Al max potrei offrire un caffè eheheh

P.S. Seguendo attentamente la tua guida, al programmatore ho aggiunto anche LM7805 in modo da renderlo autonomo e poterlo utilizzare con un'alimentazione esterna :smiley: :wink:

Buonasera, spero che Leo72 possa rispondermi, ho letto il tuo tutorial sui "Millis" e a grandi linee ho capito il funzionamento, realizzando 2 apposite funzioni, una per il lampeggio e una per il buzzer, ma c'è un però, come faccio a far lampeggiare tutti e 6 i Led? Perdonate la mia ignoranza. :blush: :blush:

Spiega meglio il problema.
Casomai potresti anche pensare ad usare uno scheduler, ad esempio il looper o il leOS, che eseguono compiti brevi ad intervalli predefiniti. In questo modo potresti programmare i 6 lampeggi, se diversi, e poi scordarti della cosa.

Chiedo venia, rileggendolo ora mi sono reso conto che mi sono spiegato malissimo nell'ultimo messaggio. Per quello che voglio fare io, la funzione Millis è perfetta, e colgo l'occasione per ringraziarti del tutorial.
Mi spiego. Il progetto base è la clessidra compresa nel kit di Arduino Uno, e siccome mi è piaciuto particolarmente, lo vorrei, diciamo confezionare in quanto mi tornerà utile per i giochi da tavolo e per tenere il tempo negli esercizi con il TRX. Detto questo, ho voluto aggiungere il lampeggio all'arrivo dei 60 secondi e per complicarmi la vita, ho aggiunto un buzzer che esegue dei toni come avviso.
Precedentemente, avevo sfruttato "for(int x=7; x>1; x--)" per far lampeggiare contemporaneamente tutti e 6 i Led, ma come mi ha fatto notare Menniti i "delay" facevano lampeggiare i Led con il tempo impostato nel "long interval", quindi un lampeggio ogni 10 secondi.
Ho letto il tuo tutorial sui Millis e ho risolto il problema, però a differenza di prima, ho dovuto dichiarare le variabili per ogni Led, es:

const byte ledPin1 = 2;
const byte ledPin2 = 3;
const byte ledPin3 = 4;
const byte ledPin4 = 5;
const byte ledPin5 = 6;
const byte ledPin6 = 7;
void lampeggio() {
   
    if (millis() - previousMillis1 > interval1) {
    previousMillis1 = millis();
    ledState ^= 1; 
    digitalWrite(ledPin1, ledState);
    digitalWrite(ledPin2, ledState);
    digitalWrite(ledPin3, ledState);
    digitalWrite(ledPin4, ledState);
    digitalWrite(ledPin5, ledState);
    digitalWrite(ledPin6, ledState);
    }
}

Ora la mia curiosità, in quanto personalmente va benissimo anche così, ma sto facendo tutto questo anche per imparare, se si poteva utilizzare una funzione più compatta, tutto qui. Spero di essere riuscito a spiegarmi correttamente senza aver scritto eresie :* :wink: Mi scuso ancora con tutti per la mia ignoranza e vi ringrazio per l'aiuto XD

Non potresti ricorrere ad un ciclo FOR ed usare direttamente i numeri dei pin (2÷7) invece dei nomi che gli hai assegnato (ledPin1, ecc)? così ti risparmi le assegnazioni, devi solo dichiararli come OUTPUT in setup (è lo puoi fare con un altro FOR)

Ciao,
in effetti ci avevo provato, ma mi veniva restitutito sempre un errore, e non ne capivo il motivo, poi ho controllato bene, e avevo posizionato male il "digitalWrite(x, ledState);", maledette parentesi graffe :blush:
Vi ringrazio per il vostro aiuto e soprattuppo per riuscire ad aprirmi la mente. Se posso, vorrei chiedervi un consiglio su un buon libro per neofiti come me, ve ne sarei grato.
Ora passo all'assemblaggio del contenitore :wink:

Vai nella sezione MegaTopic, Topic "link utili", c'è un sacco di roba di riferimento :wink: