.. note::

    Ciao, benvenuto nella SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community su Facebook! Approfondisci le tue conoscenze di 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 promozioni speciali e concorsi durante le festività.

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

.. _4.1.8_py:

4.1.8 Benvenuto
=====================================

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

In questo progetto, utilizzeremo il PIR per rilevare il movimento dei pedoni e useremo 
servomotori, LED e buzzer per simulare il funzionamento di una porta automatica di un 
negozio. Quando un pedone entra nell'area di rilevamento del PIR, si accenderà la spia, 
la porta si aprirà e il buzzer suonerà una melodia di benvenuto.


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

In questo progetto, avremo bisogno dei seguenti componenti.

.. image:: ../img/list_Welcome.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_led`
        - |link_led_buy|
    *   - :ref:`cpn_pir`
        - \-
    *   - :ref:`cpn_servo`
        - |link_servo_buy|
    *   - :ref:`cpn_buzzer`
        - |link_passive_buzzer_buy|
    *   - :ref:`cpn_transistor`
        - |link_transistor_buy|


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

============ ======== ======== ===
T-Board Name physical wiringPi BCM
GPIO18       Pin 12   1        18
GPIO17       Pin 11   0        17
GPIO27       Pin 13   2        27
GPIO22       Pin 15   3        22
============ ======== ======== ===

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

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

**Passo 1:** Costruisci il circuito.

.. image:: ../img/image239.png
    :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.8_Welcome.py

Dopo l'esecuzione del codice, se il sensore PIR rileva il passaggio di una persona, 
la porta si aprirà automaticamente (simulata dal servomotore), si accenderà l'indicatore 
e verrà riprodotta la melodia del campanello. Dopo che la melodia è terminata, il 
sistema chiuderà automaticamente la porta e spegnerà la spia, in attesa del passaggio successivo.

Ci sono due potenziometri sul modulo PIR: uno regola la sensibilità e l'altro la 
distanza di rilevamento. Per far funzionare meglio il modulo PIR, devi girarli 
entrambi completamente in senso antiorario.

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

**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

    #!/usr/bin/env python3

    import RPi.GPIO as GPIO
    import time

    SERVO_MIN_PULSE = 500
    SERVO_MAX_PULSE = 2500

    ledPin = 18    # definire il ledPin
    pirPin = 17    # definire il sensorPin
    servoPin = 22  # definire il servoPin
    buzPin = 27    # definire il buzzerpin


    CL = [0, 131, 147, 165, 175, 196, 211, 248]        # Frequenze delle note di Do basso

    CM = [0, 262, 294, 330, 350, 393, 441, 495]        # Frequenze delle note di Do medio

    CH = [0, 525, 589, 661, 700, 786, 882, 990]        # Frequenze delle note di Do alto

    song = [    CH[5],CH[2],CM[6],CH[2],CH[3],CH[6],CH[3],CH[5],CH[3],CM[6],CH[2]    ]

    beat = [    1,1,1,1,1,2,1,1,1,1,1,]


    def setup():
        global p
        global Buzz                        # Assegna una variabile globale per sostituire GPIO.PWM 
        GPIO.setmode(GPIO.BCM)       # Numerazione dei GPIO in base alla posizione fisica
        GPIO.setup(ledPin, GPIO.OUT)   # Imposta il ledPin come uscita
        GPIO.setup(pirPin, GPIO.IN)    # Imposta il sensorPin come ingresso
        GPIO.setup(servoPin, GPIO.OUT)   # Imposta il servoPin come uscita
        GPIO.output(servoPin, GPIO.LOW)  # Imposta il servoPin su low
        GPIO.setup(buzPin, GPIO.OUT)    # Imposta i pin come uscite

        Buzz = GPIO.PWM(buzPin, 440)    # 440 è la frequenza iniziale.
        Buzz.start(50)                    # Avvia il pin del buzzer con un duty cycle del 50%

        p = GPIO.PWM(servoPin, 50)     # Imposta la frequenza a 50Hz
        p.start(0)                     # Duty Cycle = 0

    def map(value, inMin, inMax, outMin, outMax):
        return (outMax - outMin) * (value - inMin) / (inMax - inMin) + outMin

        
    def setAngle(angle):      # Fa ruotare il servo ad un angolo specifico (0-180 gradi) 
        angle = max(0, min(180, angle))
        pulse_width = map(angle, 0, 180, SERVO_MIN_PULSE, SERVO_MAX_PULSE)
        pwm = map(pulse_width, 0, 20000, 0, 100)
        p.ChangeDutyCycle(pwm) # Mappa l'angolo al duty cycle e lo applica

    def doorbell():
        for i in range(1, len(song)):        # Riproduci il brano 1
            Buzz.ChangeFrequency(song[i])    # Cambia la frequenza in base alla nota della canzone
            time.sleep(beat[i] * 0.25)        # Ritarda una nota per beat * 0.25s
        time.sleep(1)                        # Attendi un secondo per la prossima canzone.

    def closedoor():
        GPIO.output(ledPin, GPIO.LOW)
        for i in range(180, -1, -1): # Fa ruotare il servo da 180 a 0 gradi
            setAngle(i)
            time.sleep(0.001)
        time.sleep(1)

    def opendoor():
        GPIO.output(ledPin, GPIO.HIGH)
        for i in range(0, 181, 1):   # Fa ruotare il servo da 0 a 180 gradi
            setAngle(i)     # Scrivi sul servo
            time.sleep(0.001)
        time.sleep(1)
        doorbell()
        closedoor()

    def loop():
        while True:
            if GPIO.input(pirPin)==GPIO.HIGH:
                opendoor()


    def destroy():
        GPIO.cleanup()                     # Rilascia le risorse
        p.stop()
        Buzz.stop()

    if __name__ == '__main__':     # Il programma parte da qui
        setup()
        try:
            loop()
        except KeyboardInterrupt:  # Quando viene premuto 'Ctrl+C', il programma eseguirà destroy()
            destroy()

**Spiegazione del Codice**

.. code-block:: python

    def setup():
        global p
        global Buzz                        # Assegna una variabile globale per sostituire GPIO.PWM
        GPIO.setmode(GPIO.BCM)       # Numerazione dei GPIO in base alla posizione fisica
        GPIO.setup(ledPin, GPIO.OUT)   # Imposta il ledPin come uscita
        GPIO.setup(pirPin, GPIO.IN)    # Imposta il sensorPin come ingresso
        GPIO.setup(buzPin, GPIO.OUT)    # Imposta i pin come uscite
        Buzz = GPIO.PWM(buzPin, 440)    # 440 è la frequenza iniziale.
        Buzz.start(50)                    # Avvia il pin del buzzer con un duty cycle del 50%
        GPIO.setup(servoPin, GPIO.OUT)   # Imposta il servoPin come uscita
        GPIO.output(servoPin, GPIO.LOW)  # Imposta il servoPin su low
        p = GPIO.PWM(servoPin, 50)     # Imposta la frequenza a 50Hz
        p.start(0)                     # Duty Cycle = 0

Queste istruzioni servono per inizializzare i pin di ciascun componente.

.. code-block:: python

    def setAngle(angle):      # Fa ruotare il servo ad un angolo specifico (0-180 gradi) 
        angle = max(0, min(180, angle))
        pulse_width = map(angle, 0, 180, SERVO_MIN_PULSE, SERVO_MAX_PULSE)
        pwm = map(pulse_width, 0, 20000, 0, 100)
        p.ChangeDutyCycle(pwm) # Mappa l'angolo al duty cycle e lo applica

Crea una funzione, ``servowrite`` per impostare l'angolo del servo tra 0 e 180 gradi.

.. code-block:: python

    def doorbell():
        for i in range(1,len(song)): # Riproduci il brano1
            Buzz.ChangeFrequency(song[i]) # Cambia la frequenza in base alla nota della canzone
            time.sleep(beat[i] * 0.25) # Ritarda una nota per beat * 0.25s

Crea una funzione, ``doorbell`` per far suonare la musica al buzzer.

.. code-block:: python

    def closedoor():
        GPIO.output(ledPin, GPIO.LOW)
        Buzz.ChangeFrequency(1)
        for i in range(180, -1, -1): # Fa ruotare il servo da 180 a 0 gradi
            setAngle(i)
            time.sleep(0.001)

Chiude la porta e spegne la spia.

.. code-block:: python

    def opendoor():
        GPIO.output(ledPin, GPIO.HIGH)
        for i in range(0, 181, 1):   # Fa ruotare il servo da 0 a 180 gradi
            setAngle(i)     # Scrivi sul servo
            time.sleep(0.001)
        doorbell()
        closedoor()

La funzione, ``opendoor()`` consiste in diverse parti: accende la spia, ruota 
il servo (per simulare l'apertura della porta), suona la musica del campanello 
del negozio e chiama la funzione ``closedoor()`` dopo la musica.

.. code-block:: python

    def loop():
    while True:
        if GPIO.input(pirPin)==GPIO.HIGH:
            opendoor()

Quando il PIR rileva il passaggio di qualcuno, chiama la funzione, ``opendoor()``.

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

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