Archivi categoria: arduino

Lezione 4 – Arduino GamePad – Disegnare caratteri speciali su LCD1602 Keypad Shield della Keyestudio

In riferimento a quanto esposto a lezione questa mattina durante la lezione a distanza, aggiungo alcune indicazioni per disegnare icone personalizzate sul display: pacman, alieno, fantasmi, ecc… La modalità di realizzazione icone è la medesima di quella spiegata nella lezione svolta alcuni mesi fa: Disegnare caratteri personalizzati con Arduino per un LCD 16×2 in cui veniva utilizzato un display I2C.

Le modifiche per l’utilizzo dell’LCD1602 Keypad Shield della Keyestudio sono minime e di seguito indico alcuni esempi.

E’ importante, per inserire nuove icone sul display, studiare la lezione precedente in cui descrivo come realizzare le icone.

Di seguito tre esempi utili per sviluppare il vostro progetto di PCTO.

Esempio 1

In questo esempio mostro come visualizzare sulla prima riga del display una stringa di presentazione e sulla seconda riga 8 icone

1/*
2 *  Prof. Michele Maffucci
3 *  Crezione di caratteri personali
4 *  Utilizzo di un display LCD1602 Keypad Shield della Keyestudio
5 *  Data: 19.03.2021
6*/
7 
8// inclusione della libreria LiquidCrystal.h
9#include <LiquidCrystal.h>
10 
11// inizializza la libreria con i numeri dei pin dell'interfaccia
12LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
13 
14// caratteri personalizzati
15 
16byte lucchettoChiuso[8] = {
17  0b01110,
18  0b10001,
19  0b10001,
20  0b10001,
21  0b11111,
22  0b11011,
23  0b11011,
24  0b11111
25};
26 
27byte lucchettoAperto[8] = {
28  0b01110,
29  0b10000,
30  0b10000,
31  0b10000,
32  0b11111,
33  0b11011,
34  0b11011,
35  0b11111
36};
37 
38byte Altoparlante[8] = {
39  0b00001,
40  0b00011,
41  0b01111,
42  0b01111,
43  0b01111,
44  0b00011,
45  0b00001,
46  0b00000
47};
48 
49byte batteriaMezza[8] = {
50  0b01110,
51  0b11011,
52  0b10001,
53  0b10001,
54  0b10001,
55  0b11111,
56  0b11111,
57  0b11111
58};
59 
60byte alieno[8] = {
61  0b10001,
62  0b01010,
63  0b11111,
64  0b10101,
65  0b11111,
66  0b11111,
67  0b01010,
68  0b11011
69};
70 
71 
72byte pacmanBoccaChiusa[8] = {
73  0b01110,
74  0b11101,
75  0b11111,
76  0b11111,
77  0b11000,
78  0b11111,
79  0b11111,
80  0b01110
81};
82 
83byte pacmanBoccaAperta[8] = {
84  0b01110,
85  0b11101,
86  0b11111,
87  0b11100,
88  0b11000,
89  0b11000,
90  0b11111,
91  0b01110
92};
93 
94byte fantasmino[8] = {
95  0b01110,
96  0b11111,
97  0b10101,
98  0b11111,
99  0b11111,
100  0b11111,
101  0b11111,
102  0b10101
103};
104 
105void setup()
106{
107 // impostazione del numero di colonne e righe del display
108  lcd.begin(16, 2);
109 
110  // creazione nuovi caratteri
111  lcd.createChar(0, lucchettoChiuso);
112  lcd.createChar(1, lucchettoAperto);
113  lcd.createChar(2, Altoparlante);
114  lcd.createChar(3, batteriaMezza);
115  lcd.createChar(4, alieno);
116  lcd.createChar(5, pacmanBoccaChiusa);
117  lcd.createChar(6, pacmanBoccaAperta);
118  lcd.createChar(7, fantasmino);
119   
120  // Cancella il display
121  lcd.clear();
122 
123  // Stampa la stringa
124  lcd.print("PCTO a.s. 20/21");
125 
126}
127 
128void loop()
129{
130  lcd.setCursor(0, 1);
131  lcd.write(byte(0));
132 
133  lcd.setCursor(2, 1);
134  lcd.write(byte(1));
135 
136  lcd.setCursor(4, 1);
137  lcd.write(byte(2));
138 
139  lcd.setCursor(6, 1);
140  lcd.write(byte(3));
141 
142  lcd.setCursor(8, 1);
143  lcd.write(byte(4));
144 
145  lcd.setCursor(10, 1);
146  lcd.write(byte(5));
147 
148  lcd.setCursor(12, 1);
149  lcd.write(byte(6));
150 
151  lcd.setCursor(14, 1);
152  lcd.write(byte(7));
153}

Esempio 2

In questo secondo esempio mostriamo come visualizzare l’icona del Pacman che va avanti e indietro sulla prima riga del display

1/*
2 *  Prof. Michele Maffucci
3 *  Crezione di caratteri personali
4 *  Utilizzo di un display LCD1602 Keypad Shield della Keyestudio
5 *  Data: 19.03.2021
6 
7 *  Movimento verso destra e sinistra di una icona (alieno)
8*/
9 
10// inclusione della libreria LiquidCrystal.h
11#include <LiquidCrystal.h>
12 
13// inizializza la libreria con i numeri dei pin dell'interfaccia
14LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
15 
16// Velocità con cui viene stampato il l'icona 
17int velocita = 300;
18 
19// caratteri personalizzati
20 
21byte alieno[8] = {
22  0b10001,
23  0b01010,
24  0b11111,
25  0b10101,
26  0b11111,
27  0b11111,
28  0b01010,
29  0b11011
30};
31 
32void setup()
33{
34 // impostazione del numero di colonne e righe del display
35  lcd.begin(16, 2);
36 
37  // creazione nuovi caratteri
38  lcd.createChar(4, alieno);
39 
40  // visualizzazione sul display del nome
41  // dell'attività
42   
43  // Cancella il display
44  lcd.clear();
45 
46  // Stampa la stringa
47  lcd.print("PCTO a.s. 20/21");
48  delay(1000);
49 
50  // Cancella il display
51  lcd.clear();
52}
53 
54void loop()
55{
56   // Movimento verso destra del carattere
57  for (int contatorePosizioneColonna = 0; contatorePosizioneColonna < 16; contatorePosizioneColonna++) {
58    // Cancella il display
59    lcd.clear();
60    // Spostamento di una posizione verso destra del cursore
61    lcd.setCursor(contatorePosizioneColonna, 0);
62    // Stampa del icona: alieno
63    lcd.write(byte(4));
64    // Attesa di un'istante per percepire il movimento del carattere
65    delay(velocita);
66  }
67 
68  // Movimento verso sinistra del carattere
69  for (int contatorePosizioneColonna = 16; contatorePosizioneColonna > 0; contatorePosizioneColonna--) {
70    // Cancella il display
71    lcd.clear();
72    // Spostamento di una posizione verso sinistra del cursore
73    lcd.setCursor(contatorePosizioneColonna, 0);
74    // Stampa del icona: alieno
75    lcd.write(byte(4));
76    // Attesa di un'istante per percepire il movimento del carattere
77    delay(velocita);
78  }
79}

Esempio 3

Realizzare le medesime funzionalità dell’esercizio precedente in cui l’icona del Pacman nell’avanzamento apre e chiude la bocca.
In questo esempio il Pacman quando torna indietro non si gira.

1/*
2    Prof. Michele Maffucci
3    Crezione di caratteri personali
4    Utilizzo di un display LCD1602 Keypad Shield della Keyestudio
5    Data: 19.03.2021
6 
7    Movimento verso destra e sinistra di una icona (Pacman)
8    Durante il movimento il Pacman apre e chiude la bocca
9*/
10 
11// inclusione della libreria LiquidCrystal.h
12#include <LiquidCrystal.h>
13 
14// inizializza la libreria con i numeri dei pin dell'interfaccia
15LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
16 
17// Velocità con cui viene stampato il l'icona
18int velocita = 300;
19 
20// caratteri personalizzati
21 
22byte pacmanBoccaChiusa[8] = {
23  0b01110,
24  0b11101,
25  0b11111,
26  0b11111,
27  0b11000,
28  0b11111,
29  0b11111,
30  0b01110
31};
32 
33byte pacmanBoccaAperta[8] = {
34  0b01110,
35  0b11101,
36  0b11111,
37  0b11100,
38  0b11000,
39  0b11000,
40  0b11111,
41  0b01110
42};
43 
44void setup()
45{
46  // impostazione del numero di colonne e righe del display
47  lcd.begin(16, 2);
48 
49  // creazione nuovi caratteri
50  lcd.createChar(0, pacmanBoccaChiusa);
51  lcd.createChar(1, pacmanBoccaAperta);
52 
53  // Cancella il display
54  lcd.clear();
55 
56  // Stampa la stringa
57  lcd.print("PCTO a.s. 20/21");
58}
59 
60void loop()
61{
62 
63  // Movimento verso destra del carattere
64  for (int contatorePosizioneColonna = 0; contatorePosizioneColonna < 16; contatorePosizioneColonna++) {
65    // Cancella il display
66    lcd.clear();
67    // Spostamento di una posizione verso destra del cursore
68    lcd.setCursor(contatorePosizioneColonna, 0);
69    if (contatorePosizioneColonna % 2 == 0) {
70      // Stampa del icona: Pacman bocca chiusa
71      lcd.write(byte(0));
72    }
73    else
74    {
75      // Stampa del icona: Pacman bocca aperta
76      lcd.write(byte(1));
77    }
78    // Attesa di un'istante per percepire il movimento del carattere
79    delay(velocita);
80  }
81 
82  // Movimento verso sinistra del carattere
83  for (int contatorePosizioneColonna = 16; contatorePosizioneColonna > 0; contatorePosizioneColonna--) {
84    // Cancella il display
85    lcd.clear();
86    // Spostamento di una posizione verso sinistra del cursore
87    lcd.setCursor(contatorePosizioneColonna, 0);
88    if (contatorePosizioneColonna % 2 == 0) {
89      // Stampa del icona: Pacman bocca chiusa
90      lcd.write(byte(0));
91    }
92    else
93    {
94      // Stampa del icona: Pacman bocca aperta
95      lcd.write(byte(1));
96    }
97    // Attesa di un'istante per percepire il movimento del carattere
98    delay(velocita);
99  }
100}

Esercizio 1

Eseguire le stesse funzionalità dell’esempio 3 in cui però il Pacman rivolga il viso nella stessa direzione del movimento.

Esercizio 2

Movimentare il Pacman con i pulsanti RIGHT e LEFT, rivolgendo sempre il viso nella giusta posizione di movimento.

Buon Coding a tutti 🙂

Lezione 3 – Arduino GamePad – LCD1602 Keypad Shield della Keyestudio

Terza lezione in cui aggiungo alcuni esempi che suggeriscono alcune azioni di gioco che gli allievi del gruppo di lavoro dell’attività di PCTO: Arduino GamePad potranno sfruttare per la realizzazione del loro.

Esempio 1

Controllo dello spostamento del carattere:

  • destra/sinistra mediante i pulsanti: RIGHT e LEFT sul display
  • su/giù mediante i pulsanti UP/DOWN

Per realizzare queste azioni riprendiamo quanto realizzato nella lezione precedente aggiungendo all’ultimo sketch il controllo della pressione del pulsante UP o DOWN in cui viene controllato se l’analogRead sul A0 restituisce un valore comprese tra:

Controllo UP
(val >= 50 && val <= 150)

Controllo DOWN
(val >= 150 && val <= 300)

Lo spostamento del carattere dalla prima alla seconda riga deve essere fatta cancellando prima l’intero schermo, poi posizionando il carattere con il metodo setCursor() a cui si passa la variabile globale “contatorePosizioneColonna” che viene modificata di volta in volta alla pressione dei pulsanti RIGHT e LEFT. La selezione della riga avviene passando il valore 0 che identifica la prima riga e il valore 1 per la seconda riga.

1/*
2   Prof. Michele Maffucci
3   Utilizzo dell'LCD Keypad Shield della Keystudio
4   Data: 14.03.2021
5 
6   Controllo dello spostamento del carattere:
7   - destra/sinistra mediante i pulsanti: RIGHT e LEFT sul display
8   - su/giù mediante i pulsanti UP/DOWN
9*/
10 
11// inclusione della libreria LiquidCrystal.h
12#include <LiquidCrystal.h>
13 
14// inizializza la libreria con i numeri dei pin dell'interfaccia
15LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
16 
17// Colonna in cui si trova il carattere
18int contatorePosizioneColonna = 0;
19 
20// Valore restituito dall'analogRead su A0
21int val;
22 
23// Velocità con cui viene stampato il carattere 
24int velocita = 200;
25 
26void setup() {
27  // impostazione del numero di colonne e righe del display
28  lcd.begin(16, 2);
29 
30  // Carattere stampato nella prima colonna e prima riga (0,0)
31  lcd.print("*");
32}
33 
34void loop() {
35 
36  // Memorizza in val il valore presente su A
37  int val = analogRead(A0);
38 
39  // Alla pressione del pulsante UP sul display il carattere si sposta sulla prima riga
40   if (val >= 50 && val <= 150) {
41    // Cancella il display
42    lcd.clear();
43    // Spostamento sulla prima riga nella colonna corrente
44    lcd.setCursor(contatorePosizioneColonna, 0);
45    // Stampa del carattere: *
46    lcd.print("*");
47    // Attesa di un'istante per percepire il movimento del carattere
48    delay(velocita);
49  }
50 
51  // Alla pressione del pulsante DOWN sul display il carattere si sposta sulla seconda riga
52  if (val >= 150 && val <= 300) {
53    // Cancella il display
54    lcd.clear();
55    // Spostamento sulla seconda riga nella colonna corrente
56    lcd.setCursor(contatorePosizioneColonna, 1);
57    // Stampa del carattere: *
58    lcd.print("*");
59    // Attesa di un'istante per percepire il movimento del carattere
60    delay(velocita);
61  }
62 
63  // Premendo il pulsante RIGHT sul display, il carattere si sposta di una posizione
64  // a destra fino a quando non si raggiunge l'ultima colonna a destra.
65  // Premendo ancora il pulsante RIGHT non si ha l'avanzamento del carattere.
66  if ((val >= 0 && val <= 50) && contatorePosizioneColonna < 15) {
67    lcd.scrollDisplayRight();
68    delay(velocita);
69    contatorePosizioneColonna++;
70  }
71 
72  // Premendo il pulsante LEFT sul display, il carattere si sposta di una posizione
73  // a sinistra fino a quando non si raggiunge l'ultima colonna a sinistra.
74  // Premendo ancora il pulsante LEFT non si ha l'avanzamento del carattere.
75  if ((val >= 300 && val <= 500) && contatorePosizioneColonna > 0) {
76    lcd.scrollDisplayLeft();
77    delay(velocita);
78    contatorePosizioneColonna--;
79  }
80}

Esempio 2

In questo secondo esempio viene aggiunta una semplice matrice di cinque “X” che identificano degli ostacoli che devono essere superati. Nell’esempio esposto però gli ostacoli possono essere superati, lascio quindi a voi la realizzazione dello sketch che consente il blocco dell’avanzamento nel caso in cui ci si scontra con l’ostacolo.

1/*
2   Prof. Michele Maffucci
3   Utilizzo dell'LCD Keypad Shield della Keystudio
4   Data: 14.03.2021
5 
6   Controllo dello spostamento del carattere *:
7   - destra/sinistra mediante i pulsanti: RIGHT e LEFT sul display
8   - su/giù mediante i pulsanti UP/DOWN
9 
10   Stampa di una serie di X che rappresentano gli ostacoli
11    
12*/
13 
14// inclusione della libreria LiquidCrystal.h
15#include <LiquidCrystal.h>
16 
17// inizializza la libreria con i numeri dei pin dell'interfaccia
18LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
19 
20// Colonna in cui si trova il carattere
21int contatorePosizioneColonna = 0;
22 
23// Valore restituito dall'analogRead su A0
24int val;
25 
26// Velocità con cui viene stampato il carattere
27int velocita = 200;
28 
29// Riga in cui si trova il carattere *
30int riga = 0;
31 
32void setup() {
33  // impostazione del numero di colonne e righe del display
34  lcd.begin(16, 2);
35 
36  // Carattere stampato nella prima colonna e prima riga (0,0)
37  lcd.print("*");
38}
39 
40void loop() {
41 
42  // Memorizza in val il valore presente su A
43  int val = analogRead(A0);
44 
45  stampaOstacoli();
46 
47  // Alla pressione del pulsante UP sul display il carattere si sposta sulla prima riga
48  if (val >= 50 && val <= 150) {
49    // Cancella il display
50    lcd.clear();
51    stampaOstacoli();
52    // Spostamento sulla prima riga nella colonna corrente
53    lcd.setCursor(contatorePosizioneColonna, 0);
54    riga = 0;
55    // Stampa del carattere: *
56    lcd.print("*");
57    // Attesa di un'istante per percepire il movimento del carattere
58    delay(velocita);
59  }
60 
61  // Alla pressione del pulsante DOWN sul display il carattere si sposta sulla seconda riga
62  if (val >= 150 && val <= 300) {
63    // Cancella il display
64    lcd.clear();
65    stampaOstacoli();
66    // Spostamento sulla seconda riga nella colonna corrente
67    lcd.setCursor(contatorePosizioneColonna, 1);
68    riga = 1;
69    // Stampa del carattere: *
70    lcd.print("*");
71    // Attesa di un'istante per percepire il movimento del carattere
72    delay(velocita);
73  }
74 
75  // Premendo il pulsante RIGHT sul display, il carattere si sposta di una posizione
76  // a destra fino a quando non si raggiunge l'ultima colonna a destra.
77  // Premendo ancora il pulsante RIGHT non si ha l'avanzamento del carattere.
78  if ((val >= 0 && val <= 50) && contatorePosizioneColonna < 15) {
79    // Cancella il display
80    lcd.clear();
81    contatorePosizioneColonna++;
82    // Spostamento di una posizione verso destra del cursore
83    lcd.setCursor(contatorePosizioneColonna, riga);
84    // Stampa del carattere: *
85    lcd.print("*");
86    // Attesa di un'istante per percepire il movimento del carattere
87    delay(velocita);
88  }
89 
90  // Premendo il pulsante LEFT sul display, il carattere si sposta di una posizione
91  // a sinistra fino a quando non si raggiunge l'ultima colonna a sinistra.
92  // Premendo ancora il pulsante LEFT non si ha l'avanzamento del carattere.
93  if ((val >= 300 && val <= 500) && contatorePosizioneColonna > 0) {
94    // Cancella il display
95    lcd.clear();
96    contatorePosizioneColonna--;
97    lcd.setCursor(contatorePosizioneColonna, riga);
98    // Stampa del carattere: *
99    lcd.print("*");
100    // Attesa di un'istante per percepire il movimento del carattere
101    delay(velocita);
102  }
103}
104 
105void stampaOstacoli() {
106  lcd.setCursor(2, 0);
107  lcd.print("X");
108  lcd.setCursor(5, 1);
109  lcd.print("X");
110  lcd.setCursor(7, 1);
111  lcd.print("X");
112  lcd.setCursor(9, 0);
113  lcd.print("X");
114  lcd.setCursor(12, 0);
115  lcd.print("X");
116}

Esercizio 1

Utilizzando l’esempio 2 esposto sopra, aggiungere la funzionalità che blocca l’avanzamento del carattere “*” nel caso in cui ci si scontra con l’ostacolo.

Esercizio 2

Definire tre matrici di ostacoli diversi e fare in modo che ad ogni avvio di Arduino la scelta della matrice venga fatta in modo casuale.

Esercizio 3

Aggiungere la funzionalità che permette di modificare la matrice degli ostacoli se si raggiunge l’ultima colonna a destra.

Esercizio 4

Definire tre scenari diversi costituiti da tre matrici ostacoli diversi. La navigazione può avvenire solamente all’interno di questi tre scenari. La partenza del carattere “*” avviene dalla colonna 0 del secondo scenario, il movimento dovrà essere il seguente:

  • partendo dalla colonna 0 del secondo scenario, la pressione del pulsante LEFT porta allo scenario 1 e il carattere “*” viene posizionato nella colonna 15 del display;
  • se si è nel secondo scenario in colonna 15, la pressione del pulsante RIGHT conduce alla colonna 0 del  3′ scenario;
  • la pressione del pulsante LEFT in colonna 0 del primo scenario non permette nessun cambiamento di scenario
  • la pressione del pulsante RIGHT in colonna 15 del terzo scenario non permette nessun cambiamento di scenario

Buon Coding a tutti 🙂

Arduino – Dividere uno sketch in più file

Domanda dello studente: “Prof. il progetto per controllare il robot sta diventando lunghissimo e anche se commento ogni parte e cerco di creare funzioni specifiche per ogni azione, leggere modificare il codice diventa un lavoro che porta via molto tempo, come posso fare?”

Possiamo agire in due modi:

  1. creazione di librerie specifiche in cui inserire il codice che deve essere richiamato dallo sketch principale, leggere la parte finale della lezione: “Arduino – lezione 08: display a 7 segmenti e creazione di librerie” in cui mostro come fare questa operazione;
  2. utilizzare la funzione specifica che trovate nell’IDE di Arduino “Nuova scheda” o “New Tab” in inglese a destra della finestra.

Supponiamo di aver creato un nuovo sketch vuoto a cui assegniamo un nome, nel mio esempio “ilMioBlink.ino”, come sapete il file verrà inserito in una cartella che avrà lo stesso nome dello sketch principale:

Selezionare “New Tab” a destra della finestra dell’IDE:

noterete che la selezione di questa voce di menù aprirà in basso alla finestra dell’IDE un’area evidenziata in giallo in cui dovrete inserire il nome del file.

Inserirò a titolo di esempio il nome: “impostazioni”.
Verrà immediatamente aggiunta una nuova tab:

 

Appena salvate il progetto, il simbolo a fianco del nome scompare ed il nuovo file “impostazioni” verrà automaticamente inserito nella stessa cartella dello sketch principale.
Il salvataggio del progetto salva automaticamente tutte le variazioni fatte nei file allegati al progetto.

Si tenga presente che la lettura (esecuzione) dei file aggiunti avverrà in ordine alfabetico, pertanto se vengono usate variabili globali all’interno di uno dei file, queste potranno essere viste solamente dai file che seguono nell’ordine alfabetico, pertanto buona regola è inserire tutte le variabili globali nel progetto principale (quello che reca lo stesso nome della cartella di progetto).

Quindi si potrebbe pensare di strutturare un lungo progetto in questo modo:

  1. tutte le variabili globali nello sketch principale;
  2. impostazioni di setup() in un secondo file;
  3. loop() nello sketch principale in cui sono incluse le chiamate alle funzioni esterne principali;
  4. file con tutte le funzioni. Se le funzioni sono lunghe e complesse si potrebbe pensare di separarle in altri file.

Esempio

Come esempio consideriamo il semplicissimo sketch che permette di far lampeggiare ripetutamente due LED e dividiamolo in due parti:

Il file principale, ilMioBlink.ino avrà al suo interno variabili globali e loop(), mentre il file impostazioni avrà al suo interno solo il setup():

Bene!

Per i miei studenti, da questo momento in poi per rendere più veloce e semplice la correzione dei vostri lavori è obbligatorio suddividere sketch di grandi dimensioni in più file i vostri lavori 🙂

Buon Coding a tutti!

 

I miei corsi per Tecnica della Scuola: Laboratori STEAM con Arduino

Sono felice di comunicarvi che svolgerò nel mese di aprile con Tecnica della Scuola il corso: Laboratori Steam con Arduino.
Sono più di 10 anni che utilizzo questa stupenda scheda, stupenda soprattutto perché mi ha permesso di recuperare negli anni molti ragazzi demotivati o con carenze di carattere logico matematico e tali mancanze pregiudicavano inevitabilmente la comprensione di argomenti che insegno: elettronica, informatica, sistemi elettronici.
Arduino nasce come scheda elettronica fatta per NON elettronici, una scheda che doveva servire prevalentemente per prototipare e quindi  permettere a chiunque di superare lo scoglio della complessità elettronica ed informatica, almeno nella prima fase di apprendimento, per produrre un prodotto da utilizzare in diversi ambiti: design, medico, umanistico, ecc…

Successivamente si è constatato che l’uso di Arduino a scuola, in moltissime attività laboratoriali, risultava estremamente utile. Soprattutto nel mio caso Arduino ha permesso di trovare un ausilio didattico in grado di catalizzare interesse e passione da parte anche di chi aveva scarse competenze matematiche.

Quando l’azione didattica veniva condotta con precisione, l’uso di Arduino ha permesso di far comprendere allo studente che, se è relativamente facile realizzare progetti con forte interazione con il mondo reale, ancora più interessanti potevano diventare quegli stessi progetti se le competenze nelle discipline STEAM fossero state maggiori.

Con l’attività pratica basata su Arduino si fornisce un motivo in più per sopportare e superare l’insuccesso scolastico, sviluppando progetti pratici il cui funzionamento dipenderà dall’impegno e dallo studio, quindi lo studente, in modo evidente vede in  Arduino l’oggetto che permette la materializzazione della propria competenza, cosa che non mi stancherò mai di dire e che più volte ho scritto su queste pagine. Se io studente conosco la fisica e la chimica probabilmente saprò gestire progetti che hanno a che fare con l’IoT, la fisiologia umana , le arti, l’economia e molto altro.

Come dico nella presentazione del corso:

Le attività laboratoriali di “fabbricazione digitale” che fanno uso di Arduino, favoriscono lo sviluppo delle competenze metacognitive e relazionali, potenziamento del pensiero logico, della capacità di astrazione e di problem solving.

ed aggiungo: la percezione che imparare è bello.

Quindi l’uso di Arduino diventa il pretesto per mettere in atto processi di analisi e autoanalisi e di messa in pratica di conoscenze e abilità.

Questa è ciò che ho visto e continuo a vedere durante le attività di laboratorio.

Ma è possibile che Arduino, una semplice scheda elettronica, possa fare tutto ciò?
Sì ne sono assolutamente convinto, l’evidenza si ha quando si vive il laboratorio ogni giorno, si percepisce negli studenti la sensazione che è bello imparare, perché imparare mi fornisce un immediato riscontro fisico di ciò che so e ciò che mi serve per far diventare “ancor più bello” il mio progetto.

Non si pensi assolutamente che Arduino è fatto per pochi addetti, non è l’oggetto che manipola solo l’insegnante di elettronica, è l’oggetto che usa l’insegnate di musica per far costruire strumenti musicali, è lo strumento che usa l’insegnate di arte per mostrare come creare installazioni di arte cinetica, è lo strumento che usano gli insegnanti di materie umanistiche quando vogliono sperimentare azioni di educazione civica in cui gli allievi devono progettare un ausilio per la disabilità per un loro compagno di classe, ma Arduino è anche lo strumento utilizzato costruire strumenti per comprendere i cambiamenti climatici.

Vorrei con questo corso farvi percepire come è semplice costruire progetti didattici laboratoriali trasversali, che coinvolgono tutte le discipline.
Spero di vedermi al mio corso, il primo di una serie di corsi a carattere assolutamente laboratoriale che svolgerò nei prossimi mesi con Tecnica della Scuola.

Non mi resta quindi che lasciarvi al programma del corso e sperare che insieme, durante le attività a distanza,  si possano sviluppare oggetti fisici utili per voi.

E’ necessario disporre della scheda Arduino?
E’ consigliato, ma sarà possibile seguire assolutamente il corso anche se non si dispone della scheda, ma il mio consiglio è quello di mettere mani subito sugli oggetti fisici in modo che si assimilino più velocemente le nozioni di base. Vi fornirò tutte le indicazioni e i dettagli tecnici per sapere dove  e cosa acquistare per cominciare il proprio percorso di apprendimento e impostare le lezioni laboratoriali per i vostri studenti.

Presentazione

LABORATORI STEAM CON ARDUINO
Come fare coding, tinkering e making a scuola

Come realizzare laboratori Steam utilizzando Arduino, una delle più affermate tecnologie open-source e open-hardware che sempre di più si sta affermando a scuola. Un corso per conoscere e approfondire le opportunità della robotica educativa e del coding. Il corso, combinando diverse tecnologie innovative, avrà un approccio assolutamente laboratoriale e fornirà tecniche ed idee per supportare l’apprendimento degli studenti favorendo in loro anche lo sviluppo dell’espressione personale e della creatività. Verranno mostrati esempi realmente sperimentati in classe in cui si evidenzieranno gli aspetti legati all’interdisciplinarietà e all’inclusione che hanno trovato largo impiego nella quotidianità scolastica.

Particolare attenzione verrà posta anche all’attività di sperimentazione pratica con Arduino in modalità di didattica digitale integrata utilizzando simulatori online e non solo.

L’intero corso è pensato per tutti gli insegnati, non è necessario in alcun modo avere competenze di elettronica o informatica e la proposta formativa è disegnata su un percorso testato da anni indirizzato a persone non tecniche in particolar modo ad insegnanti e studenti.

Cos’è Arduino:

  • Arduino è un hardware, una scheda elettronica di facilissimo utilizzo, e di basso costo
  • Arduino è un’ambiente di programmazione che permetterà di realizzare programmi che verranno poi eseguiti sulla scheda elettronica per la realizzazione molteplici progetti che potranno avere una forte interazione con il mondo reale;
  • Arduino è un sito ed una comunità online che condivide risorse e progetti utilissimi in campo didattico, soprattutto nelle attività che rientrano all’interno dell’insegnamento delle STEAM (Science, Technology, Engineering, Arts, Mathematics).

Perché usare Arduino nella didattica laboratoriale.

  • Il costo contenuto;
  • le dimensioni ridotte;
  • la semplicità di utilizzo;
  • la possibilità di sviluppare una vasta gamma di attività possibili data dalla notevole modularità della scheda;
  • una comunità di appassionati molto attiva tra cui moltissimi docenti.

L’uso di Arduino diventa un pretesto per mettere in atto processi di analisi e autoanalisi e di messa in pratica di conoscenze e abilità. Le attività laboratoriali di “fabbricazione digitale” che fanno uso di Arduino, favoriscono lo sviluppo delle competenze metacognitive e relazionali, potenziamento del pensiero logico, della capacità di astrazione e di problem solving.

Inoltre, uno degli ambiti che maggiormente viene svolto a livello laboratoriale è quello della robotica educativa. Durante il corso verranno forniti esempi e percorsi didattici completi immediatamente utilizzabili in classe, volti alla realizzazione di attività laboratoriali per la costruzione di robot didattici basati su piattaforma Arduino in cui verranno presi in considerazione le seguenti azioni:

  1. come si pensa e si progetta in gruppo;
  2. come si progetta un robot didattico;
  3. come si realizza un robot con materiali riciclati;
  4. come si programma il robot;

Durante il corso verranno forniti anche consigli sulle dotazioni tecniche necessarie per iniziare ad utilizzare questa piattaforma:

  • cosa comprare;
  • dove comprare;
  • come imparare ad utilizzare in modo semplice Arduino;
  • come avviare un laboratorio di STEAM in cui si fa uso di Arduino.

Saranno svolti 4 incontri in webinar di 2 ore ciascuno, per un totale di 8 ore.

  • Martedì 20 aprile 2021 – Dalle 17.00 alle 19.00
  • Giovedì 22 aprile 2021 – Dalle 17.00 alle 19.00
  • Martedì 27 aprile 2021 – Dalle 17.00 alle 19.00
  • Giovedì 29 aprile 2021 – Dalle 17.00 alle 19.00

Per iscriversi al corso seguire il link allegato.

PCTO A.S. 2020 – 2021 – SumoBot – lezione 4

Come probabilmente avrete avuto modo di verificare gestendo i due servomotori a rotazione continua, pur provenendo dal medesimo costruttore e impostando le medesime configurazione di velocità, hanno un comportamento non sempre identico. Ricordo che si tratta di apparati economici che devono rispondere a specifiche esigenze didattiche, ma in ogni caso è possibile effettuare alcune regolazioni che ne possono migliorare le prestazioni.
Un’altra funzionalità utile è quella dello start/stop del robot che potrebbe servire per evitare immediati movimenti non appena trasferiamo il codice sul robot.

In questa lezione vi dettaglio gli sketch di esempio, lasciando a voi modifiche e miglioramenti.

Regolazione dei motori

Per poter valutare la velocità e l’angolo di rotazione da impostare all’interno dello sketch è possibile attivare la funzione di calibrazione collegando a GND il pin 3, in questo modo sarà possibile dalla Serial Monitor verificare quali sono i giusti valori per:

  • velocità di rotazione;
  • durata della rotazione;
  • motore/i da impostare

e quindi ciò consentirà di impostare i parametri corretti per le funzioni:

  • orarioRobot()
  • antiorarioRobot()

Pertanto da serial monitor potremo comprendere come far compiere una rotazione di 90° in un senso, oppure come far avanzare di una certa quantità di centimetri il robot e molto altro, tenendo però bene a mente che tutto ciò dipenderà fortemente dalla carica della batteria.

La scelta del pin3 è puramente casuale se ritenete potete scegliere un altro pin digitale.

Esempio 1

1/*
2   Prof. Maffucci Michele
3   SumoRobot
4   Data: 26.01.2021
5 
6   Sketch 03: rotazione oraria e antioraria continua
7              con funzioni parametrizzate
8 
9              Per valutare la velocità e l'angolo di rotazione è possibile
10              attivare la funzione di calibrazione collegando a GND il pin 3,
11              in questo modo sarà possibile dalla Serial Monitor verificare
12              quali sono i giusti valori per:
13              - velocità di rotazione;
14              - durata della rotazione;
15              - motore/i da impostare
16 
17              Ciò consentirà di impostare i parametri corretti per le funzioni:
18 
19              - orarioRobot()
20              - antiorarioRobot()
21 
22   Note:
23            L'orientamento dei motori è fatto
24            guardano il robot anteriormente
25 
26            180: max velocità in senso antiorario
27            90 : servomotori fermi
28            0  : max velocità in senso orario
29 
30*/
31 
32// inclusione della libreria servo.h per il controllo dei servomotori
33#include <Servo.h>
34 
35// Creazione oggetti servo
36Servo motoreDX;  // Inizializzazione del servomotore destro
37Servo motoreSX;  // Inizializzazione del servomotore sinistro
38 
39byte pinDx = 4;     // Inizializza del pin 4 a cui è connesso il pin segnale del servo destro
40byte pinSx = 5;     // Inizializza del pin 5 a cui è connesso il pin segnale del servo sinistro
41 
42// Per Calibrazione
43 
44// per stampare una sola volta il messaggio sulla Serial Monitor
45bool abilitaMessaggio = 0;
46 
47// per attivare la calibrazione impostare startCalibrazione a 0
48bool startCalibrazione = 1;
49 
50// Pin di calibrazione se a LOW abilita modalità calibrazione
51byte pinCal = 3;
52 
53void setup() {
54 
55  // inizializzazione della seriale
56  Serial.begin(9600);
57 
58  // attach() consente di definire a quale pin viene connesso il servomotore
59  // e lo collega all'oggetto che gestisce il servomotore
60 
61  motoreDX.attach(pinDx); // pinDx collegato al motore destro
62  motoreSX.attach(pinSx); // pinSx collegato al motore sinistro
63 
64  pinMode(pinCal, INPUT);
65}
66 
67void loop() {
68 
69  // se sul pinCal è LOW è possibile impostare i motori
70  if (digitalRead(pinCal) == LOW) {
71    calibrazione();
72  }
73  else
74  {
75    orarioRobot(30, 250);      // Rotazione in senso orario del robot
76    stopRobot(3000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
77    antiorarioRobot(150, 250); // Rotazione in senso antiorario del robot
78    stopRobot(3000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
79  }
80}
81 
82// Funzione da utilizzare una sola volta per impostare
83// i tempi necessari per effettuare uno specifico angolo
84// di rotazione e la velocità di rotazione desiderata
85 
86void calibrazione() {
87 
88  // consente di visualizzare sulla Serial Monitor
89  // una sola stampa delle stringa
90  if (abilitaMessaggio == 0) {
91    // ritardo che evita la doppia stampa del messaggio
92    delay(200);
93    Serial.println("Calibrazione tempo rotazione");
94    Serial.println("velocità (0-180), durata(ms), motore(1: DX, 2: SX, 3: SX+DX)");
95    Serial.println();
96    abilitaMessaggio = 1;
97  }
98 
99  // Controlla se è disponibile almeno un carattere sulla seriale
100  // La Serial.available() restituisce
101  // 1 se presente un cattere,
102  // 0 se non è presente un carattere
103 
104  if (Serial.available()) {        // Viene controllato se è disponibile un carattere
105 
106    // per maggior informazioni sull'uso di parseInt() consultare il link:
108 
109    // inserimento da tastiera su Serial Monitor dei parametri di controllo
110    // separati da spazio o virgola
111    int velocita = Serial.parseInt();
112    int durata   = Serial.parseInt();
113    int motore   = Serial.parseInt();
114 
115    // funzione per il movimento dei servomotori con i parametri
116    // inseriti sulla serial monitor.
117    calMotoreRobot(velocita, durata, motore);
118  }
119}
120 
121// funzione movimento servomotori per impostazione
122// velocità, durata, motore/i
123 
124void calMotoreRobot(int calVel, int calDurata, int nMotore) {
125  if (nMotore == 1) { // motore DX
126    motoreDX.write(calVel);
127    delay(calDurata);
128    motoreDX.write(90);   // Ferma il motore DX
129    motoreSX.write(90);   // Ferma il motore SX
130    Serial.println("Fine calibrazione motore DX");
131    Serial.println();
132  }
133  if (nMotore == 2) { // motore SX
134    motoreSX.write(calVel);
135    delay(calDurata);
136    motoreDX.write(90);   // Ferma il motore DX
137    motoreSX.write(90);   // Ferma il motore SX
138    Serial.println("Fine calibrazione motore SX");
139    Serial.println();
140  }
141  if (nMotore == 3) { // motore SX+DX
142    motoreDX.write(calVel);  // Rotazione oraria del motore DX
143    motoreSX.write(calVel);  // Rotazione antioraria del motore SX
144    delay(calDurata);
145    motoreDX.write(90);   // Ferma il motore DX
146    motoreSX.write(90);   // Ferma il motore SX
147    Serial.println("Fine calibrazione motore DX e SX");
148    Serial.println();
149  }
150}
151 
152// rotazione del robot in senso antiorario
153// velMaxOraria: velocità massima in senso antiorario
154// durata: durata della rotazione
155 
156void antiorarioRobot(int velMaxAntioraria, int durata) {
157  motoreDX.write(velMaxAntioraria);  // Rotazione oraria del motore DX
158  motoreSX.write(velMaxAntioraria);  // Rotazione antioraria del motore SX
159  delay(durata);                     // durata: durata della rotazione
160}
161 
162// rotazione del robot in senso orario
163// velMaxOraria: velocità massima in senso orario
164// durata: durata della rotazione
165 
166void orarioRobot(int velMaxOraria, int durata) {
167  motoreDX.write(velMaxOraria);    // Rotazione antioraria del motore DX
168  motoreSX.write(velMaxOraria);    // Rotazione oraria del motore SX
169  delay(durata);                   // durata: durata della rotazione
170}
171 
172// stop del robot
173// ferma: durata dello stop del robot
174 
175void stopRobot(int ferma) {
176  motoreDX.write(90);   // Ferma il motore DX
177  motoreSX.write(90);   // Ferma il motore SX
178  delay(ferma);         // Durata dello stop
179}

La calibrazione viene attivata se la condizione ad inizio loop è vera:

1...
2// se sul pinCal è LOW è possibile impostare i motori
3  if (digitalRead(pinCal) == LOW) {
4    calibrazione();
5  }
6  else
7  {
8    orarioRobot(30, 250);      // Rotazione in senso orario del robot
9    stopRobot(3000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
10    antiorarioRobot(150, 250); // Rotazione in senso antiorario del robot
11    stopRobot(3000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
12  }
13}
14...

Se la condizione dell’if risulta vera viene attivata la calibrazione:

1...
2// se sul pinCal è LOW è possibile impostare i motori
3  if (digitalRead(pinCal) == LOW) {
4    calibrazione();
5  }
6  else
7  {
8    orarioRobot(30, 250);      // Rotazione in senso orario del robot
9    stopRobot(3000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
10    antiorarioRobot(150, 250); // Rotazione in senso antiorario del robot
11    stopRobot(3000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
12  }
13}
14...

In tal caso viene chiamata la funzione calibrazione:

1...
2void calibrazione() {
3 
4  // consente di visualizzare sulla Serial Monitor
5  // una sola stampa delle stringa
6  if (abilitaMessaggio == 0) {
7    // ritardo che evita la doppia stampa del messaggio
8    delay(200);
9    Serial.println("Calibrazione tempo rotazione");
10    Serial.println("velocità (0-180), durata(ms), motore(1: DX, 2: SX, 3: SX+DX)");
11    Serial.println();
12    abilitaMessaggio = 1;
13  }
14 
15  // Controlla se è disponibile almeno un carattere sulla seriale
16  // La Serial.available() restituisce
17  // 1 se presente un cattere,
18  // 0 se non è presente un carattere
19 
20  if (Serial.available()) {        // Viene controllato se è disponibile un carattere
21 
22    // per maggior informazioni sull'uso di parseInt() consultare il link:
24 
25    // inserimento da tastiera su Serial Monitor dei parametri di controllo
26    // separati da spazio o virgola
27    int velocita = Serial.parseInt();
28    int durata   = Serial.parseInt();
29    int motore   = Serial.parseInt();
30 
31    // funzione per il movimento dei servomotori con i parametri
32    // inseriti sulla serial monitor.
33    calMotoreRobot(velocita, durata, motore);
34  }
35}
36...

La prima parte della funzione calibrazione() esegue una sola volta la stampa sulla Serial Monitor dell’help che spiega come inserire i dati:

velocità (0-180), durata(ms), motore(1: DX, 2: SX, 3: SX+DX)

che sono tutti valori interi separati da virgola.

Nella parte restante del codice della funzione viene verificato con il metodo available() se sono presenti sulla seriale caratteri. Serial.available() restituisce TRUE se sono presenti caratteri e il corpo dell’if verrà eseguito. I valori inseriti vengono letti utilizzando la funzione parseInt() di cui trovate spiegazione approfondita con esercizi seguendo il link.

1...
2if (Serial.available()) {        // Viene controllato se è disponibile un carattere
3 
4    // per maggior informazioni sull'uso di parseInt() consultare il link:
6 
7    // inserimento da tastiera su Serial Monitor dei parametri di controllo
8    // separati da spazio o virgola
9    int velocita = Serial.parseInt();
10    int durata   = Serial.parseInt();
11    int motore   = Serial.parseInt();
12 
13    // funzione per il movimento dei servomotori con i parametri
14    // inseriti sulla serial monitor.
15    calMotoreRobot(velocita, durata, motore);
16  }
17...

Non appena premiamo invio sulla tastiera, questi valori vegono acquisiti e passati alla funzione calMotoreRobot()

1...
2calMotoreRobot(velocita, durata, motore);
3...

Tra i parametri che vengono passati alla funzione calMotoreRobot() è presente l’indicazione di quale/i motore/i devono essere controllati, questo parametro può assumere i valori: 1, 2, 3 e questi valori vengono utilizzati per selezionare, tramite i blocchi if corrispondenti, quale azione è da compiere. Nei commenti i dettagli di funzionamento.

1...
2void calMotoreRobot(int calVel, int calDurata, int nMotore) {
3  if (nMotore == 1) { // motore DX
4    motoreDX.write(calVel);
5    delay(calDurata);
6    motoreDX.write(90);   // Ferma il motore DX
7    motoreSX.write(90);   // Ferma il motore SX
8    Serial.println("Fine calibrazione motore DX");
9    Serial.println();
10  }
11  if (nMotore == 2) { // motore SX
12    motoreSX.write(calVel);
13    delay(calDurata);
14    motoreDX.write(90);   // Ferma il motore DX
15    motoreSX.write(90);   // Ferma il motore SX
16    Serial.println("Fine calibrazione motore SX");
17    Serial.println();
18  }
19  if (nMotore == 3) { // motore SX+DX
20    motoreDX.write(calVel);  // Rotazione oraria del motore DX
21    motoreSX.write(calVel);  // Rotazione antioraria del motore SX
22    delay(calDurata);
23    motoreDX.write(90);   // Ferma il motore DX
24    motoreSX.write(90);   // Ferma il motore SX
25    Serial.println("Fine calibrazione motore DX e SX");
26    Serial.println();
27  }
28}
29...

La parte restante dello sketch riguarda funzioni già analizzate spiegate nelle lezioni precedenti.

Start/stop del robot

Questa semplice funzionalità viene ottenuta nel medesimo modo della calibrazione, utilizziamo il pin2 cortocircuitato a massa per evitare l’avvio del robot, secondo questa regola:

  • Pin 2 a GND: robot fermo
  • Pin 2 a Vcc: robot start

Questo lo sketch generale:

1/*
2   Prof. Maffucci Michele
3   SumoRobot
4   Data: 26.01.2021
5 
6   Sketch 04: rotazione oraria e antioraria continua
7              con funzioni parametrizzate con Start e Stop sistema.
8 
9              Per evitare in avvio immediato del robot si realizza un
10              un interruttore di start/stop utilizzando il pin 2:
11               
12              - Pin 2 a GND: robot fermo
13              - Pin 2 a Vcc: robot start
14   Note:
15            L'orientamento dei motori è fatto
16            guardano il robot anteriormente
17 
18            180: max velocità in senso antiorario
19            90 : servomotori fermi
20            0  : max velocità in senso orario
21 
22            Per avviare il robot collegare a GND il pin 2
23 
24*/
25 
26// inclusione della libreria servo.h per il controllo dei servomotori
27#include <Servo.h>
28 
29// Creazione oggetti servo
30Servo motoreDX;  // Inizializzazione del servomotore destro
31Servo motoreSX;  // Inizializzazione del servomotore sinistro
32 
33byte pinDx = 4;     // Inizializza del pin 4 a cui è connesso il pin segnale del servo destro
34byte pinSx = 5;     // Inizializza del pin 5 a cui è connesso il pin segnale del servo sinistro
35byte pinStart = 2;  // Pin di avvio, se a LOW Start sistema
36 
37void setup() {
38 
39  // inizializzazione della seriale
40  Serial.begin(9600);
41 
42  // attach() consente di definire a quale pin viene connesso il servomotore
43  // e lo collega all'oggetto che gestisce il servomotore
44 
45  motoreDX.attach(pinDx); // pinDx collegato al motore destro
46  motoreSX.attach(pinSx); // pinSx collegato al motore sinistro
47 
48  pinMode(pinStart, INPUT); // pin per avviare il sistema
49}
50 
51void loop() {
52 
53  // se pinStart a LOW il sistema è in stop
54  if (digitalRead(pinStart) == LOW) {
55    stopRobot(1);
56  }
57 
58  // se pinStart è diverso da LOW si avvia la sequenza
59  else
60  {
61    orarioRobot(70, 500);      // Rotazione in senso orario del robot
62    stopRobot(1000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
63    antiorarioRobot(130, 500); // Rotazione in senso antiorario del robot
64    stopRobot(1000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
65 
66  }
67}
68 
69// rotazione del robot in senso antiorario
70// velMaxOraria: velocità massima in senso antiorario
71// durata: durata della rotazione
72 
73void antiorarioRobot(int velMaxAntioraria, int durata) {
74  motoreDX.write(velMaxAntioraria);  // Rotazione antioraria del motore DX
75  motoreSX.write(velMaxAntioraria);  // Rotazione antioraria del motore SX
76  delay(durata);                     // durata: durata della rotazione
77}
78 
79// rotazione del robot in senso orario
80// velMaxOraria: velocità massima in senso orario
81// durata: durata della rotazione
82 
83void orarioRobot(int velMaxOraria, int durata) {
84  motoreDX.write(velMaxOraria);    // Rotazione oraria del motore DX
85  motoreSX.write(velMaxOraria);    // Rotazione oraria del motore SX
86  delay(durata);                   // durata: durata della rotazione
87}
88 
89// stop del robot
90// ferma: durata dello stop del robot
91 
92void stopRobot(int ferma) {
93  motoreDX.write(90);   // Ferma il motore DX
94  motoreSX.write(90);   // Ferma il motore SX
95  delay(ferma);         // Durata dello stop
96}

Come si può notare lo start/stop è regolato dalla parte di codice:

1...
2// se pinStart a LOW il sistema è in stop
3  if (digitalRead(pinStart) == LOW) {
4    stopRobot(1);
5  }
6 
7  // se pinStart è diverso da LOW si avvia la sequenza
8  else
9  {
10    orarioRobot(70, 500);      // Rotazione in senso orario del robot
11    stopRobot(1000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
12    antiorarioRobot(130, 500); // Rotazione in senso antiorario del robot
13    stopRobot(1000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
14 
15  }
16}
17...

Se il pin è collegato a GND, quindi al LOW il robot è in stop, infatti viene chiamata la funzione stopRobot(1);

Nella prossima lezione vedremo come integrare le due funzionalità:

  • calibrazione
  • start/stop

Buon Making a tutti 🙂