Sei sulla pagina 1di 43

RobotC

E’ un manuale d’uso del programma RobotC, (in particolare vuole essere utile agli studenti che seguono i
corsi di robotica educativa e desiderassero avere un testo di riferimento dove trovare un elenco delle
informazioni e dei concetti appresi durante la lezione in laboratorio, ed ai loro docenti).Il documento nasce
nello spirito di condivisione del sapere che ha ispirato la creazione della rete STAARR (all’interno della
quale lavoro) e della robotica educativa italiana facente capo alla rete di scuole per la robotica.

E’ da considerarsi un passo verso la creazione, libera e compartecipata, di materiale didattico sotto licenza
Creative Commons. Ciascuno dunque può usufruirne sia personalmente, che per fare didattica, purché se ne
segua lo spirito di condivisione.

Prerequisiti e convenzioni:

E’ necessaria per seguire il documento e comprenderlo appieno la conoscenza almeno per sommi capi del
linguaggio C, quantomeno i costrutti basilari (cicli, variabili, decisioni).

E’ necessario un PC con Windows 7 almeno, e una copia del programma RobotC.

RobotC è liberamente scaricabile dalla rete ma la sua licenza prevede un tempo limitato di uso gratuito.
Trascorso quel tempo, ci si aspetta che l’utente paghi una certa cifra per ottenere la licenza definitiva.

La stesura di questo testo fa riferimento ad esempi riguardanti un robot Lego EV3 (e con la versione di
RobotC 4.56). Se avete altri robot oppure un’altra versione del programma gli esempi da me proposti
possono non corrispondere esattamente.

Preparazione del robot e collegamento col PC.


Prima di iniziare a lavorare con RobotC ci sono alcune operazioni da effettuare una volta per tutte in modo
da poter trasferire al robot i file creati sul computer.

Selezionare la piattaforma Hardware corretta

In questo tutorial prendiamo in considerazione la piattaforma Lego EV3, e quindi le immagini dello schermo
si riferiscono a questa opzione. Ovviamente per altre piattaforme si devono selezionare le voci relative.

Da Menu testuale che troviamo appena aperto RobotC, clicchiamo sulla voce Robot, quindi selezioniamo
Pltatform Type, Lego Mindstorm, EV3
1
Installazione del Kernel

Da Menu testuale, clicchiamo sulla voce Robot, quindi selezioniamo Download EV3 Linux Kernel,
Standard File.

L’aggiornamento del kernel è piuttosto lungo, impiega qualche minuto. E’ però una operazione che va svolta
una volta per tutte, come tutte le operazioni che stiamo descrivendo in questa parte del tutorial.

Installazione del Firmware

Completato l’aggiornamento del kernel, si passa a quello del firmware.

Sempre dal Menu testuale, clicchiamo sulla voce Robot, quindi selezioniamo Download Firmware,
Standard File.

Stabilire una connessione

E’ quasi fatta: ora dobbiamo solo decidere come scambiare dati tra il robot ed il PC e stabilire un tipo di
connessione da usare quando programmeremo il nostro robot. Essenzialmente i tipi di connessione sono 2:

2
 Tramite interfaccia USB (e quindi con un cavo di connessione), oppure
 Tramite interfaccia Bluetooth (e quindi wireless)

Ognuna di esse ha i suoi vantaggi e svantaggi.

La connessione tramite cavo USB è più rapida, funziona sempre senza intoppi, ma ovviamente ha lo
svantaggio di non poter programmare il robot ad una distanza maggiore della lunghezza del cavo.

Quindi un robot in movimento dovrà o essere sconnesso dal cavo ogni volta che si testa un nuovo
programma.

La connessione wireless invece ci permette di trasferire i programmi al robot, e di ricevere dati dal robot,
senza bisogno di connetterlo e disconnetterlo continuamente tramite un cavo e questo è molto vantaggioso
qualora si eseguano dei tentativi di miglioramento del codice con solo piccoli aggiustamenti di parametri,
seguiti da una prova effettiva sul campo.

Per scegliere il tipo di connessione

Da Menu testuale, clicchiamo sulla voce Robot,quindi selezioniamo Lego Brick, Communication Link
Setup.

Si apre una finestra nella quale possiamo scegliere il tipo di connessione desiderata.

3
Nella casella Communication Methods si possono scegliere tre opzioni:

USB – Bluetooth – oppure Usb or Bluetooth

La migliore scelta è optare per quest’ ultima opzione, in modo che il programma sceglie automaticamente
l’interfaccia di connessione: se c’è il cavo connesso usa l’USB , in caso contrario usa il Bluetooth.

Per consentire l’uso del Bluetooth si deve abilitare l’opzione anche sul robot, vediamo come.

Si spunta la casella Bluetooth, in modo da abilitare l’interfaccia.

Non basta: serve anche una “password” che viene chiesta quando il PC tenta di stabilire la connessione con
l’EV3. Questa password è semplicemente 1234.

4
E’ fatta! Terminate queste operazioni, è possibile iniziare ad usare RobotC e produrre codice per il nostro
robot. Possiamo passare alla prossima sezione, nella quale capiremo il programma e lo useremo per scrivere
del codice per il nostro robot.

Uso del programma.


All’apertura del programma, viene di default visualizzata una pagina introduttiva che riporta le ultime novità
ed aggiornamenti importanti.

Letti questi (o deciso di non interessarcene) si deve dire al programma cosa fare:

Aprire un programma di esempio

Scegliendo Open Sample Program

Aprire un file presente sul disco sul quale abbiamo lavorato in precedenza

Scegliendo l’opzione Open and Compile

Oppure creando un nuovo file

Scegliendo l’opzione New – New file

5
Siamo pronti a lavorare sul codice sorgente, ma prima c’è ancora una operazione fondamentale: dire al
programma che tipo di sensori e motori ha il nostro robot, ed a quali porte essi sono connessi. In questa fase
possiamo anche dare un nome ai motori ed ai sensori, che sia valido poi all’interno del nostro codice.

Configurazione dell’Hardware del Robot.

Prima di iniziare la programmazione del robot è necessario comunicare al programma la configurazione dei
sensori e dei motori ad esso collegati.

Il robot potrebbe essere di volta in volta differente: avere più o meno sensori e/o motori, collegati magari a
porte differenti. Il software non sa, ovviamente, come è fatto il nostro robot, e per questo è necessario
comunicarglielo.

L’operazione è semplice: basta cliccare sull’icona di configurazione posta in alto al centro:

Nel menu che si apre in risposta alla pressione dell’icona si può scegliere se usare una configurazione
predefinita dal sistema, o se configurare manualmente motori e sensori presenti nel nostro modello.

Inoltre è possibile, una volta configurato un modello di robot, salvarlo su un file e ricaricarlo in futuro, senza
dover di volta in volta ripetere l’operazione.

6
La schermata iniziale, in cui si può scegliere un modello standard di robot, con i sensori ed i motori già
prefigurati, oppure caricare da file un proprio modello (File Containing User Defined Model
Configuration).

Per configurare un modello di robot si deve andare nelle sottosezioni Motors e Sensors

7
Una volta scelti i tipi di sensori e motori, deciso a quali porte del robot sono connessi, e che nome assegnare
loro, si ritorna alla schermata iniziale, dove c’è il pulsante:

Save As New User Model

Cliccando sul pulsante, il programma ci chiede dove salvare il file di configurazione. Dalla volta successiva
non sarà più necessario ridefinire la configurazione ma basterà caricarla dalla schermata iniziale.

Il software RobotC
Robot C è,come dice il nome,un programma per la programmazione dei robot didattici nel linguaggio C.

Il codice sorgente può essere prodotto in due modi distinti, utilizzabili alternativamente:

 Programmazione a blocchi (Graphic RobotC)

 Programmazione in codice sorgente C facilitata ( RobotC natural language)


 Programmazione in C (RobotC)

8
Graphic RobotC (RobotC a Blocchi)
La modalità a blocchi permette l’utilizzo del programma anche a studenti alle prime armi nel coding, magari
provenienti da altre piattaforme semplificate come Scratch, Openroberta Nepo o App Inventor, tutti
programmi prodotti da enti molto importanti nel campo della robotica educativa, che man mano stanno
rendendo i loro prodotti sempre più uniformi come interfaccia e sempre più facili da utilizzare.

Anche la configurazione dell’interfaccia grafica di Graphic RobotC è ispirata al modello delle piattaforme
sopra citate: sulla sinistra una serie di blocchi dotati di un “nome”, che si possono trascinare col mouse sulla
parte destra dello schermo, a comporre il programma.

Non serve quindi quasi per nulla digitare il codice, ma soltanto trascinare i blocchi e “costruire un codice”.
Alla fine, esso si può compilare ed inviare al robot per l’esecuzione.

Il codice, ovviamente, pur se in forma semplificata va costruito con rigore logico e formale, ma tramite
questo approccio si può appiattire la curva di apprendimento del linguaggio.

Una particolarità molto interessante è anche questa: terminato di comporre un codice a blocchi possiamo
vedere il corrispondente codice C con facilità. Questa utilità permette agli studenti di comprendere
istantaneamente in che modo si possono convertire i blocchi in comandi testuali, e facilita enormemente poi
il passaggio verso l’uso del più completo e performante RobotC standard.

Per passare alla visualizzazione del codice C è quello di scegliere da menu: view – e poi Convert Graphical
File to Text.

L’interfaccia grafica:

Come già accennato, i blocchi sono raccolti nella parte destra della finestra del programma, evidenziati con
colori differenti tra loro ed organizzati in gruppi semanticamente omogenei. In alto, in colore arancio, ci
sono i blocchi relativi alla programmazione in C vera e propria.
9
Blocchi relativi a costrutti del linguaggio C

Cicli (repeat,repeat (forever), repeatUntil, while)


Permettono al robot di ripetere più volte una, o un determinato gruppo di istruzioni.

Decisioni (if, if/else, waitUntil).


Permettono al robot di scegliere come comportarsi in base al verificarsi o meno di certe condizioni.

break – esce da un loop o da uno switch

continue – salta una iterazione del loop

Commenti

Subito sotto, in verde, il blocco relativo ai commenti.


I commenti servono agli uomini per inserire del testo nel codice in modo da spiegare ad altri uomini che
leggeranno in futuro il significato del codice e il perché si è scelto di scrivere quelle istruzioni e/o di
assegnare certi valori.
Il robot semplicemente non vedrà i nostri commenti, sono solo utili per altri uomini (o per noi stessi se
dobbiamo riprendere in mano il nostro lavoro a distanza di tempo).

Variabili

10
Sotto ai commenti, i blocchi relativi alle variabili sono contrassegnati dal colore rosso.
Permettono di dichiarare le variabili, di eseguire operazioni di assegnazione e semplici operazioni
matematiche sul contenuto di una variabile.

Simple Behavior (Comportamento Semplice)

I blocchi di questa sezione sono contrassegnati dal colore bianco, come da ora in poi tutti quelli che
incontreremo, perché sono blocchi “di azione” e cioè che prevedono che venga compiuta una azione quando
li inseriamo nel codice.

backward fa andare il robot indietro

forward lo fa andare avanti

moveMotor muove un singolo motore

turnLeft fa girare il robot a sinistra

turnRight lo fa girare a destra

Notiamo che tra tutti questi blocchi, solo moveMotor prevede che sia specificato quale motore muovere. I
restanti blocchi, usando due motori, sanno già quali devono essere usati, perché il robot è già configurato
specificando quali motori sono connessi a quali porte prima di iniziare a programmare.

Spiegazioni ed esempi:

Simple Behaviors

11
Esempi d’uso:

backward (come forward, turnLeft e turnRight) accetta questi parametri:

 nella prima casella un numero intero che sta a specificare per quanto il motore si muove.
 nella seconda casella, c’è la possibilità di aprire un menu a tendina nel quale specificare l’unità di
misura del tempo o dei gradi di rotazione dei motori, per cui il robot si muove.
 nella terza casella, si può specificare la “velocità” (un parametro che va da 0 a 100) di rotazione
del motore.

movemotor accetta i seguenti parametri:

 prima casella: specifico quale motore muovere.


 seconda casella: un numero intero che sta a specificare per quanto il motore si muove.
 terza casella, c’è la possibilità di aprire un menu a tendina nel quale specificare l’unità di misura
del tempo o dei gradi di rotazione dei motori, per cui il robot si muove.
 quarta casella, si può specificare la “velocità” (un parametro che va da 0 a 100) di rotazione del
motore.

12
Motor Commands (comandi dei motori)

In questa sezione sono riuniti i comandi relativi al movimento dei motori. Per capire bene il meccanismo di
gestione dei motori si deve comprendere che ciascun motore del robot contiene un encoder: un componente
optoelettronico che riesce a sapere e ricordare la posizione del motore, e ci permette di muoverlo con
precisione molto alta, anche di un solo grado di rotazione.

In questa sezione abbiamo sostanzialmente tre tipi di comandi: quelli per azionare i motori per un tempo
indefinito:

setMotor e setMultipleMotors

quelli per azionare i motori per un tempo o per un regime di rotazione predefinito:

moveMotorTarget e setMotorTarget

e comandi di spegnimento dei motori:

stopMotor stopMultipleMotors e stopAllMotors

I comandi resetMotorEncoder setMotorReversed e setMotorBrake sono comandi che regolano le


modalità di funzionamento dei motori e dell’encoder in essi presente.

Spiegazioni ed esempi:

Motor Commands

13
Spiegazioni del funzionamento dei singoli blocchi:

Fa muovere un motore verso un obiettivo stabilito.Nelle tre finestre si inseriscono i parametri relativi a
quale motore, quanti gradi di rotazione vogliamo che il motore esegua, e infine la velocità con cui si deve
muovere.

Riporta a zero il valore dell’encoder di un motore. Il solo parametro da inserire è la scelta del motore.

Mette in moto un motore per un tempo indefinito. Nelle due finestre dei parametri, si deve specificare
quale motore si intende azionare, e con quale velocità.

Specifica il modo di spegnimento di un motore: motorBrake indica uno spegnimento brusco, frenando il
motore, mentre motorCoast indica uno spegnimento fluido senza frenatura. I due parametri da inserire
sono il motore ed il modo di spegnimento.

14
Specifica se il motore si deve muovere in un senso o nell’altro. Se nella seconda casella il parametro è
true, il motore si muove in senso contrario rispetto al normale, mentre se il parametro è false il motore si
muove normalmente.

Specifica un obiettivo (in gradi) da raggiungere per il motore: nelle tre caselle delle opzioni vanno inseriti:
il motore, i gradi di rotazione considerati come obiettivo, e la velocità con cui il motore si muove.Non
confondete questo comando con moveMotorTarget , quest’ ultimo comando muove il motore di un tot di
gradi, mentre setMotorTarget stabilisce l’obiettivo di rotazione. Se il motore ha già raggiunto e superato
quell’obiettivo può anche tornare indietro.

Mette in moto più motori per un tempo indefinito. Nelle finestre dei parametri,la prima finestra specifica
la velocità,le restanti quali motori (fino a 4) si intendono azionare.

Beh, non c’è da spiegare niente. Ferma tutti i motori e non necessita di parametri.

Accetta solo un parametro: quale motore si intende fermare.

Nel caso di questo comando i parametri da fornire nelle varie finestre sono i motori da fermare, fino a 4.

15
Remote Control

In questa sezione sono raccolti i comandi relativi al controllo remoto del robot. Non sono interessanti per i
nostri scopi, in quanto noi vogliamo che il robot che andiamo a programmare si muova autonomamente e
non comandato dall’uomo.

Timing

Questo set di blocchi raggruppa i comandi che sono correlati al trascorrere del tempo.Il blocco resetTimer
semplicemente porta a zero il tempo ti uno dei 4 timer di sistema.I timer di sistema partono da quando il
robot è stato avviato (cioè funzionano anche mentre scriviamo il programma e lo trasferiamo al robot). Serve
resettarli (riportarli a zero), se vogliamo che ci forniscano la durata di un qualche evento che avviene dopo
che carichiamo il software.

Il blocco wait, invece ferma l’esecuzione del programma per un certo tempo. Trascorso quel periodo di
tempo, il programma riprende l’esecuzione passando all’istruzione successiva.

Spiegazioni ed esempi:

Timing

Spiegazioni del funzionamento dei singoli blocchi:

Porta a zero uno dei quattro timer di sistema (T1,T4,T3,T4). L’unico parametro necessario è il timer da
azzerare.

16
Ferma temporaneamente l’esecuzione del codice per un tempo prefissato. Nella prima finestra si inserisce
il valore numerico relativo al tempo da attendere e nella seconda si sceglie l’unità di misura: millisecond,
secondi, o minuti.

Line Tracking

In questa sezione sono raccolti i comandi relativi ad un seguilinea già programmato che possa guidare il
robot lungo una traccia sul pavimento usando un sensore ottico. I blocchi non sono interessanti per noi,
perché noi vogliamo usare più di un sensore per seguire la linea, e perché noi vogliamo scrivere
autonomamente la routine seguilinea, senza usare quella predefinita.

Data Logging

Questa è una sezione particolarmente interessante del programma. Con la funzione di data logging possiamo
salvare fino ad otto elenchi di valori letti in tempo reale dai sensori o dai motori durante l’esecuzione del
programma. Terminata l’esecuzione del programma, o addirittura anche durante la fase di debugging è
possibile sia vedere i dati raccolti, che un grafico che ne mostra l’andamento nel tempo.

Spiegazione ed esempi:

Datalog2

17
Spiegazioni del funzionamento dei singoli blocchi:

Il Datalog può salvare i dati in 8 serie differenti (da 0 a 7). DatalogSetup permette di assegnare un
parametro (il valore di una variabile, la posizione o la velocità di un motore, il valore letto da un
sensore,ecc.) ad una serie di dati.Accetta valori in due finestre con possibilità di scelta tramite menu a
tendina: nella prima finestra si sceglie la serie in cui immagazzinare i dati, nella seconda finestra si sceglie
il tipo di dati da registrare.

Questo blocco cancella tutti i vecchi dati nel datalog, prima di iniziare a raccogliere delle nuove serie di
dati.Non ha bisogno di alcun parametro da specificare.

Questo parametro decide la frequenza temporale con cui vengono immagazzinati i dati.Nelle due finestre
si specifica un numero, e nella seconda una unità di misura di tempo. Nel caso qui sopra, ogni 50
millesimi di secondo verranno aggiunti dei dati nel datalog.

Questo blocco fa partire la cattura e l’immagazzinamento dei dati, e lo fa funzionare per il periodo di
tempo indicato nelle finestre dei suoi parametri. Nel caso che vediamo, questa istruzione fa partire la
cattura e l’immagazzinamento dei dati e la fa continuare per 5 secondi.

Questo blocco ferma (anticipatamente rispetto a quanto previsto da datalogStart) la cattura e


18
l’immagazzinamento dei dati.

La registrazione di un datalog ha l’effetto di generare un file con i valori desiderati. Ma come trovare il
file e leggere i valori? La maggioranza delle volte si vogliono soltanto controllare a video i valori, e
quindi basta visualizzare il file.Per fare questo si deve, preventivamente, abilitare la visualizzazione del
datalog nella fase di debug del programma. Dal menu principale di RobotC, si selezione dunque Robot –
Debugger windows – Datalog. Da ora in poi,quando faremo il debug del programma, potremo aprire una
finestra in cui sono riportati i dati del nostro datalog.

Display

Nella sezione Display sono raccolti i comandi per visualizzare alcuni valori sullo schermo del robot.In
qualche modo questa funzionalità è assimilabile a quella del data logging, ma è ancora più immediata
perché mostra i valori già sul robot, mentre questo svolge il suo compito.

Spiegazione ed esempi:

Display2

Nei vari blocchi di comando c’è una parametro da inserire che corrisponde al numero di riga dello
schermo,poiché il display del robot è trattato in questi comandi come fosse una pagina di testo,organizzata
dunque in righe orizzontali.

Non c’è molto da dire: questo blocco vuole che si specifichi il motore e la linea dello schermo nella quale
19
stampare i valori relativi,

Anche in questo caso va specificato il sensore in oggetto e la linea dello schermo da usare per visualizzare
i valori.

Questo blocco ci permette di scrivere testo sullo schermo.Ovviamente vuole come parametri la riga del
display, ed il testo da visualizzare.

Questo blocco è utilizzato per visualizzare a schermo il valore di una variabile. Al solito: i parametri da
indicare sono quale riga dello schermo utilizzare e quale variabile.

EV3 Led

Questo blocco serve a cambiare il colore del led che illumina i pulsanti del robot (Lego EV3). Si possono
scegliere vari colori e decidere se il led deve essere illuminato in modo costante o lampeggiante.

Ecco un esempio di utilizzo:

L’unico parametro necessario è il colore del led. Tra i vari colori, accessibili come sempre cliccando la
freccina rivolta verso il basso dentro alla finestrella delle opzioni, è permesso scegliere anche delle opzioni
che permettono di ottenere il lampeggio del led.

Gyro Sensor

20
Questo blocco riporta a zero il valore del giroscopio. Per capire la sua utilità immaginiamo di voler fare
ruotare il robot di 90 gradi quando incontra un ostacolo: senza fare conti complicati, è facile dire:resetto il
giroscopio e poi muovo i motori fino a che il giroscopio indica 90 gradi.

Ecco un esempio di utilizzo del blocco Come funziona è elementare: si specifica quale giroscopio azzerare.

Touch Sensor

Il blocco resetBumpedValue riporta a zero il numero di pressioni subite dal contatore di tocco.

Anche in questo caso l’utilizzo del blocco è elementare: si deve solo specificare nell’ apposita finestra quale
dei sensori di tocco va azzerato.

Sounds

L’ultima sezione di blocchi è quella che riguarda la riproduzione del suono da parte del robot.La sezione si
compone di due blocchi: playSound, che esegue un suono (scelto tra quelli presenti nella memoria del
robot), e playTone , che invece riproduce una nota (tono).

Il blocco playSound necessita per funzionare di una semplice indicazione: quale tra i vari suoni presenti
nella memoria del robot deve essere riprodotto.

Il blocco playTone necessita di due parametri: la frequenza del tono da generare nella prima finestra (un La
in questo caso, la cui frequenza è di 440 Hz) , e nella seconda finestra un tempo, in millisecondi che indica
la durata della riproduzione.

Considerazioni finali:
21
Graphic RobotC è un programma che ha qualche difetto: a differenza della maggior parte dei prodotti dei
colossi dell’ informatica educazionale (Mit, e Fraunhofer Institute) e del movimento che sorge “dal basso”
(Arduino, Raspberry, ecc) è ancora legato ad un solo sistema operativo e necessita di essere installato su un
computer specifico per funzionare, cosa che impedisce agli studenti di poter lavorare legalmente col
software fuori dall’ambiente scolastico. Inoltre un suo problema è quello della giovane età: soffre infatti di
crash e malfunzionamenti frequenti, e certe cose si comportano oggi in un modo e domani nell’altro. Il
peggiore dei difetti è la difficoltà di reperire informazioni e una valida guida né una comunità attiva di
utilizzatori che dia una mano ai neofiti nel farsi le ossa.

Nonostante questo, è l’unica risorsa per chi vuole programmare in un linguaggio semplice ma che apra le
porte fattivamente all’apprendimento di un linguaggio di alto livello dopo l’introduzione di Lego EV3.
Questo programma, dato il suo utilizzo semplice ed intuitivo, è in grado di permetterci di programmare con
profitto i nostri robot didattici anche in una classe scolastica, dove non è consentito perdere troppo tempo e
distrarre l’attenzione degli alunni con installazioni astruse, trasferimenti di files, uso di IDE cervellotiche.

Il suo maggiore pregio e la sua maggiore funzionalità si estrinsecano nella possibilità di costruire un progetto
pluriennale, magari tra varie istituzioni e gradi scolastici. Gli alunni che inizialmente apprendono la
programmazione col metodo grafico possono passare negli anni successivi all’utilizzo del RobotC per la
programmazione in codice C vero e proprio traendo giovamento dal poter affinare col tempo la conoscenza
del linguaggio utilizzando però sempre lo stesso strumento e la stessa interfaccia.

22
RobotC natural language
Introduzione
RobotC permette di programmare in codice C. Possiede un ottimo IDE, con funzionalità di scrittura di
linguaggio, compilazione e debugging. In aggiunta, permette di trasferire i programmi verso il robot sia via
cavo che wireless.

La compilazione offre delle interessanti funzioni: permette di correggere in automatico i più semplici errori,
individua le variabili dichiarate e non utilizzate ecc.E’ anche presente una funzionalità di sintax highlighting,
e cioè se il programma si accorge che ho scritto una delle parole chiave del linguaggio la evidenzia usando
un colore e uno stile tipografico differente.Questo fa sì che se si commette un errore di scrittura nel digitare
una parola chiave del linguaggio la cosa salta immediatamente all’occhio, e consente di ridurre molti banali
errori di digitazione.

Si possono aprire più file contemporaneamente, in varie finestre.

Il debug può essere semplice ed anche complesso ed articolato: si possono dichiarare dei breakpoint, e si
può fare il log di variabili, stati dei motori, e valori dei sensori.

Si può con facilità scegliere per quale tipo di robot si desidera venga compilato il sorgente.

Si dispone di molti programmi di esempio già fatti, in modo da capire come si usano le procedure per gestire
le varie componenti del robot.

Le procedure di gestione dei motori e dei sensori sono molte e ben fatte, e permettono sia una gestione
semplificata ed intuitiva, sia complessa e sofisticata.Nel nostro tutorial non esamineremo tutte le procedure,
ma ci limiteremo a quelle più interessanti per un utilizzo didattico del programma.Cercheremo quindi di
avere una conoscenza completa delle funzionalità del linguaggio ma senza addentrarci in raffinati controlli
avanzati che presuppongono una conoscenza dell’ hardware.

Configurazione dell’ hardware


Di come si predispone e si carica la configurazione dell’ hardware del robot (motori e sensori) abbiamo già
parlato nella pagina principale, e non vogliamo ripeterci.C’è da dire soltanto che, mentre nel caso del RoboC
grafico, alla fine della configurazione del robot, si entrava semplicemente nell’ambiente di programmazione
nel caso del RobotC testuale alla fine della configurazione dell’ hardware ,ci troviamo all’inizio del codice
una sezione automaticamente generata che contiene i dati dei motori e dei sensori.

23
Organizzazione delle finestre

La finestra del codice

Nella finestra di destra, la più grande ed importante, c’è il nostro codice C: all’apertura del programma , una
volta che si seleziona un nuovo file (mediante il click sull’icona New File in alto a sinistra sulla barra delle
icone), appare automaticamente in essa il codice che dichiara il task main con le relative parentesi graffe di
apertura e chiusura.

Inoltre, è tassativo prima di iniziare la programmazione comunicare al programma quali motori e quali
sensori sono connessi al robot. Una volta che si è compiuta questa operazione (descritta nei dettagli in
precedenza in questo tutorial), la finestra del codice riporterà al suo inizio una aggiunta automatica nella
24
quale sono visualizzati i valori scelti ed i nomi personalizzati che abbiamo assegnato ai motori ed ai sensori.
Alla fine del codice generato automaticamente, un commento ci ricorda che quella sezione è stata scritta
autonomamente dal RobotC (e che da lì in poi inizia invece il codice scritto dal programmatore).

La finestra delle procedure

Nella finestra di sinistra c’è invece un elenco delle procedure di sistema, raggruppate tematicamente (EV3
LED, Motors, Sensors,Natural Language,Sound,Timing) . Aggiungerle al codice è molto facile: basta
trascinarle col mouse nella finestra di destra.In questo modo si evitano anche errori di digitazione.Dopo aver
trascinato una procedura nella finestra del codice appare, tra parentesi tonda, una scritta che ci riassume il
parametro di cui necessita quella procedura.Cliccando col mouse dentro le parentesi tonde e iniziando a
digitare, RobotC capisce intelligentemente quello di cui potremmo avere bisogno e ci propone un menu
contestuale a tendina nel quale scegliere il valore desiderato (Figura sottostante).

La finestra di segnalazione degli errori (debug)

La terza finestra, in basso, è quella usata dal programma per mostrare gli errori di compilazione.

Compilazione
Per ottenere la compilazione, basta cliccare sulla relativa icona: Compile Program: in alto nella barra delle
icone.Prima della compilazione viene salvato il codice sorgente: il programma chiede di inserire un nome
per il file. Questa opzione è davvero utile nel lavoro con gli studenti, che spesso non salvano per
dimenticanza e perdono il lavoro svolto.

RobotC viene in aiuto al programmatore con una funzionalità molto interessante: mentre gli errori gravi
vengono contrassegnati da una X rossa e viene riportata la loro posizione nel codice, lasciando poi al

25
programmatore l’onere di rimediare correggendo il codice, gli errori “veniali” sono riportati, anch’essi, e
contrassegnati da una X gialla e il programma spesso si fa carico della loro correzione automatica.

Se il codice è corretto, non ci sono errori e nella finestra appare una scritta che ci dice che il codice è stato
compilato e visualizza la posizione del file compilato su disco.

Natural Language:
Per chi vuole utilizzare il linguaggio testuale, ma non è ancora esperto a sufficienza per programmare in C
vero e proprio, è disponibile un linguaggio “facilitato”che gli estensori del RobotC hanno chiamato natural
language. Questo linguaggio è composto da procedure di facile memorizzazione ed associazione con i
comportamenti del robot che determinano.Inoltre le procedure stesse sono organizzate e raggruppate
tematicamente, in modo che si possano visualizzare e scegliere, invece di doverle ricordare a memoria.

Per accedere a questa modalità dal menu si scelgono le voci Robot – Robot Type – e si spunta le casella
Natural Language.Questa operazione va fatta una tantum: il programma ricorderà i settaggi e partirà in
questa modalità fino a diverso intervento.

26
Le procedure per il movimento del robot:
Natural Language ha una ottima gestione dei movimenti del robot: dispone di procedure sia semplificate, che
piuttosto sofisticate. Per un uso semplice ed immediato è davvero elementare costruire un codice che sia
funzionale, e questo aiuta molto gli studenti che possono avere una gratificazione immediata vedendo il loro
robottino iniziare subito a muovere i primi passi, senza dover perdere troppo tempo ed energie
nell’apprendere strutture complicate di codice.

Le procedure semplificate per il movimento

La sezione natural language del menu nella sottosezione simple behaviors contiene alcune procedure
semplificate per muovere il robot. Esse sono molto utili per chi è alle prime armi, o per chi usa il software
per finalità didattiche, permettendo di focalizzare subito l’attenzione degli studenti sul comportamento del
robot piuttosto che sul noioso apprendimento di parametri e procedure. Il nome di queste procedure evoca
immediatamente il comportamento del robot che seguirà alla sua esecuzione, ed i parametri di cui
necessitano sono semplici e standardizzati per tutte.Eccole elencate qui sotto:

forward (quantity, unitType, speed);

muove il robot in avanti.

backward (quantity, unitType, speed);

muove il robot indietro.

turnLeft (quantity, unitType, speed);

fa girare il robot a sinistra.

turnRight (quantity, unitType, speed);


27
fa girare il robot a destra.

E riguardo ai parametri,che cosa significano ?

 quantity è una quantità numerica espressa con un numero intero.


 unitType vuole una unità di misura. (degrees=gradi – rotations=rotazioni intere).
 speed vuole una velocità (in una quantità compresa tra zero e 100).

Ma…come fa il programma a sapere come mandare avanti il robot, semplicemente dicendogli “vai avanti”?
Come fa a sapere a che porte sono connessi i motori, che tipo di motori ho attaccato? Lo sa, perché glielo
abbiamo detto quando abbiamo fatto la configurazione del robot, all’inizio. Quindi ora basta dire avanti, o
indietro, o gira, e lui si sa arrangiare.

Le procedure per la gestione dei singoli motori

La gestione dei motori è un po’ incasinata in RobotC. Niente di terribile, soltanto: le procedure sono riunite
in differenti raggruppamenti logici nella finestra di sinistra, il che può creare una certa confusione.

Qui sopra si vede l’organizzazione delle procedure relative alla gestione dei motori.

Sotto al menu Motors ci sono due procedure get, che cioè forniscono dati relativi allo stato dei motori,
anziché permetterci di azionarli.

I comandi per azionare i motori sono invece nella sezione Natural Language ma organizzati in due
sottosezioni differenti. Quasi tutti i comandi relativi all’azionamento dei motori stanno sotto Motor
Commands ad eccezione del malefico moveMotor, che qualche buontempone ha voluto mettere sotto alla
sezione Simple Behaviour.

Cambiare le cose non possiamo e quindi ce ne si fa una ragione: tutti i comandi stanno sotto Motor
Commands, tranne uno.Iniziamo proprio da quello e vediamo come mettere in moto un motore:
28
moveMotor (motorPort, quantity, unitType, speed);

Se il termine moveMotor ci lascia intuitivamente intendere che funzione abbia, dobbiamo capire cosa sono
ed a cosa servono i parametri che ci chiede.

 motorPort sta ad indicare la porta a cui è connesso o il nome del nostro motore.
 quantity vuole una quantità , un numero intero.
 unitType vuole una unità di misura. (degrees=gradi – rotations=rotazioni intere).
 speed è facile: vuole una velocità (in una quantità compresa tra zero e 100).

Esempio: moveMotor (motoredestra, 5, degrees, 74);

Riassumendo, moveMotor è una procedura che fa muovere il motore che desidero ad una velocità che posso
regolare di una quantità di giri o gradi a mio piacere.Terminato il movimento il motore si spegne
automaticamente.

Questo comando avvia un motore singolo per un certo numero di giri o di gradi.Ma se volessi avviare il
motore e mantenerlo in moto senza sapere per quanto?Il comando da usare in questo caso è:

setMotor (motorPort,speed);

Questo comando mette in moto un motore senza specificare per quanti giri o per quanto tempo.
I parametri che chiede sono due:

 motorPort sta ad indicare la porta a cui è connesso o il nome del nostro motore.
 speed è facile: vuole una velocità (in una quantità compresa tra zero e 100).

Esempio: setMotor(motoredestra, 43);

Questo comando di esempio mette in moto un motore che si chiama motoredestra alla velocità di 43 e lo
mantiene in moto indefinitamente.

Da sola, questa istruzione non produce alcun effetto. Quando la incontra, il programma fa partire il motore, e
poi passa all’istruzione successiva così rapidamente che non c’è il tempo per il motore di avviarsi. Quindi
per fare in modo che il motore rimanga attivo devo impedire al programma di proseguire e di passare
all’istruzione successiva.

Il modo più semplice per fare ciò è utilizzare un comando di sleep.

Sleep (x) blocca il programma per un certo tempo (il numero x di millisecondi specificato tra le parentesi
tonde) .Durante questo tempo il motore che ho messo in moto rimarrà attivo.Al terminare del tempo x , il
programma riprenderà l’esecuzione e il motore di conseguenza si fermerà.

All’atto pratico dunque un esempio completo e funzionale di uso del comando (che fa partire e girare il
motore alla “velocità” di 43 per la durata di un secondo ) è il seguente:

Esempio:
setMotor(motoredestra, 43);
sleep(1000);

29
Però facciamo attenzione: durante il periodo di tempo specificato dall’istruzione Sleep il programma diventa
privo di capacità di elaborazione di segnali dai sensori o dai pulsanti: il robot “chiude gli occhi” ed avanza
alla cieca per un secondo. Se, per fare un esempio, il robot dovesse avanzare fino a quando il sensore di
distanza rileva un muro a meno di 10 centimetri, il codice scritto sopra non andrebbe affatto bene.

Ecco che allora si deve ricorrere ai costrutti del C.

Esempio:
while (getUSDistance(sensoredistanza)>10)
{
setMotor(motoredestra, 43);
}

In questo modo il motore rimarrà attivo fino a quando saremo dentro al ciclo e cioè fino a quando la distanza
letta dal sensore di ultrasuoni è maggiore di 10 centimetri. Appena questa condizione cesserà di essere vera,
il motore smetterà di funzionare.

Ma se volessi fare partire più motori contemporaneamente? Il comando c’è ovviamente:

setMultipleMotors(speed,firstMotor,secondMotor,thirdMotor;fourthMotor);

Il suo utilizzo è molto intuitivo ora che sappiamo che parametri si aspetta una procedura di azionamento di
un motore.

Dobbiamo specificare la velocità (uguale per tutti i motori), e quali motori mettere in movimento. Non
necessariamente i motori da avviare devono essere quattro. Basta omettere quelli che non ci interessano.

Esempio:
setMultipleMotors(43, motoredestra,motoresinistra,motorecentro);
sleep(1000);

Si noti che anche in questo caso non basta dare il comando di avviamento del motore ma esso deve essere
seguito da un comando di sleep, oppure deve essere contenuto in un adeguato costrutto del C (ciclo,
thread…)

Se voglio fare andare indietro un motore posso usare due sistemi:

Il primo sistema è quello di usare un parametro di velocità o di rotazione negativo. Alcuni esempi qui sotto,
usando i comandi già visti:

moveMotor (motorPort, quantity, unitType, speed);

30
Come si vede si deve dare un valore negativo al parametro che indica la rotazione.

setMotor (motorPort,speed);

Nel caso di SetMotor, invece, va messo negativo il parametro che indica la “velocità” (speed).

setMultipleMotors(speed,firstMotor,secondMotor,thirdMotor;fourthMotor);

Anche in questo caso, scegliendo come parametro speed un valore negativo, ottengo l’inversione di marcia
dei motori.

Le soluzioni che sono esemplificate sono utili nel caso in cui si voglia muovere un motore alternativamente
avanti ed indietro. E’ possibile invece una soluzione diversa, che prevede di cambiare indefinitamente il
senso di rotazione del motore.Questa soluzione è più utile nel caso in cui un motore debba sempre girare in
senso inverso rispetto agli altri.

setMotorReversed(nMotorindex,bReversed);

Questa procedura accetta come parametri:

 il nome di un motore
 un valore boolean (1 o 0 oppure true o false)

31
In questo esempio il senso di rotazione del motore di destra viene invertito e poi il motore viene mandato
avanti col comando SetMotor, poi il senso di rotazione viene ripristinato alla normalità e di nuovo il motore
viene mandato avanti col comando SetMotor. Il risultato totale è che il robot va avanti ed indietro
ritornando alla posizione iniziale.

Le procedure per la lettura dei sensori


Ora che abbiamo le idee chiare su come gestire i motori, è tempo di capire come leggere i valori dai sensori:
vogliamo che il nostro robot in grado di ricevere degli input dall’esterno e reagire di conseguenza.La
gestione dei sensori coinvolge tecnologie molto differenti tra loro e protocolli di comunicazione anch’essi
differenti, ma il RobotC maschera all’utente la cosa in maniera da permettere di procedure intuitive e
semplici per la maggior parte dei casi.

Il sensore di luce

Il sensore di luce di cui è dotato il Lego EV3 è piuttosto sofisticato. Può leggere sia luce che colore.I modi di
funzionamento del sensore sono tre:

Sensore di luce ambientale: misura e traduce in un segnale elettrico la luce presente nell’ambiente. E’ utile
nelle situazioni in cui la luce ambientale sia elevata.

Sensore di luce riflessa: emette un segnale luminoso e misura la luce riflessa.E’ utile in caso di scarsa luce
ambientale.

Sensore di colore: riconosce il colore del materiale che ha di fronte e/o ne misura le percentuali dei colori
fondamentali Rosso,Verde e Blu.

Le procedure per la gestione del sensore di luce che prenderemo in considerazione in questo documento ci
permettono di gestire tutte queste funzionalità.

getColorAmbient (nDeviceIndex);

E’ la procedura che serve per leggere il valore di luce ambientale. Necessita solo di un parametro che è il
nome del sensore o della porta da cui leggere il dato.

32
Ecco un esempio del suo utilizzo:

luceambiente=GetColorAmbient (sensorecoloredestro);

La procedura restituisce un valore numerico intero proporzionale all’intensità della luce ambientale che
investe il sensore.

getColorReflected (nDeviceIndex);

E’ la procedura che serve per leggere il valore di luce riflessa. Necessita solo di un parametro che è il nome
del sensore o della porta da cui leggere il dato.

Ecco un esempio del suo utilizzo:

luceriflessa=GetColorReflected (sensorecoloresinistro);

Il sensore emette una luce (di tonalità rossa) e la procedura restituisce un valore numerico intero
proporzionale all’intensità della luce riflessa.

getColorRGB (nDeviceIndex,pRedChannel,pGreenChannel,pBlueChannel);

Questa procedura legge i valori delle singole componenti Rossa Verde e Blu della luce vista dal sensore.

Esempio del suo utilizzo:

GetColorRGB (sensorecoloresinistro,colorerosso,coloreverde,coloreblu);

La procedura fa sì che il sensore emetta in rapida sequenza le tonalità di luce Rossa, Verde e Blu, legga di
conseguenza la luce riflessa nelle tre tonalità, e riporti i valori letti dentro a tre variabili che qui abbiamo
chiamato colorerosso, coloreverde, coloreblu. La luce totale letta dal sensore è la somma delle tre
componenti.

Il codice che segue raccoglie un esempio dell’ uso di tutti i comandi descritti riguardanti la gestione del
sensore di colore:

33
Il sensore di distanza ad ultrasuoni

La gestione di questo sensore è piuttosto semplice esso perché fornisce un dato soltanto: la distanza da un
oggetto che gli sta davanti. Perciò la procedura per leggere il sensore di distanza ad ultrasuoni è una soltanto,
ed è la seguente:

getUSDistance (nDeviceIndex);

L’unico parametro da fornire è la porta o il nome del sensore. La lettura del sensore fornisce la distanza in
centimetri tra il sensore e l’oggetto che gli sta di fronte. Da notare che i nuovi sensori di distanza dell’ EV3
usano un protocollo di comunicazione differente da quello dell’ NXT e questo significa che non è possibile
usare questa procedura per leggere i vecchi sensori.

E’ comunque possibile leggere i sensori di distanza ad ultrasuoni degli NXT mediante la procedura:

sensorValue (nDeviceIndex);

Da notare che se vogliamo usare dei sensori di precedenti generazioni con la piattaforma EV3, dobbiamo
prima configurare la sezione Motor and Sensor Setup, scegliendo il tipo di sensore sotto la voce NXT
Legacy Sensors.

Il sensore di tocco

Il sensore di tocco dà alcune semplici informazioni: il suo stato attuale, e cioè se l’interruttore presente in
esso è premuto o non premuto (rispettivamente stato logico 1 o 0) e quante volte è stato premuto.Per
conoscere lo stato del sensore allo stato attuale possiamo usare la procedura:

getTouchValue (nDeviceIndex);

Dobbiamo specificare come parametro, come sempre, la porta cui è connesso o il nome del sensore. La
risposta sarà un valore booleano: true o false, ovvero 0 oppure 1.

Una seconda procedura per la gestione del sensore di tocco ci fornisce il numero di volte per le quali è stato
premuto:

getPumpedValue (sensorport);

Anche questa procedura è di semplice utilizzo e necessita di un solo parametro: la porta a cui il sensore è
connesso.

L’ ultima procedura per la gestione del sensore riporta a zero il contatore del sensore, e quindi il numero di
volte per cui è stato premuto. Il suo nome è esplicativo:

resetPumpedValue (sensorport);
34
Ed ancora, la procedura necessita di un solo parametro: la porta a cui il sensore è connesso.

Il “Gyro sensor”

Il Gyro sensor è un sensore complesso e sofisticato (nei fatti non è proprio e soltanto un giroscopio ma
qualcosa di più sofisticato), ma la lettura dei suoi dati anche in questo caso avviene in maniera molto
semplice per il programmatore.Le procedure per il suo utilizzo sono poche, e di facile impiego. La più
semplice di esse serve per azzerare i valori del giroscopio, ed è molto importante perché questo sensore per
sua natura tende ad avere errori di lettura che si sommano nel tempo. Il suo utilizzo comune quindi è il
seguente: si azzerano i suoi valori e poi lo si legge dopo poco,per poi azzerare nuovamente, oppure lo si
azzera e subito dopo si fa muovere il robot mentre contemporaneamente si leggono i dati dal sensore fino al
raggiungimento di un certo valore desiderato.

resetGyro (nDeviceIndex);

Molto semplice il suo utilizzo: si deve solo specificare nome della porta o del sensore da azzerare.

La procedura per la lettura dei gradi di rotazione invece è la seguente:

getGyroDegrees(nDeviceIndex);

Ovvio e semplice: richiede la porta cui è connesso oppure il nome del sensore, e fornisce un numero di gradi
di rotazione che sono intercorsi dall’ultima volta in cui il sensore è stato azzerato (o dall’accensione, se non
lo abbiamo mai azzerato). Il valore restituito sarà positivo se la rotazione è avvenuta in un verso, e negativo
se è avvenuta in senso opposto.

Altra procedura per la lettura dei gradi di rotazione:

getGyroDegrees(nDeviceIndex);

La differenza tra la procedura in questione e quella precedente è sottile ma importante:


getGyroDegrees(nDeviceIndex) fornisce una orientazione in cui il sensore è stato azzerato (o
dall’accensione, se non lo abbiamo mai azzerato) , e quindi il suo range è limitato a 360 gradi. Superati i 360
gradi si azzera. Il parametro unico di cui necessita è la porta di connessione del sensore o il suo nome.

La procedura che segue è quella propria di un giroscopio: ci fornisce la velocità istantanea di rotazione:

getGyroRate(nDeviceIndex);

L’unità di misura è gradi/secondo ed il range di valori che può fornire va da -440 a +440 gradi/secondo.
Questa procedura ci è quindi utile per capire se il robot si sta girando, e con che velocità lo fa.

L’unico parametro di cui necessita è la porta di connessione del sensore o il suo nome.

35
La gestione del led di EV3
Il brick EV3 è dotato di un LED che illumina i pulsanti il quale può assumere colorazioni varie. Il Led
permette al robot di comunicare visivamente il verificarsi di un evento anche a distanza e quindi è utile per
la programmazione come feedback di facile ed immediata fruizione. Per spegnerlo , accenderlo, cambiare il
suo colore, si usa in RobotC una sola procedura:

setLEDColor(LEDpatterns);

Non c’è bisogno di specificare quale LED essendocene uno solo, e l’unico parametro da fornire alla
procedura è il tipo di accensione del LED. Non solo il colore, dunque, ma anche se il LED deve
lampeggiare o meno, ed in che maniera.

setLEDColor(LEDOff); – Led spento.

setLEDColor(LEDRed); – Led acceso costantemente, colore rosso.

setLEDColor(LEDGreen); – Led acceso costantemente, colore verde.

setLEDColor(LEDOrange); – Led acceso costantemente, colore arancio.

setLEDColor(LEDRedFlash); – Led acceso intermittente, colore rosso.

setLEDColor(LEDGreenFlash); – Led acceso intermittente, colore verde.

setLEDColor(LEDOrangeFlash); – Led acceso intermittente, colore arancio.

L’intermittenza prodotta da Flash prevede l’alternarsi di un istante in cui il LED è attivo ed un istante di pari
durata in cui il LED è spento.

setLEDColor(LEDRedPulse); – Led acceso intermittente, colore rosso.

setLEDColor(LEDGreenPulse); – Led acceso intermittente, colore verde.

setLEDColor(LEDOrangePulse); – Led acceso intermittente, colore arancio.

L’intermittenza prodotta da Pulse prevede l’alternarsi di due brevi istanti in cui il LED è acceso (intervallati
da un brevissimo periodo di spegnimento), ed una pausa in cui il LED è spento.

Eco qui sotto un esempio che riassume tutti i modi di utilizzare il LED di EV3

36
La gestione del display LCD
Anche il display LCD è molto utile come strumento di output da parte del robot.Differentemente dal LED i
messaggi che comunica sono difficili da apprezzare se non si osserva il robot da vicino, o se il robot è in
movimento, ma al contrario del LED è possibile visualizzare messaggi complessi ed articolati.

Le procedure di gestione del display LCD sono quattro. I dati vengono visualizzati su display LCD
indicando la riga su cui scriverli. Le righe sono 8, numerate da 1 a 8.

La prima procedura stampa su una linea del display i dati dell’ encoder di uno specifico motore:

displayMotorValues(linenumber,nDeviceIndex);

Gli argomenti da fornire alla procedura sono:il numero di linea del display LCD su cui scrivere ed il nome o
la porta cui è connesso il motore.

La seconda procedura stampa su una linea del display i dati letti da un qualunque sensore. E’ forse la
procedura maggiormente usata, perché permette, se usata con intelligenza, di capire esattamente quali sono i
dati che il robot riceve dai sensori in qualsiasi momento vogliamo.

displaySensorValues(linenumber,nDeviceIndex);

37
Gli argomenti da fornire sono: il numero di linea del display LCD su cui scrivere il dato ed il nome o la
porta cui è connesso il sensore.

La terza procedura stampa su una linea del display i valori di una variabile dichiarata all’interno del
programma:

displayVariableValues(linenumber,value);

Richiede questi due argomenti : la linea del display LCD su cui scrivere il dato ed il nome della variabile il
cui contenuto va visualizzato.

L’ultima variabile per la gestione del display LCD è quella che permette di scrivere qualsiasi cosa
desideriamo usando una variabile di tipo stringa come contenitore del testo. Per usarla va dunque dichiarata
al variabile all’interno del programma, poi va “riempita” col testo desiderato, poi si chiama la procedura e si
stampa sullo schermo il suo contenuto.

displayText(linenumber,sString);

La procedura richiede come parametri il il numero di linea del display LCD su cui scrivere il dato ed il
nome della variabile stringa.

Qui sotto sono raccolte in un esempio tutte le procedure per la gestione del display LCD.

La riproduzione di suoni e di note


La riproduzione del suono completa (e termina) la sezione dedicata alle comunicazioni del robot verso il
mondo esterno. In modo simile all’accensione del LED, questo modo di comunicare verso il mondo esterno
38
raggiunge con facilità ed immediatezza tutti gli osservatori circostanti , anche ad una certa distanza. E’
quindi molto usato come strumento di debug e di monitoraggio del robot, ma è anche usato per divertimento
e gioco. E’ divertente che il robot suoni una musichetta quando ha finito con successo il suo compito, o
produca un suono greve se si accorge di aver fallito la missione. La gestione del suono è quindi una sezione
importante perché di certo gli studenti lo utilizzeranno massicciamente durante la programmazione.

Per fortuna il RobotC ci permette di gestire il suono in modo facile ed intuitivo, tramite solo due procedure.

La prima procedura effettua la riproduzione di un suono tramite l’altoparlante di cui EV3 è equipaggiato:

playSound(sound);

Il solo parametro di cui necessita è il nome del suono di cui si desidera la riproduzione.

La seconda procedura effettua invece la riproduzione di una nota.

PlayTone(frequency,durationin10MsecTicks);

I parametri di cui necessita sono la frequenza della nota da riprodurre ed il tempo di riproduzione della
stessa. Mediante una procedura simile è possibile ottenere delle informazioni sul robot e sui dati forniti dai
sensori. Immaginiamo ad esempio di assegnare il valore della frequenza da riprodurre al valore letto da un
sensore.Otterremo una nota acustica che ci fa capire in tempo reale il range del valore del dato fornito dal
sensore al robot.

Qui sotto è riportato un codice con gli esempi d’uso delle procedure per la gestione del suono:

Timing
La gestione del timing è una funzione accessoria di RobotC che è interessante prendere in considerazione
nel nostro tutorial perché permette di gestire il comportamento del robot nel tempo. Alcune operazioni
affidate al robot necessitano di sincronizzazione precisa, altri compiti invece hanno un tempo massimo per
essere eseguiti. In tutti questi casi una precisa gestione e conoscenza dei tempi è molto utile.
39
Come sempre RobotC ci permette una gestione molto semplice mettendoci a disposizione delle procedure
intuitive e con nomi semplici da ricordare. RobotC mette a disposizione dell’ utilizzatore quattro timers, i
cui nomi sono T1,T2,T3,e T4. Ciascuno di questi timer è accessibile ed azzerabile a piacere.

La procedura di azzeramento è la seguente:

clearTimer(theTimer);

Il parametro di cui necessita è semplicemente il nome di uno dei quattro timers.

La lettura del tempo avviene invece con la procedura:

time1[ ];

Nella parentesi quadra va indicato il nome del timer da leggere.

Qui sotto c’è un codice di esempio dell’ uso delle procedure di timing:

Datalog
Il nostro tutorial si conclude prendendo in considerazione la funzionalità di datalog. A differenza di quanto
abbiamo appreso fino ad ora , la conoscenza dell’ uso del datalog non accrescerà la nostra capacità di gestire
le caratteristiche hardware del nostro robot ma ci consentirà invece di andare ad analizzare il software che
abbiamo scritto e capire come viene eseguito da parte del robot, consentendoci con questo di capire le
criticità e correggere gli errori o regolare in maniera precisa i parametri che forniamo al robot via software. Il
datalog non è che la registrazione in tempo reale di quello che succede al robot durante l’esecuzione del
software. Questa registrazione può essere visualizzata in tempo reale, oppure in seguito, per capire ed
analizzare la situazione in cui il robot si trovava e il come ha messo in pratica i comandi impartiti.

Per capire come usare il datalog dobbiamo intanto comprendere che RobotC permette di memorizzare in
esso fino ad otto canali diversi, registrati simultaneamente in un gruppo.

40
Dobbiamo quindi, per usare il datalog, scrivere un valore in uno degli 8 canali del datalog tramite la
procedura:

datalogAddValue (canale, valore);

I parametri della procedura sono quindi costituiti dal numero del canale di datalog che vogliamo usare, e dal
valore che desideriamo memorizzare in esso. Possiamo assegnare fino ad 8 canali e valori differenti.

Se vogliamo che i dati vengano raccolti e raggruppati tra loro è conveniente usare le due procedure:

datalogDataGroupStart (); e datalogDataGroupEnd ();

Che non hanno bisogno di parametri. Nelle esempio che segue raccogliamo i dati di due sensori di colore
dentro al datalog usando il primo ed il secondo canale per registrare i dati di ciascun sensore.

Una volta raccolti i dati, RobotC ci permette visualizzarli a monitor, di visualizzarne il grafico e di salvarli
come file formato csv, leggibile con facilità dai fogli elettronici.

Per poter vedere i dati del datalog a schermo dobbiamo abilitare la funzionalità di visualizzazione.Da menu,
scegliere Debugger Windows e spuntare l’opzione Datalog.

41
D’ora in avanti quando andremo a scaricare il codice sul computer e ci apparirà la finestra di debug in fondo
allo schermo, potremo in essa selezionare l’opzione Datalog e visualizzare a schermo i dati raccolti.

Inoltre potremo accedere alla sezione relativa al datalog cliccando su Show Datalog, nella finestrella
Program Debug.

42
Dentro alla sezione Datalog Control, che ora appare possiamo compiere operazioni sul dati relativi al
datalog (cancellazione,salvataggio) e visualizzarne il grafico premendo Show Graph.

43