RaspberryPi2にNode-REDをインストールして使ってみる

(注意)今更RaspberryPi2を使うネタです。

7月ぐらいから仕事が微妙に忙しく体力的にも割とハードな感じだったので全くなにもできてませんでした。とはいえそろそろ何かやらないとという感じで再始動します。 (現在は営業的な業務の管理職なのでデイタイムには全くなにもできない状況…)

リハビリを兼ねて、少し前に教えてもらったNode-REDRaspberryPiにインストールして、少し使ってみたいと思います。

とはいえ、家にある開発に使用しているRaspberryPi3を使うのは環境が変わってしまう可能性があるので、家に転がっていたRaspberryPi2を使用して見ようと思います。 2も3も多分作業的には変わらないかなと思います。さすがにZeroだと違うとは思いますが…


RaspberryPi2にNode-REDをインストールしてみる

家に余っていたRaspberryPi2を使うのですが、いつも通りRaspbianをダウンロードしてもうまくいきません。WiFiのUSBドングルのドライバの対応がうまく行っていないのだと思います。

最近のRaspbianイメージはBusterベースなのですが、RaspberryPi2BではWiFiのUSBドングルのドライバがうまく認識できないので少し古いイメージを使用します。 今回使用したイメージは一つ古い2019-04-08-raspbian-stretch.img(2019/08現在)です。

基本、以下のサイトを見ながらインストールをしていくことになります。

nodered.org

あとで気がついたのですが、日本語訳もありました…涙

nodered.jp

インストールとその後の設定

先程Raspbianのイメージのインストールを行い、ネットワークの設定を行った後からの設定になります。

インストール後のRaspbianのバージョンは以下のようになっていると思います。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 9.9 (stretch)
Release:        9.9
Codename:       stretch

f:id:ueponx:20190817203416p:plain

インストール後にaptコマンドを使用してパッケージ関連のアップデートを行っておきます。

$ sudo apt update
$ sudo apt upgrade

Node-REDのインストールコマンドは以下となります。

$ bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)

このコマンドを実行すると過去にNode-REDがインストールされていた場合でもアンイストール後に最新版のインストールを行ってくれます。 その際、Node.jsのバージョンがLTSバージョンに変わるので古いバージョンのNode.js使用していた場合には注意が必要かもしれません。

f:id:ueponx:20190817204154p:plain

質問されますが、内容を確認して問題なければyキーを押下します。

f:id:ueponx:20190817204441p:plain

インストールは時間が結構結構かかるので、その間は別の作業をするのがおすすめです。 以下のような表示になればインストール終了です。

f:id:ueponx:20190817205522p:plain

インストール後のNode.jsバージョンの確認

Node-REDと同時にインストールされたNode.jsのバージョンも確認しておきましょう。

$ node -v
v10.16.3
$ npm -v
6.10.3

Node.jsはうまくインストールできているようです。

Node-REDの起動

コマンドラインでNode-REDを開始する場合にはnode-redコマンドを起動します。

$ node-red

f:id:ueponx:20190817210423p:plain

実行すると起動したコンソールが奪われてしまうので、RaspberryPiの起動時にサービスとしてスタートさせるのがおすすめかもしれません。 といっても、Node-REDWebブラウザで使用するので操作するのでそのままでいいかもしれませんが。

サービスとしてスタートさせる場合には以下のように

$ sudo systemctl enable nodered.service

サービスを停止するのであれば以下のコマンドを実行します。

$ sudo systemctl disable nodered.service

エディタへのアクセス

Node-Redが無事に起動したら、Webブラウザから以下のアドレスでアクセスをします。

http://<ip-address>:1880

http://<hostname>:1880

IPアドレスでもホストネームでも問題ありません。 Raspbianがデフォルト状態でmDNSが使用できるようであれば以下のようなアクセスも可能です。

http://raspberrypi.local:1880

f:id:ueponx:20190817213240p:plain

RaspbianのX経由のブラウザでアクセスする場合は、

http://localhost:1880

とします。

f:id:ueponx:20190817214932p:plain

これで無事に作業を始めることができるようになりました。 以降はPCからのWEBブラウザ経由で操作をしてみようと思います。

Hello World

では、最初にHello Worldを動かしてみます。

まずは左側のノード一覧の【入力】グループの中から【inject】ノードを

f:id:ueponx:20190901162645p:plain

ワークスペースにドロップします。するとドロップされたノードは【タイムスタンプ】という表示に変わります。

f:id:ueponx:20190901162653p:plain

続いては、左側のノード一覧の【出力】グループの中から【debug】ノードを

f:id:ueponx:20190901162701p:plain

ワークスペースにドロップします。ドロップされたノードは【msg.payload】という表示に変わります。

f:id:ueponx:20190901162711p:plain

上記のような表示になっていればOKです。ノードをワークスペースに配置したら、ノード間の端子をマウスでドラッグしてつなぎます

f:id:ueponx:20190901170727p:plain

f:id:ueponx:20190901170847p:plain

この操作が基本的な操作になります。

ではとりあえずここまでで一旦実行してみます。画面の左上にある【デプロイ】ボタンをクリックします。【デプロイ】ボタンはワークスペースに変更があると赤く表示が変わります。変更が反映されないときなどは確認をしておきましょう。(変更がないときにはグレーダウンしています)

f:id:ueponx:20190901171249p:plain

【デプロイ】ボタンをクリックすると、結果が表示されます。エラーがなければ以下のようなに表示されます。

f:id:ueponx:20190901171552p:plain

デプロイが成功したら、画面左にある【デバック(虫のアイコン)】ボタンを押します。

f:id:ueponx:20190901172050p:plain

すると右側のタブがデバック表示に変更します。

f:id:ueponx:20190901172433p:plain

これで準備ができました。ここまできたら【inject(タイムスタンプ)】ノードの左側のボタンをクリックしてみます。

f:id:ueponx:20190901172749p:plain

クリックするとデバックタブに実行結果が表示されます。

f:id:ueponx:20190901174320p:plain

デバックに表示されているのはタイムスタンプのNumber型での表示なのでよくわからない数値になっています。とりあえず今回はHelloWorldという文字列を表示させたいので編集していきます。

ワークスペースの【inject(タイムスタンプ)】ノードのダブルクリックします。

f:id:ueponx:20190901174527p:plain

するとワークスペースにノード編集画面が表示されます。

f:id:ueponx:20190901174848p:plain

その中に【ペイロード】の値を【日時】から【文字列】に変更します。

f:id:ueponx:20190901175208p:plain

変更後に入力ボックスに

f:id:ueponx:20190901175458p:plain

HelloWorldを入力します。終わったらノード編集の【完了】ボタンを押します。

f:id:ueponx:20190901175811p:plain

ボタンを押すと以下のような画面になります。【inject(タイムスタンプ)】ノードが【inject(HelloWorld)】ノードに変わっています。

f:id:ueponx:20190901180335p:plain

変更が確認できたら右上の【デプロイ】ボタンをクリックします。

f:id:ueponx:20190901181705p:plain

デプロイが成功したら【inject(HelloWorld)】ノードの左側のボタンをクリックしてみます。

f:id:ueponx:20190901182013p:plain

ようやく念願のHelloWorldが表示されました。

f:id:ueponx:20190901182704p:plain

おわりに

今回は長くなってきたのでここまでとなります。

割とノンコーディングでもできるっていうのはいいですね。とはいえ、始めるにはある程度、事前知識が必要になるので、準備も必要なんだろうなと感じました。

今後はWebサービスをやってみたりArduinoとの連携やRaspberryPiのGPIOの使用をやってみたいと思います。

【Node-RED 関連エントリ-】

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

RaspberryPiからObnizを使用してみる

とても久しぶりにエントリーを書いているような感じです。5月から6月はリアルな仕事で異動関連のイベントがあったのでなかなか時間がとれなかったり、 大阪で行われたデジットハッカソンに参加したりと割と忙しい感じでした。最近、本当に体力が落ちた実感があります。

その中で、ObnizRaspberryPiでエッジデバイスとして使用したいなと思うことがありました。Obnizはピンが5V出るのでArduinoUnoのような使い方ができるところとHTMLでUIを作ることができるのが結構気に入っています。あと、RaspberryPiだとGPIOが3.3Vなのでたまに電圧変換を何とかしないといけないのが面倒に感じてしまいます。回路組めばいいんだけど…、最近は老眼が進んでしまって抵抗値のカラーコードが全く見えず泣きそうです。そこで、Obnizをエッジデバイスとして使えないかなというアイデアに行きつきました。その場合にはシリアル接続かWiFiでの接続になる感じですが、コスト的にはもったいない気もしますw

折角だから、Python経由で動かそうと思っていたのですが、ObnizPythonでの利用はPython3.6以上である必要があり、RaspberryPiPythonバージョンはver3.5なので解決が必要という感じです。そこで、RaspberryPiPythonのバージョンを上げて使用してみようという実験を行いました。

手法として考えられるのは

  • pyenvを使用する
  • ソースからPython3.6をインストールする

という2つの方向性があるのですが、できればソースからのインストールは勘弁という感じです。 では、やってみたいと思います。(この実験を行ったのは2019/06/20頃です。そのため、このエントリーを書き終えた時点では壮大なオチがありますが気にしてはいけません

pyenvを使用してPython3.6系に上げる

pyenvpythonのバージョン管理を容易にするものと考えてもらっていいかなと。 詳細はこちら…

pyenv lets you easily switch between multiple versions of Python. It's simple, unobtrusive, and follows the UNIX tradition of single-purpose tools that do one thing well.

Node.jsでいうところのnと同じようなものだという考えでいいと思います。

事前に必要なものをインストール

pyenvはインストールにライブラリが必要なものがあるので事前にaptでパッケージインストールを行います。

$ sudo apt update
$ sudo apt install -y git openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev

pyenvgithubから取得

github.com

githubからクローンします。

$ git clone git://github.com/yyuu/pyenv.git ~/.pyenv

.bash_profileファイルに設定を追加、反映。

pyenvはそのまま使用できるのですが、PATH環境変数PYENVを設定していないと毎回設定する必要があるので、 ~/.bash_profileに設定を追記しておくのが楽です。

$ vi ~/.bash_profile

以下の内容を末尾追記します。(デフォルトではpiユーザには~/.bash_profileは存在しないので、そのまま書き込めばOKです)

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

~/.bash_profileに設定を追記したら、以下のコマンドで有効化しましょう。

$ source ~/.bash_profile

これでpyenvは使用可能になりました。

pyenvで利用できるバージョンの確認

では、pyenvで利用できるバージョンの確認してみます。以下のように実行すると使用可能なバージョンのリストが出力されます。

【コマンド】

$ pyenv install --list

【ログ】

$ pyenv install --list
Available versions:
(中略)
  2.7.0
  2.7-dev
  2.7.1
  2.7.2
  2.7.3
  2.7.4
  2.7.5
  2.7.6
  2.7.7
  2.7.8
  2.7.9
  2.7.10
  2.7.11
  2.7.12
  2.7.13
  2.7.14
  2.7.15
  2.7.16
(中略)
  3.5.0
  3.5-dev
  3.5.1
  3.5.2
  3.5.3
  3.5.4
  3.5.5
  3.5.6
  3.5.7
  3.6.0
  3.6-dev
  3.6.1
  3.6.2
  3.6.3
  3.6.4
  3.6.5
  3.6.6
  3.6.7
  3.6.8
  3.7.0
  3.7-dev
  3.7.1
  3.7.2
  3.7.3
  3.8-dev
  3.9-dev
  activepython-2.7.14
  activepython-3.5.4
  activepython-3.6.0
(中略)
  stackless-3.4-dev
  stackless-3.4.1
  stackless-3.4.2
  stackless-3.4.7
  stackless-3.5.4

出力している中に3.6.6があったので、今回はこれをインストールしていきます。

pyenvを使用してPython3.6をインストール

pyenvを使ってPython3.6.6をインストールします。

$ pyenv install 3.6.6
$ pyenv global 3.6.6

インストール時間は長いので、気長に待ちましょう。 globalの設定は全てのシェルでそのバージョンを利用できるようにしています。

インストールが完了したら、さっそくバージョン確認してみます。

$ python3 -V
Python 3.6.6

$ python -V
Python 3.6.6

$ pip3 -V
pip 10.0.1 from /home/pi/.pyenv/versions/3.6.6/lib/python3.6/site-packages/pip (python 3.6)

$ pip -V
pip 10.0.1 from /home/pi/.pyenv/versions/3.6.6/lib/python3.6/site-packages/pip (python 3.6)

上手くインストールされていました。 pipもインストールされていました。 ただ、Python コマンドは2系も含めて今回インストールしたバージョンに塗り替えられています。

要約準備ができたのでObnizのライブラリをインストールしてみましょう。

obniz-python-sdkをインストール

以下のドキュメントと同様にインストールを行います。

github.com

【コマンド】

$ sudo pip install obniz

【ログ】

$ sudo pip install obniz
Collecting obniz
  Downloading https://files.pythonhosted.org/packages/91/33/540c6504add677965294db2149962c3a1a843ac0fc2346f19179b1db1b92/obniz-0.3.0.tar.gz (42kB)
    100% |████████████████████████████████| 51kB 793kB/s 
Collecting attrdict==2.0.1 (from obniz)
  Downloading https://files.pythonhosted.org/packages/ef/97/28fe7e68bc7adfce67d4339756e85e9fcf3c6fd7f0c0781695352b70472c/attrdict-2.0.1-py2.py3-none-any.whl
Collecting pyee==6.0.0 (from obniz)
  Downloading https://files.pythonhosted.org/packages/ad/d8/5608d571ffad3d7de0192b0b3099fe3f38d87c0817ebff3cee19264f0bc2/pyee-6.0.0-py2.py3-none-any.whl
Collecting semver==2.8.1 (from obniz)
  Downloading https://files.pythonhosted.org/packages/21/18/a0de8cda637ba3efee1b3617ded00601507ce15bd70a39399740e0fd415f/semver-2.8.1-py2.py3-none-any.whl
Collecting websockets==7.0 (from obniz)
  Could not find a version that satisfies the requirement websockets==7.0 (from obniz) (from versions: 1.0, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, 3.4, 4.0.1, 5.0, 5.0.1)
No matching distribution found for websockets==7.0 (from obniz)

エラー…エラーメッセージを確認してみると、websocketsの依存関係がうまく行っていないようです。

【ログ抜粋】

Collecting websockets==7.0 (from obniz)
  Could not find a version that satisfies the requirement websockets==7.0 (from obniz) (from versions: 1.0, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, 3.4, 4.0.1, 5.0, 5.0.1)
No matching distribution found for websockets==7.0 (from obniz)

ということなので、pipで別途websocketsをインストールしておきます。

$ sudo pip install websockets

websocketsインストール後にもう一度、obnizのインストールを行うと問題なく完了します。

ただ、REPLでテストしてみると

$ python 
Python 3.6.6 (default, Jun  6 2019, 23:09:21) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from obniz import Obniz
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'obniz'

やっぱりエラー。うーむ。ネットを検索してみると似たようなエラーはあるので、

forum.obniz.io

できそうな感じなんですけど…解決できないので別の手段を考えてみます。


ソースコードからPython3.6系をインストールしてみる

できればこちらの手は使いたくなかった…

パッケージのアップデート

まずは必要なパッケージをインストールします。

ビルドに必要なパッケージのインストール

$ sudo apt update
$ sudo apt-get upgrade
$ sudo apt-get install build-essential tk-dev libncurses5-dev libncursesw5-dev libreadline6-dev libdb5.3-dev libgdbm-dev libsqlite3-dev libssl-dev libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev libffi-dev libc6-dev

こちらの方が必要になるライブラリが多いです。

Pythonのダウンロードとインストール(例:Python 3.6.6)

※任意のPythonバージョンをインストールする場合は以下の公式サイトを参考にファイル名を調整してください。

www.python.org

$ wget https://www.python.org/ftp/python/3.6.6/Python-3.6.6.tgz
$ tar -zxvf Python-3.6.6.tgz
$ cd Python-3.6.6
$ ./configure --prefix=/usr/local
$ sudo make
$ sudo make install

久々にソースコードからmakeしましたが、無事に終わった感じ。

pipのアップデート

pythonのインストールが終わったのでpip3もインストールしておきます。

$ sudo pip3 install -U pip
$ sudo pip3 install -U setuptools

動作確認(今回の例:Python 3.6.6)

今回のインストールはPython3のみがバージョンアップされたので、実行するのはPython3pip3になります。

$ python3 -V
Python 3.6.6

$ pip3 -v
pip 19.1.1 from /usr/local/lib/python3.6/site-packages/pip (python 3.6)

無事にインストールされたようです。

obniz-python-sdkをインストールしてテスト

先ほどと同様にインストールを行います。

【コマンド】

$ sudo pip install obniz

インストール後のテストですが、REPL環境では特にエラーなども発生していなかったので以下のようなソースを実行させてみます。

【obnizConnect.py】

import asyncio
from obniz import Obniz

async def onconnect(obniz):
    pass

obniz = Obniz('****-****') # ここには使用するobnizのIDを入力してください
obniz.onconnect = onconnect

asyncio.get_event_loop().run_forever()

【実行】

$ python3 obnizConnect.py 
WebSocket connection is closed: code = 1000 (OK), no reason
_call_on_connect

特にエラーは発生しませんでした!やったー!

f:id:ueponx:20190625202020j:plain

動作するとObnizの本体はこのような表示になっているので、実行がされているのも画面でわかります。

このサンプルは何もしないものなので更にテストを行っていきます。


以下のサンプルのソースコードを実行してみます。3Vと5VのGPIOやUARTなどを使用しています。

【ObnizSample.py】

import asyncio
from obniz import Obniz
    
async def onconnect(obniz):
    obniz.io0.drive("5v")
    obniz.io0.output(True)
    obniz.io1.pull("3v")
    obniz.io1.drive("open-drain")
    obniz.io1.output(False)
    obniz.io2.drive("3v")
    obniz.io2.output(True)

    def callback(voltage):
        print("change to {} v".format(voltage))

    obniz.ad3.start(callback)

    pwm = obniz.get_free_pwm()
    pwm.start({"io": 4})
    pwm.freq(1000)
    pwm.duty(50)

    uart = obniz.getFreeUart()
    uart.start({"tx": 5, "rx": 6, "baud": 9600})

    def onreceive(data, text):
        print(data)

    uart.onreceive = onreceive

    uart.send("Hello")

obniz = Obniz('****-****') # ここには使用するobnizのIDを入力してください
obniz.onconnect = onconnect

asyncio.get_event_loop().run_forever()

【実行】

$ python3 ObnizSample.py 
WebSocket connection is closed: code = 1000 (OK), no reason
_call_on_connect
Task exception was never retrieved
future: <Task finished coro=<onconnect() done, defined at ObnizSample.py:4> exception=AttributeError("'Obniz' object has no attribute 'getFreeUart'",)>
Traceback (most recent call last):
  File "ObnizSample.py", line 23, in onconnect
    uart = obniz.getFreeUart()
AttributeError: 'Obniz' object has no attribute 'getFreeUart'
change to 0.215 v
change to 0.205 v
change to 0.215 v
change to 0.196 v
change to 0.22 v
change to 0.205 v

UART系がエラーを出していますが、基本的には期待した動作が確認できました。

f:id:ueponx:20190625202004j:plain

動作するとObnizの本体はこのような表示になっているので、実行がされているのも画面でわかります。 GPIOの状態も変化してますのでわかりやすいです。

おわりに

なんとか、‘‘‘RaspberryPi‘‘‘から‘‘‘Python SDK‘‘‘を使用して‘‘‘Obniz‘‘‘をエッジデバイスとして使用できそうです。 もしかしたら、‘‘‘pyenv‘‘‘の場合も一度インストール済みの‘‘‘python3‘‘‘環境をクリーンにしてしまえば、うまく実行できるのかもしれません。(そこまでやりませんが)

さて、オチになりますが。 2019/06/20にリリースされた新しいRaspbianである2019-06-20-raspbian-busterではPythonのバージョンは3.7.3になっているのでこの作業は不要です。

RaspberryPiをUSB接続のSSDから起動する

今回はRaspberryPiをUSB接続のSSDから起動してみたいと思います。

※失敗しても責任は持てませんので自己責任でお願いいたします。

RaspberryPi 3 B+モデルからはUSB起動はデフォルトで有効になっていますが、RaspberryPi 3 BまでではUSB起動自体ができない状態でした。

ですが、以下の情報を読むと…

www.raspberrypi.org

USB boot is available on the Raspberry Pi 3B, 3B+, 3A+ and Raspberry Pi 2B v1.2 models only.

RaspberryPi 2Bでも行けるとのこと。これは試してみたいですね。

ブートモードはワンタイムプログラマブルメモリ(OTP(One-Time Programmable) memory)を変更することで、 有効化されます。そこでまずはRaspberryPi3でブートモードを有効化にする必要があります。具体的には/boot/config.txtにパラメーター設定をします。

では、設定をしてみましょう!

今回使用したRaspberryPiについて

今回しようしたのはRaspberryPi3ですが以下のものを使用しています。 ちなみにB+では初期状態からUSBのストレージからの起動にはデフォルトで対応しているので 作業不要です。

【ハードウエア】

$ cat /proc/device-tree/model 
Raspberry Pi 3 Model B Rev 1.2

【OS】

$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 9.8 (stretch)
Release:        9.8
Codename:       stretch

今回使用したデバイスは以下になります。SSDはかなり古めのデバイスですが、SDカードよりは十分早いので効果は現れるかなと思います。

USB起動の設定

通常起動したら、OTPメモリの状況を確認します。

$ vcgencmd otp_dump | grep 17:
17:1020000a

この値が状態がデフォルトになので、ここを書き換えていきます。 まずはaptでパッケージを更新して、そのあとrpi-updateコマンドでRaspberryPiもアップデートしておきます。一応、念の為の作業になりますが、やっておきましょう。

$ sudo apt update
$ sudo apt upgrade
$ sudo rpi-update
$ sudo reboot

下の再起動が終わったら、以下のコマンドを入力してOTPメモリに書き込みをする準備をします。 以下のコマンドで/boot/config.txtの末尾に追記します。

$ echo program_usb_boot_mode=1 | sudo tee -a /boot/config.txt

これらの作業が終わったら、一応再起動を行います。この再起動によってOTPメモリが書き換えられます。

$ sudo reboot

起動後に再度OTPメモリの状態を確認すると以下のように変更されていることがわかります。

$ vcgencmd otp_dump | grep 17:
17:3020000a

(旧)17:1020000a → (新)17:3020000a

これで作業完了です。 あとは、この状態でインストールイメージを書き込んだストレージをUSBに挿入すれば起動できます。

起動用のSDカードを作成するEtcherではUSBメモリSSDも初期化できるのでお手軽です。(確認のダイアログが何回か表示されますが問題ありません)

www.balena.io

USBで起動する

自分の手持ちのUSBストレージ環境でいくつかのを試しましたが、USBメモリ、SSDHハードディスクでは問題なさそうですが、USB-USBメモリの変換コネクタでは失敗することもありました。

ちなみにUSBメモリとSDカードメモリを両方挿した状態はSDカードの起動が優先されるようです。

250GのSSDで起動し、Raspbianをインストールしたときのディスクの状態はこんな感じになりました。

SSD起動時の状態】

$ sudo fdisk -l

…(略)…

Disk /dev/sda: 238.5 GiB, 256060514304 bytes, 500118192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x679a8aa9

Device     Boot Start       End   Sectors   Size Id Type
/dev/sda1        8192     96042     87851  42.9M  c W95 FAT32 (LBA)
/dev/sda2       98304 500118191 500019888 238.4G 83 Linux

ちゃんと起動されていることがわかります。

【比較:SDカード起動時の状態】

$ sudo fdisk -l

…(略)…

Disk /dev/mmcblk0: 29.6 GiB, 31765561344 bytes, 62042112 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x8e8f7bbf

Device         Boot Start      End  Sectors  Size Id Type
/dev/mmcblk0p1       8192    96042    87851 42.9M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      98304 62042111 61943808 29.6G 83 Linux

【比較:USBメモリ起動時の状態】

$ sudo fdisk -l

…(略)…

Disk /dev/sda: 28.7 GiB, 30752000000 bytes, 60062500 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xd92665a9

Device     Boot Start      End  Sectors  Size Id Type
/dev/sda1        8192    96042    87851 42.9M  c W95 FAT32 (LBA)
/dev/sda2       98304 60062499 59964196 28.6G 83 Linux

sysbenchのインストールとベンチマークテスト

今回はベンチマークのアプリケーションとしてsysbenchを使用します。 Unixbenchでも良かったのですが、今回はbuildの必要がないsysbenchとしました。

以下を参考にインストールをします。

github.com

RasbianはDebian/Ubuntuと同様で大丈夫なので以下でOKです。

$ sudo apt install sysbench

Optionなしでsysbenchを起動すると、以下のようにOption一覧が表示されます。

$ sysbench 
Missing required command argument.
Usage:
  sysbench [general-options]... --test=<test-name> [test-options]... command

General options:
  --num-threads=N            number of threads to use [1]
  --max-requests=N           limit for total number of requests [10000]
  --max-time=N               limit for total execution time in seconds [0]
  --forced-shutdown=STRING   amount of time to wait after --max-time before forcing shutdown [off]
  --thread-stack-size=SIZE   size of stack per thread [32K]
  --init-rng=[on|off]        initialize random number generator [off]
  --test=STRING              test to run
  --debug=[on|off]           print more debugging info [off]
  --validate=[on|off]        perform validation checks where possible [off]
  --help=[on|off]            print help and exit
  --version=[on|off]         print version and exit

Compiled-in tests:
  fileio - File I/O test
  cpu - CPU performance test
  memory - Memory functions speed test
  threads - Threads subsystem performance test
  mutex - Mutex performance test
  oltp - OLTP test

Commands: prepare run cleanup help version

See 'sysbench --test=<name> help' for a list of options for each test.

今回はファイルIOのベンチマークを取りたいので--test=fileioのオプションをつけることになりますが、さらにサブオプション(--file-test-mode)をつけることができます。サブオプションは以下の通りです。

モード 説明
seqwr シーケンシャル書き込み
seqrewr シーケンシャル読み書き
seqrd シーケンシャル読み出し
rndrd ランダム読み出し
rndwr ランダム書き込み
rndrw ランダム読み書き

今回はシーケンシャルの読み書きをテストしてみるので--file-test-mode=seqrewrを指定しています。

$ sysbench --test=fileio --file-test-mode=seqrewr run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing sequential rewrite test
Threads started!
Done.

Operations performed:  0 Read, 131072 Write, 128 Other = 131200 Total
Read 0b  Written 2Gb  Total transferred 2Gb  (32.635Mb/sec)
 2088.66 Requests/sec executed

Test execution summary:
    total time:                          62.7540s
    total number of events:              131072
    total time taken by event execution: 58.4210
    per-request statistics:
         min:                                  0.04ms
         avg:                                  0.45ms
         max:                                713.06ms
         approx.  95 percentile:               0.15ms

Threads fairness:
    events (avg/stddev):           131072.0000/0.00
    execution time (avg/stddev):   58.4210/0.00

ベンチマークで使用されたファイルは残ってしまうので、以下のコマンドでクリーンにして置きましょう。

$ sysbench --test=fileio cleanup

結果は

32.635Mb/sec

すごい!このSSDは4年ぐらい前に購入したのですが、Windowsでは全く使い物にならなかった(プチフリが原因?)感じでしたが、RaspberryPiであればそこまでのパフォーマンスの低下は感じなさそうなのでいい感じかなと思います。USB2.0転送速度の限界のこともあるので、少し古めでお安いSSDでもいい効果が見られるのかなと思いますよ。

【比較:SDカードでのベンチマーク

$ sysbench --test=fileio --file-test-mode=seqrewr run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing sequential rewrite test
Threads started!
Done.

Operations performed:  0 Read, 131072 Write, 128 Other = 131200 Total
Read 0b  Written 2Gb  Total transferred 2Gb  (11.802Mb/sec)
  755.35 Requests/sec executed

Test execution summary:
    total time:                          173.5244s
    total number of events:              131072
    total time taken by event execution: 168.8663
    per-request statistics:
         min:                                  0.04ms
         avg:                                  1.29ms
         max:                               6575.40ms
         approx.  95 percentile:               0.16ms

Threads fairness:
    events (avg/stddev):           131072.0000/0.00
    execution time (avg/stddev):   168.8663/0.00

【比較:USBメモリでのベンチマーク

$ sysbench --test=fileio --file-test-mode=seqrewr run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing sequential rewrite test
Threads started!
Done.

Operations performed:  0 Read, 131072 Write, 128 Other = 131200 Total
Read 0b  Written 2Gb  Total transferred 2Gb  (17.081Mb/sec)
 1093.16 Requests/sec executed

Test execution summary:
    total time:                          119.9023s
    total number of events:              131072
    total time taken by event execution: 109.9788
    per-request statistics:
         min:                                  0.04ms
         avg:                                  0.84ms
         max:                               1930.89ms
         approx.  95 percentile:               0.15ms

Threads fairness:
    events (avg/stddev):           131072.0000/0.00
    execution time (avg/stddev):   109.9788/0.00
ストレージ 転送速度
SDカード 11.802Mb/sec
USBメモリ 17.081Mb/sec
SSD HDD 32.635Mb/sec

おわりに

予想以上のパフォーマンスなので、ファイルIOを多用する場合にはUSB経由の起動にしたほうが良さそうです。 ただ、RaspberryPiからUSB給電する場合には電源には気をつけたほうがいいかもしれません。

体感もかなり高速だなと思いました。特にパッケージのインストールなどではそれが顕著に感じました。SDカードの挿入も面倒なので今後はUSBの運用にしちゃうかもしれません。

Pixelaを使ってはてなブログにPV数の草を生やしてみた

今回のエントリの内容はメモレベルです。

去年のMashupAwards2018で出た作品でFesta(最後のイベント)に参加したときに、githubのような感じででコミットの状態を出すサービスでPixelaというものがあるということを知りました。そのときはおもしろいなと思ってましたが、自分にはあんまり関係ないのかな~という感じでみていました。

ただ、少し前まで使用していた、ブログのPV数をTwitterでつぶやいてくれるサービスがうまく動作してない(多分https化したときに設定が変わったから?)という状況と、最近はTwitterのタイムラインを見る機会がそれほど多くなくなってきたということもあるので、別の手段でなんか見れないかなと思っていました。

んで、ググってみたところPixelaの作者さんのエントリーに当たりました。

pixe.la

blog.a-know.me

このやり方をそのまま進めれば問題ないのですが、設定していたところちょっと躓いたのでメモ。 上記の2つのエントリーを読んでについて書いています。

  1. ユーザの登録
  2. グラフデータの作成の仕方
  3. はてなブログへの貼付け方法

ただ、設定してブログに貼り付けたあとPV数の更新(カウントアップ)がされない状況になります。これだけではなにかが足りないような感じです。グラフの生成はされているので、外部にカウント機能を持った何かが必要なのかなと思っていたのですが、以下のエントリを読み込んでみてわかりました。

blog.a-know.me

ここで、これまでの Pixela を知っている人向けの説明として、今回のバージョンアップで selfSufficient というフィールドが指定できるようになっています。直訳すると自給自足。これはつまり、グラフが見られるごとに自分自身を加算(もしくは減算)していく、ということを指定するための属性になります。

グラフの生成時のJSON"selfSufficient":"increment"のフィールドを追加することでグラフへアクセスするたびにカウントできるということです。これを指定すれば問題は解決します。

ただサンプルにあるコマンド例がcurlのため、Windowsではかなり不安ですw。

そこで作者の方が別途作成されたpiというCLIツールを使用することにします。ここまでやると別途curlをインストールしてもいいんですけどね。

blog.a-know.me

まずはこちらからダウンロードします。 Windows処理系なのでリスト中からpi_v1.0.1_windows_amd64.zipを選んでダウンロードします。 Windows処理系なのでリスト中からpi_v1.0.2_windows_amd64.zipを選んでダウンロードします。 アーカイブを展開するとこんな感じになるので、テキトーな場所に展開します。

f:id:ueponx:20190421182625p:plain

実はこのままだとうまくいかないです。 実行ファイルのpiに拡張子がないので実行しようとしても失敗します。リネームしてpi.exeにします。 念の為githubで作者の方にissueを投げたところ、version 1.0.2にバージョンアップして対応していただきました。超感謝! これで準備完了です。

あとは事前に以下を決めておきます。

  • ユーザーネーム
  • アクセスに必要なAPIトーク
  • グラフ名(URLで使用)
  • グラフ名(人間識別用)

この実行ファイルはAPIトークンを環境変数で使用するのでユーザー登録をしたときのトークンは登録が成功したら環境変数PIXELA_USER_TOKENに登録しておきましょう。

今回は以下の様に決める前提としようと思います。

設定項目 設定値
ユーザーネーム hogepon
APIトーク fuga2019
グラフ名(URLで使用) hatena-pv
グラフ名(人間識別用) "HatenaPV graph"

これを使って実行していきます。

> pi users create --username hogepon --token fuga2019 --agree-terms-of-service yes --not-minor yes
> set PIXELA_USER_TOKEN=fuga2019
> pi graphs create -u hogepon -g hatena-pv -n "HatenaPV graph" -i view -t int -c shibafu -z "Asia/Tokyo" -s increment

f:id:ueponx:20190421143451p:plain

piコマンドは成功すると以下の様なJSONが帰ってくるので判断に使用します。

{"message":"Success.","isSuccess":true}

上記のコマンドが成功すると以下のURLでグラフの状況を見ることができます。 ユーザー名、グラフ名が自分のものになっているかを確認しましょう!

https://pixe.la/v1/users/hogepon/graphs/hatena-pv.html

f:id:ueponx:20190421143749p:plain

これでOKです。

リロードするとちゃんとカウントアップできました。

f:id:ueponx:20190421144231p:plain

あとは

blog.a-know.me

上記のブログ通りに設定すれば問題ありません。あとは引っかかるところはほとんどありませんが、 テストで使用しているURLは作者さんのページなので自分のグラフのURLに書き換えましょう。

おわりに

今回はちょっと引っかかった部分があったのでやってみましたが、REST API経由でこういうグラフが出せるのは便利かも。あとカウンタの値がページ描画完了してからのカウントになっているのではてなブログのアクセスカウンターよりも少なく表示されています。多分、ちゃんとページロードが走った部分だけがカウントされているからだと推測。はてなさんのアクセス数はGoogleさんのBots経由のアクセスも含まれているのかもしれませんね。

以下が設定して配置した結果です。

f:id:ueponx:20190421145502p:plain

これからの草生え具合を楽しみにします。

RaspberryPi3にWindows10 ARM版をインストールする【インストール編】(2019/04/12現在)

前回のエントリに引き続きRaspberryPi3にWindows10 ARM版をインストールするということでやっていこうと思います。 前回のエントリではMicroSDカードメモリにインストールイメージを作成するところまでを行いました。

【前回のエントリ】

uepon.hatenadiary.com

今回のエントリではそのMicroSDカードメモリをRaspberryPi3に挿して起動し、Windows10のARM版を立ち上げる部分となります。 わりとバギーなものなので、なぜそうなるのかということよりも、うまく行った方法みたいなことになりますので、ご注意ください。 うまく行かなかった点もそのうち治ると思いますよw

起動→UEFIっぽい部分

MicroSDカードメモリをRaspberryPi3に挿入します。今回使用したのはRaspberryPi3 Bになります。最近はB+も出ていますが、多分どちらでも大きくは変わらないのではと思います。

起動するとRaspberryPiのロゴが大きくでプログレスバーがその下に出てきます。

f:id:ueponx:20190414080121j:plain

そのままにしているとUEFIのシェルモード画面になってしまいます。

f:id:ueponx:20190414080129j:plain

ロゴが出ているうちに【ESC】キーを押してメニューモードに入りましょう。2019/04/17追記:UEFIのシェルモード画面になった場合にはexitと入力すればメニューモードに行けるようです。このような画面になります。BIOSのような画面のような感じです。

f:id:ueponx:20190414080137j:plain

ここまで来たらBootの順番などの設定を行っていきます。まずは【Boot Maintenance Manager】にカーソルをあわせて【Enter】キーを押して設定を行っていきます。

f:id:ueponx:20190414080145j:plain

Boot Maintenance Managerの画面になったら【Boot Options】を選択し、【Enter】キーを押して進みます。

f:id:ueponx:20190414080154j:plain

Boot Optionsの画面になったら【Change Boot Order】を選択し、【Enter】キーを押して進みます。

f:id:ueponx:20190414080201j:plain

Change Boot Orderの画面にくると【Change the order】で<UEFI Shell>`<SD/MMC on Broadcom SDHOST>にカーソルが来ていると思うので、そのまま【Enter】キーを押します。

f:id:ueponx:20190414080210j:plain

以下のような画面になったら、【UEFI Shell】にカーソルが当たっている状況で【-(マイナス)】キーを押して

f:id:ueponx:20190414080218j:plain

以下のように【SD/MMC on Broadcom SDHOST】(上)と【UEFI Shell】(下)に変化させます。

f:id:ueponx:20190414080237j:plain

設定が終わったら【ESC】キーを押してメニューに戻ります。

f:id:ueponx:20190414080244j:plain

設定を変更したので【Commit Changes and Exit】にカーソルを移動させて【Enter】キーを押します。

f:id:ueponx:20190414080252j:plain

すると、Boot Optionsの画面に戻ります。そのまま、【Go Back To Main Page】にカーソルを合わせて、【Enter】キーを押します。

f:id:ueponx:20190414080302j:plain

Boot Maintenance Managerの画面に戻ります。そのまま、【ESC】キーを押してメインメニューに戻ります。

f:id:ueponx:20190414080310j:plain

メインメニューに来たら今度はカーソルを【Boot Manager】に合わせて【Enter】キーを押します。

f:id:ueponx:20190414080328j:plain

※注意この操作をするとSDカードから起動を行います。

Boot Managerの画面に遷移したら、【SD/MMC on Broadcom SDHOST】にカーソルを合わせて【Enter】キーを押します。これでRaspberryPiは再起動され、Windows10のインストール処理を開始しますので注意してください。

f:id:ueponx:20190414080343j:plain

Windows10のインストール処理

再起動が行われるとWindows10のロゴが表示されインストール処理が開始されます。ここからも時間がかかる処理が多いので30分ぐらいかかると思っていてください。

f:id:ueponx:20190414080353j:plain

時間が経つと以下のような画面になります。住んでいる地域の設定になります。今回はデフォルトだった【日本】にカーソルを合わせて【はい】ボタンをクリックします。(ここからはマウス操作はできます。)

まずはWindows10のインストール作業が進んだということで一安心となるのですが…

f:id:ueponx:20190414080519j:plain

問題が発生しましたと表示されます。画面上にはやり直すことも、今はスキップすることもできます。という優しい言葉が表示されますが、何度【やり直す」ボタンをクリックしても同じ画面にいきつきます。ですので、【スキップ】ボタンをクリックして処理を進めていきます。

OOBEKEYBOARDと表示されているのでキーボードの認識関連でコケているのだと推測。その後の設定でもキーボードが英語キーボードの配列になっているので注意です。

ここで脱落する人もいるかもという罠その1

f:id:ueponx:20190414080528j:plain

そのあと、ネットワークに接続していなければ有線ネットワークの設定などを行う画面が入ったりしますが、事前にEthernetケーブルを指しておけば、セットアップは何もしなくても継続してくれます。

f:id:ueponx:20190414080536j:plain

処理中に、またもや問題が発生しましたと表示されます。OOBEEULAとかかれていますが、こちらは内容がよくわかりませんが、やり直すことができます。と書かれていますというか【やり直す】ボタンしかないので、これをクリックして進めていきます。

f:id:ueponx:20190414080545j:plain

そのまま処理は進めていけました。

f:id:ueponx:20190414080600j:plain

少し時間が経つとWindows10の使用許諾契約の画面が表示されます。【同意】ボタンをクリックします。

f:id:ueponx:20190414080608j:plain

設定する方法を指定してください。と画面に出るので今回は個人用に設定を選び

f:id:ueponx:20190414080615j:plain

【次へ】ボタンをクリックしました。

f:id:ueponx:20190414080624j:plain

Microsoftアカウントでサインインという画面に来ます。 もうこれで大丈夫そうだなという空気が漂います。 アカウントのメールアドレスを入力します。先程もいいましたがキーボードの配列がJISではないので気をつけて入力してください。入力が終わったら【次へ】ボタンをクリックします。

f:id:ueponx:20190414081205j:plain

続いてはパスワードを入力します。入力後に【次へ】ボタンをクリックします。

f:id:ueponx:20190414081251j:plain

するとまたインストール処理が進みます。

f:id:ueponx:20190414081334j:plain

少しすると今度はPINの設定処理になります。ここはスキップはできないようですね…

f:id:ueponx:20190414081359j:plain

好きなものをPINにして処理を進めましょう。入力できたら【OK】ボタンをクリックします。

f:id:ueponx:20190414081421j:plain

アクティビティの履歴を利用してデバイス感でより多くのことを行うという画面が表示されます。ここでは【いいえ】を選択しました。

f:id:ueponx:20190414081453j:plain

AndroidまたはiPhoneをこのPCにリンクするという画面になります。ここは画面左下の【後で処理する】をクリックしてスキップを行います。

f:id:ueponx:20190414081501j:plain

OneDriveの設定になりますが、SDカードの容量などもあるのでこのあたりはやめて画面左下の【このPCにのみファイルを保存する】をクリックしてスキップをしました。

f:id:ueponx:20190414081511j:plain

デジタルアシスタントを利用する画面が表示されます。もうそろそろ完了しそうな雰囲気ですね! 基本的にはデジタルアシスタントはスキップする項目なので【拒否】をクリックして選択するのですが、

f:id:ueponx:20190414081525j:plain

問題が発生しました。(エラーはOOBESETTINGS)となります。やり直すことができますと表示されますが、何度やってもこの画面に戻ってきます。(※でも何度かやることが重要のようです)しかたないので、画面犠打理上の【←(左矢印)】ボタンをクリックして一手順戻します。

f:id:ueponx:20190414081533j:plain

するとデジタルアシスタントを利用する画面に戻ります。今度は【同意】ボタンをクリックします。

f:id:ueponx:20190414081542j:plain

すると、デバイスのプライバシー設定の選択に画面が遷移します。 初回から【同意】ボタンをクリックして進めても実は問題が発生しました。(エラーはOOBESETTINGS)が表示されます。何回か、このエラー画面を表示させて、その後手順を戻さないと何故か進められなかったようです。

ここが結構わかりにくいハマりポイントでした。

ここでは適切に設定して貰もらって、【同意】ボタンをクリックします。(結局同意にしないと進められないということです)

f:id:ueponx:20190414081550j:plain

クリックすると処理が進みます。

f:id:ueponx:20190414081557j:plain

そして、画面の解像度がアップして全画面モードになります!漸くWindowsの設定が完了した様子です。

f:id:ueponx:20190414081605j:plain

数分かかるらしい…

f:id:ueponx:20190414081614j:plain

いよいよインストールが終わりそうです!

f:id:ueponx:20190414081622j:plain

予想より長いらしい…こんな表示初めてみました!

f:id:ueponx:20190414081632j:plain

やっと起動しました!(45分弱経っていたようです)

f:id:ueponx:20190414081640j:plain

Edgeの画面がでるのですが、真っ白。ネットワークの設定が画面右からニューっと出てくるのでその設定をしたら

f:id:ueponx:20190414081650j:plain

Edge言語設定ダイアログが表示されました。

f:id:ueponx:20190414081700j:plain

プルダウンから【日本語】の設定にして、【Get Start】ボタンをクリックします。

f:id:ueponx:20190414081709j:plain

無事に起動できたようです。

f:id:ueponx:20190414081717j:plain

インストールの情報に関して

画面のキャプチャなども通常のWindows同様にできるようなのでやってみました。スピードに関しては全く実用的ではありませんが、Webの閲覧もかなり我慢すればできなくはないと行ったところです。

f:id:ueponx:20190414081924p:plain

コンピュータの情報のキャプチャもとってみました。

f:id:ueponx:20190414081939p:plain

ちゃんとARMベースのプロセッサになっています!

おわりに

なんとかRaspberryPi3にWindows10のARM版をインストールできました。 動作が遅いのはPC資源としては非力なので致し方ないです。ですが、この大きさのものでWindows10も動くのだな~という点では関心しました。

パフォーマンスのチェックはしませんでしたが、一番のネックはストレージでしょうか。 CPUのパワーも100%に近い状態ではありましたが、クロックを600MHzからもう少し上げることができるので、熱対策を行ってそれを行えば割とまだありかな? ストレージに関してはもう100%から下がることはほとんどなかったです。

RaspberryPi 3B+モデルではUSBストレージからの起動もデフォルトで可能なのでSSDUSBメモリなどを接続(電源的な辛さもありそう)すればもう少し動作の改善がみられるかなと思いました。

残りの課題としてはノートPCのVisual Studioで作成したARM処理系のプログラムが動くのかに関しては後日調べてみたいです。

でも最後のトラップは普通だとあきらめるよなあ…

/* -----codeの行番号----- */