2020年9月29日火曜日

apt upgradeでエラーでアップデートできない

この前ソースからコンパイルしようと悪あがきをしていた3bですが、phpが無くなっていたようでwebサーバーでうまくページが表示されなくなくなっていました。あまり問題は無いので放置していましたが少し不便なのでphpのインストールをしようかとapt updateしたところupgradeのタイミングでエラーが出てしまい途中で処理が止まってしまいました。

検索するとそれらしい話が

Unable to Install using apt-get https://www.raspberrypi.org/forums/viewtopic.php?t=17016

公式フォーラムの掲示板でした。

つらつらっと見てみると、結論としては単純にサーバーに到達できていないだけの様子。解決策も提案されていて、

sudo nano /etc/resolv.conf

and then add the lines

Code: Select all
nameserver 8.8.8.8
nameserver 8.8.4.4

dnsサーバーをgoogleのネームサーバーを参照するように設定することが提案されていました。早速、nanoで編集してそのままapt updateしたところうまく行きました。

この状況に陥っているということは、ルーターのリセットが必要なのかもしれません。もうちょっとまともなそろそろルーターに買い替えるべきかなぁ…

ただ、非常に気になるのが、結構な根幹部分のアップデートがかかっていて/boot/kernelとか/boot/overlaysとか見えているのが気になります。時間も結構かかっているようだし様子を見守りましょう。

2020年9月16日水曜日

cronで連続される

ことの発端はボードの温度の異常上昇でした。


午前4時の間に気温の変動がない状態でボードの温度だけ上昇しています。これにはSoftEatherが入っているので外部からのハッキングを一番に考えました。そんなわけで昨日の更新を行ったわけですが…。

2020年9月15日火曜日

SoftEtherの更新

自動起動させている場合はサービスを停止して、wgetでダウンロードして、makeしてファイルをディレクトリに配置して、設定を更新するだけ。だけ?(笑)

今回はstretchが入ったRaspberry pi 3B+です。なのでArmの32bit版。busterで64bitだとどうなるのかな??

2020年9月13日日曜日

lircがうまくインストールできませんでした

赤外線リモコンを減らすためだけに結構前からRasberry piで赤外線コントロールをしたかったのですが、なかなか環境を整えることができません。
学習リモコン的な事を行うためには赤外線受信センサーと赤外線のLEDが必要ですが、まずLEDが無かったのでそこから準備を始めることに。
入手してからどんなパッケージを使うのがいいのか見ていたんですが、lircというパッケージを使うのが一般的なようなのでパッケージをインストールしてみるもののどうもうまく動いてくれない様子。
原因はどうもbusterだとソースからコンパイルする必要があるらしいので検索で引っかかったブログの解説に従って進めてみましたが、コンパイルは通った感じでパッケージまでビルドできた感じですがインストールがうまく行きませんでした。
原因としては、そのブログのページにも書いてありましたが、アップデートでstretchからbusterに下環境だとだめなときがあると言うことと、更に痛かったのが、パッケージソースをインストールするためにパッケージ参照のファイルのコメントアウトを行ってソースを有効化したのですが、その時にstretchのままだったという…
aptのキャッシュの削除や、設定を正しくした上でソースをインストールし直したりしてみたものの、それでも結果は変わらず。
取りあえずlircは諦める方向で考えることにしようかと。
lirc自体結構大掛かりな感じになっていて、ポートの設定などを行った上でサービスを動かして動作させる形になっていて、更に設定を見ている限りリモート接続して操作させるような実装になっていました。まぁネーミングからもそんな感じがありますよねぇ😑
リモートで行いたいけど、ダイレクトに実装されるのもなぁ…
ただサンプリングと再生を考えると、直接GPIOピンを扱おうとすると、割込処理をガードするためにドライバが必要になりそうなのでlircを使った方がいいとは思うのですが…
取りあえず手持ちのLEDの発光はスマホのレンズ越しで確認したのと、赤外線受信センサーはpythonのスクリプトで確認できたのでこれからまた少し遊べそうです。

夜中に夜空を見上げたら

ペルセウス流星群は流れ星が沢山流れて、北斗七星が見える程度の夜空でもハッキリと肉眼で見ることができました。
今朝寝る前に夜空を見上げたら、オリオン座が確認できたのでベランダにでて少し眺めていたとこと、オリオン座の少し左上方向から短いですが流れ星が流れました。
街頭が減ったのか、コロナの影響で空気が綺麗になったのかはわかりませんが、今年は流星を見かける機会がとても多いです。

2020年8月14日金曜日

懲りもせず今日も少し夜空を見上げてしまいました

今日の昼間は雨こそ降りませんでしたが、雷は激しく、思わず動画撮影したらいい音が取れました。手ごろな編集ソフトが無いのでyoutubeにアップして前後をカットしてコレクションにw

寝る前に窓の外を見てみると、北の空の雲がなさそうなので出てみると意外と涼しかったです。

そんな中さすがにラッキーなことは3度目は起こらず、結局1時間ぐらい外に居ました。

見えたものは…カシオペア座の下の方に上から下へ短く流れるものを見た気がするのと、飛行機か人工衛星の光が右へゆっくりと流れる光ぐらいでした。

2020年8月13日木曜日

ペルセウス流星群

 日付としては一昨日になりますが、12日は天気が悪くなるとのことで前日の夜に少しベランダで夜空を眺めていました。youtubeでウェザーニュースなどでも幕張の夜空のライブ中継やっていましたが、私がちょうど一つ流星を見つけて満足して戻ったらライブは終わってました。時刻は23時20分ごろで北極星の下側に左から右へほぼ真横に流れました。見えた流星はかなり短め(手を伸ばして5~10㎝程度)でしたがはっきりと見えました。

そして今日はふと外をみると星が見えたのですこしベランダに出て北側を少し眺めているとほぼ真上にカシオペア座が見え、その下に右から左へ流れる流星を見ることができました。長さはいい感じの長さ(腕を伸ばしたところで20~30㎝程度かな?)でした。時刻は2:30過ぎかな…そのあと蚊取り線香に火をつけてスマホを構えてベランダで待機してみましたが、残念ながら写真に収めることはできませんでした。ベランダに出て2、3分もしないうちに見れたのがラッキーだっと思います。

昨日もyoutubeでライブが流れていましたが、北海道とどこかな。レーザー光線やら人工衛星やら色々と邪魔が入ってたようですが、ライブ中継で映ったのなら、どこかで編集して公開してくれると嬉しいですね。

2020年8月7日金曜日

実行時間の計測

全体でどのくらいの負荷がかかっているのか気になったのでどんな手段があるのか検索してみました。

Linuxでシェルレベルの時間計測は3つの方法がありそうです。

  • timeコマンドを利用する
  • dateコマンドを利用する
  • bashで利用可能なSECONDS変数を利用する

timeコマンドは秒単位ですが小数点を表示しているのでミリ秒程度の精度はあるようです。dateコマンドとSECONDS変数は秒単位となります。

コマンドレベルで利用するのに便利なのはtimeで、シェルスクリプトで利用するなら表示形態によってdateコマンドかSECONDS変数を利用するか変わるのではないでしょうか。

試しに実行してみました

pi@rasp4b4g:~/gpioread $ time ./dht2 -h
未知のオプションが指定されました。

dht ver.0.1 debugコードコミコミ版

指定可能なオプション
--debug : デバッグ情報の表示
--gpio n : GPIOピン番号(デフォルトはGPIO5番).
--type x : DHT11かDHT22を指定する。(デフォルトはDHT11)大文字、小文字の判別はしない。
        指定された型の手順でセンサーから読込み、湿度、温度を出力するが、
        読込んだデータをもとに判定しできる限り出力する。
        ただし、その時のリターンコードはエラーとなる。
--oneread : 無指定時はセンサーから2回読込み、2回目に取得した値を出力する。
        このオプションが指定されるとセンサーからの読込を1回だけに限定する。
        センサーがスリープしていた場合はスリープ前の値が出力される。

real    0m0.010s
user    0m0.000s
sys     0m0.011s

最初からなんか数字がおかしい感じなので調べてみると

real > user + sys

という関係になると思いますが、0.001sずれている結果に。

気を取り直して、同じような状態になるようにオプションをつけてcで作成したものとpythonとで比較したいと思います。

pi@rasp4b4g:~/gpioread $ time ./dht2 --oneread
temperature : 35.6
humidity : 60.0

real    0m0.044s
user    0m0.001s
sys     0m0.043s
pi@rasp4b4g:~/gpioread $ time python3 ./dht.py --onetime --nodirect
DHT results.
Conversion  : DHT11V1.3
Temperature : 35.5 C
Humidity    : 60.0 %

real    0m0.257s
user    0m0.136s
sys     0m0.052s

実行時間で比較すると0.2s程度python側の方が時間がかかっているようです。実行時間が長いpythonでは確実に割り込みによって実行時間が伸びている感じがします。

この差の大小を考えるには運用方法とそれぞれの利点と欠点を比較する必要がありますね。
個人レベルとしては、

  • ソースファイルと実行ファイルが分かれていないので、管理コストがかなり低い。
  • ほとんどのことがpythonだけで完結する。
  • ライブラリなども動的にリンクさせて実行できる。

といったpythonの利点がかなり有利なのでpython以外の選択肢はない気がしていますが、それでも常駐させるような形のものをpythonで書くのはどうかという部分も引っかかっています。

この数字はその時の判断材料となりそうです。 

c側のコマンドがサンプリングバッファを利用しない形に対応していないので --nodirectとして実行していますが、先日書き換えた結果どのくらい効果があったのか見てみたいと思います。

pi@rasp4b4g:~/gpioread $ time python3 ./dht.py --onetime
DHT results.
Conversion  : DHT11V1.3
Temperature : 35.6 C
Humidity    : 60.0 %

real    0m0.246s
user    0m0.134s
sys     0m0.042s
 

時間にして0.257s - 0.246s = 0.011s まぁこんなものでしょうwメモリー操作なら数メガ単位の操作にならなければ、個人レベルのデータ量であればそこまで気にする必要はなさそうです。

2020年8月5日水曜日

無駄にpython側でもダイレクトにdataformatへ格納する処理を作ってみた

スクリプト的に流れが気に入らなかったので、結局pythonでもドライバで実装したサンプリング配列を作らないで直接dataformatを作成する処理を実装することに。

ついでに異常値に色付けなども行ってみました。
ドライバを介さないと途端に割り込み処理による取りこぼしが発生していました。
pi@rasp4b4g:~/gpioread $ python3 ./dht.py --debug --nodriver
Output for debugging.
gpio_no : 5
No driver is used.
OSError : 1 IsNoDriver
Sampling is performed without using a driver.
respons low  : 82
respons high : 87
data low     : 51 ~ 55
data high '0': 23 ~ 26
data high '1': 69 ~ 72
data format : 3F 00 23 06 68
2nd read.
OSError : 1 IsNoDriver
Sampling is performed without using a driver.
respons low  : 85
respons high : 89
data low     : 43113
data high '0': 21 ~ 29
data high '1': 66 ~ 73
data format : 2F 00 23 06 68
CRC Error.
ErrorCode :  2  retry.
OSError : 1 IsNoDriver
Sampling is performed without using a driver.
respons low  : 82
respons high : 87
data low     : 48 ~ 133
data high '0': 21 ~ 29
data high '1': 65 ~ 72
data format : 3F 00 23 06 D0
CRC Error.
ErrorCode :  2  retry.
OSError : 1 IsNoDriver
Sampling is performed without using a driver.
respons low  : 88
respons high : 87
data low     : 48 ~ 58
data high '0': 21 ~ 29
data high '1': 65 ~ 72
data format : 3F 00 23 06 68
DHT results.
Retry count : 2 time(s)
Conversion  : DHT11V1.3
Temperature : 35.6 C
Humidity    : 63.0 %

不完全とはいえ、こうなると割り込み停止させるためにメモリマップドレジスタに展開されている割り込み停止処理も入れておきたくはなります。個人的にはそれよりドライバをちゃんと登録して、再起動時にも読み込まれるようにするのが先の様な気がしますw

サンプリングせずにダイレクトにビットを格納してみると…

作業としてはあまり大変そうではなかったので、コピペして切り張りして試してみました。
最初、ちょっと間違えてLOW信号の長さを見てしまったため、FFFFFFFFFFになってしまいましたが、見直してすぐに正しい処理が流れてよかったw
インターバルのデバッグもそのままコピーしたのでログから実行時間を比べてみました。

2020年8月4日火曜日

サイクルカウントのウェイトを作成してGPIOのPull Up/Downを実装してみました。

150Cycleのウェイトループが作れるようになったのでドライバ側でpull up/downの実装も行ってみました。これで一歩踏み込んだ形になります。
ただし、データシート上に記載してありましたが、pull up/downの設定値はcpuから見えなくなるため、設定値はソフト側で管理する必要があるとのこと。なので、これを行うとRpi.gpioの内部バッファと実際値のズレが生じてRpi.gpoiでうまく機能しなくなる可能性があります。

実装中に色々と新たな発見というか記載を見かけて色々な部分を書き換えながら実装していましたが、一番気になったのがioremapでアクセスできるようになったメモリーに対してアクセスするためにioread/iowriteといった関数を通す必要があるらしいという点。

2020年8月3日月曜日

arm gccが改めてすごいと感じたこと

サイクルカウンタを使ってみて気になったのはパフォーマンスカウンタを有効にしていると発熱や消費電力に影響があるのかないのか?気にはなりますが、おそらく数字に出てこないレベルなのではないかと思うのですが、とはいえ、使用が終わったらカウンタを止めておきたいと思ったときに、本当に止まっているのかテストをしてたところ、

    while((cnt<50000) && (((unsigned long)end - start)<150)){
        cnt++;
        end = pmon_read_cycle_counter();
    }
    if(isStart){
        pmon_stop_cycle_counter();
        dummy = pmon_read_cycle_counter();
        printf("stop\n");
        dummy2 = pmon_read_cycle_counter();

        printf("%ld, %ld\n", dummy, dummy2);
    }

まぁこんなことをやってみたわけです。
サイクルカウンタのテストプログラムでも、一定の回数を回している上記のループが終わった時のカウンタの値が150なのでたまたまかな?と思っていたんですが、これが上記の物でも150という数字を返してきました。
何がすごいかといえば、ループの終了条件判断の分岐とその後の条件文の分岐を無視して機械語レベルで1サイクルの中でサイクルカウンタが止められているということです。
armの特性として、実行条件が命令と結合しているので条件分岐がハマれば実行順序の乱れが無いというのは分っていたのですが、ここまで正確に数字に出てくると驚きの方が大きかったです。
試しに停止直前に
        dummy = pmon_read_cycle_counter();
        pmon_stop_cycle_counter();
        dummy = pmon_read_cycle_counter();
などと、やってみましたが、これで返される値は151という。
dummyに代入するところは直後に再度同じdummyに代入しているので、最適化で外されているとは思いますが、インラインアセンブラとは言え本当に1cycleしかかかっていないとか…

正直凄い以外の言葉が出ない。

2020年8月2日日曜日

ARMのサイクルカウンタ

先の投稿でARMなにがしの手順はあったのですが、結局Raspberry piで使えるのかどうか確認するのにえらい手間取りました。
そもそもARMでの開発をするためのバイブルなんて一切ないので。
昔は書店に行って「やっぱりない」と言うことがとても多く、無駄なお金を使っていましたが、今ならアマゾンとかあるので、、、
だからポチるのか?と言われれば、まずは下調べからしないと痛い目を見そうですし、そもそもARMの種類ってよくわかんないんですよねw気づけば64bitだとか。
とりあえずダイレクトで検索して見るとバイブルっぽいPDFがいくつかありました。
さらに、Raspberry pi 2bで採用されているARMv7の仕様書っぽい感じのものがありました。
https://static.docs.arm.com/ddi0406/c/DDI0406C_C_arm_architecture_reference_manual.pdf
英語なので細かい所はさっぱりですが、コードとその場のノリでなんとなく必要なことが見えてきました。
少なくてもRaspberry pi 2bなら ARM Coretex-A9と同じ手順で行けそうな気配がしてきました。
Raspberry pi 3bとかはARM Coretex-A53とかA72とか互換性はどんな風になってるのか想像できません…下位互換性なCPUでも結構維持されていなかったりするのであれなんですが、そもそもの拡張のされ方とか内容と型番を覚えるのが苦手なので正直つらいですw

パフォーマンスカウンタが複数設定できそうなところとかが良くわかってませんが、一つ一つ確認したところポイントは変わっていないのが確認できました。
まぁ最悪カーネルパニックになるだけなので、とっとと試したいと思います。


ソースファイルなどを準備して、まずは…権限付与ドライバからいきましょうかね。
pi@rasp4b4g:~/pmon $ ls
Makefile  pmon_ca9.h  pmuser.c  test.c
pi@rasp4b4g:~/pmon $ make
make -C /lib/modules/5.4.51-v7l+/build M=/home/pi/pmon modules
make[1]: ディレクトリ '/usr/src/linux-headers-5.4.51-v7l+' に入ります
  CC [M]  /home/pi/pmon/pmuser.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC [M]  /home/pi/pmon/pmuser.mod.o
  LD [M]  /home/pi/pmon/pmuser.ko
make[1]: ディレクトリ '/usr/src/linux-headers-5.4.51-v7l+' から出ます
pi@rasp4b4g:~/pmon $ ls
Makefile        modules.order  pmuser.c   pmuser.mod    pmuser.mod.o  test.c
Module.symvers  pmon_ca9.h     pmuser.ko  pmuser.mod.c  pmuser.o
ドライバが作れる環境なのと、すこしmakeを調べたので手直しすべき部分はあっさりとクリアw
さて…
pi@rasp4b4g:~/pmon $ gcc -o test test.c
pi@rasp4b4g:~/pmon $ ./test
Illegal instruction
権限がないと、例外が発生するのも確認。
pi@rasp4b4g:~/pmon $ sudo insmod ./pmuser.ko
pi@rasp4b4g:~/pmon $ ./test
time = 94, x = 500500
pi@rasp4b4g:~/pmon $ ./test
time = 105, x = 500500
pi@rasp4b4g:~/pmon $ ./test
time = 94, x = 500500
無事動作確認が取れました!
ARM Cortex-A72の4bで行けたから2b以降なら大丈夫でしょう(ただし32bit環境)…ということで。

これで…150サイクルが実現できて、ドライバ内で処理が完結しやすくなります。
pi@rasp4b4g:~/pmon $ sudo rmmod pmuser
で削除するか再起動をお忘れなく…

湿度が下がってかなり楽にはなったけど、温度が上がってくるときになることは…

昨日から関東上空に停滞続けていた梅雨前線の中央が消滅したと同時に湿度が下がりようやく梅雨明けしました。
昨日の午前中はまだ若干部屋の中の湿度が高めだったのですが、午後からはようやく夏の気候になりました。それでも日本の夏は湿度高めですが…

気温が低くても湿度が高いと体感温度はかなり上がってしまうので、正直2週間ほど前の状態よりは体感温度は低く感じますが、温度計を見ると結構上がってました。
そこで気になるのは…そうですRaspberry piの本体温度ですw

サイクルカウントのヒント?

全然関係のないことを調べていたら検索結果にタイムリーな記事が。
サイクルカウントできそうな話題!
正直なところ、モード切替の150サイクルを待機する部分がお手上げだったのでソースを探して…まではしたんですけど、いままでまったく興味が無かった部分でソースや断片がどこにあるのかとか明るくないのでそちらもお手上げでしたw
で、いきなり「コプロセッサとアクセス…」ドライバ側で何もしないでアクセスできるのかどうか不安になりつつも、少し見ていくとそれの元ネタのページへのリンク。
なんとなく行けそうなタイトルです。「このソースは特権モードで使用することを想定しています。」ど、ドライバ内で使えるのかな?

早速組み込んで遊んでみようかな。

見てみると色々と捉え方が変わりますね。まずドライバをinsmodすると初期化処理が動いてrmmodするまでそのままの状態であるということ。確かにそうですが、こんな感じに利用するのが本来の使い方なのかな?。確かに権限付与とかやりやすそうな実装に見えます。

2020年8月1日土曜日

気になる部分を書き換え中に気付いたこと

今日はraspberry pi 4bで動かしていますが、気になったこと。

python側もサンプリング時のループ回数を表示させてみたところ、cで試していた時とは違った違いが出てきました。dhtセンサーの値を2連続で取得しているのですが、1回目と2回目の差が出てきています。

array('I', [11, 82, 88, 53, 25, 54, 70, 54, 24, 54, 24, 54, 24, 54, 24, 54, 25, 53, 72, 54, 24, 54, 24, 54, 24, 54, 24, 54, 24, 54, 24, 54, 24, 54, 26, 53, 25, 54, 24, 54, 70, 54, 24, 54, 24, 54, 24, 54, 24, 54, 25, 54, 25, 54, 24, 54, 24, 54, 24, 54, 24, 54, 70, 54, 71, 54, 25, 54, 24, 54, 70, 54, 71, 54, 24, 54, 24, 54, 70, 54, 70, 54, 72, 54])
array('I', [104, 805, 852, 526, 236, 527, 687, 526, 235, 526, 236, 526, 236, 526, 236, 527, 236, 526, 697, 526, 236, 526, 236, 526, 236, 526, 236, 526, 236, 526, 236, 526, 236, 526, 246, 526, 236, 526, 236, 526, 695, 526, 236, 526, 236, 526, 236, 526, 236, 526, 245, 527, 235, 527, 236, 526, 236, 526, 236, 526, 238, 527, 687, 526, 688, 526, 246, 526, 236, 526, 687, 526, 688, 526, 235, 527, 235, 526, 688, 526, 687, 527, 694, 526])
2nd read.
array('I', [8, 82, 87, 55, 24, 54, 70, 54, 24, 54, 24, 54, 24, 54, 24, 54, 24, 54, 72, 54, 24, 54, 24, 54, 24, 54, 24, 54, 24, 54, 24, 54, 24, 54, 25, 54, 25, 53, 25, 54, 70, 54, 24, 54, 24, 54, 24, 54, 24, 54, 25, 54, 25, 53, 25, 53, 25, 54, 24, 54, 24, 54, 70, 54, 71, 53, 72, 54, 24, 54, 70, 54, 71, 54, 24, 54, 70, 54, 24, 54, 24, 54, 25, 54])
array('I', [29, 328, 347, 215, 96, 214, 280, 214, 96, 215, 96, 214, 96, 215, 96, 214, 96, 214, 284, 215, 96, 214, 96, 215, 96, 214, 96, 214, 96, 215, 96, 214, 96, 214, 100, 215, 96, 214, 96, 215, 280, 214, 96, 214, 96, 214, 96, 215, 96, 214, 100, 215, 96, 214, 96, 214, 96, 215, 96, 214, 96, 215, 280, 214, 280, 214, 284, 215, 96, 214, 280, 214, 280, 215, 96, 214, 280, 215, 96, 214, 96, 214, 100, 214])
順番にサンプリングのデータ、サンプリング時のウェイトループのループ回数とありますが、サンプリングのデータはほぼ同じような数字となっていますが、ループ回数が大きく違います。
ドライバを呼び出さない場合も比べてみると、
array('I', [6, 82, 88, 52, 23, 55, 69, 54, 23, 54, 23, 54, 23, 54, 23, 54, 69, 54, 23, 54, 23, 54, 23, 54, 23, 54, 23, 53, 25, 53, 25, 51, 26, 51, 25, 54, 23, 54, 23, 54, 71, 54, 23, 53, 25, 51, 25, 53, 23, 53, 25, 54, 23, 52, 25, 53, 23, 54, 23, 54, 23, 55, 69, 53, 25, 51, 72, 54, 23, 53, 69, 54, 70, 55, 23, 54, 23, 53, 70, 55, 71, 52, 72, 54])
array('I', [1, 24, 33, 19, 8, 20, 26, 20, 8, 20, 8, 20, 8, 20, 8, 20, 26, 20, 8, 20, 8, 20, 8, 20, 8, 20, 8, 20, 9, 20, 9, 19, 9, 19, 9, 20, 8, 20, 8, 20, 27, 20, 8, 20, 9, 19, 9, 20, 8, 20, 9, 20, 8, 19, 9, 20, 8, 20, 8, 20, 8, 21, 26, 20, 9, 19, 19, 20, 8, 20, 26, 20, 26, 20, 8, 20, 8, 19, 26, 20, 26, 19, 27, 20])
2nd read.
array('I', [0, 81, 87, 53, 26, 52, 72, 51, 27, 51, 25, 51, 25, 51, 26, 52, 70, 58, 19, 58, 25, 51, 25, 51, 25, 50, 25, 52, 25, 51, 25, 52, 26, 51, 26, 57, 19, 59, 18, 59, 64, 58, 19, 52, 25, 57, 19, 59, 20, 52, 26, 58, 19, 58, 19, 57, 25, 51, 25, 51, 26, 51, 71, 51, 26, 52, 72, 57, 18, 58, 70, 51, 72, 51, 26, 53, 25, 52, 70, 51, 71, 52, 72, 52])
array('I', [0, 8, 12, 7, 3, 7, 10, 7, 3, 7, 3, 7, 3, 7, 3, 7, 10, 8, 2, 8, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 2, 8, 2, 8, 9, 8, 2, 7, 3, 8, 2, 8, 2, 7, 3, 8, 2, 8, 2, 8, 3, 7, 3, 7, 3, 7, 10, 7, 3, 7, 10, 8, 2, 8, 10, 7, 10, 7, 3, 7, 3, 7, 10, 7, 10, 7, 10, 7])
サンプリングのブレ幅はありますが、こちらもループ回数が半減していました。

それぞれの4番目のデータを見てみます。
ドライバで求めた値 53 562 / 55 215
python内で求めた値 52 19 / 53 7
562 ÷ 215 ≒ 2.6
19 ÷ 7 ≒ 2.7

もうちょい正確にいってみましょうかw
1μ秒単位のループ回数比で計算してみると
562÷53≒10.60
215÷55≒3.909
10.6÷3.9≒2.711

19÷52≒0.3653
7÷55≒0.1272
0.3653÷0.1272≒2.871
それぞれ回数の低い方基準の数字ですが、こんな感じに。0.16の差は何かというのは気になりますね。レジスタアクセスでキャッシュが効いてないアクセスがあるのが原因か、pythonの実行処理がキャッシュ前提の効率化がうまく行っているのかはわかりません。

このぐらいの数字で心当たりがあるとすれば、CPUクロックの変動ぐらいしかなさそうなので、確認してみます。
pi@rasp4b4g:~/gpioread $ cpufreq-info -p
600000 1500000 ondemand
pi@rasp4b4g:~/gpioread $ cpufreq-info -f
600000

1500000÷600000=2.5

原因はおそらくこれかな…cではそのまま実行されるので、クロック変動しないままサンプリング処理を終えていましたが、pythonはおそらくオーバーヘッドの処理が重たいのでクロックアップ状態のままサンプリングを行って、2秒の待ち時間があることでクロックダウンしたのではないかと推測。記憶を辿ると、3bでcで連続で試したときもリトライ時の方が処理速度が落ちていたときがあったような気がします。

2020年7月31日金曜日

ドライバで気になっていること

ドライバでちゃんと動作しているのか確認するために色々見ていたところ、メモリーアクセス時のアライメントはどうなっているのか?という点

試しにGPIOレジスタ周りで実際に表示させてみたところ

[250867.394720] f0abd000 00008900
[250867.394733] f0abd000 00008900
[250867.394749] f0abd001 00677069
[250867.394764] f0abd002 69006770
[250867.394778] f0abd003 70690067
[250867.394790] f0abd004 00024000

アドレスとその内容を出力させてみると、4バイトごとの時には正しくアクセスできているようですが、アライメントからずれているとどうも前後ではない部分にアクセスしている感じ。
気になるのはその「どこか」の内容がそれなりにずれているのも気になります。

一回りしてpythonに戻って

一通り手直しを終え、ドライバが無かったらそれなりに動く形のものに落ち着きました。

各変数の位置がいい加減だったり、配列は相変わらずどんぶりだったりと突っ込み所も多いですが、参考になれば

2020年7月30日木曜日

pythonで作って動かしてたけど、cで作り変えて軽くしようかな?

などととてつもなく面倒そうな事が頭から離れません。

そのまま動くから絶対的なオーバーヘッドが無くなるからraspberry piに優しいはず?
基本的にはmotionを動かしっぱなしなのですが、そこまでcpuリソースが切迫しているわけでもないわけで…
そもそもpythonで揃え始めた理由の一つはスクリプトなのに結構そのまま動かせるというのが一番の理由だった記憶が。

2020年7月29日水曜日

ioctlだと割り込みは発生しない?

寝付こうかと思ったらふとこんな疑問が。

システムコールが割込み処理という話は今まで聞いたことは無いけど、ありえなくはなさそうなので、気になりだすとダメですねwざっくりと検索して見るものの、これといった話はなさそう。なので割込み制御部分をコメントアウトしてしばらく様子を見ることに。

連続実行しているとようやく発生しました。

2020年7月28日火曜日

ようやく綺麗な感じに

のんびりとドライバの作り方を参考にそれなりのものが形になってきました。
ユーザープログラムから一歩踏み込めば割り込み制御もなんの制限もなく行えました。
この辺の部分の経験は全く無く、ハードウェアで遊んでいたところからいきなり離れてソフト的な部分が主体となってしまった結果だと思います。

そんなドライバとアプリを組み合わせた見慣れてきたデバッグ結果は…

2020年7月24日金曜日

ドライバをコンパイルできる環境

ドライバの作り方を見てみると、凝ったことでなければ敷居は低い様なので試してみることに。

最初に躓いたのは、Makefileの名前をmakefileとしたことによってmakeが通らなかったり、ヘッダファイルのバージョンが実行環境と不一致で強引にコンパイルしてinsmodしたときにエラーで失敗したり。

割り込みの様子を見てみる

日照時間が少なく、日が差しても気温が上がるだけで湿気が高い日が続いていて過ごしにくい日が続いていますね…。

色々と無駄な足掻きを必死にしてもう少しで、、、というところでやっぱりダメという感じのことを繰り返しています。

取りこぼしの原因は何らかの割り込み処理なんだろうなぁとは分っているものの、μsやms単位の処理を気にすることはほとんどない世界に居すぎたため、armやlinuxの割り込み処理を調べることがから始めました。

割り込みを一時的に停止させる方法は大きく分けて3つあるようで、アセンブラでCPSIE/CPSIDでIとFのフラグを操作すれば割り込みを有効/無効化する方法と、armのメモリマップドレジスタを操作することで割込み制御を行う方法があるようです。
ただし、CPS命令は特権モードでしか使用できません(無視されるだけかも)。

2020年7月19日日曜日

処理落ち

検索して何とかなるなら何とかしたいので「処理落ち」とかで日本語も検索してたらちょっとびっくりするようなネタが…

そこには処理落ちと並んで「重い」「遅い」とかの蘊蓄が綴ってありましたが、
昔のゲームのスプライト表示が消えたりする事が「処理落ち」です。と、エー😰

表示落ちとかグラディウスや沙羅漫蛇ぐらいの状態なら処理落ちでいいと思うけど、消えるのはハードウェアの制約で、ちらつくのはただ消えるなら表示タイミングごとにスプライトの優先順位を切り替えた結果ちらついてるだけで、処理落ちとは違うんじゃないかなぁ…と

まぁそんなことはさておき、処理落ちを抑えるためにはcpuロックを行って排他的に占有するぐらいしか手はなさそうです。しかもカーネルじゃないのに出来るのかどうか…う~ん…

英語で検索するしかないかな…

何となく落ち着いた感じと少しまとめ

値段以上に結構元を取れたと思うDHT22ですが、結局のところほぼDHT11と同じだったという感想。測定範囲だけはどうしてもDHT11だとダメなところはありますが。湿度の小数点は実用上ほぼ不要だと思いますし。

DHT11の時に記憶に残っている注意書きとかと同じ現象がDHT22も発生し、データシート上を見続けているとちゃんとそのことが記載されていたりします。そんなところでまとめ的な点として
・その時点の湿度と温度を取得したい場合は2回連続で読み出す必要がある。
・連続で読み出す場合は2秒間をあける必要がある。
この点が、やっぱりDHT11/DHT22が好きになれないところとなっています。
結局2連続で読み出す必要があるので、最低でも2秒もかかってしまいます。

2020年7月18日土曜日

cでも取りこぼしがw

sampling_start_lev : 1
sampling_end_lev   : 1
length : 82
179 54 26 54 26 54 26 54 26 54 26 54 26 54 74 53 26 67 74 54 26 54 73 54 74 54 26 54 73 54 26 54 73 67 26 54 26 55 40 39 27 53 26 55 26 53 27 54 25 67 74 54 73 54 74 54 73 54 74 54 74 54 26 54 25 64 74 54 26 54 73 54 74 54 26 54 26 54 73 54 73 47

GPIO操作をcで

取りこぼし発覚からpython以外でGPIOを直接操作したくてライブラリやパッケージを検索してたのですが、思っていたよりは乱立していなかったものの、メジャーっぽいので4つぐらい存在していました。ほとんどpythonから利用できるもので、cから使えそうな感じでした。

すでに意識してなかったけど、pythonでも使ってるし、raspberry piの公式ページで見かけていたRPI.GPIOがいいかな?とcのソースを起こし始めたのですが…あれ?cのサンプルになりそうなソースが検索で引っかからない…
もう何でもいいかと投げやりで、最悪デバイスをファイルから出力すればいいか…とかあきらめかけていたところ、もう少しハードよりの低レベルライブラリとしてhttp://www.airspayce.com/mikem/bcm2835/bcm2835-1.64
というものがありました。
良くも悪くもハード寄りなので定数や変数、関数名が分かりづらいですが、これで直接操作できそうです。

扱い方の基本はpythonでGPIOを操作するときと変わらないので手元のスクリプトを基にデータを受信するところまで作って、受信内容を表示させてみたいと思います。

まずは…コメントの日本語でコンパイルがおかしいことにwクソッw
gccのコンパイルでソース記述のコードページと、生成したオブジェクトが出力するコードページを指定するようにしてコンパイルが通るようになりました。
pi@rasp3b:~ $ gcc dht22.c -o dht22 -l rt -l bcm2835  -finput-charset=UTF-8 -fexec-charset=UTF-8

さっそく実行させてみましす。

pi@rasp3b:~ $ ./dht22
sampling_start_lev : 0
length : 81
22 26 54 27 56 23 54 27 53 27 53 27 54 73 54 25 68 74 54 73 54 26 53 27 54 26 54 73 55 26 54 25 67 26 54 27 53 27 53 27 53 26 54 26 54 27 53 25 68 74 54 73 54 74 53 74 54 26 54 26 54 74 54 25 65 73 54 26 54 74 54 73 54 74 54 26 54 26 52 27 47

受信はμs単位ですが、何となくデータは取りこぼしも発生してなさそうで、連続で実行しても見た感じは大丈夫そうです。

ただ、気になるのはデータ送信開始の信号の時間間隔が短すぎるところと、pythonではこち側のHIGHレベルの信号を受信できることがあったのですが、今回作成したものは開始がLOWから始まることしかないのが気になり、そうしていると受信データが79個とかいきなり取りこぼしてそうな感じに。

実際に信号をサンプリングしているループがどの程度の速度で回っているのか様子を見ることから始めました。

sampling_start_lev : 0
length : 81
37 27 53 26 55 25 54 26 55 26 54 26 54 73 54 25 67 74 54 74 54 26 54 26 54 26 54 74 53 26 54 73 67 26 55 26 53 27 54 26 53 27 54 26 54 26 54 25 68 73 54 73 55 73 54 74 53 27 53 27 54 26 54 25 64 74 54 26 54 73 54 74 54 26 54 74 53 74 54 73 46
82 58 119 58 120 57 120 58 120 58 119 58 120 163 119 56 149 164 119 164 119 58 119 58 120 58 118 164 119 58 120 161 149 58 120 58 119 58 120 58 119 58 120 57 120 58 120 55 150 163 120 163 113 153 119 164 119 58 119 58 120 58 119 56 143 163 120 58 120 163 120 163 120 58 120 163 119 164 120 160 104

2個目の数字の塊がループ中カウントを行った回数です。
37μsで82回、回ってるので処理落ちしている様子はありません。
何度か実行していると、ループのカウンタが200を越える数字が見えるようになりました。
66 101 205 100 209 101 214 101 204 101 206 97 205 279 205 96 256 277 208 98 205 280 208 277 209 280 207 277 207 278 208 98 257 102 211 90 192 94 176 88 185 80 179 89 175 85 179 84 221 262 209 281 211 281 208 277 207 101 201 100 207 277 207 91 247 278 210 101 203 289 203 283 203 101 209 94 208 277 207 96 175

もしかしてCPUクロックが変動するので、変なタイミングで処理落ちするのかな?と途方に暮れながらソースを眺めて寝落ちした後、少し落ち着いて考えてみると、sleepさせて開始させているけど、実際の時間はどのぐらいなのだろう?と実際に計測させてみました。

sampling_start_lev : 0
sampling_end_lev   : 1
length : 81
37 26 54 25 54 27 54 25 55 26 54 25 54 74 54 25 68 73 54 26 54 74 54 74 53 74 54 74 54 26 53 73 67 27 54 26 53 27 54 26 53 27 54 26 54 26 54 25 67 74 54 73 54 74 54 74 54 26 54 26 54 73 54 73 64 74 60 20 54 73 54 74 54 26 54 26 54 74 53 26 47
70 53 111 53 111 54 111 52 102 48 110 53 111 152 110 52 139 151 111 54 111 151 111 152 110 152 111 151 111 54 110 150 138 54 111 53 111 54 111 54 110 54 111 53 111 54 111 51 138 152 111 151 111 152 111 151 111 53 111 53 111 152 111 149 132 152 40 38 107 146 107 146 107 51 107 52 106 146 107 50 93
start : 1595040856 964706
p1 : 613
p2 : 50726
p3 : 70816
p4 : 71017
p5 : 71020
p6 : 1075103
p7 : 1075978

すべてμs単位で開始からの経過時間を表示させていますが、p1が最初のHIGH信号を送信する直前で、p2が信号を送信したあとusleep(50000);を行った後なのですが、50113μs経過しています。最初のHIGHの送信は実際は必要ないので経過時間はあまり関係ないのですが、それでもセットアップして信号をHIGHにするだけで100μs程度かかっているのは予想以上にもたついています。
次のp3はLOW信号を送信してusleep(20000);させた後なのですが、ここでも経過時間が20090μsとなっていて90μs程度もかかっています。
時間が不安定→sleepが原因
というわけで、ちょっとCPUに優しくなくなりますが、時間ループを作って様子を見ることに。

start : 1595041084 066267
p1 : 631
p2 : 50639
p3 : 70639
p4 : 70838
p5 : 70840
p6 : 1074781
p7 : 1075044

同じく8μs、1μs以下と、まったく高速化処理をしていない状態でかなりの精度で処理が行われるようになりました。
p3からp4はピンを入力に切り替えた後に信号をプルアップさせてHIGH状態に切り替えています。(この辺の手順が前々から気になっているんですけど、本来はHIGH状態にしてからピンの入出力を切り替えるべきだと思うんですがこの辺の考え方が良くわからない)199μsと、それなりに時間がかかっています。
p4からp5はループさせる前の初期設定で、2μs。p5からp6がループ中の時間で最後は出力系の部分で必要な処理ではありません。
時間的にタイトなところはp3からp4の部分で信号線がHIGHになった後、DHT22のデータシート(Table 6: Single bus signal characteristics)では
Tgo(ホスト側のHIGH信号)とTrel(センサー側のLOW信号)の最低時間が20μs、75μsとなっていて、最低でもHIGH信号をに変えた後、95μs以内にで受信開始できないと最初のデータを取りこぼすことが出てくるというところ。
なのでもう少し時間を見てみましょう。

start : 1595042362 253428
p1 : 607
p2 : 50615
p3 : 70616
p4 : 70618
p5 : 70892
p6 : 70894
p7 : 1074949
p8 : 1074949

増やした部分はp4のところでbcm2835_gpio_fselの処理が2μsで、信号をHIGHにしているbcm2835_gpio_set_pudが274μsも…
p3 : 70585
p4 : 70586
p5 : 70746
もう一回実行してみると今度は160μsとかなり処理時間にばらつきがあるようです。実際にどのぐらいのタイミングで切り替わっているのか不明ですが、結構こわい感じです。内部で後処理ではなく、前処理に時間がかかっていることになっていることを祈りましょう…

さて、この状態で受信データはどんな感じでしょうかねぇ…

sampling_start_lev : 1
sampling_end_lev   : 1
length : 82
21 54 26 54 26 54 26 54 26 54 26 54 26 54 74 53 26 67 74 54 26 54 73 54 74 54 74 53 74 54 26 54 73 67 26 54 26 54 26 54 26 54 26 54 26 54 26 54 25 68 73 54 74 54 74 53 74 54 26 54 74 54 26 54 72 65 73 54 26 54 74 54 74 53 27 53 74 54 26 54 25 47

開始がHIGHから拾えているのと、データの個数が82個になっていていい感じになってそうです。HIGH信号の部分を取って8bitで区切ってみると
21
26 26 26 26 26 26 74 26
74 26 73 74 74 74 26 73
26 26 26 26 26 26 26 25
73 74 74 74 26 74 26 72
73 26 74 74 27 74 26 25

結果からするとセンサー側の開始信号のLOWを見事に取りこぼしています。
何度か実行していると取得しているデータも79ことか76個に減っているときがあって、なんか嫌な予感です。
実際にプルアップしている処理時間は190μsと245μsと、データシート上のセンサー側からの信号を標準タイミングで計算してみると…80, 80, 50μsで データ信号のLOW状態までとなっていて、190でギリギリデータの開始ビットが見え、240μsだとデータの信号のHIGH信号からしか見えず、ビットの判定ができなくなります。
と、なると…pythonでいままでデータが上手く拾えていなかったパターンもこれじゃね?とか感じますが、cだとサンプリングが数μs単位で綺麗に取れているのでこのまま続けましょうw

さて、こうなると、pullup処理自体がダメなんじゃないかとなるので、データシートの手順に変更してみます。
sampling_start_lev : 1
sampling_end_lev   : 1
length : 82
20 78 82 54 26 54 26 54 27 53 26 54 26 54 26 54 74 54 25 67 74 54 26 54 74 54 73 54 74 54 26 54 26 54 72 68 26 54 26 54 26 54 26 54 26 54 26 54 26 160 60 54 74 54 73 54 74 54 26 54 74 54 73 54 25 64 74 54 26 54 74 54 73 54 26 54 26 54 26 54 73 47
40 162 170 112 55 112 54 112 55 112 54 112 54 112 54 112 153 112 53 140 153 112 54 112 154 112 150 91 149 113 54 112 54 112 151 140 55 112 54 112 54 113 54 112 54 112 55 111 55 83 119 106 146 107 146 108 147 107 53 107 147 108 146 106 50 127 146 107 52 108 147 107 147 108 48 173 94 197 101 208 275 182
start : 1595044413 146081
p1 : 614
p2 : 50624
p3 : 70625
p4 : 70626
p5 : 70626
p6 : 70628
p7 : 1074862
p8 : 1074862
最悪データが送られてこなくなるとも思われましたが、何の問題もなくデータの受信ができました。
p3,p4の間のbcm2835_gpio_set_pud部分はコメントアウトして、p3の手前で信号をHIGHにしてから受信状態にしています。
こうしてしまうと、信号をプルアップしなくなってしまうのですが、ハード的にセンサーの基盤にデータ信号とVCCの間に抵抗が入っていてプルアップされた状態なのでいいんじゃないのかな…と思います。
データもこちら側のHIGH信号から見えているようで、センサー側からの開始信号であるLOW(Trel 80μs)→HIGH(Treh 80μs)信号も取れているようなので時間的には十分問題なさそうです。
何度か実行してみると、データの個数は84個で開始もHIGHから取れているので問題なさそうです。

時間的な制約は問題なくなったので、あとは実際にデータビットを組み立てて数値を組み立てることになりますが、cなんてほんと何年ぶり?何十年ぶりだろうw

2020年7月15日水曜日

結構な頻度で取りこぼすのですが?

色々と試行している最中ですが、そろそろ万策尽きそうです。

DHT11の古い方のデータシートに注意書きとして
Note: The host reads the temperature and humidity data from DHT11 always the last measured value, such as twice the measured interval of time is very long, continuous read twice to the second value of real-time temperature and humidity values.
とデータタイミングダイアグラムの図の下に書いてありました。しかも赤い色の文字で。
英語力が無いのでよくわかりませんが、グーグル翻訳に通すと
注:ホストは、DHT11から温度と湿度のデータを常に読み取ります。たとえば、測定間隔の2倍は非常に長く、リアルタイムの温度と湿度の値の2番目の値を2回連続して読み取るなどです。
一時期のグーグル翻訳はかなりすごい感じで訳されてた気がするのですが、最近なんかパッとしませんね…
とにかく2連続で値を取得して後から取得した値がその時の気温、湿度だよと言ってるのだと思うのですがどうでしょうw

そのためにどうしても2連続でDHTからデータを読み込みさせようとしています。昔の記憶をたどると、DHT11では連続してデータを読み取ろうとするとエラーが頻発してしまうことがありました。これがDHT22も同様に発生しています。
原因を調べるために結構突っ込んで調べたのが昨日で、今日はそれなりに改善策を講じたりしていますが、結果としてこれといったインパクトはありませんでした。
面白かった?ポイントとしては、python3でarray.array('B', [0 for i in range(100)])とかで一気に領域確保を行うと、予想以上に時間がかかってしまい、センサーに送信要求を出すと、受信準備が整う前にデータが送信され始めてしまい、開始部分を思いっきり取りこぼすという事態に陥りました。
安易な逃げ方としてクラス変数にして、領域確保はインスタンス作成時に逃がして、使いまわすためにバッファの長さも変数として追加しました。
そのおかげで、サンプリング時のループがかなり安定したのですが、問題は結構な頻度で取りこぼしてしまう状態に。
過去の経験から、GPIO.inputを短時間に呼び出している部分を1μsとか10μs以下では呼ばないようにしたり、軽くなりすぎたループにあえてウェイトをかけたりと、やってみましたがこれといったインパクトもなく、悪影響しか出なかったので最終的にバッファの確保以外はそのままとなりました。
別の角度から取りこぼしてしまうのならデータから救えそうな状態なら救ってしまえということで、信号を取りこぼしてバースト状態になっている部分を補正する処理も実装してみたものの、予想以上に取りこぼしが発生していて多少は救えましたが決定打にはなりませんでした。
DHT22はDHT11と比べてデータシート上のタイミングが結構違っていて、推奨値なども結構異なっています。実際はDHT11と同様の手順でデータは送られてくるのですが、推奨値にしたり、記載通りの手順に則ると素早く受信開始できるようになりました。けども…どうしても2連続の呼出しを行うためには間に0.5~2秒程度時間を置かないとデータが送られてこないのであまり違いは無いかもw
データシートにはセンサー自体のレスポンスタイムが、条件付きの数字ですが、湿度は6s未満、温度は10s未満とそれなりにかかるので、下手をすると10s程度待たないとだめかもしれません。2sでスリープするっていうのが個人的には引っかかりますが、きっとデータ送受信部分だけなんだよね?と考えてます。
センサーのハード的な問題もありそうなのですが、一番の問題はやはりデータの取りこぼし問題なのは変わらず、ps -aFでプロセス番号を拾って、taskset -cp 0 14437でプロセッサー固定させて実行しても状況は変わらず仕舞い。
プロファイラなどでどこでウェイトがかかっているのか調べてもよさそうなんですが…ここで他の言語の力を借りることを考え始めました。pythonはその辺がメインの使用用途だと思うんですが、正直面倒くさそうwとはいえ、実際にどのくらいの実行時間がかかるのかちょっと様子を見てみたいということで、時間取得から様子を見てみました。
検索すると超単純な時間取得のソース(https://www.mm2d.net/main/prog/c/time-04.html)があったのでそれをコピペして実行時間を見てみることに。
pi@rasp3bprs:~ $ gcc test.c
pi@rasp3bprs:~ $ ./a.out
1594811448 557473
1594811448 557880

これはgettimeofday()で取得した値を表示させることを2回行っただけの物なのですが、これで結構参考になる数字が。秒数はさすがにカウントアップされないものの、μ秒の単位では
407μ秒「も」かかってしまっていて正直ダメかとも思ったのですが、よくよく考えればこれはprintfの処理も含まれているので、gettimeofday()の応答時間をざっくりと様子を見てみたいのであれば、連続して呼び出した後で表示させるしかないわけで…変えて実行してみました。
pi@rasp3bprs:~ $ gcc test.c
pi@rasp3bprs:~ $ ./a.out
1594811575 025131
1594811575 025132

勘違いでなければ1μ秒で変数に格納されているのでいい感じです。(すべてraspberry pi 3b+で実行)
実際に必要な解像度としては安定していれば20μ秒程度になってしまっても行けるとは思うので、とりあえずcで作って、pythonへの組み込みはそのあと考えようかなとか。

2020年7月14日火曜日

DHT22のCRCエラーが発生した様子

いろいろとグダりながらもざっくりと変更していて少しだけ見えてきた部分があります。
現時点での結論を言ってしまえば、原因は実行時の何らかのウェイトによってうまく信号を拾えていない感じ。

そもそもpythonでリアルタイムっぽい処理が書けててすごいなぁと感心してただけなんですが、DHT11で使用していたライブラリっぽい物も大雑把にしか見ていなく細かく追って行ってようやくつかめた感じです。
肝心のデータ信号の受信部分がループを使ったソフト的なカウントのサンプリングを行ってそこからビットを起こすということをやっているのですが、そのサンプリング処理はループに依存してました。時間軸とは異なっているために、ループ自体のサイクルが一定ではない場合データ受信で失敗するということです。
しかも、時間を無視しているために、エラー原因もいくらバッファを見ても原因の究明ができません。
良くも悪くも現状1ループ10μs以下では動いているので、サンプリングレートは10μs程度はあるようです。(Raspberry pi 3b+)処理時間がどの程度変わってしまうか正直わからないままごりっと書き換えてみました。
まずはデータフォーマットも単なるサンプリングから信号が切り替わるまでのループ回数を記録するように変更。これだけで配列への格納タイミングがざっと10分の1程度にはなるはずです。
実測値は 1508個から82個へ処理速度が上がれば上がるほど元々の方はデータが増えますが、変更後はバーストや取りこぼしなどで変動することはあっても極端に巨大化することは無いはずです。(変更後のバージョンは初期の信号状態を保持する必要があると思ったので、本来は81個のはず)

続いてループカウントになっている部分を時間へ変更します。
μ秒単位の時間操作がまともにできるか不安を抱えつつ、time.time()でμ秒を扱うことに。さらに、配列をarray.array('B')で1byteのデータとしてみました。(python3ではint扱いになっているので、1データあたりの消費量は4バイトだとは思います。('B')を指定したため、オーバーフローや範囲エラーが出るので想定外の事態になるとエラーで落ちるというおまけつきです(笑)
データーフローを見ると時間は最大でも80μ秒程度なので255μ秒以上は格納することが無いという前提です。
その結果がこちら
array('B', [1, 29, 81, 54, 52, 26, 52, 26, 54, 24, 53, 26, 54, 26, 51, 26, 54, 73, 53, 26, 66, 74, 52, 26, 54, 73, 52, 74, 52, 75, 52, 73, 54, 73, 54, 71, 68, 26, 54, 24, 54, 26, 56, 23, 53, 26, 51, 26, 54, 26, 52, 73, 66, 26, 54, 24, 55, 24, 55, 73, 54, 72, 53, 73, 55, 73, 52, 25, 64, 73, 54, 73, 54, 74, 52, 26, 54, 24, 54, 25, 54, 26, 52, 26, 45])
最初の1個目の1は信号線が初期状態でHIGH状態だったことを示し、その後からは切り替わるまでのμ秒時間となっています。数字を見る限りそんなに悪くない感じで入っていて、3B+のpython3でもそれなりに処理が行える感じがしました。
このサンプリング結果からビットパターンの信号のみを抜き出している部分があるのですが、もともとトリッキーな部分があったのですが、格納データを変えたのですこしすっきりしました。
データ開始の信号を除去してHIGH状態のビット情報だけのサンプリングデータは
[26, 26, 24, 26, 26, 26, 73, 26, 74, 26, 73, 74, 75, 73, 73, 71, 26, 24, 26, 23, 26, 26, 26, 73, 26, 24, 24, 73, 72, 73, 73, 25, 73, 73, 74, 26, 24, 25, 26, 26]
となります。基本的にはLOWデータは50μs前後の数値を取り除いた部分となります。
逆に取り除いた数字を並べてみましょう…手作業ですがw
52, 52, 54, 53, 54, 51, 54, 53, 66, 52, 54, 52, 52, 52, 54, 54, 68, 54, 54, 56, 53, 51, 54, 52, 66, 54, 55, 55, 54, 53, 55, 52, 64, 54, 54, 52, 54, 54, 54, 52, 45
結構疲れましたが、こんな感じ
最低は最後の45ですが、これはデータが終了した後のLOW信号なので正直関係ありません。
そうすると、範囲は51~66μsで、サンプリングサイクルが数μsということを考えれば悪くない範囲だと思います。
ここの処理以降はまた手を入れていませんが、データビットの0か1かを判断するためにサンプリングデータの最小値と最大値から閾値を決めてビット列を作成し、5byteのデータを組み立てていました。もともとはループカウントなのでこのようなことをやっていますが、サンプリング単位がμsになっているので、もうすこし決め打ちしても大丈夫なような気はします。ただスループットが低いRaspberry pi zeroとか2bとかを考えるともう少し様子を見ないとダメですね。zeroは欲しいと思いつつ、結局まだ買っていない…。

ここまできてようやくCRCエラーやビット落ちの様子が判断できるようになります。

何度かコンソールから連続してセンサー値を拾っていると、結構な確率でエラーが発生するようになります。
その時に発生したCRCエラーの様子。
pi@rasp3bprs:~ $ python3 ./setup/sbin/dht22.py --pin 6 --debug
pin : 6
Output for debugging.
array('B', [0, 74, 79, 55, 24, 55, 23, 54, 28, 52, 24, 54, 27, 54, 23, 53, 76, 51, 28, 67, 71, 54, 71, 54, 28, 54, 23, 54, 76, 50, 28, 54, 72, 54, 72, 67, 28, 54, 23, 54, 28, 54, 23, 54, 24, 56, 24, 54, 28, 54, 71, 67, 28, 50, 28, 51, 28, 51, 77, 50, 28, 54, 72, 54, 23, 54, 25, 63, 76, 54, 71, 54, 71, 54, 27, 54, 23, 54, 28, 54, 71, 54, 23, 49])
[24, 23, 28, 24, 27, 23, 76, 28, 71, 71, 28, 23, 76, 28, 72, 72, 28, 23, 28, 23, 24, 24, 28, 71, 28, 28, 28, 77, 28, 72, 23, 25, 76, 71, 71, 27, 23, 28, 71, 23]
the_bytes
02 cb 01 14 e2 ← これは正常なデータですが、初回なので破棄されますw
array('B', [0, 58, 88, 48, 25, 59, 25, 56, 25, 49, 25, 56, 25, 56, 24, 55, 76, 49, 24, 100, 39, 56, 77, 46, 24, 56, 32, 45, 77, 55, 24, 56, 65, 56, 77, 66, 24, 56, 24, 56, 25, 56, 24, 56, 24, 49, 25, 56, 24, 56, 66, 76, 24, 56, 24, 48, 24, 56, 77, 55, 24, 56, 66, 56, 24, 56, 28, 56, 76, 55, 76, 45, 75, 56, 24, 56, 24, 55, 25, 56, 66, 56, 24, 46])
[25, 25, 25, 25, 25, 24, 76, 24, 39, 77, 24, 32, 77, 24, 65, 77, 24, 24, 25, 24, 24, 25, 24, 66, 24, 24, 24, 77, 24, 66, 24, 28, 76, 76, 75, 24, 24, 25, 66, 24]
the_bytes
02 4b 01 14 e2 ← CRCエラーが発生しているデータ
CRC Error.
2nd. retry. 2
array('B', [0, 50, 76, 48, 36, 49, 25, 56, 25, 49, 25, 56, 24, 56, 24, 56, 76, 48, 25, 67, 77, 56, 66, 56, 24, 57, 32, 46, 77, 45, 35, 45, 76, 56, 66, 66, 35, 45, 35, 46, 24, 55, 24, 55, 24, 58, 24, 55, 24, 55, 76, 65, 24, 55, 24, 48, 35, 45, 76, 55, 24, 56, 66, 55, 24, 55, 28, 115, 31, 46, 66, 55, 76, 56, 24, 55, 24, 55, 26, 56, 65, 56, 24, 45])
[36, 25, 25, 25, 24, 24, 76, 25, 77, 66, 24, 32, 77, 35, 76, 66, 35, 35, 24, 24, 24, 24, 24, 76, 24, 24, 35, 76, 24, 66, 24, 28, 31, 66, 76, 24, 24, 26, 65, 24]
the_bytes
02 cb 01 14 62
CRC Error.
2nd. retry. 2
array('B', [0, 62, 85, 57, 24, 57, 24, 45, 35, 48, 25, 55, 25, 55, 24, 56, 76, 47, 24, 65, 75, 55, 76, 55, 24, 55, 30, 46, 76, 55, 65, 54, 24, 55, 24, 66, 35, 44, 34, 45, 34, 45, 35, 45, 34, 48, 24, 56, 24, 55, 76, 65, 24, 55, 24, 58, 24, 55, 66, 56, 24, 56, 75, 55, 24, 55, 27, 56, 76, 55, 75, 45, 76, 55, 24, 55, 24, 55, 25, 55, 76, 45, 76, 46])
[24, 24, 35, 25, 25, 24, 76, 24, 75, 76, 24, 30, 76, 65, 24, 24, 35, 34, 34, 35, 34, 24, 24, 76, 24, 24, 24, 66, 24, 75, 24, 27, 76, 75, 76, 24, 24, 25, 76, 76]
the_bytes
02 cc 01 14 e3
DHT22 results.
Retry count : 2 time(s)
Error code  : 0
Temperature : 276 C
Humidity    : 716 %
なんのこっちゃというような結果ですが、気温と湿度が10倍されたままというのは置いておいて、最初に正常にデータを得られているのですが、どこかに「センサー値の現時点での値を取得するためには複数回データを取得する必要がある」と書いてあった記憶があり、破棄しています。記述された資料が見当たらないので昨日この部分を外して様子を見ていたら、しばらく放置して2回センサー値を表示させたら1回目と2回目で気温が1℃以上変わったので、スリープ直後はスリープ前のセンサー値を返す感じなのだと思います。
で、問題なのが、DHTが悪いのか、Raspberry piが悪いのかわからない部分で、連続でデータを取得するとエラーが発生しやすい。でも連続で値を取得しないと現時点でのセンサー値が分からないというジレンマに陥ります。
ま、どうでもいいんですがw

で、本題の異常値を探ってみると、2つ目のサンプリングデータで100μsとかある部分があります。3つ目では115μsとなっている部分があり、おそらくこの時に何らかの原因で処理が止まってしまったのだと思われます。
今回は運良く?LOW信号がバーストしたような感じになっていてHIGH信号のビットが1になるべきものが0になっただけと考えられます。(気色塗り部分)

もう一つのデータ落ちに見えてしまったパターンはおそらくHIGH信号がバーストしてしまったようになってしまい、結果としてLOW信号への切り替わりのタイミングを取りこぼした結果だと推測しています。
さてどうでしょうか…

array('B', [0, 70, 76, 56, 27, 54, 21, 54, 26, 54, 29, 49, 26, 54, 26, 54, 73, 54, 22, 71, 70, 54, 75, 54, 25, 49, 25, 57, 27, 54, 26, 49, 77, 54, 26, 65, 24, 55, 26, 54, 26, 53, 26, 49, 26, 54, 29, 48, 26, 53, 76, 65, 26, 54, 25, 55, 24, 54, 72, 54, 26, 49, 76, 54, 26, 54, 71, 61, 77, 54, 71, 183, 30, 49, 72, 55, 26, 49, 78, 52, 27, 43])
[27, 21, 26, 29, 26, 26, 73, 22, 70, 75, 25, 25, 27, 26, 77, 26, 24, 26, 26, 26, 26, 29, 26, 76, 26, 25, 24, 72, 26, 76, 26, 71, 77, 71, 30, 72, 26, 78, 27]
pull up lengths Error. len : 39
ログから漁ってみましたが、こんなデータです。
パット見あまり変なところはありませんでしたが、赤塗したところが怪しそうな気がします。信号的には60μsを超える波形はデータ開始時のみでデータ中には現れることはありません。なのでここの間にHIGH信号を完全に取りこぼしているのかな?と推測しました。
とおもったらもっと怪しいのが183とかトンでも数字がありましたwよって正解は、HIGH信号のバーストではなく、LOW信号バースト、正確には単なる「HIGH信号の取りこぼし」でした(笑)

といった具合に、悪者がはっきりしました。Raspberry pi で動いている環境でした(´-ω-`)

Raspberry pi 4bでDHT11を動かしたときにエラーが発生しにくい気がするというのは気のせいではなく、処理速度が上がってスクリプトの実行が安定した結果だった様です。

あと気づいたのは、正常時はビット信号が綺麗にサンプリングできている感じなのに対して、エラー時は全体的にサンプリングにばらつきがあるように思えます。70μsを越えているデータが頻発している。



データシートに詳しくはホームページ見てね的なことが書かれていたので見てみると、センサーの一押しが、DHT10とか外見はあまり変わらずI2C仕様のDHTが…マジかw早速アマゾンで見てみると、3個セットで2400円ぐらいだったかな…微妙な値段だけど、悪くなさそう?

配列への追加についてグダる

時事ネタは突っ込み所が多すぎて全然関係のない話題が続いていますが、今回もそんなネタ。

最近のスクリプトや言語は型や配列に関してものすごい自由度が高いのですが、その代償として何かしらの犠牲を伴っています。

私が言語に最初にどっぷりと漬かった言語はturbo-pascalなのですが、その原因はどうしても細かい所まで見て実装を確認しないと処理が上手く回らなかったり、処理時間を短くするために内部でどのように動いているのかまで見ないといけなかったからだと思います。
あと付属するマニュアルが結構読み応え満点で実際にそうなっているかどうかは別にして、結構突っ込んだ事まで解説されてたりしました。日本語版なので訳者の思い入れが加味されていたのかもしれませんが。

基本的な考え方として、配列は単なるメモリ空間なので、最初に領域を決めたら拡張することができません。動的に変動させるためにはどうするか?というところで実装の仕方は色々な考え方でうまく乗り越えているだけのこと。
追加に対して代償を減らすには領域確保で指定された領域以上に予め確保することで時間的リソースの節約を行います。これはどんな形の配列でも変わりません。繰り返すことでメモリー空間に分断された状態になると、どうしてもアクセス効率が落ちるので、最終的にはガーベージコレクトや再生成するなどして綺麗な状態に保つ必要があるかもしれません。とはいっても、すでにCPUキャッシュやらなんちゃらキャッシュやら、広大なメモリー空間のおかげで実害は出てこないのも事実。ただおまかせ状態だとそれなりに何らかのリソースの浪費はしていると思います。

一番非効率なやり方は、新たに配列全体の領域+追加分の領域を確保して、配列の内容のコピーを行って不要になった領域を解放するという方法ではないでしょうか?これの代償としては配列に対してメモリアドレスなどで直接参照しているものがある場合、参照している部分も変更する必要があるので、結構な処理負荷が出てきたり、放置すると簡単に処理が落ちることになります。
これを結構積極的に行っている言語というかシェルというか物が、おそらくAndroidだと思います。基本的な考え方として、すべてのオブジェクトインスタンスは最悪破棄して再生成すれば元通りという発想のもと、リソース不足になると積極的に破棄したり、どこかに追いやられてしまいます。最近のバージョンではかなりうまい仕組みが導入されて改善されていますが、その辺がどうしても好きになれない場合は苦痛しかないかも。
とはいえ、非効率なやり方の利点として、追加しても常に新規に領域確保された状態になるので配列へのアクセスでまずおかしなことは発生しません。配列の要素へのアクセス速度も常に変わらない状態でアクセスできるため、タイミングの影響を受けるようなこともまず発生しません。

で、なんでこんなたかが配列への要素の追加というくだらない話をだらだら書いているのかといえば、pythonスクリプトで結構安易に .append()で要素の追加を行っている部分を見て、最近気にしたことはなかったけどこの辺どうなのかな?とちょっと突っ込んでみたところ、やはり結構処理的に割高な処理なんだと再認識したのでグダりましたw
たしかに便利なんですけどねw処理時間がμ秒単位の場合はやめた方が良いかも。どうしてもという場合はpythonの場合はarray.array('b')とか、要素の追加を減らす処理に変更するとか、そもそも要素の追加をさせない形にするとか、仕様を見直した方がいいんじゃないかな?

実際にどんな処理でこの辺の処理時間が気になっかと言えば、DHTxxのライブラリっぽいやつで、エラーが発生したときにどんな状態で発生しているのか気になったので色々と書き換えて気になりました。
どのくらいのインパクトがあるかといえば…raspberry pi 3b+でループでGPIOピンの状態をサンプリングしている処理があるのですが、そこでループのタイミングで配列に要素を追加してサンプリングしていたときは、最大25回ぐらいだったのですが、これを信号が変動した時だけにした場合、最大30回ぐらいになりました。「ただし」が付くのですが、raspberry piで使用しているCPUはマルチコアとなっていてメインとなるプロセッサー0とその他とで処理能力の差があるようで、25回→10回、30回→10回ぐらいに簡単に落ち込みました。処理が落ちてる状態なら変わりないということではなく、おそらく不利になるのがGPIOなどのIO周りのウェイトがプロセッサーによって異なっているためだと思います。逆に言えば、現状ではメモリアクセスの時間リソースへの影響が小さくなったという結果なのかもしれませんw(結局何が言いたいんだ(;´д`)

2020年7月13日月曜日

DHT11とDHT22

色々と思うところがあってセンサーの選定をしていましたが、安価で簡単に手に入りそうなDHT22をポチって見ました。2個セットで1400円。一個700円とか3個セットのBME280より高価ですね…。

で早速手持ちのソースをデータシートをみつつ変更したところ、いきなりうまく行かず…すこし試行錯誤した結果、開始時の手順はDHT11の時と同じにするのが安定しました。データシート上だと細かく記載されていて手順が増えているようにも思えたのですが、結果としてpull upされた状態からダウン状態にした後、アップして待機するだけでデータが送られてきました。

それなりにDHTの共通ライブラリっぽいソースも見てみましたが、DHT11とDHT22とではデータの加工方法が違うだけのようでした。

今回DHT22を選んだ理由として、小数点以下の数字が取得できるっていうのがポイントだったのですが、これは今日発覚したDHT11でも温度の小数点が取得できたということで半減してしまいました…。(解像度が16bitで温度が整数のみってどう考えてもおかしいだろという突っ込みはさておきw)

気を取り直してスペックを見てみましょう。

DHT11DHT22
温度範囲0~50℃
-20~60℃
-40~80℃
温度解像度16bit16bit
温度レスポンス10s10s未満
湿度範囲20~90%RH
5~95%RH
0~99.9%RH
湿度解像度16bit0.1
湿度レスポンス6s5s未満
電源電圧3.5~5.5V3.5~5.5V
消費電力0.3mA8mA
サスペンド時60μA10~20μA
スリープまでの時間2s2s
上記は各データシートからの抜粋値で、レスポンスに関してはデータシート上に前提条件として1/e(63%)とか25℃でとか書いてあるので、センサー素子から値を得るのに何度も試行する必要があるもののようです。範囲が広がっているDHT22の方が消費電力が上がっているのもこの辺が影響してそうです。

正直、アップデート後のDHT11なら一般使用は問題ないんじゃというのはさておき、気になる違いはとしてDHT22の優れている点は温度、湿度の範囲が少し広いところでしょうか。DHTの仕様特性として、ほとんどの時間をサスペンド状態で放置されるはずなので、サスペンド時の消費電力が低くなっているのもいい感じです。
デメリットとして消費電力が数字上結構上がっているところ。データシート上はturn onと書いてありましたが、絶えず値をとり続けるのであれば、DHT11は結構優位ですね。

見直せば見直すほど、DHT22を買った利点がないわけですがw



関係ないところで、Raspberry piの放熱やセンサー自体の放熱もあるようで、DHTシリーズはエラー時のリトライで取得できる温度が少し上ってしまう感じがします。手で連続で値を取得すると温度がすこし上がることが多いのもおそらくセンサー自体の発熱があるためのような。

DHT11の温度は小数点まで持っていたw

錯乱状態が少し解消され様子を見たところ、
16時過ぎぐらいからグラフの形が矩形からいい感じになりました。
今までは小数点以下は無いと思っていたので、ここで100均の基準温度計に表示を合わせてみます。
小数以下がカットされていたという感じの重なり具合に。

すでにDHT22を買ってしまったんですが、温度の小数部があるなら、基準センサーはDHT11でもよかったかも…(==;

仕様を呑み込めなく錯乱へ…

昨日電車の中で、スマホでデータシートやソースを見ながら頭の中を整理してかなりの部分がすっきりしたのですが、困ったことにDHT11の仕様で勘違いしていた部分があったようで…

そもそもの起点に戻って整理してみようかと。

まず元となったpythonのソースがどこだったのか謎だったのですが、おそらく
ここだったと思われ。再度アクセスしたらgitサーバーが落ちたのかアクセスがエラーに。
で、経緯としてはその後、修正が加わって大きな違いは
「温度と湿度ともに小数部を加味するようになった。」
という点。
で、DHT11自体は仕様がアップグレードされセンサーの感度範囲が広がったこと。
湿度は 20-90%RHから5-95%RH
温度は 0 to 50 ℃ to - 20 to 60 ℃

大きな違いは温度がマイナス温度から検知できるということ。

で、アップデート後のドキュメントで温度に関しての説明で
The temperature is high as part of the data of the temperature.
The temperature is low as part of the data of the temperature, and the temperature low bit 8 is the negative temperature, otherwise the temperature is positive
と書かれていて、あんまり意識していなかったのですが、これをグーグル翻訳にかけてみると…
気温のデータとして気温が高い。
温度データの一部として温度が低く、温度の低いビット8が負の温度で、それ以外の場合は温度が正
意味不明すぎなのですが、原文を見直せば見直すほど意味が理解できなくなりました(*´Д`)
もともと英語力なんて無いのであれなんですけどw
英語圏の人はこれで理解できるのかな?

で、色々と考えた結果、アップデート後のv1.3では「温度がマイナスの場合は、温度の下位バイトの8ビット目が1になる」というとらえ方でいいのかな?どのタイプのDHT11を手にしているのかもわからないのであれなんですが、、、現状の上記のgitのソースを見ると、
humidity = the_bytes[0] + float(the_bytes[1]) / 10
となっていて、pythonで 0b10000000ってなっててもマイナスの扱いなんてしないし、そもそも足しこんでいるのですっげーやばいと思うんですよね。
そもそも「/10」っていう部分が気になる人には気になるかもw
pi@rasp4b4g:~ $ python3
Python 3.7.3 (default, Dec 20 2019, 18:57:59)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 0b10000000
128
>>> float(0b10000000)
128.0

こんな感じでfloatしても、こんなことに。 仕様上は下位バイトは0~9までしか格納されないのですが、マイナスの場合は符号ビットを取り外さないとイケないわけで。
humidity = (the_bytes[0] + (the_bytes[1] & 0x7F)*0.1)*(-1if(the_bytes[1] & 0x80)else(1))
とか、そんな感じにする必要があるような?

v1.3のセンサーも無いし、データシートのデータサンプルに気温4024℃とパリティーエラーしか載ってないので正確なことは言えませんが。

他にもなんか色々といままで見かけた仕様も矛盾してしまってたりしてほんとに錯乱状態だったので綺麗さっぱりと忘れることにしよう。

この辺が気になりだした原因は、そもそもDHT11の仕様で湿度、温度ともに整数値しかないと思っていたところ、受け取った4バイトのデータを実際に表示して気づいたという。
しかも、decimalを10進と翻訳されて、データフォーマットが回路用に設計されてるのかな?とか勘違いしてたのが原因でした。実際のデータを表示させてその勘違いに気付いた次第です。




そもそもなところで、センサー誤差を拾うために結局DHT22も入手して只今思案中w

2020年7月11日土曜日

再起動後、録画直後にmotionが落ちる

再起動した後、気づいたらカメラの動作ランプが消えていて、サービス無効化したっけか?とsudo service motion statusで確認すると、Activeの表示。(topとかでプロセスの状態を確認すればよかったかも…)問題がなさそうなので、ログを見てみることに。
/var/log/motion/motion.log
が存在していたので、起動したのは確実。理由はこのraspberry piはほとんどのlogはtmpなので再起動で消えてしまいます。
中身を見ると、確かに[ERR]がいくつかでててそこで終わっています。

特に考えもせずにsudo service motion restartで、motionを再起動。
そしてカメラを動作させて様子を見ると…普通に動いてます。ですよねぇ…今まで動いていたし。
思い起こせば、マスクをかけていたのを外したからムービーファイルが巨大になって落ちたのかな?とか。でもそんなことはないと思うのでちょっと納得いかない。

しばらく放置しても落ちそうになかったので、再度再起動してみる。
カメラの動作ランプが点灯して、motionを反応させて録画させてみると、保存のタイミングでカメラのランプが消えてしまいました。落ちたか…。
sudo service motion restartで再起動させて、しばらく様子を見ると普通に動作している感じです。
原因がさっぱりわかりません。

再度ログをみてみると、
[1:ml1:F] [NTC] [EVT] [Jul 11 01:38:03] event_newfile: File of type 8 saved to: /tmp/20200711013802F-01.avi
[1:ml1:F] [NTC] [ALL] [Jul 11 01:38:03] motion_detected: Motion detected - starting event 1
[1:ml1:F] [ERR] [ENC] [Jul 11 01:42:20] ffmpeg_avcodec_log: Too large number of skipped frames 235812 > 60000
[1:ml1:F] [ERR] [ENC] [Jul 11 01:42:20] ffmpeg_put_frame: Error while writing video frame: No such file or directory
[1:ml1:F] [NTC] [ALL] [Jul 11 01:42:20] preview_save: different filename or picture only!
[1:ml1:F] [NTC] [EVT] [Jul 11 01:42:20] event_newfile: File of type 1 saved to: /tmp/20200711013809F-01-01.jpg
[0:motion] [NTC] [ALL] [Jul 11 01:56:05] motion_startup: Using log type (ALL) log level (NTC)
[0:motion] [NTC] [ALL] [Jul 11 01:56:05] become_daemon: Motion going to daemon mode
設定は結構変なことをしていて、一旦tmpに動画を作らせてからそのあと保存用のディレクトリに移動させてたりするので、出力が/tmpになってたりします。

原因の一端にその辺もありそうですが、エラーメッセージで検索をかけたところ、
を見てみると、timelapse設定をオフにしてみると対処できるらしい。が、そんな機能使ってないんですが。
まぁそれはそれとしてmotion.confを見てみると、timelapse関連の設定は、

ffmpeg_timelapse 0
ffmpeg_timelapse_mode daily

の2つありました。ffmpeg_timelapseが0なのでオフのはずなのですが、エラーメッセージから推測すると、ファイル名を変更しようとしているのでffmpeg_timelapse_modeも影響がありそうなので、
ffmpeg_timelapse_mode manual
と設定変更してみました。

変更後、とりあえず落ちることは無くなりました。





motion -hで表示されたバージョン情報
motion Version 4.0, Copyright 2000-2016 Jeroen Vreeken/Folkert van Heusden/Kenneth Lavrsen/Motion-Project maintainers

パッケージバージョン
4.0-1

2020年7月10日金曜日

サンワサプライのマウス

サンワサプライから発売された無線2.4GHz/bluetoothのマウスがちょっと気になりました。
カッコいいかと言われれば微妙ですが、使い心地が気になります。

結局今使ってるマウスは軽くて、電池で使用できるただのホイール付きのマウスで、利点としては内蔵バッテリーではないので電池切れを起こしたときに即座に入れ替えて使い続けられること。
bluetoothヘッドフォンで結構痛いのが、内蔵バッテリーの欠点はバッテリー切れの時の復帰時間が必要になってしまうこと。これを補うために、ヘッドフォンは最低でも2つ無いとかなり不便です。
ヘッドフォンは軽くするためにバッテリー内蔵させた方が軽くなるので選択肢が無かったりしますので諦めざるおえない部分です。

細かい記載が無かったのでサンワダイレクトのページにあった取扱い説明書によると、USBケーブルで接続しても直接マウスデバイスとはならないものの、充電中もマウスの操作は可能と書いてありました。
結構欲しいかもw

2020年7月6日月曜日

グラフのセンスが無さすぎる

センサーごとのアジャストを行ったり、色の調整を少ししたら、

そういえば温度のメモリも1℃刻みでほしいよなとか、
温度、湿度、気圧と表示は気温しか出していなかったので、温度と湿度の軸を揃えてみようかなとか、

まずは温度の刻みを直してみると、グレーの濃さが微妙だなとか、、、きりがないw

私以外見ることが無いマイグラフなのでとにかく把握しやすいものということであえてy軸は温度、湿度、気圧と分けていたわけですが、phpのスクリプトは単純にそれぞれ独立して上限下限を決めてプロットしているだけなので、軸を揃えたければ単純に一致させてあげるだけでグラフも簡単にそろう作りになっていたので試しにやってみたところ
高湿度のこの時期はこんな感じに。温度の波が今までの半分程度になってしまうので結構寂しい感じに。
元々、温度を中心に考えて、湿度と気圧はおまけ的に表示させていたのですが、改めて見てみると、やっぱり軸を揃える意味は少ないようです。
温度に関しては、気温は0℃~40℃、Raspberry pi の温度が~60℃として考えても、20目盛ぐらい助長になっています。
軸の状態を元に戻してみると、、
高湿度なのでRaspberry piの温度と重なってしまう感じになっていますが、数字の重なりさえなければ実用的に問題ないかなぁ…グラフとしては上下に踊ってくれた方が楽しいし。
やはりほとんど波が無いグラフは面白くない。

正直、グラフなんてこだわったことがことがほとんどないのでセンスも何もないのが一番悲しいw





DHT11とBME280の差異は上下に数値を補正しただけで波形はほぼ一致しました。試しに湿度や温度をエアコンで変えてみましたが振れ幅も一緒なのでこの温度、湿度下ではいい感じです。冬場までこのままセンサーをつなげたままの状態を維持すれば少し違った結果が得られそうな感じはします。
ただ、驚くべきことに、安価なDHT11の湿度の方が反応が良いようです。温度の反応速度はどちらも一緒のような雰囲気です。

意外と変なところに躓く…

グラフの表示をかなーり低レベルで自前で折れ線グラフを書いているわけですが、いろいろと引っかかってきました。
設定ファイルとしてiniファイルを使ってみたところ、phpではコメントに2byteコードを書いても無視してくれるのですが、python3だとコードページが違うだとか結構面倒な感じに。
Windows10のメモ帳でもUTF-8が扱えることを考慮すると、すべてUTF-8で揃えてしまうのが幸せになれそうなのですが、iniファイルといえばシフトJISとか変なプライドが邪魔してしまい、shft-jisファイル形式のままアップロードしています。

昔はクライアント内ではクライアント側のファイル形式や文字コードで管理してftpで変換し、サーバー側ではサーバーのファイル形式、文字コードという考え方でよかったのですが、最近はやってもファイル形式(とはいっても改行コード変換程度)で文字コードはそのままというかなりアバウトな感じで管理していました。
その一つにphpが結構いい感じに文字コードや改行コードを無視してくれるというのがあったのですが、これがpython3になると、スクリプト内の文字コードも結構厳しかったり、パーサーなどもしっかりとコードページを意識しているので簡単に処理が通らなくなってきます。

一番最悪だったのがiniファイルをsift-jisのままアップロードして、サーバー側のテキストエディタでコメントまでコピペして保存するとそのファイルはsift-jisとUTF-8が混在した不思議なファイルが出来上がってしまうと、python3のiniパーサーで直接扱うことができなくなってしまいます。
サーバー側で直接触らなければいいのでしょうけど、設定ファイルだし直接触りたい欲求はあるわけです。
で、python3でiniファイルを扱うときは予めコメントをカットしてパーサーに渡してあげれば…とか考えたんですけど、そこまでしてオーバーヘッド増やすなら、いっそのこと全部UTF-8でいいんじゃ?的なw

phpのiniファイル絡みでもう一つ。
iniファイル上のセクション名などに関して数字で始まる文字は数値になるとかいう仕様があってこれが値に対しても行われるのかな?と思ったら行われていなかったという。
色の設定を行いたくて、
name=0xF0F000
みたいな設定を行ったら、結果としてiniパーサで、文字列として取り込まれていたのですが、これが分かるまでに結構四苦八苦しました。
結果としてデバッグ用に if (php_sapi_name() == 'cli') とか判断して色々出力するようにしておきました。これで今後はかなり複雑怪奇な形になっても内部が目で見えるようになるので便利かな?

2020年7月5日日曜日

センサー類の情報、そして個人的なセンサーに対する結論

センサーについて何かないかと検索してみると、見知らぬ型番が出てきて少し気になっていました。そもそも出発点は電子部品セットの中にあったDHT11とBMP180の2つの温度センサーからなので、それ以外の系統の部品やメーカーは知りもしませんでした。

その一つとしてSHT11という型番。
メーカー特性としては精度は高いが、部品も高いという感じらしい。

視野が狭すぎると感じたので他にも温度系のセンサーはない物か?と検索し続けてみましたが、デジタル部品としては主にこれらの3社系統がメジャーな雰囲気です。

でそんな中、似たような趣旨の記事を発見!


ようやく複数のセンサーを比較している内容を見つけた感じです。言語を広げればもっと良かったのかな?
同じ型の部品も複数比較していたり、かなり突っ込んでいると思います。

上のブログ記事にも書かれていますが他のブログ記事にもDHTシリーズの湿度は実際の値より少し高めになってしまうようです。

デジタル部品を見回すと、メーカーや型番によりかなり差があることは当たり前のようで、絶対的な温度、湿度の精度を求めるのならアナログ部品を使って直接値を加工した方がよさそうな気がしてきました。

寝る前にはその気になるセンサーを入手して使ってみようかとも考えていたのですが、どうせ個体差があるならこれ以上細かいことを気にしても用途(ただ室内の温度を知りたい)的に意味がなさそうです。
デジタル部品であっても基準を決めて補正するとか、複数の種類のセンサーを組み合わせて補正するしかなさそうですね。



最後に昨日の夜からDHT11とBME280を1分間隔でロギングしたグラフを残しておこうかな。
温度に関してはDHT11は少数なしの整数値なので矩形波っぽくなっていますが、温度に関してはDHT11が30℃、このBME280とはほぼ一致している感じです。目視の温度計は29.0℃ぐらいなので、まぁ誤差範囲でもいいとおもいます。
湿度は、DHT11では70%、BME280では58%と、数値として12程度ずれています。このBME280は湿度が異様に低くなっていますねぇ…

(2020/08/03追記) 大きな訂正となりますが、DHT11の気温は小数点第一位まで出力しますが、この時点では整数しかもっていないものと勘違いしていました。

2020年7月4日土曜日

気になりだすと止まらないセンサーの精度

使っているスクリプトを色々な角度から確認してみたところこれ以上おかしな点はなさそうなので、さらに別の角度から考えてみようかと。
極論は温度、湿度、気圧計を横に並べて比べてみるしかないとおもいます。
ですが、手持ちに無いので、既に使わなくなってしまったDHT11を発掘してつなげてみました。
個人的には、DHT11は温度、湿度センサーで、精度も整数値しか取得できない上、センサー値を取得するときにどうしてもエラーが発生してしまうことからあまり信用していませんでした。
エラーに関しては仕様上の問題もありますが、レスポンスが確実に悪くなるのと、リトライが発生するので時間上不安定になりがちになります。いままで10分間隔にロギングしていた理由の一つとして当初はDHT11も使用していて分刻みだと1分以内に処理が終わらなくなるかも?と考えていたからです。もうすこしエラー率が低くて、リトライもあまり発生していなければよかったのですが。あとは、分刻みだとログデータの発生量が結構インパクトありそうな気がしていたところです。ざっくりと計算すると、固定長のバイナリファイルに収めると1年間で10Mbyte程度になりました。これが大きいか小さいかというのは考え方次第です(が、他に本体の電源電圧やCPUクロックなどのログも取り入れていけばそれだけ大きくなってしまいます)。現状はいろいろ便利そうという理由だけでSQLite3を使ってデータを記録しているので、だいたい1日80Kbyte程度。これが365日なので約26Mbyte程度となります。(ざっくり昼間計算したら1年間で30Mbyteという数字が出てきたきがしますw)
まぁその他もろもろの事情で10分間隔だったわけでが。

さて、少しロギングできたので様子を見てみると…

DATE TIMEBoardTempHumiPressTemp3Humi3error3Temp1-3Humi1-3B - T
2020-07-04 23:07452772877066309100405429000780000-230-1169116507
2020-07-04 23:06452772882066196100414029000770000-180-1080416457
2020-07-04 23:05447902883066111100419329000770000-170-1088915960
2020-07-04 23:04452772888065887100418130000770000-1120-1111316397
2020-07-04 23:03457642892065794100422330000770000-1080-1120616844
2020-07-04 23:02452772884066079100417430000770000-1160-1092116437

データは1000倍して整数値で格納しているので、温度のBME280とDHT11の差は1℃程度でしたが、気になっている湿度は10%以上の差が発生していました。同じBME280の別の個体との差が7%程度あったので、気になっていましたが、まさかの10%以上の差がでているとは…。

昨日の夜に天気HPの地点情報の湿度を比べてもBME280の湿度の数値はかなり低く、室内とはいえ窓を開けた状態で30%程度低かった記憶があります。
現時点でDHT11と比べると…HPでは89%、78%、BME280の湿度は…66%となってます。同じ部屋にあるもう一つのBME280は、73%と出ています。

結構な期間温度センサーを動かしていましたが、あまり細かいところは気にしていなかったとはいえ、BME280は気圧センサー以外はあまり正確な値ではないようです。ただ、センサー感度は悪くないので、ちょっとした変化はすぐに掴める気はします。

結構気に入ってBME280を買いそろえてしまいましたが、別の気温センサー探そうかな?

2020年7月3日金曜日

BME280のオーバーサンプリングを試してみた

どこかのライブラリを基にして、python3で使えるようにしてクラスっぽい実装にしたものを使っているので、データシートを見ながら1ステップづつ確認しているような状態ですが、モード値以外はほぼ問題なさそうというのが現時点での結論となっています。

そんなこんなで、まずはオーバーサンプリングを試してみましたが、結果から言えばほんとに小数点以下の誤差が若干落ち着くかな?といった感じでした。
フィルタリングに関しては、データシートの説明でノーマルモードで使用することが推奨されていて、よくよく読んでみると、設定のレジスタに書き込むと内部のフィルタメモリがクリアされる仕組みになっているので、現状の使い方(毎回初期設定して温度を読み取っている)ではあまり効果が期待できなさそうです。このへんはもう少し手を加えれば変えられそうですが、そこまでの精度の値が欲しいわけではないので踏ん切りがつきません。

データシートにはフィルタを有効にすると、気圧と温度の解像度(分解性能?)が上がると書かれているので、気になりますが、原文とグーグル翻訳を使って読んでいる限りドアの開閉や扇風機などの気流の乱れの誤差を減らすのが目的なようなので現状関係ないかも(笑)

オーバーサンプリングやフィルタ効果を見るために、同じ場所の2つのセンサーのグラフを実際に重ねて比較してみると、
気温

湿度(上部にCPU温度がかぶってます)

気圧
温度、湿度、気圧とものにほぼ同じ形になっているのでやっぱりオーバーサンプリングやフィルタリングの効果は少ないようです。
気圧に関しては、数値もほぼ同じになっていて気持ちがいい反面、温度は0.5℃、湿度は5%程度の差がありました。
やはりキャリブレーションデータの計算が間違っているのか、個体差か、劣化による誤差なのかは謎のままです…





コピー品が出回ってるかも?と検索したら、日本語版のデータシートが存在してました。
細かいスペックは英語の方がわかりやすかったりしますが、製品そのもののイメージを捉えるためには日本語で読めると全体がつかみやすいです。英語力ほとんどないからなぁw

と、いろいろとはっきりしたポイントとして、英語でも「ゲームモード」と書かれていて何に使うのかな?と引っかかっていましたが、気圧と温度で高度の差異を捉えて高精度の高度センサーとして利用するのが目的のようです。そのためにわざわざノーマルモードなるひたすらセンサー値をレジスタに書き込むモードがあるようです。実際に数Hz程度のサイクルで値が更新され続けるので、動態検知だけでなく、ヘッドマウントディスプレイなどに組み込めば加速度センサーとは違った実際の上下移動距離をリアルタイムで取得できそうです。
なるほどねぇといった感じですが、、、実際に使うのはただの温度、湿度、おまけで気圧の観測記録だけなのですw

ちろっと、サンプルを見かけたと思ったんですが、やはり日本語です。はっきりと認識できました。
気象観測用のおすすめ設定は…
オーバーサンプリングは気圧、気温、湿度すべてx1。フィルターはオフ。強制モードで、サイクルは1分間隔とのこと。
理由はよくわかりませんが、一昨日から昨日までノーマルモード(毎回初期化してるので上記の想定からはやや離れているのですが、)1分単位で取得した温度の値が、百均の温度計との差が少なくなりました。


色々とスクリプトを見直していたら今まで使っていたものはどうもdouble型で簡易的に求めるもののようで、基準となる変数が本来は整数なのに対してdoubleのままになっていました。記憶はあまりないですが、BMP180のソースを基に自分で起こしたような気もしてきました。とはいっても、やはり小数点以下の誤差しか出てこないので、温度と湿度の個体差が予想以上に出ているという残念な結果が残りました。

2020年7月2日木曜日

"Direct firmware load for brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.txt failed with error -2"

起動時に電圧不足となっているRaspberry piを再起動して気になったエラーメッセージがありました。


[    7.411836] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1
[    7.412142] usbcore: registered new interface driver brcmfmac
[    7.436191] brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.txt failed with error -2
[    7.652810] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1
[    7.652954] brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available
[    7.655857] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/1 wl0: Oct 23 2017 03:55:53 version 7.45.98.38 (r674442 CY) FWID 01-e58d219f

検索してみると
https://askubuntu.com/questions/1252760/how-do-i-activate-the-bluetooth-function-on-my-ubuntu-system-if-theres-no-defa
I finally found a solution that works: sudo hciattach /dev/ttyAMA0 bcm43xx 921600 After running this command everything seemed to be fine.
とのこと
詳細を見る前にアップデートするとファーム更新まで走らないかな?試してみよう

BME280センサーの個体差が気になるので

いままで何回かバラバラで購入しているので結構個体差があります。
百均で温度計も購入して比べてみましたが、予想以上にズレがありました。とはいえ、±2℃程度ではあるので実用的には全く問題はありませんがw
センサーチップにキャリブレーションデータがあるので誤差の原因がその補正計算で問題があるのではないかと気になって仕方がなかったので、使っているソースとデータシートを見比べてみました。

結果としては、データシートの参考ソースから補正計算をさせた結果と、今までの結果の差は

今まで使っているライブラリの値
温度 28.008137599710608
気圧 1004.5331902330901
湿度 68.45038478114147

データシートから起こしたスクリプトの値
温度 28.01
気圧 1004.5329296875
湿度 68.4453125

誤差の根源は内部で使いまわしているt_fineという基礎数の計算時の誤差が由来のようです。

143401.6645105183
143401

データシートに記載されているソースは桁あふれが発生させないように整数で扱っているのに対して、今まで扱っているライブラリの方は誤差は演算処理任せにして演算している感じです。

その結果、今回データシートから起こしたスクリプトは気圧と湿度に関しては算出された値からさらに表示用にそれぞれ256と1024で割り算しているのでその誤差が出てきているだけの格好です。

ついでに細かいところでレジスタから取得している部分も見直してみたのですが、結局は問題ありませんでした。ビットで切り離している値などもあるので、怪しいと思ってアドレス計算とかまでして確認したんですけどね無駄でしたw

とはいえ、根本的なところで、
The “config”register sets therate, filter and interface options of the device. Writes to the “config” register in normal mode may be ignored.In sleep mode writes are not ignored.
「config」レジスタは、デバイスのレート、フィルタ、およびインターフェースオプションを設定します。通常モードでの「config」レジスタへの書き込みは無視される場合があります。スリープモードでは書き込みは無視されません。
という記述を発見。
ライブラリではノーマルモードのままとなっているので、若干心配ではあります。

あと、サンプリングの回数を10分間隔から1分間隔に変更して様子を見ているのですが、1分間隔にしたら温度計の温度との差がかなり少なくなった感じがします。
と、すると、オーバーサンプリングうんたらかんたらでセンサーの値を拾ってあげると結果が変わりそうな気配がしますが…そのうち確認してみましょう。

2020年6月28日日曜日

Raspberry pi 3bのthrottled=0x50000

今までまったく気にしていなかったthrottledのフラグですが、設定を確認しているとRaspberry pi 3bで異常値を示していました。

0x50000
なので
0b 0101 0000 0000 0000 0000
    | 1111 1111 11
bit | 9876 5432 1098 7654 3210
----+-------------------------
    | 0101 0000 0000 0000 0000
       | |
       | +--------------------16: under-voltage has occurred
       +----------------------18: throttling has occurred
これを見ると低電圧状態とスロットリングが発生したということです。
今まで気になってる点といえばI2Cで接続しているBME280センサーが突然アクセスできなくなり、うまく行えてるか微妙なところですが、I2Cのリセットをしても復旧せず、Raspberry piをrebootしても元に戻らない状態に陥ってしまうことがまれに発生しています。
最初はセンサー側を疑っていましたが、別のメーカー製のBME280を使用しているRaspberry pi 2bでも発生したので、Raspberry pi側の問題かな?程度に考えていました。
ただアクセス不能に陥っていた時にログなどを確認すればよかったのですが、何も考えずシャットダウンさせて、電源再投入で再起動させてしまっていて原因がさっぱりわからないままです。
throttledの異常状態になっていても、特に問題は起きていない状態なのですが、とりあえず何か調べてみようかなと、最初にdmesgを見てみることに。
pi@rasp3b:~ $ dmesg
  [    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.4.35-v7+ (dom@buildbot) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1314 SMP Fri May 1 17:41:46 BST 2020[    0.000000] CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=10c5383d
[    0.000000] CPU: div instructions available: patching division code
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] OF: fdt: Machine model: Raspberry Pi 3 Model B Rev 1.2
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] Reserved memory: created CMA memory pool at 0x37000000, size 64 MiB
[    0.000000] OF: reserved mem: initialized node linux,cma, compatible id shared-dma-pool
[    0.000000] On node 0 totalpages: 241664
[    0.000000]   Normal zone: 1888 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 241664 pages, LIFO batch:63


[    8.223547] uart-pl011 3f201000.serial: no DMA platform data
[    8.300452] usb 1-1.4: set resolution quirk: cval->res = 384
[    8.302336] usbcore: registered new interface driver snd-usb-audio
[    8.318097] Under-voltage detected! (0x00050005)
[    9.220251] brcmfmac: brcmf_cfg80211_set_power_mgmt: power save enabled
[    9.891057] smsc95xx 1-1.1:1.0 eth0: hardware isn't capable of remote wakeup
[   11.056763] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
[   11.967507] usb 1-1.4: reset high-speed USB device number 4 using dwc_otg
[   12.477611] Voltage normalised (0x00000000)
[   13.378331] Bluetooth: Core ver 2.22
[   13.378515] NET: Registered protocol family 31
起動時にUSB関連の初期化中に低電圧とスロットリングが発生しているようでした。

現時点でほかのRaspberry piでは発生していないので比較はできませんが、今度センサーが止まった時にでも様子を探るようにしてみましょう。

2020年6月27日土曜日

スクリプト作成時に検索していて使い勝手が悪くなってる

私は頭が悪いので、スクリプトなどを書く時に少しでも引っかかったら検索してできる限り予期しないことが起こらないようにしています。
最近は昔と違って結構見やすくて分かりやすいサイトが上位になっていて良かったのですが、広告系と思われるサイトが上位やトップに来てしまい非常に使い勝手が悪くなってきています。
初期のgoogle検索は除外サイトとか検索オプションを保存できたような気がするのですが、現時点では毎回設定する必要があるようで…バカバカ検索をかけるときにわざわざオプション指定をしたりするかといえばしないわけで、この手のアドオンが何かあるかな?と探してみると、Google Chromeなら検索エンジンの編集で細工ができるようです。
FireFoxでもできるんじゃ…と思ったら、検索エンジンがすべてアドオン扱いで微妙な状態に…昔は直接設定できたような気がするんだが…

で、さらにuBlacklistなるものがChromeならアドオンがあるっぽい!
Personal Blocklist の代替になりそうな Chrome 拡張機能を作ってみた
FireFoxのアドオンでもないかな?と検索してみると出てきました。
でも…Google系のサイトの書き換えを許可するとかちょっと怖いのでもう少し辿ってみました。
見る限り作者はChrome版と同じ方のようで、問題なさそう?

機能はgoogle検索特化型のアドオンで、検索結果画面を直接フィルタリングと加工を行っているようです。
実際に使ってみると悪くはないし、ツールボタンで表示中のサイトを直接除外対象に含めることができて使い勝手も悪くはないんです。悪くはない。
でも正直なところ、怖いですねww

仕組みとしてはフィッシングサイトにまっしぐらな感じになっているのを使うべきかどうか…

一つ二つなら-site:オプションで行けるので、検索エンジンでオプション強制形式でいいのないかな?

2020年6月18日木曜日

OpenOffice Writterもやっぱり行間がズレる

最新のLibreOfficeをアンインストールして、Apache OpenOfficeの最新のものをダウンロードしてインストールしてみました。
ウィンドウ周りをみるとWindows10以前の描画方法のままのようで、使用しているノートは文字の大きさを少し大きくしているので全体的にぼやけた感じになっています。
初期設定のフォント設定も古いままでした。
それでも全体的にLibreOfficeよりOpenOfficeの方が動作がしっかりした印象を受けました。
が、、、
結局改行させてかな文字やスペース、アルファベットを入力させると行間がLibreOfficeと同様にずれまし。
LibreOfficeとApache OpenOfficeの違いがあるのはLibreOfficeは継続する改行マークが改行した行の行間が変わったことによってずれるだけではなく、改行マークのフォントが変わってしまったのか改行マークの左側も隙間が開いた感じになったのですがApache OpenOfficeではそれは起こらなさそうでした。初期設定フォント異なるし、要因がはっきりしているわけでも無いので断定できませんが。

結論からいえば、文字入力すると行間が変わるのは仕様ってことなんでしょうね。

2020年6月15日月曜日

LibreOffice Writerを使おうかと思ったら初っ端から躓く

ちょっと整理するために図形を描いて残しておきたいと思い、LibreOfficeのWriterを使ってみようかと。

Calcは結構使っていて、印刷は使っていませんが、表計算として機能的なところはある程度信頼していたりします。マクロも言語はともかく普通に使えそうという感じ。
Writerはドキュメントを起こしてなかったのでまともに使ったことはありませんでした。
で、
新規作成。

矢印を水平に…Ctrl押しながらかな?Shift押しながらみたいだな。と、ここまでは至って普通。
アンカーが打たれて、アンカーの癖はどんな感じかな?昔のWordみたいなアホさがあるのかな?と、改行して入力してみる。表示がされないので、設定を見てもなさそうなので、ウィンドウのメニューの表示から表示された…改行マークがなんだか不揃いなんですが。
ここでものすごく不安を感じる。

まぁWordとかも結構ひどかった記憶があるし…

スタイルの表示があるので色々といじってみる。

書式設定の解除、標準のスタイル、本文…
改行だけのところにスペースを入れると、行の高さが変わって後続の位置が上にずれる。
アルファベットだと、位置はずれない。アルファベットを入力してスペースを入れても大丈夫。全角かなを入力すると、位置がずれる…

ん~なんか思った以上にダメっぽそうw

バージョンアップチェックをすると、6.3があるらしいので、ダウンロードページを開いてみると6.4.4もあるみたいなので、どうせ不安定ならと、パワーユーザー用のそちらをダウンロードしてみることに。

6.4はおそらく安定化バージョンではなさそうなのですが、それでもこの状況は変わらず。
スタイルでフォントを英文字と同じにそろえると、揃ったような雰囲気にはなるものの、スペースを入れると今度は行間が詰まって下の行が上に上がってきます。
しかも、スペースを削除しても、改行マークの大きさが微妙に異なる状態にw

何だかなぁ…ちょっといじっていきなり痒くなってきた。原因は図形矢印のアンカーが触れた行っぽいけど、図形を削除してアンカーが無い状態でもこのまま。
ちなみに、アルファベットを入力すると行間は変化しないものの、スペースを入力すると行間が詰まる。かな文字を入力すると行間が詰まってアルファベットを追加すると、行間が広がる(アルファベットの行と同じ行間に)。

と、最後にスタイルを確認すると、
そもそものサイズが違っているという事実に。
なるほどねぇ…色々と細かいところがぐちゃぐちゃになりそうな仕様になってそう。
それを踏まえて考えると、スペースの扱いはどうも2つ目のフォントを使用するようになっていて、行間がずれる感じみたいですね。良いか悪いかは別ですが。

で、サイズを揃えても、1つ目と2つ目のフォントが違うと、改行マークが混ざる…この辺はもうなんかそんな感じなんですね。

そしてもうちょっと突っ込んでいくと、この状態でアルファベットを入力してスペースを入れる場合と、アルファベットが入力されている前にスペースを挿入した場合でスペースのサイズが変わるとか難儀な仕様に…。
痛すぎるw

もう一つのOpenOfficeはこの辺の仕様は一緒なのかな?



ついで話
スクリーンショットをWindows10の標準の環境でまともに加工してみましたが、フォトでスクリーンショットの一覧が見れるのは便利でそこからPC次第ですがすぐにクリッピングしてコピー保存できるので便利だなとは思ったんですが、最初はここで保存される場所はファイル選択画面が表示されてローカルドライブのフォルダを選択して保存したんですが、次に保存したら無言でOneDriveのフォルダになったり、フォト内の表示がダブったり…溜息しか出ねぇ…

2020年6月10日水曜日

ファイルエクスプローラーで[Ctrl]+[X], [Ctrl]+[V]の動作がおかしい

ファイル整理を行うとき、結構頻繁に切り取り[Ctrl]+[X]と貼り付け[Ctrl]+[V]をキーボードショートカットを使っています。
もちろんドキュメントを書く時や、ソースを書く時には多用しますが、ファイル整理ではタイピング以上に操作ミスを犯さないために、キーボードショートカットで操作を行っています。
マウス操作を全く使わないわけではないですけど。

特にファイル整理の時は、ファイルのコピーが作られてわからなくなったり、コピーだとファイルの作成日時のタイムスタンプがコピー日付になるのを嫌がるために切り取りで移動させることが多いです。(この操作もファイル移動が不安定な状態のWindowsでは痛い目を見ることになりますがw)

で、フォルダの中に新しいフォルダを作成してから、ファイルの切り取りと貼り付けを行ったところ見慣れないエラーが表示されました。
いやいやwありえないっしょw

キーボードショートカットが選択状態になってるフォルダを無視してカレントフォルダに貼り付けようとしてるんですがw

それだけではなく、複数のファイルエクスプローラを開いた状態で、片方で切り取ったはずのファイルを切り取り貼り付けして移動したつもりが、コピーされたりと、動作おかしくね?

どちらもマウス操作はかろうじてちゃんと動作するようなので、マウス操作してしのぎましたが、なんでしょねこのバグ?仕様変更?




ちょっとだけ掘り下げて動作をよくよく見てみるとマウス操作の切り取り、貼り付けは従来通りで、キーボードショートカットを使うと色々と動作が異なっている感じがします。
キーボードショートカットの切り取りはファイル選択は選択中のものが影響されますが、貼り付け時は無視されています。マウスでフォルダを右クリックして貼り付けると影響します。この辺の細かいところでいろいろやらかしてる最中なのかも。

再確認してみると、複数のファイルエクスプローラ間の[Ctrl]+[X]で切り取って[Ctrl]+[V]で貼り付けるとちゃんと移動しました。さっきは2回やってもコピーされただけだったので、マウス操作したのですが、操作を間違えただけの勘違いなのかいまいち納得できませんが。

2020年6月3日水曜日

Windows10でVPN接続中にWifiが切断されたときに運が悪いと再起動が必要になる

どうもいい感じにVPN接続が切断されてしまうので、いろいろと原因を探っていたところ、もっと深刻な状況に。

2020年5月25日月曜日

医療従事者に慰労金

給付金の一律というのも引っかかったが、今日のニュースを見ていてちょっとオカシイんじゃないかと思った。
医療従事者に慰労金最大20万円 厚労省検討、2次補正 https://news.yahoo.co.jp/articles/ea94bcbc1825b6521a85c12b7ac791dd6af19c6c

突っ込み所が多すぎて困る。

2020年3月13日金曜日

Bluetoothデバイスが消えた原因は不明

Windowsのイベントビューアーで原因となるトリガーをちょっと調べてみました。

システムログを確認すると、夕方スリープ状態が解除されたとき、BTHUSBでトラブルが発生したのかな?

2020年3月12日木曜日

Bluetoothデバイスが消えた

昨日、家に戻ってからマウスのランプが点滅していたので、いつもの電池切れかと思って電池を交換してみたところ、ノートが全く反応せず。