Di seguito si riportano i passi per l’acquisizione dei valori di due sensori (DHT11 per Temperatura e Umidità e BMP180 per Pressione e Temperatura), utilizzando la scheda STM Nucleo (F411RE), regalatami da una società del calibro di STMicroelectronics[1], nel corso di una MakerFaire di qualche anno fa,…

La semplicità di uso è stata imbattibile, e aiuta chi, come me, generalmente non entra troppo nel dettaglio di ogni singolo aspetto delle cose quando c’è qualcosa da fare. Questo però non vuol dire che debba esser preso da esempio, anzi la semplicità e la rapida curva d’apprendimento, devono essere solo uno sprone per approfondire di più quello che si è fatto. Vedere che il tutto funziona quasi subito aiuta, ma non deve diventare una stampella, perché altrimenti, si rischia di abbandonare alle prime difficoltà o fermarsi dopo aver appreso molto poco o in modo superficiale. Partendo per gradi, dal più semplice e, via via, incrementare la difficoltà una volta che si è presa confidenza con i vari ambienti. Di seguito ci sono tutti gli spunti, si può fare poco sforzo, ma ci sono anche i riferimenti per approfondire di più…

Partiamo, quindi, per semplicità, con l’ambiente di sviluppo online [2], premendo il bottone “Compiler” in alto a destra. Volendo poi si può usare un vero e proprio ambiente di sviluppo, come Eclipse, descritto ottimamente qui [3]. Non entro nel merito di quale sia migliore, ognuno ha le proprie caratteristiche. Essere veloce, online e indipendente dal Sistema Operativo, contro un editor e debugging migliore che può essere utilizzato anche quando non si ha un connessione a Internet. In alternativa, si può partire dall’editor online per passare poi a Eclipse, una volta che si è presa confidenza [4].

Per le procedure iniziali, non mi dilungo, visto che qualcun altro lo ha già fatto molto meglio di me, quindi rimando all’ottimo tutorial di Luca Tanganelli, ospitato nel Blog del grande Giovanni Bernardo [5].

…Una volta entrati nell’IDE online, cliccando su “New” si crea un nuovo Progetto, attraverso una finestra di dialog come la seguente:

Dialog Nuovo Progetto

Figure 1: Crea un nuovo progetto…

 

Ricordarsi di selezionare la propria scheda in “Platform”, nel mio caso la Nucleo-F411RE e scegliere il nome in “Program Name”, come a esempio:”SensorReading” (per abitudine, passando da un sistema operativo all’altro, evito sempre di lasciare spazi nei nomi, specialmente quando diventeranno anche cartelle nel file system).

Si, arriva quindi a una situazione, tipo quella riportata di seguito:

Esempio creazione progetto 
Figure 2: Esempio di programma creato

 

Cliccare quindi sulla seconda voce del Menù: Import (avendo cura di aver selezionato il programma in esame, la “cartella” non i suoi contenuti (come nella foto)).

Nella casella di input di “Search” riportare DHT11. Dalla lista che ne risulterà, selezionare la voce relativa alla libreria che si vuole scaricare, nel mio caso ho provato la prima riga dell’Autore Wim De Roeve (per selezionare l’intera riga, si deve cliccare sul nome DHT e non sugli altri campi).

Una volta selezionata la prima riga, si abilita il Bottone “Import!” in alto a destra. Cliccare e confermare quindi con il nuovo bottone “Import” della dialog come da immagine seguente.

Importazione librerie 
Figure 3: Importazione delle Librerie

 

Ripetere gli stessi passi per importare le librerie per il sensore BMP180, nel mio caso la libreria che ha funzionato è quella di Kevin Gillepsie.

A questo punto cliccare due volte su “main.cpp” e apparirà nell’area di editing il sorgente del programma principale. Se volete evitare di editare il vostro codice potrete provare l’esempio che ho caricato in fondo alla pagina [Allegato 1], prendendolo “as it is” senza garanzia di funzionamento, come spunto per le vostre modifiche del caso. Quindi, copiate e incollate il sorgente, sostituendo integralmente il contenuto dell’attuale main.cpp.

Se tutto è andato correttamente dovreste avere la situazione come quella della figura seguente, librerie e main inclusi…

Esempio Main.cpp 
Figure 4: Esempio di Main.cpp con le librerie installate

 

Per entrambi i sensori, non ho fatto altro che integrare il software di esempio incluso nelle librerie dei rispettivi sviluppatori, facendo un merge dei due sorgenti. E cosa, non solita, almeno per me, ha funzionato tutto al primo colpo. Ho perso solo tempo per le formattazioni e l’output su seriale, ma sono a discrezione e a proprio piacimento.

Per poter sperimentare è necessario collegare i sensori alla Nucleo e provare il tutto.

Anche qui se per pigrizia non volete ricavarvi le connessioni dei relativi sensori (derivandole dalla lettura, che consiglio sempre di fare integralmente, anche se riconosco di essere il primo a non farlo, dai rispettivi datasheet [6] e [7], ricavati dalla rete) potrete utilizzare lo schema seguente, “tradotto” nella vista reale delle conessioni tramite breadboard, come da figura seguente.

Per la realizzazione dello schema pratico, dal quale poi è stato ricavato lo schema elettrico (il contrario di quello che suggerirebbe la regola e il buon senso), ho utilizzato il semplice e potente Fritzing [8], che è molto utile proprio a livello didattico, consentendo tra l’altro di potersi creare il proprio PCB (Printed Circuit Board, circuito stampato) da dare a qualche service per realizzarlo se non si possono usare i vecchi e cari metodi di una volta per farselo in proprio con l’acido, trasferibili o bromografo.

Anche se il sensore che ho io non è esattamente uguale a quello trovato cercando nella libreria degli oggetti che Fritzing mette a disposizione, rende perfettamente l’idea e la pinnatura è comunque serigrafata nel piccolissimo circuito stampato.

Schema pratico per ricavare le connessioni 
Figure 5: Schema pratico delle connessioni tra la Nucleo e i sensori

 

Il passaggio dallo schema pratico a quello elettrico, aiuta anche a capire quali siano i pin da connettere.

L’unico neo di Fritzing è che a volte scombina una vista agendo nell’altra, capita quindi che risistemando lo schema elettrico che lui ha abbozzato sulla base di quello che abbiamo disegnato nel pratico, si creino dei disallineamenti su quest’ultimo.

Schema Elettrico 
Figure 6: Schema Elettrico

 

Nel datasheet del sensore BMP180 ci sono le due resistenze di pullup e i due condensatori verso massa, di rito, per rendere “puliti” i collegamenti. Dalla libreria di Fritzing che ho trovato, sembra che la schedina del sensore già contenga i componenti aggiuntivi (e nel caso non occorre aggiungere pullup e condensatori esterni), ma nel mio caso intorno al sensore in se non c’è altra componentistica. Senza dirlo troppo in giro, però, a me sta funzionando anche connettendo direttamente, senza altro, i due fili dai rispettivi pin della scheda Nucleo al sensore per SCL e SDA del bus I2C.

Per capire il funzionamento del bus I2C, consiglio di leggere, perché le potenzialità e l’enorme casistica di utilizzi di tale bus lo giustificano, il seguente tutorial [9], molto dettagliato ed esaustivo.

Per il sensore DHT11, invece il discorso è più dedicato alla logica di funzionamento propria solo di questo dispositivo peraltro diffusissimo, insieme al DHT22. Per capirne veramente la logica ho trovato questa descrizione molto dettagliata [1o], anche se usa un altra scheda per leggerlo.

Per tutto quello che c’è da sapere sulla scheda Nucleo-F411RE, non si può non riportare il datasheet ufficiale della STMicroelectronics [11].

A questo punto, preparato lo hardware e preparato il software, non resta che salvare e compilare (“Save” e “Compile” dall’Ide di Mbed).

Il file generato (SensorReading.NUCLEO_F411RE.bin), si troverà dove deciso dal browser (nel mio caso la directory Download) e andrà copiato con un semplice drag&drop (trascina e rilascia), direttamente nella nucleo, connessa con il relativo cavetto USB, che viene vista dal Sistema Operativo come disco (nel mio caso Computer→Nucleo(F:)).

Seguirà un lampeggìo rosso-verde del led accanto al connettore miniUSB della scheda Nucleo che conferma il “trasferimento”.

Avendo a disposizione un display lo si potrebbe utilizzare per presentare i valori in uscita, modificando di conseguenza il codice, invece che leggerlo, come nel nostro caso, tramite un emulatore di seriale (come quelli consigliati da Luca Tanganelli. Io avevo sottomano Hercules e ho usato quello), ottenendo il risultato, tipo quello che segue.

Esempio lettura tramire emulatore seriale 
Figure 7: Esempio di output da emulatore seriale

 

Le impostazioni per la seriale, sono quelle in evidenza, ma il tutto è comunque già descritto sempre nel tutorial di Luca.

I primi tre dati in uscita, sono: la temperatura e la pressione lette dal sensore BMP180, e l’umidità letta tramite DHT11.

La successiva temperatura e le relative conversioni, sono letti dal DHT11. Come si può notare c’è una significativa differenza tra le temperature fornite dai due sensori, questo è dovuto alle differenti precisioni e risoluzioni dei sue sensori (si vedano i rispettivi datasheet) oltre che alle conversioni nei calcoli.

Chi ha scritto la libreria del DHT11, si è preso la briga di fornire anche tutte le varie conversioni (Celsius, Fahrenheit e Kelvin), compreso il calcolo del DewPoint [12].

Diciamo che sarei portato a utilizzare il DHT11 solo per la lettura dell’umidità relativa, mentre la temperatura la leggerei dal BMP180 che nasce per la pressione (visto che da questo sensore la temperatura è più vicina a quanto riportato dal termostato di casa).

Anche se forse sarà dovuto alla cavetteria che ho usato per la breadboard (con i pin troppo piccoli per i fori della breadboard), ma credo che anche la stabilità nella lettura, sia migliore nel sensore BMP180 rispetto al DHT11, perché quest’ultimo ha spesso perso i dati (Err. 6 o Err. 7 tradotti dal codice di Wim De Roeve, rispettivamente con: ERROR_CHECKSUM, e ERROR_NO_PATIENCE). Questo spiega la suddivisione nella rappresentazione dei dati.

Sperando che sia stato un minimo di utilità, vi esorto a riportare eventuali errori o migliorie in un tutorial migliore…


References:

[1] https://www.st.com/content/st_com/en.html

[2] https://www.mbed.com/en/

[3] http://www.perlatecnica.it/getting-started-with-nucleo-f401re-and-mbedos/toolchain-offline-per-la-scheda-a-microcontrollore-stm32-nucleof401re-ed-mbed-os/

[4] http://www.perlatecnica.it/uncategorized/esportare-un-progetto-mbed-online-in-eclipse/

[5] https://www.settorezero.com/wordpress/alla-scoperta-delle-schede-di-sviluppo-stm32-nucleo/

[6] Datasheet del sensore DHT11 [DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf] https://www.mouser.com/ds/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf

[7] Datasheet del sensore BMP180 [BST-BMP180-DS000-09.pdf]

https://cdn-shop.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf

[8] http://fritzing.org/home/

[9] [Protocollo-di-comunicazione-I2C.pdf]

http://www.crivellaro.net/wp-content/uploads/2017/03/Protocollo-di-comunicazione-I2C.pdf

[10] https://www.logicaprogrammabile.it/arduino-dht11-lettura-grezza-dei-dati/

[11] STM32 Nucleo-64 boards User Manual [UM1724]

https://www.st.com/content/ccc/resource/technical/document/user_manual/98/2e/fa/4b/e0/82/43/b7/DM00105823.pdf/files/DM00105823.pdf/jcr:content/translations/en.DM00105823.pdf

[12] https://it.wikipedia.org/wiki/Punto_di_rugiada

Author:  Carlo Ottaviani


Allegato 1: Main.cpp

#include "mbed.h"
#include "DHT.h"
#include "BMP180.h"

DigitalOut myled(LED1);

// It creates an instance of the class Serial. 'pc' is the name of the variable and assign the TX and RX pin to it
Serial pc(USBTX, USBRX);

// It creates an instance of SEN11301P DHTSensor
DHT DHTSensor(PA_10,SEN11301P); 

// It creates an instance for I2C and BMPSensor
I2C i2c(I2C_SDA, I2C_SCL);
BMP180 BMP180Sensor(&i2c);


int main() {
    int err;
    // Writing on Serial line Title
    pc.printf("\r\nDHT11 & BMP180 program");
    pc.printf("\r\n**********************\r\n");
    
    while(1) 
    {
        if (BMP180Sensor.init() != 0) {
            printf("Error communicating with BMP180\n");
        } else {
            printf("Initialized BMP180\n");
            break;
        }
    }  
    wait(1); // wait 1 second for device stable status
  
    
    while (1) {
        myled = 1;
        // Reading BMP180
        // Temperture
        BMP180Sensor.startTemperature();
        wait_ms(5);     // Wait for conversion to complete
        float BMPTemperature;
        if(BMP180Sensor.getTemperature(&BMPTemperature) != 0) 
        {
            pc.printf("Error getting temperature from BMP180\n");
            continue;
        }

        // and Pressure
        BMP180Sensor.startPressure(BMP180::ULTRA_LOW_POWER);
        wait_ms(10);    // Wait for conversion to complete
        int BMPPressure;
        if(BMP180Sensor.getPressure(&BMPPressure) != 0) 
        {
            pc.printf("Error getting pressure\n");
            continue;
        }
    
        
        // Defining and initializing Variables for reading DHT sensor
        float TempCels=0;
        float TempFaren=0;
        float TempKelvin=0;
        float Humidity=0;
        float DEWP=0;
        float DEWPFast=0;

        // Reading DHT
        err = DHTSensor.readData();
        if (err == 0) 
        {
            TempCels = DHTSensor.ReadTemperature(CELCIUS);
            TempFaren =  DHTSensor.ReadTemperature(FARENHEIT);
            TempKelvin = DHTSensor.ReadTemperature(KELVIN);
            Humidity = DHTSensor.ReadHumidity();
            DEWP = DHTSensor.CalcdewPoint(DHTSensor.ReadTemperature(CELCIUS), DHTSensor.ReadHumidity());
            DEWPFast = DHTSensor.CalcdewPointFast(DHTSensor.ReadTemperature(CELCIUS), DHTSensor.ReadHumidity());
         } else
            pc.printf("\r\nErrore Reading DHT11: Err %i \n",err);
        myled = 0;
        

        // Output of data via Serial line
        pc.printf("______________________________________\r\n");
        pc.printf("\r\n");
        pc.printf("Pressure              = %7.2f    hpa \r\n", BMPPressure/100.00);
        pc.printf("Temperature           = %7.2f    %cC  \n", BMPTemperature,(char)186);
        pc.printf("Humidity              = %4.0f       %c \r\n",  Humidity,(char)37);
        pc.printf("______________________________________\r\n");
        pc.printf(" \r\nFrom DHT11 \r\n");
        pc.printf("     Temperature      = %7.2f    %cC \r\n",  TempCels,(char)186);
        pc.printf("     Temperature      = %7.2f    %cF \r\n",  TempFaren,(char)186);
        pc.printf("     Temperature      = %7.2f    %cK \r\n",   TempKelvin,(char)186);
        pc.printf("     Dew point        = %7.2f    %cC \r\n", DEWP,(char)186);
        pc.printf("     Dew point (fast) = %7.2f    %cC \r\n", DEWPFast,(char)186);
    
        wait(3);
    }
}
This site uses cookies. Find out more about this site’s cookies.
%d blogger hanno fatto clic su Mi Piace per questo: