[RISOLTO] Convertire un int (0...255) a byte

Ciao a tutti... mi sto un po' ingarbugliando coi casting e coi tipi di dati...

fondamentalmente voglio acquisire un valore da un ingresso analogico di arduino, convertirlo nel range 0...255 e inviarlo sotto forma di singolo byte (che è unsigned) tramite seriale.

questa è la bozza:

(byte) constrain(map(analogRead(photorPin), PHOTOR_MIN, PHOTOR_MAX, 0, 255), 0, 255)

prima domanda: che tipo di dato restituisce constrain? int? unsigned int? nella documentazione non c'è scritto
seconda domanda: funzionerà mai il casting a byte? constrain è come penso un int, non rischio che i numeri maggiori di 127 vengano convertiti "male" durante il casting a byte che è unsigned?

alla fine è stato più semplice provandolo (e analizzando i singoli bit con bitRead). risultato? funziona!
morale, il casting di un (signed) int che contiene numeri da 0 a 255 ad un (unsigned byte) si può fare direttamente

constrain non ritorna un tipo particolare di dato perchè è una macro non una funzione.
dal file Arduino.h:

#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

Il compilatore sotituisce l'espressione sopra, ogni volta che la richiami nello sketch. Sempre il compilatore, in ciascuino dei confronti fa delle conversioni implicite di tipo e quello che passi agli argomenti low e high viene convertito nello stesso tipo di dato di amt.
Nel tuo caso come argomento "amt" passi la funzione map che ritorna un long, quindi il confronto avverrà tra long.

Dato che constrain per come l'hai scritta ti garantisce di non sforare la dimensione massima di un byte, non hai bisogno di fare nessun cast esplicito

byte data = constrain(map(analogRead(photorPin), PHOTOR_MIN, PHOTOR_MAX, 0, 255), 0, 255)

È tutto chiaro tranne il punto in cui dici che constrain non è una funzione. Come fa il compilatore a sapere il valore della variabile se ancora deve essere letta da analogRead?
Edit:lascia stare tutto perfetto, ho capito dopo :slight_smile:
Edit2: mi confermi però che con la tua soluzione c'è un casting implicito da long a byte? E in questo caso per me non era così ovvio che si potevano fare casting tra signed ed unsigned...

il compilatore appena incontra constrain opera la sostituzione con la macro definita in "Arduino.h"

byte data = ((map(analogRead(photorPin), PHOTOR_MIN, PHOTOR_MAX, 0, 255)) < (0) ? (0) : ((map(analogRead(photorPin), PHOTOR_MIN, PHOTOR_MAX, 0, 255)) > (255) : (map(analogRead(photorPin), PHOTOR_MIN, PHOTOR_MAX, 0, 255))

non sono così esperto di compilatori, non saprei che tipo viene assegnato a 0 e 255 ma quasi certamente non un long.

In questo caso la conversione tra variabile con segno a senza segno è "sicura" perchè ti viene garantito da constrain.

ok grazie :slight_smile:

Normalmente il tipo predefinito è "int".

Manca il ; alla fine. :wink: