Questa è la prima parte di una serie di progetti collegati tra loro.
In generale la soluzione risultante è composta da più parti che sono:
- Sensori
- "Hub"
- Un server web (compreso un database)
- App (Windows e Android universali)
L'obiettivo è monitorare il mio ambiente a casa. Per questa serie copro 3 aree in cui utilizzo tecnologie diverse per ogni singolo elemento.
Iniziamo con il giardino d'inverno (giardino d'inverno) e il giardino adiacente.
Per questo utilizzo un NodeMCU ESP32, un dispositivo economico incluso
- Bluetooth (BLE è utilizzato in questo caso)
- WiFi (utilizzato per trasferire i dati su un hub diverso e fungere da web server)
- Diversi ingressi analogici (ne uso 5)
- I2C - utilizzato per eseguire un display
- Input tattile: utilizzato come una sorta di pulsanti
Avvicinati a uno: ottieni dati ambientali dal giardino.
Per questo utilizzo un sensore in grado di catturare l'umidità (0-100%) e la temperatura (da -40 a 60 °C). Il sensore che utilizzo è un EE060 con uscita analogica.
Ho scelto questo sensore perché è preciso e robusto, fornendo operazioni di livello industriale anche in ambienti difficili.
Nel mio caso fornisce 0-3V (sono disponibili diverse gamme). Sebbene 0-10 V sia più comune, 0-3 V è una buona scelta perché gli ingressi analogici ESP32 funzionano per un intervallo di 0-3,3 V.
Quindi il sensore scelto può essere utilizzato senza alcun cablaggio aggiuntivo (es. partitore di tensione) collegandolo agli ingressi analogici dell'ESP32.
L'ESP32 può funzionare tra 3,5 e 3,7 V o (utilizzando NodeMCU) a 5 V.
C'è anche un sensore EE060 che può funzionare a 3,6 V ma questo modello ha un'uscita di 0-1 V. Successivamente aggiungerò anche un altro sensore che necessita di almeno 15V ho deciso di scegliere lo 0-3V per avere un range analogico più ampio,
Il modello che scelgo può funzionare a 8-30 V CC - io uso 18 V perché ho un alimentatore adatto a questa tensione.
Ho deciso di alimentare il mio ESP32 tramite la porta USB. Questa porta viene utilizzata anche per caricare schizzi sul dispositivo e per l'output seriale (debug/informativo).
Come sai, un progetto non è mai finito, quindi ho pensato che sarebbe stato utile avere un facile accesso alla porta USB senza dover aprire la custodia.
La mia soluzione è simile a questa:
Questo convertitore prende i miei 18 V e fornisce 5 V tramite una porta USB femmina dove posso collegare il mio ESP32 (modalità di funzionamento normale). Ma sono anche in grado di utilizzare la spina e collegarla a un computer di sviluppo.
Nella parte inferiore della custodia puoi anche vedere il retro del display. L'ho incollato a un piccolo pezzo di plastica e l'ho avvitato alla custodia. Ovviamente avrei potuto usare la colla, ma uso due delle viti (contrassegnate nell'immagine sopra) come pulsanti sensibili al tocco.
Il display nella sua cornice
L'immagine sopra mostra il display con una pellicola protettiva su di esso. Prima di montarlo sulla custodia, l'ho rimosso, invece ho posizionato un pezzo di protezione per lo schermo del cellulare sopra la plastica blu.
Dall'esterno il case ora si presenta così:
La parte grigia in questa immagine mostra un sensore diverso (EE800 - trattato nella parte successiva di questa serie). All'interno della scatola c'è l'ESP32 montato su una tavola di razza.
Diamo un'occhiata a questo:
Puoi vedere i connettori del display (4 pin); qui il VCC (rosso) viene spostato un po' usando il comune plus rail per tenerlo separato dalla porta USB.
Puoi anche vedere i due fili collegati alle viti (pulsanti a sfioramento - blu e verde) e accanto (tre pin lasciati non collegati) sono gli ingressi analogici - due di essi (verde e giallo) sono per l'EE060 utilizzato in questo post. Accanto ad esso ci sono tre analoghi (bianco, grigio, magenta) utilizzati da un sensore trattato nella parte 2 di questa serie.
Puoi anche vedere il cavo USB collegato alla scatola (convertitore DC / DC) che può essere facilmente scollegato e collegato a un PC.
Sulla parte superiore della scatola ci sono i collegamenti al sensore EE060.
Ho usato gli stessi colori delScheda tecnica EE060.
Infine ecco una semplice panoramica del cablaggio. L'ESP32 sull'immagine non è il NodeMCU ESP32 utilizzato: ho posizionato i fili nelle posizioni dei pin corrette.
I pin utilizzati sono:
- VCC 3.3V Rosso (display)
- ADC0 GPIO36 magenta (EE800)
- ADC3 GPIO39 marrone (EE800)
- ADC6 GPIO34 bianco (EE800)
- ADC7 GPIO35 giallo (EE060)
- ADC4 GPIO32 verde (EE060)
- TOUCH7 GPIO27 (vite - pulsante touch)
- TOUCH6 GPIO14 (vite - pulsante touch)
- Filo SCL GPIO22 arancione (display)
- Cavo SDA GPIO21 giallo (display)
- GND nero
Il display
Usandoquesta libreriaè stato molto facile mostrare alcuni valori sullo schermo. Ho deciso di utilizzare lo schermo in tre modalità.
- Spento
- Display meteo (che mostra i dati dal sensore)
- Informazioni di registrazione
Passerò da una modalità all'altra "premendo" le mie viti nella parte inferiore dello schermo.
Per mantenere semplice la logica del programma ho deciso di costruire una sorta di "display virtuale" sopra il display reale. Questo fornisce tre metodi:
- toggleDisplay (se acceso => spento se spento => acceso)
- printLogLine
- printData
Con questo approccio posso semplicemente utilizzare lo schermo nel mio programma senza la necessità di occuparmi di ciò che effettivamente dovrebbe essere visualizzato al momento.
Pulsanti a sfioramento
Esistono due modi per utilizzare i pulsanti a sfioramento. Uno sta interrogando (leggere i valori in un ciclo) l'altro sta usando un interrupt. Scelgo il secondo approccio. Per abilitare un interrupt per tocco devi fornire due parametri. L'indirizzo di un metodo che viene chiamato quando si verifica un evento di tocco e l'altro è una soglia. A seconda dell'ambiente (materiale della custodia, cablaggio, ...) otterrai un valore (per me circa 70) durante la lettura di un input tattile (non toccato).
Quando tocchi il perno (vite) otterrai un valore notevolmente inferiore. Eseguo semplicemente un piccolo campione per verificare i valori. Da quel test scelgo una soglia di 30 per segnalare un buon tocco.
Le routine di interruzione in genere dovrebbero tornare il più velocemente possibile, quindi ho appena impostato un flag lì. Che viene controllato nel ciclo principale - codice semplificato:
void gotTouch1(){flagUno=vero;}void gotTouch2(){flagDue=vero;}touchAttachInterrupt(T7, gotTouch1, 30);touchAttachInterrupt(T6, gotTouch2, 30);
ESP32 e ingresso analogico
L'ingresso analogico dell'ESP32 ha alcune particolarità e uno dei problemi che ho notato era più o meno lo stesso descritto inil primo post qui.
I valori che ho letto sono troppo bassi, almeno nell'intervallo di tensione inferiore. Ho trovato una soluzione di restringimento per questo. La buona notizia è che la deviazione è quasi la stessa su ogni pin ed è anche relativamente lineare.
Quindi, usando un generatore di tensione e un semplice pezzo di codice, ho scoperto una formula che dà risultati piuttosto buoni per le mie esigenze qui.
double DoCalc(int nVal) {doppio dBase = 4100;doppio dFactor = 0,00000004595;doppio dCalcBase = 0,000801;//calcola l'offset al massimodoppio dTmp = dBase - nVal;//moltiplica con il fattore per compensare l'offsetdTmp *= dFactor;//aggiungi la base (non utilizzata nel calcolo dell'offset)dTmp += dCalcBase;return(nVal*dTmp);}
Un altro fatto è chenon puoi usare tutti i pin ADC quando usi il WiFi. Buona fortuna anche qui - abbiamo bisogno solo di 5 pin (2 al momento - 3 nella seconda parte) - sono disponibili su ADC1.
ERA - GATT
Ce ne sono moltiSpecifiche GATT. Uno dei servizi èESS (servizio di rilevamento ambientale)che è perfetto per le nostre esigenze.
Le informazioni fornite nelle pagine collegate sembrano complicate? Lascia che ti spieghi come funziona.
Per prima cosa ho bisogno di un dispositivo (in termini di hardware E software) e di un server che contenga i servizi. L'hardware è la nostra scheda ESP32 e nel codice definisco un dispositivo e un server con 2 righe di codice.
// Avvia il dispositivo BLEBLEDevice::init("ESP32-EE060");// crea il server BLEBLEServer *pServer = BLEDevice::createServer();
Ora questo server può (deve) implementare servizi - Iaggiungere un servizio con l'ID 0x181A.
// crea il servizio BLEBLEService *pService = pServer->createService(BLEUUID((uint16_t)0x181A));
A quel servizio aggiungo due caratteristiche:temperaturaEumidità. Entrambi possono notificare e sono leggibili.
BLECharacteristic outHumidityCharacteristic(BLEUUID((uint16_t)0x2A6F),BLECaratteristica::PROPERTY_READ | BLECaratteristica::PROPERTY_NOTIFY);BLECharacteristic outTemperatureCharacteristic(BLEUUID((uint16_t)0x2A6E),BLECaratteristica::PROPERTY_READ | BLECaratteristica::PROPERTY_NOTIFY);
Per supportare le notifiche, una caratteristica deve implementare una descrizione speciale (scrivibile) in cui un client può memorizzare lo stato della sottoscrizione.
outHumidityCharacteristic.addDescriptor(nuovo BLE2902());outTemperatureCharacteristic.addDescriptor(nuovo BLE2902());
Puoi anche fornire ulteriori descrizioni (alla caratteristica) come portata, unità...
In questo caso utilizzo una descrizione facoltativa, fornendo un testo "leggibile dall'uomo" in modo che un client BLE comune possa visualizzare il valore all'utente.
BLEDescriptor outdoorHumidityDescriptor(BLEUUID((uint16_t)0x2901));BLEDescriptor outdoorTemperatureDescriptor(BLEUUID((uint16_t)0x2901));outdoorHumidityDescriptor.setValue("Umidità da 0 a 100%");outdoorTemperatureDescriptor.setValue("Temperatura -40-60°C");outHumidityCharacteristic.addDescriptor(&outdoorHumidityDescriptor);outTemperatureCharacteristic.addDescriptor(&outdoorTemperatureDescriptor);
Ultimo ma non meno importante, aggiungo i descrittori alle caratteristiche e allego le caratteristiche al servizio. Nell'ultimo passaggio avvio il servizio e la pubblicità.
pService->addCharacteristic(&outHumidityCharacteristic);pService->addCharacteristic(&outTemperatureCharacteristic);pService->start(); // avvia il servizio// Inizia la pubblicitàpServer->getAdvertising()->start();
Sebbene le cose possano sembrare complicate, sono facili da codificare.
Dopo questa configurazione se uno dei valori (temperatura, umidità) cambia è necessario
- Impostare il valore nella caratteristica BLE
- Notifica al cliente che il valore è cambiato
Anche un lavoro facile: basta formattare i dati secondo le specifiche e fornirli a BLE.
int16_t nTempOut... //valore con 2 cifre moltiplicato per 10 (15.32 diventa 1532)//la funzione esclude un puntatore uint8_t - puntiamo a un int16_t quindi la dimensione è 2outHumidityCharacteristic.setValue((uint8_t*)&uHumOut, 2); //imposta un nuovo valoreoutHumidityCharacteristic.notify(); // notifica al cliente
Poiché utilizzo servizi / caratteristiche BLE "noti", chiunque può leggere i valori utilizzando app esistenti. Uno (collegato nella sezione software) è NRF Tool che mostra:
E dopo la connessione puoi leggere i valori e la descrizione:
Un altro strumento è BLE Tools che mostra servizi/caratteristiche GATT comuni:
Tre schermi - combinati qui
Il server web
Poiché ESP32 ha il WiFi, posso fornire i valori correnti come una semplice pagina html. Lo faccio usando una stringa con segnaposto. Quando un client richiede la pagina (naviga sul server Web), faccio una copia della stringa, sostituisco i segnaposto con valori e invio la stringa risultante come risposta al client.
Dati e data
Quando si raccolgono dati ambientali è importante sapere QUANDO è stata effettuata la misurazione. Grazie al WiFi questa è solo una riga di codice in più. L'EPS32 può richiamare la data/ora corrente dai server SNTP e fornirla tramite la funzione "getLocalTime".
Per avviare questa magia devi solo chiamare una funzione che dice al sistema il fuso orario (TZ e DST-offset) e quali server SNTP usare. Su una semplice riga di codice.
configTime(_TZOffset * 3600, _DSTOffset * 3600, "pool.ntp.org");
Per ottenere l'ora utilizzo una semplice funzione:
tm TryToGetLocalDateTime() {tmtmInfo;if(!getLocalTime(&tmInfo)) { //in caso di errore fornire valori predefiniti validitmInfo.tm_anno = 100; //2000tmInfo.tm_hour = 0;tmInfo.tm_min = 0;tmInfo.tm_sec = 0;tmInfo.tm_mon = 1;tmInfo.tm_mday = 1;}return(tmInfo);}
ESP32 e molte cose da fare
In Arduino normalmente usi 2 funzioni: setup e loop.
Inimpostareprepari tutte le cose (questa funzione viene eseguita una volta dopo l'avvio) e inciclo continuofai tutto il tuo lavoro.
Per separare le cose ho deciso di utilizzare le attività. Ciò significa che un numero di funzioni viene eseguito "contemporaneamente". ESP32 ha due core, quindi in teoria 2 funzioni possono essere eseguite contemporaneamente. Semplicemente non importa molto di ciò che è veramente parallelo e di ciò che viene fatto in sequenza. Supponiamo che tutto sia parallelo e consideriamolo quando si accede a variabili comuni.
Separiamo le cose che dobbiamo fare:
- Leggere valori analogici
- Fornire valori analogici tramite BLE
- Gestire i pulsanti
- Mostra dati
- Visualizza le informazioni di registrazione
- Trasferisci i dati al "cloud"
- Agire come server web (servire una singola pagina)
Iniziamo con il ciclo: la considero la funzione principale. Nel ciclo controllerò se è stato premuto un pulsante - in tal caso, cambierò il display (impostando un flag). Questo può essere fatto come una (molto semplice) macchina a stati finali in cui la pressione di un pulsante cambia lo stato.
State==1 - display spento, State==2 Visualizza dati meteo, State==3 visualizza dati di registro.
Il prossimo è leggere i valori analogici. Ciò richiede un accesso ai dati comune: utilizzare un semaforo per controllare l'accesso. Per semplificare le cose utilizzo un metodo "readGardenValues" per leggere/memorizzare i valori. Lo chiamo ogni 2 secondi mentre controllo i pulsanti ogni 500 ms (interruttore di visualizzazione più veloce).
Il ciclo fa:
- Controllare i pulsanti e cambiare il display se necessario
- Visualizza i dati (o niente se disattivato)
- Ogni 4 cicli leggere i valori analogici (e aggiornare BLE)
- Dormi per 500 ms
Accanto al loop abbiamo un thread che funge da server web e 4 gestori di eventi/interrupt che sono:
- Pulsante uno premuto
- Pulsante due premuto
- Cliente BLE connesso
- Client BLE disconnesso
Per maggiori informazioni controlla il codice sorgente (documentato). Commenti/domande e suggerimenti sono i benvenuti.
FAQs
How many BLE devices can be connected to ESP32? ›
When using ESP32 device as the server of Bluetooth® LE, how many client devices can be connected? ¶ The ESP32 Bluetooth LE supports up to nine client devices for connection. It is recommended to hold this number within three.
How do you test ESP32 BLE? ›Testing the ESP32 BLE Server
Upload the code to your board and then, open the Serial Monitor. It will display a message as shown below. Then, you can test if the BLE server is working as expected by using a BLE scan application on your smartphone like nRF Connect. This application is available for Android and iOS.
The ESP32 should NOT provide a random number (as seen in tty log). It should expect 123456.
What is the signal strength of ESP32 BLE? ›Very close to the ESP32 ( 20-30 cm) the signal strenght - RSSI value is about -55 -60 dBm that is good. Already at 2 meters (without any obstacle) the signal strenght drop to -70 - 75 dBm (that is accettable). But at more than 4-5 meters the signal goes at - 90 dBm that is too low signal.
What is the maximum number of connections for BLE? ›x protocol SPEC, when the iPhone/Android phone play as role of BLE central mode, the limitation to have active connection at the same time is up to 8 devices.
What is the maximum data size for BLE? ›The default size is 23 bytes (which allows the packet to fit in one LL packet) but the size can be negotiated via the Exchange MTU Request & Response. Per the Bluetooth Core Specification, the maximum allowed length of an attribute value (the ATT payload) is 512 bytes 3.
Can ESP32 run BLE and Wi-Fi at the same time? ›Overview. ESP32 has only one 2.4 GHz ISM band RF module, which is shared by Bluetooth (BT & BLE) and Wi-Fi, so Bluetooth can't receive or transmit data while Wi-Fi is receiving or transmitting data and vice versa. Under such circumstances, ESP32 uses the time-division multiplexing method to receive and transmit packets ...
What is the difference between a GATT server and a client? ›A GATT Server is a device which stores attribute data locally and provides data access methods to a remote GATT Client paired via BLE. A GATT Client is a device which accesses data on a remote GATT Server, paired via BLE, using read, write, notify, or indicate operations.
Can ESP32 be both server and client? ›One ESP32 board will act as a server and the other ESP32 board will act as a client. The following diagram shows an overview of how everything works. The ESP32 server creates its own wireless network (ESP32 Soft-Access Point).
What is GATT in Bluetooth? ›Just as the GAP layer handles most connection-related functionality, the GATT layer of the Bluetooth low energy protocol stack is used by the application for data communication between two connected devices.
What is the difference between BLE client and BLE server? ›
Client devices access remote resources over a BLE link using the GATT protocol. Usually, the master is also the client. Server devices have a local database and access control methods, and provide resources to the remote client. Usually, the slave is also the server.
What is the difference between Bluetooth client and server? ›what is client and server The client made a request to the Server for data communication which allows a device to wirelessly exchange data with other Bluetooth devices. The server provides data services to the Client, it encapsulates data through characteristic.
What is a good RSSI for BLE? ›An ideal RSSI value of a Bluetooth device should be between -30 to -55. Reading the Received Signal Strength Indicator (RSSI) can sometimes be challenging. It is essential to understand that a lower number indicates a lower connection while a higher number illustrates a better connection.
How do I check my ESP32 signal strength? ›Get WiFi Connection Strength
Open the Serial Monitor and press the ESP32 on-board RST button. It will connect to your network and print the RSSI (received signal strength indicator). What is this? A lower absolute value means a strongest Wi-Fi connection.
A Brief Note of ESP32 Bluetooth
Operating in the unlicensed 2.4 GHz ISM (Industrial, Scientific and Medical) frequency band, Bluetooth is a short-range wireless communication technology with range up to 100 m. ESP32 SoC integrates both the Bluetooth Link Controller (or Link Manager) and the Baseband into its silicon.
The transmit power of BLE radios available today usually range between 0 dBm to around 20 dBm, with the majority having an upper bound of 4 dBm or 5 dBm, but a few devices exceed this.
Can you connect to multiple BLE devices? ›Yes you can and i have done this using a simple loop. What i do is, First I scan for the devices, once they are found I put it in an arraylist and call this connect method.
How far can BLE broadcast? ›This range can be less if the signal has to travel through objects and walls. However, Bluetooth low energy (BLE) beacons, the type typically used in indoor positioning and indoor navigation (IPIN) systems, do have a higher range - generally, the range on these devices stands at around 80 meters.
How many max bluetooth devices can be connected at once in IOT? ›The official Bluetooth specifications state seven is the maximum number of Bluetooth devices that can be connected at once.
What is the maximum range of ESP32 BLE? ›Feature | Bluetooth Classic |
---|---|
Power Consumption | High (up to 1W) |
Audio Streaming | Original audio protocol used in most of devices |
Range | Limited range 10m – 50m |
RF bandwidth | 2.4 GHz ISM band (2400-2483.5 MHz) |
What is the difference between pairing and connecting in BLE? ›
At a high level, you will always use "connect" to connect to a device, but you may have to "pair" the devices first. Bluetooth pairing is a security procedure. A one-off provisioning step that equips the two devices in a pairing with a series of shared security keys which allow communication to be encrypted.
How do I allow multiple Bluetooth connections? ›Android users need to go to Bluetooth Settings and pair either Bluetooth headphones or speakers one by one. Once connected, tap the three-dot icon on the right and click on Advanced Settings. Toggle on the 'dual audio' option if not already turned on. This should enable users to connect to two devices at once.
How much current does ESP32 Bluetooth draw? ›ESP32 Active Mode
Normal mode is also referred to as Active Mode. In this mode, all peripherals of the chip remain active. Since everything is always active in this mode (especially the WiFi module, processing core, and Bluetooth module), the chip consumes about 240 mA of power.
Up to 20 MBit/s TCP throughput and 30 MBit/s UDP throughput over the air.
What is the maximum Wi-Fi speed for ESP32? ›ESP32 supports a data rate of up to 150 Mbps, and 20.5 dBm output power at the antenna to ensure the widest physical range.