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 に記述しておけばグラフィカルログイン時に自動実行されるので、とりあえず問題は収まりました。マルチモニタで直っているかどうかまでは見ていません(ケーブル抜いてしまったので・・)。

Raspberry Piでラジコン用サーボを動かす

Raspberry Pi(初代)でラジコン用サーボを制御してみました。

ラジコン用サーボの信号生成には、秋月の16chキットを使いました。まず、コマンドラインでI2Cのレジスタを見ることができるようにします。

pi@raspio:~ $ sudo apt install i2c-tools python-smbus
pi@raspio:~ $ ls -la /dev/i2c*
crw-rw---- 1 root i2c 89, 0 10月 19 08:57 /dev/i2c-0
pi@raspio:~ $ sudo i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --  

次に、Python3でサーボ制御用の仮想環境を用意します。

pi@raspio:~/python3 $ sudo apt-get install python3-pip python3-venv
pi@raspio:~/python3 $ python3 -m venv servo
pi@raspio:~/python3 $ cd servo/
pi@raspio:~/python3/servo $ source bin/activate
(servo) pi@raspio:~/python3/servo $ pip install --upgrade pip
(servo) pi@raspio:~/python3/servo $ python -V
Python 3.7.3

gitでAdafruitのPCA9685用のライブラリをダウンロードしてきてインストールします。

(servo) pi@raspio:~/python3/servo $ sudo apt-get install git
(servo) pi@raspio:~/python3/servo $ git clone https://github.com/adafruit/Adafruit_Python_PCA9685.git
Cloning into 'Adafruit_Python_PCA9685'...
(servo) pi@raspio:~/python3/servo $ cd Adafruit_Python_PCA9685 
(servo) pi@raspio:~/python3/servo/Adafruit_Python_PCA9685 $ python setup.py install

exampleディレクトリにあるサンプルを実行します。

(servo) pi@raspio:~/python3/servo/Adafruit_Python_PCA9685 $ cd examples/
(servo) pi@raspio:~/python3/servo/Adafruit_Python_PCA9685/examples $ python simpletest.py 

これでPCA9685の16チャネルのサーボモータ接続端子のうちの0番に接続したラジコン用サーボが動作しました。

MH-Z19B CO2センサにケースを作りました

記事を公開するのを忘れていましたが、MH-Z19B CO2センサーにケースを作りました。

WeMOS WiFi&Bluetooth Batteryの上部にMH-Z19Bセンサを埋め込みました。

写真でも、実際に見ても見えませんが、右側面にタッチセンサを内部から貼ってあります。これにタッチするとOLEDディスプレイに写真のようにCO2ガスの濃度を15秒間表示します。表示の残り時間が下のバーグラフです。

ソフトウェアも更に変更と機能追加を行いました。これまで、Auto CalibrationはONで動作していましたが、これをOFFで動作(起動)するように変更しました。ただ、補正したいときに困るので、MQTTでコマンドを送ると、Auto CalibrationをONにすることができるようようにしてあります。Auto CalibrationがONになっている場合には、OLEDの右上に小さく「CAL」と表示するようにしてみました。

OLEDの下の穴は基板上のタクトスイッチを押すための穴です。奥がBOOT、手前がENです。

sshで公開鍵認証を設定

同じRasperry Piに繰り返しsshでアクセスするのに面倒なので、後悔カギ認証を設定します。

1.鍵の生成

~/.ssh ディレクトリで、ssh-keygenコマンドをただ実行すれば、対話的に作成できます。コマンドラインでオプションで指定してもいいのですが、覚えるのが面倒なので。

~/.ssh$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/home/USERNAME/.ssh/id_rsa): id_rsa_(ホスト名)
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in id_rsa_(ホスト名)
Your public key has been saved in id_rsa_(ホスト名).pub
The key fingerprint is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (ユーザー名@ローカルホスト名)
The key's randomart image is:
+---[RSA 3072]----+
|        =oo.. o +|
|       .+=o+ = o+|
|     . o.E* + o.+|
|      B o+O=.+  o|
|   . = =S+.+o.. +|
|    o o. o. .  o.|
|        .        |
|                 |
|                 |
+----[SHA256]-----+
~/.ssh$

2.接続先への転送

以下のようにssh-copy-idコマンドを使うと勝手にやってくれます。

~/.ssh$ ssh-copy-id -i id_rsa_(ホスト名).pub pi@(ホスト名).local

これで、

~/.ssh$ ssh pi@(ホスト名).local

で接続できます。全然簡単なのでした。