Con questo articolo cominceremo una serie di post in cui verrà trattata la programmazione delle schede Arduino. Il linguaggio di base che utilizzeremo è il linguaggio C, un linguaggio di programmazione che ha fatto la storia dell’informatica e che molti di noi hanno utilizzato per sviluppare molti progetti su molte altre piattaforme. Comunque, non è sufficiente avere delle nozioni di C per poter programmare in Arduino. Infatti, come vedremo, è importante anche conoscere molti concetti legati al mondo dell’elettronica e alcuni particolari costrutti che il linguaggio C assume per poterli definire.
Approfittiamo quindi di questa serie di articoli per prendere più familiarità con la programmazione di Arduino, e per quelli che non conoscono il linguaggio C sarà un’ottima occasione per cominciare ad impararlo partendo da zero.
La Struttura di un Programma (Sketch) con Arduino
Per cominciare vediamo le prime differenze per quanto riguarda il mondo di Arduino e come viene concepito e strutturato un programma.
Gli Sketch
Per chiunque viene dal mondo della programmazione, certamente avrà familiarità con il concetto di programma: una serie di codici implementato tramite un particolare linguaggio di programmazione che viene compilato (o interpretato) con lo scopo di eseguire una determinata operazione o applicazione.
Per quanto riguarda invece il mondo di Arduino, un listato di codice che poi viene compilato ed eseguito, viene riferito come Sketch. Inoltre generalmente siamo abituati ad avere programmi in c, con estensione .c (o .cpp per C++), ma per quanto riguarda Arduino, questi saranno riconoscibili nel nostro file system con .ino come estensione.
La struttura Setup – Loop
La struttura base di uno sketch di Arduino è basata principalmente sulla definizione di due funzioni:
- void setup()
- void loop()
Queste due funzioni sono alla base di qualsiasi programma, o sketch, che dovrà essere implementato e poi compilato su Arduino, semplice o complesso che sia.
La funzione setup() è la prima ad essere invocata durante l’esecuzione dello sketch. In questa funzione vengono generalmente definite ed implementate tutte le variabili e funzioni che sono necessarie per far partire correttamente il programma.
Avremo quindi l’inizializzazione di variabili, la definizione di costanti, il controllo e l’attivazione dei pin o di periferiche collegati alla scheda Arduino. Un classico esempio è quello di impostare tutti i parametri necessari per creare una connessione seriale con un dispositivo esterno e poi chiamare una funzione per stabilire questa connessione con il dispositivo.
Quindi all’interno della funzione setup() implementeremo tutto quel codice necessario per impostare ed eseguire tutte quelle operazioni necessarie per poi far partire a pieno regime il programma vero e proprio.
Tutto il codice che invece implementa le operazioni di routine del programma, è spesso nel caso di Arduino, un’operazione ripetitiva e sarà definito all’interno della funzione loop().
Questo concetto risulta ben chiaro se vediamo lo schema di funzionamento rappresentato nella figura seguente:
Dallo schema rappresentato e da quanto detto in precedenza è facile intuire che in realtà un programma in Arduino, non ha l’evoluzione classica, di inizializzazione, svolgimento dell’operazione e conclusione con l’interruzione finale dell’esecuzione, bensì una inizializzazione al momento dell’accensione della macchina, ed una esecuzione in loop infinita che si interromperà solo allo spegnimento della macchina o alla pressione del tasto reset.
Per chi è alle prime armi con le schede elettroniche, in particolare Arduino, ed osservando le applicazioni già implementate da altri, potrà pensare che a volte Arduino rimanga in uno stato inattivo. In realtà, Arduino sta in attesa, o meglio in ascolto, in un eterno loop, di un particolare evento che faccia innescare (triggering) una determinata operazione di risposta.
Ma vediamo alcuni esempi
Esempio con void setup()
void setup() { Serial.begin(9600); pinMode(3, OUTPUT); }
In questo esempio possiamo vedere alcune istruzioni comuni che troverete in molti sketch per Arduino. Per esempio Serial.begin() si usa spesso per impostare la velocità di una comunicazione seriale (in questo caso 9600 baud) che dobbiamo stabilire per far funzionare il nostro programma. pinMode() invece è una funzione che attiva uno dei PIN presenti sulla scheda (il pin 3 in questo caso) a funzionare come una uscita di segnale (OUTPUT).
Esempio con void loop()
Dopo che le istruzioni all’interno della funzione setup() sono state eseguite, Arduino comincia ad eseguire la funzione loop() in maniera ciclica.
void loop() { digitalWrite(3, HIGH); delay(1000); digitalWrite(3, LOW); delay(1000); }
Elementi di uno sketch e relativa sintassi
Le istruzioni
Gli Sketch, quindi anche se strutturati in modo setup() e loop() sono dei veri e propri programmi costituiti da un elenco di istruzioni. Le istruzioni sono l’elemento basilare su cui si costruiscono i programmi, e nel linguaggio C si possono facilmente riconoscere perché sono sempre concluse da un punto e virgola (;).
Il carattere ‘;’ deve essere sempre aggiunto e serve al compilatore per riconoscere nel testo una parte del codice corrispondente ad una singola istruzione. La mancata aggiunta di questo carattere comporterà un errore al momento della compilazione oppure (peggio) ad una non corretta interpretazione delle istruzioni inserite.
Un blocco di istruzioni
Un blocco di istruzioni è un gruppo di istruzioni racchiuso all’interno di due parentesi graffe:
{ blocco di istruzioni }
Lo abbiamo appena visto in precedenza con le funzioni loop() e setup(), il cui comportamento veniva definito in esecuzione dalla sequenza di istruzioni contenute all’interno di due parentesi graffe.
void loop() {
blocco di istruzioni;
}
I blocchi di istruzioni non servono solo per definire le funzionalità di una funzione, ma vengono utilizzati anche in molti altri casi. Per esempio, si usano quando si hanno a che fare con delle istruzioni decisionali e con cicli for.
for (int i=0; i < n; i++) {
blocco di istruzioni;
}
In questo caso il blocco di istruzioni verrà eseguito tante volte ( più precisamente n volte).
I Commenti
Un altro elemento contenuto all’interno di un programma, e quindi anche in uno sketch è il commento. I commenti non sono altro che dei testi inseriti all’ìnterno del codice ma che vengono ignorati sia dal comilatore che dall’esecuzione delle istruzioni.
Ma perchè allora inserire del testo all’interno del programma, se non viene letto dai compilatori? Bene, i commenti hanno una funzione molto utile: servono per dare informazioni al lettore “umano” riguardo al codice riportato all’interno del programma, come per esempio la funzionalità di un blocco di istruzioni, il nome dello sviluppatore, la data e la versione dello sketch, note importanti sul significato di alcuni parametri o costanti, ecc. ecc.
Un buon codice non è solo quello scritto con una sintassi corretta ed elegante, ma è anche fornito di tutte le informazioni, tramite commenti, che rendono il programma più leggibile e manutenibile (soprattutto per gli sviluppatori che devono avere a che fare con programmi scritti da altre persone in precedenza).
In C, e quindi anche negli sketch, per definire dei commenti all’interno del codice ci sono 2 possibilità:
/*
Questo tipo di commento è adatto
per scrivere del testo su più righe
*/
e questo
// Questo commento è breve e sta su una sola riga
Conclusioni
In questo articolo introduttivo hai avuto modo di vedere come si implementano i programmi su Arduino tramite gli sketch, come sono strutturati e di quali elementi sono composti. Nel prossimo articolo vedremo le funzioni, come si implementano e che ruolo giocano all’interno della programmazione.[:en]