ラベル Raspberry Pi の投稿を表示しています。 すべての投稿を表示
ラベル Raspberry Pi の投稿を表示しています。 すべての投稿を表示

2026年2月26日木曜日

Raspberry Pi 500+ 日本語配列版はほぼパソコン

Raspberry Pi 500+ 日本語配列版をポチってしまいました。 

Raspberry Pi 500+は2025年9月25日に発表されましたが、そのキーボードを日本語版にして16GBメモリに256GB SSD持つキーボード一体型のRaspberry Pi 5 になります。
その詳細はこちらに詳しく紹介されているので見て下さい。

自宅に来た、Raspberry Pi 500+を早速試してみました。
数値的なものよりも体感的にどう感じるかで評価したいと思いますのでブラウザを使って試したいと思います。標準でChromiumとFirefoxが入っていて初回起動時に選択ができるようになっていました。
Raspberry Pi 4はmicroSD、Raspberry Pi 5はSSDからの起動となります。

2回目以降起動時ChromiumFirefox
Raspberry Pi 4/8GB4.238.89
Raspberry Pi 500+/16GB1.484.29

追記:2026/02/27
初回起動時の測定も行なってみました。
SSDの威力が発揮されている結果となりました。

初回起動時ChromiumFirefox
Raspberry Pi 4/8GB12.7118.25
Raspberry Pi 500+/16GB2.766.5

初回起動時はライブラリの読み込みなどで時間がかかるので、数回起動してから測定を行なっています。電源投入後の初回は2,3秒microSDでは8秒〜10秒、SSDでは1、2秒時間が多くかかるようです。
注目すべきはRaspberry Pi 500+でのChromiumでほぼ瞬間で起動される印象です。

そのお値段ですが、本体+公式マウス+公式ACアダプターで約53,000円(秋月電子通商)でした。これに公式ディスプレーを付けると約73,000円ですが、すでにディスプレーを持っていたり、リビングのTVを使うなら5万円ちょっとです。

しばらく使ってみてちょっと不満なのは、電源ボタンがDeleteキーのすぐ横にあるので、Deleteキーを多用する身としては誤って電源ボタンを押して、ログアウトダイアログボックスが表示されるのが面倒なのと、キー音がちょと耳障りな事でしょうか。

Chromiumを快適に使うちょっとした作業

Raspberry PiといえばChromiumですが、実はRaspberry Pi OSがBookwormになってからChromiumで日本語入力ができないという現象が出ていました。そのあたりの詳細はこちらに詳しいのですが、ここではとりあえずどうすれば解消できるかだけ纏めておきたいと思います。

STEP1: fcitxをfcitx5に変更する。

標準では fcitx-mozc がインストールされていますが、これを fcitx5-mozc にインストールし直すと共に、日本語フォントもインストールしておきます。
Terminalを開いて以下のコマンドを順次実行して下さい。

sudo apt update
sudo apt install fcitx5-mozc fcitx5-config-qt -y
sudo apt install fonts-noto-cjk fonts-ipafont -y

STEP2: Wayland用にChromiumを設定する。

これでChromiumで日本語入力は可能ですが、変換ポップアップがおかしな場所に表示される問題があるのでこの対策を行います。

具体的には /etc/chromium.d/10-gtk-version ファイルを作成して以下の内容を追加します。

<実行コマンド>

sudo nano /etc/chromium.d/10-gtk-version

<追加内容>

if [ ! "$XDG_SESSION_TYPE" = "x11" ]; then
    export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --gtk-version=4"
fi

編集を保存して終了するには、Ctrl+o、Enter、Ctrl+x の順にキー入力します。

STEP3: Fcitx5 をデフォルトに設定

以下のコマンドを実行して、再起動すれば Chromium で日本語入力が問題なく出来る様になります。

im-config -n fcitx5


2022年5月24日火曜日

bullseyeで初期設定後画面が真っ黒になって困った

あれ、画面が真っ黒に 

Raspberry Pi OSとして最近はbullseyeを主に使っています。
今まではIoT用途が多かったのでヘッドレスでのセットアップがばかりでしたが久々にディスプレイ+キーボード+マウスの構成でインストールをしたところ初期設定後の再起動で画面が真っ黒になって困ってしまいました。

どうやら言語設定を日本語にすると画面が真っ黒になってしまうようです。

最新のImagerでは色々と初期設定が可能ですが何もしないで今まで通りのインストールを行うと英語の初期設定画面は問題なく表示されるのですが、ロケールなどを日本語環境用に設定した後のリブート後に画面が真っ黒になってしまいます。

OSは問題なく起動されているのでsshでログインすることは可能です。

インストール環境

Raspberry Pi 4B 8MB
MicroSDカード:GIGASTONE 32MB
Raspberry OS:2022-04-04-raspios-bullseye-arm64.img
ディスプレイ:I-O DATA EX-LD2071TB
キーボード、マウス:自宅にあったもの

boot.txtの修正で問題解決

他のディスプレイに接続すると問題なく画面が表示されるディスプレイもあります。
どうやらディスプレイとの相性のようです。

昔もディスプレイとの相性があってconfig.txtをいじったことを思い出しました。

と言うことで今回はSDカードを取り出してWindowsで/boot/config.txtの以下の部分を修正して問題なく画面が表示されるようになりました。
値についてはそれぞれの環境によって違いますが参考としてはこちらと各自のディスプレイの取説を見て下さい。

ちなみにI-O DATA EX-LD2071TBは1920×1080のプログレッシブモードでHDMI接続なので1080pの60Hzの設定(hdmi_mode=5)を使用しました。

framebuffer_width=1920
framebuffer_height=1080

hdmi_group=1
hdmi_mode=5


2022年5月3日火曜日

bullseyeでGrove Base Hat for Raspberry Piが動かない!

 Raspberry Pi OS bullseyeがリリース

2021年10月30日にbullseyeがリリースされましたが、その後Busterも引き続きサポートされていく事がアナウンスされました。本家のNewは2021年12月2日に出されましたが、2021年12月10日にはZD Net Japanが日本語の記事をアップしています。

これに伴ってGrove Base Hat for Raspberry Piの一部センサー等についてbullseyeでは提供されるライブラリで動かなくなったものが出てきた様です。

いずれライブラリもアップデートされるでしょうが今回仕事でGrove Base Hat for Raspberry Pi(以下Hat)を使う必要があったのであえてLegacyを使わずにbullseyeにチャレンジしてみました。

Online one-click installationは使えません

まずはseeed studioのHatのページを見てみるとbullseye以上の場合は「Online one-click installation」が使えないと記載されています。これはbullseyeからPython2が標準インストールされてなくなったのが原因です。但し「Step by step installation」の手順でPython3でインストールすればbullseyeでもHatの利用は可能です。

ほとんどのセンサー類は問題なく動く様です。

では何が問題なのかと言う事ですが、色々と調べてみるとHatライブラリでupmとmraaを使っていると問題になるようです。
bullseyeにはupmとmraaはインストールされていないので手動でインストールしようとしてもパッケージが見つからないのでインストール出来ませんでした。
seeed studioのGithubでもupmとmraaについては既にメンテナンスされていない様なのでGroveモジュールでupmとmraaを使用している物は使えないとなっています。

Node-REDで動かしてみる

取り敢えずはbullseyeの環境でインストールしてNode-REDでこちらの温度センサーを使ってみると以下の様なエラ〜メッセージが表示されます。

Error: Command failed: python -u /home/pi/.node-red/node_modules/node-red-contrib-grove-base-hat/grove-temperature-sensor/grove-temperature-sensor.py 2 1651393678682
Traceback (most recent call last):
  File "/home/pi/.node-red/node_modules/node-red-contrib-grove-base-hat/grove-temperature-sensor/grove-temperature-sensor.py", line 26, in <module>
    from grove.factory import Factory
  File "/usr/local/lib/python3.9/dist-packages/grove/factory/__init__.py", line 2, in <module>
    from .factory import *
  File "/usr/local/lib/python3.9/dist-packages/grove/factory/factory.py", line 38, in <module>
    from grove.temperature import *
  File "/usr/local/lib/python3.9/dist-packages/grove/temperature/__init__.py", line 2, in <module>
    from .mcp9808 import TemperMCP9808
  File "/usr/local/lib/python3.9/dist-packages/grove/temperature/mcp9808.py", line 38, in <module>
    from upm.pyupm_mcp9808 import MCP9808
ModuleNotFoundError: No module named 'upm'
    at ChildProcess.exithandler (child_process.js:383:12)
    at ChildProcess.emit (events.js:400:28)
    at maybeClose (internal/child_process.js:1058:16)
    at Socket.<anonymous> (internal/child_process.js:443:11)
    at Socket.emit (events.js:400:28)
    at Pipe.<anonymous> (net.js:686:12) {
  killed: false,
  code: 1,
  signal: null,
  cmd: 'python -u /home/pi/.node-red/node_modules/node-red-contrib-grove-base-hat/grove-temperature-sensor/grove-temperature-sensor.py 2 1651393678682'
}

この温度センサーではNTC Thermistorを使っているのでMCP9808は使っていないのですがエラーになっています。「grove/temperature/__init__.py」が有無を言わさずに「mcp9808.py」をimportしている様です。

そこでupmとmraaを使用しているモジュールを調べてみると

$ sudo grep -rl upm /usr/local/lib/python3.9/dist-packages/grove
/usr/local/lib/python3.9/dist-packages/grove/display/jhd1802.py
/usr/local/lib/python3.9/dist-packages/grove/display/__init__.py
/usr/local/lib/python3.9/dist-packages/grove/display/sh1107g.py
/usr/local/lib/python3.9/dist-packages/grove/display/__pycache__/jhd1802.cpython-39.pyc
/usr/local/lib/python3.9/dist-packages/grove/display/__pycache__/__init__.cpython-39.pyc
/usr/local/lib/python3.9/dist-packages/grove/display/__pycache__/sh1107g.cpython-39.pyc
/usr/local/lib/python3.9/dist-packages/grove/temperature/mcp9808.py
/usr/local/lib/python3.9/dist-packages/grove/temperature/__pycache__/mcp9808.cpython-39.pyc
/usr/local/lib/python3.9/dist-packages/grove/grove_optical_rotary_encoder.py
$
$sudo grep -rl mraa /usr/local/lib/python3.9/dist-packages/grove
/usr/local/lib/python3.9/dist-packages/grove/display/sh1107g.py
/usr/local/lib/python3.9/dist-packages/grove/display/jhd1802.py
/usr/local/lib/python3.9/dist-packages/grove/display/__pycache__/sh1107g.cpython-39.pyc
/usr/local/lib/python3.9/dist-packages/grove/display/__pycache__/jhd1802.cpython-39.pyc
/usr/local/lib/python3.9/dist-packages/grove/gpio/gpio_mraa.py
/usr/local/lib/python3.9/dist-packages/grove/gpio/__init__.py
/usr/local/lib/python3.9/dist-packages/grove/gpio/__pycache__/gpio_mraa.cpython-39.pyc
/usr/local/lib/python3.9/dist-packages/grove/gpio/__pycache__/__init__.cpython-39.pyc
/usr/local/lib/python3.9/dist-packages/grove/grove_optical_rotary_encoder.py

それぞれのソースにあたってみると、

  • displayでは__init__.pyで直接upmからimportしています。
  • temperatureでは__init__.pyで直接upmをimportしていませんが、__init__.pyでmcp9808.pyをimportしているので間接的にimportされます。
  • grove_optical_rotary_encoderについては光ロータリーエンコーダを使用しなければ問題ありません。
  • gpioについてはRPi.GPIOがインストールされていない場合にgpio_mraaを使用するようになっていますがbullseyeではRPi.GPIOがインストールされているのでmraaは使用されません。

以上からdisplayとtemperatureについて対応してあげれば使用できるようになりそうです。

Groveにパッチを当てる

以下の修正をする事でNode-REDで問題なく温度の測定をする事ができるようになりました。

$ sudo vi /usr/local/lib/python3.9/dist-packages/grove/temperature/__init__.py

from .temper import Temper,TemperTypedNTC
### from .mcp9808 import TemperMCP9808

### __all__ = ["Temper", "TemperTypedNTC", "TemperMCP9808"]
__all__ = ["Temper", "TemperTypedNTC"]

$ sudo vi /usr/local/lib/python3.9/dist-packages/grove/display/__init__.py

### from upm.pyupm_lcd import SSD1306, SSD1308, SSD1327
### from .jhd1802 import JHD1802
### from .sh1107g import SH1107G_SSD1327

### __all__ = ["JHD1802", "SH1107G_SSD1327"]
__all__ = []

尚、コメントにしたGroveモジュールについて使用する場合は自分で対応する必要があります。

2022年5月2日月曜日

Raspberry Pi Imager update to v1.7

 知らないうちにRaspberry Pi Imagerが便利になっていた


セミナーでハンズオンを行う機会が多いのですが、その場合ヘッドレスインストールする事がほとんどでした。
この時に今まではssh、Wi-Fiの設定については/bootにファイルを設置することで可能でしたがhostnameを変更することは出来ませんでした。この為、複数のRaspberry Piが「raspberrypi」と言うhostnameでインストールされることになりせっかくZeroconfでssh接続しようと思っても同じhostnameが乱立することになり初期設定手順が煩雑になっていました。

Raspberry Pi Imagerなんてイメージが書き込めればいいと思っていたのでアップデートすることもなくほったらかしになっていたのですがいつの間にか便利機能が追加されていた様です。

今回v1.7になることで日本語対応してくれた様ですが、v1.6の時に便利機能が追加されていた様です。2021年3月19日のNewsにちゃんと紹介されていました(><)

この時はまだCtrl-Shift-Xと裏技的な取り扱いでしたが今回v1.7ではわかり易くなっていましたので日本語化されたその画面を紹介したいと思います。基本的な設定内容はv1.6と変更はありませんので詳細は上記のNewsを見てください。とは言っても画面を見れば判る事ばかりですが。

Raspberry Pi Imager v1.7


起動直後の画面が日本語になっています。
まだこの時点では設定ボタンは表示されていません。


此処でインストールするOSを選択すると


設定ボタンが表示されます。
これをクリックするとこんな画面が表示されてhostnameも設定できる様になっています(@_@)


これなら複数台のRaspberry Piがあって一斉にインストールしてもssh接続で困る事は無くなったのでセミナーがよりスムーズに進みそうです。
また、この設定はインストールのデフォルト設定とする事も可能なので自宅で何回もイメージの書き換えを行う時も楽になりそうです。

※1:bullseyeからユーザpiが自動設定されなくなったのでユーザ名/パスワードの設定を忘れるとbullseyeのヘッドレスインストールではMicroSDへの書き込み後初めての起動で立ち上がらなくなるのでご注意ください。

※2:bullseyeからuserconf.txtを/bootに用意する事で初期ユーザの作成が行われます。

2021年9月23日木曜日

Raspberry Pi ZeroでHeadphonesが無くなった

最近こんなの

Adeept Robotic Arm Kit for Arduino

や
こんなの

「Petoi Bittle」(ペトイ・ビトル)

を購入して遊んでいました。








両方共にArduino互換ボードでサーボモーターを駆動する物ですが基本的なプログラムは提供されるのでとりあえず組み立てるだけで動かすことができます。

Arm Kitの方は仕組みは簡単なので工夫すればいろいろとプログラムをして遊べそうです。ただバッテリーが18650を2本とちょっと特殊ですが、バッテリーがなくてもUSBからの給電でも動くので無理してバッテリーを購入する必要はないとおもいます。なをバッテリーを購入するときは充電器も専用なものが必要となるのでご注意下さいね。

Bittleの方は赤外線リモコンもついていて組み立てればすぐに遊ぶことができます。
提供されるプログラムですぐに動かすことができますが、スムーズに歩くようにさせるには調整が必要になるようです。ビデオ等ではスムーズに動いているようですが、この写真のように顔をつけていない物がほとんどです。
ちょっと調整をしてみましたが思ったようにうまく動かすことができません。想像ですが提供されるプログラムは顔の部分がついていない状態で調整されているのではないかなと思われます。顔がつくことで重量バランスが違ってくるので、単純なキャリブレーションで調整できずにプログラム側の調整も必要になるのではないかなと。

ということでBittleのプログラムをざっと眺めてみましたが、各サーボモータの角度を持つフレームを複数用意してループさせることで動作をさせるという形式でした。
うまく歩かない場合はこの角度を微調整していくことでよりスムーズに動作させることが可能になります。とはいえ、なかなか時間がかかる作業になりますので今回は見送り、よたよたと動くことで満足することにしました。

といったことをやっていて、そういえばRAPIROをしばらく動かしていないということに気が付きました。

引っ張り出して来て1年ぶり程に動かしたら、どうも調子が悪いようです。

MicroSDカードでエラーが発生


原因を調べてみると組み込んだRaspberry Pi ZeroのMicroSDカードでエラーが発生しているようです。あちこちのデモで使用した時にきちんとShutdownせずに電源を切っていたのが原因かもしれません。せっかくShutdownスイッチを付けたのですが撤収時にバタバタしてついつい電源をプチンと切ることが多かったのかもしれません。
fsckで修復してみましたがやはりファイルシステムが破損しているようです、ログインがパスワードエラーで弾かれてしまいます。

出来る範囲で必要なファイルをサルベージしてからMicroSDカードをフォーマットしなおしてRaspberry Pi OSからインストールです。

bcm2835 Headphonesがなくなった


Raspberry Pi Zeroにはヘッドフォン用ジャックは付いていませんがHDMIで音声出力も可能にはなっています。また、RAPIROに組み込んで使うときはPWM Audioを利用してスピーカーから音声を出力していました。
ということでOSインストール後音声の出力先を3.5mm Jackに変更しようとraspi-configを実行してみたのですがHDMIしか表示されません。どうやらOSがStretchからBusterに変わったのが原因のようです。ハードウエア的についていない物は表示しないということでしょうか?

config.txtの修正で解決


ネットを検索すると同じような現象でこまっていた方もいるようで、こちらのサイトに解決策が上がっていました。
以下の2行を/boot/config.txtの最後に追加することでGPIO 12と13でPWM Audioが利用できます。(一般的にはGPIO 13と18のペアが利用されますがGPIO 18がRAPIROとの接続ケーブルで使用しているのでペアを変更して利用しています)
dtoverlay=audremap,enable_jack=on
dtoverlay=pwm-2chan,pin=12,func=4,pin2=13,func2=4

2021年4月22日木曜日

Vega-liteで温度測定グラフを描いてみた

ここ数日はVegaにハマっています。
IoTシステムでよく使う稼働状況グラフは表示できたので次に測定結果をグラフにすることにチャレンジしました。Node-REDのDashboardを使えば簡単に表示できますが、同じことをVega-liteで出来るようにしてみました。

mark: lineのTips


折れ線グラフはVega-liteのサンプルにもあるので簡単に表示できましたが、以下2点がちょっと不満なのであれこれと格闘してみました。
  • 表示範囲にちょっと余白を持ちたい
    • Vegaではデータからグラフの表示範囲(domain)を自動的に計算してくれるのですが、数値軸の場合は0から最大値までとなり、時間軸の場合はデータの時間範囲になります。
      domainを指定することでその範囲を指定することが可能ですが、データの値を元に指定したい。さらに、domainを最小値と最大値に設定すると上下(あるいは左右)に余白がなくなってグラフとしてちょっと見辛いという問題がありました。
  • 時間軸の表示方法をHH:MMとしたい
    • 時間軸の場合timeUnitをhoursminutesに設定すると軸ラベルはHH:MMで表示してくれるようになりますが、データも分単位に集約されてジャギーなグラフになってしまいます。測定が1秒毎のデータを表示しつつラベル表示はHH:MMとしたい時にどうしたら良いかでちょっとハマリました。

Dashboardでは何気に配慮してくれているので見やすいグラフに仕上がっています。

結果は以下のようになりました、Vega-Editorで確認してください。
ポイントはtransformのcalculateを使って軸データから上下(あるいは左右)の余白分を加減算した列を追加してdomainで指定することです。

{
    "description": "Line Chart Sample",
    "width": 600,
    "height": 600, 
    "data": {
		"values": [
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.35,"P":980.094,"H":33.53},"sensed_at":"2021-04-21T01:35:38.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.35,"P":980.096,"H":33.53},"sensed_at":"2021-04-21T01:35:43.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.35,"P":980.105,"H":33.53},"sensed_at":"2021-04-21T01:35:48.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.35,"P":980.116,"H":33.531},"sensed_at":"2021-04-21T01:35:53.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.36,"P":980.099,"H":33.531},"sensed_at":"2021-04-21T01:35:58.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.36,"P":980.138,"H":33.52},"sensed_at":"2021-04-21T01:36:03.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.36,"P":980.133,"H":33.52},"sensed_at":"2021-04-21T01:36:08.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.36,"P":980.152,"H":33.52},"sensed_at":"2021-04-21T01:36:13.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.36,"P":980.138,"H":33.52},"sensed_at":"2021-04-21T01:36:18.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.37,"P":980.143,"H":33.509},"sensed_at":"2021-04-21T01:36:23.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.37,"P":980.118,"H":33.509},"sensed_at":"2021-04-21T01:36:28.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.38,"P":980.124,"H":33.51},"sensed_at":"2021-04-21T01:36:33.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.38,"P":980.14,"H":33.509},"sensed_at":"2021-04-21T01:36:38.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.38,"P":980.126,"H":33.51},"sensed_at":"2021-04-21T01:36:43.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.38,"P":980.16,"H":33.51},"sensed_at":"2021-04-21T01:36:48.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.38,"P":980.126,"H":33.51},"sensed_at":"2021-04-21T01:36:53.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.38,"P":980.116,"H":33.51},"sensed_at":"2021-04-21T01:36:58.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.38,"P":980.144,"H":33.51},"sensed_at":"2021-04-21T01:37:03.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.39,"P":980.128,"H":33.486},"sensed_at":"2021-04-21T01:37:08.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.38,"P":980.11,"H":33.51},"sensed_at":"2021-04-21T01:37:13.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.38,"P":980.11,"H":33.51},"sensed_at":"2021-04-21T01:37:18.000Z"},
			{"machine_id":"machine01","unit_address":"FC:F5:C4:1A:53:64","sensor_number":2,"sensor_type":"BME280","data":{"T":22.38,"P":980.094,"H":33.497},"sensed_at":"2021-04-21T01:37:23.000Z"}
		]
    },
    "transform": [
        {"calculate": "datum.data.T-0.01", "as": "minY"},
        {"calculate": "datum.data.T+0.01", "as": "maxY"}
    ],
    "mark": {"type":"line", "clip": true},
    "encoding": {
        "x": {
            "field": "sensed_at",
            "timeUnit": "hoursminutesseconds",
            "axis": { "format": "%H:%M" }
        },
        "y": {
            "field": "data.T",
            "type": "quantitative",
            "scale": {
                "domain": {"data": "data_0", "fields": ["minY", "maxY"]}
            }
        }
    }
  }

2021年4月17日土曜日

Vega-liteで稼働状況グラフを作成してみた

現在ESP32とRaspberry Piを使ってNC工作機械の稼働監視を行おうとしています。
稼働監視その物はESP32のNC工作機械主軸の電流を計測することで可能なのですが、問題はその稼働状況をグラフ化するところになります。

データはRaspberry Pi上でNode-redを動かしているのでDashboardを使えば可視化はある程度できましすが、よく見かける稼働監視グラフ(横方向の積み上げグラフあるいはガントチャートの応用)を表示しようとしてつまづきました。
Dashboardそのものはchartでグラフ化は可能ですが、積み上げグラフには対応していないようです。

node-red-node-ui-vega

ライブラリを検索しているとnode-red-node-ui-vegaというノードを発見しました。
Vega(「可視化を記述する言語」を目指した物で描画ライブラリとしてはD3を使用しているようです)及びVega-lite(Vegaの文法を簡略化した物でVega用の定義ファイルを出力して描画はVegaで行います)をNode-redから使えるようにしてくれるノードのようです。非常に高機能なグラフ化ツールのようです。積み上げグラフを表示する程度ならVega-liteで十分なようです。

サンプルも豊富に用意されていますが、残念ながらx軸を時間でとった横方向の積み上げグラフのサンプルはありませんでした。(横方向の積み上げ棒グラフのサンプルはありました)
これを修正して横軸を時間にできれば出来そうです。

ところがこれでハマってしまいました。Vegaに関する日本語の解説本もなく情報が少ない上にVegaの概念がちょっと複雑なのが原因です。基本的にはデータをチャネルという概念でデータ変換(データドメインから表示ドメインへ変換)して表示用の修飾を行って可視化(グラフ表示)するという考え方のようです。

Vega-liteによる稼働状況グラフ

結局数日かけた結果が以下のソースになります。Vega-Editorをブラウザで表示してコピペをするとどのように表示されるか見ることが出来ます。
このサイトを使えば自分で表示したいグラフのテストが簡単に出来るので開発もスムーズに出来ます。

{
  "config": {
      "legend": { "disable": true }
  },
  "width": 600,
  "height": 100,
  "data": {
    "values": [
      {"machine": "machine01", "start": "2021-04-01 08:30:00", "end": "2021-04-01 10:00:00", "color": "#ff0000"},
      {"machine": "machine01", "start": "2021-04-01 10:00:00", "end": "2021-04-01 11:15:00", "color": "#00ff00"},
      {"machine": "machine01", "start": "2021-04-01 12:00:00", "end": "2021-04-01 13:00:00", "color": "#ff00ff"},
      {"machine": "machine01", "start": "2021-04-01 14:00:00", "end": "2021-04-01 16:42:00", "color": "#0000ff"}
    ]
  },
  "mark": "bar",
  "encoding": {
    "y": {"field": "machine", "title": null},
    "x": {
      "field": "start",
      "timeUnit": "hoursminutes",
      "scale": {
        "domain": [{"hours": 8}, {"hours": 19}]
      },      
      "title": null
    },
    "x2": {
      "field": "end",
      "timeUnit": "hoursminutes"
    },
    "color": {
      "legend": {"disable": true, "title": null, "values": [ "" ]},
      "field": "color",
      "scale": {
          "range": {"field": "color"}
      }
    }
  }
}

2021年4月8日木曜日

PowerBI 32bitでMariaDBに接続できなかった件

Microsoft.PowerBI.OleDb is not registered

 最近IoT関係で計測データの分析をする必要があったのでPowerBIを使ってみました。
とりあえず自分のPCで分析できたので、顧客先のPCで同じことをやろうとしたところ上記のようなエラーになって分析できませんでした。
違いといえば自分のWindows10が64bitのProバージョンなのに対して、顧客のWindows10は32bitのHomeであることでした。

PowerBI及びMariaDB Connector/ODBCについては32bit版をインストールしたので問題ないと思ったのですが・・・
テーブルの選択は可能なのでMariaDBへの接続まではできているようです、その後内部的にデータ処理用にOleDBのオブジェクトに変換しているようで、そこでクラスが登録されていないというエラーのようです。

いつものようにGoogleさんにお伺いを立てるとこちらのサイトに行き当たりました。

内容的には64bitのPowerBIから32bitのAccessに接続しようとして発生したエラーの話のようですが、結論としてはMicrosoft Access Database Engineをインストールすれば解決するよという事のようです。OLE DBがAccess Database Engineに含まれているのかな?

一件落着


早速こちらから32bitのAccess Database Engineをダウンロードしてインストールして再度テストしましたが・・・

う・ご・か・な・い・・・

同じくOleDBが無いというエラーです。
PCを再起動してテストしても同じです。

そこで再度PowerBIも含めてインストールをやり直してみました。
  1. Microsoft Access Database Engineのインストール
  2. MariaDB Connector/ODBCのインストール
  3. PowerBIのインストール
今度はちゃんとアクセスすることができました。

とすると、インストールされているエンジンに合わせてPowerBIが必要なモジュールをインストールしているのかもしれませんね。

いずれにしろ一件落着でした。

2020年8月17日月曜日

Raspberry PiでMariaDBをインストールしたらまず行うこと

ESP32で収集したセンサーデータを保存する為にRaspberry PiにMariaDBをインストールしてそこに保存しようと考えていますが、久々にMariaDB(MySqlでも同じですが)をインストールしたのでインストール直後に行うセキュリティ対策をメモして置きます。

STEP1:インストール

MariaDBはRaspberry PiのGUI画面のメニューで

設定>Add/Remove Software

から

「Mariadb」で検索して、

MariaDB database client(metapackage depending on the latest version)
MariaDB database server(metapackage depending on the latest version)

にチェックしてサーバーとクライアントのバイナリインストールができます。

インストール直後にはサーバも起動されているのが確認することができます。(hostnameはiotserverに変更してあります)

pi@iotserver:~ $  systemctl status mariadb.service
* mariadb.service - MariaDB 10.3.23 database server
   Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2020-08-17 13:01:03 JST; 1h 41min ago
     Docs: man:mysqld(8)
           https://mariadb.com/kb/en/library/systemd/
 Main PID: 2268 (mysqld)
   Status: "Taking your SQL requests now..."
    Tasks: 30 (limit: 2065)
   CGroup: /system.slice/mariadb.service
           `-2268 /usr/sbin/mysqld
 8 17 13:01:06 iotserver /etc/mysql/debian-start[2306]: Phase 6/7: Checking and upgrading tables
 8 17 13:01:06 iotserver /etc/mysql/debian-start[2306]: Running 'mysqlcheck' with connection arguments: --socket='/var/run/mysqld/mysqld.sock' --host='localhost' --socket='/var/run/mysqld/mysqld.sock' --host='
 8 17 13:01:06 iotserver /etc/mysql/debian-start[2306]: # Connecting to localhost...
 8 17 13:01:06 iotserver /etc/mysql/debian-start[2306]: # Disconnecting from localhost...
 8 17 13:01:06 iotserver /etc/mysql/debian-start[2306]: Processing databases
 8 17 13:01:06 iotserver /etc/mysql/debian-start[2306]: information_schema
 8 17 13:01:06 iotserver /etc/mysql/debian-start[2306]: performance_schema
 8 17 13:01:06 iotserver /etc/mysql/debian-start[2306]: Phase 7/7: Running 'FLUSH PRIVILEGES'
 8 17 13:01:06 iotserver /etc/mysql/debian-start[2306]: OK
 8 17 13:01:06 iotserver /etc/mysql/debian-start[2362]: Triggering myisam-recover for all MyISAM tables and aria-recover for all Aria tables


STEP2:インストール直後に行う事

他のサイトでもよく紹介されいる

pi@iotserver:~ $ sudo /usr/bin/mysql_secure_installation

を行ってrootにパスワードの設定を行います。(ルートの新パスワード以外はEnterで進めて問題ありません)

ただ、この状態では

pi@iotserver:~ $ mariadb
ERROR 1698 (28000): Access denied for user 'pi'@'localhost'
pi@iotserver:~ $ mariadb -u root -p
Enter password:
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
pi@iotserver:~ $ sudo mariadb
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 63
Server version: 10.3.23-MariaDB-0+deb10u1 Raspbian 10


Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


MariaDB [(none)]> 

のようにrootがパスワード無しでログインできてしまいます。これはrootのユーザ認証にunix_socket認証プラグインが使われている為で


MariaDB [(none)]> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A


Database changed
MariaDB [mysql]> select host,user,password,plugin from user;
+-----------+------+-------------------------------------------+-------------+
| host      | user | password                                  | plugin      |
+-----------+------+-------------------------------------------+-------------+
| localhost | root | *A764549B3367FB60049727C812C20114B39D834E | unix_socket |
+-----------+------+-------------------------------------------+-------------+
1 row in set (0.001 sec)

次のSQLコマンドでpluginを無効化します。


MariaDB [mysql]> update user set plugin='' where user='root';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

MariaDB [mysql]> select host,user,password,plugin from user;
+-----------+------+-------------------------------------------+--------+
| host      | user | password                                  | plugin |
+-----------+------+-------------------------------------------+--------+
| localhost | root | *A764549B3367FB60049727C812C20114B39D834E |        |
+-----------+------+-------------------------------------------+--------+
1 row in set (0.001 sec)

MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.001 sec)

rootでのログインにパスワードが必須となります。


pi@iotserver:~ $ sudo mariadb
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
pi@iotserver:~ $ mariadb -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 69
Server version: 10.3.23-MariaDB-0+deb10u1 Raspbian 10

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>quit
pi@iotserver:~ $ sudo mariadb -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 72
Server version: 10.3.23-MariaDB-0+deb10u1 Raspbian 10

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

2020年8月9日日曜日

node-red-node-pisrfでのピン番号

自作のIoT教育用ボードのテストを行っています。

Raspberry Pi Zero WHでNode-REDを使ってテスト用プログラムを作成していますが、超音波距離センサーHC-SR04のテストでnode-red-node-pisrfを使った時のメモです。

node-red-node-pisrfはSRF04 又はSRF05用なんですがネットで調べるとHC-SR04でも使えることが分かりました。早速インストールして使って見ましたが上手く動きませんでした。

設定としてはtriggerピンとechoピンの番号を指定するだけなんですが、この番号がBCMではなくBOARDだったという落ちでした。


2020年7月8日水曜日

LineageOS 16.0 (Android 9) for Raspberry Pi 4をインストールしてみた

前回Raspberry PiにLineageOSをインストールしてから1年以上が経過してRaspberry Piも4に進化しましたが、LineageOSも今年の2月にはRaspberry Pi 4用のLineageOS 16.0(Android 9)がリリースされていました。

前回はScratch JrをRaspberry Piで動かすことが目的でしたが、残念ながらScratch Jrについてはマウスで操作ができなかったので断念した経緯があります。新しいバージョンではどうかも含めて再度トライすることにしました。

Google appsのインストールも前回同様用意されていました。多少スクリプト名が変更になっていたり、TWRPの画面がちょっと変わったりしてしていましたが、作業は前回と全く同じでした。
注意点としてはGoogle appsのインストール後、起動設定変更作業前にパーティションのマウントを行いますが、この時に「boot」にもチェックを入れないとエラーが発生します。/bootに書き込みに行っているのが原因だと思います。


今回改善されていた点

  • インストール時に言語選択で日本語が選択できるようになっていました。頑張って下の方までスクロールして下さい。インストール後すぐに日本語環境になっています。
  • Raspberry Pi 4の威力でしょうか、前回と違って設定などですぐに落ちることはなくなりました。そこそこのレスポンスで作業ができるようになっていました。

やっぱり問題が

  • Scratch Jrはやはり使えません。画面は表示されますが、マウスで操作ができませんでした。
  • Play Storeでのインストールは保留中となって先に進みませんが、そのまま再起動するとインストールされるようです。
  • インストールもそうですが、ネットワーク周りでおかしな動作が見受けられます。

前回同様にadbでもテストしてみましたが、adbでマウスイベントを発生させると動作するのですが、実際のマウスでは動作しないという現象が発生します。adbの場合は直接イベントを発生させているので、実際のマウスの場合はOS側の動作が違うのでしょうか?

Scratch JrはAndroidとiOSで動作するように、基本部分はJavaScriptで作成されていてOSに関わる部分だけをそれぞれのネイティブな言語で作成してあります。
Androidの場合はWebViewでJavaScriptを有効にして、handleTouchStartとhandleTouchEndで処理しているようです。

私が公開しているアプリは問題なくインストールできて動作も確認できました。ただこのアプリはAndroidネイティブなのでWebViewを使ったアプリではありません。
時間があれば簡単なアプリでテストをしたいと思いますが、今回はここまでとしたいと思います。

2020年6月13日土曜日

Raspberry Piのhostnameを起動時に変更したい

半年以上立っていますね。(T . T)
やはり物書きには向いてないようです。^ ^

・・・

最近IoT関連のハンズオンとかやる機会が増えてきています。
参加者はパソコン持参ですが、Raspberry Pi Zero Wを使う場合にちょっと困っています。
ネットワーク用のコネクタが付いていないのでWiFi接続となりますが、ディスプレイやキーボード、マウスを用意するのも大変です。

sshの設定とWiFiのSSID、PSK(Pre-Shared Key)の設定についてはブート時に自動設定する方法がこちらに書いてあります。

/bootフォルダに「ssh」という空ファイルを作成しておくとsshが自動的にONになりますし、「wpa_supplicant.conf」というファイルにWiFiの設定をしておけば自動的にWiFiに接続することができます。

wpa_supplicant.confはこんな感じです。
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP
network={
 ssid="<Name of your wireless LAN>"
 psk="<Password for your wireless LAN>"
}

ここでWiFiの接続先に注意してください。
Raspberry Pi Zero Wがサポートしているのは「802.11 b/g/n」だけなので2.4GHzしかサポートされていません。NECとかBuffaloのルータを使っている場合、SSIDは大体「A」「G」がついたSSIDが2.4GHzのはずです。

2020/09/08 訂正: Aは5HzでGが2.4GHzでした。正確にはご自分のルータの設定を確認してください。

あと私のハマった点は、Raspberry Pi Zero Wが立ち上がったかを確認するのに「ping raspberrypi.local」でまずは確認するのですが、Zeroconfが割と遅いということでしょうか?
あれ、pingが通らないや!と勘違いしないでちょっと時間を置いてみて再度確認して下さい。これで2回程SDカードの初期化からやり直してしまいました。

と、ここまではあちこちのサイトで紹介されています。

Windowsパソコンで作業している場合でも、SDカードへrasbianのイメージを書き込んだあと/bootがマウントできるのでWindowsだけで作業ができます。

ただ、ここで問題なのはセミナーのハンズオンなどで同時に複数台の設定を行う場合です。
WiFi接続がDHCPでも1台だけのセットアップならRaspberry Pi Zero Wのhostnameが「raspberrypi」固定なので
ssh pi@raspberrypi.local
でssh接続が可能です。

ところが複数の参加者が同じWiFiに接続するとhostnameが被ってしまいます。
それぞれのSDカードで別のhostnameにするか、IPアドレスを固定にするかで回避できますが、
残念ながらどちらも初回ブート時に設定する方法は無いようです。

そこでこちらのサイトで回答のあったサービスを利用する方法を応用して初回ブート時にhostnameを変更するイメージを作成することにしました。

こうすることで、SDカードにイメージを書き込んだ後に、Windowdsパソコンでssh、wpa_supplicant.conf、hostnameの3つのファイルを用意することで、参加者各自が任意のhostnameのRaspberry Piを立ち上げることができます。(実際にはsshは設定済みのイメージになるので、会場のWiFiに併せたSSID/pskとhostnameの設定を行います)


STEP1:rasbianのイメージを書き込んだSDカードの用意


こちらのサイトから必要なrasbianのイメージファイルをダウンロードします。本家は遅い場合がありますので、その場合はこちらのサイトも試してみてください。
私はSDカードへの書き込みはSD Memory Card Formatterでフォーマット後に、balenaEtcherを使用しています。


STEP2:/booにsshとwpa_supplicant.confを作成


上で説明したようにrasbianのイメージを書き込んだ後、SDカードを抜き差しすると/bootがWindowsでもマウントされて見えるようになります。ここでsshとwpa_supplicant.confをbootフォルダに作成します。

この時に、ちょっと工夫をしておくことで後でimgファイルを作成する時間が短縮できます。

それは、最近のrasbianではパーティションの拡張作業が初回boot時に自動で行われるようになっているので、そのまま再起動してしまうとパーティションサイズがSDカードいっぱいになってしまいます。後でイメージファイルを作成する時にSDカード全体をイメージファイルにすることになって時間がかかりますし、SDカードにイメージファイルを焼く時間も長くなります。

/boot/cmdline.txtの
init=/usr/lib/raspi-config/init_resize.sh
を
init=/sbin/init
に書き換えておきます。init_resize.shがパーティションの拡張を行なっているシェルスクリプトです。


STEP3:Raspberry Pi Zero Wを起動


SDカードをRaspberry Pi Zero Wに挿し、電源を入れて下さい。しばらくしてからパソコンからsshで接続できれば、無事にWiFiに接続できています。
この時はまだhostnameは「raspberrypi」のままです。


STEP4:hostname変更サービスの登録


以下の作業で、起動時にhostnameを変更するサービスを追加します。
$ sudo vi /etc/systemd/system/change-hostname.service
[Unit]
Description=Change hostname from sd
ConditionPathExists=/boot/hostname
Before=dhcpcd.service

[Service]
Type=oneshot
ExecStartPre=/bin/bash -c 'CURRENT_HOSTNAME=$(/bin/cat /etc/hostname | /usr/bin/tr -d "\t\n\r");NEW_HOSTNAME=$(/bin/cat /boot/hostname | /usr/bin/tr -d "\t\n\r");/bin/sed -i "s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\t$NEW_HOSTNAME/g" /etc/hosts'
ExecStart=/bin/mv /boot/hostname /etc/hostname
ExecStartPost=/sbin/reboot

[Install]
WantedBy=multi-user.target

$ sudo systemctl enable change-hostname.service

STEP5:imgファイルの作成


以上で、起動時に/boot/hostnameが存在する場合、hostnameを変更してWiFIで接続してssh可能なrasbianが出来ました。

後は
  1. /boot/cmdline.txtのinitを元に戻す。(パーティション拡張の自動処理)
  2. /etc/wpa_supplicant/wpa_supplicant.confからnetworkを削除(SSID、psk消去)
  3. rm ~/.bash_history(コマンド履歴の削除)
を行なってから電源を切って、SDカードのイメージを作成すれば完了です。

私はSDカードのイメージ作成にはWin32 Disk Imagerを使っているので、「Read Only Allocated Partitions」にチェックを入れて作成されるイメージファイルを小さくしています。

2019年5月21日火曜日

RAPIROをScratchで制御する

5月25日(土)にスクラッチディ 2019 山梨にデモ出展することになりました。

何も準備できていませんが、この秋から予定しているプログラミング塾での教材をデモしようかなと考えています。Scratchでプログラミング可能なLEGO MINDSTORMS NXT(Enchanting)、Edison(EdScratch)、Scratch Jr on Raspberry Piなんですが、それだけでもちょっと寂しいのでRAPIROにMCをやってもらおうかなと考えました。

 Raspbian StretchではScratch 2.0 オフラインエディターが標準でインストールされています。
(注:Scratch3.0のリリースに合わせて2019年1月2日からScratch2.0オンラインエディターの提供が終了しました。)
そしてオフラインエディターには拡張機能があり、独自のブロックを簡単に追加できるようです。
Python で軽量サーバを作って Scratch 2 のHTTP拡張を待ち受けてみる
これで、拡張機能を作ってScratch(RAPIROとは別にRaspberry Pi 3で動かします)でシナリオ通りにRAPIROに喋らせるという魂胆です。確認の為にRaspberry PiでScratch2を立ち上げて、Shiftキーを押しながら「ファイル」を選ぶと「import experimental extension」と表示されるので、行けそうです。

Step1:HTTP拡張機能の作成


参考のページを元に拡張機能を定義しようとしましたが、外部のHTTPサーバへアクセスすることはできないようです。ポート番号は指定できますが、サーバについては指定方法がないようです。

仕方がないので、Bottle+PythonでRAPIROへリクエストを繋ぐ簡易サーバを作成しました。次にJSON 形式の.s2eファイルを作成して、拡張機能を読み込ませようとしましたが、うまく読み込んでくれません。URL を指定するようダイアログが出るので、「file:///.s2eファイルへのパス」で指定しても読み込んでくれません。

ここで、断念かと思いましたが・・・


Step2:Javascript Extensions


拡張機能で検索をしているとこちらのページにたどり着きました。
ここに
The current 2.0 extensions available in the offline editor, like the PicoBoard extension, are Javascript extensions.
とありました。
ということで、Step1で作成したPythonと.s2eファイルをJavaScriptに変換してみました。

Javascriptで拡張機能を作成する詳細仕様はこちらに上がっていますが、Ajaxも使えるようなのでRAPIROへのリクエスト送信も簡単に記述できました。

さて、実際にテストしてみると無事に拡張ブロックが表示されました。
今回は、最低限の機能だけ拡張機能として取り込んだので、今後時間を見てバージョンアップしたいと思います。



Javascriptについてはこちらにアップしてあります。

2019年5月17日金曜日

RAPIRO完全無線化 ー完結編(ソフトウエア)ー

大分時間が空いてしまいました。他の事で時間が取られてしまって書いている時間が取れませんでした。
さて、RAPIROの完全無線化についてハードウエアの方は完了したので、ソフトウエアの設定を行いたいと思います。と言っても、各パーツについてはすでに動作確認が終わっているので、それらを統合して簡単に使えるようにするだけです。

なお、以下の作業はRAPIROに組み込んだRaspberry Pi Zero B+(以下 PiZero)での作業になるので、まずは、sshでログインしてください。

Step1:カメラ画像のストリーミング


カメラ画像のストリーミングについてはこちらに投稿しておきましたが、PiZeroの電源を入れたら自動的にストリーミングを始めるようにサービス化しておきます。

まず、/home/pi/streaming/streaming.shとして以下を作成します。
#! /bin/sh
export LD_LIBRARY_PATH=/usr/local/lib/mjpg-streamer
mjpg_streamer -o "output_http.so -w /usr/local/share/mjpg-streamer/www" -i "input_raspicam.so -fps 5 -x 480 -y 320"
次に、/usr/lib/systemd/system/streaming.serviceとして以下を作成します。
[Unit]
Description=Mjpg-Streamer

[Service]
ExecStart =/home/pi/streaming/streaming.sh
Restart=always
Type=simple

[Install]
WantedBy=multi-user.target
以下のコマンドで作成したサービスをsystemdに登録します。
$ sudo systemctl enable streaming.service

Step2:RAPIROコントローラ(Python)


Bottle + PythonでRAPIROを外部から制御できるようにします。HTTPでコマンドを受け取ると、シリアル通信でRAPIROへコマンドを投げるという簡単な仕組みです。
Python用軽量Webフレームワークとしては他にFlaskもあり、どちらも簡単にREST風アプリが作れますが、私はBottleを利用しています。

Pythonのソース(本体)とindex.html、RAPIROのサーボモータをOFFにする機能をつけたスケッチをGitHubに上げてあるのでそちらを参照してください。詳細はソースを見ていただければすぐにわかると思います。
index.htmlではmjpg_streamerの提供するCSSファイル等をstaticフォルダ経由で利用しているので注意してください。又、python3、bottleについてはインストール済みであるとします。
$ cd ~
$ git clone https://github.com/KeiIchimaru/rapiroctl.git
$ cd rapiroctl
$ ln -s /usr/local/share/mjpg-streamer/www static
スケッチについてはRAPIROへの書き込みを行っておいてください。
あとはサービスとして登録する作業になります。
/usr/lib/systemd/system/rapiroctl.serviceとして以下を作成します。
[Unit]
Description=RAPIRO Controller

[Service]
ExecStart =/home/pi/rapiroctl/rapiroctl.py
Restart=always
Type=simple

[Install]
WantedBy=multi-user.target
以下のコマンドで作成したサービスをsystemdに登録します。
$ sudo systemctl enable rapiroctl.service
以上で、PiZeroのポート80でHTTPリクエストを待ち受けているので、ブラウザでアクセスするとサンプルの画面が表示されます。サンプルではカメラからのストリーミングも表示しているので、RAPIROに搭乗して操縦しているような感覚が得られると思います。(移動すると、画面が左右に大きく揺れるので酔いやすい方はご注意くださいw)

Step3:shutdownスイッチ


PiZeroはRAPIROの頭部に組み込まれているので、shutdownする場合は外部からsshでログインする必要があります。その為にPCを立ち上げるのも面倒なので、ハードウエア編で触れていますが、こちらのサイトを参考にshutdown用タクトスイッチを付けることにしました。利用したGPIOはBCM23(P16:物理ピン番号)とGND(P14)を使い、組み立てる時にタクトスイッチから配線しておきました。

PythonのプログラムはGitHubに上げてあるので、すでにダウンロードしてあるはずですのでサービスとして登録するだけです。
/usr/lib/systemd/system/shutdownbuttond.serviceとして以下を作成します。
[Unit]
Description=Shutdown by Button Daemon

[Service]
ExecStart =/home/pi/rapiroctl/shutdownd.py
Restart=always
Type=simple

[Install]
WantedBy=multi-user.target
以下のコマンドで作成したサービスをsystemdに登録します。
$ sudo systemctl enable shutdownbuttond.service

Step4:動かしてみて


以上で、全て完了したので動作確認です。
PiZeroの電源をONにすると、しばらくしてカメラが赤く光って起動が終了したことがわかりますので、その後RAPIRO本体の電源を入れて準備完了です。

ブラウザからPiZeroにアクセスすると下のような画面が出てきます。どう動くかは、各自試してみてくだサイ。ノートパソコンやスマフォからだと画面からはみ出て使いずらいと思いますので、各自自由にカスタマイズして使いやすい画面にして頂ければ幸いです。


rapiroctl.pyそのものはhttpサーバとして動いているだけなので、スマフォアプリを作成するなど応用は色々あると思います。

画面下部の「Play」はaudioフォルダ内の.wavファイルを再生する機能です。アンプが組み込んであるのでRAPIROを喋らせることができます。「Say」は指定されたテキストを音声合成して喋らせようとしたのですが、処理に時間がかかるので現在は使っていません。この辺りのこともそのうち時間ができたら投稿したいと思います。

電源を切るときは、タクトスイッチを長押しするとshutdownプロセスが開始されるので、しばらくしてカメラのランプが消えたら、PiZeroの電源を切って、最後にRAPIRO本体の電源を切ってください。


2019年4月16日火曜日

RAPIRO完全無線化 ー完結編(ハードウエア)ー

親指の抜糸は終わりましたが、一部の神経は切断されているのでちょっと感触がおかしな状態です。とは言え、作業には支障が無いのでRAPIROの完全無線化を終わらせたいと思います。

出来上がった状態はこんな感じです。



リチウムイオン電池を搭載してRaspberry Pi Zero W用の電源としています。RAPIROに付属している標準の接続ケーブルだとRaspberry Piの電源をRAPIROから取るようになっていますが、今回はそのケーブルからは電源を取らず(UART+RESET用のケーブルを作成しましたが、標準ケーブルからRaspberry Piの+5vに行く2本の線を外してもOKです)にRAPIROの電源と完全に分離しているので、より長い時間、動作させることができます。

Step1: ベース基盤


RAPIROの頭部にRaspberry Pi Zero Wやリチウム電池をのせる為にベースとなる基盤が必要になりますが、RAPIROの頭部はRaspberry Piの基盤サイズを対象としているので、このサイズの基盤を探します。

こちらのサイトで見つけました。

Raspberry Pi用の基盤はいくつかありますが、HAT用の物がほとんでサイズ的にも小さな物ばかりですが、基盤サイズで価格も手頃(¥165+税)でした。








Step2:電源部


部品:

・6W 5V UPS mobile power Diy Board Charger & Step-up DC DC Converter
・1500mah lithium-ion polymer battery 3.7 V 
・基板用マイクロUSBコネクタ(電源専用)
・マイクロUSBコネクタDIP化
・ピンヘッダ 1×40 (40P)
・TJC8ピンターミナル(メス) (10本入)
・コネクタ用ハウジング 2P
・配線用コード

TJC8ピンターミナル+コネクタ用ハウジングは工具が必要になるので、工具が無い場合はブレッドボード用ジャンパワイヤーを利用することも可能です。

組立:

USBコネクタをDIP化基盤に取り付ける時には基盤の表裏に気をつけて、こちらの写真を参考に半田付けしてください。なお、ピンヘッダについては下の写真のようにちょっと変則的な取り付け方をします。これは参考にした写真ではブレッドボードでの利用を想定していますが、今回はユニバーサル基盤に取り付けるので、基盤との接触を避ける為にこのような取り付けを行いました。

DCDCコンバータについても、取り付け用の穴が無いので同じようにピンヘッダを取り付けてからベース基盤に半田付けします。配線については、部品のサイトにある画像の通りに配線すれば問題ありません。

電源の出力側についてはマイクロUSBオスコネクターでRaspberry Pi Zero Wへ電源を供給しますが、途中にミニスライドスイッチを入れて電源のON/OFFができるようにしておきます。USBからの給電にしてあるので、電源スイッチによるノイズも問題ないと思います。


Step3:RAPIROへの組込


部品:

・2.6mmネジ+ナット(ホームセンターで精密ねじ、精密ねじ用ナットとして販売されてます)

組立:

RAPIROの後頭部へ、電源スイッチとShutdown用タクトスイッチ(ソフトで解説)を取付ける為に片面ユニバーサル基盤を加工します。

大まかに切断した後、RAPIRO後頭部へ当てながらヤスリで微調整をしていきます。電源スイッチはこのユニバーサル基盤にネジ止めしますが、ネジ穴の位置は具合を見ながら位置決めをします。今回の写真ではちょっと中に寄りすぎでした、もう少し外よりの方が良かったと思います。

RAPIROへの取付位置も実際に調整しながら決めます。なお、電源スイッチを取付たねじの頭があるので、ナットを1つか2つ挟んであげてください。

また、電源スイッチのボックス部分がアンプモジュールを取付けるスペーサーに当たることもあるので、そちらとの兼ね合いも見ながら取付位置を決める必要があります。

当初はネジ1本で支えようとしましたが、実際にスイッチを操作すると安定しないので、上側もネジ止めするようにしました。

次に、Raspberry Pi Zero Wをベース基盤にねじ止めしますが、ここでも基盤同士が接触しないように、ナットを間に挟んで高さ調節をします。今回は3mmのナット1つを挟みました。

最後に、スペーサ(11mm)を使ってアンプモジュールを取付け、配線をして終了です。

Step4:スピーカ用の穴


スピーカは頭部に内蔵しますが、そのままだと音がこもるので耳の部分に穴を開けて音が外に出やすいよう加工してあげます。

まずは、方眼紙に半径2cmの円を描いて穴を開ける位置を決め、マーク部分に穴を開けます。

次にRAPIRO頭部を前後合わせて仮止めし、方眼紙を耳の部分に当てセロテープで仮止めし、上から油性ペンで印をつけてあげます。

方眼紙を外し、頭部を前後分離してからマークに合わせてドリルで穴を開けます。

今回使ったのは2mmの木工用のビットを利用して穴を開けました。あまり力を入れると割れる恐れがあるので、ドリルの自重で穴を開けるような感じで作業します。




2019年3月9日土曜日

Android on Raspberry Piを安全にシャットダウン

左手の親指を怪我して2針縫ったのでしばらく不自由していました。

現在、Raspberry Pi 3 B+でAndroid7.1.1を動かしてScratch Jrを動かしていますが、Raspberry Piには電源ボタンが無いので、Androidをシャットダウンするには他のPCからadbコマンドでシャットダウンしてから電源を切るか、直接電源を切る必要があります。

できればシャットダウンしてから電源を切りたいので、シャットダウンアプリを導入しようとしましたが、rootを取っておく必要があるアプリばかりのようです。

そこで「android adb shutdown」でネットを検索すると、いくつかのサイトがヒットしますが、概ねrootを取ってあることが前提のようです。

幸い、現在使用しているAndroid7.1.1のadb shellコマンドはroot権限で動作するようなので(adb shellのプロンプトが#になります)、以下のコマンドでシャットダウンが可能でした。
adb shell am start -a com.android.internal.intent.action.REQUEST_SHUTDOWN
adb shell am start -n android/com.android.internal.app.ShutdownActivity
さらに、Android4.4以降は
adb shell setprop sys.powerctl shutdown
でもシャットダウン可能です。

その1:ターミナルアプリのインストール


とは言え、シャットダウンする為だけにPCを立ち上げ、コマンドを叩くのも面倒です。

なんとかRaspberry Piだけでシャットダウンできないかと考え、adb shellを実行しているならターミナルアプリをインストールして、上記コマンドを実行すればいいんでは無いかと考えテストしてみると。

amを利用するものはAndroidの権限で弾かれてしまいましたが、setpropを利用するケースは問題なくシャットダウンしてくれました。

これで、わざわざPCを立ち上げなくてもRaspberry Piだけでシャットダウンしてから電源を切れるようになりました。

その2:ShutdownPiの作成


とは言っても、毎回ターミナルアプリを立ち上げてコマンドを入力するのは面倒です。ワンクリックでシャットダウンしたいものです。

ということで、Kotlinの勉強も含めてシャットダウンアプリを作成することにしました。

以下はメインとなるダイアログ部分のソースです。ダイアログを表示して、シャットダウン/リーブート/キャンセルを選択できるようにしてあります。

package com.example.keiichimaru.shutdownpi.dialog

import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.support.v4.app.DialogFragment
import android.support.v4.app.FragmentManager
import android.support.v7.app.AlertDialog
import android.util.Log
import com.example.keiichimaru.shutdownpi.R

class DlgShutdownConfirm(context: Context) {
    private val mContext: Activity? = if (context is Activity) context else null

    companion object {
        const val TYPE_SHUTDOWN = "shutdown"
        const val TYPE_REBOOT = "reboot"
    }

    fun show( manager: FragmentManager, tag: String?) {
        val dialog = DlgShutdownConfirmDialog()
        dialog.onRebootButtonClickListener = DialogInterface.OnClickListener { _, _ ->
            finishActivity()
            doShutdown(TYPE_REBOOT)
        }
        dialog.onShutdownButtonClickListener = DialogInterface.OnClickListener { _, _ ->
            finishActivity()
            doShutdown(TYPE_SHUTDOWN)
        }
        dialog.onCancelButtonClickListener = DialogInterface.OnClickListener { _, _ ->
            finishActivity()
        }
        dialog.show(manager, tag)
    }
    private fun finishActivity() {
        requireNotNull(mContext) {"DlgShutdownConfirm initialize error."}
        mContext.finishAndRemoveTask()
    }
    private fun doShutdown(type: String) {
        require((type == TYPE_SHUTDOWN) or (type == TYPE_REBOOT)) { "type required $TYPE_SHUTDOWN or $TYPE_REBOOT." }
        val command = arrayOf(
            "sh",
            "-c", "setprop sys.powerctl $type"
        )
        val runtime = Runtime.getRuntime()
        try {
            Log.d(DlgShutdownConfirm::class.qualifiedName, command.reduce { s1, s2 -> "$s1 $s2" })
            val process = runtime.exec(command)
            val result = process.inputStream.bufferedReader().use { it.readText() }
            Log.d(DlgShutdownConfirm::class.qualifiedName, result)
            process.waitFor()
        } catch (e: InterruptedException) {
            e.printStackTrace()
        }
    }
    class DlgShutdownConfirmDialog : DialogFragment() {
        override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
            val builder = AlertDialog.Builder(activity!!)
            builder
                .setMessage(R.string.dlg_shutdown_msg)
                .setNeutralButton(R.string.dlg_reboot, onRebootButtonClickListener)
                .setNegativeButton(R.string.dlg_shutdown, onShutdownButtonClickListener)
                .setPositiveButton(R.string.dlg_cancel, onCancelButtonClickListener)
            return builder.create()
        }
        internal var onRebootButtonClickListener: DialogInterface.OnClickListener? = null
        internal var onShutdownButtonClickListener: DialogInterface.OnClickListener? = null
        internal var onCancelButtonClickListener: DialogInterface.OnClickListener? = null
    }
}

MainActivityは以下の通りです。
アプリが起動されると、画面は表示せずに確認ダイアログを表示してシャットダウンします。

package com.example.keiichimaru.shutdownpi.dialog

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import com.example.keiichimaru.shutdownpi.dialog.DlgShutdownConfirm

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // setContentView(R.layout.activity_main)
        DlgShutdownConfirm(this).show(supportFragmentManager, MainActivity::class.qualifiedName)
    }

}

2019年2月25日月曜日

Raspberry Pi 3b+でLineageOS 15.1を動かす

前回、Raspberry Pi 3b+でLineageOS 14.1 (Android 7.1.2)をインストールしてみましたが、Scratch Jrのマウスクリックができずに挫折してしまいました。今回、LineageOS 15.1(Android 8.1.0)を見つけたので、再度チャレンジしてみました。

ステップ1:LineageOS 15.1インストール


インストールそのものは簡単です。システムイメージをダウンロードして、マイクロSDカードに書き込んで、Raspberry Piで起動するだけです。

LineageOSの嬉しいところは、F5の長押しで、電源OFFかリブートのメニューが出て安全に電源を切ることが出来ることです。
スマフォでしたら電源ボタン長押しで電源を切ることができますが、Raspberry Piには電源ボタンがないので、電源そのものをOFFにするしかないことです。この場合、SDカードへの書き込み中だとシステムが壊れる可能性もあるので、安全を考えるならshutdownをしてから電源を切りたい所です。
rootが取れれば電源OFF用アプリをインストールできますが、現在Raspberry Piで動いているAndroid 7.1.1ではrootを取るのことは出来ませんが、adb shellがroot権限で動くようなので、別端末から「adb shell setprop sys.powerctl shutdown」で電源を切るようにしています。

ステップ2:Google Play Storeのインストール


こちらもホームページに導入手順が書いてありますので、そのまま実行すればGoogle Play Storeが使えるようになります。
事前準備としては
  • Settings -> Developer options -> Root accessでadbとappにRoot権限を与える
  • Settings -> Developer options -> Local terminalでターミナルを使えるようにする
  • ブラウザを立ち上げて必要なファイルをRaspberry Piにダウンロード
ここで、ともかくやたらと設定が落ちます。この時点で、使い物にならないと諦めてしまいそうになります。コツとしてはスクロールはマウスで行わずに、上下矢印(↑↓)を使って、ゆっくりと行うことがポイントです。どうやらListViewで画面スクロールをする時に処理が追いつかずに落ちている感じです。↓しては待って、また↓して待ってと、ひたすら我慢で使いこなしてください。

準備ができたらTWRPへブートし直します。これもFAQに方法が書かれていますが、ターミナを立ち上げて
su
rpi3-recovery.sh
を叩いて、再起動します。




TWRPのメニュー画面です。
まずは、ダウンロードしておいたGappsをインストールします。
「Install」ボタンを押して






Downloadをクリックすると









ファイルがあるのを確認してクリック後「Install Image」ボタンを押します。









「Swipe to confirm Flash」を右にスワイプしてインストール開始です。









インストールが終わったら、
「Wipe cache/dalvik」を押すと










右にスワイプしてキャッシュのクリアを行います。









キャッシュのクリアが終わったら、続けてFactory resetを行うので「Back」でTOPメニューに戻ります。







TOPメニューで「Wipe」ボタンをクリックすると、この画面が表示されるのでスワイプしてFactory resetを行います。







Factory resetが完了したら、Androidが起動するように起動時設定を変更するために「Back」ボタンでTOPメニューへ戻ります。






TOPメニューで「Mount」ボタンを押して、Systemのマウントを行います。








OKでマウントします。










TOPメニューから「Advanced」を選択して、「Terminal」を開きます。









「rpi3-recovery.sh boot」で起動設定を変更して、TOPメニューへ戻ります。








最後にTOPメニューから「Reboot」を選択して、「System」を再起動します。










ステップ3:Scratch Jrのインストール


再起動後は、Play Storeがインストールされているので、ログインすることでScratch Jrのインストールが可能です。

ただ起動してみると、やはりマウスクリックが効きません。Android 7.1.1では問題なく動いているのでアプリ側の問題ではなさそうです。

そこで
add connect [Raspberry PiのIPアドレス] ・・・adbで接続
adb shell wm size                    ・・・画面サイズの表示
adb shell input mouse tap [x] [y]    ・・・マウスクリックのシミュレーション
で、概ねの座標からボタンをクリックさせると、問題なく動きました。でも、物理的なマウスでクリックしても動かないんですね。

ということで、システム全体の動作ももっさりしていますし、マウスクリック問題があるので、やはり使い物にはなりませんでした。Raspberry Pi 4が出て、処理能力がさらにアップすれば使えるようになるかな?







2019年2月11日月曜日

Raspberry Pi 3B+でScratch Jrを動かす

2020年から小学校でプログラミング教育を行うということで教育関係ではそれなりに混乱されているようです。そんな中でバズワードとしてScratchが浮上し、Scratchの入門編としてScratch Jrもあちこちで聞くようになってきました。
ScratchについてはRaspberry Piで動くことは実証済みですが、Scratch Jrは動作環境がiOSまたはAndroidということでRaspberry Piでは動かすことはできません。

とは言えRaspberry PiでAndroid OSを動かしてみた方もたくさんいますし、ビジネスとして展開している会社もあるようです。そこで、我が家のRaspberry Pi 3B+にAndroidを導入してその上でScratch Jrを動かしてみたいと思います。

ステップ1:Raspberry Pi で動くAndroid


まずはRaspberry PiでAndroid OSを動かしている例を検索してみると。
といったところが出てきます。

結論から言うと、現在は一番上のページを参考にしてRaspberry Pi 3B+にAndroid7.1.1を導入してScratch Jrを動かしています。

☆ emteria.OS
企業がビジネスとして公開しているので無償版といえ安定して動いてくれました。ただ、マーケットアプリがF-DroidということでScratch Jrは登録されていませんでした。また、個人使用なら無償ですが、ビジネスで使用するとなるとライセンスが必要なのも注意点でしょうか。Play Storeのインストールは試してみませんでしたが、sshサーバが無償版では使えなかったりと自由にカスタマイズするのは難しそうです。

☆LineageOS 14.1
WikipediaによるとCyanogen Inc.が開発していたCyanogenModというAndroidをカスタマイズしたOSが元になっているそうです。
OSをインストールした状態ではPlay Storeはインストールされいませんが、こちらの方法でインストールは可能なのでScratch Jrのインストールも問題なくできました。
ただ、残念なのはScratch Jrを起動したところ初回の利用場所設定画面でマウスクリックができずに先に進めず、Scratch Jr利用することはできませんでした。

☆Android 7.0 Nougat on Raspberry Pi 3
インストールは問題ありませんでしたが、起動後に設定画面を開こうとしたところ設定が終了してしました。

ステップ2:Raspberry Pi3にScratch Jrをインストール


先ほどの参考ページにもありますが、元ページはこちらになります。ほぼ元ページの作業手順で問題なくPlay Storeのインストールまで出来ました。

参考ページでは有線接続の時のIPアドレスの確認方法がわからないとありますが、Android起動後、設定>端末情報>端末の状態で確認できますし、あらかじめRaspberry Pi 3をrasbianで立ち上げてIPアドレスを確認しておいても良いと思います。

今回、時間がかかったのが画面表示のところでした。今回は古いSharp LL-173Cというディスプレイを使っていましたが初めは真っ黒で何も表示してくれませんでした。
この場合、AndroidをインストールしたSDカード内の/boot/config.txtを編集するのですが、Androidを起動した状態では編集できない(そもそも画面が真っ黒です!)ので、Windows等で編集する必要があります。

Sharp LL-173C、DELL E2014H、Panasonic TH-32LX70(液晶テレビ)で画面表示できるようにしましたが、その時の設定を以下に示しておきますので、画面が真っ黒になった時には参考にしてください。直感的には最近のモニタであればデフォルト設定で問題なく表示されるのではないかと思います。
# DELL E2014H
#hdmi_group=2
#hdmi_mode=87
#hdmi_cvt=1600 900 60 6 0 0 0
#disable_overscan=1

# Panasonic TH-32LX70 4(720p),16(1080p)
#hdmi_group=1
#hdmi_mode=16
#disable_overscan=1

# Sharp LL-173C(OK=36,17,8)
hdmi_group=2
hdmi_mode=8
disable_overscan=1

Androidが起動直後は、言語設定が英語になっているので、設定>言語と入力>言語>言語の追加で日本語を追加して、日本語をドラッグして一番上に持って行きます。これで設定の表示なども日本語に切り替わります。また、設定>日付と時刻>タムゾーンで「日本標準時」を選択して日本時間にしておきます。

次にユーザ登録をしてからPlay Storeのインストールをしましょう。

ユーザ登録は設定>アカウント>アカウントを追加>Googleで、ユーザの追加をします。
私はAndroidが起動後すぐにPlay Storeのインストールをしたので、Play Storeインストールでユーザ登録が要求されましたが、うまく既存ユーザでの登録ができませんでした。

あとはScratch JrをPlay StoreからインストールすればRaspberry Pi 3でScratch Jrが利用できるようになります。

ステップ3:マウスポインターの解消


Raspberry PiにAndroidを導入したサイトをみてもマウスポインターが化けているとの報告(導入動画でもマウスがモヤモヤしています)がされています。Androidでは標準でマウスカーソルの表示(そもそもマウス全般)に対応して無いのが原因かと思いますが、以下の方法で解消できましたので、モヤモヤカーソルを解消した方は設定して見て下さい。
  • 設定>ユーザ補助>大きなマウスポインタをONに設定
ちょっと大袈裟なくらい大きくなってしまいますが、画面サイズからすればまあ許容範囲かなということで(笑)

ステップ4:Scratch Jrでの日本語入力


Scratch Jrは問題なく利用できたのですが、日本語の入力でちょっと問題がありました。

標準のJapanese IMEでは日本語キーボードのレイアウトがサポートされてませんし、入力ができたり、できなかったり、長い文章を入力するとおかしくなったりと不安定でした。そこで日本語入力をGoogle日本語入力に変更して、設定を一部見直したところ安定したようです。
  • Play Storeで「Google日本語入力」を検索して、インストールします。
  • 設定>言語と入力>仮想キーボード>キーボードを管理で、Google日本語入力をON、Japanese IMEをOFFに設定
  • 設定>言語と入力>仮想キーボード>Google日本語入力>入力>ハードウエアキーボードのキーマッピングで「日本語109A」を選択
  • 設定>言語と入力>仮想キーボード>Google日本語入力>入力で変換オプションを全てOFFに設定(CPU負荷を軽減するためです)
  • 設定>言語と入力>物理キーボードで「仮想キーボードの表示」をOFFに設定

最後に:使い物になるか?


今のところScratch Jrの操作感として、速度的には我慢どころかなという印象です。日本語入力も余り早いキータッチには追随できませんが、CPUの能力を考えれば致し方ないかなと思います。

音の出力は外部スピーカーを付けるか、テレビをモニタ代わりにすれば問題はありませんが、その場合はconfig.txtの設定が必要になるかもしれません。カメラとマイクの利用もUSB接続という方法もありますが、プログラムの勉強用なら特に無くても問題はないかと考えています。

今回はScratch Jrを動かすことが目的でしたが、他の学習用アプリもいくつかインストールして使ってみました。結果は、全てのアプリが使い物になりませんでした。起動しないアプリ、起動してもマウスクリックを受け付けなくて(全く受け付けない、画面の一部で受け付けないの2パターンがありました)操作ができないものなど、普通に使う範囲で問題が発生しました。

ちなみに、私が公開しているアプリもインストールしてみましたが、アプリそのものは動いているようですが、画面が真っ黒になりやはり使えませんでした。動作はしているようなのでテーマ絡みで画面が真っ黒になっているのではないかと想像しています。現在、Android 8.0対応を進めているので、落ち着いたら調べてみたいと思います。

そういった意味でScratch Jrは特に問題なく動いているのはすごいなという感想でした。

EXCELの表をKaTeX形式に変換するマクロ

生成AI時代にプログラミング言語を学習する必要はあるのか? 最近では生成AIがプログラムを作成する時代になってきましたが、そんな時代にプログラミング言語を学習する必要はあるのでしょうか? ということで早速 Google さんに聞いてみました。 生成AI時代にプログラミング言語を学...