.. note::
Hallo und willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Gemeinschaft auf Facebook! Tauchen Sie tiefer ein in die Welt von Raspberry Pi, Arduino und ESP32 mit anderen Enthusiasten.
**Warum beitreten?**
- **Expertenunterstützung**: Lösen Sie Nachverkaufsprobleme und technische Herausforderungen mit Hilfe unserer Gemeinschaft und unseres Teams.
- **Lernen & Teilen**: Tauschen Sie Tipps und Anleitungen aus, um Ihre Fähigkeiten zu verbessern.
- **Exklusive Vorschauen**: Erhalten Sie frühzeitigen Zugang zu neuen Produktankündigungen und exklusiven Einblicken.
- **Spezialrabatte**: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.
- **Festliche Aktionen und Gewinnspiele**: Nehmen Sie an Gewinnspielen und Feiertagsaktionen teil.
👉 Sind Sie bereit, mit uns zu erkunden und zu erschaffen? Klicken Sie auf [|link_sf_facebook|] und treten Sie heute bei!
.. _3.1.6_c:
3.1.6 Verkehrsampel
=========================
Einführung
---------------
In diesem Projekt nutzen wir LED-Leuchten in drei Farben, um den
Wechsel von Verkehrsampeln darzustellen. Zudem wird eine vierstellige 7-Segment-Anzeige verwendet,
um die Zeitdauer jeder Ampelphase anzuzeigen.
Benötigte Komponenten
------------------------------
Für dieses Projekt benötigen wir die folgenden Komponenten.
.. image:: ../img/list_Traffic_Light.png
:align: center
Es ist definitiv praktisch, gleich ein ganzes Set zu kaufen. Hier ist der Link:
.. list-table::
:widths: 20 20 20
:header-rows: 1
* - Name
- ARTIKEL IN DIESEM KIT
- LINK
* - Raphael Kit
- 337
- |link_Raphael_kit|
Sie können die Teile aber auch einzeln über die untenstehenden Links erwerben.
.. list-table::
:widths: 30 20
:header-rows: 1
* - KOMPONENTENBESCHREIBUNG
- KAUF-LINK
* - :ref:`cpn_gpio_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|
Schaltplan
--------------------
============ ======== ======== ===
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
Experimentelle Verfahren
----------------------------
**Schritt 1:** Schaltung aufbauen.
.. image:: ../img/image254.png
**Schritt 2:** Verzeichnis wechseln.
.. raw:: html
.. code-block::
cd ~/raphael-kit/c/3.1.6/
**Schritt 3:** Kompilieren.
.. raw:: html
.. code-block::
gcc 3.1.6_TrafficLight.c -lwiringPi
**Schritt 4:** Programm ausführen.
.. raw:: html
.. code-block::
sudo ./a.out
Während das Programm läuft, simulieren die LEDs den Farbwechsel von
Verkehrsampeln. Zuerst leuchtet die rote LED 60s lang, dann die grüne LED
für 30s und anschließend die gelbe LED für 5s. Danach leuchtet wieder die rote LED für 60s.
Dieser Ablauf wiederholt sich fortlaufend.
.. note::
Wenn nach dem Starten ein Problem auftritt oder die Fehlermeldung: \"wiringPi.h: No such file or directory\" erscheint, verweisen Sie bitte auf :ref:`install_wiringpi`.
Code
---------
.. 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){ //Timer function
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;
}
Code-Erklärung
--------------------
.. 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();
Diese Codes dienen dazu, die Anzeigefunktion von 4-stelligen 7-Segment-Anzeigen zu realisieren. Für weitere Details verweisen Sie bitte auf Kapitel 1.1.5 des Dokuments. Hier nutzen wir die Codes, um den Countdown der Ampelzeit anzuzeigen.
.. 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);
}
Die Codes werden verwendet, um die LED ein- und auszuschalten.
.. 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){ //Timer function
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]);
}
}
Die Codes werden verwendet, um den Timer ein- und auszuschalten. Weitere Details finden Sie im Kapitel
1.1.5. Hier wird, wenn der Timer null erreicht, der ``colorState`` gewechselt, um die LED umzuschalten, und der Timer erhält einen neuen Wert.
.. code-block:: c
void loop()
{
while(1){
display();
lightup();
}
}
int main(void)
{
//…
signal(SIGALRM,timer);
alarm(1);
loop();
return 0;
}
Der Timer wird in der ``main()`` Funktion gestartet. In der ``loop()`` Funktion wird eine
**while(1)** Schleife verwendet und die Funktionen von 4-stelligen 7-Segment-Anzeigen und LED aufgerufen.
Phänomen-Bild
-------------------
.. image:: ../img/IMG_8319.jpg
:align: center