ブラウザでターミナル入力をするbutterflyを試す

Webブラウザでターミナル入力ができるbutterflyというソフトウェアがあることを知りました。Webブラウザ内でターミナルが動く、という点で似たようなことができそうなソフトウェアとしては、shellinaaboxwebsshsshwiftyttydwettyなどもありそうですが、まずはbutterflyを試してみます。(ttydはOpenWRTでも動くようです)

“ブラウザでターミナル入力をするbutterflyを試す” の続きを読む

Raspberry Piでoverlayfsを使う

Raspberry Piを使っていると面倒なのがシャットダウンです。最近のRaspbian(Raspberry Pi OS)にはoverlayfsがあるので使ってみることにしました。

設定自体は簡単で、raspi-configを起動して「Performance Options」の中にある「Overlay File System」を設定するだけです。設定して再起動すると有効になります。また、再度raspi-configを起動して設定を無効にして再起動すると無効になります。これで普段有効にしておけばいきなり電源断しても大丈夫になります。

一方で、有効になったままいろいろ作業して再起動してしまうとすべて失われてしまいます。ですので、ちょっと工夫をすることにしました。

“Raspberry Piでoverlayfsを使う” の続きを読む

MQTT用に個別に証明書を用意する

WebArenaでMQTTサーバを立てたときに、電子証明書はWebサーバのものを使うように設定しましたが、これだとLet’s Encryptでサーバ証明書やフィンガープリントが更新されたときに困ってしまいます。

ですので、mosquitto用に専用の証明書を用意します。Webブラウザは関係ないので、今回はオレオレ証明書で行くことにします。といっても、ほぼこちらの記事のままです。ですので、参考にされる方はこちらの記事を見てください。あと、公式ドキュメントも参考になります。以下は自分の作業記録として必要な部分だけです。

“MQTT用に個別に証明書を用意する” の続きを読む

APDS-9960をRaspberry Piで試す

BluePillでは検出すらできなかったAPDS-9960ですが、Raspberry Piで試してみます。
とりあえず、3.3V、GND、SDA、SCLを結線してRaspberry Piの電源を入れて、I2C上に見えているか確認します。

$ i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- 39 -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --                   
$

アドレス0x39でデバイス自体は見えているようですので、実際に動作させます。今回はお手軽に済ませたいので、こちらのライブラリを使用して進めます。
まずはPython3の仮想環境を作って、ライブラリをインストールします。

$ cd python3
$ python3 -m venv apds9660
$ cd apds9660
$ source bin/activate
$ pip install --upgrade pip
$ pip install apds9960 RPi.GPIO smbus
$ cd python-apds9960
$ python3 setup.py install
/usr/lib/python3.7/distutils/dist.py:274: UserWarning: Unknown distribution option: 'long_description_content_type'
  warnings.warn(msg)
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/apds9960
copying apds9960/const.py -> build/lib/apds9960
copying apds9960/__init__.py -> build/lib/apds9960
copying apds9960/device.py -> build/lib/apds9960
copying apds9960/exceptions.py -> build/lib/apds9960
running install_lib
running install_egg_info
Writing /home/pi/python3/apds9660/lib/python3.7/site-packages/apds9960-0.2.egg-info
$ 

gitでプロジェクトをcloneしてサンプルプログラムを実行してみます。

$ git clone https://github.com/liske/python-apds9960.git
Cloning into 'python-apds9960'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 114 (delta 3), reused 6 (delta 2), pack-reused 102
Receiving objects: 100% (114/114), 37.23 KiB | 150.00 KiB/s, done.
Resolving deltas: 100% (49/49), done.
$ cd python-apds9960/rpi
$ python3 test_gesture.py 
Traceback (most recent call last):
  File "test_gesture.py", line 8, in <module>
    bus = smbus.SMBus(port)
FileNotFoundError: [Errno 2] No such file or directory
$ 

ということで、エラーになってしまいます。どうやら、普通のsmbusモジュールでは仮想環境ではダメなようです。

$ pip install smbus2
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting smbus2
  Downloading https://www.piwheels.org/simple/smbus2/smbus2-0.3.0-py2.py3-none-any.whl (9.1 kB)
Installing collected packages: smbus2
Successfully installed smbus2-0.3.0
$

として、smbus2というモジュールをインストールします。その後、test_gesture.py の ソースの冒頭の

import smbus

というモジュールをインポートしている箇所を

import smbus2 as smbus

と修正します。これで実行すると、今度は、

$ python3 test_gesture.py 
Traceback (most recent call last):
  File "test_gesture.py", line 8, in <module>
    bus = smbus.SMBus(port)
  File "/home/pi/python3/apds9660/lib/python3.7/site-packages/smbus2/smbus2.py", line 279, in __init__
    self.open(bus)
  File "/home/pi/python3/apds9660/lib/python3.7/site-packages/smbus2/smbus2.py", line 308, in open
    self.fd = os.open(filepath, os.O_RDWR)
FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'
$

ということで、「そんなデバイスはない」と怒られます。ソース7行目の「port = 1」を「port = 0」に修正すると、ようやく動作しました。センサーの前で手を動かすと、その方向に応じた表示が出ます。なかなか面白いです。

・・・・が、Raspberry Piで動かすのではなく、もっと小さなマイコンで動かしたいんだよなぁ。なんでBluePillのI2Cは動かないんだろう??

BluePillでI2C(うまくいかん・・)

STM32(BluePill)がArduino環境で動くようになったので、I2Cにチャレンジしています。

ターゲットデバイスはジェスチャー検知デバイスのAPDS-9960です。ちょうど、Arduinoの標準ライブラリがあるので、これで動かしてみたいと思ってトライしています。

で、ブレッドボード上にこんな感じで組んでみました。

BluePillボード+APDS-9660センサテスト環境。Flashの書き込みはSTLinkで実施。シリアルはSerial3に秋月の絶縁タイプのFT234X基板を使用。左下の3本のケーブルはラジコンサーボに接続されています。

この記事でRTOSのテストを兼ねてLチカしたり、ラジコンサーボを動かしたりした環境に追加したので、それらが残ったままになっています。

で、ライブラリのサンプルを動かしてもさっぱり動きません。オシロで波形をみても、SDAが出ておらず、わけがわかりません。

もっとシンプルに、I2Cデバイスのスキャンを行うサンプルプログラムを実行したのですが・・・。

上の赤がSCL(PB7)、下の黄色がSDA(PB6)です。そもそもStart Conditionが出ていないので、動かないのも当たり前なのですが、理由がさっぱりわかりません。ターゲットデバイス以前の問題です。

SoftWire.hをインクルードして、ハードウェアI2CではなくソフトウェアI2Cとしても波形は一緒です。

うーん。

BluePill+FreeRTOSのテスト

スケッチ例のFreeRTOS900をベースにLED点滅+ラジコンサーボ制御をさせてみました。オンボードのLED(PC13)と、PB0、PB1に接続したLEDを異なる周期で点滅させると同時に、PWM出力を使ってPA7に接続したラジコンサーボをゆっくり動かしています。RTOSを使ってそれぞれ独立したタスクとして制御していて、今回は4つのタスクを起動しています。setup()の最後のvTaskStartScheduler();は帰ってこないようで、loop()の中は実行されません。
4つのタスクを動作させてもこのくらいなら問題ないようですが、configMINIMAL_STACK_SIZEは120になっていますので、処理を増やしていくとどっかでスタックオーバーランすることと思います。このサンプルには記述していないですが、ハードウェアシリアル(テストではSerial3を使用)も各タスクで動かしてもとりあえず動くようで、デバッグの際に使えそうです。

“BluePill+FreeRTOSのテスト” の続きを読む

NenoPiNeo2+NASキットで自宅内Ubuntuサーバを仕立てる

今回はUbuntu Focal(20.08LTS)で仕立てました。
なお、記載中のIPアドレスは実際のIPアドレスと異なります。

1.起動用MicroSDの準備とNASキットの組み立て

まずはイメージをダウンロードしてきます。
https://www.armbian.com/nanopi-neo-2/

これをディスクイメージライタでMicroSDに書き込んだら、NASキットを組み立てます。
NASキットのHDDには余っていた1TBのHDDを使いました。そろそろメカニカル障害を回避することを考えると、宅内のサーバくらいなSSDの240GBとかでもいいのかもしれません。

2.初回の接続

ネットワークにつないで起動する前に、

$ fping -g 192.168.1.0/24 2> /dev/null | grep alive

として生きているIPアドレスを列挙しておきます。
表示が完了したら、NASキットの電源を投入して起動します。
再び、

$ fping -g 192.168.1.0/24 2> /dev/null | grep alive

として、増えたIPアドレスにsshで接続します。

$ ssh root@192.168.1.x

初期パスワードは「1234」なので、これを入力してログインします。
ログインすると、パスワードを何に変更するか聞いてくるので、変更したいパスワードを入力します。
次に、一般ユーザーの作成を聞いてくるので、アカウント名とパスワード、本名(いつも入れません)を入力すると、一般ユーザーのアカウントが作成されます。

この状態では root でログインしているので、できることから作業していきます。

3.まずは更新します

なにはともあれ更新します。

$ apt update
$ apt upgrade

で更新をかけます。更新したら、カーネルが更新されていることが多いのでrebootコマンドで再起動します。しばらく待って、再度 root で再度ログインします。

4.HDDのパーティション設定

HDDのパーティションを設定します。

$ fdisk /def/sda

でfdiskを起動して、pコマンドでパーティションを表示して内容を確認。想定しているディスクであることを確認したら、dコマンドですべてのパーティションを消去します。すべてのパーティションを消去したら、nコマンドでディスク全体をext3パーティンションとして作成します。最初は /home を分けようかとか /var を分けようかとか悩んだのですが、考えること自体が面倒なのでディスク全体で1パーティションにしてしまいました。

5.HDDにルートファイルシステムを移動

armbian-configを起動して、HDDにルートファイルシステムを移動します。

Systemメニューの中のInstall(Install to/update boot loader)を選択します。

これで次のメニューで/dev/sda1を選択すれば、bootはMicroUSBのままですが、システムを/dev/sda1に移動することができます。(内部的にはUSBで接続されています)
sda1を選択後、ディスクが全部消えるよ、とかフォーマットどうする?とか聞いてきますが、すべてデフォルトでいいと思います。これで、ext4でフォーマットされて、システムの転送が始まります。転送には自分の場合には約4分かかるとの表示でした。転送完了後、リブートするか聞いてきますので、そのままEnterを押してリブートします。
ちなみに、NASキットでもUSBメモリを挿して同じ操作をすれば、USBメモリをシステムに置くことができるので、より速くなります。(速度だけならより高速なMicroSDカードを挿すほうがいいかもしれませんが)

6.ネットワークなどの設定

しばらく待って、再度rootでログインして、再びarmbian-configを起動して、今度はNetworkのメニューを設定します。IPのメニューでIPアドレスを固定化します・・・が、DNS設定がないようです。まあ、名前解決できているようなのでヨシとします。
Personalのメニューで必要に応じてタイムゾーンをAsia/Tokyo、ロケール、ホスト名を設定します。
ホスト名を設定したらSystemメニューでAvahiをイネーブルにします。

これでリブートすれば、とりあえず最低限の設定は終わりです。
引き続き、必要なソフトウェアをインストールするなりなんなりと・・・です。

ただ、気づいたのは3rd party softwareの中にOpenMediaVaultがなくなっていることです。まあ、今回はOpenMediaVaultは目的ではないですが・・・。

LinuxMint20にMPLAB Xをインストール

久しぶりにLinux環境にMPLAB Xをインストールします。その記録です。結論から言うと、「Microchipさん、もうちょっとリンク先とか管理してもらえるとありがたい」です。まあ、地雷はそこそこあってもLinux版としては圧倒的に簡単にインストールできる(至れり尽くせり)ことには変わりないのですが。

Microchip社のダウンーロードページからLinux 64bit用MPLAB X IDEをダウンロードします。

“LinuxMint20にMPLAB Xをインストール” の続きを読む

Celeron J3160+LinuxMint20の不具合

Web閲覧用の静かなマシンCeleron J3160をLinuxMint20にアップデートしたところ、Xの表示に不具合が出ました。マウスカーソルを左端に持っていったときに引っかかったり固まったりするというものです。マルチモニタ時はさらに顕著に発生します。

マルチモニタをやめれば出ないのかと思ったら、シングルモニタでも出るのでほぼ使うのをやめてしまっていたのですが、回避策が見つかりました。

まず、xrandr で接続されているポートを確認します。自分のところではDP-3でした。確認したら、

$ xrandr --output DP-3 --scale 0.9999x0.9999

とすると、(とりあえず)直ります。このコマンドを ~/.xprofile に記述しておけばグラフィカルログイン時に自動実行されるので、とりあえず問題は収まりました。マルチモニタで直っているかどうかまでは見ていません(ケーブル抜いてしまったので・・)。