.. note::

    Ciao, benvenuto nella SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community su Facebook! Approfondisci le tue conoscenze su Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.

    **Perché unirti a noi?**

    - **Supporto esperto**: Risolvi i problemi post-vendita e le sfide tecniche con l'aiuto della nostra comunità e del nostro team.
    - **Impara e condividi**: Scambia suggerimenti e tutorial per migliorare le tue competenze.
    - **Anteprime esclusive**: Ottieni accesso anticipato agli annunci di nuovi prodotti e anteprime speciali.
    - **Sconti esclusivi**: Approfitta di sconti riservati sui nostri prodotti più recenti.
    - **Promozioni festive e concorsi**: Partecipa a concorsi e promozioni durante le festività.

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

.. _2.2.3_py:

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

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

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


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

In questo progetto, abbiamo bisogno dei seguenti componenti.

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

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

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

    *   - Nome
        - ARTICOLI IN QUESTO KIT
        - LINK
    *   - Kit Raphael
        - 337
        - |link_Raphael_kit|

Puoi anche acquistarli separatamente dai link qui sotto.

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

    *   - INTRODUZIONE AI COMPONENTI
        - LINK PER L'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 nella cartella del codice.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python

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

.. raw:: html

   <run></run>

.. code-block::

    sudo python3 2.2.3_DHT.py

Una volta eseguito il codice, il programma stamperà la temperatura e l'umidità 
rilevate dal DHT11 sullo schermo del computer.

**Codice**

.. note::

    Puoi **Modificare/Reimpostare/Copiare/Eseguire/Interrompere** il codice qui sotto. Ma prima devi accedere al percorso del codice come ``raphael-kit/python``. 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_COUINT = 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 start --------------
         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

               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}')

         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 = ""

      # -------------- send start --------------
      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 operazioni del DHT11. I dati rilevati vengono archiviati 
nell'array bits[]. Il DHT11 trasmette 40 bit di dati alla volta. I primi 16 bit sono 
relativi all'umidità, i successivi 16 bit sono relativi alla temperatura, e gli ultimi 
8 bit vengono utilizzati per la verifica. Il formato dei dati è:

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

Quando la validità è rilevata 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 intero a 8 bit dell'umidità)
00000000 (valore decimale a 8 bit dell'umidità) 00111100 (valore intero a 8 bit della 
temperatura) 00000000 (valore decimale a 8 bit della temperatura) 01100111 (bit di controllo)

**Calcolo:**

00101011 + 00000000 + 00111100 + 00000000 = 01100111.

Se il risultato finale è diverso dai dati del bit di controllo, 
la trasmissione dei dati è anomala: restituisce False.

Se il risultato finale è uguale ai dati del bit di controllo, 
i dati ricevuti sono corretti, e verranno restituiti ``humidity`` e ``temperature``, con la stampa
\"Umidità =43%, Temperatura =60°C\".
