Una Introduzione ad Arduino

69
Introduzione La Testa Robotica Una Introduzione ad Arduino Prof. Michele Scarpiniti Dipartimento di Ingegneria dell’Informazione, Elettronica e Telecomunicazioni “Sapienza” Universit` a di Roma http://ispac.diet.uniroma1.it/scarpiniti/index.htm [email protected] M. Scarpiniti Una Introduzione ad Arduino 1 / 69

Transcript of Una Introduzione ad Arduino

IntroduzioneLa Testa Robotica

Una Introduzione adArduino

Prof. Michele Scarpiniti

Dipartimento di Ingegneria dell’Informazione, Elettronica e Telecomunicazioni“Sapienza” Universita di Roma

http://ispac.diet.uniroma1.it/scarpiniti/index.htm

[email protected]

M. Scarpiniti Una Introduzione ad Arduino 1 / 69

IntroduzioneLa Testa Robotica

1 IntroduzioneIntroduzioneL’IDEGli esempi

2 La Testa RoboticaL’hardwareIl softwareIl funzionamento

M. Scarpiniti Una Introduzione ad Arduino 2 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Introduzione

Introduzione

M. Scarpiniti Una Introduzione ad Arduino 3 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Introduzione

L’obiettivo di queste slides e di introdurre ed illustrare il funzionamento dellascheda Arduino attraverso semplici esempi.

Si vedra, in particolare, l’applicazione di Arduino nel controllare una testarobotica in grado di localizzare una sorgente in movimento all’interno di unastanza attraverso una coppia di microfoni (orecchi) e una coppia di webcam(occhi).

Maggiori informazioni su Arduino e accessori possono essere reperite al linkhttp://www.arduino.com/ da cui e anche possibile scaricare l’ambientegrafico (IDE) per la programmazione del dispositivo.

M. Scarpiniti Una Introduzione ad Arduino 4 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Arduino in sintesi

Arduino e una piccola scheda equipaggia-ta con un microcontrollore e una circui-teria di contorno, utile per creare rapi-damente prototipi. Con Arduino si pos-sono realizzare in maniera relativamenterapida e semplice, piccoli dispositivi per ilcontrollo di sensori e attuatori.

Completamente italiano, il progettodi Arduino e stato sviluppato pressol’Interaction Design Institute, un istitu-to di formazione post-dottorale con se-de a Ivrea, fondato da Olivetti e TelecomItalia.

M. Scarpiniti Una Introduzione ad Arduino 5 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

La storia di Arduino

Il nome della scheda deriva da quello di un bar di Ivrea frequentato da alcuni deifondatori del progetto. Il progetto ha preso avvio in Italia ad Ivrea, nel 2005,con lo scopo di rendere disponibile, a progetti di Interaction design realizzati dastudenti, un device per il controllo che fosse piu economico rispetto ad altri sistemidi prototipazione disponibili all’epoca.

I progettisti sono riusciti nell’intento di creare una piattaforma di semplice utilizzoma che, al tempo stesso, permettesse una significativa riduzione dei costi rispettoa molti prodotti disponibili sul mercato. A ottobre 2008 erano gia stati venduti piudi 50.000 esemplari di Arduino in tutto il mondo.

A partire dal 2015, per via di alcune scel-te dei creatori del progetto, il marchio Ar-duino e disponibile solo sul mercato ame-ricano. Nel resto del mondo, le stesseschede vengono commercializzate con ilnuovo marchio Genuino.

M. Scarpiniti Una Introduzione ad Arduino 6 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Arduino UNO (Genuino UNO)

La scheda piu comune e diffusa della famiglia Arduino e senz’altro Arduino UNO(ovvero Genuino UNO, in Europa), equipaggiato di un micro-controllore ATme-ga328P della Atmel. E’ poi presente una porta USB per interagire con il PC ecaricare il software e vari connettori per l’I/O, in particolare:

1 14 connettori per l’I/O digitale (numerati da 0 a 13);

2 6 connettori specificamente dedicati a ingressi di segnali analogici (collegatiquindi ad una ADC).

M. Scarpiniti Una Introduzione ad Arduino 7 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Arduino UNO: specifiche tecniche

Le specifiche tecniche di Arduino UNO sono riportate nella seguente tabella.

Microcontrollore ATmega328POperating Voltage 5VInput Voltage (recommended) 7-12 VInput Voltage (limit) 6-20 VDigital I/O Pins 14 (of which 6 provide PWM output)PWM Digital I/O Pins 6Analog Input Pins 6DC Current per I/O Pin 20 mADC Current for 3.3V Pin 50 mAFlash Memory 32 KB of which 0.5 KB used by bootloaderSRAM 2 KBEEPROM 1 KBClock Speed 16 MHzLength 68.6 mmWidth 53.4 mmWeight 25 g

M. Scarpiniti Una Introduzione ad Arduino 8 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Arduino UNO: l’anatomia della scheda

Descriviamo nello specifico le varie parti e i vari componenti della scheda Arduino UNO.

1 Pin digitali: per leggere da sensori e scrivere su attuatori;

2 LED pin 13: utile per il debugging ;

3 LED accensione: indica se la scheda e accesa;

4 Microcontrollore ATmega: il cuore della scheda;

5 Ingressi analogici: per leggere valori analogici;

6 Pin alimentazione GND e 5V: per fornire l’alimentazione a aidispositivi collegati;

7 Connettore alimentazione: per alimentare la scheda se nonconnessa tramite porta USB. Accetta tensioni nell’intervallo7-12 V;

8 LED di TX e RX: indicano la comunicazione tra la scheda e ilcomputer;

9 Porta USB: per collegare la scheda al computer;

10 Tasto di Reset: per resettare il microcontrollore.

M. Scarpiniti Una Introduzione ad Arduino 9 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Altre schede della famiglia Arduino

Esistono diverse varianti alla scheda Arduino/Genuino UNO. Le piu diffusesono elencate nella seguente tabella.

Entry Level Genuino UNO, Genuino 101, Genuino MICROEnhanced Features Genuino MEGA, Genuino ZERO, Genuino YunInternet of Things Genuino MKR1000

In particolare, l’ultima scheda e stata progettata per offrire una soluzionepratica e conveniente per coloro i quali cercano di aggiungere ai loro progettila connettivita Wi-Fi con il minimo sforzo.

M. Scarpiniti Una Introduzione ad Arduino 10 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

L’IDE di Arduino

L’ambiente di sviluppo integrato (IDE) di Arduino e un’applicazione multi-piattaformascritta in Java, che include un editore di testo dotato di syntax highlighting, il con-trollo delle parentesi e indentazione automatica. L’editor e inoltre in grado dicompilare e lanciare il programma eseguibile in una sola passata e con un soloclick. La sintassi e C-like, ma molto piu intuitiva.

L’IDE e utilizzata per scrivere i codici sor-genti che contengono tutte le istruzioninecessarie affinche il computer possa con-trollare tutte le funzionalita di Arduino.Tali codici sono chiamati sketch. L’IDEsi occupa anche di trasferire tali istruzionisulla scheda (upload) in modo tale che Ar-duino funzioni anche se non piu connessoal calcolatore.

M. Scarpiniti Una Introduzione ad Arduino 11 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

L’IDE di Arduino: il Monitor Seriale

L’IDE di Arduino mette a disposizione uno strumento molto comodo, chia-mato monitor seriale. Il monitor seriale e uno strumento che permettedi leggere i dati che Arduino comunica tramite la porta seriale (COM) alcomputer e consente anche di stampare alcuni messaggi utili per testare ilcorretto funzionamento dell’applicazione. L’interfaccia del monitor seriale erappresentata di seguito.

M. Scarpiniti Una Introduzione ad Arduino 12 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Le funzioni principali dell’IDE di Arduino

Quando si apre l’IDE per scrivere un nuovo sketch, sul prompt compaiono le de-finizioni di due funzioni da editare, che risultano fondamentali per il correttofunzionamento del dispositivo:

void setup()

// put your setup code here , to run once:

void loop()

// put your main code here , to run repeatedly:

Tali funzioni si occupano delle inizializzazioni di tutte le variabili e della definizionedei compiti che la scheda dovra ripetere durante l’intero funzionamento.

Eventuali altre funzioni, da utilizzare all’interno di loop(), possono essere definite

a seguire.

M. Scarpiniti Una Introduzione ad Arduino 13 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

La funzione setup()

La funzione setup() viene chiamata all’inizio del programma e viene utiliz-zata per inizializzare tutte le variabili, i vari pin e per linkare tutte le librerienecessarie.

Questa funzione viene eseguita una sola volta, all’avvio dell’applicazione.Segue un esempio:

int buttonPin = 3;

void setup()

Serial.begin (9600);

pinMode(buttonPin , INPUT);

In questo esempio, si crea una variabile buttonPin, che rappresenta il terzopin digitale, impostandola come un input e abilitando la comunicazioneseriale a 9600 b/s. L’intento e dunque, di leggere il livello di tensione(basso o alto) dal pin 3.

M. Scarpiniti Una Introduzione ad Arduino 14 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

La funzione loop()

La funzione loop(), chiamata subito dopo la setup(), e iterata costan-temente per tutta la durata dell’applicazione, eseguendo ad ogni ciclo leistruzioni presenti nel suo blocco. Tale funzione e dunque utilizzata per ladescrizione dei compiti che la scheda dovra compiere. Segue un esempio:

void loop()

if (digitalRead(buttonPin) == HIGH)

Serial.println(’H’);

else

Serial.println(’L’);

delay (1000);

In tale esempio, si legge la tensione dal pin 3, impostato precedentemente,e se la tensione e alta si scrive H nel monitor seriale, altrimenti L. Dopoogni lettura del pin si attende un secondo.

M. Scarpiniti Una Introduzione ad Arduino 15 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Le funzioni principali

Nelle funzioni precedenti sono state utilizzate alcune funzioni fondamentali,di seguito descritte.

Serial.begin(speed): setta la velocita di trasmissione tramite laporta seriale al valore indicato;

pinMode(pin, mode): configura il comportamento (INPUT o OUTPUT)del pin indicato;

digitalRead(pin): legge il valore digitale (HIGH o LOW) dal pinindicato;

Serial.println(’stringa’): stampa un valore o una stringa sulmonitor seriale, andando poi a capo;

delay(ms): mette in pausa il programma per un numero di millisecondispecificato.

M. Scarpiniti Una Introduzione ad Arduino 16 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Le librerie principali

Molte funzionalita utili nelle applicazioni, sono raccolte in librerie di funzionidisponibili nell’IDE. Un esempio e la libreria Serial utilizzata precedentemen-te, che consente la comunicazione seriale, oppure la Servo che implementai metodi per la gestione dei servomeccanismi.

Per utilizzare nell’IDE una certa libreria, la si deve includere con la direttiva

# include <Libreria.h>

Ad esempio, se volessi utilizzare la libreria Servo:

# include <Servo.h>

void setup()

// il mio codice

void loop()

// il mio codice

M. Scarpiniti Una Introduzione ad Arduino 17 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Le librerie principali

Anche se esistono alcune librerie specifiche solo per alcuni modelli di Arduino, e disponibileun insieme di librerie standard funzionanti su tutti i dispositivi. Nello specifico:

Libreria DescrizioneEEPROM Lettura e scrittura su supporti permanentiEthernet Per utilizzare una scheda di rete opzionaleFirmata Per comunicare attraverso un protocollo seriale standardGSM Per utilizzare una scheda GSM opzionaleLiquidCrystal Per il controllo di display a cristalli liquidi (LCD)SD Lettura e scrittura su SD cardSerial Per le comunicazioni seriali con PC e serial monitorServo Per il controllo dei servo-motoriSPI Per comunicare attraverso il bus Serial Peripheral Interface (SPI)SoftwareSerial Per le comunicazioni seriali verso i pin digitaliStepper Per il controllo di motorini passo-passoTFT Per comandare schermi TFTWiFi Per la connessione wireless attraverso un’apposita schedaWire Per ricevere/inviare dati dalle interfacce TWI/I2C

M. Scarpiniti Una Introduzione ad Arduino 18 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

La libreria Serial

La libreria Serial e fondamentale per qualsiasi applicazione, poiche abilita la comunica-zione da e verso computer ed inoltre abilita l’utilizzo del monitor seriale. Non e possibileimmaginare di lavorare senza. Per questo motivo, tale libreria e predefinita nell’IDE diArduino e non e necessaria includerla manualmente con la direttiva #include.

Tale libreria include 21 funzioni. Oltre la begin(), le piu importanti sono:

available(): restituisce il numero di byte disponibili nel buffer di lettura (che nepuo contenere fino a 64);

end(): termina la comunicazione seriale;

peek(): restituisce il byte (o carattere) seriale successivo , senza rimuoverlo dalbuffer;

print(), println(): stampa un valore (o una stringa) sulla porta seriale o monitorseriale. Il secondo comando manda a capo;

read(): legge i dati dalla connessione seriale;

setTimeout(): configura il tempo massimo (in millisecondi) di attesa per la comu-nicazione seriale;

write(): scrive dati binari alla porta seriale.

M. Scarpiniti Una Introduzione ad Arduino 19 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

La libreria Serial

Tale libreria (Serial) e quindi utilizzata per la comunicazione tra la schedaArduino e il computer o altri dispositivi. Tutte le schede Arduino hannoalmeno una porta seriale (anche nota come UART o USART). La comuni-cazione avviene sul pin digitale 0 (RX, per la trasmissione) e sul pin digitale1 (TX, trasmissione) e con il computer tramite la porta USB. Quindi, se siutilizzano le funzioni di tale libreria, non e possibile utilizzare i pin 0 e 1 perl’ingresso o l’uscita digitale da eventuali sensori/attuatori.

E anche possibile utilizzare l’ambiente monitor seriale, incorporato in Ardui-no, per comunicare con la scheda. Facendo clic sul pulsante del monitorseriale nella barra degli strumenti e selezionando la stessa velocita di trasmis-sione utilizzata nella chiamata di Serial.begin(), si aprira una finestra incui e possibile stampare (scrivere) valori ricevuti (trasmessi) dalla scheda.

M. Scarpiniti Una Introduzione ad Arduino 20 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

La modulazione PWM

La modulazione a larghezza di impulso (Pulse Width Modulation o PWM) puoessere usata in Arduino per ottenere valori analogici a partire da segnali digitali.Un segnale PWM e, in effetti, un’onda quadra che varia da 0 V a 5 V, con frequenzacostante, ma in cui e variabile la frazione di tempo in cui il segnale e attivo a 5 V(detto dutycycle), che puo variare tra lo 0 e il 100 %.

La modulazione PWM e implementata in Arduino tramite la funzione:

analogWrite(pin , dutyCycle)

dove dutyCycle e un valore tra 0 e 255, e pin euno dei pin PWM (3, 5, 6, 9, 10 o 11). Il comandoanalogWrite non fornisce alcun controllo sulla fre-quenza. Il valore della tensione di uscita del pin sarauna frazione dei 5 V, proporzionale al dutycycle: equindi possibile far variare con continuita una tensioneda 0 a 5 V.

M. Scarpiniti Una Introduzione ad Arduino 21 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Alcuni semplici esempi

L’IDE di Arduino mette a disposizione un certo numero di esempi moltoutili per chi e alle prime armi. Infatti, attraverso questi esempi, e possi-bile imparare l’utilizzo delle funzioni e delle librerie principali. Tali esempisono suddivisi per categoria (analogico, digitale, comunicazione, controllo,sensori, display, USB, ecc.) e sono accessibili dal menu File => Esempi.Alcuni di questi esempi sono descritti approfonditamente nel testo “GenuinoProjects Book”, che e venduto insieme allo starter kit, che contiene, oltrealla scheda Genuino UNO, numerosi altri componenti per implementare gliesempi proposti.

E’ comunque possibile trovare numerosi altri esempi in rete oppure nei tantitesti dedicati alla scheda, facilmente reperibili in commercio.

M. Scarpiniti Una Introduzione ad Arduino 22 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Far lampeggiare un LED

Il primo classico esempio consiste nel far lampeggiare un LED. Si collega un LEDrosso, con in serie un resistore, tra il pin digitale 13 e il pin GND, come schemati-camente indicato nelle figure seguenti. Si programma quindi la scheda per inviarealternativamente una tensione alta (5 V) e una bassa (0 V) al pin 13.

Il resistore R serve per limitare il valore della corrente che scorre nel LED, per nonbruciarlo ed il suo valore e calcolato come:

R =V − VLED

I≡ 5− 1.7

15 · 10−3= 220 Ω,

in cui I e la corrente (di solito intorno ai 15÷ 20 mA) e VLED = 1.7 V per il LED

rosso.M. Scarpiniti Una Introduzione ad Arduino 23 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Far lampeggiare un LED

Lo sketch di Arduino che fa lampeggiare il LED e il seguente:

void setup()

pinMode (13, OUTPUT); // pin digitale 13 impostato come

output

Si inizializza, cioe, il pin digitale 13 come uscita:

void loop()

digitalWrite (13, HIGH); // si accende il LED

delay (1000); // si aspetta 1 secondo

digitalWrite (13, LOW); // si spegne il LED

delay (1000); // si apsetta 1 secondo

Si ripete ciclicamente: si invia tensione alta in uscita al pin 13 (LED acceso), si

aspetta 1 secondo, si invia tensione bassa (LED spento), si aspetta 1 secondo e

cosı via finche non si stacca la scheda. Quindi ogni secondo il LED si accende e si

spegne.

M. Scarpiniti Una Introduzione ad Arduino 24 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Far sfumare l’intensita di un LED

Si vuol far variare con continuita l’intensita in un LED, aumentandola gradualmentefino ad un valore massimo e poi diminuendola fino a spegnere il LED e poi di nuovoaumentandola. A tal proposito si utilizza la modulazione PWM. Il LED sara dunquecollegato ad un pin analogico (il pin 9), controllato con un dutycycle variabile da0 a 255 e di nuovo a 0, attraverso la funzione analogWrite(pin, dutyCycle).

Anche in questo caso il resistore R1 e determinato come nel caso precedente.

M. Scarpiniti Una Introduzione ad Arduino 25 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Far sfumare l’intensita di un LED

Lo sketch di Arduino inizia con la definizione di tre variabile che indicano il numerodel pin a cui collegare il LED, il valore della luminosita iniziale del LED e di quantofar aumentare la luminosita dopo un certo intervallo temporale. Si sceglie il pinnumero 9 che e uno di quelli abilitati alla modulazione PWM, con cui si fara variarel’intensita.

int led = 9; // il pin PWM del LED

int brightness = 0; // luminosita del LED

int fadeAmount = 5; // variazione della luminosita del LED

La funzione setup() imposta semplicemente il pin a cui e collegato il LED (ilnumero 9) come un pin di uscita.

void setup()

pinMode(led , OUTPUT); // il pin 9 e impostato come output

M. Scarpiniti Una Introduzione ad Arduino 26 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Far sfumare l’intensita di un LED

La funzione loop() imposta inizialmente il valore di luminosita iniziale (pari a zero)e quindi il LED risulta spento. Si aumenta quindi l’intensita del valore prestabili-to fadeAmount, si aspetta per 30 millisecondi e si reimposta la nuova luminositacon analogWrite(). Se nel frattempo si e raggiunta la luminosita massima,cioe l’onda quadra e diventata una costante con dutycycle pari a 255, la variabilefadeAmount viene impostata negativa in modo da diminuire gradualmente l’in-tensita. Viceversa, quando il dutycycle e divenuto nullo, la variabile fadeAmount

viene reimpostata positiva per aumentare l’intensita e cosı via.

void loop()

analogWrite(led , brightness); // impostare la luminosita

brightness = brightness + fadeAmount; // cambio di

luminosita

if (brightness == 0 || brightness == 255) // raggiunto

il limite massimo si inverte la luminosita

fadeAmount = -fadeAmount;

delay (30); // aspetta 30 millisecondi

M. Scarpiniti Una Introduzione ad Arduino 27 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Rilevatore di vibrazione

Il prossimo esempio, consiste in un rilevatore di vibrazione attraverso un sensorepiezoelettrico. Se il sensore piezoelettrico vibra, produce una tensione ai suoi capiche puo essere letta attraverso un pin di ingresso analogico della scheda. Il sensoree collegato ai pin GND e A0 (il primo ingresso analogico disponibile). Si colleghera inseguito un LED al pin digitale 13, che si accende se il sensore rileva una vibrazionesufficientemente grande.

Per proteggere il sensore piezoelettrico da tensioni e correnti eccessive, viene inserito

in parallelo un resistore da 1 MΩ.

M. Scarpiniti Una Introduzione ad Arduino 28 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Rilevatore di vibrazione

Lo sketch di Arduino inizia con la definizione di tre costanti che indicano il numerodel pin a cui collegare il LED, il numero del pin analogico a cui collegare il sensoree la soglia per determinare se c’e stata una vibrazione consistente. Si dichiaranopoi una variabile per leggere il valore del sensore e una variabile che indica lo statodel LED, inizializzata a LOW.

const int ledPin = 13; // LED colleg. al pin digitale 13

const int knockSensor = A0; // piezo colleg. al pin analogico 0

const int threshold = 100; // soglia

int sensorReading = 0; // valore del piezo

int ledState = LOW;

La funzione setup() imposta semplicemente il pin a cui e collegato il LED (ilnumero 13) come un pin di uscita e inizializza una comunicazione seriale a 9600baud.

void setup()

pinMode(ledPin , OUTPUT); // pin del LED impostato OUTPUT

Serial.begin (9600); //si utilizza la porta seriale

M. Scarpiniti Una Introduzione ad Arduino 29 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Rilevatore di vibrazione

La funzione loop() legge inizialmente il valore di tensione generato dal sensore,attraverso la funzione analogRead() che restituisce un intero compreso tra 0 e1023. Se questo valore supera il valore di soglia threshold, lo stato del LED vienecambiato in HIGH e quindi acceso tramite digitalWrite(), mentre nel monitorseriale viene stampato un messaggio. Si attenono poi 100 millisecondi per evitareproblemi di sincronizzazione e il programma termina.

void loop()

sensorReading = analogRead(knockSensor); // legge il valore

del sensore

if (sensorReading >= threshold) // se supera la soglia

ledState = !ledState; // stato del LED e HIGH

digitalWrite(ledPin , ledState); // accende il LED

Serial.println("Knock!"); // stampa "Knock!" sul monitor

seriale

delay (100); // aspetta 100 millisecondi

M. Scarpiniti Una Introduzione ad Arduino 30 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Utilizzo di un accelerometro

Nel prossimo esempio si vuole leggere i dati relativi alle accelerazioni nelle tredirezioni x, y e z attraverso un accelerometro della famiglia ADXL3xx (prodottiprincipalmente da SparkFun e Adafruit), che e un sensore analogico.Lo schema di collegamento e rappresentato nelle seguenti figure, anche se e possibileavere configurazioni differenti per sensori di diversi produttori (attenzione ai valoridi alimentazione).

L’accelerometro della famiglia ADXL3xx e collegato a tutti i pin analogici A0-A5,secondo il seguente schema

ADXL3xx Pin Self-Test z-axis y-axis x-axis Ground VDDArduino Pin Analogico 0 1 2 3 4 5

M. Scarpiniti Una Introduzione ad Arduino 31 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Utilizzo di un accelerometro

Si dichiarano tutti e 5 i pin da utilizzare. Poiche si vuole utilizzare i pin A4 e A5come alimentazione, li si dichiarera come pin digitali (rispettivamente il 18 e 19).

const int groundpin = 18; // pin A4 -- Ground

const int powerpin = 19; // pin A5 -- VDD

const int xpin = A3; // x-axis

const int ypin = A2; // y-axis

const int zpin = A1; // z-axis

A questo punto, si inizializza una comunicazione seriale a 9600 baud, si impostanoi pin 18 e 19 come uscite, settandole a livello LOW (Ground) e HIGH (VDD).

void setup()

Serial.begin (9600);

// Non necessario se si utilizzano i pin 5V e Gnd:

pinMode(groundpin , OUTPUT);

pinMode(powerpin , OUTPUT);

digitalWrite(groundpin , LOW);

digitalWrite(powerpin , HIGH);

Se per l’alimentazione si utilizzano i pin 5V e Gnd e possibile commentare le righe

precedenti e la dichiarazione dei pin 18 e 19.M. Scarpiniti Una Introduzione ad Arduino 32 / 69

IntroduzioneLa Testa Robotica

IntroduzioneL’IDEGli esempi

Utilizzo di un accelerometro

Nella funzione loop() si legge semplicemente i valori dei tre pin A1, A2 e A3 at-traverso al funzione analogRead(), stampando il valore sul monitor seriale insiemead una tablatura per incolonnare i risultati. Si attendono quindi 100 millisecondie si ricomincia a leggere e stampare i nuovi valori finche non si spegne la scheda.

void loop()

Serial.print(analogRead(xpin)); // Stampa del valore lungo x

Serial.print("\t"); // Stampa di una tablatura

Serial.print(analogRead(ypin)); // Stampa del valore lungo y

Serial.print("\t");

Serial.print(analogRead(zpin)); // Stampa del valore lungo z

Serial.println ();

delay (100); // Si attendono 100 millisecondi prima della

prossima lettura

Si osservi che non si e utilizzato il pin di self-test.

M. Scarpiniti Una Introduzione ad Arduino 33 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La Testa Robotica

La Testa Robotica

M. Scarpiniti Una Introduzione ad Arduino 34 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La testa robotica: Bender

L’applicazione principale consiste nel costruire una testa robotica in gradodi seguire una sorgente sonora in movimento all’interno di un ambiente.

La testa robotica, denominata Ben-der, ha dimensione di 21 x 16 x 13cm ed e equipaggiata con due micro-foni, che fungono da orecchi, e duewebcam, che fungono da occhi. E’poi presente un algoritmo di localizza-zione binaurale, basato sulle registra-zioni dei due microfoni e un algorit-mo di face detection, basato una solawebcam, che viene utilizzato per cor-reggere gli errori dovuti al riverberodell’ambiente.

M. Scarpiniti Una Introduzione ad Arduino 35 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La testa robotica: Bender

Piu in dettaglio, i microfoni utilizzati sono due AKG-c562cm, che sonomicrofoni a condensatore con eccellenti caratteristiche di radiazione, comemesso in evidenza dalla figura seguente a sinistra.

Le webcam utilizzate sono due comuni webcam a bassa risoluzione 640 x480.

I movimenti sono controllati da tre servomotori, precisamente un servomo-tore digitale (pan del collo), un micro-servomotore digitale (tilt degli occhi)e un micro-servomotore analogico (pan degli occhi).

M. Scarpiniti Una Introduzione ad Arduino 36 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La testa robotica: Bender

I tre servomotori devono essere alimentati con una alimentazione in conti-nua di 5 V. Poiche tali attuatori non assorbono troppa corrente, e possibilealimentarli direttamente tramite la scheda Arduino, utilizzano i pin di ali-mentazione 5V e GND. Tali pin sono collegati alle linee di alimentazionedella breadboard ai cui verranno successivamente collegate le alimentazio-ni dei servomotori. Nel caso sia richiesta molta corrente da parte di unattuatore, sara necessario utilizzare un alimentatore esterno.

I servomotori possiedono un terzo cavo (dicolore giallo) per il loro controllo. Siutilizzeranno a tal proposito i pin:

3: per il pan del collo;

5: per il pan degli occhi;

6: per il tilt degli occhi.

M. Scarpiniti Una Introduzione ad Arduino 37 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La libreria Servo

Per utilizzare i servomotori , e necessario utilizzare alcune funzioni contenute nellalibreria Servo, gia presente nella distribuzione installata dell’IDE di Arduino.

Per creare un oggetto di tale classe, si dichiara una variabile di tipo Servo:

Servo myservo;

Le sei funzioni della libreria sono elencate di seguito:

attach(pin): collega la variabile myservo al pin indicato;

read(): legge l’angolo corrente del servomotore;

write(angle): sposta il servomotore all’angolo indicato. Valore compresotra 0 e 180, dove 90 indica la posizione centrale di riposo;

writeMicroseconds(us): invia al servomotore un valore in microsecondi conun conseguente spostamento del dispositivo. Di solito e un valore compresotra 1000 e 2000 µs, con valore centrale pari a 1500 µs, ma puo dipendere dalparticolare servomotore;

attached(): verifica se la variabile myservo e collegata a qualche pin;

detach(): scollega la variabile myservo dal pin in cui era collegata.M. Scarpiniti Una Introduzione ad Arduino 38 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Lo sketch in Arduino

Lo sketch Arduino per utilizzare la testa robotica e il seguente:

#include <Servo.h>

Servo eyepan;

Servo eyetilt;

Servo neckpan;

Si dichiarano quindi le tre variabili eyepan, eyetilt e neckpan che descrivono itre servomotori.

void setup()

eyepan.attach (5);

eyetilt.attach (6);

neckpan.attach (3);

eyepan.writeMicroseconds (1280);

eyetilt.writeMicroseconds (1680);

neckpan.writeMicroseconds (1475);

Serial.begin (9600);

La funzione setup(), collega le tre variabili ai pin 3, 5 e 6, inizializzando la

posizione dei servomotori. Si apre poi una comunicazione seriale a 9600 baud.M. Scarpiniti Una Introduzione ad Arduino 39 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Lo sketch in Arduino

Viene quindi creato un buffer di sei elementi di tipo carattere:

char buf[]=0,0,0,0,0,0;

Non appena sono disponibili 6 byte, vengono memorizzati nel buffer appena creato.La funzione readBytes() restituisce caratteri. Questi caratteri sono convertiti innumeri interi con la funzione convert() e quindi passati al writeMicroseconds()che fa spostare i servomotori quanto specificato.

void loop()

if(Serial.available () >5)

int num = Serial.readBytes(buf ,6);

if(num ==6)

int *val = convert(buf);

eyepan.writeMicroseconds(val [0]);

eyetilt.writeMicroseconds(val [1]);

neckpan.writeMicroseconds(val [2]);

Si noti che i 6 caratteri, cioe 6 byte, equivalgono a 3 interi (un intero e 2 byte).

M. Scarpiniti Una Introduzione ad Arduino 40 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Lo sketch in Arduino

La conversione dai 6 caratteri e ai 3 interi e effettuata con la seguente funzione.

int* convert(char arr[])

void *vpt = arr;

int *pt = (int*)vpt;

return pt;

In pratica si dichiara un puntatore all’array di caratteri e si esegue un’operazione dicasting (conversione di tipo) verso il tipo intero:

int *pt = (int*)vpt;

Alla fine si restituisce tale puntatore.

M. Scarpiniti Una Introduzione ad Arduino 41 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

Il driver della testa robotica consiste in un file di header, denominato BenderWin.h,che contiene alcune funzioni per la gestione della stessa, come, ad esempio, l’ini-zializzazione, la connessione, la lettura e l’invio della posizione e la limitazionedell’escursione massima consentita dei servomotori. Nelle applicazioni che utilizze-ranno la testa robotica, si dovra includere il file BenderWin.h. Tale file e scrittoper il sistema operativo Windows, ma e disponibile anche la versione BENDER.h perMac OS e Linux.

Le funzioni implementate sono le seguenti:

void Serial(char *portName);

void Serial ();

bool IsConnected ();

int ReadData(char *buffer , unsigned int nbChar);

bool WriteData(uint16_t *buffer , unsigned int nbChar);

void constrain(uint16_t& eyepan , uint16_t& eyetilt , uint16_t&

neckpan);

void sendAngles(uint16_t eyepan , uint16_t eyetilt , uint16_t

neckpan);

double map(double x, double a,double b, double c, double d);

void computeAndSendAngles(double x0,double y0 ,double z0);

M. Scarpiniti Una Introduzione ad Arduino 42 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

Si inizia con l’inclusione di tutte le librerie necessarie e la definizione di una variabileARDUINO WAIT TIME impostata a 2 secondi.

#include <windows.h>

#include <stdlib.h>

#include <stdio.h>

#include <stdint.h>

#include <tchar.h>

#include <string >

#include <unistd.h>

#include <fcntl.h>

#include <math.h>

#define ARDUINO_WAIT_TIME 2000

Si passa quindi alla dichiarazione di alcune variabili utili per la gestione dellacomunicazione con la testa robotica.

HANDLE hSerial; // HANDLE e un tipo di dato trasparente

// usato come PUNTATORE ad una risorsa

bool connected; // Stato della connessione

COMSTAT status; // Informazione sulla connessione

DWORD errors; // Mantiene traccia dell’ultimo errore

M. Scarpiniti Una Introduzione ad Arduino 43 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

La prima funzione Serial(portName), crea una connessione attraverso la portaindicata da portName.

void Serial(char *portName)

connected = false; // Non ancora connessi

hSerial = CreateFile(portName , // Crea una connessione

GENERIC_READ | GENERIC_WRITE , //Tipo di connessione

0, // Condivisioni

NULL , // Non puo generare processi figli

OPEN_EXISTING , // Apre la risorsa solo se esiste

FILE_ATTRIBUTE_NORMAL , // Attributi base

NULL); // Eventuale handle se non esiste la risorsa

La funzione CreateFile(), definita in windows.h, ha il compito di creare la

connessione seriale

M. Scarpiniti Una Introduzione ad Arduino 44 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

A questo punto si verifica la connessione. Se non si e trovata la porta indicata attra-verso la funzione GetLastError(), viene stampato il relativo messaggio di errore,altrimenti c’e stato un errore generico e si stampa semplicemente “ERRORE!!!”.

if(hSerial == INVALID_HANDLE_VALUE) // Verifica la connessione

//Se si e riscontrato un errore

if(GetLastError ()== ERROR_FILE_NOT_FOUND)

printf("ERRORE: la porta %s non e disponibile .\n",

portName);

else

printf("ERRORE !!!");

M. Scarpiniti Una Introduzione ad Arduino 45 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

Altrimenti, se non ci sono stati errori di connessione, si inizializzano i parametridella comunicazione seriale e se c’e effettivamente comunicazione (verificato tramitela funzione GetCommState()) tali parametri vengono impostati.

else

// Se connesso si impostano i parametri

DCB dcbSerialParams = 0;

if (! GetCommState(hSerial , &dcbSerialParams)) // Stato

corrente

printf("Non si sono letti i parametri attuali!");

else

// Parametri per la scheda Arduino

dcbSerialParams.BaudRate=CBR_9600;

dcbSerialParams.ByteSize =8;

dcbSerialParams.StopBits=ONESTOPBIT;

dcbSerialParams.Parity=NOPARITY;

In particolare vengono impostati il rate di trasmissione (BaudRate), quanti bit da

trasmettere per byte (ByteSize), il numero di stop bits (StopBits) e se c’e il

controllo di parita (Parity).

M. Scarpiniti Una Introduzione ad Arduino 46 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

Con la funzione SetCommState() si settano i parametri sulla scheda. Se c’e statoun errore si stampa un messaggio di errore, altrimenti si imposta lo stato dellaconnessione (true) e si attendono due secondi prima di fare altro.

// Verifica dell’applicazione dei parametri

if(! SetCommState(hSerial , &dcbSerialParams))

printf("ATTENZIONE: non sono stati impostati i

parametri della Porta Seriale");

else

connected = true; // Se tutto e andato bene

Sleep(ARDUINO_WAIT_TIME); // Attende 2s prima

di resettare Arduino

M. Scarpiniti Una Introduzione ad Arduino 47 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

La funzione Serial() (senza argomenti) si occupa di disconnettere la scheda, seprecedentemente era connessa.

void Serial ()

if(connected) // Se era connessa

connected = false; // Ora e disconnessa

CloseHandle(hSerial); // L’handle viene chiuso

La funzione CloseHandle(), definita in windows.h, si occupa di chiudere l’handel

relativo ad un certo numero di oggetti, tra cui le connessioni seriali. Accetta come

argomento di ingresso l’handle relativo alla risorsa da chiudere.

M. Scarpiniti Una Introduzione ad Arduino 48 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

La funzione ReadData() legge un numero nbChar di caratteri, salvandoli nel vet-tore buffer. Dopo aver verificato lo stato della comunicazione, se sono arrivatiun certo numero di caratteri maggiori di quelli da leggere, si pone la variabile diappoggio toRead al valore desiderato nbChar.

int ReadData(char *buffer , unsigned int nbChar)

DWORD bytesRead; // Numero di byte letti

unsigned int toRead; // Numero di byte da leggere

ClearCommError(hSerial , &errors , &status); // Stato della

porta seriale

if(status.cbInQue >0) // Se e stato letto qualcosa

if(status.cbInQue >nbChar) // Se sono arrivati

sufficienti dati

toRead = nbChar;

M. Scarpiniti Una Introduzione ad Arduino 49 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

Altrimenti si pone la variabile di appoggio toRead al numero di caratteri corrente-mente letti e li si legge con la funzione ReadFile().

else

toRead = status.cbInQue;

// Cerca di leggere il numero di dati richiesto

if(ReadFile(hSerial , buffer , toRead , &bytesRead , NULL)

&& bytesRead != 0)

return bytesRead;

return -1; // Se non e stato letto nulla

M. Scarpiniti Una Introduzione ad Arduino 50 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

La funzione WriteData() invia alla porta seriale un buffer di dati lungo nbChar.A tal proposito, utilizza la funzione WriteFile() e se c’e stato un errore nellascrittura dei dati, si chiude la comunicazione con la funzione ClearCommError().Ritorna un valore booleano a seconda dell’esito della scrittura dei dati.

bool WriteData(uint16_t *buffer , unsigned int nbChar)

DWORD bytesSend;

// Cerca di scrivere il buffer sulla porta seriale

if(! WriteFile(hSerial , (void *)buffer , nbChar , &bytesSend ,

0))

ClearCommError(hSerial , &errors , &status); // Status

della porta seriale

return false;

else

return true;

M. Scarpiniti Una Introduzione ad Arduino 51 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

La funzione IsConnected() verifica semplicemente lo stato della connessione.

bool IsConnected ()

// Ritorna semplicemente lo stato della connessione

return connected;

La funzione map(), associa al valore x , il seguente valore y :

y =(x − a) (d − c)

b − a+ c .

Tale valore serve a mappare gli angoli di rotazione dei servomotori all’interno di unintervallo massimo di escursione, al fine di evitare danni meccanici.

double map(double x, double a,double b, double c, double d)

return ((x-a)*(d-c)/(b-a))+c;

M. Scarpiniti Una Introduzione ad Arduino 52 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

La funzione constrain() vincola la massima escursione che i servomotori potran-no compiere, in modo da evitare angoli pericolosi che potrebbero danneggiare idispositivi.

void constrain(uint16_t eyepan , uint16_t eyetilt , uint16_t

neckpan)

eyepan=eyepan <950?950:( eyepan >1610?1610: eyepan);

eyetilt=eyetilt <1370?1370:( eyetilt >1970?1970: eyetilt);

neckpan=neckpan <750?750:( neckpan >2200?2200: neckpan);

Tali limiti corrispondono a:

pan dell’occhio: [950−−160] µs ≈ 70;

tilt dell’occhio: [1370−−1970] µs ≈ 70;

pan del collo: [750−−2200] µs ≈ 160.

M. Scarpiniti Una Introduzione ad Arduino 53 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

La funzione sendAngles invia i dati relativi agli angoli dei tre servomotori attraver-so la connessione seriale. Tale funzione, dopo aver vincolato la massima escursionetramite constrain(), scrive i tre angoli (contenuti nell’array data) utilizzandola funzione WriteData() vista precedentemente. Nel caso di errore stampa unmessaggio.

void sendAngles(uint16_t eyepan , uint16_t eyetilt , uint16_t

neckpan)

uint16_t data [3];

data [0]= eyepan;

data [1]= eyetilt;

data [2]= neckpan;

constrain(data[0],data[1],data [2]); // Limita le escursioni

if(IsConnected ()) // Se e connesso mando i dati

WriteData (&data[0], 2);

WriteData (&data[1], 2);

WriteData (&data[2], 2);

else

printf("Il dispositivo NON e connesso .\n");

M. Scarpiniti Una Introduzione ad Arduino 54 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

Infine la funzione computeAndSendAngles() trasforma una coordinata cartesiana[x0, y0, z0], espressa nella terna di riferimento solidale alla testa, negli angoli dapassare ai servomotori per orientare la testa e gli occhi verso il punto in questione,inviando tali dati attraverso la connessione seriale.

void computeAndSendAngles(double x0,double y0 ,double z0)

double x=x0;

double y=y0 -24; // Le webcam sono a 24 cm dalla base

double z=z0 -5.5; // Le webcam distano 5.5 cm dall’asse

double r=sqrt(x*x+z*z); // Uso le coordinate polari

double phi=atan2(y,r); // Angolo del tilt dell’occhio

double max35 = (( double)35/180)*M_PI; // 35 gradi

double max4 = (( double)4/9)*M_PI; // 80 gradi

if(phi >max35) // -35 <= phi <= 35

phi=max35;

else if(phi <-max35)

phi=-max35;

M. Scarpiniti Una Introduzione ad Arduino 55 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

Si controlla che gli angoli non eccedono i limiti impostati (nel caso impostando ilvalore massimo) e si stampa sul prompt il valore dei tre angoli.

double thetaneck=atan2(x,z); // Pan del collo

double thetaeye; // Pan dell’occhio

if(thetaneck >max4)

thetaeye=thetaneck -max4;

thetaneck=max4; // -35 <= thetaeye <= 35

if(thetaeye >max35*M_PI) // -80 <= thetaneck <= 80

thetaeye=max35*M_PI;

else if(thetaneck <-max4)

thetaeye=thetaneck+max4;

thetaneck=-max4;

if(thetaeye <-max35*M_PI)

thetaeye=-max35*M_PI;

else

thetaeye =0;

printf("Angles (eyepan ,tilt ,neckpan): %f %f %f\n\n",

thetaeye ,phi ,thetaneck);

M. Scarpiniti Una Introduzione ad Arduino 56 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il driver per Bender

A questo punto, i tre valori calcolati vengono convertiti nel valore corretto dapassare alla scheda attraverso la funzione map() e trasformati in interi a 16 bit.Infine, la terna appena calcolata viene inviata alla scheda con la precedente funzionesendAngles().

double neckpand=map(thetaneck ,-max4 ,max4 ,750 ,2200);

double eyepand=map(thetaeye ,-max35 ,max35 ,1610 ,950);

double eyetiltd=map(phi ,-max35 ,max35 ,1990 ,1370);

uint16_t neckpan =( uint16_t)(neckpand);

uint16_t eyepan =( uint16_t)(eyepand);

uint16_t eyetilt =( uint16_t)(eyetiltd);

sendAngles(eyepan , eyetilt , neckpan);

M. Scarpiniti Una Introduzione ad Arduino 57 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il funzionamento della testa robotica

La testa robotica funziona con due algoritmi di localizzazione che lavorano con-giuntamente.

1 localizzazione binaurale: utilizza l’audio raccolto dai due microfoni per lo-calizzare la coordinata del parlatore. E’ basata sulle due grandezze seguenti:

ILD (Interaural Level Difference): differenza del livello sonoro tra i duesensori;ITD (Interaural Time Difference): differenza tra i tempi di arrivo del-l’onda sonora ai due sensori.

2 face detection: utilizza una delle due webcam. Utilizza il metodo di Viola-Jones, basato sull’estrazione delle features di Haar.

Purtroppo, negli ambienti indoor reali il riverbero introduce un errore nella localiz-

zazione acustica. A tal proposito, per correggere tale errore (angolare) si utilizza il

face detector: la testa si “aggancia” alla faccia e la segue per qualche istante.

M. Scarpiniti Una Introduzione ad Arduino 58 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La localizzazione binaurale

Il modello della localizzazione binaurale e il seguente:

xl [n] = hl [n] ∗ s[n] + ηl [n],

xr [n] = hr [n] ∗ s[n] + ηr [n],

in cui s[n] e il segnale del parlatore, hl [n] e hr [n] sono le risposte impulsive delcanale sinistro e destro, xl [n] e xr [n] sono i segnali raccolti dal sensore sinistro edestro, e ηl [n], ηr [n] sono due eventuali rumori additivi.

Per il calcolo dell’ILD e ITD, si effettua la Short Time Fourier Transform (STFT)dei segnali xl [n] e xr [n], ottenendo per l’n-esimo frame

X nl (ω, θ, φ) ,

X nr (ω, θ, φ) ,

in cui ω e la frequenza, θ e φ sono gli angoli di elevazione e azimut, rispettivamente.

M. Scarpiniti Una Introduzione ad Arduino 59 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La localizzazione binaurale: ILD

L’Interaural Level Difference o ILD e calcolato, per il generico frame n, nel seguentemodo:

ILDn (ω, θ, φ) = 20 log10

∣∣∣∣X nr (ω, θ, φ)

X nl (ω, θ, φ)

∣∣∣∣ .Esprime dunque, in dB, la differenza dei moduli del segnale ricevuto al sensore de-stro rispetto a quello ricevuto al sensore sinistro. Descrive il fenomeno dell’effettoombra provocato dalla testa. Tale indice diviene ambiguo al di sotto di circa 1.5kHz in quanto l’effetto ombra provocato dalla testa e nullo.

M. Scarpiniti Una Introduzione ad Arduino 60 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La localizzazione binaurale: ITD

L’Interaural Time Difference o ITD e calcolato, per il generico frame n, nel seguentemodo:

ITDn (ω, θ, φ) =1

ω

(∠

X nr (ω, θ, φ)

X nl (ω, θ, φ)

+ 2πp

).

Esprime dunque, la differenza di fase tra il segnale ricevuto al sensore destro e quelloricevuto al sensore sinistro. La variabile p costituisce un fattore di molteplicita dellafase e, purtroppo, non e noto a priori. Tale indice diviene ambiguo al di sopra dicirca 1.5 kHz per via della molteplicita.

M. Scarpiniti Una Introduzione ad Arduino 61 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La localizzazione binaurale: le HRTF di riferimento

La localizzazione avviene per confronto degli indicatori ILD e ITD calcolati conquello relativo a un database di riferimento di HRTF (Head Related TransferFunction). Tali funzioni sono valutate mantenendo fissa l’elevazione θ:

ILDn (ω, φ) = 20 log10

∣∣∣∣HRTF nr (ω, φ)

HRTF nl (ω, φ)

∣∣∣∣ ,ITDn (ω, φ) =

1

ω

(∠

HRTF nr (ω, φ)

HRTF nl (ω, φ)

+ 2πp

).

Esiste un database, il CIPIC, che contiene 45 HRTF registrati su persone reali e un

manichino KEMAR. In particolare, per la localizzazione Bender utilizza il soggetto

21, corrispondente al manichino.

M. Scarpiniti Una Introduzione ad Arduino 62 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La localizzazione binaurale: le HRTF di riferimento

Si effettua la differenza tra i valori di ILD e ITD calcolati dai segnali registratie le HRTF, prendendo i valori minimi θLn(ω) e θTn,p(ω): al minimo corrispondera

l’angolo corrispondente al parlatore. Rimane una ambiguita su θTn,p(ω) dovuta allascelta di p. Tale ambiguita e risolta prendendo il valore di p che rende minimol’ITD, cioe

θTn (ω) = θTn,p(ω)∣∣p=argminpθTn,p(ω)

Infine si effettua la media dei valori θLn(ω) e θTn (ω) su tutti i frame n, ottenendo lestime finali θL(ω) e θT (ω) per ogni frequenza.

not change dramatically across azimuth [3]. Smoothing across azimuth with aconstantQ filter was performed on the ILD lookup set in order to better representthe limits of human interaural level difference perception. More specifically, aGaussian filter was employed, as indicated in the CIPIC database [5].

Comparison between the ILD and ITD lookup sets and the estimated ILDand ITD allows to estimate the azimuth of the sound source. In particular ILDis exploited to find the correct value of the unwrapping factor p and to selectthe azimuth value minimizing the difference between the ITD-only and ILD-only estimates. This p-estimation procedure was repeated for each available timeframe. A time average across frames was performed and the results graphed.The final azimuth estimations selected were those displaying a minimum in thedifference function that was consistent across frequencies.

As an example, fig. 2 shows the results obtained in simulations with thesource placed at different azimuth angles. Joint exploitation of ILD and ITDallows to obtain an azimuth estimate which is correct over the whole frequencyband and for different positions of the source.

ILD

2 4 6 8

ITD

Frequ

ency

[kHz

]

2 4 6 8

Joint

−80 0 80

2 4 6 8

ILD

2 4 6 8

ITD

2 4 6 8

Joint

−80 0 80

2 4 6 8

ILD

2 4 6 8

ITD

2 4 6 8

Joint

Azimuth [degrees]−80 0 80

2 4 6 8

ILD

2 4 6 8

ITD

2 4 6 8

Joint

−80 0 80

2 4 6 8

ILD

2 4 6 8

ITD

2 4 6 8

Joint

−80 0 80

2 4 6 8

Fig. 2. Source azimuth estimate in an anechoic room and Gaussian noise: ILD, ITDand joint ILD-ITD methods. Columns from left to right refer to source azimuth anglesof 0, 20, 45, 60 and 80 respectively. Darkest pixels are lowest in value.

Fig. 3 shows the results obtained in a real environment with a female speaker,speaking from an azimuth angle of 15, in terms of the ILD and ITD estimatesin different ranges of frequencies. Slight reverberation is present. It is clear thatin the presence of reverberation [6], commonly assumed in closed environments,proper prefiltering techniques should be adopted [7] [8] [9]. An example is cepstralprefiltering [10].

Mediando quindi in frequenza, e possibile deter-minare la direzione media θL e θT . Utilizzandocongiuntamente queste due informazioni (media)e dunque possibile ottenere una stima θ delladirezione del parlatore.

M. Scarpiniti Una Introduzione ad Arduino 63 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

La localizzazione binaurale

E’ possibile riassumere la localizzazione binaurale implementata, nei passi riportatinel seguente algoritmo:

1: for n = 1 to Nf do2: Calcolo di ILDn (ω, θ, φ) e ITDn (ω, θ, φ);3: Calcolo dei riferimenti ILDn (ω, φ) e ITDn (ω, φ);4: Stima delle differenze θLn(ω) e θTn,p(ω);

5: Stima del valore ottimale di p e quindi di θTn (ω);6: end for7: Media su tutti i frames, ottenendo θL(ω) e θT (ω);8: Media su tutte le frequenze, ottenendo θL e θT ;9: Stima della direzione di arrivo θ basata sull’utilizzo congiunto di θL e θT .

Nf indica il numero totale di frames utilizzati.

M. Scarpiniti Una Introduzione ad Arduino 64 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il face detector

Il riconoscimento facciale e ottenuto tramite il metodo di Viola-Jones (VJM),implementato in C nella librerie OpenCV. Il processo di rilevazione classifica le im-magini basandosi sui valori di specifiche feature piuttosto che sul valore di intensitadei singoli pixel. I concetti chiave sono quattro:

1 Haar features: ottenute per somme e differenze delle somme dei valori deipixel in zone chiare e scure;

2 integral image, per la rilevazione veloce delle feature: determina la presenzao assenza di centinaia di queste features per tutta l’immagine e con diversescalature;

3 il metodo di Machine Learning AdaBoost: la procedura seleziona vari classi-ficatori deboli e ne fa una combinazione pesata, cosi da ottenere un classifi-catore robusto;

4 un classificatore a cascata per la combinazione efficiente delle moltepli-ci features: combina una serie di classificatori AdaBoost in cascata, catenaparticolarmente efficiente per la classificazione di porzioni di immagini.

M. Scarpiniti Una Introduzione ad Arduino 65 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il face detector: tracking

Una volta estratta la regione video contenente la rivelazione della faccia, e neces-sario manipolare gli angoli di tilt e pan della testa facendo si che la faccia stessavenga fatta posizionare, in vari step, sempre al centro del video in esame.

La realizzazione del controllo e realizzata con un sistema di retroazione ad anellochiuso in cui una coppia di controlli proporzionali e impiegata per correggere ladifferenza di posizione tra il centro della faccia rilevata e il centro del frame video.Uno dei due regolatori correggera la differenza in direzione orizzontale, l’altro indirezione verticale. Tale sistema e rappresentato nella seguente figura.

Head

actuatorsKp

Output

coordinates

Input

coordinates

e t u t

Proportional controller

M. Scarpiniti Una Introduzione ad Arduino 66 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Il software per la localizzazione audio-video

Le funzioni utilizzate per la localizzazione sono contenute nel file recording.cpp,mentre i prototipi delle funzioni che utilizzano l’audio e il video sono contenuti nelfile recording.h:

int camdetect ();

void detectAndDraw(Mat& img , CascadeClassifier& cascade ,

CascadeClassifier& nestedCascade , double scale);

static int recordCallback( );

static int playCallback( );

double STFT(SAMPLE chLeft[],SAMPLE chRight[], int signalLength ,

int hopSize);

Tali funzioni attivano la wecam, identificano le facce (disegnando un rettangolo

in corrispondenza del volto) e registrano l’audio. La localizzazione e effettuata

all’interno della funzione STFT(), che calcola anche la STFT dei segnali registrati.

M. Scarpiniti Una Introduzione ad Arduino 67 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Integrazione audio-videoCAPITOLO 5. LA TESTA ROBOTICA: PARTE AUDIO 97

Figura 5.7: Diagramma di flusso dell’algoritmo di localizzazione

L’algoritmo di face tracking andra a coadiuvarequello basato sull’audio, in modo da perseguireuna stima dell’angolo di arrivo attraverso il mat-ching delle informazioni provenienti dalla catenavideo e da quella audio. Una volta localizzatala provenienza del suono, e mossa la testa diconseguenza, la funzione camdetect() dara luo-go alla localizzazione video. La testa, a partiredall’angolo stimato dal lato audio, affinera la sti-ma inquadrando il volto del soggetto pronuncian-te la parola. La localizzazione video durera qual-che secondo, dopo di che si procedera nuovamenteal controllo della soglia sui frame, per dar luogoeventualmente a una nuova localizzazione audio.L’intero procedimento e illustrato nel diagrammaa lato.

M. Scarpiniti Una Introduzione ad Arduino 68 / 69

IntroduzioneLa Testa Robotica

L’hardwareIl softwareIl funzionamento

Bibliografia

Arduino Tutorials.https://www.arduino.cc/en/Tutorial/HomePage.

M. Margolis.

Arduino - Progetti e soluzioni.O’Reilly, 2013.

M. Banzi e M. Shiloh.

Arduino – La guida ufficiale.Tecniche Nuove, 2015.

M. Schmidt.

Il manuale di Arduino.APOGEO, 2011.

S. Majocchi.

Arduino UNO. Programmazione avanzata e librerie di sistema.Vispa, 2012.

D. J. Russell.

Introduction to Embedded Systems: Using ANSI C and the Arduino Development Environment.Morgan and Claypool Publishers, 2010.

M. Scarpiniti Una Introduzione ad Arduino 69 / 69