.. note::
こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ!Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。
**参加する理由は?**
- **エキスパートサポート**:コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。
- **学び&共有**:ヒントやチュートリアルを交換してスキルを向上させましょう。
- **独占的なプレビュー**:新製品の発表や先行プレビューに早期アクセスしましょう。
- **特別割引**:最新製品の独占割引をお楽しみください。
- **祭りのプロモーションとギフト**:ギフトや祝日のプロモーションに参加しましょう。
👉 私たちと一緒に探索し、創造する準備はできていますか?[|link_sf_facebook|]をクリックして今すぐ参加しましょう!
.. _4.1.12_py_pi5:
4.1.9 交通信号灯
========================
概要
---------------
このプロジェクトでは、3つの色のLEDライトを使用して交通信号の変更を実現し、
4桁の7セグメントディスプレイを使用して各交通状態のタイミングを表示します。
必要な部品
------------------------------
このプロジェクトには、次のコンポーネントが必要です。
.. image:: ../python_pi5/img/4.1.12_traffic_light_list.png
:width: 800
:align: center
一式を購入するのが便利です、こちらがリンクです:
.. list-table::
:widths: 20 20 20
:header-rows: 1
* - 名前
- このキットのアイテム
- リンク
* - Raphael Kit
- 337
- |link_Raphael_kit|
以下のリンクから別々に購入することもできます。
.. list-table::
:widths: 30 20
:header-rows: 1
* - コンポーネントの紹介
- 購入リンク
* - :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|
配線図
--------------------
============ ======== ======== ===
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:: ../python_pi5/img/4.1.12_traffic_light_schematic.png
:align: center
実験手順
------------------------
**ステップ 1:** 回路を組み立てます。
.. image:: ../python_pi5/img/4.1.12_traffic_light_circuit.png
**ステップ 2:** ディレクトリを変更します。
.. raw:: html
.. code-block::
cd ~/raphael-kit/python-pi5
**ステップ 3:** 実行します。
.. raw:: html
.. code-block::
sudo python3 3.1.7_TrafficLight_zero.py
コードを実行すると、LEDが交通信号の色変更をシミュレートします。最初に赤いLEDが60秒点灯し、次に緑のLEDが30秒点灯します。その後、黄色のLEDが5秒点灯します。その後、再び赤いLEDが60秒点灯します。このように、この一連のアクションが繰り返し実行されます。同時に、4桁の7セグメントディスプレイにはカウントダウン時間が連続して表示されます。
コード
----------
.. note::
以下のコードを **変更/リセット/コピー/実行/停止** することができます。ただし、それを行う前に、ソースコードのパス( ``raphael-kit/python-pi5`` のような)に移動する必要があります。コードを変更した後、それを直接実行して効果を確認できます。
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import OutputDevice, LED
import threading
# Setup GPIO pins for 74HC595 shift register
SDI = OutputDevice(24) # Serial Data Input
RCLK = OutputDevice(23) # Register Clock
SRCLK = OutputDevice(18) # Shift Register Clock
# Setup GPIO pins for digit selection on 7-segment display
placePin = [OutputDevice(pin) for pin in (10, 22, 27, 17)]
# Segment codes for numbers 0-9 on 7-segment display
number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90)
# Setup GPIO pins for traffic light LEDs
ledPinR = LED(25) # Red LED
ledPinG = LED(8) # Green LED
ledPinY = LED(7) # Yellow LED
# Duration settings for traffic lights
greenLight = 30
yellowLight = 5
redLight = 60
# Traffic light color names
lightColor = ("Red", "Green", "Yellow")
# Initialize state variables
colorState = 0
counter = 60
timer1 = None
def setup():
""" Initialize the traffic light system and start the timer. """
global timer1
timer1 = threading.Timer(1.0, timer)
timer1.start()
def clearDisplay():
""" Clear the 7-segment display. """
for _ in range(8):
SDI.on()
SRCLK.on()
SRCLK.off()
RCLK.on()
RCLK.off()
def hc595_shift(data):
""" Shift data to the 74HC595 shift register for digit display. """
for i in range(8):
SDI.value = 0x80 & (data << i)
SRCLK.on()
SRCLK.off()
RCLK.on()
RCLK.off()
def pickDigit(digit):
""" Select a specific digit to display on the 7-segment display. """
for pin in placePin:
pin.off()
placePin[digit].on()
def timer():
""" Handle the timing for traffic light changes. """
global counter, colorState, timer1
timer1 = threading.Timer(1.0, timer)
timer1.start()
counter -= 1
if counter == 0:
counter = [greenLight, yellowLight, redLight][colorState]
colorState = (colorState + 1) % 3
print(f"counter : {counter} color: {lightColor[colorState]}")
def lightup():
""" Update the traffic light LED based on the current state. """
global colorState
ledPinR.off()
ledPinG.off()
ledPinY.off()
[ledPinR, ledPinG, ledPinY][colorState].on()
def display():
""" Display the current counter value on the 7-segment display. """
global counter
for i in range(4):
digit = counter // (10 ** (3 - i)) % 10
if i == 0 and digit == 0:
continue
clearDisplay()
pickDigit(3 - i)
hc595_shift(number[digit])
def loop():
""" Main loop to continuously update display and lights. """
while True:
display()
lightup()
def destroy():
""" Clean up resources when the script is terminated. """
global timer1
timer1.cancel()
ledPinR.off()
ledPinG.off()
ledPinY.off()
try:
setup()
loop()
except KeyboardInterrupt:
destroy()
コードの説明
--------------------
1. gpiozeroライブラリから ``OutputDevice`` および ``LED`` クラスをインポートし、一般的な出力デバイスと特にLEDを制御するための機能を有効にします。Pythonのスレッディングモジュールもインポートされており、スレッドを作成して処理するために使用されます。
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import OutputDevice, LED
import threading
2. シフトレジスタのシリアルデータ入力(SDI)、レジスタクロック入力(RCLK)、およびシフトレジスタクロック入力(SRCLK)に接続されたGPIOピンを初期化します。
.. code-block:: python
# Setup GPIO pins for 74HC595 shift register
SDI = OutputDevice(24) # Serial Data Input
RCLK = OutputDevice(23) # Register Clock
SRCLK = OutputDevice(18) # Shift Register Clock
3. 7セグメントディスプレイの各ディジット用のピンを初期化し、0から9までの数値を表示するためのバイナリコードを定義します。
.. code-block:: python
# Setup GPIO pins for digit selection on 7-segment display
placePin = [OutputDevice(pin) for pin in (10, 22, 27, 17)]
# Segment codes for numbers 0-9 on 7-segment display
number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90)
4. 交通信号のシミュレーションに使用する赤、緑、黄色のLEDのGPIOピンを初期化します。交通信号システムの各色の状態の継続時間(秒単位)を設定します。参照のために、交通信号の色の名前も定義します。
.. code-block:: python
# Setup GPIO pins for traffic light LEDs
ledPinR = LED(25) # Red LED
ledPinG = LED(8) # Green LED
ledPinY = LED(7) # Yellow LED
# Duration settings for traffic lights
greenLight = 30
yellowLight = 5
redLight = 60
# Traffic light color names
lightColor = ("Red", "Green", "Yellow")
5. 現在の色の状態、タイミングのためのカウンタ、およびタイマーオブジェクトのプレースホルダを初期化します。
.. code-block:: python
# Initialize state variables
colorState = 0
counter = 60
timer1 = None
6. 交通信号システムを初期化し、タイマースレッドを開始します。
.. code-block:: python
def setup():
""" Initialize the traffic light system and start the timer. """
global timer1
timer1 = threading.Timer(1.0, timer)
timer1.start()
7. 7セグメントディスプレイの制御用の関数です。 ``clearDisplay`` はすべてのセグメントをオフにし、 ``hc595_shift`` はデータをシフトレジスタにシフトし、 ``pickDigit`` はディスプレイ上の特定のディジットをアクティブにします。
.. code-block:: python
def clearDisplay():
""" Clear the 7-segment display. """
for _ in range(8):
SDI.on()
SRCLK.on()
SRCLK.off()
RCLK.on()
RCLK.off()
def hc595_shift(data):
""" Shift data to the 74HC595 shift register for digit display. """
for i in range(8):
SDI.value = 0x80 & (data << i)
SRCLK.on()
SRCLK.off()
RCLK.on()
RCLK.off()
def pickDigit(digit):
""" Select a specific digit to display on the 7-segment display. """
for pin in placePin:
pin.off()
placePin[digit].on()
8. 交通信号の変更のタイミングを管理し、カウンターと色の状態を更新します。
.. code-block:: python
def timer():
""" Handle the timing for traffic light changes. """
global counter, colorState, timer1
timer1 = threading.Timer(1.0, timer)
timer1.start()
counter -= 1
if counter == 0:
counter = [greenLight, yellowLight, redLight][colorState]
colorState = (colorState + 1) % 3
print(f"counter : {counter} color: {lightColor[colorState]}")
9. 現在の色の状態に基づいて交通信号のLEDの状態を更新します。
.. code-block:: python
def lightup():
""" Update the traffic light LED based on the current state. """
global colorState
ledPinR.off()
ledPinG.off()
ledPinY.off()
[ledPinR, ledPinG, ledPinY][colorState].on()
10. 7セグメントディスプレイの各セグメントに表示されるディジットを計算し、それに応じて更新します。
.. code-block:: python
def display():
""" Display the current counter value on the 7-segment display. """
global counter
for i in range(4):
digit = counter // (10 ** (3 - i)) % 10
if i == 0 and digit == 0:
continue
clearDisplay()
pickDigit(3 - i)
hc595_shift(number[digit])
11. ディスプレイと交通信号のLEDを連続的に更新するメインループです。
.. code-block:: python
def loop():
""" Main loop to continuously update display and lights. """
while True:
display()
lightup()
12. スクリプトが終了したときにLEDをオフにし、タイマースレッドを停止するなど、リソースをクリーンアップします。
.. code-block:: python
def destroy():
""" Clean up resources when the script is terminated. """
global timer1
timer1.cancel()
ledPinR.off()
ledPinG.off()
ledPinY.off()