こんにちは、Zero-Cheeseです。
今回は、久々に趣味で制作した物を、紹介いたします。
制作した物は
- 外部PCのGPU使用率を計測して、
- 目の色を変化させるオブジェ
です。
下記の属性をお持ちの方は、楽しめると、思います。
- Python初心者以上の方
- ワクワクした物を作りたい人!!
- (3Dモデル、3Dプリンタの知見は、なくても大丈夫です)
- (Raspberry Pi(ラズパイ)の知見がなくても、問題なしです。)
【構想時の絵】
今回、計測に用いた外部PCは、GPUが2個、付いています。(自作PCです。)
- Nvidiaの、「GTX1080Ti」と「GTX1080」が付いています。
きしょい・・・
この子のスペック:
- 外部パソコンのGPU使用率に応じて、目の色を変えられる
筆者が勢いで作った物なので、軽い気持ちで、流し読みしてやって下さい。
動機
家の自作PCが、ディープラーニング学習のために、ずーと働いてくれてます。
ディープラーニングの学習をしていると、GPU使用率が気になるところです。
ターミナルを開いて、コマンドを打ち込めば、簡単に分かりますが、
- なにかもっと、感情的に訴えるものがほしい!!
と思い、本企画を実行に移しました。
制作に必要なモノ
一覧
- RaspBerry Pi Zero WH
- LED(フルカラータイプ)
- 抵抗
- ブレッドボード
- ブレッドボード用ジャンバー線
- 3Dプリンタ
RaspBerry Pi Zero WH
とても、小さなコンピュータです。
コンピュータなのに、手のひらにのるサイズです!
WiFi、Bluetooth 等も付属しています。
CPUは、クロック1GHzもあります。
月に行った、アポロのコンピュータのクロックが、0.002GHzだったとか・・ (あちらは、リアルタイム組込なので、単純比較が難しい所ですが・・)
主な特徴
- 802.11 b/g/n wireless LAN
- Bluetooth 4.1
- Bluetooth Low Energy (BLE)
- 1GHz, single-core CPU
- 512MB RAM 等々
より詳細を知りたい方は、公式サイトをご参照ください。
マルチスレッド性能が5倍向上した、「Raspberry Pi Zero 2 W」が発売予定です。
しかし、半導体不足等の影響により、まだ入手困難な状況です。(2022年6月現在)
LED(フルカラータイプ)
RGB全部ありの、フルカラーLEDを使いました。
ピンは、
- RGBのそれぞれに対応するピン(+側:アノードと呼ばれます。)
- GNDに対応するピン(−側:カソードと呼ばれます。)
の合計、4本になります。
秋月電子通商さんのリンクを貼っておきます。
RGBフルカラーLED 5mm OSTAMA5B31A アノードコモンhttps://akizukidenshi.com/catalog/g/gI-12167/
電源とLEDの直接接続は、NGです。
LEDは、抵抗がほぼゼロのため、大電流が流れ、一発で壊れるからです。
よって、電源と抵抗との間に、必ず抵抗を入れ、LEDの許容電流以下にします。
抵抗
今回使用した抵抗は、330Ωです。
一般的な、抵抗を使用しました。
ブレッドボードとブレッドボード用ジャンバー線
ちょっとテストする場合、配線のハンダ付けとか、面倒だと思います。
そんなとき、ブレッドボードとジャンバー線は、とても便利です。
【ブレッドボードに、ジャンバー線が、刺さっている写真】
こんな感じで、ブレッドボードに、抵抗や、ジャンバー線をさすだけで、簡単に、電子工作が楽しめます。
制作手順
以下の手順で、制作しました。
- 「ガイコツ」の3Dモデルを制作
- 3Dプリンタで、「ガイコツ」制作
- 電子工作(ラズパイとLED接続等)
- プログラム制作
① 「ガイコツ」の3Dモデル制作
3Dモデル制作には、Fusion 360を使用しました。
制作したモデルは、こちらです。
【斜め上から】
【下から】
下部には、ラズパイ設置用スペースを設けました。
また、目にLEDの配線するため、 ラズパイまでの配線スペースである、貫通穴も作りました。
【配線イメージ】
3Dモデルでは、配線が太く描かれてしますが、ただのリード線を使っています。
もっとガイコツっぽい外観にしたかったのですが、作者のスキルが・・
② 3Dプリンタで、「ガイコツ」制作
うちにある、3Dプリンタは、こちらになります。
主なスペック
- メーカー:QIDI Technology
- 型番:X-Plus
- 造形材料:PLA, ABS TPU PETG, PC, Nylon, Carbon fiber
- ビルドサイズ:270×200×200mm
- 層の厚さ:0.05 – 0.4 mm
- 位置決め精度:Z:0.0025mm; XY:0.011mm
様々な材料が使える!(カーボンが使えるのはGood!)、 積層厚も0.05mm とGood!、あと結構大きいモノまで作れるので、購入しました。
制作した「ガイコツ」は、こちらです。
【3Dプリンタ直後 (サポート材有りの状態)】
せっかくなので、金色で作ってみました!
結構、色がリアルです!
③ 電子工作(ラズパイとLED接続等)
電子回路は、本当に単純です。
ラズパイのピンと、LEDと、抵抗を直列に繋ぐだけになります。
ラズパイのピンは、番号がふられています。
上図の、GPIO(汎用入出力)と記載されている「ピン」を使用します。
制作した回路 (+から−まで、接続の順番を、記しています。)
◆ GTX1080Ti 用の LED
- LEDのR用回路: GPIO 17ピン → LED R → 抵抗 → GND ピン
- G用回路:GPIO 27ピン → LED G → 抵抗 → GND ピン
- B用回路:GPIO 22ピン → LED B → 抵抗 → GND ピン
◆ GTX1080 用の LED
- LEDのR用回路: GPIO 13ピン → LED R → 抵抗 → GND ピン
- G用回路:GPIO 19ピン → LED G → 抵抗 → GND ピン
- B用回路:GPIO 26ピン → LED B → 抵抗 → GND ピン
回路図でご紹介しようと思いましたが、単純なので、省略しました。
④ プログラム制作
ソフトウェア部分は、下記の構成になっています。
- 外部PCのWebサーバを立てて、GPU使用率を知らせるAPIを作る
- ラズパイで、そのAPIを叩いて、GPU使用率を取得 → LEDを光らせる
<構成イメージ>
外部PCにWebサーバを立てる
Webアプリ フレームワークである、Flaskを使用しました。
このプログラムは、外部PC側で、走らせます。
エンドポイント「/get_gpu_usage」を叩くと、JSONで、GPUの使用率が返ります。
import os
import subprocess
from flask import Flask
from flask import jsonify
app = Flask(__name__)
@app.route('/')
def get_main():
# この部分は、特にいらない
return 'world'
@app.route('/get_gpu_usage')
def get_gpu_usage():
try:
p1 = subprocess.Popen(['nvidia-smi', '--query-gpu=utilization.gpu', '--format=csv,noheader,nounits'], stdout=subprocess.PIPE)
output = p1.communicate()[0]
output = output.decode()
output = output.split()
output_json = {
'GTX1080Ti': {
'usage': output[0],
'temp': None
},
'GTX1080': {
'usage': output,
'temp': None
}
}
return jsonify(output_json)
except:
return {'message': 'Error'}
if __name__ == '__main__':
app.run(debug='True', host='0.0.0.0', port=8000)
ラズパイ側のプログラム
外部PCのAPIを叩いて、GPU使用率を取得するコード
「gpu_usage.py」 というファイル名で作成しました。
import json
import requests
import time
class GpuUsage(object):
def __init__(self, url):
self.url = url
def get_both_usage(self):
try:
r = requests.get(self.url)
r = r.json()
gtx1080ti_usage = r['GTX1080Ti']['usage']
gtx1080_usage = r['GTX1080']['usage']
return gtx1080ti_usage, gtx1080_usage
except Exception as e:
print(e)
LEDを光らせるクラスと、全体管理するクラス
「monitor_controller.py」というファイル名で、作成しています。
import time
import RPi.GPIO as GPIO
import gpu_usage
GPIO.setmode(GPIO.BCM)
class Led(object):
def __init__(self, name: str):
self.name = name
self.port_R = 0
self.port_G = 0
self.port_B = 0
if self.name == 'GTX1080ti':
self.port_R = 17
self.port_G = 27
self.port_B = 22
elif self.name == 'GTX1080':
self.port_R = 13
self.port_G = 19
self.port_B = 26
self.ports = [self.port_R, self.port_G, self.port_B]
for port in self.ports:
GPIO.setup(port, GPIO.OUT)
def _set_color(self, r, g, b):
GPIO.output(self.ports[0], r)
GPIO.output(self.ports, g)
GPIO.output(self.ports, b)
def red_light_on(self):
self._set_color(1, 0, 0)
print('red')
def green_light_on(self):
self._set_color(1, 0, 1)
print('green')
def blue_light_on(self):
self._set_color(0, 0, 1)
print('blue')
def light_off(self):
self._set_color(0, 0, 0)
print('off')
class MonitorController(object):
PROCESS_TIME = 0.5 # 何秒おきに、GPU使用率をチェックするか
MAX_USAGE_LOW_LEVEL = 80 # GPU使用率 80%以上でLEDの色を変える
MAX_USAGE_MIDDLE_LEVEL = 95 # GPU使用率 95%以上でLEDの色を変える
def __init__(self, gpu_usage: GpuUsage, led_gtx1080: Led, led_gtx1080ti: Led):
self.gpu_usage = gpu_usage
self.led_gtx1080 = led_gtx1080
self.led_gtx1080ti = led_gtx1080ti
def process(self):
while True:
gtx1080ti_usage, gtx1080_usage = self.gpu_usage.get_both_usage()
gtx1080ti_usage = int(gtx1080ti_usage)
gtx1080_usage = int(gtx1080_usage)
self._change_led_color(gtx1080ti_usage, self.led_gtx1080ti)
self._change_led_color(gtx1080_usage, self.led_gtx1080)
time.sleep(PROCESS_TIME)
def _change_led_color(self, usage: int, led: Led):
if usage <= MAX_USAGE_LOW_LEVEL:
led.blue_light_on()
elif usage <= MAX_USAGE_MIDDLE_LEVEL:
led.green_light_on()
else:
led.red_light_on()
if __name__ == '__main__':
# 外部PCのIPアドレスが、192.168.10.100 ポートが、8000の場合
gpu_usage_obj = gpu_usage.GpuUsage('http://192.168.10.100:8000/get_gpu_usage')
gtx1080_led = Led('GTX1080')
gtx1080ti_led = Led('GTX1080ti')
monitor_controller = MonitorController(gpu_usage_obj, gtx1080_led, gtx1080ti_led)
monitor_controller.process()
制作物を鑑賞
さっそく、制作したオブジェを、PCにセットしてみました!
うん! ばっちり!!
・・・・・・・
最後に
夜、ふと目がさめて、このパソコン部屋に行ってみたら、すごいびっくり!!
このオブジェを動かしているのを、完全に忘れてました。
その時の写真 ↓
本当にガイコツ! PCの中身が、まるで肋骨に・・・
けっこう、ビビりました(笑)
最後まで読んでいただき、ありがとうございました。
また、お会いしましょう!