.. note::
Ciao, benvenuto nella Community di appassionati di SunFounder Raspberry Pi & Arduino & ESP32 su Facebook! Approfondisci Raspberry Pi, Arduino ed ESP32 insieme agli altri appassionati.
**Perché unirti a noi?**
- **Supporto esperto**: 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 a nuovi annunci di prodotti e anteprime.
- **Sconti speciali**: Godi di sconti esclusivi sui nostri prodotti più recenti.
- **Promozioni festive e omaggi**: Partecipa a omaggi e promozioni speciali per le festività.
👉 Sei pronto a esplorare e creare con noi? Clicca su [|link_sf_facebook|] e unisciti oggi stesso!
.. _3.1.6_c:
3.1.6 Semaforo
============================
Introduzione
---------------
In questo progetto, useremo luci LED di tre colori per simulare il
cambiamento del semaforo e utilizzeremo un display a 4 cifre a 7
segmenti per visualizzare il tempo di ciascun stato del traffico.
Componenti necessari
------------------------------
In questo progetto, avremo bisogno dei seguenti componenti.
.. image:: ../img/list_Traffic_Light.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 acquistare i componenti separatamente dai link qui sotto.
.. list-table::
:widths: 30 20
:header-rows: 1
* - INTRODUZIONE COMPONENTI
- LINK DI 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_4_digit`
- \-
* - :ref:`cpn_74hc595`
- |link_74hc595_buy|
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
Procedura sperimentale
-------------------------
**Passo 1:** Costruisci il circuito.
.. image:: ../img/image254.png
**Passo 2:** Cambia directory.
.. raw:: html
.. code-block::
cd ~/raphael-kit/c/3.1.6/
**Passo 3:** Compila.
.. raw:: html
.. code-block::
gcc 3.1.6_TrafficLight.c -lwiringPi
**Passo 4:** Esegui.
.. raw:: html
.. code-block::
sudo ./a.out
Durante l'esecuzione del codice, i LED simuleranno il cambio dei colori
del semaforo. Per prima cosa, il LED rosso si accende per 60 secondi,
poi il LED verde si accende per 30 secondi; successivamente, il LED giallo
si accende per 5 secondi. Dopo di ciò, il LED rosso si accenderà di nuovo
per 60 secondi. In questo modo, questa serie di azioni verrà eseguita ripetutamente.
.. note::
Se non funziona dopo l'esecuzione, o appare un errore come: \"wiringPi.h: Nessun file o directory\", fai riferimento a :ref:`install_wiringpi`.
Codice
---------
.. code-block:: c
#include
#include
#include
#include
#include
#define SDI 5
#define RCLK 4
#define SRCLK 1
const int ledPin[]={6,10,11};
const int placePin[] = {12, 3, 2, 0};
unsigned char number[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
int greenLight = 30;
int yellowLight = 5;
int redLight = 60;
int colorState = 0;
char *lightColor[]={"Red","Green","Yellow"};
int counter = 60;
void lightup()
{
for(int i=0;i<3;i++){
digitalWrite(ledPin[i],HIGH);
}
digitalWrite(ledPin[colorState],LOW);
}
void pickDigit(int digit)
{
for (int i = 0; i < 4; i++)
{
digitalWrite(placePin[i], 0);
}
digitalWrite(placePin[digit], 1);
}
void hc595_shift(int8_t data)
{
int i;
for (i = 0; i < 8; i++)
{
digitalWrite(SDI, 0x80 & (data << i));
digitalWrite(SRCLK, 1);
delayMicroseconds(1);
digitalWrite(SRCLK, 0);
}
digitalWrite(RCLK, 1);
delayMicroseconds(1);
digitalWrite(RCLK, 0);
}
void clearDisplay()
{
int i;
for (i = 0; i < 8; i++)
{
digitalWrite(SDI, 1);
digitalWrite(SRCLK, 1);
delayMicroseconds(1);
digitalWrite(SRCLK, 0);
}
digitalWrite(RCLK, 1);
delayMicroseconds(1);
digitalWrite(RCLK, 0);
}
void display()
{
int a,b,c;
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]);
}
}
void loop()
{
while(1){
display();
lightup();
}
}
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]);
}
}
int main(void)
{
int i;
if(wiringPiSetup() == -1){
printf("setup wiringPi failed !");
return 1;
}
pinMode(SDI,OUTPUT);
pinMode(RCLK,OUTPUT);
pinMode(SRCLK,OUTPUT);
for(i=0;i<4;i++){
pinMode(placePin[i],OUTPUT);
digitalWrite(placePin[i],HIGH);
}
for(i=0;i<3;i++){
pinMode(ledPin[i],OUTPUT);
digitalWrite(ledPin[i],HIGH);
}
signal(SIGALRM,timer);
alarm(1);
loop();
return 0;
}
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 dei
numeri del display a 4 cifre e 7 segmenti. Consulta il capitolo 1.1.5
del documento per ulteriori dettagli. Qui usiamo i codici per visualizzare
il conto alla rovescia del tempo 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);
}
I codici vengono utilizzati 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]);
}
}
I codici vengono utilizzati per attivare e disattivare il timer. Consulta il capitolo 1.1.5 per ulteriori dettagli. Qui, quando il timer torna a zero, colorState verrà modificato in modo da cambiare il 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 **while(1)** per richiamare le funzioni del display a 4 cifre e
7 segmenti e dei LED.
Foto del fenomeno
-----------------------
.. image:: ../img/IMG_8319.jpg
:align: center