M5Stack UnitV2 は実はメモリー(RAM)が256MBだった?

M5Stack UnitV2の外箱の裏のスペック欄 シールを剥がす前

今回の話は画像を見れば終わってしまう内容です。

上の画像をよく見てください。

M5Stack UnitV2の外箱です。

私の箱だけなのかどうなのかわからないのですが、MEMORY欄の”128MB DDR”と書かれた部分の”128MB”の部分がシールっぽくなっているのがわかりますでしょうか。

で、そのシールをそぉーっと剥がしてみました。

シールを剥がすと...

公式のスペックがRAMは128MBなので直前にスペックをアップでもしたのかなと思っていたのですが。

シールを剥がすとあらびっくり、”256MB”と書かれています。

  • 直前までメモリーのサイズが決まらなかった
  • 外箱を先に作った
  • 128MBのメモリーしか調達できなかった
  • 電力的/構造的な問題で128MB以上のメモリーは使えなかった

理由は上記のどれかでしょうか。

以前、仕事でこういうガジェット系の商品のパッケージの外箱を作っていたことがあるので、こういう後からのシール貼りってのは結構面倒なんだよなってのを思い出しました。

外箱を作ってしまったのにスペックに間違いがあって、急遽シールを貼らないと出荷できなくなり、東急ハンズでプリンタ用のシールを買ってきて、イラストレータでシールのデータを作って会社の印刷機で印刷して、カッターで切って自分たちで貼る、なんてことをやってました。

作業中はなんでこんなことやらんきゃならんのよ、これやってる時間あったら次のパッケージ作らなきゃ、サイトに「スペック間違っちゃったごめんね」って書くだけでいいじゃん、みたいに思ってました。

さらにスペック欄の訂正シールって大きすぎると隣の項目に被ったりして、微妙なサイズが求められるんですな。

だから貼るのも結構めんどいのです。

でもお客さんからしたら外箱に書いてあることは「ホントウノこと」なのでそうも行かないというのもよくわかります。

この外箱の訂正部分(256MB=>128MB)は下にストレージ容量の512MBと同じ文字数で書かれているので、作業中にストレージの512MBの上にシール貼っちゃったりして後で気づいて貼り直しなんてことをしたんだろうなと思います。

お疲れ様です。

外箱を作り直していたら出荷が1週間くらいは延びてしまうし、さらに既に外箱に製品を入れた後だったらそこから出して入れなおさなきゃならないんで、まあやっぱシール対応になりますね。

お疲れ様です。

メモリーが256MBあった方がよかったなと思ってこの記事を書いたのですが、無事出荷できてよかったねという思いの方が強くなりました。

以上。

M5Stack UnitV2 で静止画を撮影する(python直叩き)

以前httpリクエストでM5Stack UnitV2で静止画を取得する方法を書きましたが、今回はUnitV2内でpythonを直に叩いて静止画を取得する方法です。

まずshot.pyをPCにダウンロードしてから下記のコマンドを叩いてください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# @PC UnitV2にsshでログイン
$ ssh m5stack@unitv2.py

# @UnitV2
$ sudo chmod 666 /dev/null

## いったんログアウトするか、新しいターミナルをPCで立ち上げる ##

# @PC
$ scp <ファイルを置いたディレクトリ>/server_core.py m5stack@10.254.239.1:/media/sdcard/
$ ssh m5stack@unitv2.py

# @UnitV2
$ sudo mv /media/sdcard/shot.py ~/payload/

## 画像認識用サーバーが起動している場合はJupyter Notebook モードにする ##

# @UnitV2 撮影
## 最後にファイル名が表示されるのでそれをメモ(※1) => /media/sdcard/に保存される
$ sudo python3 ~/payload/shot.py

## ログアウトするか新しいターミナルをPCで立ち上げる

# @PC
# PCのカレントディレクトリにjpg画像がコピーされる
$ scp m5stack@10.254.239.1:/media/sdcard/<※1でメモしたファイル名> ./

以上です。

pythonコマンドを叩く前に、画像認識用サーバーが起動している場合はJupyter Notebook モードにしてください。メモリー不足?のためコマンドがエラーになります。

Jupyter Notebookモードでもなんらかのnoteが起動しているとダメなので、JupyterNotebookの画面から個々のnoteをshutdownしてください。

それでもダメであれば、Jupyter NoteBookを落としてください(ページ右上のQuitで落とせると思います)。

これでUnitV2でサーバーとかを使わず静止画が取得できます。

ただ、フルHD(1920x1080)の画像が取得できると思ってましたが、最大サイズはフルじゃないHDサイズ(1280 x 720)のようです。

【続】 私はunko派

以前私はunko派という記事を書いた。

今回の記事はその続報です。

2019年時点の”unko”と”unco”のGoogleにおける検索結果数は下記の通りであった。

  • 2019年11月19日くらい
    • “unko”: 21,400,000件
    • “unco”: 22,700,000件

unco派が100万ポイントくらいリードしていた。

  • 2021年6月24日
    • “unko”: 3,860,000件
    • “unco”: 3,690,000件

だが、しかし今回はunko派が10万ポイントくらいリードしている。

unkoが逆転した。

ん、待てよ、そもそもunkoもuncoも全体で一桁分ポイントが減っている。

Googleの検索結果数はかなり適当なので、そもそも信用していいのかわからないものだが一桁もポイントが下がるとは尋常ではない。

大丈夫か。

で、気になったのが前回の記事でも紹介した株式会社うんこである。

この会社は生粋のunco派であり、unco派の筆頭である。何故なら会社のサイト名がunco.co.jpなのだ。

久々にページを見てみると、うんこTシャツを着た人たちのイラストは変わっていない、”うんこ発射”ボタンも健在だ。

会社概要も変わっていない、よかった、元気そうだ。

公式ショップには可愛いうんこのマスクやTシャツが出品されている。

ボーナスも出たことだし買ってしまおうか。

サイトを見ていて、うんこ新聞というページを見つけた。

前もあったような記憶があるが、発行日が書いてないので前に見たとき(2019年の11月)にあったのかはよくわからない。

株式会社うんこの社長が書いているようで、不定期で連載されているようだ。

PCのお絵かきソフトで書いたような絵と縦書きの文字で構成されていて、学級新聞のような感じ。

これが非常に面白い、「うんこ新聞 その16」のサイゼリヤみたいなレストランでの話しかちゃんと読んでないが、残りを読むのが非常に楽しみである。

私は株式会社うんこの社長はこの新聞を世に出したかっただけでこの会社を立ち上げたのではないのか?ぐらいの勢いのあるなんかを感じる。

今後にさらに期待、ぶりっ。

東京オリンピックやるのか問題

東京オリンピックの開催予定日まで1か月を切った。

このままなし崩し的に開催となってしまうのだろーか。

「1964年のオリンピックの夢を今に」みたいなのがとってもとってもダサい、高度経済成長期に成功したイベントを今やることによって景気をよくして不況を脱出する!みたいなのがほんとにダサい、ダサすぎて私はうんこが漏れそうになる。

私は1964年のオリンピックも経験してないし、さらにロストジェネレーションとか言われて腹が立っている世代なので、そんなもんいらない。

私は別にやりたい人だけでやってれば文句ないのだが、今はコロナが流行っている。

コロナが流行してないなら私には無関係なので自由にやってくださいということなのだが、こちらは1年以上リモートワークを続けていて外食なんかもほとんどしてない。

オリンピックを開催して流行がさらに拡大したら籠っていなければいけない期間がさらに延びる、そのことに私は怒ってる。

あと、「偉大だった日本を取り戻す!」みたいな雰囲気がもうホントにイヤだ。

まず、そもそも偉大だったのか?

何で偉大じゃなきゃいけないの?

それって、大日本帝国がアジア太平洋地域で戦争を拡大させていったのと同じような考え方だよね。

オリンピックやるくらいなら横浜博覧会でももう一度やってくれ。

私はあの時小学校4年生だった。父と横浜のみなとみらいに行って非常に楽しかった思い出がある。

あの時はバブルがはじける前で、世の中には「希望」と「夢」が溢れているみたいに少年時代の私には見えていた。

って、でも、やっぱそいういノスタルジーというか、昔はよかった、懐かしいねーみたいなのを国をあげてやったらダメだよね。

AndroidにTermuxを入れてSSHで入ってLinux環境を作る【まとめ版】

このブログでTermuxを使ってAndroidにLinux環境を作る話を何個か書きました。

上記のように似たような記事ばかりで書いた私もよくわからなくなりました。

TermuxでLinux環境を作るために自分のブログを調べても混乱するばかりなので今回は総まとめというか、私にとって必要な部分だけを今回の記事でまとめときます。

0.前提条件

今回のまとめはWi-Fi環境下で行います。ADBを使ってもできますが、ADBはインストールと接続が煩雑なので今回は取り上げません。

条件は下記のとおりです。

  • Android端末とPCが同じWi-Fi内にいる
  • PC側にターミナル的な環境がある
  • PC側でSSHクライアントが使える

1.Androidにアプリのインストール @Android

まず、Android端末にTermuxアプリをインストールします。

Android端末で”Google Play”を起動し、Termuxをインストールします。なおTemux:APIはAndroidのカメラとかを使うためのアプリなので入れなくても大丈夫です。

次にキーボードアプリをインストールします。
下記のどちらかのキーボードアプリがおすすめですが、私はCodeBoardを使っています。

AndroidでTermuxを起動したらまず下記のコマンドを打って最初のセットアップを行います。
この際、先ほどインストールしたキーボードアプリ(CodeBoardとか)を使います。
デフォルトのAndroidのキーボードが表示されると思うのでスペースを長押ししてキーボードを変更してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# @Android

# /data/data/com.termux/files/home(~)にstorageディレクトリを作る
$ termux-setup-storage

# パッケージのアップデート
$ pkg update
$ pkg upgrade

# よく使いそうなパッケージのインストール
$ pkg install vim
$ pkg install git

# Temux:APIを使うのであれば
## Google Play で Termux:API をインストールしておく必要あり
$ pkg install termux-api

2.Termux側にSSHの設定をする

TermuxにOpenSSHサーバをインストールしてIPを確認します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# @Android

# OpenSSHサーバのインストール
$ pkg install openssh

# OpenSSHサーバーの起動
$ sshd

# IP確認
$ ip -4 a
## inet 192.168.1.x/24 という表記の192.168.1.xの部分がIPになります

# ユーザー名確認
$ id
## uid=xxxxx(u0_axxx) という表記のu0_axxxがユーザー名になります

# パスワード設定 これでパスワードを設定します、適当なパスワードを設定してください
$ passwd

3.PC側からTermuxにログイン

以降はPC側からAndroidのTermuxに入るので操作はPC側から行います。

下記のようにパスワードでログインします。

1
2
3
4
5
6
# @PC

# ユーザー名: u0_axxx, ip: 192.168.1.1の場合
$ ssh -p 8022 u0_axxx@192.168.1.1

# パスワードを聞かれるので先ほどTermux側でpasswdで設定したパスワードを入れる

なお、パスワードを使わず公開鍵認証でSSHログインしたい場合は下記のように行ってください。
パスワードを毎回使っても大丈夫と言う方は下記は飛ばして4に行ってください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# @PC
$ cd ~/.ssh
$ ssh-keygen -t rsa -b 2048 -f <名前>
## 公開鍵:名前.pub
## 秘密鍵:名前
## が生成される
# scpで公開鍵をコピー
$ scp ~/.ssh/名前.pub u0_axxx@192.168.1.1:~/

# .ssh/configに下記を記述
Host ssh2android
HostName 192.168.1.1
User u0_axxx
Port 8022
IdentityFile ~/.ssh/名前
ServerAliveInterval 60


# @PC PCからTermuxにSSHでログインしてから下記を叩く
$ cat ~/名前.pub >> ~/.ssh/authorized_keys
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys

この設定をしておけば次回以降PCからは$ ssh ssh2androidでログインできます。

4.TermuxにLinuxをインストールして起動

LinuxのインストールはAndroidにまともなターミナル環境(Ubuntu on Termux)を作った話で紹介されているUbuntuをインストールする方法を使用します。

1
2
3
4
5
6
7
# @Termux from SSH on PC
# 下記コマンドはホーム(~)でやることを想定しています
# https://nombi.info/posts/computer/uot/ より一部引用
$ pkg install wget openssl-tool proot -y
$ hash -r
$ wget https://raw.githubusercontent.com/EXALAB/AnLinux-Resources/master/Scripts/Installer/Ubuntu/ubuntu.sh
$ bash ubuntu.sh

上記の方法はAnLinux-ResourcesのUbuntuを使用する方法です。このレポジトリにはUbuntu以外にもAlpineやKali Linuxもあるようなのでそちらを使っても行けると思いますが、私はテストしていないので何とも言えません。

その際は上記のコードのUbuntuの部分を当該のLinuxの名前に書きかえればよいと思います。

5.Termux内にLinuxを起動

最後に下記コマンドを叩きます。

1
$ ./start-ubuntu.sh

これでUbuntuが起動します。

また、Termux起動時にOpenSSHサーバーとLinux(Ubuntu)を起動しておきたい場合は下記のコードを~/.bashrcに書いておきます。

1
2
sshd
./start-ubuntu.sh

これでTermuxを起動するとOpenSSHサーバーとLinux(Ubuntu)が起動するのであとはログインするだけとなります。

以上。

Termux上にLinuxマシンをとても簡単にインストールする

結構前にAndroidにTermuxを入れてさらにその中にDebianを入れるという方法を紹介した。

debootstrapを入れてシェルスクリプトを作ってごにょごにょするというものだったが、もっと簡単にできる方法を紹介しているブログがあった。

それが、こちら。Androidにまともなターミナル環境(Ubuntu on Termux)を作った話

termuxにログインしたあと、下記の4行のコードだけでUbuntuがインストールできるようだ。

1
2
3
4
5
# https://nombi.info/posts/computer/uot/ より一部引用
$ pkg install wget openssl-tool proot -y
$ hash -r
$ wget https://raw.githubusercontent.com/EXALAB/AnLinux-Resources/master/Scripts/Installer/Ubuntu/ubuntu.sh
$ bash ubuntu.sh

AnLinuxというアプリのソースを使ってインストールをするようだ。

なお、$ bash ubuntu.shでのインストールは私のZenfone 3 Laserで20分くらいかかった。数年前のデバイスなので最近のデバイスであればもう少し速く終わるはず。

インストール完了後に$ ./start-ubuntu.shでUbuntuが起動する。

さらに上記のブログにはユーザーの作り方とかも詳しく書かれているので色々参考になる。

私もこれぐらいちゃんと書きたい、なので気になった方というかそもそも最初からAndroidにまともなターミナル環境(Ubuntu on Termux)を作った話を見てください。

M5Stack UnitV2 で起動時にJupyter Notebookを立ち上げる方法

M5Stack UnitV2を電源に接続して起動するとデフォルトで入っている画像認識のサーバーが起動して、画像認識のサンプルページ(10.254.239.1)が見られるようになります。

Jupyter Notebookを起動するにはページの右上の設定ボタン「Notebookに切り替える」みたいなボタンを押すことで画像認識用のサーバーが落ちてJupyter Notebookが起動します。

Jupyter Notebookを起動するには毎回この切り替え作業を行わなくてはならないのは煩わしいです。

下記がM5Stack UnitV2起動時に画像認識のページではなくJupyter Notebookを起動する方法です。

PCとUnitV2をUSB LANで接続して下記のコマンドを叩きます。

なお、UnitV2でsudoを使えるようにしている必要があります。sudoを使えるようにする方法はこちら

1
2
3
4
5
# @PC
$ ssh m5stack@10.254.239.1

# @M5Stack UnitV2
$ sudo vi ~/payload/server.py

viの編集モードになるので下記の行(29行目付近と45行目付近)を探します。

1
process = subprocess.Popen(['python3','server_core.py', str(os.getpid())], stdout=subprocess.PIPE, stdin=subprocess.PIPE, close_fds = True, bufsize = 1)

'server_core.py'の部分を'run_notebook.py'に変えます。

こんな感じになればOKです。

1
process = subprocess.Popen(['python3','run_notebook.py', str(os.getpid())], stdout=subprocess.PIPE, stdin=subprocess.PIPE, close_fds = True, bufsize = 1)

保存して抜けます(Esc => : => wq => Enter)。

下記のコマンドを叩きます。

1
$ sudo reboot

これでM5Stack UnitV2の起動時にJupyter Notebookが立ち上がるようになります。

画像認識のページに戻したい場合は~/payload/server.pyの記述を元に戻せばOKです。

SCPでM5Stack UnitV2 にファイルを持っていったり持ってきたりする

以前書いたM5Stack UnitV2の記事の続きです。

なお、sudoコマンドを使用するため、この記事の方法でsudoを使えるようにしておく必要があります。

PCとUnitV2をUSB LANで接続して下記のどちらかのコマンドを叩きます。

1
2
3
4
5
6
# Unitv2 => PC にコピー
$ scp m5stack@10.254.239.1:/media/sdcard/sample.file ~/

# PC => UnitV2 にコピー
# コピー先は/media/sdcard/がオススメ
$ scp ~/sample.file m5stack@10.254.239.1:/media/sdcard/

するとCouldn't open /dev/null: Permission deniedというエラーが表示されコピーができません。

下記のようにSSHでUnitV2に入り/dev/nullのパーミッションを確認します。

1
2
3
4
5
6
7
# @PC
$ ssh m5stack@10.254.239.1

# @M5Stack UnitV2
$ ls -la /dev/null
# 下記のように表示される
crw-rw---- 1 root root 1, 3 Jan 1 00:00 /dev/null

rootユーザーかrootグループは読み書きが可能となっています。

m5stackユーザーはrootグループではないので/dev/nullの読み書きができないということです。

試しに$ idコマンドを叩くとm5stackユーザーはwheelグループに属しています。

wheelはグループはsudoが叩けたり、suでrootユーザーにログインできる権限を持ったグループのようです。

M5Stack UnitV2でsudoできるようにしたからwheelグループになっているかはわかりませんが、scpコマンドでsudoを叩くことができないので/dev/nullに対してroot権限でゴニョゴニョできないということです。

なのでscpしたい場合は下記のコマンドを叩きます。

1
2
3
4
5
# @PC
$ ssh m5stack@10.254.239.1

# @M5Stack UnitV2
$ sudo chmod 666 /dev/null

これで、PCからUnitV2へのコピー、UnitV2からPCへのコピーができるようになります。

なおUnitV2にコピーする場合はパーミッションが777になっている/media/sdcard/にまずはコピーしてからmvする方法がオススメです。

でもscpでPermission deniedになるファイルを無理やり転送するというような方法もあるようです。

この方法ならsudoが使えるのでうまく行きそうです。

今度試してみます。

上記のscpでPermission deniedになるファイルを無理やり転送するは接続元でPermission deniedになる場合に使える方法で、接続先でエラーになる場合の方法ではなかったようです。

M5Stack UnitV2 で静止画を撮影する(http方式)

今回紹介するのはM5Stack UnitV2で静止画像をキャプチャする方法です。

UnitV2を起動してhttp://10.254.239.1/video_feedを叩けばストリーミング映像が取得できますが、静止画ではありません。

静止画を取るパスがないか探しましたがどうにもないようなので強引にsever_core.pyを改造してみました。

まず78行目付近にcurrent_imgというグローバル変数を追加しました。

1
2
3
4
# ~~~ server_core.py 78行目付近~~~
pipe_img_rx_queue = queue.Queue(10)
current_img = None #<= ココ
pipe_msg_rx_queue = queue.Queue(10)

そして203行目付近でvideo_feed用のキューに画像を詰め込んでるところの前でcurrent_imgにも画像を入れます。

1
2
3
4
5
6
# ~~~ server_core.py 203行目付近~~~
if pipe_img_rx_queue.qsize() >= 10:
continue
current_img = frame #<= ココ
pipe_img_rx_queue.put(b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

最後に/image_shotというパスに対応したメソッドを作成します。switchFunctionを呼んでcamera_streamにモードを変更して映像の取得を開始させます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ~~~ server_core.py 596行目付近~~~
@app.route('/image_shot')
def image_shot():
# global current_img, process, client_is_connected, process_name
global process, client_is_connected
client_is_connected = True
if not process is None:
process.stdout.flush()
time.sleep(1)

if process_name != "camera_stream":
switchFunction('camera_stream', "")
time.sleep(3)
else:
switchFunction('camera_stream', "")

pipe_img_rx_queue.get()
pipe_img_rx_queue.task_done()

return Response(current_img, mimetype='image/jpeg')

改造したserver_core.pyはこちらです。これをUnitV2と接続したPCにダウンロードしてきます。

M5Stack UnitV2への適用方法

  1. PC => UnitV2へserver_core.pyをコピー

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # @PC UnitV2にsshでログイン
    $ ssh m5stack@unitv2.py

    # @UnitV2 /dev/nullのpermissionを変えないとscpできない
    $ sudo chmod 666 /dev/null

    # @PC PCからUnitV2へscpでファイルをもっていく
    # コピー先を/media/sdcardにしたのは~/だとm5stackユーザーが直で置けないため、m5stackユーザ用のディレクトリをどこかに作ってもいい
    $ scp <ファイルを置いたディレクトリ>/server_core.py m5stack@10.254.239.1:/media/sdcard/

    # @UnitV2 一応置き換える予定のserver_core.pyをリネームしておく
    $ sudo mv ~/payload/server_core.py ~/payload/_server_core.py

    # @UnitV2 server_core.pyを~/payload/に持っていく
    $ sudo cp /media/sdcard/server_core.py ~/payload/

  2. M5Stack UnitV2を再起動する。USBを再接続でもいいと思いますが、私はsudo haltしてからUSBを抜き差ししています。

  3. M5Stack UnitV2が再起動したら http://10.254.239.1/image_shot を叩くと画像が表示されます。

コピーするのがめんどくさい場合は、sshでUnitV2にログインしてインストールされているviなどを使って当該箇所を書き換えてください。sever_core.py内のcurrent_imgという変数が使われている箇所を持ってくれば動くはずです。

課題

かなり強引に実装したので課題点が結構あります。

  • 画像サイズを自由に変えたい
  • ストリーミングの処理に乗っかるのではなく、単体の静止画取得メソッドを作りたい
  • shot_image.pyみたいなファイルにして直接ファイルを実行させたい
  • ブラウザを叩いてから戻ってくるまで数秒待つので、もっと速くしたい

また、間違っているところがあるかもしれないのでその場合はお問い合わせかgithubのプルリクで知らせてください。

M5Stack UnitV2 の映像をVLCプレーヤーでストリーミング再生する

M5Stack UnitV2でストリーミング再生する方法です。

  1. M5Stack UnitV2とPCをUSBで接続
  2. WindowsかMacの場合は公式のDriver Instrationを参照してドライバをインストール
  3. USB LANとして認識されるのを待つ(30秒くらい?)
  4. PCでブラウザを開きhttp://10.254.239.1/video_feedを開く

以上!

でもこれだとhttp://10.254.239.1/をブラウザで開いたのと大差ないのでVLC Media Playerで再生する方法が下記です。

  1. VLC メディアプレイヤーを開き”ネットワークストリームを開く”でURL蘭にhttp://10.254.239.1/video_feedを入れるもしくはターミナルでvlcコマンドが叩けるのであれば$ vlc http://10.254.239.1/video_feedでVLCが起動してストリーミング再生します。