Parere su sketch con temporizzazioni

Ciao a tutti. Mi è stato chiesto di fare un circuitino che tramite un pulsante comandasse due relè.....Spiego il funzionamento....appena do tensione al circuito il relè_5 deve partire subito ed appena premo il pulsante si deve diseccitare e trascorso un certo tempo variabile (es, da 1 a 10 secondi) e sempre tenendo premuto il pulsante si deve eccitare rele_6. A questo punto appena rilascio il pulsante il rele_6 si deve diseccitare e trascorso un certo tempo variabile(diverso dal primo caso) riecciterà nuovamente il rele_5 ed il ciclo si ripete...
Altra precisazione....Se premo il pulsante e diseccito il rele_5 e non trascorre tutto il tempo impostato come ritardo per eccitare il rele_6, al rilascio del pulsante si dovrà eccitare di nuovo il rele_5..
Lo sketch l'ho fatto,montato il circuito e provato.....tutto funziona a dovere....vi chiedo se secondo voi si poteva fare in modo diverso . Per quanto sia complicato da capire il funzionamento son riuscito a far tutto con meno di 1700 byte ma se si può migliorare ben venga....ciao e grazie

void loop(){
  
  rit_1=analogRead(A0);    //attribuisco a rit_1/2 il valore letto dai trimmer applicati sugli ingressi
  rit_2=analogRead(A2);    //analogici A0,A2 che mi servono per variare i ritardi
  
      while(digitalRead(pulsante)==HIGH){     //mentre è premuto disattivo il rele_5 ed  
      digitalWrite(rele_5,LOW);             //applico a tempo il valore di millis
      tempo=millis();
      while(millis()<(tempo+(rit_1*2))){    //mentre millis è minore di......
        if(digitalRead(pulsante)==LOW){     //controllo lo stato del pulsante,se è stato rilasciato
          digitalWrite(rele_5,HIGH);        //esco dal ciclo while senza aspettare il tempo previsto
          break;                            //e riattivo il rele_5
        }
      }
      if(digitalRead(pulsante)==HIGH){      //se invece uscendo dal ciclo il pulsante è ancora premuto
        digitalWrite(rele_6,HIGH);          //attivo il rele_6 ed assegno alla variabile stato il valore di uno
        stato = 1;                          //che uso per capire lo stato del rele_6..1=eccitato,0=diseccitato
      }
        while(stato==1){                    //mentre il rele_6 è eccitato  
          if(digitalRead(pulsante)==LOW){   //se rilascio il pulsante 
            digitalWrite(rele_6,LOW);       //lo diseccito 
            tempo=millis();
            while(millis()<(tempo+(rit_2*2))){}  //trascorso tale tempo
            digitalWrite(rele_5,HIGH);            //riattivo il rele_5 e porto a "0" lo stato del rele_6 
            stato=0;
          }
        }
    }
  }

Non vedo potenzialitá di semplificazione.

Non so se definisci una funzione

attesa(int pinrele, int ritardo){
while(stato==1){                    //mentre il rele_6 è eccitato  
          if(digitalRead(pulsante)==LOW){   //se rilascio il pulsante 
            digitalWrite(pinrele,LOW);       //lo diseccito 
            tempo=millis();
            while(millis()<(tempo+(ritardo))){}  //trascorso tale tempo
            digitalWrite(rele_5,HIGH);            //riattivo il rele_5 e porto a "0" lo stato del rele_6 
            stato=0;}
          }

guadagni spazio.
Ciao Uwe

Grazie della risposta uwefed...La domanda mi sorgeva non tanto per risparmiare spazio ma visto che non sono una cima in programmazione mi chiedevo se si poteva fare in un modo più semplice,più che altro per capire se ho usato una strada troppo lunga o sbagliata..
Ciao

visto che i while sono cilci bloccanto, in almeno un caso li pui sostituire con i delay ( while(millis()<(tempo+(rit_2*2))){} //trascorso tale tempo )

Più semplice di così la vedo dura... Si potrebbe riscrivere il tutto in modo un po' più elegante come macchina a stati, eliminando contemporaneamente l'uso delle attese bloccanti. Ciò avrebbe senso caso in cui fosse richiesta qualche altra operazione aggiuntiva, magari con temporizzazioni diverse da quelle attuali.

Forse potresti usare un Attiny85 per risparmiare spazio sulla board e i consumi del circuito.
Inoltre col core tiny, forse il programma potrebbe venire più piccolo.

Ciao e grazie a tutti delle risposte.

@lesto Hai pienamente ragione ma ho preferito usare un while solo perchè qual'ora si decidesse di interrompere il conteggio basta solo creare l'uscita dal cilclo ed aggiungerlo...

@tuxduino come imposteresti tu la cosa? Il concetto mi interessa ma per ignoranza non saprei come impostare la cosa.

@ PaoloP Pensavo anche io di non usare un 328 ma qualcosa di più piccolo...Per quanto riguarda il consumo non ho problemi in quanto la scheda la alimenterò direttamente dalla rete con trasfo o switching.....probabilmente userò un trasformatore per un problema di incompatibilità (nel caso switching) con troppi valori di tensione in ingresso es. 12-24-48-60-ed avanti fino a 230 mi conviene farmi un trasfo con un primario a diversi ingressi ed una sola uscita e poi usare un 7805 e via..Resta comunque il fatto che se deciderò di usare un tiny dovrò documentarmi perchè non ne ho mai usati.

Ciao

tonid:
Resta comunque il fatto che se deciderò di usare un tiny dovrò documentarmi perchè non ne ho mai usati.

Non hai che da chiedere :wink:

Non hai che da chiedere

Grazie della disponibilità :slight_smile:
Ora sistemo il discorso alimentazione e poi valuto il chip in base anche ai pin in/out....vi farò sapere !

tonid:
poi valuto il chip in base anche ai pin in/out....vi farò sapere !

Ecco, questo punto tienilo bene a mente, perché ci sono diversi Tiny (usabili con l'IDE di Arduino) ed ogni ha un numero diverso di linee I/O. Tieni anche a mente il fatto che i Tiny non hanno alcune periferiche presenti invece sui fratelli maggiori (manca la seriale HW, l'I2C non c'è ma può essere emulavo via SW ecc).

Ecco, questo punto tienilo bene a mente, perché ci sono diversi Tiny (usabili con l'IDE di Arduino) ed ogni ha un numero diverso di linee I/O. Tieni anche a mente il fatto che i Tiny non hanno alcune periferiche presenti invece sui fratelli maggiori (manca la seriale HW, l'I2C non c'è ma può essere emulavo via SW ecc).

Si ,infatti ho dato un occhio in rete ed ho visto delle versioni in dip8 che hanno 2kbyte su cui scrivere il sw e nel mio caso ci starei(penso) perchè arrivo a +/- 1670 ,devo vedere pero se c'è qualcosa con due ingressi analogici e 4 1/0 altrimenti dovrò passare ad una versione con più pin. Per le periferiche a cui fai riferimento è buono a sapersi ma in questo caso specifico non le utilizzerei.

Allora un ATtiny84 ti dovrebbe andare bene.

PaoloP:
Allora un ATtiny84 ti dovrebbe andare bene.

Datasheet --> http://www.atmel.com/Images/doc8006.pdf

Allora un ATtiny84 ti dovrebbe andare bene.

Hai ragione penso possa fare proprio al caso mio...
Ho visto che ha le porte che possono essere configurate come ingressi analogici o 1/0 digitali,togliendone due per il quarzo faccio tutto.

Su questi micro il quarzo normalmente non lo metti. Sono fatti per piccoli circuiti, e possono lavorare a 1 o 8 MHz con l'oscillatore interno, quindi basse tensioni e basse frequenze = bassi consumi e pochi componenti. Certo, puoi aggiungercelo il quarzo, ma solo se effettivamente ti serve una velocità elevata.

Coll'oscillatore esterno può andare a 10 o 20 Mhz.

PaoloP:
Coll'oscillatore esterno può andare a 10 o 20 Mhz.

Con l'oscillatore interno i micro Atmel vanno ad 1 MHz od 8 MHz. L'oscillatore interno è ad 8 MHz, si ottiene il valore di 1 MHz attivando il divisore /8 tramite un apposito fuse. Questo vale sia per i Tiny che per i Mega. Ad abbondanza, tutti i micro Atmel vergini escono di fabbrica settati ad 1 Mhz.

Ad esser sincero non saprei se metterlo e di che valore il quarzo.....Non ho bisogno di particolare velocità, mi interessa che funzioni la millis() per gestire i tempi dei relè,accendere 3 led di cui 2 di stato relè ed 1 che indica la presenza di alimentazione ,controllare due trimmer su due ingressi adc ed un pulsante in digitalRead.....So per certo che diminuendo il valore del quarzo diminuiscono le prestazioni del micro in termini di velocità e quindi di consumo,consumo che non mi preoccupa in questo caso, ma non so bene come funziona la cosa all'interno quindi davo sinceramente per scontato l'uso di in quarzo da 16MHz anche se credo che uno da 8 basti e avanzi per ciò che deve gestire...

Se imposti il micro ad 1 o 8 MHz non devi usare un quarzo esterno. Il chip integra un oscillatore per cui si genera internalmente il clock. Di lavorare ad un clock inferiore non devi preoccupartene, ci pensa il core ad adattare millis in modo che il calcolo sia regolato sul clock inferiore.

Se imposti il micro ad 1 o 8 MHz non devi usare un quarzo esterno. Il chip integra un oscillatore per cui si genera internalmente il clock. Di lavorare ad un clock inferiore non devi preoccupartene, ci pensa il core ad adattare millis in modo che il calcolo sia regolato sul clock inferiore.

Ciao, quindi la diminuzione del valore del quarzo influisce solamente sulla velocità di esecuzione del programma ?
Se per esempio ad una data istruzione servono tre cicli di clock,la eseguirà sempre con tre cicli di clock ma essendo inferiore il quarzo il tempo di esecuzione sarà maggiore.....giusto,no?