.. 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.7_py:

4.1.7 Dispositivo Contatore
==========================================

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

In questo progetto realizzeremo un sistema di conteggio con display a 4 cifre, 
composto da un sensore PIR e un display a 4 segmenti. Quando il sensore PIR rileva 
il passaggio di qualcuno, il numero sul display a 4 cifre incrementerà di 1. Puoi 
utilizzare questo contatore per conteggiare il numero di persone che passano attraverso 
un passaggio.

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

In questo progetto, avremo bisogno dei seguenti componenti.

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

.. image:: ../img/list_Counting_Device2.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_4_digit`
        - \-
    *   - :ref:`cpn_74hc595`
        - |link_74hc595_buy|
    *   - :ref:`cpn_pir`
        - \-


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

============ ======== ======== ===
T-Board Name physical wiringPi BCM
GPIO17       Pin 11   0        17
GPIO27       Pin 13   2        27
GPIO22       Pin 15   3        22
SPIMOSI      Pin 19   12       10
GPIO18       Pin 12   1        18
GPIO23       Pin 16   4        23
GPIO24       Pin 18   5        24
GPIO26       Pin 37   25       26
============ ======== ======== ===

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

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

**Passo 1**: Costruisci il circuito.

.. image:: ../img/image235.png


**Passo 2**: Vai alla 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 4.1.7_CountingDevice.py

Dopo l'esecuzione del codice, quando il sensore PIR rileva il passaggio di qualcuno, 
il numero sul display a 4 cifre incrementerà di 1.

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

    sensorPin = 26

    SDI = 24
    RCLK = 23
    SRCLK = 18

    placePin = (10, 22, 27, 17)
    number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90)

    counter = 0

    def clearDisplay():
        for i in range(8):
            GPIO.output(SDI, 1)
            GPIO.output(SRCLK, GPIO.HIGH)
            GPIO.output(SRCLK, GPIO.LOW)
        GPIO.output(RCLK, GPIO.HIGH)
        GPIO.output(RCLK, GPIO.LOW)    

    def hc595_shift(data): 
        for i in range(8):
            GPIO.output(SDI, 0x80 & (data << i))
            GPIO.output(SRCLK, GPIO.HIGH)
            GPIO.output(SRCLK, GPIO.LOW)
        GPIO.output(RCLK, GPIO.HIGH)
        GPIO.output(RCLK, GPIO.LOW)

    def pickDigit(digit):
        for i in placePin:
            GPIO.output(i,GPIO.LOW)
        GPIO.output(placePin[digit], GPIO.HIGH)

    def display():
        global counter                    
        clearDisplay() 
        pickDigit(0)  
        hc595_shift(number[counter % 10])

        clearDisplay()
        pickDigit(1)
        hc595_shift(number[counter % 100//10])

        clearDisplay()
        pickDigit(2)
        hc595_shift(number[counter % 1000//100])

        clearDisplay()
        pickDigit(3)
        hc595_shift(number[counter % 10000//1000])

    def loop():
        global counter
        currentState = 0
        lastState = 0
        while True:
            display()
            currentState=GPIO.input(sensorPin)
            if (currentState == 0) and (lastState == 1):
                counter +=1
            lastState=currentState

    def setup():
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(SDI, GPIO.OUT)
        GPIO.setup(RCLK, GPIO.OUT)
        GPIO.setup(SRCLK, GPIO.OUT)
        for i in placePin:
            GPIO.setup(i, GPIO.OUT)
        GPIO.setup(sensorPin, GPIO.IN)

    def destroy():   # Quando si preme "Ctrl+C", viene eseguita la funzione.
        GPIO.cleanup()

    if __name__ == '__main__':  # Il programma parte da qui
        setup()
        try:
            loop()
        except KeyboardInterrupt:
            destroy()

**Spiegazione del codice**

Basato su :ref:`1.1.5_py`, questo progetto aggiunge il **modulo PIR** per trasformare 
il conteggio automatico in rilevamento del conteggio. Quando il PIR rileva il passaggio 
di qualcuno, il numero sul display a 4 cifre incrementerà di 1.

.. code-block:: python

    def display():
        global counter                    
        clearDisplay() 
        pickDigit(0)  
        hc595_shift(number[counter % 10])

        clearDisplay()
        pickDigit(1)
        hc595_shift(number[counter % 100//10])

        clearDisplay()
        pickDigit(2)
        hc595_shift(number[counter % 1000//100])

        clearDisplay()
        pickDigit(3)
        hc595_shift(number[counter % 10000//1000])

Prima si avvia il quarto display a segmenti e si scrive la cifra singola.
Poi si avvia il terzo display a segmenti e si scrive la cifra delle decine; 
infine, si avviano rispettivamente il secondo e il primo display a segmenti 
e si scrivono rispettivamente le cifre delle centinaia e delle migliaia. 
Grazie alla velocità di aggiornamento molto elevata, vediamo un display a 
quattro cifre completo.

.. code-block:: python

    def loop():
    global counter
        currentState = 0
        lastState = 0
        while True:
            display()
            currentState=GPIO.input(sensorPin)
            if (currentState == 0) and (lastState == 1):
                counter +=1
            lastState=currentState 

Questa è la funzione principale: visualizza il numero sul display a 4 cifre e legge 
il valore del PIR. Quando il PIR rileva il passaggio di qualcuno, il numero sul display 
a 4 cifre incrementerà di 1.

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

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