1.1.5 4桁7セグメントディスプレイ

前書き

次に、4桁7セグメントディスプレイを制御してみてください。

部品

_images/list_4_digit.png

原理

4桁7セグメントディスプレイ

4桁の7セグメントディスプレイは、連携して動作する4つの7セグメントディスプレイで構成されている。

_images/4-digit-sche.png

4デジタル7セグメントディスプレイは独立して動作する。人間の視覚的持続性の原理を使用して、ループ内の各7セグメントの文字をすばやく表示し、連続した文字列を形成する。

つまり、ディスプレイに「1234」が表示されている場合、最初の7セグメントに「1」が表示され、「234」は表示されないということである。しばらくすると、2番目の7セグメントに「2」が表示され、7セグメントの1番目、3番目、4番目に表示されなくなり、4つのデジタルディスプレイショーが順番に表示される。このプロセスは非常に短く(通常5ms)、光学的残光効果と視覚的残留の原理により、同時に4つの文字を見ることができる。

_images/image78.png

表示コード

7セグメントディスプレイ(アノードコモン)がどのように番号を表示するかを知るために、次の表をご参照ください。数字は7セグメントディスプレイに表示される0〜Fの数字である。(DP)GFEDCBAは、0または1に設定された対応のLEDを指す。たとえば、11000000はDPおよびGが1に設定され、他のLEDが0に設定されることを意味する。 したがって、7セグメントディスプレイには0が表示され、HEXコードは16進数に対応する。

_images/common_anode.png

回路図

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

_images/schmatic_4_digit.png

実験手順

ステップ1: 回路を作る。

_images/image80.png

C言語ユーザー向け

ステップ2:コードのフォルダーに入る。

cd /home/pi/davinci-kit-for-raspberry-pi/c/1.1.5/

ステップ3:コードをコンパイルする。

gcc 1.1.5_4-Digit.c -lwiringPi

ステップ4:EXEファイルを実行する。

sudo ./a.out

コードの実行後、プログラムは1秒間に1つずつ増やすカウントを行い、4桁の7セグメントディスプレイにそのカウントが表示される。

コード

#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 placePin[] = {12, 3, 2, 0};
unsigned char number[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};

int counter = 0;

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 loop()
{
    while(1){
    clearDisplay();
    pickDigit(0);
    hc595_shift(number[counter % 10]);

    clearDisplay();
    pickDigit(1);
    hc595_shift(number[counter % 100 / 10]);

    clearDisplay();
    pickDigit(2);
    hc595_shift(number[counter % 1000 / 100]);

    clearDisplay();
    pickDigit(3);
    hc595_shift(number[counter % 10000 / 1000]);
    }
}

void timer(int timer1)
{
    if (timer1 == SIGALRM)
    {
        counter++;
        alarm(1);
        printf("%d\n", counter);
    }
}

void main(void)
{
    if (wiringPiSetup() == -1)
    {
        printf("setup wiringPi failed !");
        return;
    }
    pinMode(SDI, OUTPUT);
    pinMode(RCLK, OUTPUT);
    pinMode(SRCLK, OUTPUT);

    for (int i = 0; i < 4; i++)
    {
        pinMode(placePin[i], OUTPUT);
        digitalWrite(placePin[i], HIGH);
    }
    signal(SIGALRM, timer);
    alarm(1);
    loop();
}

コードの説明

const int placePin[] = {12, 3, 2, 0};

これらの4つのピンは、4桁の7セグメントディスプレイのアノードコモンピンを制御する。

unsigned char number[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};

16進数(アノードコモン)の0〜9のセグメントコード配列。

void pickDigit(int digit)
{
    for (int i = 0; i < 4; i++)
    {
        digitalWrite(placePin[i], 0);
    }
    digitalWrite(placePin[digit], 1);
}

値の場所を選択する。毎回有効な場所は1つだけである。有効な場所はhighに書き込まれる。

void loop()
{
    while(1){
    clearDisplay();
    pickDigit(0);
    hc595_shift(number[counter % 10]);

    clearDisplay();
    pickDigit(1);
    hc595_shift(number[counter % 100 / 10]);

    clearDisplay();
    pickDigit(2);
    hc595_shift(number[counter % 1000 / 100]);

    clearDisplay();
    pickDigit(3);
    hc595_shift(number[counter % 10000 / 1000]);
    }
}

この機能を使用して、4桁の7セグメントディスプレイに表示される番号を設定する。

  • clearDisplay():11111111に書き込み、7セグメントディスプレイ上のこれら8つのLEDをオフにして、表示されたコンテンツを消去する。

  • pickDigit(0):4番目の7セグメントディスプレイを選択する。

  • hc595_shift(number[counter%10]):カウンターの1桁の数字が4番目のセグメントに表示される。

signal(SIGALRM, timer);

これはシステム組み込みの関数であり、コードのプロトタイプは次のとおりである:

sig_t signal(int signum,sig_t handler);

signal() を実行した後、プロセスは対応する signum(ここでSIGALRM)を受信すると、すぐに既存のタスクを一時停止し、設定関数(ここでtimer(sig))を処理する。

alarm(1);

これもシステム組み込み関数である。コードのプロトタイプは:

unsigned int alarm (unsigned int seconds);

指定した秒数後にSIGALRMシグナルを生成する。

void timer(int timer1)
{
    if (timer1 == SIGALRM)
    {
        counter++;
        alarm(1);
        printf("%d\n", counter);
    }
}

上記の関数を使用して、タイマー関数を実装する。 alarm() がSIGALRMシグナルを生成した後、タイマー関数が呼び出される。カウンターに1を追加すると、1秒後に関数 alarm(1) が繰り返し呼び出される。

Python言語ユーザー向け

ステップ2:コードのフォルダーに入る。

cd /home/pi/davinci-kit-for-raspberry-pi/python/

ステップ3:EXEファイルを実行する。

sudo python3 1.1.5_4-Digit.py

コードの実行後、プログラムは1秒ずつ増加するカウントをして、4桁のディスプレイにカウントが表示される。

コード

注釈

以下のコードを 変更/リセット/コピー/実行/停止 できます。 ただし、その前に、 davinci-kit-for-raspberry-pi/python のようなソースコードパスに移動する必要があります。

import RPi.GPIO as GPIO
import time
import threading

SDI = 24
RCLK = 23
SRCLK = 18

placePin = (10, 22, 27, 17)
number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90)

counter = 0
timer1 = 0

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():
    global counter
    global timer1
    timer1 = threading.Timer(1.0, timer)
    timer1.start()
    counter += 1
    print("%d" % counter)


def loop():
    global counter
    while True:
        clearDisplay()
        pickDigit(0)
        hc595_shift(number[counter % 10])

        clearDisplay()
        pickDigit(1)
        hc595_shift(number[counter % 100//10])

        clearDisplay()
        pickDigit(2)
        hc595_shift(number[counter % 1000//100])

        clearDisplay()
        pickDigit(3)
        hc595_shift(number[counter % 10000//1000])


def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(SDI, GPIO.OUT)
    GPIO.setup(RCLK, GPIO.OUT)
    GPIO.setup(SRCLK, GPIO.OUT)
    for i in placePin:
        GPIO.setup(i, GPIO.OUT)
    global timer1
    timer1 = threading.Timer(1.0, timer)
    timer1.start()

def destroy():   # When "Ctrl+C" is pressed, the function is executed.
    global timer1
    GPIO.cleanup()
    timer1.cancel()  # cancel the timer

if __name__ == '__main__':  # Program starting from here
    setup()
    try:
        loop()
    except KeyboardInterrupt:
        destroy()

コードの説明

placePin = (10, 22, 27, 17)

これらの4つのピンは、4桁の7セグメントディスプレイのアノードコモンピンを制御する。

number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90)

16進数の0〜9のセグメントコード配列(アノードコモン)。

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)

SDIに「1」を8回書き込むと、7セグメントディスプレイの8つのLEDが消灯し、表示されたコンテンツが消去される。

def pickDigit(digit):
    for i in placePin:
        GPIO.output(i,GPIO.LOW)
    GPIO.output(placePin[digit], GPIO.HIGH)

値の場所を選択する。毎回有効な場所は1つだけである。有効な場所はhighに書き込まれる。

def loop():
    global counter
    while True:
        clearDisplay()
        pickDigit(0)
        hc595_shift(number[counter % 10])

        clearDisplay()
        pickDigit(1)
        hc595_shift(number[counter % 100//10])

        clearDisplay()
        pickDigit(2)
        hc595_shift(number[counter % 1000//100])

        clearDisplay()
        pickDigit(3)
        hc595_shift(number[counter % 10000//1000])

この機能は、4桁の7セグメントディスプレイに表示される番号を設定するために使用される。

まず、4番目のセグメントディスプレイを開始し、1桁の数字を書き込む。次に、3番目のセグメントディスプレイを開始し、10桁の数字を入力する。その後、2番目と1番目のセグメントディスプレイをそれぞれ開始し、それぞれ数百桁と数千桁を書き込む。リフレッシュ速度が非常に速いため、完全な4桁のディスプレイが表示される。

timer1 = threading.Timer(1.0, timer)
timer1.start()

モジュール、スレッドはPythonの一般的なスレッドモジュールであり、タイマーはそのサブクラスである。コードのプロトタイプは次のとおりです:

class threading.Timer(interval, function, args=[], kwargs={})

間隔の後、関数が実行される。ここでは、間隔は1.0、関数は timer() である。 start() は、タイマーがこの時点で開始することを意味する。

def timer():
    global counter
    global timer1
    timer1 = threading.Timer(1.0, timer)
    timer1.start()
    counter += 1
    print("%d" % counter)

Timerが1.0秒に達すると、Timer関数が呼び出される。カウンターに1を追加すると、タイマーが再び使用されて、1秒ごとに繰り返し実行される。

現象画像

_images/image81.jpeg