RaspberryPiを使った電子工作は、インターネットと連動させたフィジカル・コンピューティングを簡単に実現させることができる優れたデバイスですよね!アイデア次第で、様々な目的に使用できます。
というわけで、今回はラズパイと7セグメントLEDを活用した工作のヒントになるようなテーマを扱います。
7セグメントLEDとは、デジタルの数字を表示させるためのパーツです。様々な製品に使われており、安価に入手することが可能です。電子工作で数字を表示するような作品を制作する場合にはとても重宝します。
例えば、デジタル時計、インターネット上にアップされている何かの数字を読み込んで表示するなどの用途が考えられます。以前会社のウェブサイトのFaceBookの「いいね!」の数を表示する「いいね!カウンター」という作品を制作したのですが、今日はその作品の回路図及びソースコードを公開したいと思います!同じような作品を制作しようとしている方のヒントになれば幸いです。
目次
- 仕様について
- この工作に必要なパーツ
- 必要なライブラリとパッケージ
- 配線図
- プログラムソース(Python)
- 解説
- まとめ
1.仕様について
今回紹介する回路図及びPythonコードは、以下の仕様を想定しています。
- インターネット上にアップされているJSON形式の数字を読み込む
- 桁数は4桁
- テレビ番組の「なんでも鑑定団」の鑑定金額のようなランダムに数字を表示させる演出の後、数字を表示させる
- cronを使って定期的にプログラムを回す
2.この工作に必要なパーツ
まず今回の工作で必要なパーツを準備しましょう。以下にリストアップします。
※上記一覧のリンクはamazon・秋月電子通商へのリンクとなっています。
工作に必要なパーツに関して少し補足します。RaspberryPiは古いものでもOKです。自分の場合は、RaspberryPiには性能よりも小ささに魅力を感じているので、大抵RaspberryPi Zeroを使います。ただ、初めて購入される方は、上記リンクにある最新のPi 4をお勧めします。メモリは4GBで、ちょっと前のノートPC並みの性能ですから、ひとまずどんな用途にも使えます。技適マーク付きのものを買いましょう。それと、ブレッドボードとジャンパーワイヤはお手持ちのものがあればOKです。
7セグメントLEDですが、これだけ注意点があります。amazonなどにも大小様々な7セグメントLEDが販売されていますが、この記事の回路図とコードに対応しているのは、上記の秋月電子通商で販売されているシリアルドライバモジュール付のものです。他の製品については当方では確認していませんのでご注意ください。色は青、赤の2色があり、半田付けされていないキット(200円)と完成品(220円)がそれぞれあります。半田付けに慣れていない人は、20円しか違わないので完成品がお勧めです。
3.必要なライブラリとパッケージ
urllib2
まずインターネットのデータを取得するための「urllib2」というライブラリが必要になりますのでインストールしましょう。インストールにはpipを使用します。
$ pip install request
urllib2の詳細についてはこちらもご覧ください。
WiringPi
WiringPiというライブラリがあるのですが、これはラズパイのGPIOを簡単に制御するためのものです。
$ sudo apt-get update
$ sudo apt-get install wiringpi
WiringPi2-Python
WiringPiはC言語で書かれているために、これをPythonでも使えるようにするためのラッパーモジュールであるWiringPi2-Pythonが必要となります。
$ cd ~/Downloads/
$ sudo apt-get install python-dev python-setuptools
$ git clone https://github.com/Gadgetoid/WiringPi2-Python.git
$ cd WiringPi2-Python
$ sudo python setup.py install
githubからダウンロードが必要になるので、任意のディレクトリに移動しておきましょう。上記のコマンド例では、Downloadsフォルダに移動して作業しています。
4.配線図
今度はRaspberryPi、7セグメントLED、ブレッドボード、ジャンパーワイヤを使って配線していきます。

RaspberryPi側の配線ですが、17番の3.3v、25番のGNDの他に19番、23番、24番をそれぞれ使用します。ちなみにグレーの部分に7セグメントLEDを差し込みます。
5.プログラムソース(Python)
# -*- coding: utf-8 -*-
import urllib2
import json
import RPi.GPIO as GPIO
from time import sleep
import wiringpi2 as wiringpi
import random
# pin raspi 74HC595
# MOSI = 19 # SDI
# CLK = 23 # SCK
# CE0 = 24 # LATCH
SPI_Ch = 0 # CE0
SPI_Speed = 100000
# number setting
digit1 = 0
digit2 = 0
digit3 = 0
digit4 = 0
number_list = [
0, # all off
6, # 1
91, # 2
79, # 3
102, # 4
109, # 5
125, # 6
7, # 7
127, # 8
103, # 9
63, # 0
64, # minus
128, # dot
255 # all on
]
# get now_count
req = urllib2.Request('https://(あなたが読み込みたいJSONのURL)')
res = urllib2.urlopen(req)
cur = res.read()
cur_json = json.loads(cur)
now_count = format(cur_json['任意のJSON構造']['任意のJSON構造'])
old_count = 0
# save old_count
r = open('/home/pi/raspi_counter/share_count.txt', 'r')
for row in r:
old_count = row
w = open('/home/pi/raspi_counter/share_count.txt', 'w')
w.write(now_count)
w.close()
now_count_length = len(now_count)
if now_count_length == 1:
digit1 = int(now_count[0])
if digit1 == 0:
digit1 = 10
elif now_count_length == 2:
digit1 = int(now_count[1])
digit2 = int(now_count[0])
if digit1 == 0:
digit1 = 10
elif now_count_length == 3:
digit1 = int(now_count[2])
digit2 = int(now_count[1])
digit3 = int(now_count[0])
if digit1 == 0:
digit1 = 10
if digit2 == 0:
digit2 = 10
elif now_count_length == 4:
digit1 = int(now_count[3])
digit2 = int(now_count[2])
digit3 = int(now_count[1])
digit4 = int(now_count[0])
if digit1 == 0:
digit1 = 10
if digit2 == 0:
digit2 = 10
if digit3 == 0:
digit3 = 10
# initialization
print("Initialization...")
wiringpi.wiringPiSPISetup (SPI_Ch, SPI_Speed)
if old_count != now_count:
# circuit counter
for i in range(0,40):
if i >= 40:
circuit1 = digit1
else:
circuit1 = random.randint(1,10)
if i >= 30:
circuit2 = digit2
else:
circuit2 = random.randint(1,10)
if i >= 20:
circuit3 = digit3
else:
circuit3 = random.randint(1,10)
if i >= 10:
circuit4 = digit4
else:
circuit4 = random.randint(1,10)
data = chr(number_list[circuit1]) + chr(number_list[circuit2]) + chr(number_list[circuit3]) + chr(number_list[circuit4])
wiringpi.wiringPiSPIDataRW(SPI_Ch, data)
sleep(0.1)
# debug
debug_list = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ]
print(debug_list[digit4] + debug_list[digit3] + debug_list[digit2] + debug_list[digit1])
# display counter
data = chr(number_list[digit1]) + chr(number_list[digit2]) + chr(number_list[digit3]) + chr(number_list[digit4])
wiringpi.wiringPiSPIDataRW(SPI_Ch, data)
sleep(1)
6.解説
このプログラムの使い方ですが、ラズパイ側で定期的にプログラムが走るようにcronを設定しましょう。例えば、下記は1分毎の設定です。raspi_counterというディレクトリにプログラムコードが置いてあることに留意してください。
$ crontab -e
*/1 * * * * python /home/pi/raspi_counter/counter.py 2>>/home/pi/raspi_counter/error.log
23〜38行目:
このリストは7セグメントLEDの表示を定義したものです。このリストで定義されている何の脈絡もなさそうなintでデジタル数字を構成するLEDを発光させることができます。自分もこの部分の理屈はちゃんと調べてません(笑)とにかく、この数字をwiringpiに渡してやると所定のLEDが数字として読めるように発光するのです。この数字と表示の法則はググったり実験したりして突き止めました。
41〜45行目:
JSONを読み込んでパースしています。必要な構造に合わせて書き換えてください。読み込んだ数字は「now_count」に読み込ませます。
Facebookの「いいね!」の数を読み込んだりすることもできます。読み込むにはFacebook側のAPIと連動させる必要があります。
49、54行目:
「counter.py」と同じディレクトリに「share_count.txt」という空のファイルを配置します。
99〜119行目:
ここのforループで「なんでも鑑定団」の鑑定金額のようなランダムに数字を表示させる演出を実現しています。コードを読める人なら「あぁ、こんな風にやってんだ」と分かってもらえるはずです。
7.まとめ
今回ご紹介した7セグメントLEDの桁数は4桁でしたが、公開した回路図とコードをそのまま拡張すれば、RaspberryPiの3.3vのGPIOピンの出力のまま、6桁くらいまでは桁数を増やせるのではないかと思います。
今回解説した回路とコードを応用すれば、インターネット上にある様々なデータを参照して可視化したり、カウント表示したりできるはずです。是非チャレンジしてみてください!