Nota

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 [Qui] e unisciti oggi stesso!

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.

../_images/list_Traffic_Light.png

È sicuramente conveniente acquistare un kit completo, ecco il link:

Nome

ELEMENTI IN QUESTO KIT

LINK

Kit Raphael

337

Raphael Kit

Puoi anche acquistare i componenti separatamente dai link qui sotto.

INTRODUZIONE COMPONENTI

LINK DI ACQUISTO

Scheda di estensione GPIO

ACQUISTA

Breadboard

ACQUISTA

Cavi Jumper

ACQUISTA

Resistore

ACQUISTA

LED

ACQUISTA

Display a 7 Segmenti da 4 Cifre

-

74HC595

ACQUISTA

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

../_images/Schematic_three_one7.png

Procedura sperimentale

Passo 1: Costruisci il circuito.

../_images/image254.png

Passo 2: Cambia directory.

cd ~/raphael-kit/c/3.1.6/

Passo 3: Compila.

gcc 3.1.6_TrafficLight.c -lwiringPi

Passo 4: Esegui.

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.

Nota

Se non funziona dopo l’esecuzione, o appare un errore come: "wiringPi.h: Nessun file o directory", fai riferimento a Installa e Controlla wiringPi.

Codice

#include <wiringPi.h>
#include <stdio.h>
#include <wiringShift.h>
#include <signal.h>
#include <unistd.h>
#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

#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.

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.

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.

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

../_images/IMG_8319.jpg