RISOLTO Cambio IDE, non funziona più mezzo programma

Ciao :slight_smile:
Avevo un programma funzionante su MEGA, usavo la IDE 1.0.6. Ho installato l'ultima IDE, la 1.6.5, ora mi funziona male la funzione millis e delle variabili che incrementavano non incrementano più, insomma si è incasinato tutto, anche reinstallando la vecchia IDE ormai non va più... Dove sta l'inghippo?
Grazie
ciao ciao :slight_smile:

Ciao,
bisognerebbe vedere il codice sorgente per capirlo.

Ci sono sicuramente mooooolte differenze tra l'IDE 1.0 e l'1.6, ma millis() credo sia una delle poche cose rimaste uguali :). Mi unisco alla richiesta del codice.

Vi allego il codice ragazzi, grazie :slight_smile:

Antifurto_casa_passw.ino (30.1 KB)

Rieccomi, spero di aver allegato bene il codice, mettendolo fra i suoi tag non ci stava.....
Aggiungo un'informazione, non è millis() che non va, quella funziona regolarmente, è l'incremento delle variabili, perciò un allarme mi continua all'infinito, perchè non incrementa o decrementa la rispettiva variabile....
grazie

Qualche consiglio:

  1. Sistema l'indentazione, c'è pure una funzione automatica nell'IDE per farlo.
  2. Verifica se la libreria LCD supporta le stringhe su flash e racchiudi tutte le string tra F(), ti farebbe risparmiare un po' di RAM. Verifica anche se ci sono aggiornamenti della libreria (e di tutte le altre).
  3. BARCAPANN=BARCAPANN++; e tutte le costruzioni simili sono undefined behavior. Se vuoi incrementare la variable fai solo BARCAPANN++ oppure BARCAPANN=BARCAPANN + 1. Probabilmente è questo il tuo problema.

SukkoPera:
3. BARCAPANN=BARCAPANN++; e tutte le costruzioni simili sono undefined behavior. Se vuoi incrementare la variable fai solo BARCAPANN++ oppure BARCAPANN=BARCAPANN + 1. Probabilmente è questo il tuo problema.

Si, facendo a=a++ il valore di a rimane quello attuale perché l'operazione ++ viene eseguita dopo l'assegnazione, il valore di a risulta incrementato solo alla successiva iterazione.
Modi validi sono a++, a +=1, a= a+1.

astrobeed:
Si, facendo a=a++ il valore di a rimane quello attuale perché l'operazione ++ viene eseguita dopo l'assegnazione, il valore di a risulta incrementato solo alla successiva iterazione.

Errato: il comportamento di un'istruzione del genere è del tutto indefinito nello standard C/C++. Ci sono due assegnazioni alla stessa variabile senza un sequence point che le separi.

Il compilatore potrebbe fare come dici, potrebbe fare nell'ordine inverso o potrebbe fare tutt'altro, per cui non si può dire niente su quale sarà l'effettivo valore di a dopo quella riga. A giudicare da questo thread sembrerebbe già che il GCC incluso nella 1.0 si comporti diversamente da quello della 1.6.

SukkoPera:
Errato: il comportamento di un'istruzione del genere è del tutto indefinito nello standard C/C++.

No, A++ vuol dire postincrementa A, ovvero dopo l'operazione in corso, in questo caso l'assegnazione, mentre se fai ++A vuol dire preincrementa A prima dell'operazione in corso, queste sono le regole del C/C++.
Poi cosa succede esattamente se fai A=A++ dipende anche dal compilatore, con avrgcc A rimane sempre a zero, con il C++ Borland A viene incrementato dopo l'assegnazione e se rileggi il valore risulta incrementato di 1.
Se fai A = ++A invece ottieni il risultato desiderato sempre e comunque, ovvero A si incrementa di 1 ad ogni iterazione.
Provare per credere :slight_smile:

mi tocca dare ragione ad @astro, quella bruttisima riga di codice non ha un comportamento indefinito!

esattamente, co e già detto, viene assegnata "a" ad "a" e poi incrementata, quindi il compilatore la trasforma cosi:
a=a;
++a;
e in questo caso molto probabilmente lascerà solo il comando dell'incremento.

Ciao ragazzi :slight_smile:
siete mitici!!! Come sempre... Errore azzeccato in pieno, ora funziona tutto correttamente, pensate che questo modo lo avevo trovato in un manuale online per arduino (andiamo bene).
Riepilogando, i modi per incrementare una variabile (o decrementare) sono questi:

a = ++a
a ++
a = a+1
a + = 1

Quindi i più logici e leggibili secondo me sono i primi 2, il secondo è più veloce da scrivere.....

Sukkopera, ho sistemato il codice con ctrl + t, grazie, però devi spiegarmi F(), avevo letto qualcosa sul forum relativo alla scrittura seriale, ma non pensavo servisse anche per la scrittura sul display, non ho ben capito come andrebbe messo, e se mi puoi spiegare come mai senza va a occupare più memoria...
Grazieeeeeee :slight_smile:

Mi tocca dare torto ad entrambi :). Il problema è che una riga del genere contiene due assegnazioni alla stessa variabile:

  1. Assegna ad a il valore di a
  2. Assegna ad a il valore di a + 1

È decisamente controintuitivo, ma tali assegnazioni NON sono separate da un sequence point, perché l'operatore di assegnazione degli standard C e C++ NON ne introduce uno. Lo standard C++ dice espressamente:

Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.

Nel caso in cui questo vincolo non sia rispettato, il comportamento che il compilatore deve assumere è indefinito. Ne è prova il fatto stesso che astro abbia rilevato comportamenti diversi su compilatori diversi.

Credo che in altri linguaggi, tipo C#, ci siano regole aggiuntive che rendono ben definita una riga del genere, ma in C e C++ non è così. A dire il vero, già nel C++11 le cose cambiano in una maniera che non mi è ben chiara, che pare rendere a = ++a; ben definita, mentre a = a++; dovrebbe rimanere undefined. Ci sono opinioni contrastanti :(.

Sinceramente penso che l'unica cosa sana da fare sia evitare costrutti del genere, sono cervellotici e basta.

thedrifter:
Riepilogando, i modi per incrementare una variabile (o decrementare) sono questi:

a = ++a
a ++
a = a+1
a + = 1

NOOOOOOOO! Il primo NOOOOO! Quelli "giusti" sono i seguenti:

++a;
a++;
a = a + 1;
a += 1;

Se li scrivi su una riga da soli sono tutti equivalenti, ma se li "incorpori" in altre righe hanno significati diversi (gli ultimi 2 sono uguali), per cui ti rimando a qualche corso di C :).

Scusa, ma Astrobeed ha scritto questo:

"Se fai A = ++A invece ottieni il risultato desiderato sempre e comunque, ovvero A si incrementa di 1 ad ogni iterazione."

Mettetevi d'acordo :slight_smile:
Comunque ok, ora ho capito, grazie.
Mi spieghi F()?
Ciao

Sì, ma nel post dopo ho cercato di spiegare che è sbagliato... Potrebbe essere corretto nel C++11, ma non vedo comunque motivo di usarlo, visto che ++a basta e avanza.

La macro F() serve semplicemente ad inserire stringhe nella flash invece che in RAM, permettendo di risparmiarne. Cerca sul forum e troverai bizzeffe di post in merito. Tuttavia non è detto che la tua libreria ti permetta di utilizzarla. Comunque se hai risolto il problema lascia perdere, evidentemente non sei a corto di RAM.

thedrifter:
Scusa, ma Astrobeed ha scritto questo:
"Se fai A = ++A invece ottieni il risultato desiderato sempre e comunque, ovvero A si incrementa di 1 ad ogni iterazione."
Mettetevi d'acordo :slight_smile:

Bastava fare un semplice esperimento:

void setup()
{ Serial.begin(9600);
 int a=10,b=20,c;
 a=a++;
 Serial.println(a);
 b=++b;
 Serial.println(b);
 c=a++;
 Serial.println(c);
} 
void loop() {}

Risultato Arduino Uno:
11
21

Sì ma c = a++ è ben diverso da a = a++...

@SukkoPera ti consiglio vivamente di rileggere il libro sul C!
Evitiamo di fare disinformazioni, quello che alludi è per il passaggio di parametri ad una funzione tipo

fnc(++a,a);

ecco questo è indefinito!

esiste solo una forma "giusta" che un programmatore C tollera ed è
++a;
anche se spesso per incrementare la leggibilità del codice viene usato
a += 1;

gli altri casi non sono mai usati
a = a + 1;
fa capire a chi legge il codice che non si conosce il linguaggio.

a++;
è fourviante perché l'operatore dopo la variabile significa POST INCREMENTO quindi dopo cosa andrebbe incrementata?

a = ++a;
a = a++;
fa capire che si sta scrivendo codice per l'obfuscate code contest.
tra la quale cito una che mi piace molto
a = 0;
a+ = a+++a+++a;

Siete ben cocciuti, eh!

[...] An often-cited example is the C expression i=i++, which apparently both assigns i its previous value and increments i. The final value of i is ambiguous, because, depending on the order of expression evaluation, the increment may occur before, after, or interleaved with the assignment. The definition of a particular language might specify one of the possible behaviors or simply say the behavior is undefined. In C and C++, evaluating such an expression yields undefined behavior.

Quello che citi tu è un altro caso di undefined behavior, ma non certo l'unico. "Evitiamo di fare disinformazioni".

Altro link utile: Question 3.8

vbextreme:
a = a + 1;
fa capire a chi legge il codice che non si conosce il linguaggio.

O magari che si arriva da altri linguaggi in cui l'incremento si può fare solo così, questione di abitudine.

vbextreme:
a++;
è fourviante perché l'operatore dopo la variabile significa POST INCREMENTO quindi dopo cosa andrebbe incrementata?

E questo che vuol dire? Allora ++a significa PREINCREMENTO, quindi prima di cosa andrebbe incrementata?

vbextreme:
a = ++a;
a = a++;
fa capire che si sta scrivendo codice per l'obfuscate code contest.
tra la quale cito una che mi piace molto
a = 0;
a+ = a+++a+++a;

Per me tutto ciò fa solo capire che non si sa cosa sia un sequence point.

L'unico motivo per cui tecnicamente si dovrebbe preferire ++a ad a++ (quando non da solo) è il fatto che apparentemente si può evitare di fare una copia della variabile, ma nella realtà sono abbastanza seghe mentali (Redirecting to Google Groups), almeno fino a quando si usa un compilatore decente e si parla di tipi semplici e non di oggetti complessi in cui vengono definiti gli operatori di preincremento e postdecremento, per i quali il compilatore difficilmente è in grado di capire che è meglio usare uno piuttosto che l'altro.

wikipedia è buggato! non sto nemmeno a leggerlo!

because, depending on the order of expression evaluation,

questa è un'immane DEMENZA!

i = c++; assegna ad i c e incrementa c
i = i++; assegna ad i i e incrementa i

L'ordine è ben specificato! DATO CHE SI USA IL POSTINCREMENTO!

O magari che si arriva da altri linguaggi in cui l'incremento si può fare solo così, questione di abitudine.

esattamente quello che ho detto, non conosce bene il linguaggio.

E questo che vuol dire? Allora ++a significa PREINCREMENTO, quindi prima di cosa andrebbe incrementata?

No, è un a tecnica di programmazione difensiva e si legge
"incremento a"
che altrimenti sarebbe
"a postincremento"
ma non è obbligatorio, in questo caso
a++
++a
sono intercambiabili anche se il buon senso di un programmatore C dovrebbe fargli segliere ++a;