ESP32: ESP32S2mini V1.0

Questa piccola schedina di appena 3,5×2,5 cm ospita a bordo un microcontrollore ESP32 equipaggiato con 4 MB di flash per i firmware, un processore ESP32-S2FN4R2 con clock a 240Mhz, 2MB di SRAM ,un interfaccia WiFi a 2,4Ghz e BlueTooth e ben 27 GPIO settabili .

PIN OUT

Tutti i pin GPIO possono essere programmati come ADC, DAC, I2C, SPI, UART.

La programmazione può essere eseguita tramite linguaggi :

  • Arduino IDE
  • MicroPython
  • CircuitPython

Programmazione tramite Arduino IDE

La programmazione tramite ide Arduino e’ possibile caricando le librerie per la gestione schede (sulle impostazioni dell’ide) inserendo il link :

http://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json,https://dl.espressif.com/dl/package_esp32_index.json

Selezionando poi nel menu Strumenti->Scheda->ESP32 Arduino->ESP32S2 Dev Module

Collegando la scheda non vedremo accendersi nessun led e la porta non comparira’ nell’elenco del menu Strumenti->porta come se la scheda non venisse riconosciuta.

A questo punto e’ necessario premere, sulla scheda, contemporaneamente i tasti RESET e D per alcuni secondi, poi rilasciare il tasto RESET mantenendo premuto per alcuni secondi il tasto D, ora la porta USB verrà riconosciuta con il nome /dev/ttyACM0.

Adesso possiamo lanciare la compilazione e il caricamento del firmware. Alla fine del caricamento l’ide ci dara’ un errore di reset e ci invitera’ a eseguire un reset hardware della scheda, lanciando cosi il FW caricato. Questo errore e’ stato risolto sulle nuove versioni della scheda.

ATTENZIONE ! Purtroppo non e’ possibile usare la porta USB come uscita seriale, in quanto l’ESP32 quando e’ in modalita’ “running”, non gestisce la USB integrata, pertanto se abbiamo necessita di eseguire il debug o comunque usare delle comunicazioni seriali, dobbiamo attivare una UART convertendola in RS232 o RS485, tramite interfacce UART->RSxxx a 3,3V collegate a due GPIO o tramite translatori di livelli a delle interfaccie TTL->RSxxx

Alimentazione del Modulo

L’alimentazione del modulo può avvenire tramite la porta USB oppure tramite il piedino VBUS, l’alimentazione tramite VBUS deve essere compresa tra 3,3 e 6Vdc massimo.

Attenzione gli ingressi vanno sempre pilotati a 3,3 massimo altrimenti si rischia la “frittura” del chip

Letture ingressi analogici

La lettura analogia degli ingressi non e’ lineare da 0 a 3,3V ma si può raggiungere una buona linearità delle letture nell’intervallo 0.10 -2.50Vdc, pertanto per una lettura precisa di tensioni superiori a 2,5Vdc e’ consigliabile l’uso di un partitore di tensione con resistenze di precisione.

L’esp32-s2 ha i convertitori AD a 13 bit pertanto la lettura dei pin restituira’ valori da 0 a 8192

ESP-12 utilizzo e programmazione.

Modulo estremamente piccolo di dimensioni (2,4×1,6 cm) ma eccezionale per applicativi IOT, equipaggiato con un processore 32bit a 160Mhz e un modulo WiFI 2,4Ghz capace di trasmettere fino a 25dBm. unico ‘neo’ ha solo un ingresso analogico con tensioni in ingresso da 0 a 1 volt (0-1024). I consumi sono molto ridotti si parla di 70mA in trasmissione (con picchi di 500mA), 20mA con modulo wifi in stand-by, fino a 0,02mA in modalita’ sleep. Come tutta la famiglia ESP l’alimentazione e tutti gli ingressi/uscite, e’ a 3,3Vdc.

Utilizzo.

Non perdiamo troppo tempo con le caratteristiche, volendo le possiamo approfondire leggendo il data sheet che potete scaricare al link in fondo alla pagina, ma passiamo a vedere come utilizzare il modulo nei circuiti.

Innanzi tutto dobbiamo sapere che per far funzionare il modulo nelle varie modalita’, flashing, upload-firmware e normal use, e’ necessario fornire i giusti segnali ad alcuni piedini che sono:

  • RST reset PIN1
  • EN/CH_PD enable PIN3
  • GPIO0 ingresso 0 PIN18
  • GPIO15 ingresso 15 PIN 16

Ne caso dell’utilizzo normale (normal use) del modulo i suddetti pin dovranno essere collegati come da schema.

Caricamento firmware con IDE arduino

Per caricare i firmware utilizzando l’IDE di arduino, possiamo sfruttare un semplicissimo ed economico adattatore USB->TTL, collegando i pin come evidenziato nello schema qui sotto.

Vediamo di seguito come impostare l’ide di arduino per caricare il firmware

E’ buona norma non utilizzare l’eventuale uscita di alimentazione del convertitore USB->TTL per alimentare il modulo durante la programmazione, in quanto potrebbe non fornire abbastanza corrente per l’operazione, ma e’ preferibile fornire l’alimentazione al modulo tramite una fonte esterna, anche perche’ se il modulo non andasse in scaricamento del firmware e’ necessario disalimentare e rialimentare senza scollegare la porta USB.

Data-sheet ESP12F

ESP32 I2C Arduino

In questo articolo vediamo come far comunicare questi due microcontrollori sfruttando il bus I2C.

La famiglia ESP lavora a 3,3V mentre la famiglia Arduino usa i 5V, questa differenza rende complicata la comunicazione tra i due microcontrollori se non andiamo a interporre un adattatore di livelli sulla UART. Il protocollo I2C puo’ lavorare sia a 3,3 che a 5V pertanto useremo questo BUS per la comunicazione tra i due microcontrollori.

img1

SCHEMA ELETTRICO

Nel caso che vedremo andremmo a settare l‘esp32 come Master mentre l’arduino nano verrà impostato come slave. Il protocollo I2C prevede che il master “interroghi” ogni singolo slave e attenda la sua risposta.

L’img1 mostra il semplicissimo schema di collegamento tra le due schede. Per il progetto useremo i pin di default I2C per entrambi ( pin21,22 per ESP e pin A4,A5) che corrispondono rispettivamente SDA linea dati e SCL clock di sincronismo. Il protocollo prevede che il bus abbia la linea SDA a livello logico alto che viene abbassato al momento della comunicazione, il master generera’ il clock (SCL). I due dispositivi devono avere in comune la massa GND.

La comunicazione tra i due device puo avvenire in due modi, nel primo il master invia una richiesta di n byte allo slave senza specificare nulla e lo slave risponde con le istruzioni contenute nella funzione specificata in .onRequest(funzione). Mentre nel secondo caso, il master invia prima dei dati allo slave il quale li elabora tramite la funzione richiamata da .onReceive(funzione) poi il master richiede i dati allo slave.

Vediamo nel dettaglio i due casi con l’ausilio di schemi e codici di esempio.

1° caso

Il master invia una richiesta di nbyte dati allo slave tramite la funzione wire.requestFrom(indirizzo, nbyte) allo slave indirizzo e poi si mette in ascolto per la risposta. Lo slave attiva la funzione onRequest() e risponde al master

– Codice –

Vediamo il codice da inserire nel master:

//ESP32 - I2C master

#include "Wire.h" //libreria I2C

void setup(){
  Serial.begin(9600);
  Wire.begin(); //senza valori significa che e' master
}

void loop(){
  Serial.println("Avvio trasmissione...");
  //contatta lo slave con indirizzo 0x1
  Wire.requestFrom(1,12); //invio richiesta e mi aspetto 12 byte di risposta
  while(Wire.available()){
        //stampo i dati provenienti dal bus
        char c = Wire.read();
        Serial.print(c);
  }
  Serial.println("\n Ricezione completata.");
  delay(2000);
}

e il codice dello slave:

//arduino nano I2C slave

#include "Wire.h" //libreria I2C

int LED = 13; 
int roger = 0;

void setup() {
  pinMode(LED,OUTPUT);
  Wire.begin(1); //inizializzo il BUS e assegno indirizzo 1
  Wire.onRequest(richiestaRicevuta); //imposto la funzione da eseguire su chiamata dal master
}

//funzione richiamata su ricezione dal master
void richiestaRicevuta(){
  digitalWrite(LED, HIGH); // accendo il led on board
  Wire.write("HELLO WORLD!"); //invio la risposta sul bus i2c
  roger = 1; // setto il roger a 1 
}

void loop() {
 if(roger){
  int ritardo = 1000*roger; //calcolo il tempo di accensione
  delay(ritardo);
  digitalWrite(LED, LOW); // spengo il led on board
  roger = 0; // resetto il roger
 }
}

I commenti inseriti nel codice sono sufficienti a capire come lavora. In pratica il Master(esp32) invia sul bus I2C una richiesta allo Slave con indirizzo 1 (arduino nano), il quale arrivata la chiamata, risponde al Master con il messaggio “HELLO WORLD!”. Il master a questo punto rimane in ascolto e riceve i 12 byte che aveva richiesto allo slave stampando i caratteri in ordine di arrivo.

2° caso

In questo caso il master invia prima dei dati verso lo slave, lo slave attiva la funzione onReceive() ed elabora i dati inviati dal master e termina. Subito dopo il master invia una richiesta dati e lo slave attiva la funzione onRequest().

Il codice da inserire nel master

//ESP32 - I2C master

#include "Wire.h" //libreria I2C

String msg ="ita";

void setup(){
  Serial.begin(9600);
  Wire.begin(); //senza valori significa che e' master
}

void loop() {
  
  Serial.print("richiesto messaggio in : ");
  Serial.println(msg);
  //inizia la trasmissione verso lo slave 1
  Wire.beginTransmission(1);
  if(msg == "ita"){
    Wire.write("ita");
    msg="eng";
  } else {
    Wire.write("eng");
    msg = "ita";
  }
  //termina la trasmissione 
  Wire.endTransmission();
  //richiede i dati allo slave
  Wire.requestFrom(1, 3);
  while(Wire.available()){
    char rx = Wire.read();
    Serial.print(rx);
  }
  Serial.println();
   delay(1000);
}

e questo e il codice dello slave

//arduino nano I2C slave

#include "Wire.h" //libreria I2C

int LED = 13; 
int roger = 0;
String rx;

void setup() {
  Serial.begin(9600);
  pinMode(LED,OUTPUT);
  Wire.begin(1); //inizializzo il BUS e assegno indirizzo 1
  Wire.onRequest(datiRichiesti); //imposto la funzione da eseguire su richiesta dati dal master
  Wire.onReceive(datiRicevuti); //imposto la funzione da eseguire su invio dati dal master
}

void loop() {
 
  delay(100);

}

void datiRicevuti(int howMany){
  digitalWrite(LED, HIGH); //accendo led onboard per segnalare la ricezione della richiesta
  //ricevo i dati e li inserisco in un array di caratteri
  char rxbuff[3];
  int i = 0;
  while(Wire.available()){
    rxbuff[i]=Wire.read();
    i++;
  }
  //converto l'arrey di caratteri in una stringa
  rx = String(rxbuff);  
 delay(500);
 digitalWrite(LED, LOW); //spengo il led onboard
}

void datiRichiesti(){
   if(rx == "ita"){
    Wire.write("ITA");
  } else {
    Wire.write("ENG");   
    }
  
}

Anche in questo caso i commenti al codice sono abbastanza chiari ma vediamo lo scopo dell’esempio e il flusso delle informazioni.

Il master richiede allo slave il messaggio alternativamente in lingua italiana o ingelse. Per far cio il master invia allo slave il codice della lingua del messaggio tramite la la sequenza .beginTrasmission() -> .write() -> .endTrasmission() lo slave si accorge che il master gli ha inviato dei dati e quindi innesca la funzione specificata tramite .onReceive(), riceve i dati con .read() e li imagazzina in una variabile globale chiamata rx. A questo punto il master invia una richiesta di dati allo slave il quale prima di inviagliela verifica in che lingua deve rispondere.

Conclusioni

Il bus i2c e’ molto comodo per le comunicazioni tra microprocessori, sensori e altre periferiche che si trovano vicine, infatti il bus non può superare i 2mt altrimenti potrebbero esserci problemi di affidabilità, d’altronde e’ stato studiato per lo scambio di dati su dispositivi alloggiati sulla stessa scheda. Per comunicazioni ad alto raggio ci sono altri bus ( rs485, canbus etc etc)

Programmazione dei DEV-KIT e moduli ESP32/ESP8266

ESP12-ESP8266-nodeMCU
ESP32-ESP-WROOM

Programmazione e Preparazione IDE Arduino

Per poter programmare questi microcontrollori con l’ IDE di Arduino e’ necessario caricare tramite la gestione delle schede la libreria corretta. Aggiungiamo il percorso per caricare il modulo gestore .

File->impostazioni

aggiungiamo le seguenti rige nel campo “URL aggiuntive per il gestore schede”

http://arduino.esp8266.com/stable/package_esp8266com_index.json (per la esp12)

https:///dl.espressif.com/dl/package_esp32_index.json (per la esp32)

Se volessimo inserirle entrambi lo possiamo fare separando le due stringe con una virgola oppure cliccando sull’icona

e inserendo una sotto l’altra le stringhe 

Clicchiamo su OK e riavviamo l’ide.

Troveremo un nuovo elenco di schede disponibili alla scelta sotto il menu Strumenti->Scheda.

Ora siamo pronti per programmarla tramite l’IDE di arduino.