Capire il nostro primo sketch Arduino

Spero che sia andato tutto bene con il vostro primo esperimento con Arduino, e che il led abbia lampeggiato senza particolari problemi.

Ma rivediamo il codice del nostro progetto:

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
*/
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

Per chi già conosce qualche linguaggio di programmazione molto probabilmente avrà già intuito il funzionamento del nostro sketch: la programmazione di Arduino è davvero molto semplice, non tutti però possono aver avuto esperienze di programmazione e se siete tra questi cercherò di rendervi la comprensione del codice il più agevole possibile.

Commenti

La prima cosa che possiamo identificare nel nostro codice sono i commenti.

I commenti sono parte del programma che non è utile alla macchina e che vengono scritti dai programmatori per appuntarsi magari qualcosa da ricordare in futuro, li possiamo notare se mastichiamo un po’ di inglese infatti non assomigliano a comandi da inviare ad una macchina.

Tecnicamente possiamo riconoscerli perche sono compresi tra i simboli /* e */, tutto quello quindi che è compreso tra questi simboli viene ignorato da Arduino quando esegue lo sketch.

Nonostante la loro inutilità a livello di comandi per la scheda i commenti sono molto importanti quando il proprio codice viene riutilizzato più volte nel tempo e magari modificato, permettendoci di avere un rapido quadro di quello che succede nel nostro codice.

Oltre all’utilità per se stessi i commenti ritornano molto utili quando la creazione del codice avviene collaborativamente tra un gruppo di persone, oppure quando il programma viene rilasciato con una licenza open source, chi utilizzerà il nostro programma capira subito quello che abbiamo fatto.

C’è un’altra forma per i commenti nel nostro sketch, in questo nuovo caso il commento però è di una singola riga: questi commenti iniziano con un // (doppia barra) e continuano fino alla fine della riga.

Ad esempio nella riga di codice:

digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)

il messaggio “turn the LED on (HIGH is the voltage level)” è un commento.

Tolti tutti i commenti il codice diventa molto più scarno e probabilmente meno ostico per chi è alle prime armi:

int led = 13;

void setup() {                
  pinMode(led, OUTPUT);     
}

void loop() {
  digitalWrite(led, HIGH);
  delay(1000);
  digitalWrite(led, LOW);
  delay(1000);
}

Funzioni

Dopo questa prima semplificazione possiamo riconoscere due blocchi principali nel nostro programma, questi due blocchi sono le funzioni setup() e loop() e saranno sempre presenti in ogni sketch che creeremo per Arduino.

Una funzione (conosciuta in gergo anche come procedura o sub-routine) è un pezzo di codice identificato da un nome che può essere richiamato in qualsiasi punto dello sketch.

Le funzioni setup() e loop() però, come abbiamo già detto, sono predefinite ed indispensabili in ogni sketch e contengono i comandi base per il funzionamento dei nostri progetti.

La funzione setup() è chiamata una volta quando lo sketch inizia la sua esecuzione. Questa funzione è ideale per eseguire funzioni di configurazione iniziali (setup significa appunto organizzazione) come ad esempio impostare la modalità dei pin che utilizzeremo oppure inizializzare eventuali librerie (argomento che vedremo più avanti).

La funzione loop() invece viene richiamata continuamente e ciclicamente (loop significa anello): una volta terminata verrà richiamata e questo fino allo spegnimento della scheda.

Se premiamo il pulsante reset, oppure togliamo l’alimentazione momentaneamente, al riavvio verrà ancora eseguita la prima volta la funzione di setup() e poi partirà continuamente la funzione loop() potendo garantire una corretta configurazione della scheda ad ogni avvio.

In uno sketch Arduino bisogna sempre dichiarare entrambe le funzioni anche se, in casi estremi, non se ne ha bisogno.

Se vediamo la definizione della funzione setup() dell’esempio:

void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

Possiamo notare che la prima linea definisce le informazioni della funzione, come il suo nome: “setup”. Il testo prima e dopo il suo nome definisco il tipo del valore che la funzione restituirà e i parametri che devono essere inviati (questi parametri saranno spiegati più avanti).
Il codice che si trova tra { e } è chiamato il corpo (body) della funzione ovvero quello che la funzione fa.
Si può chiamare una funzione se è già stata definita, ad esempio la linea “pinMode(led, OUTPUT);” chiama la funzione pinMode, passando due parametri: led e OUTPUT. Questi parametri sono usati dalla funzione pinMode per decidere quale pin e configurazione impostare.

Variabili

Le variabili sono un posto dove immagazzinare dei dati. Hanno un nome, un tipo e un valore.

Per esempio, prima delle funzioni setup e loop nella riga:

int led = 13;

abbiamo dichiarato una variabile di nome “led” che ha un tipo intero (ovvero un numero senza parte decimale) e gli assegniamo un valore iniziale uguale a 13, valore che utilizzeremo poi nel nostro sketch per indicare ad Arduino su quale porta abbiamo collegato il led.

Ogni volta che il nome “led” apparirà nel codice il valore della variabile verrà recuperato.
Si potrebbe anche scegliere di non creare una variabile contenente il numero del pin ma di indicare di volta in volta nel programma il valore 13, utilizzando una variabile però abbiamo il vantaggio di poter facilmente spostare il Led su un altro pin: basta modificare il valore 13 con il nostro pin desiderato quando assegniamo il numero di pin alla variabile.

pinMode(), digitalWrite(), delay()

pinMode(led, OUTPUT);

La funzione pinMode() configura un pin di arduino come input oppure come output. Per usarla dobbiamo passare come parametro il numero del pin che vogliamo configurare e la costante INPUT oppure OUTPUT.

Quando configurato come input il pin può rilevare lo stato di un sensore come un pulsante. Come output il pin può pilotare un attuatore come nel nostro esempio un led.

Questa funzione viene generalmente usata nel setup().

La funzione digitalWrite() imposta un valore in output su di un pin. Ad esempio la riga di codice:

digitalWrite(led, HIGH);

imposta il pin “led” (pin 13) al valore HIGH (5 volt). Impostandolo a LOW il pin viene collegato a massa (assume il valore 0 volt). Otteniamo così la funzione acceso o spento del led.

La funzione delay() fa “aspettare” Arduino un determinato tempo impostato in millisecondi prima di eseguire la prossima linea di codice. Ci sono 1000 millisecondi in un secondo quindi la riga di codice:

delay(1000);

crea un ritardo di un secondo.

Mettiamo tutto assieme

Adesso che conosciamo il significato in dettaglio del nostro codice possiamo rimettere tutto assieme:

  1. Creaiamo la variabile con il numero di pin
  2. Configuriamo il pin come uscita
  3. Applichiamo 5V all’uscita (acceso)
  4. Aspettiamo un secondo
  5. Applichiamo 0V all’uscita (spento)
  6. Aspettiamo un secondo
  7. Torniamo al punto 3

Facile no?

5 commenti su “Capire il nostro primo sketch Arduino”

  1. Ciao tutto chiaro , ma avrei una domanda , perché la variabile led e posta all inizio fuori da setup ? L assegnazione del valore 13 viene fatto una volta sola ? Mi e sembrato di capire che poi il processore lavora sempre dentro all rout loop .
    Se e così allora si potrebbe mettere dentro a setup ?

    Rispondi
  2. Se avessi dichiarato la variabile led dentro alla funzione setup non avrei potuto usarla anche dentro alla funzione loop, invece avendola dichiarata fuori posso usarla in entrambe le funzioni.
    Questo avviene per un concetto più approfondito della programmazione solitamente chiamato “ambito di validità delle variabili”, non trattato in questi tutorial base.
    Per quanto riguarda invece il mettere la funzione loop dentro setup … beh così verrebbe rieseguito all’infinito anche la funzione di setup e non è il comportamento voluto.
    La distinzione in due funzioni rende molto più logico e comprensibile il codice:
    – setup esegue il setup (appunto) di come vogliamo sia configurato l’I/O della nostra scheda
    – loop contiene il programma vero e proprio (che viene eseguito in un loop continuo)
    Setup viene eseguito una volta all’inizio, loop viene rieseguito continuamente; spengo la scheda o premo reset, setup viene eseguito di nuovo una volta e poi riparte il loop continuo.

    Rispondi

Lascia un commento