.. note::
Ciao! Benvenuto nella Community di SunFounder per appassionati di Raspberry Pi, Arduino e ESP32 su Facebook! Approfondisci il mondo di Raspberry Pi, Arduino ed ESP32 insieme a tanti altri appassionati.
**Perché unirsi?**
- **Supporto da esperti**: Risolvi problemi post-vendita e sfide tecniche con l’aiuto della nostra community e del nostro team.
- **Impara e condividi**: Scambia suggerimenti e tutorial per migliorare le tue competenze.
- **Anteprime esclusive**: Ottieni accesso anticipato alle nuove comunicazioni sui prodotti e anteprime.
- **Sconti speciali**: Approfitta di sconti esclusivi sui nostri prodotti più recenti.
- **Promozioni e concorsi**: Partecipa a giveaway e promozioni festive.
👉 Sei pronto a esplorare e creare con noi? Clicca su [|link_sf_facebook|] e unisciti oggi stesso!
3.1.7 Semaforo
=====================
Introduzione
---------------
In questo progetto utilizzeremo LED di tre colori per simulare il
cambiamento dei segnali semaforici, e un display a sette segmenti
a quattro cifre per visualizzare il conto alla rovescia per ciascuna
fase del semaforo.
Componenti
------------
.. image:: img/list_Traffic_Light.png
:align: center
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
GPIO25 Pin 22 6 25
SPICE0 Pin 24 10 8
SPICE1 Pin 26 11 7
============ ======== ======== ===
.. image:: img/Schematic_three_one7.png
:align: center
Procedure Sperimentali
---------------------------
**Passo 1:** Costruisci il circuito.
.. image:: img/image254.png
:width: 800
**Per gli Utenti C**
^^^^^^^^^^^^^^^^^^^^^^^^^^
**Passo 2:** Vai alla cartella del codice.
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/c/3.1.7/
**Passo 3:** Compila.
.. raw:: html
.. code-block::
gcc 3.1.7_TrafficLight.c -lwiringPi
**Passo 4:** Esegui.
.. raw:: html
.. code-block::
sudo ./a.out
Quando il codice viene eseguito, i LED simuleranno il cambio di colore
del semaforo. Prima si accende il LED rosso per 60 secondi, poi il verde
per 30 secondi e infine il giallo per 5 secondi. Dopo questo, il LED rosso
si riaccenderà per altri 60 secondi, ripetendo questa sequenza.
.. note::
Se il programma non funziona dopo l’esecuzione o appare un messaggio di
errore: \"wiringPi.h: No such file or directory\", fai riferimento a :ref:`faq_c_nowork`.
**Spiegazione del Codice**
.. code-block:: c
#define SDI 5
#define RCLK 4
#define SRCLK 1
const int placePin[] = {12, 3, 2, 0};
unsigned char number[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
void pickDigit(int digit);
void hc595_shift(int8_t data);
void clearDisplay();
void display();
Questi codici servono per realizzare la funzione di visualizzazione numerica
sul display a sette segmenti a quattro cifre. Consulta :ref:`1.1.5_4digit`
per maggiori dettagli. Qui utilizziamo il codice per visualizzare il conto alla rovescia del semaforo.
.. code-block:: c
const int ledPin[]={6,10,11};
int colorState = 0;
void lightup()
{
for(int i=0;i<3;i++){
digitalWrite(ledPin[i],HIGH);
}
digitalWrite(ledPin[colorState],LOW);
}
Questi codici servono per accendere e spegnere i LED.
.. code-block:: c
int greenLight = 30;
int yellowLight = 5;
int redLight = 60;
int colorState = 0;
char *lightColor[]={"Red","Green","Yellow"};
int counter = 60;
void timer(int timer1){ //Funzione Timer
if(timer1 == SIGALRM){
counter --;
alarm(1);
if(counter == 0){
if(colorState == 0) counter = greenLight;
if(colorState == 1) counter = yellowLight;
if(colorState == 2) counter = redLight;
colorState = (colorState+1)%3;
}
printf("counter : %d \t light color: %s \n",counter,lightColor[colorState]);
}
}
Questi codici servono per attivare e disattivare il timer. Consulta
:ref:`1.1.5_4digit` per maggiori dettagli.
Qui, quando il timer raggiunge lo zero, colorState cambierà per far
cambiare il colore del LED, e il timer verrà assegnato a un nuovo valore.
.. code-block:: c
void loop()
{
while(1){
display();
lightup();
}
}
int main(void)
{
//…
signal(SIGALRM,timer);
alarm(1);
loop();
return 0;
}
Il timer viene avviato nella funzione main(). Nella funzione loop(), viene
utilizzato un ciclo **while(1)** per chiamare le funzioni del display a 4 cifre e dei LED.
**Per gli utenti Python**
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Passo 2:** Cambia la directory.
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/python/
**Passo 3:** Esegui.
.. raw:: html
.. code-block::
sudo python3 3.1.7_TrafficLight.py
Quando il codice viene eseguito, i LED simuleranno la sequenza dei semafori:
inizialmente si accende il LED rosso per 60 secondi, seguito dal verde per 30
secondi, poi dal giallo per 5 secondi. Successivamente, il LED rosso si
riaccenderà per altri 60 secondi, ripetendo questa sequenza. Nel frattempo,
il display a 7 segmenti e 4 cifre visualizza continuamente il conto alla rovescia.
**Codice**
.. note::
Puoi **Modificare/Reset/Copiare/Eseguire/Interrompere** il codice qui sotto. Prima di ciò, devi spostarti nella directory del codice come ``davinci-kit-for-raspberry-pi/python``.
.. raw:: html
.. code-block:: python
import RPi.GPIO as GPIO
import time
import threading
# Definizione dei pin collegati al 74HC595
SDI = 24 # input dati seriali (DS)
RCLK = 23 # input di clock di memoria (STCP)
SRCLK = 18 # input di clock del registro a scorrimento (SHCP)
number = (0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90)
placePin = (10,22,27,17)
ledPin =(25,8,7)
greenLight = 30
yellowLight = 5
redLight = 60
lightColor=("Red","Green","Yellow")
colorState=0
counter = 60
timer1 = 0
def setup():
GPIO.setmode(GPIO.BCM)
GPIO.setup(SDI, GPIO.OUT)
GPIO.setup(RCLK, GPIO.OUT)
GPIO.setup(SRCLK, GPIO.OUT)
for pin in placePin:
GPIO.setup(pin,GPIO.OUT)
for pin in ledPin:
GPIO.setup(pin,GPIO.OUT)
global timer1
timer1 = threading.Timer(1.0,timer)
timer1.start()
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 timer(): # funzione timer
global counter
global colorState
global timer1
timer1 = threading.Timer(1.0,timer)
timer1.start()
counter-=1
if (counter is 0):
if(colorState is 0):
counter= greenLight
if(colorState is 1):
counter=yellowLight
if (colorState is 2):
counter=redLight
colorState=(colorState+1)%3
print ("counter : %d color: %s "%(counter,lightColor[colorState]))
def lightup():
global colorState
for i in range(0,3):
GPIO.output(ledPin[i], GPIO.HIGH)
GPIO.output(ledPin[colorState], GPIO.LOW)
def display():
global counter
a = counter % 10000//1000 + counter % 1000//100
b = counter % 10000//1000 + counter % 1000//100 + counter % 100//10
c = counter % 10000//1000 + counter % 1000//100 + counter % 100//10 + counter % 10
if (counter % 10000//1000 == 0):
clearDisplay()
else:
clearDisplay()
pickDigit(3)
hc595_shift(number[counter % 10000//1000])
if (a == 0):
clearDisplay()
else:
clearDisplay()
pickDigit(2)
hc595_shift(number[counter % 1000//100])
if (b == 0):
clearDisplay()
else:
clearDisplay()
pickDigit(1)
hc595_shift(number[counter % 100//10])
if(c == 0):
clearDisplay()
else:
clearDisplay()
pickDigit(0)
hc595_shift(number[counter % 10])
def loop():
while True:
display()
lightup()
def destroy(): # Quando si preme "Ctrl+C", la funzione viene eseguita.
global timer1
GPIO.cleanup()
timer1.cancel() # annulla il timer
if __name__ == '__main__': # Il programma parte da qui
setup()
try:
loop()
except KeyboardInterrupt:
destroy()
**Spiegazione del Codice**
.. code-block:: python
SDI = 24 # ingresso dati seriali (DS)
RCLK = 23 # ingresso clock di memoria (STCP)
SRCLK = 18 # ingresso clock del registro a scorrimento (SHCP)
number = (0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90)
placePin = (10,22,27,17)
def clearDisplay():
def hc595_shift(data):
def pickDigit(digit):
def display():
Questi codici sono usati per realizzare la visualizzazione dei numeri sul
display a 7 segmenti a 4 cifre. Consulta :ref:`1.1.5_4digit` nel documento per maggiori dettagli. Qui, utilizziamo il codice per mostrare il conto alla rovescia del tempo del semaforo.
.. code-block:: python
ledPin =(25,8,7)
colorState=0
def lightup():
global colorState
for i in range(0,3):
GPIO.output(ledPin[i], GPIO.HIGH)
GPIO.output(ledPin[colorState], GPIO.LOW)
Questo codice è usato per accendere e spegnere i LED.
.. code-block:: python
greenLight = 30
yellowLight = 5
redLight = 60
lightColor=("Red","Green","Yellow")
colorState=0
counter = 60
timer1 = 0
def timer(): # funzione timer
global counter
global colorState
global timer1
timer1 = threading.Timer(1.0,timer)
timer1.start()
counter-=1
if (counter is 0):
if(colorState is 0):
counter= greenLight
if(colorState is 1):
counter=yellowLight
if (colorState is 2):
counter=redLight
colorState=(colorState+1)%3
print ("counter : %d color: %s "%(counter,lightColor[colorState]))
Questo codice attiva e disattiva il timer. Consulta :ref:`1.1.5_4digit`
per maggiori dettagli. Qui, quando il timer raggiunge lo zero, il valore di colorState viene
aggiornato per cambiare il LED, e il timer viene impostato con un nuovo valore.
.. code-block:: python
def setup():
# ...
global timer1
timer1 = threading.Timer(1.0,timer)
timer1.start()
def loop():
while True:
display()
lightup()
def destroy(): # Quando si preme "Ctrl+C", viene eseguita la funzione.
global timer1
GPIO.cleanup()
timer1.cancel() # annulla il timer
if __name__ == '__main__': # Il programma parte da qui
setup()
try:
loop()
except KeyboardInterrupt:
destroy()
Nella funzione setup(), il timer viene avviato. Nella funzione loop(),
viene usato un ciclo ``while True`` per chiamare ciclicamente le funzioni
relative al display a 7 segmenti a 4 cifre e ai LED.
Immagine del Fenomeno
----------------------------
.. image:: img/IMG_8319.jpg
:width: 800
:align: center