ハードウェア組み立てを伴うので腰が引けてましたが、自作PCを組む場合とさほど変わらない感覚(かつ、はんだ付け作業なしでOK)なので、もっと早く組んでみたら良かった!と思った次第です。
品名 | 購入価格 |
ラズパイ3B+本体+キット | 30,980円 |
USB給電スピーカ | 3,473円 |
公式7インチタッチパネルディスプレイ | 10,780円 |
ケース | 5,940円 |
DAC | 3,520円 |
赤外線リモコン受光部 | 3,200円 |
赤外線リモコン送信部 | 1,379円 |
USBメモリ | 1,535円 |
microSD延長ケーブル | 989円 |
ロータリーエンコーダ(8個入) | 1,698円 |
4ボタン | 690円 |
OLEDディスプレイ(3個入) | 1,680円 |
ネジ スペーサ セット | 1,199円 |
ジャンパワイヤ | 1,680円 |
ミニブレッドボード(7個入) | 776円 |
L型RCAアダプタ | 899円 |
QIコネクタ+圧着ペンチ | 2,980円 |
鉛テープ | 3,322円 |
合計 | 76,720円 |
公式組み立てマニュアル
詳しくは動画で!
ひとまず、上記の配線とすべく、ラズパイ本体・ディスプレイ・DAC・USB電源スピーカ・RCAピンプラグ・microSD延長ケーブルの配線をしたところ。
ケースの上蓋の高さが高くないので、ケースとの間のスペーサは下記のようにした。
この後、ロータリエンコーダ、ボタンをラズパイ本体側にジャンプワイヤで配線する。(写真割愛)
#!/bin/sh DIR=`dirname \`find /mnt -type f -maxdepth 5 -name ReplaceFont.sh\`` cd /opt/jivelite/share/jive/fonts sudo rm FreeSans.ttf sudo rm FreeSansBold.ttf #sudo ln -s $DIR/ipagp.ttf FreeSans.ttf #sudo ln -s $DIR/ipagp.ttf FreeSansBold.ttf sudo cp $DIR/ipagp.ttf FreeSans.ttf sudo ln -s FreeSans.ttf FreeSansBold.ttf
ロータリーエンコーダ | 右回転(時計回り) | 左回転(反時計回り) | 短押し | 長押し |
中央 | ホーム画面などで下矢印キー | ホーム画面などで上矢印キー | 選択 | 戻る |
右側 | ボリュームアップ | ボリュームダウン | pause/play | Now Playing画面切替 |
ボタン | 短押し | 長押し |
1 | プリセット1 (LMS上のFavoritesの1つめ) | 電源オン・オフトグル |
2 | プリセット2 (LMS上のFavoritesの2つめ) | ←(左矢印) |
3 | プリセット3 (LMS上のFavoritesの3つめ) | →(右矢印) |
4 | プリセット4 (LMS上のFavoritesの4つめ) | ホーム画面へ |
tc@pCP:~$ sbpd -? Usage: sbpd [OPTION...] [e,pin1,pin2,CMD,edge] [b,pin,CMD,resist,pressed...] sbpd - SqueezeButtinPiDaemon is a button and rotary encoder handling daemon for Raspberry Pi and a Squeezebox player software. sbpd connects to a Squeezebox server and sends the configured control commands on behalf of a player running on the RPi.2017 Joerg Schwieder/PenguinLovesMusic.com At least one needs to be specified for the daemon to do anything useful Arguments are a comma-separated list of configuration parameters: For rotary encoders): e,pin1,pin2,CMD[,mode] "e" for "Encoder" p1, p2: GPIO PIN numbers in BCM-notation CMD: Command. one of. VOLU for Volume TRAC for Prev/Next track KEY: - . mode: Optional. one of 1 - Step mode (default) 2-9 - Detent mode - Assumes 1 dial click is x steps. For buttons: b,pin,CMD[,resist,pressed[,CMD_LONG,long_time]] "b" for "Button" pin: GPIO PIN numbers in BCM-notation CMD: Command. One of. PLAY - play/pause VOL+ - increment volume VOL- - decrement volume PREV - previous track NEXT - next track Commands can be defined in config file use -f option, ref:sbpd_commands.cfg Command type SCRIPT. SCRIPT:/path/to/shell/script.sh Command type KEY. KEY: . resist: Optional. one of 0 - Internal resistor off 1 - pull down - input puts 3v on GPIO pin 2 - pull up (default) - input pulls GPIO pin to ground pressed: Optional GPIO pinstate for button to read pressed 0 - state is 0 (default) 1 - state is 1 CMD_LONG: Command to be used for a long button push, see above list long_time: Number of milliseconds for a long button press -A, --address=Server-Address Set server address. Default: autodetect -f, --conf_file= Full path to command configuration file -M, --mac=MAC-Address Set MAC address of player. Default: autodetect -p, --password=password Set password for server. Default: none -P, --port=xxxx Set server control port. Default: autodetect -u, --username=user name Set user name for server. Default: none -d, --daemonize Daemonize -s, --silent Don't produce output -v, --verbose Produce verbose output -z, --debug Produce debug output -?, --help Give this help list --usage Give a short usage message -V, --version Print program version Mandatory or optional arguments to long options are also mandatory or optional for any corresponding short options. Report bugs to <coolio@penguinlovesmusic.com>.
#!/bin/sh # start pigpiod daemon pigpiod -t 0 -f -l -s 10 # wait for pigpiod to initialize - indicated by 'pigs t' exit code of zero count=10 # approx time limit in seconds while ! pigs t >/dev/null 2>&1 ; do if [ $((count--)) -le 0 ]; then printf "\npigpiod failed to initialize within time limit\n" exit 1 fi # printf "\nWaiting for pigpiod to initialize\n" sleep 1 done printf "\npigpiod is running\n" # load uinput module - required to be able to send keystrokes # then set the permission to group writable, so you don't need to run sbpd with root permissions sudo modprobe uinput sudo chmod g+w /dev/uinput # The full list of Jivelite key commands can be found here: # https://github.com/ralph-irving/tcz-lirc/blob/master/jivekeys.csv # button 1 # button-section, defines the GPIO and key-commands SW1=16 # GPIO (BCM, not Board) SH1=KEY:KEY_1 # key-command for SHORT press (here: preset 1) LO1=KEY:KEY_Q # key-command for LONG press (here: power) LMS1=300 # milliseconds for long press # button 2 SW2=26 SH2=KEY:KEY_2 # key-command for SHORT press (here: preset 2) LO2=KEY:KEY_LEFT # key-command for LONG press (here: key left) LMS2=300 # button 3 SW3=27 SH3=KEY:KEY_3 # key-command for SHORT press (here: preset 3) LO3=KEY:KEY_RIGHT # key-command for LONG press (here: key right) LMS3=300 # button 4 SW4=12 SH4=KEY:KEY_4 # key-command for SHORT press (here: preset 4) LO4=KEY:KEY_H # key-command for LONG press (here: go_home) LMS4=300 # button rotary 1 SW5=5 SH5=KEY:KEY_SPACE # key-command for SHORT press(play/pause) LO5=KEY:KEY_LEFTBRACE # key-command for LONG press(special menu) LMS5=250 # button rotary 2 SW6=17 SH6=KEY:KEY_ENTER # key-command for SHORT press(enter, OK) LO6=KEY:KEY_ESC # key-command for LONG press(back) LMS6=250 #CMD="sbpd -v -f /home/tc/sbpd_commands.cfg \ #CMD="sbpd -v \ #b,$SW1,$SH1,2,0,$LO1,$LMS1 \ # b=button, $SW1=switchnumber of button-section #b,$SW2,$SH2,2,0,$LO2,$LMS2 \ #b,$SW3,$SH3,2,0,$LO3,$LMS3 \ #b,$SW4,$SH4,2,0,$LO4,$LMS4 \ #b,$SW5,$SH5,2,0,$LO5,$LMS5 \ #b,$SW6,$SH6,2,0,$LO6,$LMS6 \ #e,13,6,VOLU,1 \ # e=encoder, 13 and 6 are GPIO #e,24,23,KEY:KEY_DOWN-KEY_UP,4 " # e=encoder, 24 and 23 are GPIO CMD="sbpd -v \ b,$SW1,$SH1,2,0,$LO1,$LMS1 \ b,$SW2,$SH2,2,0,$LO2,$LMS2 \ b,$SW3,$SH3,2,0,$LO3,$LMS3 \ b,$SW4,$SH4,2,0,$LO4,$LMS4 \ b,$SW5,$SH5,2,0,$LO5,$LMS5 \ b,$SW6,$SH6,2,0,$LO6,$LMS6 \ e,13,6,VOLU,1 \ e,24,23,KEY:KEY_DOWN-KEY_UP,4 " echo $CMD $CMD > /dev/null 2>&1 & #$CMD &
なお、今回購入したロータリエンコーダ(KY-040)は、基板裏面に抵抗が付いているせいか、基板の+ピンに3.3V給電しないと、ロータリエンコーダの回転・ボタンとも動作が不安定で使い物にならなかった。回転しても信号がきちんと伝わらなかったり(特に反時計回り)、回転している最中にロータリエンコーダのボタン押下が発生してしまったり。
ソフトウェア的な設定の問題かとも思われたが、結局ハードウェア的な問題だった。
tc@pCP:~$ sudo modprobe i2c-dev tc@pCP:~$ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
pip3 install --upgrade luma.oled -t /home/tc/python3.8/site-packages/piCorePlayerは、Raspberry Pi OSとは違い、Tiny Core Linuxで動作しており、起動時に必要なファイルをRAMディスクに展開して動作する。
opt home home/tc/python3.8/site-packages etc/asound.conf ・・・・
#!/bin/sh sudo modprobe i2c-dev /usr/local/bin/python3 /home/tc/stats.py > /dev/null 2>&1 &表示用のpythonスクリプト:stats.py
# Local python packages LOCALSITEPACKAGES='/home/tc/python3.8/site-packages' # font dir/file FONTFILE='/home/tc/PixelOperator.ttf' # display size WIDTH=128 HEIGHT=64 # Display Refresh LOOPTIME = 1.0 import os, sys import subprocess import time sys.path.append(LOCALSITEPACKAGES) from luma.core.interface.serial import i2c from luma.core.render import canvas from luma.oled.device import sh1106 from PIL import Image, ImageDraw, ImageFont serial = i2c(port=1, address=0x3C) device = sh1106(serial, width=WIDTH, height=HEIGHT) device.clear() # font font = ImageFont.truetype(FONTFILE, 16) # loop while True: cmd = "ifconfig | grep Bcast | awk -F: '{print $2}' | cut -d\' \' -F1 | tr -d \'\\n\'" IP = subprocess.check_output(cmd, shell = True ) cmd = "top -bn1 | grep CPU: | grep '%' | awk 'NR==1{print \"CPU: \",$2}' | tr -d \'\\n\'" CPU = subprocess.check_output(cmd, shell = True ) cmd = "free -m | awk 'NR==2{printf \"Mem: %sMB %.1f%%\", $3,$3*100/$2 }'" MemUsage = subprocess.check_output(cmd, shell = True ) cmd = "df -m | awk '$NF==\"/\"{printf \"Disk: %d/%dMB %s\", $3,$2,$5}'" Disk = subprocess.check_output(cmd, shell = True ) cmd = "cat /sys/class/thermal/thermal_zone0/temp | awk '{printf \"%.1f\", $1/1000}'" Temp = subprocess.check_output(cmd, shell = True ) with canvas(device) as draw: draw.text((0, 0), "IP: " + str(IP,'utf-8'), font=font, fill="white") draw.text((0,16), str(CPU,'utf-8'), font=font, fill="white") draw.text((80,16), str(Temp,'utf-8') + '\'C', font=font, fill="white") draw.text((0,32), str(MemUsage,'utf-8'), font=font, fill="white") draw.text((0,48), str(Disk,'utf-8'), font=font, fill="white") time.sleep(LOOPTIME)
$ cat /sys/class/thermal/thermal_zone0/temp 44546定期的に繰り返し表示するなら、例えば、こんな感じか。30秒ごとに表示。
while true; do date; cat /sys/class/thermal/thermal_zone0/temp; sleep 30s; done
今回はファンを付けると10度ぐらい下がった。室温 26度程度+ファンなしで55度ぐらい、ファンありで45度ぐらい。