Archivi tag: dato

Appunti di programmazione su Arduino: tipi di dati


byte
Byte memorizza numeri a 8 bit (1 byte) interi (senza decimali) ed hanno un range da 0 a 255.

byte someVariable = 180; // dichiara 'someVariable'
                         // come una variabile di tipo byte

int
Gli interi sono dei tipi di dato usati per memorizzare numeri senza decimali e memorizzano valori a 16 bit (2 byte) nel range da 32.767 a -32.768

int someVariable = 1500; // dichiara 'someVariable'
                         // come una variabile di tipo intero

Nota:: le variabili intere se raggiungono il valore massimo o minimo in operazioni di aritmetiche o di confronto, ad esempio se x = 32.767 e ad x aggiungiamo 1:

x = x + 1

o in altro modo

x++

il nuovo valore di x sarà -32.768.

quindi il range da 32.767 a -32.768 è da considerare non come una retta di numeri ma come una circonferenza il cui massimo e minimo sono consecutivi.

long
estende la dimensione degli interi, senza virgola, memorizzati con 32 bit (4 byte) e quindi il range dei valori possibili va da 2.147.483.647 a -2.147.483.648.

long someVariable = 90000; // dichiara che 'someVariable'
                           // è di tipo long

float
E’ un tipo di dato usato per i numeri in virgola mobile ed è usato per la rappresentazione di numeri piccolissimi o grandissimi con o senza segno e con o senza decimaili. I float sono memorizzati utilizzando 32 bit (4 byte) nel range tra 3,4028235E+38 a -3,4028235E+38.

float someVariable = 3,14; // dichiara che 'someVariable'
                           // è di tipo in virgola mobile

Nota: i numeri in virgola mobile non sono esatti e possono condurre a risultati strani. Per la loro dimensione l’esecuzione di calcoli con tipi float è più lunga dei calcoli realizzati con tipi interi. Se la situazione lo permette evitate l’uso di variabili di tipo float.

Vediamo quali sono i problemi a cui si può incorrere quando si confrontano valori in virgola mobile e vediamo una possibile soluzione.

float valore = 0.5;

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

void loop()
{
  valore = valore - 0.1; // riduce il valore di 0,1 ogni volta che
                         // si ripete il ciclo
  if( valore == 0)
    Serial.println("Il valore è esattamente 0");
  else if(fabs(valore) < .0001) // funzione per ricavare il valore
                                // assoluto
                                // di un numero decimale
    Serial.println("Il valore e' abbastanza vicino a zero");
  else
    Serial.println(valore);

  delay(1000);
}

Usare operazioni con numeri in virgola mobile restituisce numeri che possono avere errori di approssimazione.
Per superare il problema non bisogna verificare che i valori siano esattamente quelli che ci si aspetterebbe usando l'aritmetica standard, ma bisogna verificare che i valori calcolati si trovino all'interno di un intervallo di valori.

L'output dello sketch precedente sarà:

0.50
0.40
0.30
0.20
0.10
Il valore e' abbastanza vicino a zero
-0.10
-0.20
...

Analizzando il codice ci si aspetterebbe che quando valore assume il valore 0.1, sottraendo successivamente 0.1 venga eseguita la porzione di codice:

if( valore == 0)
    Serial.println("Il valore è esattamente 0");

ma valore non assumerà mai il valore 0, si avvicinerà molto ma non sarà mai 0.
Quindi l'unico modo per rappresentare il risultato di calcoli di numeri in virgola mobile è quella di darne un'approssimazione.

Array
Un array è un insieme di valori a cui si accede con un indice.
Un valore nell'array può essere richiamato con il nome dell'array e l'indice numerico che corrisponde al numero d'ordine del valore nell'array.
Gli array vengono indicizzati partendo dal numero zero e quindi il primo valore dell'array avrà indice 0.
Un array deve essere dichiarato ed opzionalmente si possono assegnare i valori prima di utilizzarlo.

int myArray[] = { value0, value1, value2...}

Allo stesso modo è possibile dichiarare un array dichiarandone il tipo e la dimensione e poi assegnare i valori:

int myArray[5]; // dichiara un array di interi avente una dimensione di 6
myArray[3] = 10; // assegna in quarta posizione il valore 10

Per recuperare un valore all'interno di un array, bisogna dichiarare una variabile a cui poi viene assegnato il valore assunto allo specifivo indice:

x = myArray[3]; // ora x ha il valore 10

Gli array sono molto spesso utilizzati all'interno dei cicli for, dove il contatore di incremento è anche usato come indice posizionale per ogni valore dell'array. L'esempio che segue viene utilizzato per l'accensione e spegnimento rapido (fliker) di un LED. Usando un ciclo for, il contatore incomincia da 0, scrive il valore nell'array fliker[] in posizione 0, in questo caso 180, al pin 10, pausa per 200ms, poi si sposta nella posizione successiva in quanto l'indice è incrementato di 1.

int ledPin = 10; // variabile ledPin inizializzata a 10
byte fliker[] = {180, 30, 255, 200, 10, 90, 150, 60};
                // sopra ono riportati 8 valori diversi
void setup()
{
   pinMode(ledPin, OUTPUT);
}

void loop()
{
   for (int i=0; i<8; i++)            // esegue un ciclo un numero di volte
   {                                  // pari al numero di elementi dell'array
      analogWrite(ledPin, fliker[i]); // ad ogni ciclo viene attivato ledPin          
                                      // con con un valore di duty cycle 
                                      // corrispsondente al valore indicato  
                                      // dall'indice dell'array 
      delay(200);                     // pausa di 200 ms
   }
}

Nota: il ciclo for verrà eseguito fino a quando la condizione i<8 risulta vera, cioè per valori di i che vanno da 0 a 7 compreso. Per le lezioni precedenti consultare la sezione Appunti di programmazione che trovate nella pagina Arduino di questo sito.