Funzione OR logica

Sto utilizzando la funzione "OR" ma sembra che non funzioni.
Il codice che uso è questo:

readDate();   // legge ore e minuti
  if (Ore  >= 21 || Ore < 7) orario = 7;
  else if (Ore >= 7 || Ore < 14) orario = 14;
  else if (Ore >= 14 || Ore < 21) orario = 21;

Se l' RTC mi scrive nella variabile Ore il numero 15, dovrei trovarmi nella variabile orario il numero 15, invece mi trovo il numero 14.

Dove sbaglio?
Saluti

LelloGi

Io vedo che orario può avere solo tre valori: 7, 14 oppure 21
spiegami come fa a diventare 15...

Che comunque dovresti trovare scritto 21. Non 14
Spiegati bene, ma bene bene...

Leggo il valore da DS3231 cosi:

void readDate(){
  Wire.beginTransmission(DS3231_I2C_ID);
  Wire.write(0x1);  
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ID, 2);  // scarica 2 bytes
  Minuti = bcd2dec (Wire.read() & 0b1111111);
  Ore = bcd2dec (Wire.read() & 0b00111111);
  
   // verifica degli orari corretti
   Serial.print("ora del RTC "); 
   Serial.println(Ore);  
   Serial.print("ora dell'allarme ");
   Serial.println(orario);
  }

Se vado a verificare i valori tramite la seriale mi trovo:

ora del RTC 16
ora dell'allarme 0
ora del RTC 16
ora dell'allarme 14

Il primo valore della variabile allarme è 0 perché la variabile è inizializzata a 0.
Poi nel SetUp ho la seconda lettura della funzione readdate() che passa attraverso gli if che ho postato in precedenza.
Tutto qui!

Quale parte di: "ma bene bene" non ti era chiara?

Non capisco quali altre informazioni devo documentare.
Non penso vi servano tutte le 287 righe di codice dello sketch.
Saluti

LelloGi

Ok, ok aspetta...
Consulto la sfera di cristallo....
.
.

.
Bene abbiamo il responso
Hai dichiarato la variabile del tipo sbagliato

steve-cr:
Io vedo che orario può avere solo tre valori: 7, 14 oppure 21
spiegami come fa a diventare 15...

LelloGi:
}[/code]

Se vado a verificare i valori tramite la seriale mi trovo:

ora del RTC 16

ora dell'allarme 0
ora del RTC 16
ora dell'allarme 14

Ahhh, allora era 14, non 15 !

Oltre che, come dice Standaroil, al limite avrebbe dovuto essere 21, perchè 15 è MAGGIORE di 14 ed è MINORE di 21, QUINDI 21, (terza righa del tuo if)

L'orario cambia perché faccio le prove in orari diversi.
Infatti adesso dovrei trovarmi 21.
Invece vedo:
ora del RTC 17
ora dell'allarme 0
ora del RTC 17
ora dell'allarme 14

Giusto per conoscenza:
volatile byte Ore = 0;
volatile byte Minuti = 0;
volatile byte orario = 0;

Trovero un'altra soluzione!

Saluti

LelloGi

Scusa è ... ma leggi le OR che hai scritto ...

Dalle 7 in poi "if (Ore >= 7 || Ore < 14) orario = 14;" è SEMPRE vera !

Guglielmo

Strano che cosi funziona:

if (Ore  >= 21 || Ore < 7) orario = 7;
  if (Ore >= 7 || Ore < 14) orario = 14;
  if (Ore >= 14 || Ore < 21) orario = 21;

confondendo il valore booleano || con l'operatore OR bit a bit | .
Provvedo alla correzione.

Saluti

LelloGi

LelloGi:
Strano che cosi funziona:

Non è strano. Hai tolto gli else, quindi la logica del programma è totalmente diversa da prima.

Forse intendevi mettere AND e non OR

gpb01:
Scusa è ... ma leggi le OR che hai scritto ...

Dalle 7 in poi "if (Ore >= 7 || Ore < 14) orario = 14;" è SEMPRE vera !

Guglielmo

e se Ore = 1 tutte e tre le condizioni sono vere... Come la mettiamo?

Fermi tutti!
DRIIIIIN.
Do la soluzione!

Traduciamo in italiano questa istruzione quando Ore vale 15:

  if (Ore  >= 21 || Ore < 7) orario = 7;
  else if (Ore >= 7 || Ore < 14) orario = 14;
  else if (Ore >= 14 || Ore < 21) orario = 21;

Se 15 è maggiore o uguale a 21 (falso) oppure (OR) 15 è minore di 7 (falso) scrivi 7 (non viene scritto)
altrimenti
Se 15 è maggiore o uguale a 7 (vero) oppure 15 è minore di 14 (falso) scrivi 14 (viene scritto perchè è vera la prima parte) [Qui, visto che io leggo nel pensiero, avresti dovuto metterci && cioè verificare che entrambe le condizioni fossero vere e non solo una delle due ;)]
altrimenti (ma ormai è tardi perchè è già scattata la condizione precedente e quindi qui non ci arriva più)
Se 15 è maggiore o uguale a 14 (vero) oppure 15 è minore di 21 (vero) scrivi 21 (anche qui avresti dovuto mettere && al posto di || perchè altrimenti scatterebbe sempre, un qualsiasi valore rende vera la prima o la seconda parte)

quindi:

  if (Ore  >= 21 || Ore < 7) orario = 7;
  else if (Ore >= 7 && Ore < 14) orario = 14;
  else if (Ore >= 14 && Ore < 21) orario = 21;

Ho vinto qualcheccosa?

Questa è la logica scritta giusta, ottimizzabile, ridondante, ma almeno giusta secondo quanto ho letto nella tua mente :wink:

LelloGi:
confondendo il valore booleano || con l'operatore OR bit a bit | .

In realtà hai confuso OR con AND mi sa :wink:

P.S.
Scusa l'ironia ma è più rivolta ai miei amici di merende che a te :wink:

Accetto di buon grado l'ironia che di questi tempi non guasta mai.
Quello che vorrei fare è questo:

Se l'orario è compreso tra le 21 e le 7 del giorno successivo la variabile orario diventa uguale a 7.
Se l''orario è compreso tra le 7 e le 14 la variabile orario diventa uguale a 14.
Se l''orario è compreso tra le 14 e le 21 la variabile orario diventa uguale a 21.
Volevo implementare queste tre operazioni, ma non avendo le idee chiare...

Saluti

LelloGi

si, ti avevo letto nella mente e modificato la tua logica con le && dove ci andavano al posto delle || :wink:
Nella prima condizione, verificando gli estremi, le or vanno bene, negli altri casi le condizioni vanno validate entrambe.
Cioè per il primo caso va bene sia che sia minore di 7 che maggiore di 21, ma negli altri due casi deve essere sia maggiore di 7 che minore di 14, e sia maggiore di 14 che minore di 21, altrimenti si prende sempre tutto (ho tralasciato gli uguali per velocità)

poi, volendo, l'ultima condizione, essendo il residio, non serve nemmeno testarla, se non è ne' la prima ne' la seconda, è per forza la terza, quindi basta un semplice else.

ciao

Ciao! Qualche consiglio per scrivere codice! "Scrivere il programma nella propria lingua" è una cosa positiva, rende comprensibile la logica del programma e possono diventare evidenti errori logici :wink:

Però sbagli nella traduzione codice C- Italiano, perché usi delle parole che nel linguaggio C non esistono.
In pratica il tuo programma in italiano è perfettamente funzionante, ma non esistendo quelle parole in linguaggio C non riesci a tradurlo in modo che faccia quello che vuoi.

Se io scrivo " a compreso tra 10 e 20", è perfettamente logico, ma non esistendo in linguaggio C la parola
"compreso" non riesci a tradurlo in modo spontaneo e corretto. Allora traduci in italiano ma usando le "parole" che esistono in linguaggio C, e la traduzione avverrà in modo naturale. " Se a maggiore o uguale a 10 e a minore o uguale a 20", ad esempio questa frase può essere tradotta facilmente in linguaggio C, perché nel linguaggio esistono "parole" corrispondenti if(a>=10 && a <=20).

Grazie!

Adesso penso di avere le idee un pò più chiare sulle funzioni degli OR e degli END.
Questa sera correggo lo sketch e poi domani lo testo.
Ho allegato un file PDF con i pezzi di istruzioni che mi servono per creare 3 attuazioni giornaliere.
La prima alle ore 7, poi 14 e in fine alle 21.
Sto sperimentando un attuatore automatico di crocchette per la mia gatta.

Saluti

LelloGi

Erogatore.pdf (39.2 KB)