Go Down

Topic: Come funziona FOR con IF (Read 974 times) previous topic - next topic

docdoc

..e comunque, visto che HIGH=1 e LOW=0, e facciamo a gara di compattezza ;), direi che se i requisiti sono quelli indicati dall'OP si può fare così:

Code: [Select]

  int flag = 0;
  for(int i=0; i<=3; ++i)
    flag = (flag|term[i])&!res[i];
  if (flag) {
    ...


Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

Triko93

#31
Oct 24, 2018, 01:36 pm Last Edit: Oct 24, 2018, 01:36 pm by Triko93
Code: [Select]

  int flag = 0;
  for(int i=0; i<=3; ++i)
    flag = (flag|term[i])&!res[i];
  if (flag) {
    ...



:simbolo pistola che spara alla testa:
:O
If you find my replies useful please give me a +karma.
Stay Hungry, Stay Foolish

Standardoil

Così mi suona meglio, che grazie alla valutazione di corto circuito è pure più veloce

Code: [Select]

  int flag = 0;
  for(int i=0; i<=3; ++i)
    flag = flag|(term[i]&!res[i]);
  if (flag) {
    ...

la mia versione originale era per un while, per una for serve in effetti anche una or
Comunque così si perde l'informazione (ammetto accessoria) di quale termostato ha provocato l'anomalia
Prima legge di Nelson (che sono io): Non scambiare il fine con il mezzo: ricorda "cosa" devi fare, non "come" devi farlo

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

docdoc

Comunque così si perde l'informazione (ammetto accessoria) di quale termostato ha provocato l'anomalia
Non era nei requisiti del clien... dell'OP :)

Resta comunque per me misterioso l'uso di un tale tipo di flag, ma tant'è, il requisito quello è, ed a quello rispondiamo... :D
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

Standardoil

Prima legge di Nelson (che sono io): Non scambiare il fine con il mezzo: ricorda "cosa" devi fare, non "come" devi farlo

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

docdoc

#35
Oct 24, 2018, 02:58 pm Last Edit: Oct 24, 2018, 03:00 pm by docdoc
Così mi suona meglio, che grazie alla valutazione di corto circuito è pure più veloce
Code: [Select]

  int flag = 0;
  for(int i=0; i<=3; ++i)
    flag = flag|(term[i]&!res[i]);
  if (flag) {
    ...

Ma anche no. :)
L'OR va solo tra flag e valore di term() (nel mio codice usavo le quadre perché così si può simulare con un array), prova tu stesso, il mio codice funziona come richiesto, il tuo no :) perché si perde l'informazione del valore res() quindi non soddisfa il requisito (almeno un term ad 1, nessun res a zero).

Se vuoi divertirti a provarlo (anche su Tinkercad, come ho fatto io), ecco un programmino che ho fatto poco fa "al volo":


Code: [Select]
int term[] = { 1, 0, 0, 0 };
int res[]  = { 0, 0, 1, 0 };
void setup(void)
{
  Serial.begin(9600);

  int flag = 0;
  int flagOil = 0;
  for(int i=0; i<=3; ++i) {
    Serial.print("term=");
    Serial.print(term[i]);
    Serial.print(" res=");
    Serial.print(res[i]);
    flag = (flag|term[i])&!res[i];
    flagOil = flagOil|(term[i]&!res[i]);
    Serial.print(" flagOil=");
    Serial.print(flagOil);
    Serial.print(" flag=");
    Serial.println(flag);
  }
  Serial.print("RISULTATO flagOil=");
  Serial.print(flagOil);
  Serial.print(" flag=");
  Serial.println(flag);

}

void loop()
{
}

Questo è l'output:
Code: [Select]
term=1 res=0 flagOil=1 flag=1
term=0 res=0 flagOil=1 flag=1
term=0 res=1 flagOil=1 flag=0
term=0 res=0 flagOil=1 flag=0
RISULTATO flagOil=1 flag=0
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

Standardoil

#36
Oct 24, 2018, 03:20 pm Last Edit: Oct 24, 2018, 03:22 pm by Standardoil
Scusa, forse ho capito male, ma il requisito mi sembra essere:
Se è alto un ingresso la sua corrispondente uscita deve essere alta, segnalare se in almeno un caso non lo è
Poi qui ne abbiamo viste di ogni... Ma il post originale, righe dalla 3 alla 5 mi sembra chiaro
 la tua simulazione indica che ci ho preso...
Infatti fin dalla prima riga c'è il termostato ma non la sua corrispondente uscita, fin dalla prima riga si alza il flag, e rimane alto, in realtà si potrebbe già fare un break per uscire anticipatamente....
Prima legge di Nelson (che sono io): Non scambiare il fine con il mezzo: ricorda "cosa" devi fare, non "come" devi farlo

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

docdoc

Scusa, forse ho capito male, ma il requisito mi sembra essere:
Se è alto un ingresso la sua corrispondente uscita deve essere alta, segnalare se in almeno un caso non lo è
Boh, può anche darsi, ma siamo nel classico caso dei "requisiti poco chiari perché il richiedente stesso non li ha spiegati correttamente" (e spesso con l'ulteriore clausola, classica per certi clienti, "...e forse non lo sa bene neanche lui quello che vuole" :) ).
Quello che scrisse all'inizio era:

Quote
la condizione che voglio è
- se anche una sola uscita è OFF pur avendo il termostato ON voglio accendere un flag
else
qualsiasi altra condizione il flag deve essere 0.
e poi invece (cosa che cambia un pochino la logica che si può ricavare dalla frase)

Quote
diciamo che se faccio

if term(0) == ON and RES (0) == OFF OR
term(1) == ON and RES (1) == OFF OR
term(2) == ON and RES (2) == OFF OR
term(3) == ON and RES (3) == OFF OR
term(4) == ON and RES (4) == OFF
flag = 1

è quello che voglio.
Ora quindi, o ci mette la tabella della verità delle combinazioni e relativo output desiderato, o non se ne esce.

@steve_cr se ci spieghi meglio TUTTE le combinazioni possiamo capire, altrimenti perché non prendi il mio codice di esempio e simuli su Tinkercad la logica, fino a trovare l'espressione corretta?
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

steve-cr

Non era nei requisiti del clien... dell'OP :)

Resta comunque per me misterioso l'uso di un tale tipo di flag, ma tant'è, il requisito quello è, ed a quello rispondiamo... :D

Ti tolgo la curiosità, si sa mai che non ci dormi...  :)
E' una gestione dei carichi quando hai un ben definito assorbimento che NON puoi superare.
Quindi, a rotazione, accendo i carichi (singolarmente ma anche più di uno se stanno entro l'assorbimento massimo) e poi li spengo per accendere i successivi. Però se di successivi non ce ne sono perchè quelli che ho acceso sono quelli che i vari term (x) chiamano, non ha senso accenderli e poi spegnerli per accenderli di nuovo.
Quindi, se ho i term che chiamano e le relative RES sono accese, e sono entro l'assorbimento massimo, devono rimanere accesi fintanto che un term si accende "chiamando" energia per la sua RES.
In questo caso il ciclo di "rotazione dei carichi" riparte.
Samantha Cristoforetti: "Mi fai fare un giro sul tuo ultraleggero?". "Certamente, però piloto io !"

steve-cr

Il dubbio è semplice:
Ho 5 termostati e 5 uscite
- se anche una sola uscita è OFF pur avendo il termostato ON voglio accendere un flag
else, il flag deve essere 0.

Diciamo che se faccio

if term(0) == ON and RES (0) == OFF OR
term(1) == ON and RES (1) == OFF OR
term(2) == ON and RES (2) == OFF OR
term(3) == ON and RES (3) == OFF OR
term(4) == ON and RES (4) == OFF
flag = 1

è quello che voglio.

Ma lo volevo fare, se possibile, con FOR
Io ho letto e riletto, ma dove è la differenza tra la mia prima frase (primo riquadro) e la spiegazione logica (secondo riquadro) ?
Potrebbe essere li che sbaglio, ma a me sembrano uguali
Samantha Cristoforetti: "Mi fai fare un giro sul tuo ultraleggero?". "Certamente, però piloto io !"

Triko93

Io ho letto e riletto, ma dove è la differenza tra la mia prima frase (primo riquadro) e la spiegazione logica (secondo riquadro) ?
Potrebbe essere li che sbaglio, ma a me sembrano uguali
Code: [Select]

byte status = 0;
for(byte b = 0; b < 5; b++)
{
   //Funzione che ritorna 0 se uscita ON, 1 se OFF. In questo modo
   //alla fine del FOR se avrai status > 0 sai che c'e' un uscita OFF
   status += checkExit(b);
}
if(status > 0) flag = 1; //Flag acceso
else flag = 0; //Flag spento


Ti riporto il mio codice iniziale. E' esattamente quello che vuoi fare usando un FOR!

Se 1 sola uscita e' OFF pur avendo il termostato ON oppure OFF, alla fine si accende un flag ad 1, se invece tutte le uscite sono ON il flag andra' a 0
:D
Puoi usare anche i codici super ottimizzati gia' visti!
Ma secondo me quello che vuoi fare tu e' esattamente questo!
Mi sbaglio? @steve-cr
If you find my replies useful please give me a +karma.
Stay Hungry, Stay Foolish

docdoc

#41
Oct 26, 2018, 12:04 am Last Edit: Oct 26, 2018, 12:07 am by docdoc
Io ho letto e riletto, ma dove è la differenza tra la mia prima frase (primo riquadro) e la spiegazione logica (secondo riquadro) ?
Nel primo dici (traduco leggermente) "se anche un solo res() è 0 pur avendo term() a 1 voglio flag=1, else flag=0" esatto?
Il che in pratica significa "metti flag=1 se uno o più res() sono a zero, indipendentemente dal valore di term()".
Per cui in questo caso basta testare se esiste almeno un res()=0, di term() posso fregarmene.

Nel secondo, stando all'esempio (ben più comprensibile), in pratica dici che metti flag=1 se "almeno un term() è ad 1, ed il corrispondente res() è a 0".

Cogli le differenze? So (ora) che per te "è 0 pur avendo term() a 1" significava il valore di term() associato al relativo res(), ma non era chiaro per chi non ha in mente la tua applicazione, per questo ho scritto che "cambia un pochino la logica".

Per questo NON provare in genere a "descrivere" in modo non rigoroso il requisito per un algoritmo di logica, e stando a quanto mi sembra di capire, il criterio esatto sarebbe quello che ho dedotto dal secondo, ossia:

se "almeno un term() è ad 1, ed il corrispondente res() è a 0" flag=1 altrimenti flag=0.

In ogni caso, con il codice "di test" che avevo fatto puoi simulare quello che vuoi, inserendo i valori desiderati nei due vettori in testa. Quindi ora prendi questo codice:

Code: [Select]
int term[] = { 1, 0, 0, 1 };
int res[]  = { 1, 0, 1, 0 };

void setup(void)
{
  Serial.begin(9600);

  int flag = 0;
  for(int i=0; i<=3; ++i)
    flag |= term[i]&!res[i];

  Serial.print("flag=");
  Serial.println(flag);

}

void loop()
{
}


Se il criterio è quello scritto per secondo quindi, dovrebbe essere ciò che cerchi, ad esempio per:

Code: [Select]
int term[] = { 1, 0, 0, 1 };
int res[]  = { 1, 0, 1, 0 };


flag è 1, mentre con:

Code: [Select]
int term[] = { 1, 0, 0, 0 };
int res[]  = { 1, 0, 1, 0 };


flag è 0.

Gioca con le combinazioni, se ti torna tutto, l'espressione corretta per me (e Standardoil aveva colto evidentemente prima di me la corretta soluzione tra le due possibili) è quindi:

flag |= term&!res;
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

steve-cr

#42
Oct 27, 2018, 11:03 am Last Edit: Oct 27, 2018, 11:22 am by steve-cr
Essendo dei termostati con delle resistenze, non può esistere che una RES(x) == HIGH quando il suo term(x) == LOW, ecco perché questa condizione non mi interessa, perché semplicemente SPENGO subito tutte RES() che non hanno il proprio term() acceso.


All'inizio ho scritto:
- se anche una sola uscita è OFF pur avendo il termostato ON voglio accendere un flag

il "pur avendo" è stato troppo "sintetizzato", lo ammetto, ma intendevo:

- se anche una sola uscita è OFF pur avendo il SUO termostato ON voglio accendere un flag

Chiedo venia, però io mi attengo alla lingua italiana e ho pensato, magari sbagliando, che "IL termostato" non è la stessa cosa di "UN termostato"...
Samantha Cristoforetti: "Mi fai fare un giro sul tuo ultraleggero?". "Certamente, però piloto io !"

Standardoil

Essendo dei termostati con delle resistenze, non può esistere che una RES(x) == HIGH quando il suo term(x) == LOW, ecco perché questa condizione non mi interessa, perché semplicemente SPENGO subito tutte RES() che non hanno il proprio term() acceso.

adesso però sono io che chiedo delucidazioni, scusa, ma dal post 19 tu hai esplicitamente escluso una soluzione che sarebbe andata bene, dato che hai avevi detto il contrario:
Bello, ma NON deve reagire in inverso perché potrei avere il termostato OFF e la RES ancora ON per altri motivi...

allora le soluzioni dei post 12  (fabpolli) e in particolare del post 13 (io) erano già a posto.....
Prima legge di Nelson (che sono io): Non scambiare il fine con il mezzo: ricorda "cosa" devi fare, non "come" devi farlo

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

steve-cr

#44
Oct 27, 2018, 02:51 pm Last Edit: Oct 27, 2018, 02:52 pm by steve-cr
adesso però sono io che chiedo delucidazioni, scusa, ma dal post 19 tu hai esplicitamente escluso una soluzione che sarebbe andata bene, dato che hai avevi detto il contrario:allora le soluzioni dei post 12  (fabpolli) e in particolare del post 13 (io) erano già a posto.....

Se una RES() è stata accesa a rotazione, attivo un timer e dopo x secondi la spengo passando alla successiva (se c'è una successiva che chiama).
Prima aspettavo che finisse il timer quindi poteva succedere che il termostato si spegnesse proprio in questo momento. Perciò adesso ho preferito mettere uno spegnimento incondizionato allo spegnimento del suo term().

E comunque ha poco senso avere una RES accesa se il suo term è spento, era per evitare qualsiasi complicazione e rimanere nel topic

Samantha Cristoforetti: "Mi fai fare un giro sul tuo ultraleggero?". "Certamente, però piloto io !"

Go Up