.. 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 problemi post-vendita e 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 a nuovi annunci di prodotti e anteprime speciali.
    - **Sconti speciali**: Approfitta di sconti esclusivi sui nostri prodotti più recenti.
    - **Promozioni festive e omaggi**: Partecipa a concorsi e promozioni durante le festività.

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

.. _4.1.9_py:

4.1.9 Allarme di Retromarcia
======================================

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

In questo progetto, utilizzeremo un display LCD, un buzzer e sensori a ultrasuoni 
per creare un sistema di assistenza alla retromarcia. Possiamo posizionarlo su 
un'auto telecomandata per simulare il processo reale di retromarcia in un garage.

Componenti necessari
------------------------------

In questo progetto, avremo bisogno dei seguenti componenti.

.. image:: ../img/list_Reversing_Alarm.png
    :align: center

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

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

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

Puoi anche acquistarli separatamente dai link sottostanti.

.. 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_buzzer`
        - \-
    *   - :ref:`cpn_transistor`
        - |link_transistor_buy|
    *   - :ref:`cpn_ultrasonic_sensor`
        - |link_ultrasonic_buy|
    *   - :ref:`cpn_i2c_lcd`
        - |link_i2clcd1602_buy|

Schema elettrico
-----------------------

Il sensore a ultrasuoni rileva la distanza tra sé stesso e l'ostacolo, che viene 
visualizzata sul display LCD sotto forma di codice. Allo stesso tempo, il sensore 
a ultrasuoni fa emettere al buzzer un segnale acustico la cui frequenza varia in 
base alla distanza rilevata.

============ ======== ======== ===
T-Board Name physical wiringPi BCM
GPIO23       Pin 16   4        23
GPIO24       Pin 18   5        24
GPIO17       Pin 11   0        17
SDA1         Pin 3             
SCL1         Pin 5             
============ ======== ======== ===

.. image:: ../img/Schematic_three_one3.png
   :align: center

Procedure sperimentali
--------------------------

**Passo 1:** Costruisci il circuito.

.. image:: ../img/image242.png
    :width: 400
    :align: center

**Passo 2:** Cambia directory.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python/

**Passo 3:** Esegui.

.. raw:: html

   <run></run>

.. code-block::

    sudo python3 4.1.9_ReversingAlarm.py

Una volta eseguito il codice, il modulo sensore a ultrasuoni rileverà la 
distanza dall'ostacolo e visualizzerà l'informazione sul display LCD1602. 
Inoltre, il buzzer emetterà un segnale acustico di avvertimento la cui 
frequenza cambierà in base alla distanza.

.. note::

    * Se compare l'errore ``FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'``, devi fare riferimento a :ref:`i2c_config` per abilitare l'I2C.
    * Se compare l'errore ``ModuleNotFoundError: No module named 'smbus2'``, esegui il comando ``sudo pip3 install smbus2``.
    * Se compare l'errore ``OSError: [Errno 121] Remote I/O error``, significa che il modulo è cablato male o danneggiato.
    * Se il codice e i collegamenti sono corretti ma il display LCD non mostra nulla, puoi regolare il contrasto ruotando il potenziometro sul retro del modulo.


**Codice**

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

.. raw:: html

    <run></run>

.. code-block:: python

    import LCD1602
    import time
    import RPi.GPIO as GPIO

    TRIG = 16
    ECHO = 18
    BUZZER = 11

    def lcdsetup():
    LCD1602.init(0x27, 1)   # init(indirizzo slave, retroilluminazione)
    LCD1602.clear()   
    LCD1602.write(0, 0, 'Ultrasonic Starting')
    LCD1602.write(1, 1, 'By SunFounder')
    time.sleep(2)

    def setup():
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(TRIG, GPIO.OUT)
    GPIO.setup(ECHO, GPIO.IN)
    GPIO.setup(BUZZER, GPIO.OUT, initial=GPIO.LOW)
    lcdsetup()

    def distance():
    GPIO.output(TRIG, 0)
    time.sleep(0.000002)

    GPIO.output(TRIG, 1)
    time.sleep(0.00001)
    GPIO.output(TRIG, 0)

    while GPIO.input(ECHO) == 0:
        a = 0
    time1 = time.time()
    while GPIO.input(ECHO) == 1:
        a = 1
    time2 = time.time()

    during = time2 - time1
    return during * 340 / 2 * 100

    def destroy():
    GPIO.output(BUZZER, GPIO.LOW)
    GPIO.cleanup()
    LCD1602.clear()

    def loop():
    while True:
        dis = distance()
        print (dis, 'cm')
        print ('')
        GPIO.output(BUZZER, GPIO.LOW)
        if (dis > 400):
            LCD1602.clear()
            LCD1602.write(0, 0, 'Error')
            LCD1602.write(3, 1, 'Out of range')
            time.sleep(0.5)
        else:
            LCD1602.clear()
            LCD1602.write(0, 0, 'Distance is')
            LCD1602.write(5, 1, str(round(dis,2)) +' cm')
            if(dis>=50):
                time.sleep(0.5)
            elif(dis<50 and dis>20):
                for i in range(0,2,1):
                    GPIO.output(BUZZER, GPIO.HIGH)
                    time.sleep(0.05)
                    GPIO.output(BUZZER, GPIO.LOW)
                    time.sleep(0.2)
            elif(dis<=20):
                for i in range(0,5,1):
                    GPIO.output(BUZZER, GPIO.HIGH)
                    time.sleep(0.05)
                    GPIO.output(BUZZER, GPIO.LOW)
                    time.sleep(0.05)


    if __name__ == "__main__":
        setup()
        try:       
            loop()
        except KeyboardInterrupt:
            destroy()



**Spiegazione del Codice**

.. code-block:: python

    def lcdsetup():
        LCD1602.init(0x27, 1)   # init(indirizzo slave, retroilluminazione)

    def setup():
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(TRIG, GPIO.OUT)
        GPIO.setup(ECHO, GPIO.IN)
        GPIO.setup(BUZZER, GPIO.OUT, initial=GPIO.LOW)
        lcdsetup()

In questo programma, utilizziamo componenti già impiegati precedentemente. 
Qui utilizziamo buzzer, LCD e sensore a ultrasuoni. Li possiamo inizializzare 
nello stesso modo già visto in precedenza.

.. code-block:: python

    dis = distance()
    print (dis, 'cm')
    print ('')
    GPIO.output(BUZZER, GPIO.LOW)
    if (dis > 400):
        LCD1602.clear()
        LCD1602.write(0, 0, 'Error')
        LCD1602.write(3, 1, 'Out of range')
        time.sleep(0.5)
    else:
        LCD1602.clear()
        LCD1602.write(0, 0, 'Distance is')
        LCD1602.write(5, 1, str(round(dis,2)) +' cm')


Qui otteniamo i valori del sensore a ultrasuoni e calcoliamo la distanza. 
Se la distanza supera l'intervallo rilevabile, un messaggio di errore viene 
visualizzato sul display LCD. Se la distanza è all'interno dell'intervallo 
di lavoro, verranno visualizzati i risultati corrispondenti.

.. code-block:: python

    LCD1602.write(5, 1, str(round(dis,2)) +' cm')

Poiché l'LCD supporta solo caratteri, dobbiamo usare **str()** per convertire 
i valori numerici in stringhe. Applichiamo un arrotondamento a due decimali.

.. code-block:: python

    if(dis>=50):
        time.sleep(0.5)
    elif(dis<50 and dis>20):
        for i in range(0,2,1):
            GPIO.output(BUZZER, GPIO.HIGH)
            time.sleep(0.05)
            GPIO.output(BUZZER, GPIO.LOW)
            time.sleep(0.2)
    elif(dis<=20):
        for i in range(0,5,1):
            GPIO.output(BUZZER, GPIO.HIGH)
            time.sleep(0.05)
            GPIO.output(BUZZER, GPIO.LOW)
            time.sleep(0.05)

Questa condizione viene utilizzata per controllare il suono del buzzer. In base 
alla distanza rilevata, possiamo distinguere tre casi con frequenze sonore diverse. 
Tutti gli intervalli di ritardo totali sono di 500ms, sufficienti per permettere al 
sensore a ultrasuoni di funzionare correttamente.


Immagine del fenomeno
-----------------------------

.. image:: ../img/image243.jpeg
   :align: center
