MG Arduino 02
MG Arduino 02
di Arduino
Il programma che viene usato per scrivere i programmi per Arduino si chiama arduino.exe
ed è scaricabile dal sito http://arduino.cc/en/Main/Software. Sito ufficiale della piattaforma
Arduino.
Per aprire il programma basta fare doppio click sull'icona oppure selezionare apri dal
menù a tendina che si visualizza premendo il tasto destro sull'icona del programma.
Il programma si presenta con un'interfaccia grafica senza nome chiamata sketch che
significa progetto come evidenziato dalla Figura1 che segue
1
Struttura di un programma
void setup( )
Esempio
int pulsante=3;
void setup( ){
Serial.begin(9600);
pinMode(pulsante,OUTPUT);
}
2
Figura 2: Serial Monitor
void loop( )
Dopo la creazione della funzione setup(), che inizializza e imposta i valori iniziali, la
funzione loop() fa proprio quanto suggerisce il proprio nome eseguendo ciclicamente il
programma definito al suo interno.
Permette l'esecuzione del programma, interagisce con la scheda Arduino.
Sintassi
void loop( ){
// istruzioni da ripetere in modo ricorsivo;
}
Esempio
void loop( ){
digitalWrite(3, HIGH); // metti il pin 3 allo stato alto
delay(1000); // mantieni questo stato per 1 secondo
digitalWrite(3, LOW); // metti il pin 3 allo stato basso
delay(1000); // mantieni questo stato per un secondo
}
3
Sintassi
; punto e virgola
Il punto e virgola ( ; ) deve essere inserito alla fine di un'istruzione e per separare gli
elementi del programma.
Il ; è anche utilizzato per separare gli elementi di un ciclo for.
Dimenticare ; al termine di un'istruzione darà errore di compilazione. L'errore nella
digitazione del testo è normale, trovare un errore è complicato. Quando si rileva un errore
nella compilazione prima tra tutte le cose conviene verificare se c'è stata l'omissione del ;
4
Le parentesi graffe { }
Commenti
I commenti rappresentano del testo che viene ignorato dal programma e vengono utilizzati
per descrivere il codice o per aiutare a comprendere parti di programma.
5
Blocco di commenti /* …. */
Un blocco di commenti inizia con /* e termina con i simboli */
Sintassi
/*
Tra questi simboli posso commentare il codice che sviluppo senza che in fase di
compilazione venga occupata memoria. Questi commenti vengono ignorati.
*/
Linea di commento //
Quando si vuole commentare solo una linea si utilizzano le doppie //
// linea di commento
Le linee singole di commento vengono spesso usate dopo un'istruzione per fornire più
informazioni relativamente a quanto serva l'istruzione per poterlo ricordare anche in
seguito.
6
Funzioni
Una funzione è un blocco di codice che viene eseguito nel momento in cui essa viene
chiamata.
Dichiarazione di funzione
Esempio di una funzione che effettua la somma tra due numeri interi num1 e num2
int x=somma(4,6); // esempio di chiamata di una funzione denominata somma
int somma(int num1, int num2){
int numeroSomma=num1+num2;
return numeroSomma;
}
dove:
int specifica il tipo di funzione;
somma è il nome della funzione
num1 e num2 sono i parametri che vengono passati alla funzione stessa
numeroSomma è il valore di tipo int che la funzione restituisce in caso di chiamata.
Se la funzione non deve restituire alcun valore sarà dichiarata di tipo void come accade
per le funzioni setup() e loop().
La presenza dei parametri non è obbligatoria: la chiamata ad una funzione si può fare
anche senza parametri.
7
Le costanti
Le costanti sono variabili predefinite nel linguaggio per Arduino e vengono utilizzate per
rendere il programma più semplice da leggere.
Le costanti sono classificate in diversi gruppi.
Costanti booleane
8
HIGH
Ha diversi significati a seconda se il pin è settato come INPUT o OUTPUT
Quando un pin è settato in modalità INPUT tramite pinMode e legge con il comando
digitalRead un valore superiore a 3V il microcontrollore restituirà un valore HIGH.
Un pin può essere settato come INPUT con il pinMode, in seguito reso alto HIGH con
digitalWrite, questo imposterà la resistenza interna di pullup a 20K che porterà il pin allo
stato HIGH a meno che esso non venga costretto a LOW da qualche circuito esterno.
Quando un pin è impostato come OUTPUT con il comando pinMode e viene settato a
valore HIGH con digitalWrite, il pin si troverà al valore di 5V. Esso diventa una sorgente di
corrente sia verso un carico tipo LED con resistori verso massa che verso un pin,
impostato come OUTPUT e settato basso.
LOW
Quando un pin è impostato come INPUT tramite pinMode() il microcontrollore legge valore
LOW, tramite readAnalog, se la tensione è inferiore ai 2V.
Quando un pin invece è impostato in modalità OUTPUT con pinMode() e impostato a
valore LOW con digitalWrite, il pin è posto a 0V. In questa modalità il pin assorbe corrente
ad es. da un circuito esterno o da un pin impostato come OUTPUT ma HIGH.
Le costanti intere sono numeri usati direttamente in uno sketch come ad es. 123. Per
default questi numeri son trattati come di tipo int ma possono essere cambiati con i
modificatori U e L ( vedi seguito).Normalmente le costanti di tipo integer sono considerate
di base 10, ma speciali formattatori possono modificarne la notazione.
Base esempio formattatore commento
myInt(B11001100
B11001100*256)+B10101010
B11001100 dove B11001100 è la parte alta del numero
la moltiplicazione per 256 significa traslare tutto di 8 posti.
9
Formattatori U e L
Per default una costante intera è trattata come un numero di tipo int con l'attenta
limitazione nei valori. Per specificare una costante di tipo Integer con un altro tipo di dato,
si prosegue in questo modo:
33U o 33u forza la costante in un formato di tipo int senza segno (unsigned)
100000l o 100000L forza la costante nel formato di tipo long
32767UL forza il numero nel formato di tipo long senza segno
Anche questi costanti vengono determinate nella fase di compile time e non di run.
Le costanti di tipo floating point possono essere espresse in diverse modalità scientifiche
10.0 10
2.34E5 2.34*10^5 234000
67e-12 67.0*10^-12 .000000000067
10
Le variabili
Una variabile può essere dichiarata e inizializzata prima del setup(), localmente all'interno
di una funzione, e definita anche in un blocco di istruzioni come in un ciclo in questo caso
la variabile si chiama “variabile locale”.
Variabile globale
Una variabile globale è una variabile che può essere vista e usata da ogni istruzione e
funzione del programma; nell'ambiente di sviluppo di Arduino, ogni variabile dichiarata al di
fuori di una funzione (come ad es. setup(),loop(),..) è una variabile globale.
11
Variabile locale
Le variabili locali sono visibili solo dalle funzioni entro cui sono dichiarate o all'interno di
funzioni o cicli dove vengono definite.
È possibile avere due o più variabili locali che hanno lo stesso nome ma in differenti parti
del programma, che contengono valori differenti. Bisogna essere sicuri che solo una
funzione abbia accesso alla variabile in modo da ridurre la probabilità di errore della
scrittura del codice.
Un programma può diventare molto grande e complesso e le variabili locali sono di solito
usate per assicurare che solo una funzione ha accesso alle proprie variabili. Questo
previene errori di programmazione in quanto una funzione potrebbe inavvertitamente
modificare una variabile utilizzata da un altro programma.
A volte è anche comodo dichiarare e inizializzare una variabile all'interno di un ciclo.
Questo crea una variabile a cui si può accedere solo dall'interno delle parentesi che
delimitano il ciclo.
Il seguente esempio evidenzia come dichiarare differenti tipi di variabili e evidenzia la
diversa visibilità delle stesse.
void loop( ){
int k=0;
for(int i=0;i<100;i++){
k++; // questa variabile è esterna al ciclo for ma è visibile solo nel
// ciclo loop. Per cui ha un diverso livello di località rispetto
// alla variabile successiva f
float f=analogRead(2); // f è una variabile locale che non è disponibile
// all'esterno del ciclo
}
Static
La parola chiave Static viene utilizzata per creare una variabile che è visibile solo da una
funzione.
Diversamente dalla variabile locale che viene creata e distrutta ogni volta che una
funzione la chiama, la variabile Static persiste all'interno della funzione che la chiama,
mantenendo il proprio dato all'interno della funzione chiamante.
Le variabili dichiarate come statiche saranno definite ed inizializzate solo la prima volta
che una funzione è chiamata.
12
Esempio
/* Creazione di numeri casuali spostandosi in sopra e in sotto tra due limiti
Il massimo scostamento in un loop è regolato dal parametro step
La variabile statica varia in più o in meno di una quantità random
questa tecnica è chiamata “rumore rosa”.
-20 e 20 sono i limiti inferiore e superiore che delimitano il range di variabilità dei
numeri casuali */
#define limiteInferiore -20
#define limiteSuperiore 20
int step;
int valoreRandom;
int totale;
void setup( ){
Serial.begin(9600);
}
// l'if seguente verifica che non superi il limite superiore e il limite inferiore
if ( casuale < limiteInferiore){
casuale = casuale + ( limiteInferiore - casuale);
// riflette il numero in senso positivo
}
13
}
return casuale;
}
volatile
Esempio
// accendi/spegni LED quando lo stato del pin si modifica
int pin = 13; // scelta del pin dove mettere il diodo
volatile int stato = LOW; //stato è una variabile booleana
void setup( ) {
pinMode(pin, OUTPUT);
attachInterrupt(0, blink, CHANGE); //vedi gestione Interrupt
}
void loop( ){
digitalWrite(pin, stato); //stato può essere o LOW oppure HIGH
}
void blink( ){
stato = !stato; //cambia stato alla variabile stato
}
14
const
#define or const
Si può utilizzare const o #define per creare una costante numerica o di tipo String.
Per gli array occorre che venga utilizzato il termine const.
In genere const è preferito rispetto a #define per la definizione delle costanti.
15
Tipo di dati
void
Esempio
I metodi setup( ) e void( ) non restituiscono alcuna informazione non c'è un'istruzione
di return come in altre funzioni
void setup( ){
// …
}
void loop( ) {
// ...
}
boolean
Ogni variabile booleana occupa un byte di memoria (8bit) e può assumere solo due valori:
livello logico true o livello logico false.
false è più semplice da utilizzare in quanto rappresenta lo zero (0) ;
true invece rappresenta una condizione di non-zero (non solo significato di “uno”) per cui
anche -1, 2,-200 (valori diversi da 0) sono definite tutte condizioni di vero in senso
booleano.
Importante: true e false sono scritte in minuscolo.
Esempio
int LEDpin = 5; // LED su pin 5
int switchPin = 13; // switch su pin 13, altro estremo collegato a massa.
boolean running = false;
void setup( ) {
pinMode(LEDpin, OUTPUT);
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH); // attiva il resistore di pull-up
}
16
void loop( ){
if (digitalRead(switchPin) == LOW) { // pressione del tasto – il resistore di
// pull-up mantiene il pin a valore alto
delay(100); // delay per debounce switch
running = !running; // alterna il valore della variabile running
digitalWrite(LEDpin, running); // segnala con LED
}
}
char
unsigned char
Per un tipo senza segno si utilizza “unsigned char” che codifica invece numeri da 0 a 255
(da 0 a 28). Questo per poter svolgere calcoli aritmetici con questi simboli in caso di
necessità di risparmiare spazio di memoria.
Esempio
byte
questo tipo può sostituire il tipo char unsigned in quanto memorizza un numero senza
segno a 8 bit, cioè da 0 a 255 (da 0 a 28) .
Esempio
byte b = B10010; // "B" è il formattatore binario (B10010 = 18 decimale)
int
17
Se il bit più significativo è 1 il numero sarà negativo e i rimanenti 15 numeri rappresentano
il complemento a due del numero; se il bit più significativo è 0 il numero sarà positivo e i
rimanenti 15 bit rappresenteranno il complemento a due del numero.
Sintassi
int var = val ;
var è il nome scelto per la variabile
val è il valore che si vuole assegnare
Esempio
int caso = - 3065; // dove caso è il nome che si vuole utilizzare nel corso
// del programma, -3065 è il numero assegnato.
x = 32767;
x = x+1; // x contiene -32768 ( roll over positivo )
unsigned int
Tipo che memorizza un intero senza segno memorizzato sempre in due byte.
I valori coprono un range che va da 0 a 216 – 1 = 65535.
Sintassi
unsigned int var = val ;
var è il nome scelto per la variabile
val è il valore numerico che si assegna alla variabile.
Esempio
unsigned int y = 2456 ; // y è il nome della variabile, 2456 è il valore che gli
// viene assegnato.
int x ;
x=0;
x = x - 1; // x=65535 invece di -1
18
x=65535;
x=x+1; // x=0 in quanto successivo al massimo
word
Un tipo word memorizza un numero senza segno a 16 bit, da 0 a 65535 (da 0 a 216 -1 )
allo stesso modo di un unsigned int.
Sintassi
word var = val ;
var è il nome scelto per la variabile
val è il valore numerico che si assegna alla variabile.
Esempio
word lunghezza=44663;
// lunghezza è il nome della variabile mentre 44663 è il valore assegnato
long
Sintassi
long var=val;
var è il nome scelto per la variabile
val è il valore numerico che si assegna alla variabile.
Esempio
long altezza=446657685;
// altezza è il nome della variabile, 446657685 è il numero
unsigned long
19
unsigned long profondo = 888777555;
//numero che viene memorizzato nella variabile profondo
Sintassi
float var=val;
var è il nome scelto per la variabile
val è il valore numerico che si assegna alla variabile.
Esempio
int x,y ;
float z ;
x = 1;
y = x/2; //y contiene 0 che è la parte intera di 0.5
z=float(x)/2.0; //z contiene .5 (avendo utilizzato 2.0 e non 2)
double
20
1. usando il tipo String, che fa parte del codice di Arduino a partire dalla versione
0019,
2. costruendo una stringa con un array di caratteri e null per terminarla.
L'oggetto String permette più funzionalità a scapito però di maggiore occupazione di
memoria.
Array di char
Un array è un insieme di elementi tutti dello stesso tipo. Nel caso specifico, in un oggetto
di tipo String, gli elementi dello stesso tipo sono char.
Array di stringhe
E' spesso conveniente , quando si lavora con una grande quantità di testo, lavorare con
un array di stringhe.
21
Dato che le stringhe sono a loro volta degli array , l'array di stringhe è un esempio di array
a due dimensioni.
Nel codice seguente , l' * (asterisco) dopo il tipo char (char*) indica che questo è un array
di puntatori. I puntatori sono una trovata di C che non è necessario capire qui per capire
come funzioni il codice.
char* mieStringhe[ ]= { “Stringa 1”, “Stringa 2”, “Stringa 3”, “Stringa 4”, “Stringa 5”,
“Stringa 6” };
Esempio
void setup( ) {
Serial.begin(9600); // impostazione velocità di collegamento con il pc
}
void loop( ) {
for ( int i=0; i<6; i++) {
Serial.println( mieStringhe[i] ); // stampa su monitor pc le stringhe
// presenti nell'array chiamato
// mieStringhe[ ]
delay(500);
}
}
22
length( )
replace?( )
setCharAt( )
startsWith( )
substring( )
toCharArray( )
toLowerCase( )
toUpperCase( )
trim( )
operatori
[ ] (accesso agli elementi')
+ (concatenamento?)
== (confronto?)
Array
Un array è una collezione di variabili che sono accessibili tramite un indice numerico.
Creazione e/o dichiarazione di un array
Tutti i metodi seguenti sono validi modi per creare un array.
int mieiNumeri[6]; // dichiarazione di un array senza inizializzazione
int mieiPin[ ]= {2,4,8,3,6}; // dichiarazione di un array senza definirne la dimensione.
// Il compilatore conta gli elementi e crea un array avente
// dimensione adatta.
int valoriSensori[6]={2,4,-8,3,2,5}; // dichiarazione e inizializzazione di un array
char messaggio[5]= “ciao”; // Dichiarazione ed inizializzaizone di un array di char.
// Occorre un carattere in più per definire il valore null che
// determina la fine dell'array di caratteri.
Accesso agli elementi di un array
Gli indici degli array partono dallo 0, cioè il primo elemento occupa la posizione 0.
In un array avente 10 elementi, l'indice 9 rappresenta l'ultimo della lista.
Sintassi per leggere un valore in un array
tipo var = mioArray[ n] ;
var indica la variabile di lettura o di accesso;
mioArray[ ] è il nome dell'array di cui si vuole accedere agli elementi
n indica la posizione occupata.
23
Esempio
int numeri[10]={3,4,6,8,5,12,15,7,9,13}; // definizione e inizializzazione
// dell'array chiamato numeri[ ]
// avente 10 elementi
int x ; // inizializzazione della variabile x di tipo int
x = numeri[0]; // x=3
x = numeri[9]; // x=13
x = numeri[10]; // richiesta non valida. Contiene un numero casuale (altro
// indirizzo di memoria)
Attenzione:
• accedere con un indice oltre quello richiesto dalla sezione dell'array comporta
andare a leggere memoria utilizzata per altri scopi.
• scrivere oltre può spesso portare al crash o al malfunzionamento del programma.
• questo tipo di errore potrebbe risultare di difficile individuazione in quanto
diversamente dal Basic o da Java, il compilatore C non verifica se l'accesso
all'array è nei limiti consentiti dichiarati.
24
Conversioni
char( )
byte( )
int( )
25
word( )
Converte un valore in un dato di tipo word o crea un dato di tipo word a partire da due byte
Sintassi
word(x)
word(h,l) // crea un tipo word (16 bit) definendo i due byte che lo compongono
Il parametro x rappresenta un valore di qualsiasi tipo;
Il parametro h rappresenta il byte più significativo ( a sinistra, alto) , il parametro l invece
rappresenta il byte meno significativo ( il byte più a destra, basso).
La funzione restituisce un dato di tipo word.
Esempio
int x = 126 ; // 126 è il valore che viene memorizzato in x
word y;
y=word(x); // y è la conversione in word corrispondente a 126
int h = 126 ; // 126 è il valore che viene memorizzato in x
int l=34;
word y;
y=word(h,l); // y è la conversione in word corrispondente a 126*28+34
long( )
float( )
26
Utilità
sizeof( )
L'operatore sizeof restituisce il numero di byte di cui è composta una variabile di qualsiasi
tipo, oppure il numero di byte occupato da un array.
Sintassi
sizeof ( variabile )
Il parametro variabile è qualsiasi tipo di variabile (int, float, byte...) o un array .
L'operatore sizeof è spesso usato per trattare con gli array (come le stringhe di caratteri)
dove è conveniente essere abili a cambiare la sezione dell'array senza interrompere altri
parti del programma .
Esempio: questo programma stampa una stringa di testo un carattere a volta (un
carattere di tipo char è rappresentato da un byte, meglio tenerlo a mente), prova a
cambiare la frase del testo.
char miaStringa[] = "Questo e' un test"; // attenzione agli accenti.... non è detto
che abbiano // corrispondenza in ASCII
void setup( ){
Serial.begin(9600);
}
27
Istruzioni condizionali
Istruzione if
if(x>120){
digitalWrite(LED1,HIGH); // accendi LED1
digitalWrite(LED2,LOW); // spegni LED2
delay(2000); // mantieni queste condizioni per 2 secondi
digitalWrite(LED1,LOW); // spegni LED1
digitalWrite(LED2,HIGH); // accendi LED2
delay(2000); // mantieni queste condizioni per 2 secondi
}
if (x>120) digitalWrite(LED,HIGH);
if (x>120)
digitalWrite(LED,HIGH);
if (x>120) { digitalWrite(LED,HIGH); }
if (x>120){
digitalWrite(LED,HIGH);
}
x == y // x uguale a y
x != y // x diverso da y
x<y // x minore di y
28
x>y // x maggiore di y
x<=y // x minore o uguale a y
x>=y // x maggiore o uguale a y
Attenzione:
scrivere x=10 significa assegnare alla x il valore 10, scrivere x==10 significa verificare se x
è uguale a 10.
Se per errore si scrive if( x=10 ) la condizione risultante sarà sempre vera in quanto ad x
viene assegnato il valore 10 che essendo un valore non nullo restituisce sempre vero.
Condizioni if/else
if(pin5<250){
digitalWrite(LED1,HIGH); // accendi LED1
digitalWrite(LED2,HIGH); // accendi LED2
}
else if(pin5>=700){
digitalWrite(LED1,LOW); // spegni LED1
digitalWrite(LED2,LOW); // spegni LED2
}
else // (if(x>=250 && x<700) valori di x compresi tra 250 e 700
{
digitalWrite(LED1,HIGH); // accendi LED1
digitalWrite(LED2,HIGH); // accendi LED2
}
29
Istruzioni switch … case
Spesso in un programma c'è necessità di confrontare il valore di una variabile con una
serie di valori fino a trovare quello corrispondente. Disponendo solo della struttura if il
codice potrebbe diventare contorto.
Nel linguaggio di programmazione per Arduino esiste un meccanismo che permette di
raggruppare confronti ed azioni in una sola istruzione migliorandone la leggibilità.
Questo meccanismo è chiamato switch/case.
switch/case controlla il flusso del programma permettendo di specificare codice differente
che dovrebbe essere eseguito a seconda delle condizioni.
In particolare, switch confronta il valore della variabile al valore specificato dalla clausola
case.
Sintassi:
switch(var){
case label1:
//istruzioni
break;
case label2:
//istruzioni
break;
default:
//istruzioni
}
dove var è una variabile che va a confrontarsi con i diversi casi
e label sono i valori di confronto con var
Esempio: pin5 è la variabile di confronto
switch(pin5){
case 250: //se pin5 è uguale come valore a 250 accendi tutti e due i led
digitalWrite(LED1,HIGH); //accendi LED1
digitalWrite(LED2,HIGH); //accendi LED2
break; //permette di uscire dalla ricerca del case
case 500:
digitalWrite(LED1,LOW); //spegni LED1
digitalWrite(LED2,LOW); //spegni LED2
break;
default : break;
}
30
Quando pin5 è uguale al valore definito dalla clausola case si esegue il blocco di istruzioni
che seguono il case, se nessuno dei valori coincide con il valore pin5 si esegue l'istruzione
che segue i case cioè default (che è opzionale). La condizione di default è facoltativa: se
manca e nessun valore coincide con la variabile l'esecuzione termina senza alcun effetto.
A differenza dell' if non è necessario utilizzare un blocco di istruzioni per far eseguire un
gruppo di istruzioni in sequenza.
La parola break permette la fuoriuscita dal ciclo e viene tipicamente utilizzata alla fine di
ogni clausola case.
Se mancasse l'istruzione break, anche dopo aver trovato la condizione giusta, verrebbero
eseguiti comunque i confronti successivi fino alla prima istruzione di break oppure fino alla
fine del ciclo. In alcuni casi questa procedura è corretta, in genere si includono le istruzioni
break per selezionare una sola possibilità.
Praticamente il break interrompe l'esecuzione di un ciclo e l'esecuzione del programma
riprende dal codice che segue la successiva parentesi chiusa graffa }.
L'omissione dell'istruzione break è utile quando la stessa istruzione deve essere eseguita
per più valori distinti. In questo caso le clausole per tali valori sono poste di seguito, senza
istruzioni, e switch esegue la prima istruzione che trova
Sintassi
switch(var){
case label1:
case label2:
case label3:
//istruzioni
break;
default:
//istruzioni
}
dove var è una variabile che va a confrontarsi con i diversi casi e label sono i valori di
confronto con var
Nell'esempio seguente verrà stampato x è un numero pari se x è 2, 4, 6, 8 altrimenti
stamperà x è dispari.
int x
switch(x){
case 2:
case 4:
case 6:
case 8:
Serial.println(“x è un numero pari”);
break;
default: Serial.println(“x è dispari”);
}//switch
31
Istruzione for / ciclo for
Il ciclo for ripete un'istruzione o un blocco di istruzioni per un numero prefissato di volte.
Il ciclo for viene utilizzato per una iterare (ripetere) un blocco di istruzioni per un numero
prefissato di volte e utilizza un contatore per incrementare e terminare un ciclo. Viene
spesso utilizzato per indicizzare gli elementi di un array.
Sintassi
for (inizializzazione ; condizione ; incremento){
istruzioni;
}
Esempio
for(int i=0; i<10;i++){
int pin = i ;
digitalWrite(pin,HIGH); // mette i pin che vanno da 0 a 9 a livello alto
// dopo una pausa di 500ms
delay(500);
}
void loop( ){
for(int i=0; i<255;i++){
analogWrite(PWMPin,i);
delay(150);
}//for
}
32
Ciclo while
Il ciclo while esegue ripetutamente un'istruzione o un blocco per tutto il tempo in cui una
data condizione è vera.
Sintassi
while(condizione) {
corpo di istruzioni;
}
Ciclo do/while
Nel ciclo while la condizione viene verificata prima dell'esecuzione del corpo di istruzioni
(questo significa che se la condizione è falsa il corpo non viene eseguito), nel ciclo do...
while invece la condizione viene verificata sempre dopo avere eseguito il corpo di
istruzioni, che viene eseguito sempre almeno una volta.
Sintassi
do {
corpo di istruzioni;
} while(condizione);
Il corpo consiste nelle istruzioni da eseguire durante la ripetizione mentre la condizione è
un'espressione booleana che se vale true il corpo viene eseguito se vale false si esce dal
ciclo.
Nota bene: il corpo di istruzioni viene eseguito almeno una volta.
Esempio di lettura da un sensore, utilizzando un ciclo do/while fino a quando questo
non supera un certo valore
do{
delay(50);
x=readSensor( ); //metodo che legge l'uscita da un sensore
} while(x<100);
33
il sensore viene comunque letto una volta anche se la sua uscita è superiore a 100.
break
break è un'istruzione che viene utilizzata con lo scopo di uscire da un ciclo, do, while
oppure for bypassando le condizioni normali che regolano l'esecuzione del ciclo.
È usato anche per uscire da un'istruzione switch.
Esempio
for ( x=0; x < 255 ; x++ ){
digitalWrite(PWMpin, x );
sens = analogRead ( sensorPin ) ;
if (sens < soglia){
x=0;
break ;
}
}
continue
return
34
Esempio in cui return restituisce un intero, in questo caso 0.
int testSensore( ){
if(analogRead(0)>400){
return 1;
}else{
return 0;
}
}
goto
L'istruzione goto consente di effettuare salti incondizionati da un punto all'altro del codice.
Permette quindi di trasferire il flusso dati in un punto del programma definito da una label
( con label si indica una semplice parola ).
Un'attenta scrittura del codice può evitare di ricorrere a istruzioni goto, anche se è a volte
necessario introdurre variabili aggiuntive. L'assenza di goto rende comunque il codice più
facile da analizzare.
In molti linguaggi di programmazione l'utilizzo di goto viene scoraggiato e se proprio si
deve si consiglia di utilizzarlo in modo giudizioso.
Sintassi
label:
void svolgiFunzione( );
parte del programma.
goto label; //invia il flusso dati nella posizione della label
#define
35
Operatori aritmetici
operatore di assegnamento =
Memorizza il valore a destra del segno di uguale nella variabile che si trova alla sinistra del
segno uguale.
Il segno di = è chiamato operatore di assegnamento ed ha un significato differente da
come si utilizza nel caso di equazioni aritmetiche. Questo operatore chiama il
microcontrollore a valutare sempre il valore o l'espressione che si trova a destra del
segno uguale e lo memorizza nella variabile a sinistra del segno uguale.
La variabile che si trova sul lato sinistro del segno di assegnamento deve essere in grado
di memorizzare il valore. Se non è abbastanza grande da poter memorizzare questo
valore , il valore memorizzato nella variabile sarà non corretto.
Attenzione: non confondere il segno = di assegnamento con il simbolo di confronto ==
che valuta se due espressioni sono uguali.
36
60*1000 porterebbe a valori oltre i 32767 e quindi l'overflow dei bit con conseguente
risultato negativo del prodotto.
Nota bene: Scegliere sempre variabili che siano in grado di memorizzare i risultati dei
calcoli.
Per le funzioni math che richiedono l'utilizzo di frazioni si consiglia di utilizzare variabili di
tipo float, portando in conto lo svantaggio che una variabile di gran sezione rallenta la
velocità di computazione.
Per convertire una variabile in un altro tipo si utilizza la tecnica del casting, vista già in
precedenza
Es. per trasformare un numero di tipo float in un numero di tipo si fa così : (int)NumFloat
Modulo %
Il modulo calcola il resto di una divisione quando un intero è diviso per un altro intero.
Spesso utilizzato per gestire variabili entro un certo range (es. sezione di un array).
Sintassi
result=dividendo%divisore
dove il dividendo è il numero che deve essere diviso e il divisore è il numero che divide.
Restituisce il resto della divisione.
Esempi
x=7%5; // x contiene 2
x=9%4; // x contiene 1 in quanto 9/4=2 con resto 1
void setup( ) {
}
void loop( )
{
valori[i] = analogRead(0);
i = (i + 1) % 10; // operatore modulo - variabile rolls over
// ogni 10 volte aggiorna il valore di valori
}
37
Operatori di confronto
Gli operatori di confronto vengono utilizzati normalmente insieme all'istruzione if che testa
se una certa condizione è stata ricevuta, così come un certo input abbia raggiunto un certo
valore. Il formato per un test di if è
if (Variabile > 50)
{
// svolgi istruzioni
}
che testa se una variabile è superiore a 50.
Le istruzioni che saranno valutate tra parentesi utilizzano quindi i seguenti operatori di
confronto
x==y // x uguale a y
x!=y // x diverso da y
x<y // x minore di y
x>y // x maggiore di y)
x<=y // x minore o uguale a y
x>=y // x maggiore o uguale a y
Operatore booleano
Esempio
if (digitalRead(2) == HIGH && digitalRead(3) == HIGH) {
// legge i valori ad esempio di due interruttori
// esegue delle istruzioni
}
questa condizione è vera se entrambe le condizioni sono vere.
38
|| operatore OR
La condizione sarà verificata se almeno una condizione è verificata.
Sintassi
if (condizione1 || condizione2){
// esegui istruzioni
}
Esempio
if (x > 0 || y > 0) {
// se x>0 oppure y>0 esegui delle istruzioni
}
vera se x o y sono maggiori di 0.
! operatore not
Vero se l'operando è falso
if ( !x ) {
// esegui istruzioni
}
vera se x è falsa
Attenzione
Operatore logico Operatore tra bit
Non confondere gli operatori logici con gli operatori che lavorano con singoli bit.
Le due tipologie di operatori sono nettamente differenti.
39
Operatori tra bit ( su interi a 16 bit )
Ognuno dei 16 bit sono processati utilizzando l'AND tra bit e tutti e 16 i risultati vengono
memorizzati nella variabile c corrispondente a 68 decimale.
Uno dei maggior utilizzi dell'operatore tra bit AND è quello di selezionare un particolare bit
( o particolari bit) utilizzando la tecnica del masking . Vedi in seguito per un esempio
Operatore OR tra bit |
L'operatore OR tra bit (barra verticale) lavora su ogni bit indipendentemente dalla loro
combinazione.
Il bit di uscita è 1 se almeno uno dei due operandi è 1.
0 0 1 1 operando1
0 1 0 1 operando2
-------------
0 1 1 1 (operando1 | operando2) - risultato
40
Un comune impiego degli operatori AND e OR tra bit è quello di leggere, modificare e
scrivere su una porta. Nei microcontrollori una porta è rappresentata da un numero a 8 bit
che rappresenta le condizioni dei pin. Scrivendo sulla porta si controllano lo stato di tutti i
pin.
int j;
void setup( ){
DDRD = DDRD | B11111100; // imposta a 1 i bit dei pin dal 2 al 7,
// lascia i bit dei pin 0 e 1 inalterati (xx||0 0=x x)
// alla stessa maniera di pinMode(pin,OUTPUT)
// dei pin dal 2 al 7
Serial.begin(9600);
}
void loop( ){
for (int i=0; i<64; i++){
PORTD = PORTD & B00000011; // cancella i bit 2 - 7, lascia
// inalterati i pin 0 e 1 (xx & 11 == xx)
j = (i << 2); // shifta la variabile i di due bit per comandare
// solo i bit che vanno dal 2 al 7
// per evitare i pin 0 e 1
PORTD = PORTD | j; // combina le informazioni della porta con le
// nuove informazioni dei pin dei led
Serial.println(PORTD, BIN); // controllo della maschera
delay(100);
}
}
41
Operatore tra bit XOR (^
( ^)
L'uscita è uguale a 1 se entrambi gli ingressi sono uguali, è 0 se i due bit sono diversi.
0 0 1 1 operando1
0 1 0 1 operando2
------------
0 1 1 0 (operando1 ^ operando2) = risultato
Esempio di codice :
int x = 12 ; // binario: 1100
int y = 10 ; // binario: 1010
int z = x ^ y ; // binario: 0110, o decimale 6
Il risultato negativo -104 è dovuto al fatto che il bit più significativo 1 rappresenta il segno
on questo caso quindi coincidente con il -.
42
Scorrimento verso sinistra (<<) e verso destra ( >> )
Lo scorrimento in pratica fa scorrere verso destra o verso sinistra i bit di un certo numero
di posizioni specificato dall'operando che si trova a destra del comando.
Sintassi
variable << numero di bit
variable >> numero di bit
La variabile può essere di tipo byte, int, long mentre il numero di bit da shiftare < = di 32
Esempio:
int a = 5; // binario: 0000000000000101
int b = a << 3; // binario: 0000000000101000, o 40 in decimale
int c = b >> 3; // binario: 0000000000000101, tornati alla condizione di partenza 5
Quando si fa lo shift verso sinistra di un valore x di y bits (x << y), occorre far attenzione
che non vadano persi i bit più significativi.
Per esempio
int a = 5; // binario: 0000000000000101
int b = a << 14; // binario: 0100000000000000 – in questo caso il primo bit a
// sinistra 1 in 101 è stato perso.
Se si è certi che nessuno dei bit 1 durante l'operazione di shift viene perso l'operazione di
shift verso sinistra significa moltiplicare per 2 elevato al numero di spostamenti effettuati.
Esempio
1<< 0 == 1 ( 1=20)
1<< 1 == 2 ( 1=21)
1<< 2 == 4 ( 1=22)
1<< 3 == 8 ( 1=23)
…
1<<8 ==256 ( 1=28)
Quando lo shift invece si fa verso destra di un certo numero y di cifre (x>>y) e il bit più
significativo è 1 il comportamento dipende dalla tipologia del dato.
Se x è di tipo intero il bit più significativo rappresenta il segno e su questo occorre
discutere.
In questo caso il segno viene riproposto sempre nel bit più significato e spesso questo
comportamento non è quello voluto (problema dell'estensione del segno)
int x = - 16; // binario: 1111111111110000
int y = x >> 3; // binario: 1111111111111110
111 estensione del segno
questo inconveniente si risolve nel modo che segue:
int x = -16; // binary: 1111111111110000
int y = (unsigned int) x >> 3; // binary: 0001111111111110
Se si è sicuri di evitare il problema dell'estensione del segno si può utilizzare la tecnica
dello shift verso destra per dividere per 2 elevato alla potenza dello spostamento
43
effettuato.
Esempio
int x = 1000;
int y = x >> 3; // divisione intera di 1000 per 8, dà luogo a y = 125.
Operatori composti
++ (incremento) - - (decremento)
Incrementa o decrementa una variabile
Sintassi
x++ ; // il valore di x viene reso prima disponibile e poi viene incrementato
++x ; // il valore della variabile x prima viene incrementato di 1 e poi reso disponibile
x-- ; // il valore della variabile x viene prima reso disponibile e poi decrementato
--x ; // il valore della variabile x viene prima decrementato e poi reso disponibile
x è una variabile di tipo int oppure long (possibilmente senza segno)
Il valore restituito è il valore di partenza o il nuovo valore incrementato o decrementato
della variabile.
Esempio
x = 2;
y = ++x ; // x ora contiene 3, y contiene 3
y = x -- ; // x contiene 2 , y contiene 3
+= -= *= /=
Esegue un'operazione matematica su una variabile insieme ad un'altra variabile o
costante.
Sintassi
x += y; // equivalente all'espressione x = x + y;
x -= y; // equivalente all'espressione x = x - y;
x *= y; // equivalente all'espressione x = x * y;
x /= y; // equivalente all'espressione x = x / y;
Parametri
x: qualsiasi variabile
y: qualsiasi variabile o costante
Esempi
x = 2;
x += 4; // x ora contiene 6
x -= 3; // x ora contiene 3
44
x *= 10; // ora contiene 30
x /= 2; // x ora contiene 15
Le composizioni tra operatori a livello di bit sono spesso utilizzati per cancellare e settare
uno specifico bit di una variabile.
Esempio
Prima di tutto ricordiamoci come funziona l'operatore AND (&) tra bit
0 0 1 1 operando1
0 1 0 1 operando2
----------
0 0 0 1 (operando1 & operando2)
I bit che sono & con 0 sono posti a 0, mentre i bit che sono & con 1 non cambiano
mioByte & B00000000 = 0;
mioByte & B11111111 = mioByte;
10101010 variabile
11111100 maschera
----------------------
10101000 risultato
xxxxxxxx variabile
11111100 mask
----------------------
xxxxxx00 variabile
45
Così se
mioByte = 10101010;
mioByte &= B1111100 == B10101000;
OR composto ( |= )
L'operatore composto di OR tra bit (|=) è spesso usato tra una variabile e una costante
che setta (mette a 1) particolari bit in una variabile.
Sintassi
x |= y ; // equivalente a x = x | y;
Il parametro x è una variabile di tipo char, int long
y invece una costante di tipo integer o char, int, o long
Di seguito stessa rappresentazione, solo che al posto dei bit vengono posti i simboli x
xxxxxxxx variabile x
00000011 maschera
----------------------
xxxxxx11 variabile x
Così :
mioByte = B10101010;
mioByte |= B00000011 == B10101011;
46
Funzioni
I/O digitali
pinMode(pin,mode);
pin numero del pin di cui si vuole impostare la modalità ingresso o uscita
mode sempre INPUT o OUTPUT
Esempio
int ledPin=10; //led connesso al pin digitale 10
void setup( ){
pinMode(ledPin,OUTPUT); //imposta il pin digitale come uscita (output)
}
I pin analogici possono essere usati come pin digitali purché ci si riferisca con i nomi A0,
A1...A5.
digitalWrite
Scrive un valore HIGH o LOW su un pin impostato come digitale.
Se il pin è stato impostato come OUTPUT con il pinMode(), la sua tensione sarà impostata
al corrispondente valore di 5V per HIGH e 0V per LOW.
Se il pin è impostato come INPUT tramite il pinMode(), scrivendo un valore HIGH con
digitalWrite() si abiliterà un resistore interno di pullUp da 20K. Scrivendo basso sarà
disabilitato il pullup. Il resistore di pullup è sufficiente per far illuminare un led debolmente,
per cui sembra che il diodo lavori anche se debolmente (questa è una probabile causa).
Il rimedio è di impostare il pin su un'uscita con il metodo pinMode
Attenzione: il pin 13 è più difficile da utilizzare come input digitale rispetto agli altri pin
poiché ha già collegati un diodo led e un resistore sulla board. Se si abilita il resistore di
pullup esso viene portato a 1,7V invece dei 5V attesi poiché si deve tener conto della serie
di questi due componenti e questo significa che restituisce sempre LOW (Arduino legge
sempre 0). Per ovviare a questo inconveniente occorrerebbe inserire esternamente un
resistore di pull down.
digitalWrite(pin,valore)
pin è il pin di cui si vuole impostare il valore
valore HIGH o LOW
47
Esempio
int ledPin=13; // led connesso al pin digitale 13
void setup( ){
pinMode(ledPin, OUTPUT); // imposta il pin digitale come output
}
void loop( )
{
digitalWrite(ledPin, HIGH); // accende il LED
delay(1000); // aspetta per 1 secondo
digitalWrite(ledPin, LOW); // spegni il LED
delay(1000); // attendi 1 secondo
}
I pin analogici possono essere usati come pin digitali purché ci si riferisca con i nomi A0,
A1...A5.
digitalRead
Legge il valore da un pin digitale specifico.
Sintassi
digitalRead(pin);
pin è il numero intero del pin di cui si vuole leggere il valore alto o basso.
Esempio
int ledPin = 13; // LED connesso al pin digitale13
int inPin = 7; // pulsante connesso al pin digitale7
int val = 0; // variabile che memorizza il valore letto
void setup( ) {
pinMode(ledPin, OUTPUT); // imposta il pin digitale 13 come uscita
pinMode(inPin, INPUT); // imposta il pin digitale 7 come ingresso
}
void loop( ){
val = digitalRead(inPin); // legge il pin di ingresso e lo memorizza in val
digitalWrite(ledPin, val); // imposta il LED a seconda dell'azione svolta
// sul pulsante
}
Se il pin non è connesso per un qualsiasi motivo digitalRead() può restituire sia HIGH che
LOW in modo del tutto casuale.
48
I pin analogici possono essere usati come pin digitali purché ci si riferisca con i nomi A0,
A1...A5.
I/O analogici
analogReference(type)
Configura la tensione di riferimento utilizzata per gli ingressi analogici (cioè il valore
massimo del range dei valori di ingresso). Le opzioni sono:
DEFAULT: il valore analogico di riferimento è 5V sulle schede di Arduino a 5V oppure 3.3V
su quelle a 3.3V.
INTERNAL: 1,1V sull'ATmega168 o Atmega328 e 2.56 V sull'ATmega8.
EXTERNAL: la tensione applicata al pin AREF è usata come riferimento.
Type quindi può essere DEFAULT, INTERNAL ed EXTERNAL.
Attenzione: se si vuole utilizzare un riferimento di tensione esterno, applicato al pin AREF,
occorre impostare il riferimento analogico EXTERNAL tramite analogRead(). Altrimenti si
metterà in corto con la tensione attiva interna causando un danneggiamento della scheda
Arduino.
Alternativamente si può collegare al pin di riferimento esterno della tensione AREF un
resistore di 5k e poter così scegliere tra tensione interna e tensione esterna. Si nota che il
resistore modificherà la tensione usata come riferimento esterno poiché sul pin AREF c'è
internamente un resistore da 32k. I due resistori esplicano il compito di partitore di
tensione ad esempio se la tensione applicata è di 2.5V sul pin AREF ci arriva 2.5*32/
(32+5)=2,2V circa.
analogRead()
Legge il valore da un pin di tipo analogico. La scheda Arduino contieni 6 canali ( 8 nel mini
e Nano, 16 sul Mega) convertitori analogici digitali a 10 bit.
Questo significa che 5 V vanno suddivisi da 0 a 1023 per cui la risoluzione sarà di 5V/1023
unità =4.9mV per unità. Il range di partenza e la risoluzione possono essere modificate
agendo su analogReference().
Occorrono circa 100 microsecondi per leggere da un input analogico per cui la frequenza
di lettura è circa 10000 volte in un secondo.
Sintassi
analogRead(pin);
pin: numero del pin analogico da leggere che va da 0 a 5 sulla maggior parte delle schede,
da 0 a 7 sulla Mini e nano, da 0 a 15 sul Mega ).
Restituisce un intero da 0 a 1023.
Se l'input analogico non è connesso per qualche motivo il valore fornito da analogRead
fluttuerà in funzione di diversi fattori.
Esempio
int analogPin = 3; // Cursore del potenziometro ( terminale centrale) connesso
49
// al pin 3 analogico ; gli altri due morsetti rispettivamente a
// massa e a +5V
int val = 0; // variabile che memorizza il valore letto
void setup( )
{
Serial.begin(9600); // setup serial
}
void loop( )
{
val = analogRead(analogPin); // legge il valore del pin di ingresso
Serial.println(val); // visualizza il valore
}
analogWrite( )
Scrive un valore analogico (PWM) su un pin.
Può essere utilizzato per far illuminare un led variandone l'intensità luminosa oppure per
comandare un motore e variarne la velocità.
Dopo la chiamata del metodo analogWrite(), sul pin verrà generata un'onda quadra
regolare con un duty cycle specifico fino alla prossima chiamata di analogWrite() o di
digitalWrite(), o di digitalRead() sullo stesso pin.
La frequenza del segnale PWM è all'incirca 490Hz.
Sulla maggior parte delle schede di Arduino questa funzione lavora sui pin 3,5 6,9,10 e 11.
Sulle altre schede potrebbero esserci delle varianti.
I pin analogici non necessitano di essere impostati prima della chiamata di analogWrite()
con pinMode nel setup.
Sintassi
analogWrite(pin,valore);
Il parametro pin rappresenta il pin su cui scrivere;
il parametro valore rappresenta il valore del duty cycle tra 0 (sempre off) e 255( sempre
on).
Nota:
La pwm in uscita sui pin 5 e 6 ha duty cycle maggiori di quanto aspettato.
Questo a causa di interazioni con i metodi millis() e delay() che condividono lo stesso
timer interno usato per generare il segnale PWM.
Questo fa sentire maggiormente il suo peso per bassi valori di duty-cycle (0-10% circa) e
potrebbe causare il non perfetto azzeramento in modalità di turn-off.
Esempio
50
Setta l'uscita sul LED proporzionalmente al valore letto da un potenziometro.
I/O avanzati
tone( )
Genera su un pin un'onda quadra con la specificata frequenza (il duty cycle rimane
sempre al 50%). La durata può essere specificata, altrimenti l'onda continuerà fino alla
chiamata del metodo noTone().
Il pin può essere connesso con un piezo buzzer un altro speaker che lavora sui toni.
Può essere generato solo un tono a volta.
Se un tone() sta già lavorando su un pin, la chiamata di tone() su un altro pin non avrà
alcun effetto. Se tone() sta lavorando sullo stesso pin, la sua chiamata imposterà il valore
della sua frequenza.
L'uso di tone() interferirà con l'uscita PWM dei pin 3 e 11.
Nota: per ottenere diverse intonazioni o pin multipli, occorre chiamare noTone() su un pin
prima di chiamare tone sul prossimo pin.
Sintassi
tone(pin,frequenza);
tone(pin,frequenza, durata);
pin: è il pin sul quale s vuole generare il tono
frequenza: è il valore della frequenza del tono in hertz
durata: durata del tono in ms (opzionale).
noTone( )
Ferma la generazione dell'onda quadra generata dalla chiamata di tone(). Non ha alcun
effetto se non è stato generato in precedenza un tono.
51
Sintassi
noTone(pin);
dove con pin ci si riferisce al pin sul quale si vuole fermare la generazione dell'onda
quadra.
shiftOut( )
shift out porta fuori un byte di dati un bit a volta.
Inizia dal bit più significativo (quello più a sinistra) o da quello meno significativo (quello più
a destra).
Ogni bit è scritto in sequenza su un dato pin, dopo che un pin di clock ha ricevuto l'impulso
per indicare che quel bit è disponibile.
Sintassi
shiftOut(PinDati,PinClock,bitOrder,valore)
dove il parametro PinDati è il pin sul quale vengono posti in uscita ogni bit (int);
PinClock è il pin di toggle una volta che il pindati è stato impostato al corretto valore (int);
bitOrder definisce secondo quale ordine vengono inviati i bit; o MSBFIRST o LSBFIRST
(Most Significant Bit First o Least Significant Bit First);
valore rappresenta il byte dati da mandar fuori.
La funzione non restituisce alcun valore.
Si ricorda che il PinDati e il PinClock devono essere impostati come output nel setup()
tramite la chiamata della funzione pinMode().
shiftOut attualmente è chiamato a inviare in uscita 1 byte (8 bit) così richiede due passi per
inviare uscite di valore maggiore di 255.
// Per il seriale MSBFIRST a partire dal più significativo
int dato = 500; //dato è un numero di oltre 8 bit
// shift out del byte più alto
shiftOut(PinDati, PinClock, MSBFIRST, (dato >> 8 ));
// shift out del più basso
shiftOut(PindDati, PinClock, MSBFIRST, dato);
// Per shiftout a partire dal byte meno significativo LSBFIRST
dato = 500;
// shift out byte più basso
shiftOut(PinDati, PinClock, LSBFIRST, dato);
// shift out del byte più alto
shiftOut(dataPin, clock, LSBFIRST, (dato >> 8)); //si specifica che dato>>8 è la parte da shiftout
Esempio
Controllo di un multiplexer (shift register) 74HC595
52
// Pin connesso al pin dati del 74HC595
int dataPin = 11;
void setup( ) { //impostazione dei pin di output in quanto devono essere indirizzati nel loop
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop( ) {
//routine di conteggio in avanti
for (int j = 0; j < 256; j++) {
digitalWrite(latchPin, LOW); // durante la trasmissione il latchPin deve essere collegato a
//massa e mantenuto a livello basso
shiftOut(dataPin, clockPin, LSBFIRST, j);
digitalWrite(latchPin, HIGH); // riporta il pin del latch al segnale alto in quanto non è
// più necessario attendere informazioni
delay(1000);
}
}
pulseIn( )
Legge un impulso (alto o basso) su un pin.
Per esempio se il valore è HIGH, pulseIn() attende che il pin diventi alto, inizia il conteggio,
quindi aspetta che il pin diventi basso e ferma il tempo.
Restituisce la lunghezza dell'impulso in microsecondi. Restituisce 0 se nessun impulso
inizia entro uno specifico tempo.
Gli intervalli di lavoro di questa funzione sono stati determinati empiricamente e quindi
probabilmente saranno soggetti a errori per impulsi lunghi.
pulseIn lavora su impulsi che vanno da 10 microsecondi fino a 3 minuti di durata.
Sintassi
pulseIn(pin, valore);
pulseIn(pin,valore, timeout);
pin indica il pin (numero intero) di Arduino sul quale si va a leggere la durata dell'impulso;
valore si riferisce al tipo da leggere cioè se alto (HIGH) o basso(LOW);
timeout è opzionale ed indica il numero in microsecondi di attesa per l'impulso di partenza;
il valore di default è 1secondo(senza segno long).
La funzione restituisce la durata dell'impulso, tipo long senza segno, in microsecondi
oppure restituisce 0 se l'impulso non parte prima del tempo di timeout.
Esempio
int pin = 7 ; // pin sul quale arriva un segnale di tipo impulsivo (potrebbe essere
// anche il segnale inviato da un telecomando IR )
unsigned long durata; // durata è il nome della variabile in cui memorizzare
// l'ampiezza dell'impulso alto o basso che esso sia.
53
void setup( )
{
pinMode(pin, INPUT); // il pin deve ricevere un'informazione impulsiva per cui
// impostato di tipo INPUT
}
void loop( )
{
durata = pulseIn(pin, HIGH); // misura dell'ampiezza in microsecondi
// dell'impulso in questo caso a livello alto
}
Time
mills( )
Restituisce il numero di millesecondi di tipo unsigned long da quando Arduino ha iniziato a
far funzionare un certo programma.
Questo numero andrà in overflow, tornando a 0, dopo circa 50 giorni.
Esempio
unsigned long tempo ;
void setup( ){
Serial.begin(9600);
}
void loop( ){
Serial.print ("Tempo: ");
tempo = millis( ); //stampa il tempo da quando il programma funziona
Serial.println(tempo);
delay(1000); // attesa di 1 secondo in modo da non inviare una gran
// quantità di dati da visualizzare su PC
}
La variabile definita per millis() deve essere un “unsigned long” altrimenti se si cercasse di
forzare matematicamente ad altro tipo potrebbe verificarsi un errore.
micros( )
Restituisce il numero di microsecondi da quando Arduino ha iniziato a far funzionare il
programma corrente.
Questo numero andrà in overflow dopo circa 70 minuti.
Per schede di Arduino a 16MHz (uno e Nano) questa funzione ha una risoluzione di 4
microsecondi ( il valore restituito è sempre multiplo di 4).
Esempio
54
unsigned long tempo_micro;
void setup( ){
Serial.begin(9600);
}
void loop( ){
Serial.print("Tempo: ");
tempo_micro = micros( );
Serial.println(time); // stampa tempo_micro da quando il programma è
// iniziato
delay(1000); // attesa di 1 secondo in modo da non inviare una gran
// quantità di dati
}
delay( )
Mette in pausa il programma per un certo intervallo di tempo in millesecondi specificato da
un parametro.
Sintassi
delay( ms )
ms è il numero di millisecondi di pausa di tipo unsigned long (long senza segno).
Esempio
int ledPin = 13; // LED connesso al pin digitale 13 già presente su Arduino
void setup( )
{
pinMode(ledPin, OUTPUT); // imposta il pin digitale come output
}
void loop( )
{
digitalWrite(ledPin, HIGH); // imposta allo stato alto il pin digitale led acceso
delay(1000); // aspetta 1 secondo
digitalWrite(ledPin, LOW); // spegni LED
delay(1000); // attendi 1 secondo
}
Attenzione
È semplice creare un led che lampeggia con la funzione di delay() e molti programmi
usano delay corti come switch.
In effetti l'uso del delay() in uno sketch comporta degli inconvenienti.
Nessuna lettura di sensori, calcoli matematici, o manipolazioni di pin può essere attivo
durante un'operazione di delay(), questo porta la maggior parte delle attività in sosta.
Molti evitano l'utilizzo del delay per gli eventi legati alla temporizzazione di eventi di durata
superiore al decimo di secondo a meno che lo sketch Arduino sia veramente semplice.
Alcune funzionalità di Arduino procedono nel loro corso anche se la funzione delay() sta
55
bloccando il chip Atmega, in quanto tale funzione delay() non disabilita gli interrupt.
La comunicazione seriale che appare al pin RX viene registrata, i valori della
PWM(analogWrite) e lo stato dei pin sono mantenuti, e gli interrupt funzionano come
devono.
delayMicroseconds()
Ferma il programma per una certa quantità di microsecondi specificato da un parametro.
Attualmente il valore maggiore che produce un accurato delay è 16383. Questo valore può
modificarsi con le future release di Arduino.
Per ritardi maggiori intorno ad un centinaio di microsecondi, conviene utilizzare delay().
Sintassi
delayMicroseconds(us)
us: numero di microsecondi di pausa (int di tipo unsigned- senza segno)
Questa funzione non restituisce alcun valore.
Esempio
int outPin = 8 ; // pin digitale 8 di uscita
void setup( )
{
pinMode(outPin, OUTPUT); // imposta il pin di uscita
}
void loop( )
{
digitalWrite(outPin, HIGH); // imposta il pin allo stato alto
delayMicroseconds(50); // metti in pausa per 50 microsecondi
digitalWrite(outPin, LOW); // imposta il pin allo stato basso
delayMicroseconds(50); // metti in pausa per 50 microsecondi
}
Il programma appena scritto configura il pin 8 come pin di uscita e trasmette un treno di
impulsi con un periodo di 100 microsecondi.
Problemi noti
Questa funzione lavora in modo preciso in un range che parte da 3 microsecondi in su.
Non è possibile affermare che delayMicroseconds() sarà preciso per tempi di valore
inferiori.
delayMicroseconds() non disabilita gli interrupts.
56
Funzioni matematiche Math
min(x,y)
Esempio
sensVal = min(sensVal, 100); // assegna a sensVal il più piccolo tra il valore
// precedente sensVal e 100 assicurando che non venga
// mai superato 100.
Attenzione:
Probabilmente in un contatore, max() è usato per costringere l'estremo inferiore di un
range di valori mentre min() è utilizzato per costringere l'estremo superiore del range.
A causa del modo in cui la funzione min() è implementata, evitare di usare altre funzioni
all'interno delle parentesi,altrimenti si potrebbe ottenere un risultato errato.
a++;
min(a, 100); // questo modo di scrivere mantiene altre funzioni matematiche
//al di fuori di questa funzione
max(x,y)
Esempio
sensVal = max(senVal, 20); // assegna alla variabile sensVal il valore maggiore tra
sensVal o 20
// assicurandosi che sia al massimo 20
Attenzione:
Probabilmente in un contatore, max() è usato per costringere l'estremo inferiore di un
range di valori mentre min() è utilizzato per costringere l'estremo superiore del range.
A causa del modo in cui la funzione max() è implementata, evitare di usare altre funzioni
all'interno delle parentesi, altrimenti si potrebbe ottenere un risultato errato.
max(a--, 0); // evitare questa situazione – risultato non corretto
57
a--; // usa questo invece
max(a, 0); // lascia fuori altre funzioni matematiche
abs(x)
constrain(x,a,b)
Sintassi
type valore=constrain(x,a,b);
Questa funzione costringe un numero a stare dentro un certo range.
Il parametro x è il numero da costringere entro il range e può essere di qualsiasi tipo;
a è l'estremo inferiore del range e può essere di qualsiasi tipo di dati
b è l'estremo superiore del range e può essere di qualsiasi tipo di dati
La funzione restituisce x se x è tra a e b;
restituisce a se x è minore di a;
restituisce b se x è maggiore di b.
Esempio
sensVal = constrain(sensVal, 10, 150); // limita il range del valore del sensore
// tra 10 e 150
58
daValoreAlto: limite superiore del corrente range
aValoreBasso: limite inferiore del range obiettivo
aValoreAlto: limite superiore del range obiettivo
La funzione restituisce il valore mappato.
Non costringe i valori entro un certo range, poiché i valori fuori range sono a volte
premeditati e utili. La funzione constrain() può essere utilizzata o prima o dopo questa
funzione se sono desiderati dei limiti di range.
Nota: il limite inferiore di un range può essere più grande o più piccolo del limite superiore
così la funzione map() può essere usata per invertire il range di un numero.
Esempio
y = map(x, 1, 50, 50, 1);
La funzione può trattare anche numeri negativi, così come in questo esempio:
y = map(x, 1, 50, 50, -100);
è valido e lavora bene.
La funzione map() usa numero interi così non potrà generare frazioni, quando si costringe
a restituire una frazione questa sarà troncata, non approssimata.
Esempio
void setup( ) {
}
void loop( )
{
int val = analogRead(0);
val = map(val, 0, 1023, 0, 255);
analogWrite(9, val);
}
pow(base,esponente)
59
sqrt(x)
60
Trigonometria
sin(rad)
cos(rad)
tan(rad)
Calcola la tangente di un angolo espresso n radianti. Il risultato sarà compreso tra meno
infinito e più infinito.
Sintassi
double valore=tan(rad);
valore è il risultato della funzione tan;
rad è l'angolo espresso in radianti di tipo float
La funzione restituisce la tangente dell'angolo espresso in double.
61
Numeri casuali (Random numbers)
randomSeed(seme) seed=seme
Esempio
long randNumber;
void setup( ){
Serial.begin(9600);
randomSeed(analogRead(0)); // seme puramente casuale
}
void loop( ){
randNumber = random(300);
Serial.println(randNumber);
delay(50);
}
random( )
62
Esempio
long randNumber;
void setup( ){
Serial.begin(9600);
// se il pin0 analogico non risulta connesso, il rumore analogico casuale genererà differenti
// semi nella chiamata di randomSeed( ) ogni volta che lo sketch viene chiamato.
// randomSeed( ) quindi darà luogo a diverse funzioni random.
randomSeed(analogRead(0));
}
void loop( ) {
randNumber = random(300); // stampa un numero random da 0 a 299
Serial.println(randNumber);
63
Bits and Bytes
lowByte( )
Estrae il byte più a destra di una variabile (ad esmpio di una variabile di tipo word).
Sintassi
byte valore = lowByte(x);
Il parametro x è un valore di qualsiasi tipo
La funzione restituisce un valore di tipo byte.
highByte( )
Estrae il byte più a sinistra di una parola (word) o il secondo più basso byte di un dato di
tipo di data più grande del word.
Sintassi
byte valore=highByte(x)
dove il parametro x è un valore di qualsiasi tipo
La funzione restituisce un valore di tipo byte
bitRead( )
Questa funzione legge un bit di un numero per cui restituisce il valore del bit 0 oppure 1
Sintassi
int valore = bitRead(x,n)
dove valore può assumere 0 oppure 1, x rappresenta il numero da cui leggere e il
parametro n è il bit da leggere, partendo da 0 per il bit meno significativo (quello più a
destra)
bitWrite( )
64
bitSet( )
bitClear( )
bit( )
65
External Interrupts Interruzioni esterne.
attachInterrupt(interrupt,funzione,modo)
Nota
delay() non può far parte delle funzioni attaccate alla gestione delle interrupt, non può
lavorare e il valore restituito dalla funzione millis() non verrà incrementato.
I dati seriali ricevuti durante la funzione possono essere sbagliati.
Qualsiasi variabile modificabile all'interno della funzione attached si può dichiarare come
volatile.
66
Anche altri sensori richiedono un controllo costante e continuo siffatto, per esempio
leggere un sensore di suono che deve catturare (accorgersi) un click, oppure un sensore
IR che deve catturare l'evento di caduta di una moneta.
In tutte queste situazioni usare un interrupt può alleggerire il microcontrollore che può
dedicarsi ad altri compiti senza dimenticarsi di rimanere all'erta.
Esempio
int pin = 13;
volatile int state = LOW;
void setup( )
{
pinMode(pin, OUTPUT);
attachInterrupt(0, blink, CHANGE);
}
void loop( )
{
digitalWrite(pin, state);
}
void blink( ) // ogni volta che si chiama questa funzione cambia lo stato della
// variabile state
{
state = !state ;
}
detachInterrupt(interrupt)
Interrupts
interrupts( )
Riabilita gli interrupt (dopo che essi sono stati disabilitati da noInterrupts()).
Gli interrupts permettono ad alcuni importanti eventi di avvenire in background e sono
abilitati per defalut.
Alcune funzioni non lavorano mentre gli interrupts sono disabilitati e le comunicazioni in
arrivo potrebbero essere ignorate.
Gli interrupt possono leggermente variare il tempo del codice e possono essere disabilitati
per particolari sezioni critiche del codice.
67
Esempio
void setup( ) { }
void loop( ){
noInterrupts( );
// … sezione critica del codice
interrupts( );
// altro codice }
noInterrupts
68
Comunicazione
Serial
begin()
Imposta la velocità di trasmissione dati in bit al secondo(baud) per la trasmissione seriale.
Per comunicare con il computer ci sono diverse velocità ammissibili: 300, 1200, 2400,
4800, 9600, 14400, 57600, 115200. Si può comunque specificare altre velocità – per
esempio per comunicare altri pin 0 e 1 a componenti che richiedono una particolare
velocità.
Sintassi
Serial.begin( velocità)
Solo per Arduino Mega
Serial1.begin(velocità)
Serial2.begin(velocità)
Serial3.begin(velocità)
il parametro velocità rappresenta la velocità in bit per secondi (baud) ed è dichiarata come
tipo long.
La funzione non restituisce alcun valore.
69
Esempio
void setup( ) {
Serial.begin(9600); // apri la porta seriale e imposta la velocità a 9600 bps
}
void loop( ) { }
void setup( ){
Serial.begin(9600);
Serial1.begin(38400);
Serial2.begin(19200);
Serial3.begin(4800);
Serial.println("Hello Computer");
Serial1.println("Hello Serial 1");
Serial2.println("Hello Serial 2");
Serial3.println("Hello Serial 3");
}
void loop( ) { }
end( )
Disabilita la comunicazione seriale, permettendo ai pin RX e TX di essere utilizzati come
I/O generali.
Per riabilitare la comunicazione seriale basta richiamare la funzione Serial.begin().
Sintassi
Serial.end( ) ;
Solo per Arduino Mega:
Serial1.end( ) ;
Serial2.end( ) ;
Serial3.end( ) ;
Questa funzione non restituisce alcun valore e non richiede alcun parametro.
available( )
Restiuisce il numero di byte disponibili per leggere dalla porta seriale.
Sintassi
Serial.available( )
70
Per Arduino Mega :
Serial1.available( )
Serial2.available( )
Serial3.available( )
La funzione non richiede alcun parametro e restituisce un valore di tipo byte necessari per
la lettura.
Esempio
int byteInArrivo = 0; // per iniziare la trasmissione seriale
void setup( ) {
Serial.begin(9600); // apertura porta seriale, impostazione velocità
// di trasmissione dati a 9600bps
}
void loop( ) {
if (Serial.available( ) > 0) {
byteIniziale = Serial.read( ); // leggi i byte che arrivano
Serial.print("Ricevuto: ");
Serial.println(byteInArrivo, DEC); // scrive i dati ricevuti
}
Esempio per Arduino Mega:
void setup( ) {
Serial.begin(9600);
Serial1.begin(9600);
}
void loop( ) {
// legge dalla porta 0, invia sulla porta 1:
if (Serial.available( ) ) {
int inByte = Serial.read( );
Serial1.print(inByte, BYTE);
}
// legge dalla porta 19, invia sulla porta 18:
if (Serial1.available( ) ) {
int inByte = Serial1.read( );
Serial.print(inByte, BYTE);
}
}
71
read( )
Legge i dati in entrata dalla comunicazione seriale.
Sintassi
Serial.read( )
Solo per Arduino Mega :
Serial1.read( )
Serial2.read( )
Serial3.read( )
La funzione non necessita di alcun parametro e restituisce il primo byte disponibile sulla
comunicazione seriale (tipo int) oppure -1 se non c'è alcun dato inviato.
Esempio
int byteInArrivo = 0; // per iniziare la trasmissione seriale
void setup( ) {
Serial.begin(9600); // apertura porta seriale, impostazione velocità di
// trasmissione dati a 9600bps
}
void loop( ) {
if (Serial.available( ) > 0) {
flush( )
Svuota il buffer dei dati seriali in entrata. Cioè, ogni chiamata di Serial.read() o
Serial.available() restituirà solo i dati ricevuti dopo tutte le più recenti chiamate di
Serial.flush().
Sintassi
Serial.flush( )
Per Arduino Mega :
Serial1.flush( )
Serial2.flush( )
Serial3.flush( )
La funzione non richiede alcun parametro restituisce alcun valore.
72
print( )
Questa funzione stampa sulla porta seriale un testo ASCII leggibile dall'uomo.
Questo comando può assumere diverse formati: i numeri sono stampati usando un
carattere ASCII per ogni cifra, i float sono scritti allo stesso modo e per default a due posti
decimali, i byte vengono inviati come caratteri singoli mentre i caratteri e le stringhe sono
inviati come sono.
Sintassi
Serial.print(valore)
Serial.print(valore,formato)
valore indica il valore da scrivere di qualsiasi tipo mentre formato indica la base del
sistema numerico (per i dati di tipo integer) o il numero di posti decimali per i tipi floating
point.
La funzione non restituisce alcun valore.
Esempi :
Serial.print(78) // dà come risultato "78"
Serial.print(1.23456) // dà come risultato "1.23"
Serial.print(byte(78)) // dà come risultato "N" (il valore ASCII di N è 78)
Serial.print('N') // dà come risultato "N"
Serial.print("Ciao mondo.") // dà come risultato "Ciao mondo."
Esempio:
/*
Uso di un ciclo FOR per ottenere e stampare dati in diversi formati.
*/
int x = 0; // variabile da stampare
void setup( ) {
73
Serial.begin(9600); // impostazione porta seriale a 9600 bps
}
void loop( ) {
Serial.print("NO FORMAT"); // stampa di label per la visualizzazione su PC
Serial.print("\t"); // stampa un tab (spazio vuoto)
Serial.print("DEC");
Serial.print("\t");
Serial.print("HEX");
Serial.print("\t");
Serial.print("OCT");
Serial.print("\t");
Serial.print("BIN");
Serial.print("\t");
Serial.println("BYTE");
for(x=0; x< 64; x++){
Serial.print(x); // stampa come un ASCII- base decimale - "DEC"
Serial.print("\t");
Serial.print(x, DEC); // stampa come un ASCII- base decimale - "DEC"
Serial.print("\t");
Serial.print(x, HEX); // stampa come un ASCII- base esadecimale
Serial.print("\t");
Serial.print(x, OCT); // stampa come un ASCII- base ottale
Serial.print("\t");
Serial.print(x, BIN); // stampa come un ASCII- base binaria
Serial.print("\t");
Serial.println(x, BYTE); // stampa come riga di valori byte con ritorno di
// carrello ( println )
delay(200); // delay 200 millisecondi
}
Serial.println(""); // stampa un altro ritorno a capo
}
Avvertimento
L'ultimo carattere che deve essere scritto è trasmesso sulla porta seriale dopo che
Serial.print() è terminato. Questo potrebbe essere un problema in casi particolari.
println( )
Scrive i dati sulla porta seriale come testo leggibile dall'uomo in codice ASCII seguito da
un carattere di ritorno a capo (ASCII 13 oppure '\r') e un carattere di nuova linea (ASCII
10, oppure '\n').
74
Questo comando assume la stessa forma di Serial.print().
Sintassi
Serial.println(valore)
Serial.println(valore, formato)
Il parametro valore indica il valore da scrivere di qualsiasi tipo mentre formato indica la
base del sistema numerico (per i dati di tipo integer) o il numero di posti decimali per i tipi
floating point.
La funzione non restituisce alcun valore.
Esempio
// Legge un valore analogico dal pin 0 e lo stampa in diversi formati
int analogVal = 0; // variabile che memorizza i valori analogici
void setup( ) {
Serial.begin(9600); // imposta la porta seriale a 9600 bps
}
void loop( ) {
analogVal = analogRead(0); // legge il valore analogico dal pin0
// stampa in diverso formato
Serial.println(analogVal); // stampa come ASCII- base 10
Serial.println(analogValue, DEC); // stampa come ASCII- base 10
Serial.println(analogValue, HEX); // stampa come ASCII- base 16
Serial.println(analogValue, OCT); // stampa come ASCII- base 8
Serial.println(analogValue, BIN); // stampa come ASCII- base 2
Serial.println(analogValue, BYTE); // stampa come riga di BYTE
delay(10); // attendi 10 ms prima della
// prossima lettura
}
write( )
Scrive i dati binari sulla porta seriale.
Questi dati sono inviati come byte o serie di byte; per inviare i caratteri rappresentati le
cifre di un numero usare invece la funzione print().
Sintassi
Serial.write(valore)
Serial.write(stringa)
Serial.write(buf,len)
Arduino Mega supporta anche : Serial1, Serial2, Serial3 al posto di Serial.
Il parametro valore è il valore da trasmettere come singolo byte; il parametro stringa è una
stringa da spedire come serie di byte; il parametro buf è un array da spedire come serie di
byte; il parametro len rappresenta la lunghezza del byte.
75
Indice generale: Elementi base del linguaggio di programmazione di Arduino
Ambiente di programmazione: Arduino.exe.................................................................2
Struttura di un programma................................................................................................3
void setup( ).....................................................................................................................3
void loop( ).......................................................................................................................4
Sintassi .............................................................................................................................5
; punto e virgola.............................................................................................................5
Le parentesi graffe { }......................................................................................................6
Commenti.........................................................................................................................6
Blocco di commenti /* …. */.......................................................................................7
Linea di commento //.................................................................................................7
Funzioni..............................................................................................................................8
Dichiarazione di funzione.................................................................................................8
Le costanti..........................................................................................................................9
Costanti booleane............................................................................................................9
Costanti INPUT e OUTPUT..............................................................................................9
INPUT .........................................................................................................................9
OUTPUT .....................................................................................................................9
Costanti HIGH e LOW......................................................................................................9
HIGH .........................................................................................................................10
LOW .........................................................................................................................10
Costanti a numero interi ( Integer ) ................................................................................10
Formattatori U e L...........................................................................................................11
Costante di tipo floating point (notazione numeri a virgola mobile)................................11
Le variabili........................................................................................................................12
Dichiarazione di una variabile........................................................................................12
Variabile globale.............................................................................................................12
Variabile locale...............................................................................................................13
Static..............................................................................................................................13
volatile............................................................................................................................15
const...............................................................................................................................16
#define or const.........................................................................................................16
Tipo di dati........................................................................................................................17
void.................................................................................................................................17
boolean..........................................................................................................................17
char................................................................................................................................18
unsigned char.................................................................................................................18
byte................................................................................................................................18
int ..................................................................................................................................18
unsigned int ...................................................................................................................19
76
word...............................................................................................................................20
long................................................................................................................................20
unsigned long.................................................................................................................20
floating point: numero in virgola mobile..........................................................................21
double............................................................................................................................21
char array - String .........................................................................................................21
Array di char .............................................................................................................22
Array di stringhe........................................................................................................22
String – oggetto (classe)...........................................................................................23
Array...............................................................................................................................24
Creazione e/o dichiarazione di un array....................................................................24
Accesso agli elementi di un array..............................................................................24
Assegnare un valore ad un array...............................................................................25
Conversioni......................................................................................................................26
char( ).............................................................................................................................26
byte( ).............................................................................................................................26
int( )................................................................................................................................26
word( )............................................................................................................................27
long( ).............................................................................................................................27
float( ).............................................................................................................................27
Utilità.................................................................................................................................28
sizeof( )..........................................................................................................................28
Istruzioni condizionali.....................................................................................................29
Istruzione if.....................................................................................................................29
Condizioni if/else............................................................................................................30
Istruzioni switch … case.................................................................................................31
Istruzione for / ciclo for...................................................................................................33
Ciclo while......................................................................................................................34
Ciclo do/while.................................................................................................................34
break..............................................................................................................................35
continue .......................................................................................................................35
return..............................................................................................................................35
goto................................................................................................................................36
#define ..........................................................................................................................36
Operatori aritmetici..........................................................................................................37
operatore di assegnamento =.....................................................................................37
Addizione(+), sottrazione (-), moltiplicazione (*) e divisione ( / )....................................37
Modulo %.......................................................................................................................38
Operatori di confronto.....................................................................................................39
Operatore booleano.......................................................................................................39
&& operatore AND.....................................................................................................39
77
|| operatore OR..........................................................................................................40
! operatore not..........................................................................................................40
Operatori tra bit ( su interi a 16 bit )............................................................................41
AND tra bit &.............................................................................................................41
Operatore OR tra bit | ..........................................................................................41
Operatore tra bit XOR (^)..........................................................................................43
Operatore NOT tra bit ~ ............................................................................................43
Scorrimento verso sinistra (<<) e verso destra ( >> )....................................................44
Operatori composti.........................................................................................................45
++ (incremento) - - (decremento) .........................................................................45
+= -= *= /=.............................................................................................45
AND composto tra bit (&=) e OR composto tra bit ( | = )..............................................46
AND composto ( & =)...............................................................................................46
OR composto ( |= ) ..................................................................................................47
Funzioni............................................................................................................................48
I/O digitali.......................................................................................................................48
pinMode(pin,mode);...................................................................................................48
digitalWrite ................................................................................................................48
digitalWrite(pin,valore)...............................................................................................48
digitalRead.................................................................................................................49
I/O analogici.................................................................................................................50
analogReference(type)..............................................................................................50
analogRead().............................................................................................................50
analogWrite( )............................................................................................................51
I/O avanzati....................................................................................................................52
tone( )........................................................................................................................52
noTone( )...................................................................................................................52
shiftOut( )...................................................................................................................53
pulseIn( )....................................................................................................................54
Time...............................................................................................................................55
mills( )........................................................................................................................55
micros( ).....................................................................................................................55
delay( ).......................................................................................................................56
delayMicroseconds()..................................................................................................57
Funzioni matematiche Math............................................................................................58
min(x,y)..........................................................................................................................58
max(x,y).........................................................................................................................58
abs(x).............................................................................................................................59
constrain(x,a,b)..............................................................................................................59
map(valore, daValoreBasso, daValoreAlto, aValoreBasso, aValoreAlto)........................59
pow(base,esponente).....................................................................................................60
78
sqrt(x).............................................................................................................................61
Trigonometria...................................................................................................................62
sin(rad)...........................................................................................................................62
cos(rad)..........................................................................................................................62
tan(rad)...........................................................................................................................62
Numeri casuali (Random numbers)................................................................................63
randomSeed(seme) seed=seme ...............................................................................63
random( )........................................................................................................................63
Bits and Bytes..................................................................................................................65
lowByte( ).......................................................................................................................65
highByte( )......................................................................................................................65
bitRead( ).......................................................................................................................65
bitWrite( )..........................................................................................................................65
bitSet( )...........................................................................................................................66
bitClear( ).......................................................................................................................66
bit( )................................................................................................................................66
External Interrupts Interruzioni esterne.......................................................................67
attachInterrupt(interrupt,funzione,modo)........................................................................67
Utilizzo degli interrupt................................................................................................67
detachInterrupt(interrupt)................................................................................................68
Interrupts........................................................................................................................68
interrupts( )................................................................................................................68
noInterrupts....................................................................................................................69
Comunicazione.................................................................................................................70
Serial..............................................................................................................................70
begin().......................................................................................................................70
end( ) ........................................................................................................................71
available( ).................................................................................................................71
read( )........................................................................................................................73
flush( )........................................................................................................................73
print( )........................................................................................................................74
println( ).....................................................................................................................75
write( )........................................................................................................................76
79
Gli autori autorizzano l'uso del documento e la sua divulgazione a fini educativi e non a
scopo di lucro.
Gli autori non si assumono alcuna responsabilità per danni diretti o indiretti provocati
dall'utilizzo integrale o parziale dei contenuti presenti nel manuale.
Gli autori ringraziano quanti, con segnalazioni di errori e suggerimenti, permetteranno di
migliorare le loro pubblicazioni.
Per comunicazioni dirette con gli autori:
80