10
0

はじめに

Nerves Livebook で Raspberry Pi 用スターター電子工作キットを楽しんでいます

SunFounder Raspberry Pi 用のスターター電子工作キット

これまでの記事

この記事では 4 桁 7 セグメントディスプレイに文字を表示します

実装したノートブックはこちら

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

前回の記事で使った 7 セグメントディスプレイが 4 桁分繋がっています

IMG_1582.JPG

前回の 7 セグメントディスプレイはカソードコモン(CC)でしたが、今回はアノードコモン(CA)になっています

逆方向になっているため、 0 で光って 1 で消えます

つまり前回は 0 の文字を 0b00111111 で表していましたが、今回は 0b11000000 で表します

また、 4 桁ありますが、実は同時に 4 桁全て光らせることはできません

一桁ずつ光らせるのを高速に切り替えることで、人の目には 4 桁同時に光っているかのように見せます

例えば 1234 と表示される場合、以下のように順に光らせています

   4
  3 
 2  
1   

回路の組み立て

オンライン説明書の通りに回路を組みます

ノートブックの実装

Nerves Livebook を開き、以降のコードを実行していきます

準備

ビット演算のために Bitwise を読み込みます

import Bitwise

ピンを開く

GPIO の各ピンを出力用に開きます

まずは前回と同じシフトレジスタ 74HC595 に信号を送るためのピンを開きます

{:ok, sdi} = Circuits.GPIO.open("GPIO24", :output)
{:ok, rclk} = Circuits.GPIO.open("GPIO23", :output)
{:ok, srclk} = Circuits.GPIO.open("GPIO18", :output)

次に、光らせる桁を制御するための 4 つのピンを開きます

place_pins =
  [
    "SPI_MOSI",
    "GPIO22",
    "GPIO27",
    "GPIO17"
  ]
  |> Enum.map(fn label ->
    label
    |> Circuits.GPIO.open(:output)
    |> elem(1)
  end)

4 つのうち 1 つだけに 1 を送ることで、指定の桁を光らせます

関数の定義

使用する関数を諸々定義します

clear_display では全ての LED に 1 を書き込むことで何も光っていない状態にします

clear_display = fn sdi, rclk, srclk ->
  Enum.each(1..8, fn _ ->
    Circuits.GPIO.write(sdi, 1)
    Circuits.GPIO.write(srclk, 1)
    Circuits.GPIO.write(srclk, 0)
  end)

  Circuits.GPIO.write(rclk, 1)
  Circuits.GPIO.write(rclk, 0)
end

shift_out は前回と同じで、シフトレジスタに指定した信号を順次送ってから並列伝送する関数です

shift_out = fn data, sdi, rclk, srclk ->
  for bit <- 0..7 do
    bit = data <<< bit &&& 0x80
    Circuits.GPIO.write(sdi, bit)
    Circuits.GPIO.write(srclk, 1)
    Process.sleep(1)
    Circuits.GPIO.write(srclk, 0)
  end

  Circuits.GPIO.write(rclk, 1)
  Process.sleep(1)
  Circuits.GPIO.write(rclk, 0)
end

pick_digit 関数で光らせる桁を指定します

一旦全て 0 にしておいてから光らせたい桁のピンだけ 1 にしています

pick_digit = fn place_pins, digit ->
  Enum.each(place_pins, fn pin ->
    Circuits.GPIO.write(pin, 0)
  end)

  place_pins
  |> Enum.at(digit)
  |> Circuits.GPIO.write(1)
end

これらを組み合わせて、指定した文字を指定した桁に表示する関数 display を作ります

display = fn char, place, place_pins, sdi, rclk, srclk ->
  clear_display.(sdi, rclk, srclk)

  pick_digit.(place_pins, place)

  shift_out.(char, sdi, rclk, srclk)
end

COOL を表示する

COOL の文字を表示させてみます

反転だと考えにくかったので、前回と同じカソード用の 2 進数でコードを指定しておいて、 ~~~ 演算子で反転させます

cool_code = [
  0b00111001,
  0b00111111,
  0b00111111,
  0b00111000
]

0..100
|> Enum.map(fn _ ->
  ~~~Enum.at(cool_code, 3)
  |> display.(0, place_pins, sdi, rclk, srclk)

  ~~~Enum.at(cool_code, 2)
  |> display.(1, place_pins, sdi, rclk, srclk)

  ~~~Enum.at(cool_code, 1)
  |> display.(2, place_pins, sdi, rclk, srclk)

  ~~~Enum.at(cool_code, 0)
  |> display.(3, place_pins, sdi, rclk, srclk)
end)

画質を 720p60 以上にすれば COOL の文字が見えます

それより低いとバラバラに光っているように見えます

GIF だとこんな感じで、全く同時に光っているようには見えません

cool.gif

スクリーンショットだと各文字が個別に光っているのが分かります

スクリーンショット 2024-06-27 21.54.48.png

スクリーンショット 2024-06-27 21.55.43.png

スクリーンショット 2024-06-27 21.56.22.png

スクリーンショット 2024-06-27 21.56.49.png

4桁カウンターを表示する

数字をどんどんカウントアップしていくカウンターを表示します

seg_code = [0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90]
0..1000
|> Enum.map(fn counter ->
  seg_code
  |> Enum.at(rem(counter, 10))
  |> display.(0, place_pins, sdi, rclk, srclk)

  seg_code
  |> Enum.at(div(rem(counter, 100), 10))
  |> display.(1, place_pins, sdi, rclk, srclk)

  seg_code
  |> Enum.at(div(rem(counter, 1000), 100))
  |> display.(2, place_pins, sdi, rclk, srclk)

  seg_code
  |> Enum.at(div(rem(counter, 10000), 1000))
  |> display.(3, place_pins, sdi, rclk, srclk)
end)

ピンを閉じる

遊び終わったらピンを閉じておきます

Circuits.GPIO.close(sdi)
Circuits.GPIO.close(rclk)
Circuits.GPIO.close(srclk)
place_pins
|> Enum.map(fn pin ->
  Circuits.GPIO.close(pin)
end)

まとめ

Nerves Livebook から 4 桁 7 セグメントディスプレイに文字を表示できました

高速に切り替える技も色々応用ができそうですね

10
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
0