Nota

Ciao, benvenuto nella Community su Facebook per gli appassionati di SunFounder Raspberry Pi, Arduino ed ESP32! Esplora più a fondo Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.

Perché unirsi?

  • Supporto Esperto: Risolvi problemi post-vendita e 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 dei nuovi prodotti e anticipazioni.

  • Sconti Speciali: Approfitta di sconti esclusivi sui nostri prodotti più recenti.

  • Promozioni Festive e Giveaway: Partecipa a giveaway e promozioni festive.

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

3.1.2 Benvenuto

Introduzione

In questo progetto, utilizzeremo un sensore PIR per rilevare il movimento dei passanti, e useremo un servo, un LED e un buzzer per simulare il funzionamento della porta automatica di un negozio. Quando un passante entra nel raggio di rilevamento del PIR, la luce di indicazione si accenderà, la porta si aprirà e il buzzer riprodurrà il suono del campanello d’apertura.

Componenti Necessari

In questo progetto, ci servono i seguenti componenti.

../_images/4.1.8_welcome_list.png

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

../_images/4.1.8_welcome_schematic.png

Procedura Sperimentale

Passo 1: Monta il circuito.

../_images/4.1.8_welcome_circuit.png

Passo 2: Cambia directory.

cd ~/davinci-kit-for-raspberry-pi/python-pi5

Passo 3: Esegui il file.

sudo python3 3.1.2_Welcome.py

Dopo aver eseguito il codice, se il sensore PIR rileva una persona in avvicinamento, la porta si aprirà automaticamente (simulata dal servo), accenderà l’indicatore luminoso e suonerà il campanello d’ingresso. Al termine del suono del campanello, il sistema chiuderà automaticamente la porta e spegnerà la luce indicatrice, attendendo il passaggio successivo.

Sul modulo PIR ci sono due potenziometri: uno per regolare la sensibilità e l’altro per regolare la distanza di rilevamento. Per far funzionare meglio il modulo PIR, è consigliabile ruotarli entrambi in senso antiorario fino alla fine.

../_images/4.1.8_PIR_TTE.png

Avvertimento

Se compare un errore con il messaggio RuntimeError: Cannot determine SOC peripheral base address, fai riferimento a Se gpiozero non funziona.

Codice

Nota

Puoi Modificare/Reimpostare/Copiare/Eseguire/Interrompere il codice qui sotto. Prima di procedere, assicurati di essere nel percorso sorgente, ad esempio davinci-kit-for-raspberry-pi/python-pi5. Dopo aver modificato il codice, puoi eseguirlo direttamente per vedere l’effetto.

#!/usr/bin/env python3

from gpiozero import LED, MotionSensor, Servo, TonalBuzzer
import time

# Configurazione dei pin GPIO per LED, sensore di movimento (PIR) e buzzer
ledPin = LED(6)
pirPin = MotionSensor(21)
buzPin = TonalBuzzer(27)

# Fattore di correzione per larghezza impulso del servo e calcolo
myCorrection = 0.45
maxPW = (2.0 + myCorrection) / 1000  # Larghezza massima impulso
minPW = (1.0 - myCorrection) / 1000  # Larghezza minima impulso

# Inizializza servo con larghezze impulso personalizzate
servoPin = Servo(25, min_pulse_width=minPW, max_pulse_width=maxPW)

# Melodia per il buzzer, con note e durate
tune = [('C#4', 0.2), ('D4', 0.2), (None, 0.2),
        ('Eb4', 0.2), ('E4', 0.2), (None, 0.6),
        ('F#4', 0.2), ('G4', 0.2), (None, 0.6),
        ('Eb4', 0.2), ('E4', 0.2), (None, 0.2),
        ('F#4', 0.2), ('G4', 0.2), (None, 0.2),
        ('C4', 0.2), ('B4', 0.2), (None, 0.2),
        ('F#4', 0.2), ('G4', 0.2), (None, 0.2),
        ('B4', 0.2), ('Bb4', 0.5), (None, 0.6),
        ('A4', 0.2), ('G4', 0.2), ('E4', 0.2),
        ('D4', 0.2), ('E4', 0.2)]

def setAngle(angle):
    """
    Move the servo to a specified angle.
    :param angle: Angle in degrees (0-180).
    """
    value = float(angle / 180)  # Converte l'angolo in valore per il servo
    servoPin.value = value      # Imposta la posizione del servo
    time.sleep(0.001)           # Breve pausa per il movimento del servo

def doorbell():
    """
    Play a musical tune using the buzzer.
    """
    for note, duration in tune:
        buzPin.play(note)       # Riproduce la nota
        time.sleep(float(duration))  # Durata della nota
    buzPin.stop()               # Ferma il buzzer dopo la melodia

def closedoor():
    # Spegne il LED e muove il servo per chiudere la porta
    ledPin.off()
    for i in range(180, -1, -1):
        setAngle(i)             # Muove il servo da 180 a 0 gradi
        time.sleep(0.001)       # Breve pausa per movimento fluido
    time.sleep(1)               # Attesa dopo la chiusura della porta

def opendoor():
    # Accende il LED, apre la porta (muove il servo), riproduce la melodia e chiude la porta
    ledPin.on()
    for i in range(0, 181):
        setAngle(i)             # Muove il servo da 0 a 180 gradi
        time.sleep(0.001)       # Breve pausa per movimento fluido
    time.sleep(1)               # Attesa prima di riprodurre la melodia
    doorbell()                  # Riproduce la melodia del campanello
    closedoor()                 # Chiude la porta dopo la melodia

def loop():
    # Loop principale per controllare il movimento e operare la porta
    while True:
        if pirPin.motion_detected:
            opendoor()               # Apre la porta se viene rilevato movimento
        time.sleep(0.1)              # Breve pausa nel loop

try:
    loop()
except KeyboardInterrupt:
    # Pulisce i GPIO in caso di interruzione (es. Ctrl+C)
    buzPin.stop()
    ledPin.off()

Spiegazione del Codice

  1. Lo script inizia importando i moduli necessari. La libreria gpiozero è utilizzata per interfacciarsi con il LED, il sensore di movimento, il motore servo e il buzzer tonale. Il modulo time è impiegato per gestire le funzioni legate al timing.

    #!/usr/bin/env python3
    from gpiozero import LED, MotionSensor, Servo, TonalBuzzer
    import time
    
  2. Inizializza il LED, il sensore di movimento PIR e il buzzer tonale sui rispettivi pin GPIO.

    # Configurazione dei pin GPIO per LED, sensore di movimento (PIR) e buzzer
    ledPin = LED(6)
    pirPin = MotionSensor(21)
    buzPin = TonalBuzzer(27)
    
  3. Calcola la larghezza degli impulsi massima e minima per il motore servo, incorporando un fattore di correzione per una regolazione più precisa.

    # Fattore di correzione per la larghezza degli impulsi del servo
    myCorrection = 0.45
    maxPW = (2.0 + myCorrection) / 1000  # Larghezza massima dell'impulso
    minPW = (1.0 - myCorrection) / 1000  # Larghezza minima dell'impulso
    
  4. Inizializza il motore servo sul pin GPIO 25 con le larghezze di impulso personalizzate per un posizionamento accurato.

    # Inizializzazione del servo con larghezze di impulso personalizzate
    servoPin = Servo(25, min_pulse_width=minPW, max_pulse_width=maxPW)
    
  5. La melodia è definita come una sequenza di note (frequenze) e durate (secondi).

    # Melodia per il buzzer, con note e durate
    tune = [('C#4', 0.2), ('D4', 0.2), (None, 0.2),
            ('Eb4', 0.2), ('E4', 0.2), (None, 0.6),
            ('F#4', 0.2), ('G4', 0.2), (None, 0.6),
            ('Eb4', 0.2), ('E4', 0.2), (None, 0.2),
            ('F#4', 0.2), ('G4', 0.2), (None, 0.2),
            ('C4', 0.2), ('B4', 0.2), (None, 0.2),
            ('F#4', 0.2), ('G4', 0.2), (None, 0.2),
            ('B4', 0.2), ('Bb4', 0.5), (None, 0.6),
            ('A4', 0.2), ('G4', 0.2), ('E4', 0.2),
            ('D4', 0.2), ('E4', 0.2)]
    
  6. Funzione per muovere il servo a un angolo specificato. Converte l’angolo in un valore tra 0 e 1 per il servo.

    def setAngle(angle):
        """
        Move the servo to a specified angle.
        :param angle: Angle in degrees (0-180).
        """
        value = float(angle / 180)  # Converte l'angolo in valore per il servo
        servoPin.value = value      # Imposta la posizione del servo
        time.sleep(0.001)           # Breve pausa per il movimento del servo
    
  7. Funzione per riprodurre una melodia usando il buzzer. Scorre la lista tune riproducendo ciascuna nota per la durata specificata.

    def doorbell():
        """
        Play a musical tune using the buzzer.
        """
        for note, duration in tune:
            buzPin.play(note)       # Riproduce la nota
            time.sleep(float(duration))  # Durata della nota
        buzPin.stop()               # Ferma il buzzer dopo la melodia
    
  8. Funzioni per aprire e chiudere la porta usando il motore servo. La funzione opendoor accende il LED, apre la porta, riproduce la melodia e poi chiude la porta.

    def closedoor():
        # Spegne il LED e muove il servo per chiudere la porta
        ledPin.off()
        for i in range(180, -1, -1):
            setAngle(i)             # Muove il servo da 180 a 0 gradi
            time.sleep(0.001)       # Breve pausa per movimento fluido
        time.sleep(1)               # Attesa dopo la chiusura della porta
    
    def opendoor():
        # Accende il LED, apre la porta (muove il servo), riproduce la melodia, chiude la porta
        ledPin.on()
        for i in range(0, 181):
            setAngle(i)             # Muove il servo da 0 a 180 gradi
            time.sleep(0.001)       # Breve pausa per movimento fluido
        time.sleep(1)               # Attesa prima della melodia
        doorbell()                  # Riproduce la melodia del campanello
        closedoor()                 # Chiude la porta dopo la melodia
    
  9. Loop principale che controlla costantemente il rilevamento di movimento. Quando viene rilevato movimento, attiva la funzione opendoor.

    def loop():
        # Loop principale per verificare movimento e operare la porta
        while True:
            if pirPin.motion_detected:
                opendoor()               # Apre la porta se rileva movimento
            time.sleep(0.1)              # Breve pausa nel loop
    
  10. Esegue il loop principale e garantisce che lo script possa essere interrotto con un comando di tastiera (Ctrl+C), spegnendo il buzzer e il LED per un’uscita pulita.

    try:
        loop()
    except KeyboardInterrupt:
        # Pulisce i GPIO in caso di interruzione (es. Ctrl+C)
        buzPin.stop()
        ledPin.off()