I2C Communications Part 1-Arduino a Arduino

Introduzione

Le comunicazioni I2C sono diventate il metodo de facto di comunicazione tra microcontrollori, microcomputer e una varietà di circuiti integrati e sensori. È stato intorno dal 1982 ed è stato originariamente sviluppato per l’uso in ricevitori televisivi.

Anche se abbiamo usato molti sensori e display I2C in articoli precedenti non abbiamo effettivamente esaminato come funziona I2C e come può essere utilizzato per comunicare tra microcontrollori.

Oggi lo correggeremo e impareremo di più su I2C. Vedremo anche come può essere usato per scambiare informazioni tra due Arduino e come può essere usato per consentire a un Arduino di controllarne un altro.

I2C Parte 1-Utilizzando 2 Arduino

Questo sarà il primo di quattro articoli su I2C. Negli articoli futuri vedremo come possiamo costruire i nostri dispositivi I2C, come interfacciare un Raspberry Pi e un Arduino usando I2C e come fare alcune configurazioni I2C avanzate, incluso l’utilizzo di più master su un bus I2C.

Cominciamo!

Comunicazioni I2C

I2C è un protocollo seriale utilizzato su un’interfaccia a 2 fili a bassa velocità. È stato originariamente sviluppato da Phillips nel 1982 per consentire ai circuiti integrati all’interno dei ricevitori televisivi di comunicare tra loro.

I tempi sono cambiati, Phillips è ora NXP e I2C è diventato uno standard di comunicazione che è supportato da quasi tutti i principali produttori di semiconduttori.

I2C è l’abbreviazione di “Inter-Integrated Circuit”. È anche chiamato “IIC”o ” I squared C”.

Usi e limitazioni

I2C viene utilizzato con microcontrollori come Arduino e con microcomputer come Raspberry Pi. Molti display e sensori si interfacciano con il loro controller host utilizzando I2C.

I2C ha tuttavia diverse limitazioni. Non è particolarmente veloce, anche se per la maggior parte dei suoi usi previsti è abbastanza veloce.

I2C può essere utilizzato solo su brevi distanze, dopo tutto, è stato originariamente pensato per comunicare tra circuiti integrati sullo stesso circuito stampato. La distanza massima di trasmissione affidabile diminuisce all’aumentare della velocità, alla velocità più lenta (100 Kbaud o una frequenza di clock di 100 kHz) la distanza massima è di circa un metro.

Velocità I2C

Il bus I2C originale aveva una velocità massima di 100 kHz. Le applicazioni più comuni utilizzano ancora questa velocità, in quanto è abbastanza sufficiente per trasferire dati da sensori e display semplici.

I2C e ha alcune modalità di velocità più elevate. Non tutti i dispositivi I2C supportano queste modalità:

  • Modalità veloce-Questa ha una velocità massima di clock di 400 kHz.
  • Modalità Hi-Speed – Una frequenza di clock massima di 3,4 MHz
  • Modalità Ultra Veloce – Frequenza di clock massima di 5 MHz

Su un bus I2C è il master che determina la velocità di clock.

Come funziona I2C

Un bus I2C ha due segnali, insieme a una connessione di alimentazione e terra.

Comunicazioni bus I2C

Le due linee di segnale sono le seguenti:

  • SDA – Questa è la linea dati bidirezionale.
  • SCL-Questo è il segnale di clock.

Ci sono due resistori pull-up collegati a ciascuna linea di segnale, tirano il bus fino alla tensione di alimentazione quando è inattivo.

Si noti che la tensione di alimentazione non è standard, può essere di 3,3 o 5 volt. Può anche essere una tensione più bassa per alcune implementazioni I2C ad alta velocità.

Questa differenza nelle tensioni di alimentazione può causare problemi quando si interfacciano dispositivi I2C che utilizzano diversi livelli logici. Discuteremo di questo più in un futuro articolo quando vi mostro come interfacciare un Raspberry Pi (3.logica a 3 volt) con un Arduino Uno (logica a 5 volt).

Esistono due tipi di dispositivi che possono essere interfacciati al bus I2C: Master e Slave.

Il dispositivo Master controlla il bus e fornisce il segnale di clock. Richiede i dati dagli slave individualmente. Ci può essere più di un dispositivo master sul bus, ma solo uno può essere il master attivo in un dato momento.

Ai dispositivi master non è assegnato un indirizzo.

I dispositivi slave hanno un indirizzo e questo indirizzo deve essere univoco sul bus. Usano uno schema di indirizzamento a 7 bit, quindi fino a 128 slave possono essere su un bus I2C. Nella vita reale questa vasta collezione di dispositivi non viene mai utilizzata, è raro vedere oltre una dozzina di dispositivi I2C su un bus.

È stato implementato un nuovo schema di indirizzamento a 10 bit, compatibile con il metodo di indirizzamento a 7 bit esistente.

I dispositivi I2C commerciali sono assegnati indirizzo I2C da NXP, che mantengono le specifiche del bus. Anche se I2C è stato open source dal 2006 c’è una tassa addebitata per ottenere un indirizzo slave da NXP. Non è richiesto alcun costo per i dispositivi master o per i dispositivi che non sono destinati alla produzione commerciale.

Ad alcuni dispositivi I2C vengono assegnati più indirizzi, di solito varianze nei bit di indirizzo inferiori. Questi dispositivi possono essere configurati manualmente per indirizzi diversi, consentendo di utilizzare più dispositivi dello stesso tipo su un singolo bus I2C.

Altri derivati I2C

Ci sono altri bus che sono stati derivati dal bus I2C, e che sono in molti modi compatibili con I2C.

  • TWI-L’interfaccia Twin Wire è praticamente identica al bus I2C. Questo è in realtà il bus che utilizza Arduino, TWI è stato sviluppato quando il bus I2C non era open source e Atmel non voleva rischiare una violazione del nome commerciale. L’unica grande differenza tra TWI e I2C è che TWI non supporta una tecnica avanzata chiamata “clock stretching”.
  • SMBus è un altro bus equivalente I2C, sviluppato da Intel. Come TWI supporta la maggior parte delle funzionalità I2C.

In un prossimo articolo spiegherò come sono strutturati i dati sul bus I2C. Ma ora abbiamo alcune informazioni di base I2C, abbastanza per iniziare a sperimentare.

Arduino Wire Library

Arduino ha una libreria integrata per lavorare con I2C chiamata Wire Library. Rende molto facile comunicare sul bus I2C e può configurare Arduino per diventare un master o uno slave.

La libreria Wire ha diverse funzioni utili per lavorare con I2C.

  • begin() – Questo avvia la libreria e imposta Arduino come master o slave.
  • requestFrom() – Questa funzione viene utilizzata dal master per richiedere dati da uno slave.
  • beginTransmission() – Questa funzione viene utilizzata dal master per inviare dati a uno slave specificato.
  • endTransmission() – Questa funzione viene utilizzata dal master per terminare una trasmissione iniziata con la funzione beginTransmission.
  • write () – Utilizzato da master e slave per inviare dati sul bus I2C.
  • available () – Utilizzato sia da master che slave per determinare il numero di byte nei dati che stanno ricevendo.
  • read () – Legge un byte di dati dal bus I2C.
  • SetClock () – Utilizzato dal master per impostare una specifica frequenza di clock.
  • onReceive () – Utilizzato dallo slave per specificare una funzione che viene chiamata quando i dati vengono ricevuti dal master.
  • onRequest() – Utilizzato dallo slave per specificare una funzione che viene chiamata quando il master ha richiesto dati.

Useremo alcune di queste funzioni nei nostri schizzi.

Connessioni Arduino I2C

Le connessioni SDA e SCL per I2C sono diverse tra i modelli Arduino. Gli esperimenti che sto per mostrarti sono stati fatti usando due Arduino Unos, ma puoi usare altri modelli di Arduino fornendo di cambiare i pin di conseguenza.

Ho messo insieme un grafico per aiutarti a capirlo. Esso comprende alcune schede Arduino comuni, così come alcuni dei chip discreti. I pinout per i chip che elenco (ATTiny e ATmega328P) sono con il pacchetto DIP, non quelli a montaggio superficiale.

Arduino Board or Chip SDA SCL
Uno A4 A5
Mega2560 20 21
Nano A4 A5
Pro Mini A4 A5
Leonardo 2 3
Due (has two I2C) 20 + SDA1 20 + SCL1
ATTiny85 & ATTiny45 5 7
ATmega328P 27 28

Alcuni cloni di Arduino Uno hanno pin SDA e SCL separati e puoi usarli al posto dei due pin analogici se lo desideri. Sono collegati internamente allo stesso posto.

Si noti che l’Arduino Due ha effettivamente due porte I2C.

Anche, essere consapevoli del fatto che ci sono alcuni diagrammi ai collegamenti errati su internet per la Pro Mini. Utilizzare i due pin analogici, A4 e A5, come mostrato nella tabella sopra.

I2C Tra 2 Arduino

Per il nostro primo esperimento ci sarà hoo due Arduino insieme e lo scambio di dati tra di loro. Un Arduino sarà il padrone, l’altro sarà lo schiavo.

Sto usando due Arduino Unos, ma puoi sostituire altri Arduino se non hai due Unos. Utilizzare il grafico precedente per le connessioni.

Collegare 2 Arduino

Ecco come ho collegato i miei due Arduino Unos insieme:

I2C Arduino ad Arduino

È piuttosto un semplice collegamento, in sostanza basta legare il terreno e i due pin I2C insieme.

Una cosa di cui essere consapevoli è che il mio diagramma non mostra l’uso di resistori pull-up, ho scoperto che tutto sembrava funzionare correttamente senza di loro. Tuttavia, si potrebbe desiderare di includerli, soprattutto se si verificano errori o funzionamento intermittente.

Per collegare alcuni resistori pull-up attaccare un paio di resistori 10k alle linee SDA e SCL. Collegare l’altra estremità all’uscita a 5 volt su uno dei Arduino.

Master Demo Sketch

Ecco lo schizzo che verrà utilizzato su Arduino che hai designato come master.

I2C Master Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

/*
I2C Master Demo
i2c-master-demo.ino
Demonstrate use of I2C bus
Master sends character and gets reply from Slave
DroneBot Workshop 2019
https://dronebotworkshop.com
*/
// Include Arduino Wire library for I2C
#include <Wire.h>
// Define Slave I2C Address
#define SLAVE_ADDR 9
// Define Slave answer size
#define ANSWERSIZE 5
void setup() {
// Initialize I2C communications as Master
Wire.begin();
/ /Setup serial monitor
Seriale.begin (9600);
Seriale.println (“I2C Master Demonstration”);
}
void loop () {
delay(50);
Seriale.println (“Scrivi dati su slave”);
// Scrivi un charatre sul filo Slave
.beginTransmission (SLAVE_ADDR);
Filo.scrivi (0);
Filo.endTransmission ();
Seriale.println (“Ricevi dati”);
/ / Leggi la risposta dallo Slave
/ / Leggi 5 caratteri
Filo.requestFrom(SLAVE_ADDR, ANSWERSIZE);
/ /Aggiungi caratteri alla stringa
String response=””;
while (Wire.disponibile()) {
char b = Filo.read();
response + = b;
}
/ /Stampa su monitor seriale
Seriale.println (response);
}

Come per tutti gli schizzi I2C, iniziamo includendo la libreria Wire.

Successivamente definiamo alcune costanti per rappresentare l’indirizzo I2C dello slave e il numero di byte di dati che ci aspettiamo di recuperare da esso.

Nel Setup inizializziamo le comunicazioni I2C come master. Sappiamo che è un master in quanto non esiste un parametro di indirizzo nella funzione begin. Abbiamo anche impostare un monitor seriale e stampare una riga di testo ad esso.

Ora al ciclo.

Iniziamo con un piccolo ritardo, soprattutto per rallentare le cose abbastanza da poter leggere il display sul monitor seriale.

Successivamente usiamo la funzione beginTransmission per inviare dati allo slave. In questo caso i dati che inviamo sono solo un numero zero. Finiamo l’invio con una chiamata alla finefunzione di trasmissione.

Successivamente richiediamo alcuni dati dallo slave utilizzando la funzione requestFrom.

Dopo di che formuliamo una stringa di risposta leggendo i dati, un byte alla volta, dallo slave.

Stampiamo i dettagli di ciò che stiamo facendo e dei dati che riceviamo sul monitor seriale. E poi finiamo il ciclo e rifacciamo tutto da capo.

Slave Demo Sketch

Ora sullo schizzo utilizzato dallo slave.

I2C Slave Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

/*
I2C Slave Demo
i2c-slave-demo.ino
Demonstrate use of I2C bus
Slave receives character from Master and responds
DroneBot Workshop 2019
https://dronebotworkshop.com
*/
// Include Arduino Wire library for I2C
#include <Wire.h>
// Definire Slave I2C Indirizzo
#define SLAVE_ADDR 9
// Definire Slave risposta di dimensione
#define ANSWERSIZE 5
// Definire la stringa di risposta al Master
String risposta = “Ciao”;
void setup() {
// Inizializzazione di comunicazione I2C Slave
Filo.begin (SLAVE_ADDR);
// Funzione da eseguire quando i dati richiesti dal master
Filo.onRequest (requestEvent);
// Funzione da eseguire quando i dati ricevuti dal master
Filo.onReceive (receiveEvent);
/ /Setup Serial Monitor
Seriale.begin (9600);
Seriale.println (“I2C Slave Demonstration”);
}
void receiveEvent () {
// Read while data received
while (0 < Wire.disponibile()) {
byte x = Filo.read ();
}
/ /Stampa su monitor seriale
Seriale.println (“Receive event”);
}
void requestEvent () {
/ / Imposta variabile byte nella dimensione corretta
risposta byte;
/ /Formatta la risposta come array
for (byte i=0;i<ANSWERSIZE;i++) {
response = (byte)answer.charAt (i);
}
// Invia la risposta al filo Master
.write (response, sizeof (response));
// Stampa su Serial Monitor
Serial.println(“Richiesta evento”);
}
void loop() {
// Tempo di ritardo in loop
delay(50);
}

ancora una Volta possiamo iniziare incluso il Filo biblioteca. Come per lo schizzo precedente definiamo anche l’indirizzo I2C per lo slave, così come il numero di byte che stiamo progettando di inviare di nuovo al master.

Successivamente definiamo la stringa che stiamo per inviare di nuovo al master, in questo caso solo la parola “Ciao”. Se si decide di modificare questo, assicurarsi di regolare la costante ANSWERSIZE in entrambi gli schizzi per essere corretta.

Nel Setup inizializziamo la connessione al bus I2C con una funzione begin. Prendi nota del diverso modo in cui lo facciamo, poiché questo è uno slave specifichiamo l’indirizzo I2C che useremo. In questo modo la libreria Wire sa che vogliamo operare in modalità slave.

Ora dobbiamo definire i nomi delle funzioni che chiameremo quando si verificano due eventi: una richiesta di dati ricevuta dal master e i dati ricevuti dal master. Abbiamo anche impostare e stampare sul monitor seriale.

La funzione receiveEvent viene chiamata quando riceviamo dati dal master. In questa funzione leggiamo i dati mentre i dati sono disponibili e li assegniamo a un byte (ricorda, i dati verranno ricevuti un byte alla volta).

La funzione requestEvent viene chiamata ogni volta che riceviamo una richiesta di dati dal master. Dobbiamo inviare la nostra stringa “Ciao” al master. Poiché abbiamo bisogno di inviare i dati un byte alla volta, dividiamo i caratteri in “Hello” in singoli elementi in un array e quindi li inviamo uno per uno.

Riportiamo tutti i nostri progressi in entrambe le funzioni al monitor seriale.

Il ciclo in questo schizzo aggiunge solo un ritardo temporale, che corrisponde a quello utilizzato nello schizzo principale.

Esecuzione degli schizzi demo

Per eseguire questi schizzi è necessario essere in grado di visualizzare il monitor seriale su ogni Arduino. Se si dispone di due computer con l’IDE Arduino installato allora che renderà molto più facile.

I2C Experiment 1

Su Microsoft Windows è possibile aprire due istanze dell’IDE Arduino. Se ciò è fatto è possibile visualizzare entrambi i monitor seriali side-by-side sullo stesso schermo.

In alternativa, è possibile utilizzare un computer e accendere il secondo Arduino con il proprio alimentatore. Dovresti cambiare il computer e l’alimentazione tra i due Arduino. In questo modo potresti monitorare entrambi gli schermi uno per uno.

Arduino Remote Utilizzando I2C

Nella prossima dimostrazione agganceremo un potenziometro al master Arduino e un LED allo slave. Useremo il potenziometro per controllare la velocità di lampeggio del LED.

Questa è un’altra semplice dimostrazione, puoi basarti su di essa per creare qualcosa di più pratico.

Remote Demo Hookup

Ecco come questo esperimento è messo insieme.

I2C Arduino Control

Si tratta essenzialmente dello stesso collegamento del precedente esperimento, con l’aggiunta del potenziometro sul master e del LED sullo slave.

Si noti che il LED sullo slave è stato collegato al pin 13. Poiché Arduino Uno ha un LED integrato sul pin 13, è possibile eliminare il LED e la sua resistenza di caduta, se lo si desidera.

Le osservazioni sui resistori pull-up si applicano anche a questo collegamento.

Remote Demo Master Sketch

Lo schizzo per il lato master di questo esperimento è molto semplice, in qualche modo il lato I2C è ancora più semplice di quello utilizzato nella prima dimostrazione. Questo perché stiamo solo inviando dati allo slave e non ci aspettiamo di ottenere indietro.

I2C Master con Potenziometro

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

/*
I2C Master Control Demo
i2c-master-demo-di controllo.ino
Demonstrate use of I2C bus
Master sends potentimeter position data
DroneBot Workshop 2019
https://dronebotworkshop.com
*/
// Include Arduino Wire library for I2C
#include <Wire.h>
// Define Slave I2C Address
#define SLAVE_ADDR 9
// Analog pin for potentiometer
int analogPin = 0;
// Integer to hold potentiometer value
int val = 0;
void setup () {
/ /Inizializza le comunicazioni I2C come filo Master
.begin();
}
void loop () {
delay (50);
/ / Read pot valore
/ / Mappa a gamma di 1-255 per flash rate
val = map(analogRead (analogPin), 0, 1023, 255, 1);
/ / Scrivi un charatre sul filo Slave
.beginTransmission (SLAVE_ADDR);
Filo.scrivi (val);
Filo.endTransmission();
}

Come sempre abbiamo bisogno di includere la libreria Filo all’inizio dello schizzo. Definiremo anche una costante per tenere l’indirizzo slave.

Poiché stiamo usando un potenziometro dovremo definire sia il pin a cui è collegato che una variabile per mantenere il suo valore.

Tutto ciò che facciamo nel Setup è inizializzare la connessione I2C come master.

Nel Ciclo leggiamo il valore del potenziometro e lo mappiamo ad un intervallo di 01-255. Dobbiamo farlo poiché stiamo inviando un byte di informazioni e possiamo contenere solo questi molti valori in un singolo byte.

Si noti che invertiamo la sequenza di numerazione nella funzione Mappa Arduino, questo viene fatto in modo che il sistema si comporti nel modo in cui ci aspettiamo che – ruotando il potenziometro a destra aumenta la velocità di flash. Come il” flash rate ” è specificato da un ritardo di tempo un numero maggiore di essere inviato sarà equiparare ad un più lungo flash rate.

Si noti inoltre che non inviamo il valore 0, che terrebbe semplicemente il LED in uno stato. Abbiamo impostato il nostro intervallo per terminare a 1 invece.

Ora è solo una questione di inviare il byte allo slave e ripetere di nuovo il ciclo.

Remote Demo Ricevere Schizzo

Il lato slave ha bisogno di ricevere i dati dal master e usarlo per lampeggiare il LED.

I2C Slave con LED

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

/*
I2C Slave Controllo Demo
i2c slave-demo-di controllo.ino
Demonstrate use of I2C bus
Receives potentimeter position data
Controls LED blink rate
DroneBot Workshop 2019
https://dronebotworkshop.com
*/
// Include Arduino Wire library for I2C
#include <Wire.h>
// Define Slave I2C Address
#define SLAVE_ADDR 9
// Define LED Pin
int LED = 13;
// Variable for received data
int rd;
// Variable for blink rate
int br;
void setup () {
pinMode(LED, OUTPUT);
/ /Inizializza le comunicazioni I2C come filo slave
.begin (SLAVE_ADDR);
// Funzione da eseguire quando i dati ricevuti dal master
Filo.onReceive (receiveEvent);
// Setup Serial Monitor
Seriale.begin (9600);
Seriale.println (“I2C Slave Demonstration”);
}
void receiveEvent () {
// leggere un carattere dal I2C
rd = Filo.read ();
/ /Stampa il valore dei dati in entrata
Seriale.println(rd);
}
void loop() {
delay(50);
// Calcolare blink valore
br = map(rd, 1, 255, 100, 2000);
digitalWrite(LED, HIGH);
ritardo(br);
digitalWrite(LED, LOW);
ritardo(br);
}

iniziamo con il solito inserimento del Filo biblioteca, oltre a definire l’indirizzo dello slave. Definiamo anche un pin per il LED.

Sono definite un paio di variabili aggiuntive, una che contiene i dati ricevuti mentre l’altra porta il valore di ritardo temporale per la frequenza di lampeggio.

Nel Setup impostiamo il pin I/O per il LED come uscita e inizializziamo il bus I2C. Mentre usiamo l’indirizzo slave nella funzione begin, la libreria Wire sa che stiamo agendo come slave.

Abbiamo solo bisogno di definire una funzione onReceive, a differenza dell’ultima demo non ci aspettiamo alcuna richiesta dal master. Abbiamo anche impostare e stampare sul monitor seriale, useremo il monitor per visualizzare i dati in arrivo.

La funzione receiveEvent legge i dati in entrata e li assegna alla variabile I. Stampa anche il valore sul monitor seriale.

Infine, nel Ciclo usiamo i dati in ingresso per lampeggiare il LED. Ancora una volta usiamo la funzione Mappa per ottenere questo risultato, cambiando i valori in entrata di 1-255 in un intervallo più ampio. Si può sperimentare con la modifica di questo intervallo per rendere il LED lampeggia più veloce o più lento, se lo si desidera.

Le ultime dichiarazioni sono essenzialmente lo schizzo di Arduino Blink sotto mentite spoglie! Accendiamo e spegniamo il LED per un periodo di tempo che abbiamo determinato nell’ultimo passaggio.

E poi ripetiamo il ciclo.

Esecuzione della demo remota

Caricare il codice e alimentare entrambi Arduino. È possibile utilizzare il monitor seriale sullo slave Arduino per visualizzare i dati in entrata.

I2C Experiment 2

Ruotando il potenziometro dovrebbe ora variare la frequenza di lampeggio del LED sullo slave.

Conclusione

Questo conclude il nostro primo sguardo dettagliato a I2C. Nella prossima puntata, impareremo di più sulla struttura dei dati che vengono scambiati. Prenderemo anche un sensore normale e lo trasformeremo in un sensore I2C.

Felice di comunicare!

Risorse

Schizzi – Tutti gli schizzi I2C utilizzati in questo articolo.

I2C informazioni – le Informazioni relative al protocollo I2C

I2C Comunicazioni Parte 1 – Arduino di Arduino
Sommario
I2C Comunicazioni Parte 1 - Arduino di Arduino
Nome
I2C Comunicazioni Parte 1 – Arduino di Arduino
Descrizione
In questa prima parte di una serie di articoli su I2C si impara cosa I2C è. Vedrai anche come la libreria Arduino Wire rende le comunicazioni su I2C molto semplici.
Autore
DroneBot Workshop
il Nome dell’Editore
DroneBot Workshop
Editore Logo
DroneBot Workshop

Taggati su: Arduino Tutorial

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *