Demoboard ESP32: altre applicazioni per chiudere la panoramica (parte 3)

Chiudiamo la panoramica sulla scheda di prototipazione basata sul popolare modulo WiFi, con ulteriori applicazioni. Terza puntata.

Nelle due puntate precedenti abbiamo introdotto la demoboard per il famoso e diffusissimo SoC ESP32 della Espressif, che nello specifico รจ montato a bordo di una scheda con ESP32 commercializzata da www.futurashop.it con il codice YB555. Oltre ad avervi proposto alcuni sketch scritti da noi per introdurvi nel mondo dello sviluppo con questo hardware, in ottica IoT; abbiamo descritto nel dettaglio firmware e creato degli esempi che abbiamo iniziato a presentarvi nella prima e nella seconda puntata. Adesso proseguiamo su questa strada proponendo gli ultimi esempi applicativi che utilizzano lโ€™hardware di bordo e i moduli collegabili esternamente tramite gli appositi connettori. Nello specifico andiamo a utilizzare questi componenti di bordo e moduli esterni:

  • pulsanti UP, DOWN, LEFT, RIGHT, OK;
  • Servomotore;
  • Display OLED 0,96โ€;
  • Relรฉ 5V (RL1);
  • LED rosso (LD1);
  • Led verde (LD2).

Ricordiamo che il cuore della demoboard รจ la scheda di sviluppo e prototipazione YB555 basata sullโ€™ESP32 (ESP-WROOM-32) che integra un Wi-Fi 802.11 b/g/n, un Bluetooth dual-mode (classico e BLE) e 25 GPIO. Supporta una velocitร  di trasmissione dati fino a 150 Mbps, ha una potenza di uscita inโ€™antenna di 20,5 dBm e unconsumo in modalitร  sleep di soli 5 ยตA.

Interazione LED e PULSANTI

Iniziamo con il vedere unโ€™applicazione nella quale utilizziamo i pulsanti a bordo della scheda e ne visualizziamo la condizione sul display OLED on-board (cod. OLED096C oppure cod. OLEDGVSCSD reperibili on-line su www.futurashop.it); questo esempio applicativo fornisce unโ€™idea di come si possono utilizzare e integrare i pulsanti in unโ€™applicazione vera e propria, ottenendo un feedback sul display oppure determinate azioni.

Lo sketch da caricare in questo caso si chiama OLED_Pulsanti.ino e una volta mandato in esecuzione sulla scheda ATmega2560 che governa la demoboard, sul display viene indicato di volta in volta quale pulsante รจ stato premuto fra quelli disposti a joystick, ossia UP, DOWN, LEFT, RIGHT e OK (P1, P2, P3, P4, P5). Inoltre il codice di esempio permette di associare la pressione di uno dei predetti pulsanti allโ€™accensione dei LED a bordo della scheda; per lโ€™esattezza, se viene premuto LEFT o RIGHT si accenderร  il LED verde (LD2), mentre se si preme UP o DOWN verrร  comandata lโ€™accensione del LED rosso (LD1). Nel caso venga premuto il pulsante OK si accenderanno entrambi i LED.

Questa applicazione e il codice che segue, proposto nel Listato 1, possono essere integrate in altre per ottenere un modulo di gestione dei pulsanti e per collegare i relativi input a determinate azioni, che possono essere non solo quelle descritte, ma anche lโ€™attivazione di altre uscite, non ultima quella a relรฉ.

Per lโ€™utilizzo dello sketch dovete copiare la cartella โ€œlibrariesโ€ che si trova negli esempi scaricabili dal nostro sito www.elettronicain.it fra i file di questo numero della rivista, sotto โ€œ/Documentiโ€/Arduinoโ€, quindi aprire lโ€™IDE di Arduino e caricare il codice di esempio disponibile nella cartella โ€œOLED_Pulsanti.

La sezione pulsanti e LED utilizzata nellโ€™esempio

Listato 1

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>



#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED display height, in pixels



// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

// The pins for I2C are defined by the Wire-library. 

// On an arduino UNO: A4(SDA), A5(SCL)

// On an arduino MEGA 2560: 20(SDA), 21(SCL)

// On an arduino LEONARDO: 2(SDA), 3(SCL), ...

#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)

#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);



#define NUMFLAKES 10 // Number of snowflakes in the animation example



#define LOGO_HEIGHT 16

#define LOGO_WIDTH 16



const int P_UP = 23;

const int P_DOWN = 4;

const int P_LEFT = 16;

const int P_RIGHT = 17;

const int P_OK = 5;

const int LEDV = 26;

const int LEDR = 25;



void setup() {

Serial.begin(9600);



// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally

if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {

Serial.println(F(โ€œSSD1306 allocation failedโ€));

for(;;); // Donโ€™t proceed, loop forever

}



// Show initial display buffer contents on the screen --

// the library initializes this with an Adafruit splash screen.

display.display();

delay(2000); // Pause for 2 seconds



// Clear the buffer

display.clearDisplay();

display.setTextSize(2); // Draw 2X-scale text

display.setTextColor(SSD1306_WHITE);

display.setCursor(5, 0);

display.print(โ€œ** Test **โ€);

display.setCursor(20, 30);

display.print(โ€œ PUSH โ€œ);



// Show the display buffer on the screen. You MUST call display() after

// drawing commands to make them visible on screen!

display.display();

delay(2000);

// display.display() is NOT necessary after every single drawing command,

// unless thatโ€™s what you want...rather, you can batch up a bunch of

// drawing operations and then update the screen all at once by calling

// display.display(). These examples demonstrate both approaches...





/*

// Invert and restore display, pausing in-between

display.invertDisplay(true);

delay(1000);

display.invertDisplay(false);

delay(1000);

*/



pinMode(P_UP, INPUT_PULLUP);

pinMode(P_DOWN, INPUT_PULLUP);

pinMode(P_LEFT, INPUT_PULLUP);

pinMode(P_RIGHT, INPUT_PULLUP);

pinMode(P_OK, INPUT_PULLUP);

pinMode(LEDV, OUTPUT);

pinMode(LEDR, OUTPUT);

}



void loop() 

{

display.clearDisplay();

display.setTextSize(2); // Draw 2X-scale text

display.setTextColor(SSD1306_WHITE);

switch (Ctrl_Push()) 

{

case 1:

Serial.println(โ€œPush UPโ€);

display.setCursor(50, 30);

display.print(โ€œUPโ€);

digitalWrite(LEDR,HIGH);

break;

case 2:

Serial.println(โ€œPush DOWNโ€);

display.setCursor(40, 30);

display.print(โ€œDOWNโ€);

digitalWrite(LEDR,HIGH);

break;

case 3:

Serial.println(โ€œPush LEFTโ€);

display.setCursor(40, 30);

display.print(โ€œLEFTโ€);

digitalWrite(LEDV,HIGH);

break;

case 4:

Serial.println(โ€œPush RIGHTโ€);

display.setCursor(40, 30);

display.print(โ€œRIGHTโ€);

digitalWrite(LEDV,HIGH);

break;

case 5:

Serial.println(โ€œPush OKโ€);

display.setCursor(50, 30);

display.print(โ€œOKโ€);

digitalWrite(LEDR,HIGH);

digitalWrite(LEDV,HIGH);

break;

default:

display.setCursor(40, 30);

display.print(โ€œ----โ€);

digitalWrite(LEDV,LOW);

digitalWrite(LEDR,LOW);

break;



}



display.display();

delay(500);

}



int Ctrl_Push()

{

int push = 0;

if (digitalRead(P_UP)==LOW) push = 1;

if (digitalRead(P_DOWN)==LOW) push = 2;

if (digitalRead(P_LEFT)==LOW) push = 3;

if (digitalRead(P_RIGHT)==LOW) push = 4;

if (digitalRead(P_OK)==LOW) push = 5;

return push;

}

Controllo Servocomandi

Passiamo adesso a un secondo esempio applicativo che รจ molto interessante perchรฉ riguarda la gestione dei servo analogici (da modellismo, robotica ecc.) attraverso la nostra demoboard; per implementarla utilizziamo lโ€™uscita dedicata ai servocomandi, che sul circuito stampato รจ quella siglata CNU11, a tre poli: S (1) 5V (2) e GND (3). Si tratta della connessione standard per i connettori a passo 2,54 mm utilizzati nei servo, come ad esempio quello reperibile presso la Futura Elettronica (www.futurashop.it) con il codice prodotto SERVO206, con coppia di 1,5kg, rotazione: 160ยฐ, velocitร  a 4,8V: 0,12 s,/60ยฐ.

Per la gestione dei servo abbiamo scritto lo sketch dโ€™esempio OLED_Servo.ino, il quale, quando viene eseguito, imposta la demoboard in modo che il servocomando collegato al connettore CNU11 ruoterร  prima in senso orario di 180ยฐ e poi di altrettanti gradi in senso antitorario; questo codice esegue quindi un test di funzionamento dei servocomandi, facendo compiere al loro alberino una rotazione completa, divisa in due passaggi che corrispondono alle semirotazioni opposte rispetto alla posizione di riposo (0 gradi). Per lโ€™utilizzo dello sketch dovete copiare la cartella โ€œlibrariesโ€ che si trova negli esempi scaricabili dal nostro sito www.elettronicain.it fra i file di questo numero della rivista, sotto โ€œ/Documentiโ€/Arduinoโ€, quindi aprire lโ€™IDE di Arduino e caricare uno dei codici di esempio disponibili nelle cartelle โ€œOLED_Servoโ€ oppure โ€œServoโ€. Il codice completo per la gestione dei servocomandi รจ riportato nel Listato 2.

Il connettore per collegare i servo

Listato 2

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>



//for Servo

#include <Servo.h>



#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED displdfsfdfsfdsfdsfdsfdsay height, in pixels



// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

// The pins for I2C are defined by the Wire-library. 

// On an arduino UNO: A4(SDA), A5(SCL)

// On an arduino MEGA 2560: 20(SDA), 21(SCL)

// On an arduino LEONARDO: 2(SDA), 3(SCL), ...

#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)

#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);



#define NUMFLAKES 10 // Number of snowflakes in the animation example



#define LOGO_HEIGHT 16

#define LOGO_WIDTH 16



//for Servo

static const int servoPin = 18;

Servo servo1;



void setup() 

{

Serial.begin(9600);



// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally

if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {

Serial.println(F(โ€œSSD1306 allocation failedโ€));

for(;;); // Donโ€™t proceed, loop forever

}



// Show initial display buffer contents on the screen --

// the library initializes this with an Adafruit splash screen.

display.display();

delay(2000); // Pause for 2 seconds



// Clear the buffer

display.clearDisplay();

display.setTextSize(2); // Draw 2X-scale text

display.setTextColor(SSD1306_WHITE);

display.setCursor(5, 0);

display.print(โ€œ** Test **โ€);

display.setCursor(10, 30);

display.print(โ€œ Servo โ€œ);



// Show the display buffer on the screen. You MUST call display() after

// drawing commands to make them visible on screen!

display.display();

delay(2000);

// display.display() is NOT necessary after every single drawing command,

// unless thatโ€™s what you want...rather, you can batch up a bunch of

// drawing operations and then update the screen all at once by calling

// display.display(). These examples demonstrate both approaches...





/*

// Invert and restore display, pausing in-between

display.invertDisplay(true);

delay(1000);

display.invertDisplay(false);

delay(1000);

*/

servo1.attach(servoPin);

}



void loop() 

{

for(int posDegrees = 0; posDegrees <= 180; posDegrees++) 

{

servo1.write(posDegrees);

Serial.println(posDegrees);

delay(20);

}



for(int posDegrees = 180; posDegrees >= 0; posDegrees--) 

{

servo1.write(posDegrees);

Serial.println(posDegrees);

delay(20);

}

}

Utilizzo della connessione WiFi

Il modulo ESP32 che governa lโ€™intera demoboard si distingue per una caratteristica: lโ€™avere a bordo la connessione WiFi ed รจ questa la ragione per cui lโ€™abbiamo scelta: avere a bordo una connettivitร  per lโ€™accesso a Internet e per affacciare alla Rete le nostre applicazioni, in perfetta ottica IoT.

Per quello che riguarda la sezione ricetrasmittente WiFi, opera in un range di frequenza compreso fra 2,4 GHz e 2,5 GHz e le sue caratteristiche tecniche principali sono le seguenti:

  • conformitร  IEEE 802.11 b/g/n HT40;
  • stack in banda base e LwIP;
  • modalitร  Sniffer / Station / SoftAP e Wi-Fi direct mode;
  • massimo data-rate di 150 Mbps@11n HT40, 72 Mbps@11n HT20, 54 Mbps@11g e 11 Mbps@11b;
  • massima potenza di trasmissione 19,5 dBm@11b, 16,5 dBm@11g, 15,5 dBm@11n;
  • sensibilitร  in ricezione: -97 dBm.

Il transceiver รจ anche predisposto per supportare le modalitร  di protezione della connessione WEP, WPA/WPA2 PSK/Enterprise e la crittografia con accelerazione hardware AES / SHA2 / ECC / RSA-4096. Andiamo dunque a vedere lโ€™esempio applicativo che utilizza questo hardware, il quale prevede che il dispositivo si connetterร  alla propria rete WiFi per eseguire un test di connettivitร .

A connessione avvenuta, verrร  mostrato lโ€™indirizzo IP assegnato al modulo ESP sul display. Al termine il modulo rimarrร  in attesa di una connessione da parte di un client interno alla rete, sulla porta TCP 8088. A connessione avvenuta un messaggio fornirร  tale informazione e ogni carattere scritto sul terminale del client verrร  mostrato sul display, nei limiti di capienza del display. Se a connessione avvenuta si preme uno dei cinque pulsanti a bordo della scheda, il client riceverร  sul terminale lโ€™indicazione del pulsante premuto.

Lo sketch di test si chiama OLED_WiFi.ino e si trova sotto la cartella degli esempi, ovvero sotto โ€œ/Documentiโ€/Arduinoโ€; aprite lโ€™IDE di Arduino e caricate lo sketch, quindi andate a modificare le variabili โ€œapnโ€ e โ€œssidโ€ con i parametri della propria rete, perchรฉ queste ultime avranno parametri generici in quanto non possiamo sapere a quale rete il codice sarร  applicato.

In particolare, nel codice di esempio, che vedete riportato nel Listato 3, dovete modificare le righe seguenti:

const char* ssid = โ€œNOME APNโ€;

const char* password = โ€œPASSWORD APNโ€;

inserendo al posto del testo virgolettato NOME APN il nome del vostro access point e al posto di PASSWORD APN la password (o passkey) che utilizzate per lโ€™accesso alla rete WiFi.

Il servocomando SERVO206

Listato 3

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>



//for WiFi

#include <WiFi.h>





#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED displdfsfdfsfdsfdsfdsfdsay height, in pixels



// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

// The pins for I2C are defined by the Wire-library. 

// On an arduino UNO: A4(SDA), A5(SCL)

// On an arduino MEGA 2560: 20(SDA), 21(SCL)

// On an arduino LEONARDO: 2(SDA), 3(SCL), ...

#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)

#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);



#define NUMFLAKES 10 // Number of snowflakes in the animation example



#define LOGO_HEIGHT 16

#define LOGO_WIDTH 16



//for WiFi

const char* ssid = โ€œNOME APNโ€;

const char* password = โ€œPASSWORD APNโ€;

/* create a server and listen on port 8088 */

WiFiServer server(8088);



const int P_UP = 23;

const int P_DOWN = 4;

const int P_LEFT = 16;

const int P_RIGHT = 17;

const int P_OK = 5;

const int LEDV = 26;

const int LEDR = 25;





void setup() {

Serial.begin(9600);



// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally

if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {

Serial.println(F(โ€œSSD1306 allocation failedโ€));

for(;;); // Donโ€™t proceed, loop forever

}



// Show initial display buffer contents on the screen --

// the library initializes this with an Adafruit splash screen.

display.display();

delay(2000); // Pause for 2 seconds



// Clear the buffer

display.clearDisplay();

display.setTextSize(2); // Draw 2X-scale text

display.setTextColor(SSD1306_WHITE);

display.setCursor(5, 0);

display.print(โ€œ** Test **โ€);

display.setCursor(5, 30);

display.print(โ€œ WiFi โ€œ);



// Show the display buffer on the screen. You MUST call display() after

// drawing commands to make them visible on screen!

display.display();

delay(2000);

// display.display() is NOT necessary after every single drawing command,

// unless thatโ€™s what you want...rather, you can batch up a bunch of

// drawing operations and then update the screen all at once by calling

// display.display(). These examples demonstrate both approaches...





/*

// Invert and restore display, pausing in-between

display.invertDisplay(true);

delay(1000);

display.invertDisplay(false);

delay(1000);

*/

pinMode(P_UP,INPUT_PULLUP);

pinMode(P_DOWN,INPUT_PULLUP);

pinMode(P_RIGHT,INPUT_PULLUP);

pinMode(P_LEFT,INPUT_PULLUP);

pinMode(P_OK,INPUT_PULLUP);





Serial.begin(9600);

OLED_Message(โ€œConnecting to โ€œ,ssid);

Serial.print(โ€œConnecting to โ€œ);

Serial.println(ssid);

/* connecting to WiFi */

WiFi.begin(ssid, password);

/*wait until ESP32 connect to WiFi*/

while (WiFi.status() != WL_CONNECTED) 

{

delay(500);

Serial.print(โ€œ.โ€);

}

Serial.println(โ€œโ€);

Serial.println(โ€œWiFi connected with IP address: โ€œ);

String testo = WiFi.localIP().toString();

OLED_Message(โ€œWiFi connectedโ€,testo); 

Serial.println(WiFi.localIP());

delay(2000);

/* start Server */

server.begin();

}



void loop() 

{

/* listen for client */

WiFiClient client = server.available(); 

uint8_t data[30]; 

if (client) 

{ 

OLED_Message(โ€œClient Connectedโ€,โ€โ€);

Serial.println(โ€œnew clientโ€); 

display.setCursor(0, 20); 

/* check client is connected */ 

while (client.connected()) 

{ 

switch (Ctrl_Push()) 

{

case 1:

Serial.print(โ€œPush UPโ€); 

client.write(โ€œ\nUPโ€); 

break;

case 2:

Serial.println(โ€œPush DOWNโ€);

client.write(โ€œ\nDOWNโ€); 

break;

case 3:

Serial.println(โ€œPush LEFTโ€);

client.write(โ€œ\nLEFTโ€); 

break;

case 4:

Serial.println(โ€œPush RIGHTโ€);

client.write(โ€œ\nRIGHTโ€); 

break;

case 5:

Serial.println(โ€œPush OKโ€);

client.write(โ€œ\nOKโ€); 

break;

default:

break;



}

Attendi_Push();

if (client.available()) 

{

int len = client.read(data, 30);

if(len < 30)

{

data[len] = โ€˜\0โ€™; 

}else 

{

data[30] = โ€˜\0โ€™;

} 

Serial.print(โ€œclient sent: โ€œ); 

Serial.println((char *)data); 

display.print((char *)data);

display.display(); 

}

} 

}

OLED_Message(โ€œClient Disconnectedโ€,โ€โ€);

}



void OLED_Message(String text_display1, 

String text_display2)

{

int lunghezza = 0;

display.clearDisplay();

display.setTextSize(1); 

// Draw 2X-scale text

display.setTextColor(SSD1306_WHITE);

display.setCursor(0, 0);

lunghezza = text_display1.length();

lunghezza=21-lunghezza;

lunghezza=lunghezza/2;

for (int i=0;i<lunghezza;i=i+1)

{

display.print(โ€œ โ€œ); 

}

display.print(text_display1);

display.setCursor(0, 20);

lunghezza = text_display2.length();

lunghezza=21-lunghezza;

lunghezza=lunghezza/2;

for (int i=0;i<lunghezza;i=i+1)

{

display.print(โ€œ โ€œ); 

}

display.print(text_display2);

display.display(); 

delay(1500);

}



int Ctrl_Push()

{

int push = 0;

if (digitalRead(P_UP)==LOW) push = 1;

if (digitalRead(P_DOWN)==LOW) push = 2;

if (digitalRead(P_LEFT)==LOW) push = 3;

if (digitalRead(P_RIGHT)==LOW) push = 4;

if (digitalRead(P_OK)==LOW) push = 5; 

return push;

}



void Attendi_Push()

{ 

while (( digitalRead(P_UP)==LOW) || 

(digitalRead(P_DOWN)==LOW) || 

(digitalRead(P_LEFT)==LOW) || 

(digitalRead(P_RIGHT)==LOW) || 

(digitalRead(P_OK)==LOW)) delay(10);

}

Scansione del bus IยฒC

Lโ€™ultimo esempio applicativo che proponiamo รจ in realtร  unโ€™utility, giacchรฉ il relativo codice permette di interrogare il bus IยฒC per rilevare cosa รจ affacciato ad esso e fornire sul display o tramite Serial Monitor lโ€™indirizzo di tutti i dispositivi collegati ad esso.

Come vedete nel Listato 4, il codice fa uso della libreria wire.h, che permette di comunicare con i dispositivi IยฒC/TWI attraverso le due linee SDA (linea dati) e SCL (Serial Clock) che si trovano sia a bordo scheda, sia riportate sul connettore di espansione siglato I2C, che vale per i dispositivi connessi al bus esternamente alla scheda.

A partire da Arduino 1.0, la libreria si รจ allineata alle altre librerie di lettura/scrittura; per questo motivo, le funzioni send() e receive() originarie sono state sostituite con read() e write(). Le versioni recenti della libreria Wire possono utilizzare i timeout per prevenire un blocco a fronte di determinati problemi sul bus, ma questi non sono abilitati per impostazione predefinita nelle versioni correnti (si consiglia di abilitare sempre questi timeout quando si utilizza la libreria Wire). Caricate dunque lโ€™ultima versione della libreria.

Il transceiver WiFi del modulo ESP32 รจ una periferica utilizzabile a sรจ

Listato 4

#include <Wire.h>





void setup()

{

Wire.begin();



Serial.begin(9600);

while (!Serial); 

Serial.println(โ€œ\nI2C Scannerโ€);

}





void loop()

{

byte error, address;

int nDevices;

address=0x76;



Serial.println(โ€œScanning...โ€);



nDevices = 0;

for(address = 1; address < 127; address++ )

{

// The i2c_scanner uses the return value of

// the Write.endTransmisstion to see if

// a device did acknowledge to the address.

Wire.beginTransmission(address);

error = Wire.endTransmission();



if (error == 0)

{

Serial.print(โ€œI2C device found at address 0xโ€);

if (address<16)

Serial.print(โ€œ0โ€);

Serial.print(address,HEX);

Serial.println(โ€œ !โ€);



nDevices++;

}

else if (error==4)

{

Serial.print(โ€œUnknown error at address 0xโ€);

if (address<16)

Serial.print(โ€œ0โ€);

Serial.println(address,HEX);

} 

}

if (nDevices == 0)

Serial.println(โ€œNo I2C devices found\nโ€);

else

Serial.println(โ€œdone\nโ€);



delay(5000); // wait 5 seconds for next scan

}

Conclusioni

Bene, con questo esempio di utilizzo terminiamo la panoramica sulla demoboard ESP32, che in tre articoli vi ha presentato le possibilitร  di utilizzo dellโ€™hardware, seppure non tutte quelle possibili, sia a bordo che connesso tramite i connettori dedicati. Ogni esempio รจ stato corredato di sketch per implementarlo e testarlo. Ora lasciamo a voi e alla vostra inventiva lโ€™implementazioni di ulteriori applicazioni, che testerete e debuggerete sulla demoboard, per poi uscire dalla fase prototipale e realizzarle in maniera definitiva. Buon lavoro!

Lascia un commento

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

Menu