unsigned & fading

Salve a tutti!

Mi chiamo Stefano e (attualmente) studio fisica.
Seguivo Arduino da curioso ormai da un po' e finalmente, in concomitanza con un esame di elettronica, mi sono procurato una Arduino Uno.

Durante i primi esperimenti mi è capitata la seguente cosa: pasticciando il codice per fading (quello degli esempi http://arduino.cc/en/Tutorial/Fading) capita che se dichiaro tipo unsigned la variabile fadeValue il led, dopo un primo ciclo completo, esegue solo il secondo for (conto alla rovescia).

Devo dire che:

  • Se uso lo Sketch originale funziona.
  • Se riporto ad int tutto funziona.
  • Non è una mia impressione, oltre che la luminosità del led lo conferma pure il tester.

Riporto comunque tutto lo sketch che uso

unsigned time = 30, fstep=5, ledPin = 9;

void setup()  { } 

void loop()  { 
  for(unsigned fadeValue = 0 ; fadeValue <= 255; fadeValue +=fstep) { 
    analogWrite(ledPin, fadeValue);         
    delay(time); } 

  for(unsigned fadeValue = 255 ; fadeValue >= 0; fadeValue -=fstep) {
    analogWrite(ledPin, fadeValue);
    delay(time); }
}

Preciso, anche se penso sia inutile, che uso Ubuntu 12.04.

In secondo luogo, pur sapendo che è off topic ma vergognandomi ad aprire due post appena arrivato,
esiste un testo dettagliato su Arduino? ( Es. Deitel&Deitel per il C o il Sedra-Smith per l'elettronica).
Magari per una persona con un già un po' (diciamo un pochino) di C (ma non C++) e di elettronica.

Tu scrivi:
unsigned fadeValue

Ma non specifiche il tipo "int" che deve stare lì nel mezzo :wink:
Cmq per pilotare un'uscita PWM basta un tipo byte, che contiene da 0 a 255 (che poi è un unsigned char).

Grazie mille(&ventiquattro) per la risposta in tempo reale!
Per quanto riguarda l'int purtroppo devo dire che la situazione non cambia.
La questione del tipo byte comunque è molto interessante, niente memoria buttata, ma aggiungo (dopo una prova) che fa lo stesso effetto.

Ma fai lo stesso errore anche all'inizio:
unsigned time = 30

Poi per chiarezza se metti una dichiarazione di variabile per riga è meglio.

Nonostante le correzioni, il problema (o il fatto curioso), persiste.
Lo riporto:

unsigned int time = 30;
unsigned int fstep=5;
unsigned int ledPin = 9;

void setup()  { } 

void loop()  { 
  for(unsigned int fadeValue = 0 ; fadeValue <= 255; fadeValue +=fstep) { 
    analogWrite(ledPin, fadeValue);         
    delay(time); } 

  for(unsigned int fadeValue = 255 ; fadeValue >= 0; fadeValue -=fstep) {
    analogWrite(ledPin, fadeValue);
    delay(time); }
}

Comunque sia, per dover di cronaca, altri compilatori C (gcc e bloodshed sicuramente) permettono di sottintendere l'int nella dichiarazione di interi senza segno e, negli effetti, nemmeno l'IDE di Arduino riporta errori in compilazione :).

Aspetta un attimo. Ma qual è il tuo problema?
Credevo fosse che non compilava correttamente, per cui non capisco.
Una volta che ha terminato il primo for perché non deve andare al secondo?

Non lo so, però è quello che penso in quanto ciò che vedo è:

led si spegne piano -> si accende di colpo -> si spegne piano -> ... e così via.

Mentre dovrei vedere

led si spegne piano -> si accende piano -> si spegne piano -> ...

Infatti sul tester leggo una cosa tipo 4.7->2.5->1.4->4.7->2.5->1.4, Una rampa al posto di un segnale triangolare.

Tutto torna come dovrebbe essere con lo sketch originario o semplicemente cambiando il tipo di variabile da unsigned (int :)) ad int).

Prova a togliere l'uguale nella condizione fadeValue >= 0 nel secondo for. Lasciandola così il ciclo, una volta che fadeValue arriva a zero, sottrae ancora il valore fstep (nel tuo caso 5), andando sotto zero, ma essendo la variabile unsigned, probabilemente succede qualcosa che al micro magari non va tanto giù :stuck_out_tongue: (dovrebbe "fare il giro", tornare al valore max assumibile da un unsigned int, correggetemi se sbaglio)

MrX90:
Comunque sia, per dover di cronaca, altri compilatori C (gcc e bloodshed sicuramente) permettono di sottintendere l'int nella dichiarazione di interi senza segno e, negli effetti, nemmeno l'IDE di Arduino riporta errori in compilazione :).

Errori no, al massimo se metti Verbose ti mostra qualche Warnig. Comune non è mai una buona idea sottintendere i tipi perché non sai che tipo standard sarà usato dal compilatore.
E come dire che vuoi un esemplare maschile o femminile senza specificare se si tratta di un cavallo, un ippopotamo o di un pinguino. E se invece il compilatore usasse una scimmia?

Sono gli uguali che ti fregano. Lui ripete un ciclo di for perché fadeValue arriva a 255 e ripete un ciclo, aggiungengo ancora 5. Vai a 260 che però non può essere gestito, perché il PWM arriva a 255, quindi il led si spenge di colpo.

Negli effetti la prospettiva della scimmia è inquietante.

In più escludendo lo zero si risolve il problema (eliminando il 255 va bene pure byte), quindi posso dire di aver risolto e di essermi chiarito su quella che, per quanto sopra, è una cattiva abitudine.

Pensavo fosse chissà cosa ed invece era un for (pessimo esordio), negli effetti l'ordine controllo-incremento mi crea sempre problemi sugli estremi.

Grazie mille!