.. note::

    Ciao, benvenuto nella Community di SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts su Facebook! Approfondisci il mondo di Raspberry Pi, Arduino ed ESP32 con altri appassionati.

    **Perché Unirti?**

    - **Supporto Tecnico Esperto**: Risolvi i problemi post-vendita e le sfide tecniche con l'aiuto della nostra comunità e del nostro team.
    - **Impara e Condividi**: Scambia consigli e tutorial per migliorare le tue competenze.
    - **Anteprime Esclusive**: Ottieni accesso anticipato alle novità sui nuovi prodotti e alle anteprime.
    - **Sconti Speciali**: Approfitta di sconti esclusivi sui nostri prodotti più recenti.
    - **Promozioni Festive e Giveaway**: Partecipa a giveaway e promozioni festive.

    👉 Sei pronto a esplorare e creare con noi? Clicca [|link_sf_facebook|] e unisciti oggi stesso!

.. _2.2.3_py_pi5:

2.2.3 DHT-11
==============

Introduzione
---------------

In questa lezione imparerai a collegare e leggere i dati da un sensore di 
temperatura e umidità DHT11 utilizzando un Raspberry Pi. Imparerai come 
configurare il sensore, leggere la temperatura sia in Celsius che in Fahrenheit, 
e ottenere le letture di umidità. Questo progetto ti introdurrà al lavoro con 
sensori esterni, alla gestione di dati in tempo reale e alla gestione base delle 
eccezioni in Python.


Componenti Necessari
----------------------

Per questo progetto, avremo bisogno dei seguenti componenti.

.. image:: ../img/list_2.2.3_dht-11.png

È decisamente comodo acquistare un kit completo, ecco il link:

.. list-table::
    :widths: 20 20 20
    :header-rows: 1

    *   - Nome	
        - COMPONENTI NEL KIT
        - LINK
    *   - Raphael Kit
        - 337
        - |link_Raphael_kit|

Puoi anche acquistarli separatamente dai link sottostanti.

.. list-table::
    :widths: 30 20
    :header-rows: 1

    *   - INTRODUZIONE AI COMPONENTI
        - LINK D'ACQUISTO

    *   - :ref:`cpn_gpio_extension_board`
        - |link_gpio_board_buy|
    *   - :ref:`cpn_breadboard`
        - |link_breadboard_buy|
    *   - :ref:`cpn_wires`
        - |link_wires_buy|
    *   - :ref:`cpn_resistor`
        - |link_resistor_buy|
    *   - :ref:`cpn_humiture_sensor`
        - |link_humiture_buy|

Schema Elettrico
--------------------

.. image:: ../img/image326.png


Procedure Sperimentali
-------------------------

**Passo 1:** Costruisci il circuito.

.. image:: ../img/image207.png

**Passo 2:** Vai alla cartella del codice.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python-pi5

**Passo 3:** Esegui il file eseguibile.

.. raw:: html

   <run></run>

.. code-block::

    sudo python3 2.2.3_DHT.py

Dopo l'esecuzione del codice, il programma stamperà sullo schermo la 
temperatura e l'umidità rilevate dal DHT11.

.. warning::

    Se viene visualizzato l'errore ``RuntimeError: Cannot determine SOC peripheral base address``, fare riferimento a :ref:`faq_soc`. 

**Code**

.. note::

    Puoi **Modificare/Resettare/Copiare/Eseguire/Fermare** il codice qui sotto. Ma prima, devi andare al percorso sorgente del codice come ``raphael-kit/python-pi5``. Dopo aver modificato il codice, puoi eseguirlo direttamente per vedere l'effetto.

.. code-block:: python

   from gpiozero import OutputDevice, InputDevice
   import time


   class DHT11():
      MAX_DELAY_COUNT = 100
      BIT_1_DELAY_COUNT = 10
      BITS_LEN = 40

      def __init__(self, pin, pull_up=False):
         self._pin = pin
         self._pull_up = pull_up


      def read_data(self):
         bit_count = 0
         delay_count = 0
         bits = ""

         # -------------- invio inizio --------------
         gpio = OutputDevice(self._pin)
         gpio.off()
         time.sleep(0.02)

         gpio.close()
         gpio = InputDevice(self._pin, pull_up=self._pull_up)

         # -------------- attesa risposta --------------
         while gpio.value == 1:
               pass
         
         # -------------- lettura dati --------------
         while bit_count < self.BITS_LEN:
               while gpio.value == 0:
                  pass

               # st = time.time()
               while gpio.value == 1:
                  delay_count += 1
                  if delay_count > self.MAX_DELAY_COUNT:
                     break
               if delay_count > self.BIT_1_DELAY_COUNT:
                  bits += "1"
               else:
                  bits += "0"

               delay_count = 0
               bit_count += 1

         # -------------- verifica --------------
         humidity_integer = int(bits[0:8], 2)
         humidity_decimal = int(bits[8:16], 2)
         temperature_integer = int(bits[16:24], 2)
         temperature_decimal = int(bits[24:32], 2)
         check_sum = int(bits[32:40], 2)

         _sum = humidity_integer + humidity_decimal + temperature_integer + temperature_decimal

         # print(bits)
         # print(humidity_integer, humidity_decimal, temperature_integer, temperature_decimal)
         # print(f'sum:{_sum}, check_sum:{check_sum}')
         # print()

         if check_sum != _sum:
               humidity = 0.0
               temperature = 0.0
         else:
               humidity = float(f'{humidity_integer}.{humidity_decimal}')
               temperature = float(f'{temperature_integer}.{temperature_decimal}')

         # -------------- ritorno dati --------------
         return humidity, temperature


   if __name__ == '__main__':
      dht11 = DHT11(17)
      while True:
         humidity, temperature = dht11.read_data()
         print(f"{time.time():.3f}  temperature:{temperature}°C  humidity: {humidity}%")
         time.sleep(2)

**Spiegazione del Codice**

.. code-block:: python

   def read_data(self):
      bit_count = 0
      delay_count = 0
      bits = ""

      # -------------- invio inizio --------------
      gpio = OutputDevice(self._pin)
      gpio.off()
      time.sleep(0.02)

      gpio.close()
      gpio = InputDevice(self._pin, pull_up=self._pull_up)
      #...

Questa funzione implementa le funzioni del DHT11. Memorizza i dati rilevati 
nell'array bits[]. Il DHT11 trasmette dati a 40 bit alla volta. I primi 16 bit 
sono relativi all'umidità, i successivi 16 bit alla temperatura e gli ultimi 
otto bit vengono utilizzati per la verifica. Il formato dei dati è:

**8bit dati interi umidità** +\ **8bit dati decimali umidità**
+\ **8bit dati interi temperatura** + **8bit dati decimali temperatura**
+ **8bit bit di controllo**.

Quando la validità viene verificata tramite il bit di controllo, la 
funzione restituisce due risultati: 1. errore; 2. umidità e temperatura.

.. code-block:: python

   _sum = humidity_integer + humidity_decimal + temperature_integer + temperature_decimal

   if check_sum != _sum:
         humidity = 0.0
         temperature = 0.0
   else:
         humidity = float(f'{humidity_integer}.{humidity_decimal}')
         temperature = float(f'{temperature_integer}.{temperature_decimal}')

Ad esempio, se i dati ricevuti sono 00101011 (valore a 8 bit dell'umidità intera)
 00000000 (valore a 8 bit dell'umidità decimale) 00111100 (valore a 8 bit della 
 temperatura intera) 00000000 (valore a 8 bit della temperatura decimale) 01100111 
 (bit di controllo)

**Calcolo:**

00101011+00000000+00111100+00000000=01100111.

Se il risultato finale è diverso dal bit di controllo, la trasmissione dei dati 
è anomala: ritorna errore.

Se il risultato finale è uguale al bit di controllo, i dati ricevuti sono corretti 
e verranno restituite "umidità" e "temperatura" e stampato "Umidità =43%, Temperatura =60C".
