.. note::
Ciao, benvenuto nella Community di SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts su Facebook! Approfondisci le tue conoscenze su Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.
**Perché Unirsi?**
- **Supporto Tecnico Esperto**: Risolvi i problemi post-vendita e affronta 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.
- **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!
.. _4.1.7_py_pi5:
4.1.4 Dispositivo Contatore
================================
Introduzione
------------
In questo progetto realizzeremo un sistema contatore che visualizza i numeri,
composto da un sensore PIR e un display a 4 cifre a segmenti. Quando il PIR rileva
il passaggio di una persona, il numero sul display a 4 cifre aumenterà di 1. Puoi
utilizzare questo contatore per contare il numero di persone che attraversano un passaggio.
Componenti Necessari
------------------------
In questo progetto, abbiamo bisogno dei seguenti componenti.
.. image:: ../python_pi5/img/4.1.7_counting_device_list_1.png
:align: center
.. image:: ../python_pi5/img/4.1.7_counting_device_list_2.png
:align: center
È decisamente conveniente 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 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:: ../python_pi5/img/4.1.7_counting_device_schematic.png
:align: center
Procedure Sperimentali
--------------------------
**Passo 1:** Costruisci il circuito.
.. image:: ../python_pi5/img/4.1.7_counting_device_circuit.png
**Passo 2:** Vai nella cartella del codice.
.. raw:: html
.. code-block::
cd ~/raphael-kit/python-pi5
**Passo 3:** Esegui il file eseguibile.
.. raw:: html
.. code-block::
sudo python3 4.1.7_CountingDevice_zero.py
Dopo l'esecuzione del codice, quando il PIR rileva il passaggio di qualcuno,
il numero sul display a 4 cifre aumenterà di 1.
Ci sono due potenziometri sul modulo PIR: uno per regolare la sensibilità e l'altro per regolare la distanza di rilevamento. Per far funzionare meglio il modulo PIR, è necessario ruotarli entrambi completamente in senso antiorario.
.. image:: ../python_pi5/img/4.1.7_PIR_TTE.png
:width: 400
:align: center
.. warning::
Se viene visualizzato l'errore ``RuntimeError: Cannot determine SOC peripheral base address``, fare riferimento a :ref:`faq_soc`.
**Code**
.. note::
Puoi **Modificare/Reimpostare/Copiare/Eseguire/Interrompere** il codice qui sotto. Ma prima di farlo, devi andare nel percorso sorgente del codice come ``raphael-kit/python-pi5``. Dopo aver modificato il codice, puoi eseguirlo direttamente per vedere l'effetto.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import OutputDevice, MotionSensor
# Inizializza il sensore PIR sul GPIO 26
pir = MotionSensor(26)
# Inizializza i pin del registro a scorrimento
SDI = OutputDevice(24) # Ingresso Dati Seriale
RCLK = OutputDevice(23) # Ingresso Clock del Registro
SRCLK = OutputDevice(18) # Ingresso Clock del Registro a Scorrimento
# Inizializza i pin del display a 7 segmenti
placePin = [OutputDevice(pin) for pin in (10, 22, 27, 17)]
# Definisce i codici delle cifre per il display a 7 segmenti
number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90)
# Contatore per il numero visualizzato
counter = 0
def clearDisplay():
# Cancella il display spegnendo tutti i segmenti
for _ in range(8):
SDI.on()
SRCLK.on()
SRCLK.off()
RCLK.on()
RCLK.off()
def hc595_shift(data):
# Inserisce i dati nel registro a scorrimento 74HC595
for i in range(8):
SDI.value = 0x80 & (data << i)
SRCLK.on()
SRCLK.off()
RCLK.on()
RCLK.off()
def pickDigit(digit):
# Attiva una specifica cifra del display a 7 segmenti
for pin in placePin:
pin.off()
placePin[digit].on()
def display():
# Aggiorna il display con il valore corrente del contatore
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():
# Ciclo principale per aggiornare il display e controllare il movimento
global counter
currentState = 0
lastState = 0
while True:
display()
currentState = 1 se il sensore PIR rileva movimento else 0
if currentState == 1 e lastState == 0:
counter += 1
lastState = currentState
try:
loop()
except KeyboardInterrupt:
# Spegni tutti i pin quando lo script viene interrotto
SDI.off()
SRCLK.off()
RCLK.off()
pass
**Spiegazione del Codice**
#. Questa riga importa le classi ``OutputDevice`` e ``MotionSensor`` dalla libreria ``gpiozero``. ``OutputDevice`` può essere un LED, un motore o qualsiasi dispositivo che si desidera controllare come uscita. Il ``MotionSensor`` è tipicamente un sensore PIR (Passive Infrared) utilizzato per rilevare il movimento.
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import OutputDevice, MotionSensor
#. Inizializza il sensore di movimento PIR collegato al pin GPIO 26.
.. code-block:: python
# Inizializza il sensore PIR sul GPIO 26
pir = MotionSensor(26)
#. Inizializza i pin GPIO collegati all'Ingresso Dati Seriale (SDI), all'Ingresso Clock del Registro (RCLK) e all'Ingresso Clock del Registro a Scorrimento (SRCLK) del registro a scorrimento.
.. code-block:: python
# Inizializza i pin del registro a scorrimento
SDI = OutputDevice(24) # Ingresso Dati Seriale
RCLK = OutputDevice(23) # Ingresso Clock del Registro
SRCLK = OutputDevice(18) # Ingresso Clock del Registro a Scorrimento
#. Inizializza i pin per ciascuna cifra del display a 7 segmenti e definisce i codici binari per visualizzare i numeri da 0 a 9.
.. code-block:: python
# Inizializza i pin del display a 7 segmenti
placePin = [OutputDevice(pin) for pin in (10, 22, 27, 17)]
# Definisce i codici delle cifre per il display a 7 segmenti
number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90)
#. Cancella il display a 7 segmenti spegnendo tutti i segmenti prima di visualizzare la cifra successiva.
.. code-block:: python
def clearDisplay():
# Cancella il display spegnendo tutti i segmenti
for _ in range(8):
SDI.on()
SRCLK.on()
SRCLK.off()
RCLK.on()
RCLK.off()
#. Inserisce un byte di dati nel registro a scorrimento 74HC595, controllando i segmenti del display.
.. code-block:: python
def hc595_shift(data):
# Inserisce i dati nel registro a scorrimento 74HC595
for i in range(8):
SDI.value = 0x80 & (data << i)
SRCLK.on()
SRCLK.off()
RCLK.on()
RCLK.off()
#. Seleziona quale cifra del display a 7 segmenti attivare. Ogni cifra è controllata da un pin GPIO separato.
.. code-block:: python
def pickDigit(digit):
# Attiva una specifica cifra del display a 7 segmenti
for pin in placePin:
pin.off()
placePin[digit].on()
#. Inizia visualizzando prima la cifra dell'unità, seguita dall'attivazione della cifra delle decine. Successivamente, attiva le cifre delle centinaia e delle migliaia in ordine. Questa rapida successione di attivazioni crea l'illusione di un display continuo a quattro cifre.
.. code-block:: python
def display():
# Aggiorna il display con il valore corrente del contatore
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])
#. Definisce il ciclo principale in cui il display viene continuamente aggiornato e lo stato del sensore PIR viene controllato. Se viene rilevato un movimento, il contatore viene incrementato.
.. code-block:: python
def loop():
# Ciclo principale per aggiornare il display e controllare il movimento
global counter
currentState = 0
lastState = 0
while True:
display()
currentState = 1 if pir.motion_detected else 0
if currentState == 1 and lastState == 0:
counter += 1
lastState = currentState
#. Esegue il ciclo principale e garantisce che lo script possa essere interrotto con un comando da tastiera (Ctrl+C), spegnendo tutti i pin per una chiusura pulita.
.. code-block:: python
try:
loop()
except KeyboardInterrupt:
# Spegni tutti i pin quando lo script viene interrotto
SDI.off()
SRCLK.off()
RCLK.off()
pass