If-Switch-Array-Millis-For

Mi chiarite quando si usa l'uno o l'altro ?

spesso vedo che si passa dall'uso dell'uno all'altro, quindi sembra che entrambi possano fare le stesse cose.
Ci sono cose che l'uno puo' fare e l'altro no ?

Ad esempio in questo progetto che sto' facendo voglio visualizzare per 5sec l'orario, per 5sec, la data, per 5sec la temperatura.
Voi lo fareste con IF o Switch ?

Ringrazio anticipatamente per le sicure illuminazioni che mi perverranno :slight_smile:

Lo switch serve per semplificare il codice se devi fare molti controlli uno dietro l'altro che, usando if-then-else, verrebbe fuori una sequenza illeggibile di tali costrutti.

Serve per evitere di fare un controllo dietro l'altro... invece di mettere molti if usi il CASE

quindi e' piu' un discorso stilistico e cmq con entrambi si fa tutto.

ma sul mio caso specifico come ragionare ?

stavo pensando di creare una variabile con millis che conta fino a 15sec, e poi i 3 case settati su 5-10-15

Certo ad una variabile assegni il valore di millis e poi nel case a seconda del valore esegui quello che vuoi...

il case non può lavorare con range di valori, ma solo con uguaglianze.
dal punto di vista assembly in oltre è leggermente più efficiente, soprattutto se non si usa il break.

Beh prima del case fà un controllo... ed assegna alle variabili un valore 0-1-2 ma a questo punto diventerebbe stupido, è verò me ne ero scordato... usa gli If consecutivi :slight_smile:

grazie, delle risposte,
sto' lavorando sulla creazione della data, giorno mese anno

mi potete tradurre in italiano questo comando:

long minutes  = time / MINS;    time -= minutes  * MINS;

nella variabile time ci sono i secondi, ma il resto e' una lingua che non parlo :slight_smile:

credevo fosse stato facile aggiungere la data ad un orologio :slight_smile:

ho iniziato a fare questo discorso:
1 ora = 60min
1 giorno = 24 ore
1 mese = ????????

se i mesi erano tutti di 30 giorni sarebbe stato facile, come si risolve ?

c'e' una libreria per la gestione della data ? tipo calendario ?

Intanto mettila così:

long minutes  = time / MINS;
time = time - (minutes  * MINS);

Dichiara minutes di tipo long che contiene i minuti come risultato di time/MINS
Poi da time sottrae il valore di minutes*MINS, che equivale a lasciare in time la parte decimale.

Cioè, mi spiego:
siccome minutes è un intero di tipo lungo, conterrà solo la parte intera della divisione.
Dopodiché da time verrà levata la parte intera, per lasciare solo i decimali. Come? Togliendo minutes*MINS.
E' una forma di conversione dalle date o dagli orari in formato decimale verso il formato temporale oo:mm:ss

ora e' molto piu' chiaro :slight_smile:

per il resto che fo ? mi compro un RTC ? non ci sono librerie che fungono da calendario ?

Testato:
credevo fosse stato facile aggiungere la data ad un orologio :slight_smile:

ho iniziato a fare questo discorso:
1 ora = 60min
1 giorno = 24 ore
1 mese = ????????

se i mesi erano tutti di 30 giorni sarebbe stato facile, come si risolve ?

c'e' una libreria per la gestione della data ? tipo calendario ?

Semplicemente ti fai un array con i giorni dei mesi:
mesi={31,28,31... ecc..}
Per i bisestili, li calcoli semplicemente ed aggiungi 1 giorno a febbraio nel caso di anno bisestile.

boolean bistestile(int anno) {
  if (((anno % 4) ==0) && ((anno % 100) != 0) or ((anno % 400) ==0)) {
    return true;
  } else {
    return false;
  }
}

La differenza tra IF e Switch case é anche che nelle IF puoi controllare piú condizioni e concatenarle in modo AND oppure OR.
Percui puoi usare Switch-case solo in particolari casi e non al posto del IF.
Ciao Uwe

quante cose da imparare :slight_smile:

il mio bell'orologio usa un array per passare avanti l'orario, io ne ho aggiunto un altro per la data, funziona, bravo mi sono detto.
prima di affrontare la questione dei mesi usando la strada spianata da Leo volevo creare l'IF per mandare a video 3 sec l'orario e 3 sec la data.

Debbo usare il blink without delay mi sono detto, lo modifico ed all'aspetto sembra gradevole.
Col cavolo che funziona,
Come si fa la copia di un array ?

  // IF senza delay per alternare Ora/Data
   
   if (millis() - previousMillis > interval) 
   {
    previousMillis = millis();
    
      if (alterna == ClockArray)
      alterna = DateArray;
    else
      alterna = ClockArray;
      
     // Display.
    DisplayNumberString( alterna );
    }

Gli array non puoi copiarli assegnando un array ad un altro array (credo non esistano metodi). Devi copiare i suoi elementi nell'array contenitore.

non funziona ancora

Vado a mangiare, magari a pancia piena penso meglio :slight_smile:

// IF senza delay per alternare Ora/Data
  int AlternaArray[6]={0,0,0,0,0,0};
  
   if (millis() - previousMillis > interval) 
   {
    previousMillis = millis();
    
      if (AlternaArray == ClockArray)
       {
       AlternaArray[6];
  DateArray[0] = upperDays;
  DateArray[1] = lowerDays;
  DateArray[2] = upperMonths;
  DateArray[3] = lowerMonths;
  DateArray[4] = upperYears;
  DateArray[5] = lowerYears;
  }
    else
     {
     AlternaArray[6];
       ClockArray[0] = upperHours;
  ClockArray[1] = lowerHours;
  ClockArray[2] = upperMins;
  ClockArray[3] = lowerMins;
  ClockArray[4] = upperSeconds;
  ClockArray[5] = lowerSeconds;
  
  
     // Display.
    DisplayNumberString( AlternaArray );
   }
}
}

allora, ci sono un pò di errori di base.
Se usi il nome di un array SENZA graffe, non stai utilizzando o confrontando TUTTI i suoi valori, ma l'indirizzo di memoria in cui è posizionato l'array (leggiti qualcosa sui puntatori in caso)

questo, a differenza di una copia, fa si che se ad uno dei due array vengono modificati dei valori, anche l'altro array avrà i valori modificati, perchè in realtà sono due "etichette" agli stessi dati, ovvero un'insieme di bit nella ram :slight_smile:

quindi dire:

 if (alterna == ClockArray)

equivale a dire: l'array alterna, ha (o meglio punta) lo stesso indirizzo di memoria dell'array ClockArray? sintatticamente è corretto da fare

alterna = DateArray;

vuol dire, ora alterna dovrebbe puntare all'indirizzo della prima cella di DateArray, e anche questo è corretto (ricorda che modificando alterna, anche i valori contenuti in DateArray risulteranno modificati e viceversa)

Quindi cosa c'è di sbagliato?
molto probabilmente hai dichiarato alterna come un array. gli array sono dei puntatori alla prima cella di memoria di una serie di celle di memoria nella ram (l'array dal punto di vista fisico, appunto). Cambiare questo indirizzo senza prima lanciare una free() su quella zona di memoria vuol dire che finchè il programma è in esecuzione o non termina la visibilità della variabile (savo malloc manuale ma è un'altra storia), quell'aria di memoria viene considerata "in uso" e non può essere riassegnata, è un errore di programmazione. La zona di memoria si dice garbage, e quando il garbage riempie tutta la ram sia il programma, che il sistema operativo possono crashare.
Dunque per evitare problemi, gli array hanno l'indirizzo puntato costante, se non erro. Quindi dobbiamo usare un puntatore.
alterna sarà un puntatore alla prima cella dell'array:

int *alterna;

l'if e l'assegnazione rimangono uguali, persino il display:

if (alterna == ClockArray)
      alterna = DateArray;
    else
      alterna = ClockArray;
// Display.
    DisplayNumberString( alterna );

come puoi vedere un puntatore può essere tranquillamente sostituito ad un array, l'unica differenza è che l'array si prende da solo una zona memoria, mentre col puntatore devi allocarla manualmente con una malloc(), ma in questo caso non serve perchè usi delle aree di memoria già allicate dai 2 array

spero sia chiaro e che la storia sull'indirizzo dell'array costante sia corretta, perchè non sono affatto sicuro :slight_smile:

tutto qui ?
mi mancava un asterisco ? :slight_smile:

grazie, avevo notato in altri codici quell'asterisco, credevo avesse il significato di carattere jolly :slight_smile:

funziona alla grande, il codice finale e' questo, lo posto per chi si imbattesse in questa discussione:

  // serve per cambio Ora/Data
  long previousMillis = 0;
  long interval = 3000; 
  int *alterna;
  // IF senza delay per alternare Ora/Data
   
   if (millis() - previousMillis > interval) 
   {
    previousMillis = millis();
    
      if (alterna == ClockArray)
      alterna = DateArray;
    else
      alterna = ClockArray;
      
     // Display.
    DisplayNumberString( alterna );
    }

ora devo affrontare la questone dellla gestione del mese, nel frattempo vi chiedo, il problema di overflow del millis, oltre a tutte le funzioni dell'orologio sara' presente anche su questa previousmillis che uso per lo switch, che succede dopo 2 mesi non switchera' piu' tra data e ora ?

Certamente.