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.

Lavori in corso sul server

Salve a tutti gli amici che seguono il mio blog.

Lavori in corso sul sito.
A causa della grande quantità di accessi, il sito non è stato raggiungibile per qualche ora. Al fine di evitare situazioni di downtime, ho provveduto ad ulteriore aumento di memoria del server su cui è allocato maffucci.it.
Nel caso di futuri problemi tecnici, come sempre utilizzerò Twitter per informarvi. (@maffucci)

Scusate per il disguito.
Un caro saluto a tutti.

Bloccare Arduino ed altre schede alla breadboard

L’ordine durante la realizzazione dei nostri prototipi su breadboard è fondamentale, in quanto il numero di schede e di componenti potrebbe essere elevato, ordine vuol dire soprattutto facilità nel trovare possibili errori di realizzazione.

Durante il laboratorio Arduino mi sono accorto che gli studenti posizionano la schede Arduino nelle maniere più strane ed alcune volte in modo poco sicuro rischiando in alcuni casi il danneggiamento della scheda. Ieri durante il laboratorio ho richiamato uno studente che aveva collegato la scheda mediante cavo USB al computer e la faceva penzolare dal banco… ovviamente posizione non idonea… ma si sa, la fantasia degli studenti non ha limiti 🙂

Per evitare che schede e display o altri dispositivi vadano a “spasso” per il banco di lavoro adotto un metodo semplicissimo e allo stesso tempo efficace, blocco la scheda mediante un jumper del timpo mostrato nell’immagine che segue, in questo modo rendo solidale il tutto alla breadboard:

Appunti su Arduino: pilotare un display LCD

In questi giorni sto realizzando con alcuni allievi della mia classe 5′ un misuratore di temperatura che utilizza un display LCD 16×2 (16 colonne e 2 righe) compatibile con i driver dell’Hitachi HD44780. Poiché la quantità di collegamenti è elevata ho deciso di realizzare questo post per non dimenticare ed avere traccia per le future realizzazioni in classe, in modo che possa essere di riferimento per gli allievi.
Per qualsiasi dettaglio fate riferimento al tutorial che trovate sul sito Arduino.cc: LiquidCrystal – “Hello World!”

Per poter pilotare il display avete necessità di utilizzare la libreria LiquidCrystal.h che vi permette di comunicare in modalità 4 bit o 8 bit, questo vuol dire che per la trasmissione dati possono essere utilizzate 4 o 8 linee di controllo a queste si aggiungono le due linee di controllo: Register Select (RS) e Enable (E) e alla linea opzionale Read/Write (RW).

In classe ho utilizzato la modalità a 4 bit, la stessa del tutorial sul sito Arduino, ciò comporta l’utilizzo di 6 uscite digitali sulla scheda Arduino.

Disponiamo di una serie di display economici: Xiamen GDM 1602K (seguite il link per prelevare il datasheet).

Dall’immagine tratta dal datasheet, notate che il display è dotato di 16 pin e la numerazione parte da sinistra.

Nella tabella allegata trovate le funzioni di ogni piedino.

Ricordate che la piedinatura di questi display è comune alla maggior parte degli LCD 16 x 2 standard Hitachi HD44780, ma potreste trovare qualche variazione tipicamente accade per i pin 15 e 16 che potrebbero essere al posto dei pin 1 e 2 (non è il caso di questo display).
In ogni caso come potete vedere dalle fotografie (sopra) il display reca sul lato piste, una legenda con il riferimento piedino -> funzione quindi, non potete sbagliarvi.

Funzione dei piedini

  • Pin 1: Vss – collegato al GND
  • Pin 2: VDD – collegato a +5V
  • Pin 3: V0 – controllo del contrasto dei caratteri. In genere viene collegato ad un potenziometro o trimmer in configurazione partitore di tensione in modo che possiate applicare sul Pin 3 una tensione che varia da 0 a +5V e al variare della tensione varia il contrasto.
  • Pin 4: RS segnale di selezione registro – per selezionare il registro nel quale registrare ciò che appare sul display oppure selezionare il registro di funzionamento in cui viene memorizzata di volta in volta l’istruzione da eseguire per il funzionamento dell’LCD
  • Pin 5: segnale Read/Write – per selezionare la modalità di funzionamento: lettura/scrittura – collegato a GND
  • Pin 6: segnale Enable (E) – per abilitare la scrittura nei registri
  • Pin 7 al Pin 14: linee dati che si inviano o si ricebono dai registri del display. Un valore HIGH (H) indica scrittura (WRITE) del bit nel registro del display, un valore LOW (L) indica un valore letto (READ) da un registro.
  • Pin 15: A (Anodo) – piedino a cui collegare una tensione positiva (nel caso del display descritto +4,2V) che serve per la retroilluminazione del display.
  • Pin 16: K (Catodo) – piedino da collegare a GND per consentire la retroilluminazione.

I collegamenti realizzati sono identici a quelli che trovate sul tutorial: LiquidCrystal – “Hello World!” dove al posto del potenziometro abbiamo utilizzato un trimmer:

Codice:

/* uso del display LCD 16x2 standard Hitachi HD44780

  Circuito:
 * pin RS collegato al pin digitale 12
 * pin E (Enable) collegato al pin digitale 11
 * pin D4 collegato al pin digitale 5
 * pin D5 collegato al pin digitale 4
 * pin D6 collegato al pin digitale 3
 * pin D7 collegato al pin digitale 2
 * pin R/W collegato al GND
 * pin 1 e pin 4 collegati a GND
 * pin 2 collegato a +Vcc
 * centrale del potenziometro/trimmer da 10 KOhm collegato al pin 3 del'LCD
 * pin SX potenziometro/trimmer collegato a +Vcc
 * pin DX potenziometro/trimmer collegato a GND
 * i pin SX e DX del potenziometro/trimmer possono essere interscambiati
*/

// includere la libreria:
#include <LiquidCrystal.h>

/*
   Viene creata l'istanza dell'oggetto LiquidCrystal chiamata lcd in cui
   sono indicati i pin dell'LCD collegati alle uscite digitali di Arduino
*/
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
   //impostiamo il numero di colonne ed il numero di righe di lcd
  lcd.begin(16, 2);
  // Visualizzo il messaggio sul display
  lcd.print("Salve mondo!");
}

void loop() {
  // posiziona il cursore in colonna 0 e linea 1
  // (nota: la linea 1 e la seconda linea, poichè si conta incominciando da 0):
  lcd.setCursor(0, 1);
  // stampa il numero di secondi dall'ultimo reset
  lcd.print(millis()/1000);
}

Nel caso in cui colleghiamo il Pin 15 a +5V e il Pin 16 a GND abbiamo la retroilluminazione: