2022年の投稿(時系列順)[21件]
2022年1月 この範囲を新しい順で読む
Tweet ⌚ 2022年1月2日(日) 17:50:47 日記 <260文字>
Windows の BAT ファイルで CGI しよう
ぺけぽんっていうか Windows XP の頃にあまりにも怒り心頭になって勢い Microsoft に三行半を叩きつけてからずっと Linux な生活の日々なんですが…まぁそうは云いつつ Windows も使える事をアピールしておかないとオファーが来ないんでって感じなんで今回は Windows 的な話題っていうか BAT ファイルを CGI にしちゃおう!って解説です(汗
つーか初っ端から言い訳を並べるっていうか…我が家の Windows 機は 2015 年くらいに発売された 2 万円くらいの 8 型 Windows 10 タブレットって事なんでものすっごい低スペックです リソースなんて OS を起動するだけで使い果たしちゃう感じなんで新たにアプリケーションとか入れる余裕が全くありません なんか Windows でも CGI を動かす時は Perl や Python なんかを導入してるようですが…そんなんが入る空きなんてこれっぽっちも無いんで「それじゃ今あるもので何とかするか」ってことで標準的に使える BAT ファイルを引っ張り出してきた感じですかね(泪
世間的には Windows の Web サーバは Apache や IIS がよく使われている感じ?らしいですが…もちろんその辺を入れる余裕がないんで軽量コンパクトな Web サーバとして有名だった AN HTTPD を microSD に入れて一時的なテスト環境をざっくり構築してみました ただ AN HTTPD はかなり前に開発が終了しちゃってるらしく正規のルートでは配布されていないらしい? まぁとりあえず anhttpd download なるキーワードでぐぐってみたらどうにかなったけどお約束っていうかこの辺は自己責任でお願いします
:
あーあと殆ど大半の方には関係のない話っていうか Windows の BAT ファイルを Linux で作ろうとすると色々と不都合が発生するようです…いや発生しました ごくシンプルにっていうか @echo off とだけ書いた BAT ファイルすら動かない致命的な不都合でありつつ原因に気付くまで結構かかりました orz
まずは改行コードです Windows 系列の改行コードは「CR+LF」なのに対して Linux 系列の多くは「LF」のみとなっていて…この改行コードの違いが問題になります ちなみに Mac OS では「CR」な改行コードを吐くものもあるとか??
Windows のみで開発していれば(ほぼ)気にする必要はないようですが…他の OS 上で書いた場合は改行コードの違いに要注意です
お次は文字コードです これもうっかりやらかしたっていうか Linux 上で何気に UTF-8 で書いた BAT ファイルを Windows に持ってきてテストしたらうまく動きませんでした
この文字コードの問題は改行コード以上に呪わしいっていうか…例えば Windows 標準の「メモ帳」を使用したとしてもバージョンの違いによりデフォルトの文字コードが Shift-JIS (ANSI) だったり UTF-8 だったりするので注意する必要があります
なお我が家の Microsoft Windows [Version 10.0.19042.1348] に付属のメモ帳ではデフォルト文字コードが UTF-8 だったようですが…いつの間にかメモ帳も進化したのか保存時に文字コードを選択できるようになってました ちなみに ANSI ってやつが Shift-JIS っぽいですね
つーかそもそもコマンドプロンプトで使用する文字コードが Shift-JIS (ANSI) だって保証がどこにも無いみたいです 我が家は(たぶん)何も設定していないので Shift-JIS (ANSI) になってましたが…これを他の文字コードに設定することも可能のようです
単に現在の文字コードを確認するだけなら「コマンドプロンプト」のタイトルバーを右クリックして「プロパティ」を参照するといいでしょう
もし他の文字コードに変更したい場合は chcp コマンドを使います 単に chcp とした場合には現在の設定値を表示します 変更したい場合は chcp 番号 という感じで番号を指定します 代表的なものだと「ANSI/OEM 日本語;日本語 (shift-jis) が 932」で「EUC 日本語が 51932」で「Unicode (UTF-8) が 65001」となるようです この辺の コードページ識別子の一覧 が公式(?)にあったんで参考になるかも? ちなみになんか面倒くさそうだったんで実際に変更して試してないんで今後は Shift-JIS (ANSI) で話を進めます(瀧汗
:
さて…その辺の注意事項もろもろを無事にクリアしたところで実際に BAT ファイルを CGI として動かしてみましょう
とりあえず AN HTTPD に CGI の設定をしましょう…っていうか特に何もしなくても動くっぽい?
我が家では拡張子「.bat」に対する「実行プログラム」を「空欄」もしくは「c:\windows\system32\cmd.exe /c」で動作しました テストする環境が無いんで IIS (Internet Information Services) 等では試せてないのですが…おそらくそっちも「.bat」に対する設定で「(空欄)」もしくは「c:\windows\system32\cmd.exe /c」を設定すれば動くのかなーって思ってます この辺はどなたか実際に試して教えて頂きたい感じですね ※ご連絡頂いたんで…本記事の最下部くらいに設定法などを転載してあります
そんな設定が済んだ所で…それじゃ実際に BAT ファイルを作って試してみましょう 以下のバッチファイルを適切な改行コードと文字コードで保存した後に Web サーバのドキュメントルート以下に配置してブラウザからアクセスしてみましょう
----- bat_cgi01.bat -----
@echo off
REM ブラウザに「Content-type:」を出力する(単純なTEXTファイル用)
echo Content-type: text/plain; charset=Shift_JIS
echo.
REM Windows のバージョンを表示 ※空行も表示されている
ver
REM 環境変数に設定されている CPU の種類を表示
echo %PROCESSOR_IDENTIFIER%
echo.
REM 現在日時を date と time コマンドで表示
echo. | date
echo. | time
echo.
REM 必要な所だけ抽出してみる
echo. | date | find "現在の日付"
echo. | time | find "現在の時刻"
echo.
REM 環境変数でも現在日時を取得できるっぽい??
echo %DATE%
echo %TIME%
echo.
REM 日付が設定されている変数から「年月日」を取得してログファイル的なファイル名を作ってみる
echo %DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.log
----------
正しく動作すればこんな感じの内容がブラウザに表示されます
今回は単純なテキストを表示するのに適した「Content-type: text/plain; charset=Shift_JIS」で表示させてみました コマンドプロンプトを別の文字コードに設定している場合はここの「charset=」以降を適当なものに変更する必要があると思います
Linux の Web サーバだと実行属性がどうのこうのとかありますが Windows にはそんなものは無いので「.bat」の拡張子のものであればそれだけで動きます ちなみに大文字/小文字の区別も無いのでブラウザのアドレス欄で「BAT_CGI01.BAT」なんて大文字で指定しても動きます
※少なくことも我が家の AN HTTPD を使用した環境では動きました
※テストした環境が FAT32 ファイルシステムの microSD だったから大文字/小文字の区別がない? これが NTFS ファイルシステム上だと大文字/小文字を区別するの? どうなの??
さて…うまく動きましたか? 無事に動いたのなら次にいってみましょう
----- bat_cgi02.bat -----
@echo off
REM ブラウザに「Content-type:」を出力する(HTML出力用)
echo Content-type: text/html; charset=Shift_JIS
echo.
REM HTML なページとしてのお約束的なヘッダ部
echo ^<!doctype html^>
echo ^<html^>^<head^>^<title^>今日の運勢的な?^</title^>^</head^>^<body^>
echo 今日の運勢は…^<font color=red^>
REM コマンドの実行結果を変数に取り込む
for /f "usebackq delims=" %%A in (`echo. ^| time ^| find "現在の時刻"`) do set RAND=%%A
REM 「%RAND:~-1%」で変数の末尾 1 文字を取り出す
if %RAND:~-1% == 0 echo [%RAND:~-1%] ☆大吉☆
if %RAND:~-1% == 1 echo [%RAND:~-1%] 中吉
if %RAND:~-1% == 2 echo [%RAND:~-1%] 中吉
if %RAND:~-1% == 3 echo [%RAND:~-1%] 吉
if %RAND:~-1% == 4 echo [%RAND:~-1%] 吉
if %RAND:~-1% == 5 echo [%RAND:~-1%] 吉
if %RAND:~-1% == 6 echo [%RAND:~-1%] まぁまぁ
if %RAND:~-1% == 7 echo [%RAND:~-1%] 凶
if %RAND:~-1% == 8 echo [%RAND:~-1%] 凶
if %RAND:~-1% == 9 echo [%RAND:~-1%] 大凶(-_-;)
echo ^</font^>です^<br^>
REM HTML なページとしてのお約束的なフッタ部
echo ^</body^>^</html^>
----------
正しく動作すればこんな感じの内容がブラウザに表示されます 何度かロリードして試してみたってイメージでw
今回はホームページな表示をさせるために「Content-type: text/html; charset=Shift_JIS」を設定してみました これで文字装飾などの「タグ」が使えるようになるのですが…この「タグ」に使用する「<」と「>」はそのまま使うとファイルにリダイレクト/インリダイレクトするための記号として解釈されてうまく動かなくなるのでそれをエスケープするための記号「^」を使用しています コマンドの実行結果を変数に取り込むバッククオート内ではパイプに使用する記号「|」なんかも誤動作するんでエスケープする必要があります
そんなこの CGI はありがちな「おみくじ CGI」です 標準コマンドである time の出力の中から「現在の時刻」が含まれる行を変数に取り込み…その文字列の末尾(この場合 0〜9 になる)を取り出しその値に対して処理を振り分けています
ざっと見た感じ time は 1/100 秒の値まで表示している感じなんで…その値をざっくりした乱数値として使用しています ちなみに大まか作ってから気づいたのですが…バッチファイル内で乱数となる変数 %RANDOM% なんてのもあるようです これは 0~32767 の得られるようですね たぶん動作はこちらのほうが軽いと思います
さてさて…うまく動きましたか? 無事に動いたのなら次にいってみましょう
----- bat_cgi03.bat -----
@echo off
REM ブラウザに「Content-type:」を出力する(PNG画像用)
echo Content-type: image/png
echo.
goto MAIN
REM 時間を判定して画像を表示する用のサブルーチン
REM call :SUB <時間> <ファイル名>
REM <時間> は 0~23 で指定
REM <ファイル名> は表示させたい PNG 画像を指定
:SUB
echo. | time | find " %1:" > NUL
if %errorlevel% == 0 type %2
exit /b
REM サブルーチンを呼んだりするメイン的な処理
:MAIN
call :SUB 0 img_shinya.png
call :SUB 1 img_shinya.png
call :SUB 2 img_shinya.png
call :SUB 3 img_shinya.png
call :SUB 4 img_shinya.png
call :SUB 5 img_asa.png
call :SUB 6 img_asa.png
call :SUB 7 img_asa.png
call :SUB 8 img_asa.png
call :SUB 9 img_asa.png
call :SUB 10 img_hiru.png
call :SUB 11 img_hiru.png
call :SUB 12 img_hiru.png
call :SUB 13 img_hiru.png
call :SUB 14 img_hiru.png
call :SUB 15 img_hiru.png
call :SUB 16 img_hiru.png
call :SUB 17 img_hiru.png
call :SUB 18 img_yoru.png
call :SUB 19 img_yoru.png
call :SUB 20 img_yoru.png
call :SUB 21 img_yoru.png
call :SUB 22 img_yoru.png
call :SUB 23 img_yoru.png
----------
以下の画像を bat_cgi03.bat と同じフォルダ内に用意しておいてください
※画像は いらすとや さんから拝借しました いつもありがとございます
今度は少し変わり種っていうか…正しく動作すればこんな感じの内容がブラウザに表示されます(表示は時間帯によって変化します)
今回は HTTP ヘッダとして「Content-type: image/png」出力しています これは一体何なのかと云うと…ブラウザから見たこの CGI (bat_cgi03.bat) 自体が画像となっている事を意味しています
つまりブラウザから見れば「同じファイル名」なのに「アクセス毎に違う画像」を表示できることなんですね
※なお本来はテキストデータを扱う type コマンドでバイナリデータを標準出力に流しています ざっとテストした感じではうまく動いているっぽいけど…どうなんだろうね? なんか type コマンドの仕様に「EOF」が出現したら動作を終了する的なものがあるらしいんだけど…ねぇ?
※バイナリを扱える copy コマンドで出力先を CON にして試してもみたんだけど…こちらは明確に誤動作していました 確か CON デバイスは改行コードの置換などそんな動作を行うんだっけ? 何も変換とかの動作をしない…シンプルに全てのデータをそのまま標準出力に流してくれるものがあればいいのですが
話を元に戻して… CGI (bat_cgi03.bat) 自体が画像ファイルとして動作することのメリットを考えてみましょう
例えば迷惑系の HTML メールですかね その中の画像として他のサーバにある bat_cgi03.bat を呼ばれたとしましょう するとその他の場所にあるサーバ内ではアクセスログが記録されます それ即ち「メールが読まれたこと」を記録することになります
もちろんそれだけでは大きな脅威にならないかもだけど…そこには面白い使い方があるんですよ
ブラウザから見た bat_cgi03.bat は単なる画像ファイルだけど実際にはプログラム的な動作をしています そしてプログラムの動作には「引数」を与えることができます
先ほどの bat_cgi03.bat の呼び出しに対して bat_cgi03.bat?HOGEHOGE と云った感じで「引数」を与えて呼び出しそれを解釈できるようになります この引数の部分にメールを受信した人を特定する一意のデータ(この場合はHOGEHOGE)を付けておき…その一意のデータと送信したメールアドレスを紐づけておけば「誰がメールを読んだのか」を知ることができます
例として先ほどの bat_cgi03.bat の末尾にログを収集するものを付加してみましょう
----- bat_cgi04.bat -----
@echo off
REM ブラウザに「Content-type:」を出力する(PNG画像用)
echo Content-type: image/png
echo.
goto MAIN
REM 時間を判定して画像を表示する用のサブルーチン
REM call :SUB <時間> <ファイル名>
REM <時間> は 0~23 で指定
REM <ファイル名> は表示させたい PNG 画像を指定
:SUB
echo. | time | find " %1:" > NUL
if %errorlevel% == 0 type %2
exit /b
REM サブルーチンを呼んだりするメイン的な処理
:MAIN
call :SUB 0 img_shinya.png
call :SUB 1 img_shinya.png
call :SUB 2 img_shinya.png
call :SUB 3 img_shinya.png
call :SUB 4 img_shinya.png
call :SUB 5 img_asa.png
call :SUB 6 img_asa.png
call :SUB 7 img_asa.png
call :SUB 8 img_asa.png
call :SUB 9 img_asa.png
call :SUB 10 img_hiru.png
call :SUB 11 img_hiru.png
call :SUB 12 img_hiru.png
call :SUB 13 img_hiru.png
call :SUB 14 img_hiru.png
call :SUB 15 img_hiru.png
call :SUB 16 img_hiru.png
call :SUB 17 img_hiru.png
call :SUB 18 img_yoru.png
call :SUB 19 img_yoru.png
call :SUB 20 img_yoru.png
call :SUB 21 img_yoru.png
call :SUB 22 img_yoru.png
call :SUB 23 img_yoru.png
REM 最後にログを保存する
REM 例)[日 時],[引数],[相手ホスト名(相手IPアドレス)],[ブラウザ名]
echo [%DATE% %TIME%],[%QUERY_STRING%],[%REMOTE_HOST%(%REMOTE_ADDR%)],[%HTTP_USER_AGENT%] >> %date:~0,4%%date:~5,2%%date:~8,2%.log
----------
これで「アクセス日時」「引数」「相手ホスト名(相手IPアドレス)」「ブラウザ名」がログとして記録されるようになります
たったこれだけの仕組みで「単に HTML メールを見ただけ」なのにいろいろ収集できるんで…画像ファイルとして動作する CGI には大きな意義があると思います
※なお最近のメーラは「外部コンテンツを読み込まない」的なオプションがデフォルトでオフになっていると聞きます しかしその意味をよく判らないまま「便利さを求めて」読み込むような設定に変更してる人も多いと聞きます
※まぁもちろん外部コンテンツの全部が全部にそのような動作が仕掛けられている事は無いとは思いますが…そのような危険性があることを覚えておきたいですね
:
なんて感じで長々とお疲れさまでした 久しぶりのバッチファイルっていうか…思い返せば X68000 の Human68k の AUTOEXEC.BAT の頃以来ですかね(汗 なんか今回いろいろ調べてて「サブルーチンなんて使えてたっけ??」とか新しい発見があってよかったです
今回 Web サーバ以外は最初から用意されている(と思われる)標準的なコマンドをどうにか組み合わせて機能を実現してみました それ故にっていうか…久しぶりだったんでいろいろ無駄な部分とかもあるけどその辺はご了笑くださいませ
まぁしょーみ今さらバッチファイルを CGI に使おうなんて奇特な人も居ないだろうで全く問題ないだろうけどww
あと今回テストに使った Web サーバは一時的なものなので WAN に公開していません つーか使いたくないんで年に数回くらいしか電源を入れることがない代物なんでその辺はお察しください… #Windows #CGI
:
今回使用した bat_cgi*.bat と img*.png をひとまとめにした配布セットを用意しました
bat_cgi.zip
なおこれを使用した際に発生したあらゆる利益・不利益について当方は一切の責任を負いませんって定型文でよろしくお願いします
:
※ 追記 ※
今回は AN HTTPD のみでの動作テストだった訳ですが…有志のえらいひとが IIS (Internet Information Services) でのテストをしてくれて問題点と解決法をご連絡頂けたんでここに転載させていただきます
まずは IIS の設定から
「CGI」の設定で「起動ごとに新しいコンソールを使用する」を「True」にする
「ハンドラー マッピング」の設定で「マネージハンドラーの追加」をして
「要求パス」に「*.bat」を
「実行可能ファイル」に「c:\windows\system32\cmd.exe /c %s」を
「名前」には「判りやすそうな適当な名前」を設定します
あとは上の方で示してる BAT ファイルの内容的な問題っていうか…その BAT ファイルが参照/作成するファイルへのパスですかね
どうも IIS の場合だとカレントディレクトリが「BAT ファイルを実行した場所」ではなく「物理パス(ドキュメント ルート)」となるらしく…その辺を考慮してないと誤作動となるようなのでその辺を改良します まぁ基本的には BAT ファイルを実行した場所を示す変数である「%~dp0」を追加します
----- bat_cgi01.bat -----
REM 日付が設定されている変数から「年月日」を取得してログファイル的なファイル名を作ってみる
echo %DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.log
↓
REM 日付が設定されている変数から「年月日」を取得してログファイル的なファイル名を作ってみる
echo %~dp0%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.log
----------
----- bat_cgi03.bat -----
REM 時間を判定して画像を表示する用のサブルーチン
REM call :SUB <時間> <ファイル名>
REM <時間> は 0~23 で指定
REM <ファイル名> は表示させたい PNG 画像を指定
:SUB
echo. | time | find " %1:" > NUL
if %errorlevel% == 0 type %2
exit /b
↓
REM 時間を判定して画像を表示する用のサブルーチン
REM call :SUB <時間> <ファイル名>
REM <時間> は 0~23 で指定
REM <ファイル名> は表示させたい PNG 画像を指定
:SUB
echo. | time | find " %1:" > NUL
if %errorlevel% == 0 type %~dp0%2
exit /b
----------
----- bat_cgi04.bat -----
上記 bat_cgi03.bat のサブルーチン部と同じく if %errorlevel% == 0 type %~dp0%2 と直して…
REM 最後にログを保存する
REM 例)[日 時],[引数],[相手ホスト名(相手IPアドレス)],[ブラウザ名]
echo [%DATE% %TIME%],[%QUERY_STRING%],[%REMOTE_HOST%(%REMOTE_ADDR%)],[%HTTP_USER_AGENT%] >> %date:~0,4%%date:~5,2%%date:~8,2%.log
↓
REM 最後にログを保存する
REM 例)[日 時],[引数],[相手ホスト名(相手IPアドレス)],[ブラウザ名]
echo [%DATE% %TIME%],[%QUERY_STRING%],[%REMOTE_HOST%(%REMOTE_ADDR%)],[%HTTP_USER_AGENT%] >> %~dp0%date:~0,4%%date:~5,2%%date:~8,2%.log
----------
こんな感じに修正します これで正しく動くようになるようです
わざわざのご連絡ありがとございました!(>_<)w
Tweet ⌚ 2022年1月3日(月) 16:27:56 情報 <11014文字>
かつや・デミチキンカツ丼
かつや の期間限定! 濃厚デミグラスソースにチーズのコクがたまらない デミチキンカツ丼 を食べてきました
オーダーして…厨房から漂ってくるデミグラスソースの香りからして気分が盛り上がってきます そして丼を覆い隠さんばかりのチキンカツが 2 枚! そこに豚肉たっぷりなデミソースがかかっています!
最初はデミソースがかかってないサックリした部分のチキンカツから楽しみ…お次はデミソースがかかったしっとりした衣を楽しむ流れがイイネ!
たっぷり豚肉も食べ応えあってたまりません! もちろん刻みキャベツも入っているし飽きること無く最後まで楽しめます
いやむしろ具だくさんすぎてご飯とのペース配分が困難すぎますねw これは丼より…ちょっと奮発して定食にしたほうが余すとこなく味わえるのかなーって思いました
期間限定なのが惜しい逸品です! また近いうちに食べに行きたいです #外食記録
Tweet ⌚ 2022年1月16日(日) 10:10:03 日記 <404文字>
Arduino の シリアル通信
Arduino VKLSVAN Pro Micro USB ATmega32U4 (※以下 Arduino と略す)で開発してる際のデバッグとかで「変数がどうなってるのか」を見たくなることはありませんか? 私はあります いやむしろ見ないとやってられません!!(>_<)wって感じなんだけど Arduino にはモニタ出力がありません
なんか LCD ディスプレイとやらを接続すれば文字なんかを表示させられるっぽいけど…接続とか面倒そうだし手が出ないなぁと思ってたけど何やら「シリアル通信」ってので PC と文字のやりとりができるらしいじゃん!? まじか!!
そんなシリアル通信は Arduino IDE から使えるようです
[メニュー] → [ツール] → [シリアルモニタ] と操作するか…
もしくはツールバーにある虫メガネみたいなアイコンを押下すると出てきます
出てきた「シリアルモニタ」はこんな感じです
我が家の環境では「改行コード = LFのみ」で「通信速度 = 9600bps」が初期設定となっていました
通信速度は Arduino 側で設定した速度とシリアルモニタで設定する速度は同じものにしておく必要がある…らしいんですが軽くイジってみた感じでは設定値に関係なく動作しているっぽい感じなんで気にする必要はないのかもしれません
改行コードは Linux 系が「LF」で Mac 系(の昔のやつ?)が「CR」で… Windows 系が「CR+LF」と聞いたことがあるので機種ごとに適切なものに変更しておいたほうがいいの?
ざっくり使ってみた感じでは… Arduino からシリアルモニタに送られてくる場合の改行コードは設定の影響を受けないっぽいです シリアルモニタから Arduino に送信する際に「送信ボタンを押した」もしくは「エンターキーを押した」時に改行コードをどのようにするかの設定となるようです なおここでの解説は改行コードを「LFのみ」に設定してあるものとします
:
それでは早速と言うか Arduino からシリアルモニタに文字を送信してみましょう シリアル通信を開始するには以下のように記述します
Serial.begin(speed) ってやつですね speed は BPS で… 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200 なんかがよく使われがちですがそれ以外の値も指定できるようです ここでの解説では「9600」を使用するとします
その後は Serial.print() や Serial.println() を使ってシリアルモニタに数値や文字列を送信できます Serial.print() は C で云うトコロの sprintf() を意識した作りとなってるようですが…書式を全て解説するのもアレなんでその辺は手を抜いてざっくりサンプルを載せておきます
----------
void setup() {
Serial.begin(9600); // シリアル通信を開始する
}
void loop() {
unsigned long time = millis() / 1000; // 動作時間を秒の単位で取得
String h = String(time / 3600); // 「時」を文字列にして取得
String m = String((time % 3600) / 60); // 「分」を文字列にして取得
String s = String(time % 60); // 「秒」を文字列にして取得
Serial.println(String(h + ":" + m + ":" + s)); // 整形して送信
delay(1000); // 1 秒待って繰り返し
}
----------
これは Arduino が動作開始してからの時間を延々と表示し続けるってものです 動作開始してからの時間をミリ秒で取得できる millis() 関数を使い…そこで得られた変数の値を人の目で確認しやすい(と思われる)「時:分:秒」に整形して表示しています こんな感じで変数の内容を確認できるんでデバッグなどでは大いに助かりますね!
:
シリアルモニタには Arduino に対して文字を送信する機能も備えられています それを Arduino 側から Serial.read() などを使って読み取るわけですが…基本的に「1文字づつ」送られてくる扱いになるようです
例えば「a10Z」と送信すれば「a」と「1」と「0」と「Z」に「設定した改行コード」が加えられて順番に送られてきます
あと文字は「文字コード」として送られてきます 「a」だと「97 (0x61)」となり「1」だと「49 (0x31)」となり「0」だと「48 (0x30)」となり「Z」だと「90 (0x5A)」で…最後に「改行コード(LF)」が「10 (0x0A)」って感じになります
デバッグ時に「ループ回数の変数をプログラム実行中に指定の値に変更したい」とかの場合だとシリアルモニタから送られてきた「文字」を「数値」に変換する必要があります
----------
void setup() {
Serial.begin(9600); // シリアル通信を開始する
}
void loop() {
if (Serial.available() > 0) // 文字(列)が送信されてきた?
{
byte data = (Serial.read()); // 送信されてきた文字を読み込む
if (data >= '0' && data <= '9') { // 文字は数字か?
data = data - '0'; // 文字コードを数値に変換
Serial.print("数字が入力された [" + String(data) + "]\n");
} else {
if (data == 10) { // 改行コードは表示に不都合があるんで
data = 0; // 何も表示しないようにしておく
}
Serial.print("数字以外 [" + String((char)data) + "]\n");
data = 0; // 数字以外は「0」と扱うことにする
}
for (int i=1; i <= data; i++){ // 送信された数値の数だけループしてみる
Serial.print(String(data) + " 回ループの " + String(i) + " 回目\n");
}
}
}
----------
シリアルモニタに適当な適当な文字(列)を入力して「送信」します
送信した文字に「数値」があればその数だけ for() のループ回数を変更します 「数値」以外の文字は処理しないようにしてあります
なお「1文字づつ」送られてくるってのが少々厄介で…「10以上の数値」を扱う場合にはひと工夫必要です どうしたらいいんだろう? 先に送られてきた数値を10倍してそこに新たに送られてきた数値を足すって流れになるのでしょうか ちょっと大掛かりになってくるっていうか面倒なんで今回はスルーしときますが概ねそんな流れになると思います(汗
そんなこんなな Arduino のシリアル通信なお話でした しょーみもっと早く知っとっけばよかった!って思いつつ書いてましたとさ(瀧汗 #Arduino
:
※ 追記 ※
「いやいや Arduino でも sprintf() って使えるじゃん?」ってタレコミを頂いんたんでよくよく調べたらありました(汗 参照している Arduino リファレンス にはその辺が載ってなかったんで…無いものとばっか思ってました
他にも数値かどうか?を判定する isDigit() や改行の判定に使ってたものを isPrintable() に置き換えられるようなものもありました
上で説明してる数値を変数に代入して云々…で書いてるものもこんな感じでできそうです
if (data >= '0' && data <= '9') { // 文字は数字か?
↓
if (isDigit(data)) { // 文字は数字か?
----
if (data == 10) { // 改行コードは表示に不都合があるんで
↓
if (!isPrintable(data)) { // 改行コード等は表示に不都合があるんで
いやはや勉強になりました! 興味本位でなんとなく始めた Arduino ってことでまだまだ知らないことだらけなんで…こうして知識が広がっていくのは楽しいです どもありがとございました!(>_<)w
Tweet ⌚ 2022年1月30日(日) 15:35:43 情報 <3825文字>
2022年2月 この範囲を新しい順で読む
イワタニ CB-JCB ジュニアコンパクトバーナー
クレジットカードの使いすぎっていうか…ポイントがどっさり貯まっててそれが失効しそうってご連絡を頂いたんで慌ててポイント交換して イワタニ CB-JCB ジュニアコンパクトバーナー をげっちゅしました
ハードケース入りのコンパクトなやつ
このテのバーナーは 新富士バーナー の SOTO ST-300 ってのを永らく愛用しています セパレートなんで置き場所の自由度が高くてよかったんだけど…頑丈なバーナー部が災いしてなのか 600g というずっしり感のある重さがちょっとネックだったんですよね セパレートの自由度は利点である反面…セッティング/片付けがちょっと面倒なんもあって愛用してたと云いつつ使用頻度はそれほど高くありませんでした(汗
そんな訳なんで…半分以下の重量の CB-JCB には期待しちゃってます!(>_<)w
それでは早速セッティングしてみましょう まぁ脚をパタパタパタと広げて…ゴトクをパタパタパタパタと広げて CB 缶をブッ挿してねじって完成!って感じなんで説明する間もありませんが
せっかくガスバーナーを持ち出してきたのにカプ麺じゃ少々味気ないかな…って事なんで今回は袋麺を作っちゃう!
できたw おいしいwww この日は強烈な伊吹おろしが吹き荒れる天気で…まぁ物陰に隠れてはいたもののそれなりに風が巻き込んできてたけど問題なく使用できました
今回は丸型のコッヘルを使ったのですが…このゴトクの使い勝手がいいっていうかコッヘルの座りがよく安定感を感じました
段々にカットされているのでスッポリと納まる感じですかね
ざっくり測った感じでは 15cm のコッヘルまではズバピタに収まって使えるみたいです 逆に…長方形のコッヘルっていうかメスティンとかだとどんな使い勝手になるんだろ?って思ったりしていました
:
使い終わったらお片付けって事なんだけど…付属のハードケースに入れた際に数ミリ程度の隙間があって「ガタゴト」と揺れまくるんですよね 現実的な対策として軍手で包んだ後にハードケースに納めるといい感じになりますね
そう云いつつ…我が家では某Dイソーで買ってきた重ねられる箱に CB 缶と共に入れて使おうかと思ってます カバンやザックのなかでゴロゴロしがちな CB 缶をスマートに持ち歩けるようになると期待しています
あとオマケ的な話だけど…安っすい 遠赤ヒーターアタッチメント も持ち歩くようにしています これをゴトクにセットして燃焼開始すると…遠赤外線が発生して程よい暖房になるって感じらしいです まぁ確かに直火に手をかざしているより段違いに暖かいような気がします なんならこの上にコッヘルを載っけてお湯を沸かしたりとしても使えるようです
どうなんだろね よっぽどな時の非常用なのかなーってイメージですが…むっちゃ寒い真冬のキャンプツーリングなんかで威力を試せたらなぁって思います #アウトドア
Tweet ⌚ 2022年2月7日(月) 16:35:18 趣味 <1266文字>
Arduino とマトリクスキーボード
以前にどうにかしてたっていうか「Arduino Leonardo (Pro Micro) でマルチメディアキーボードを作ろう!」の後ぐらいにいろいろ調べてたら…なんかマトリクス・キーボードっていうの? 少ないピン数で多くのスイッチを読み取れる方法があるらしい??ってのを見つけて気になってたんで勉強がてらその辺を試してみることにしました
そんなマトリクスってのを日本語的に云うと…碁盤の目みたいなものって感じになるっぽい? それをキーボード的に実装すると…例えば横方向にマイコンから何本かの出力線を這わせておいてそれと何本かの入力線をスイッチを介してあたかも碁盤の目のように配置したもの?ってなるらしい??
そんな感じで Arduino VKLSVAN Pro Micro USB ATmega32U4 (※以下 Arduino と略す)を使って実際に作ってみました ちなみに Pro Micro のピン配列図はこんな感じです つーかブレッドボード(?)が狭くて碁盤の目になってなくてアレですよね(汗
回路図的なものにするとこんな感じです つーか回路図なんて描いたことないんで正しくない図かもしれませんが…まぁ概念的な絵だと思って見てください(滝汗
ここでは Arduino の 6 番ピンと 7 番ピンを出力として使い 14 番ピンと 15 番ピンを入力として使います
そして 6 番ピンのみに信号を出力します その状態で A もしくは B のスイッチが押されればそれぞれ対応した 14 番ピンか 15 番ピンで信号を読み取ることができます それにより A もしくは B のスイッチが押されたかどうかを特定できます
※なんか PULLUP 回路の都合上っていうの?
※普段は HIGH にしてあって…「出力する」としたものを LOW にすることで動作する仕組みです ちょっとややこしいですね(-_-;)
引き続き今度は 7 番ピンにのみ信号を出力します その状態で C もしくは D のスイッチが押されればそれぞれ対応した 14 番ピンか 15 番ピンで信号を読み取ることができます それにより C もしくは D のスイッチが押されたかどうかを特定できます
この一連の動作を繰り返すことにより碁盤の目のように配置されたスイッチを特定していく…そんな構造のキーボードをマトリクスキーボードと呼ぶらしいです
それでは実際にスケッチを書いて動作を確認してみましょう
----------
#include "Keyboard.h"
void setup() {
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(14, INPUT_PULLUP);
pinMode(15, INPUT_PULLUP);
digitalWrite(6, HIGH); // 6 番ピンを HIGH にしておく
digitalWrite(7, HIGH); // 7 番ピンを HIGH にしておく
Serial.begin(9600);
Keyboard.begin();
}
void loop() {
// -------------------------------- //
digitalWrite(6, LOW); // 6 番ピンを LOW にしてスキャン開始
if (digitalRead(14) == LOW) { // 14 番ピンは LOW になっている?
Serial.print("A\n"); // LOW なら A のスイッチが押されている
Keyboard.print("A\n");
}
if (digitalRead(15) == LOW) { // 15 番ピンは LOW になっている?
Serial.print("B\n"); // LOW なら B のスイッチが押されている
Keyboard.print("B\n");
}
digitalWrite(6, HIGH); // 6 番ピンを HIGH にしてスキャン終了
// -------------------------------- //
digitalWrite(7, LOW); // 7 番ピンを LOW にしてスキャン開始
if (digitalRead(14) == LOW) { // 14 番ピンは LOW になっている?
Serial.print("C\n"); // LOW なら C のスイッチが押されている
Keyboard.print("C\n");
}
if (digitalRead(15) == LOW) { // 15 番ピンは LOW になっている?
Serial.print("D\n"); // LOW なら D のスイッチが押されている
Keyboard.print("D\n");
}
digitalWrite(7, HIGH); // 7 番ピンを HIGH にしてスキャン終了
// -------------------------------- //
delay(100); // 適当に待って繰り返し
}
----------
シリアルモニタとテキストエディタを並べて動作テストしてみましょう スイッチに対応した文字が表示されれば成功です ちなみに今回はシリアルモニタとテキストエディタの両方に出力するようにしてますが…初期のテスト段階ではシリアルモニタだけを使ったほうがいいかもですね
:
さてそんな感じでマトリクス・キーボードの大まかな動作を理解できた気になったんで…ぼちぼちマルチメディアキーボード的なやつを作るか!って思いたいトコロなんだけどスイッチ類を買い揃えて配線したりとかとかしょーみ面倒くさいなぁと思ってたんですよね そう思いつつ某Aマゾンを眺めてたら気になるものを見つけました
Ren He 5個セット 16キー 4*4 マトリックス フィルム ボタン キーボード マトリックススイッチ キーパッド メンブレン式 マトリックスキーボード Arduinoに対応
かなり怪しげな感じだけど 5 個入りなのに 600 円でお釣りがきちゃうお値段に釣られてポチっちゃいました 初期不良でいくつか動かなかったとしても十分にお値打ちっポイネ!!
なんか適当なプチプチに包まれた荷姿で届くと思ってたのに…郵便受けをギリ通る厚みのプラケースに入れられて来ましたw やるじゃんww
ちなみにデータシートの類は入ってなかったんで自力で配線を解析する必要があったけど…まぁわりと素直な作りだったんで簡単に判明してよかったです そして Arduino と接続したピン番号とかも
実際に接続してみました まぁ毎度のごとく「接続例」って感じなんで…この辺は各人のお好みでどうにかしてもらえばいいかと思います
それでは早速スケッチを書いて動作を確認してみましょう
----------
const byte KEYOT[] = {4, 5, 6, 7}; // 出力ピンの設定
const byte KEYIN[] = {14, 15, 18, 19}; // 入力ピンの設定
const int WAIT = 100; // ちょっと待たせる
// 関数 keyscan() がキーの状態を読み取った値を入れておく配列
byte SW[sizeof(KEYOT)][sizeof(KEYIN)];
const byte ON = LOW; // LOW と HIGH を…
const byte OF = HIGH; // ON と OF の別名で定義しておく
void setup() {
for (byte i = 0; i < sizeof(KEYOT); i++) {
pinMode(KEYOT[i], OUTPUT); // 出力ピンのモード設定
digitalWrite(KEYOT[i], HIGH); // 出力ピンを HIGH に設定
}
for (byte i = 0; i < sizeof(KEYIN); i++) {
pinMode(KEYIN[i], INPUT_PULLUP); // 入力ピンを PULLUP モードに設定
}
Serial.begin(9600); // シリアル通信を開始
}
void loop() {
keyscan(); // キーの状態を読み取る
// -------------------------------- //
if (SW[0][0] == ON) { Serial.println("1"); }
if (SW[0][1] == ON) { Serial.println("2"); }
if (SW[0][2] == ON) { Serial.println("3"); }
if (SW[0][3] == ON) { Serial.println("A"); }
// -------------------------------- //
if (SW[1][0] == ON) { Serial.println("4"); }
if (SW[1][1] == ON) { Serial.println("5"); }
if (SW[1][2] == ON) { Serial.println("6"); }
if (SW[1][3] == ON) { Serial.println("B"); }
// -------------------------------- //
if (SW[2][0] == ON) { Serial.println("7"); }
if (SW[2][1] == ON) { Serial.println("8"); }
if (SW[2][2] == ON) { Serial.println("9"); }
if (SW[2][3] == ON) { Serial.println("C"); }
// -------------------------------- //
if (SW[3][0] == ON) { Serial.println("*"); }
if (SW[3][1] == ON) { Serial.println("0"); }
if (SW[3][2] == ON) { Serial.println("#"); }
if (SW[3][3] == ON) { Serial.println("D"); }
// -------------------------------- //
delay(WAIT);
}
void keyscan() { // キーの状態を読み取る関数
for (byte i = 0; i < sizeof(KEYOT); i++) {
digitalWrite(KEYOT[i], LOW); // 特定の出力ピンを LOW にする
for (byte j = 0; j < sizeof(KEYIN); j++) {
if (digitalRead(KEYIN[j]) == ON) { // 入力ピンの状態を読む
SW[i][j] = ON; // キーが押されている
} else {
SW[i][j] = OF; // キーは離されている
}
}
digitalWrite(KEYOT[i], HIGH); // LOW にした出力ピンを HIGH に戻す
}
}
----------
冒頭にある
const byte KEYOT[] = {4, 5, 6, 7}; // 出力ピンの設定
const byte KEYIN[] = {14, 15, 18, 19}; // 入力ピンの設定
const int WAIT = 100; // ちょっと待たせる
この辺と…あとは loop() 内を書き換えるだけでいいように書いてみました 使用するピン数が増減しても概ね追従できると思います
あーあと setup() で使用したい機能を開始させるような辺りの書き換えも必要ですかね
それと…話がややこしくなるとアレなんで今回はシリアル通信のみで動作チェックしています
キーの状態を読み取る keyscan() 関数ってのがありますが…グローバル変数を使っているので引数も返り値もありません
読み取った値は SW[][] って二次元配列にセットしています
あと PULLUP の特性っていうか普段が HIGH となっていて…スイッチが押されると LOW になるって辺りが何となく直感的にイメージしにくいように思えたんで
const byte ON = LOW; // LOW と HIGH を…
const byte OF = HIGH; // ON と OF の別名で定義しておく
って感じでスイッチが押されてる ON ってのとスイッチが離されてる OF って感じの別名で定義してあります
:
そして loop() 内で keyscan() を呼んでキーの状態を読み取っておいて…あとは個々の SW[][] の状態に応じてお好みの文字(列)を出力させるなり何なりをすればいいでしょう
将来的にっていうかもし「1」が押されてたらキーボードとして文字を出力して「#」が押されてたらマウスの右クリックを…って感じで様々な処理を行えるよう少しばかり長ったらしく書いてあります
この辺の「やること」の種類が決まりきっているのであれば
void loop() {
keyscan();
// -------------------------------- //
const char* str[] = {
"1\n", "2\n", "3\n", "A\n",
"4\n", "5\n", "6\n", "B\n",
"7\n", "8\n", "9\n", "C\n",
"*\n", "0\n", "#\n", "D\n",
};
for (byte i = 0; i < sizeof(KEYOT); i++) {
for (byte j = 0; j < sizeof(KEYIN); j++) {
if (SW[i][j] == ON) {
Serial.print(str[sizeof(KEYOT) * i + j]);
}
}
}
// -------------------------------- //
delay(WAIT);
}
こんなふうに for() で回すように書けばもうちょっとスッキリするかもしれんですね これはまぁ「やること」の内容によっていろいろ書き方があるよねって事で参考までに
:
あーあと後半の中華クソ安 16 キーボードでの実験ではテキストエディタへの文字出力を行っていないんですが…これを実際に行うと不具合が出るものがあります
キーボード上の「*」 なんですけどね シリアルモニタではちゃんと「*」が出力されているのに…テキストエディタ上では「(」になってしまいます
※別のスケッチでテストした際の画像です
これは #include "Keyboard.h" した際のキーボードレイアウトが KeyboardLayout_en_US になってて…まぁいわゆる US キーボードってやつですかね これが日本で一般的に使われている JIS キーボードとレイアウト(キーの配置)が違うから起こる現象のようです
アルファベットと数字に関しては問題ないのですが…記号はその多くが US と JIS とで配列が違うんで問題になります
先ほどの「*」を例にすると… US キーボードでは「*」が「8」のキーに割り当てられています
そのキーコードを JIS キーボードに当てはめると「8」のキーにあるのは「(」って事になるので正しく表示されないのです
困っちゃいますよね…そこそこ数が出回ってる(と思われる) JIS キーボードなんだで Keyboard.begin(KeyboardLayout_ja_JP); くらい通るようにしといてほしいのに!って思うんだけどそうはいきません(-_-;)
どうしたもんかなーって思いつつ調べてたら…何やら Keyboard.h を複製した後に JIS キーボード向けに書き換える手法を見つけました→ Arduino Leonardoで\記号を打つ:メガギガテラス:So-netブログ
実際に試してみたところ…これでバッチリ動作しました! まぁあくまで自己責任で!って感じになるんだけど…自作キーボードでいろいろしたい!って場合にはとても有用な情報だと思うんで参考にしてみてください
:
キーボード自作って話になると耳にするマトリクスキーボードってやつですね 今までは何となく漠然と聞き流していたんですが…今回はその辺に踏み込んでその原理をほんのり理解できた気になれてよかったです マイコン側のピン数を減らしつつ…より多くのキーを読み取るテクニックは今後も色々と使えそうなんで今後もより掘り下げた勉強をしていきたいなって思いました
あと…マトリクスキーボードの構造的な問題っていうか特定条件の複数キーの同時押しをした際に正常に動きません 今回の中華クソ安 16 キーボードを使った実験を例にとると…縦軸に配されたキー(例えば「1と4」とか「AとBとC」とか)を同時押しすると「どれも押されてない」って判定されます まぁなんか読みたいキーとは別のスイッチを介して HIGH が逆流してくる(?)ことにより誤動作するらしく…そんな逆流を防ぐためにダイオードを入れるって事らしいんですが今回は既成品でその辺をどうにもできかねる感じなんでそのままにしてあります(汗
まぁその辺を踏まえた上で…この中華クソ安 16 キーボードでマルチメディアキーボード的なものを作るとしますかね 程々に硬い板に貼り付けて配線の取りまとめをすればいいだけって感じの見栄えよりお手軽さ!って感じのアレですが(瀧汗
そんなこなんで今回も長々とお疲れさまでした! 安いのに遊び甲斐のある Arduino をもっと色々と使い倒していきタイネ!(>_<)w #Arduino
Tweet ⌚ 2022年2月20日(日) 10:20:32 情報 <7955文字>
2022年3月 この範囲を新しい順で読む
和洋食レストラン&喫茶「かかし」の鉄板ナポリタン
名古屋市北区金城にある昔ながらの喫茶店「かかし」に行ってきました
麻雀のテーブル筐体が置いてあったりして昭和の雰囲気が色濃く残る雰囲気はなかなかに趣があっていいですねw
そして頂くのは鉄板ナポリタンです
これまた昭和から何も変わっていない!って雰囲気のごくごくありふれたナポリタンだけどそこがいいww
タバコの臭いが漂う…そんなノスタルジックな気分を味わいたくなった時におすすめの喫茶店ですね
:
そして特筆すべき点は「栄光の24時間営業の喫茶店」だって事ですかね
真夜中に…ふと何処か徘徊したい気分になった時とかに訪れるとなお雰囲気があっていいと思います
ただし午後 10:00 〜午前 6:00 の間は深夜料金として 1 品につき 100 円が加算されるんでご注意を!
でもまぁその分っていうか客入りまばらな深夜の店内でだらりゆっくり雰囲気を楽しめる訳なのですがww #外食記録
Tweet ⌚ 2022年3月6日(日) 08:24:49 日記 <426文字>
Android と PC のための adb メモ
Android Debug Bridge(adb)なるものがあります Debug Bridge なんて聞くと「なんか面倒くさそうだな…」って思いがちだけど…一般利用者的な使い方でも「知っておくと得をする」ような便利な機能があるっていうか忘れがちな使い方をまとめて忘れ物防止メモって感じで書き留めておきます
:
一般的には Android 端末と PC を USB ケーブルで繋ぎます なんかここんとこ Wi-Fi を使ってケーブル無しで繋ぐ手法が確立されてきてるようだけど…その話は後述って感じで
まずはスマホ側の設定ってことで「設定」メニューから「システム」→「端末情報」と進みます ※機種により若干の操作法の違い有り
その中にある「ビルド番号」を連打する
既に有効にしてあったんでアレだけど…これで「開発者向けオプション」を有効にできます
※機種によっては「設定」メニューからいきなり「デバイス情報」って入る場合や「詳細設定」の中に入っている場合とかがあるようです まぁその辺はそれっぽい項目を選びつつ「ビルド番号」を探し出してそれを連打してください(汗
次に「設定」メニューから「システム」→「詳細設定」と進むと「開発者向けオプション」が現れます ※これも機種によって進むべきメニュー項目が違う場合があるんで…あちこち探して辿り着いてください(汗
「開発者向けオプション」内にある「USBデバッグ」をオンにして許可する これで端末側の設定は概ね完了です
:
お次は PC 側の設定ってことで…本来 adb ってやつは Android Studio って開発ツールに含まれているものなんでそれをセットアップする必要があるんだけど単に adb だけを使いたい人向けにシンプルなパッケージが用意されているんでそれを入れることにします
sudo apt install adb
なお動作検証っていうか…基本的に xubuntu 20.04 LTS を USB メモリに書き込んだものをお試しモードっていうかライブ起動して諸々を試しています 画像の撮り忘れなんかで…本番環境の Ubuntu MATE 20.04 LTS を使う場合もありますがその辺はご了笑ください汗
インストールが完了したら先ほどの「USBデバッグ」をオンにした Android と PC を USB ケーブルで繋ぎ adb start-server してみましょう daemon started successfully と出れば成功です
この操作は省略してもいいのですが…接続した Android 機と PC とのやりとりを管理するデーモン(adbd)の起動を明確に確認できるので知っておいていいと思います
ちなみにデーモン(adbd)を終了する際には adb kill-server します いろいろな端末を繋ぎつつ作業してると稀に動作が不安定になる場合とかあるようなので…いったんデーモンを終了させて再び起動させるとうまくいく時があります
そんな adb ですが 1 台の PC に複数台の Android を接続することができます 接続した Android(のシリアル) は adb devices で確認することができます
そのシリアルを adb の -s オプションを使って指定するとその Android 機を操作できます 画像はそれぞれの Android 内の proc フォルダ内にある cpuinfo ファイルの末尾 10 行くらいを表示させた一例です
なお PC に 1 台だけ Android 機を接続して使用する際にはこの -s オプションは不要です 今後は説明の簡略化っていうか 1 台だけの接続にして -s オプションは省略した感じでいきます
:
それでは adb のよく使うコマンドの説明をちょびっとだけ…
adb shell で接続した Android 機にログイン(?)できます コマンドライン上の操作で Linux 系のコマンドが使えます
adb shell コマンド名 だと PC 側の端末上で接続した Android 機のコマンドを実行できます 実行結果を PC 側のファイルにリダイレクトしたりパイプに送り込んだりできます
ちなみにここで試している pm コマンドはパッケージ・マネージャ系のコマンドですね これに list package なる引数を与えて起動するとその端末にインストールされているアプリの一覧を確認できます ここではその結果から grep を用いて必要な行だけ抽出して表示させています
パッケージの一覧を確認できたってことで…それじゃ Android 機からファイルを取ってくる adb pull を使って apk(アプリ) を抜いてみましょう
目的とするアプリの ID(?) を指定することで apk ファイルを取得できます これはブラウザを使い Google Play で目的のアプリを表示させたアドレス欄にも表示されているんでその辺を参考にして grep で絞り込むといいでしょう
そうして出てきた中から /data/app/〜/base.apk を選択してコピーして adb pull /data/app/〜/base.apk として実行すると PC 側に base.apk として持ってこれます
この apk ファイルはそのまま Android 機にインストールすることができます インストールする場合は目的の Android 機に繋ぎ替えた後に adb install base.apk とすれば ok です
モノは試しに Fire HD 10 タブレット (10インチHDディスプレイ) 32GB - Alexa搭載 にインストールしてみました もともと Amazon apps 版の フェアリードール が入ってたんだけど…それとは別にインストールすることができました
Amazon Fire には Google Play が入ってないんだけどこの手法を使えばアプリのインストールが可能です…が多くの場合ハードやセキュリティの制約などで入れられないことが多いです まぁどうしてもの非常時に入ったらイイナ!って感じで覚えておくといいかもです(汗
:
アプリのバックアップの別の手法として adb backup アプリID ってのもあるようですね ただこれは機種ごとのセキュリティ設定が強く影響するのか…同じアプリでも G 社の Android だとうまくいくけど S 社のそれだとうまくいかないなんてことがあるようです
まぁもしうまくバックアップすることができたとして…出来上がった *.ab ファイルを展開するツールが存在するっぽい?
android-backup-extractor ってものらしく abe.jar ってのがそれらしいです Java 環境が必要で java -jar abe.jar unpack 解凍元.ab 解凍先.tar で展開できるようです
:
Android 機のスクリーンショットを PC で撮ってそのファイルを PC に保存するなんてこともできるようです
例えば adb exec-out screencap -p > ss$(date +%Y%m%d%H%M%S).png なんてすると実行した日時を付加した ss が PNG で PC に直接保存できます スマホの「電源 + 音量ダウン」のボタン同時押しがそれなりに使いにくいんで…微妙なタイミングを要するスクリーンショットを撮りたい時などに重宝すると思います
:
Android 機の画面を PC 上で表示させられる scrcpy ってのがあるらしいです これは sudo apt install scrcpy で入れることができるようだけど…
我が家の環境ではエラーが出て動きませんでした
それじゃ別の手法で!ってことで snap 版の scrcpy を sudo snap install scrcpy で入れてみました ちなみに apt で入れる scrcpy の方が PATH の優先順位が高いんで /snap/bin/scrcpy って感じのフルパス指定で起動してみます
snap 版の scrcpy だとうまく動きました! 思ってたより動きもスムーズでいい感じです!(>_<)w
そんな snap 版の scrcpy を毎回毎回フルパス指定で起動するのも面倒だな…って事なんで snap の別名設定を使ってみることにします
設定は sudo snap alias 元のコマンド名 新しいコマンド名 でできるようなんで sudo snap alias scrcpy Scrcpy って感じで頭文字を大文字にしてみました エイリアスを確認する際には snap aliases とするようです
:
同様に Android 機の音声を PC 上で再生させられる sndcpy ってのがあるらしいです これは rom1v / sndcpy の Get the app から sndcpy-v1.1.zip (※20220321現在) を落としてきて展開して…その中の sndcpy (シェルスクリプト) を実行すればいいようです
先ほどの Scrcpy と sndcpy を同時に使ってみた例 音声は 0.5 秒くらい(?)遅れてきてるみたいですね あーあと sndcpy を使用する場合には PC に vlc (メディアプレイヤ) を入れておく必要があるようです
スマホとかの小さい画面とショボいスピーカーの音声を PC 側に出すと見やすくて音もよくてとてもゴキゲンです! 追加投資は USB ケーブルだけ!って手軽さがいいですね!
:
そんな USB ケーブルで PC と Android 機を繋ぎっぱなしってのもなんか邪魔くさいんで…その辺をネットワーク (Wi-Fi等) でどうにかする手法があるようです ※使用するにあたり…最初の設定段階では USB ケーブルで繋いでおく必要があります
まず adb tcpip 5555 で listen するポートを 5555 に設定します ポート番号は 5555~5585 の範囲で奇数番号のポートが使用できるらしい?
次に adb connect 192.16x.x.x32 で Android 機の IP アドレスを指定して接続します Android 機の IP アドレスは「設定」→「ネットワークとインターネット」→「Wi-Fi」→「接続済みのAP」→「詳細設定」等で確認できます ※使用機種によりメニュー構成が若干違います
connected to 192.16x.x.x32:5555 などと表示され接続したら…この時点で USB ケーブルを抜いても ok です
あとは adb shell なりの adb コマンドをネットワーク経由で使用できます
:
さらに最近では最初からネットワークで全てが完了する「ワイヤレス デバッグ」も使用できるようになりつつあります ※ Android OS 11 以降で adb も新しいものが必要になります
sudo apt install adb で入れたものは Ver. 1.0.39 で…これは古いので使えません じゃぁどうしよう?ってことで…それじゃ Android Studio を入れてみましょう
Android Studio のダウンロードページ のダウンロードボタンを押下して…お決まりの了解したぜ!チェックした後にダウンロードします ダウンロードしたファイルを解凍して android-studio/bin/studio.sh を実行するとインストールが開始します 本気で使う気がないのなら…まぁこの辺は適当でいいと思います(汗
標準的なインストールを行うと ~/Android/Sdk/platform-tools/ の中に adb が用意されるのでこれを使ってみます Ver. 1.0.41 でした
お次は Android OS 11 以降の設定を行います 「設定」→「システム」→「開発者向けオプション」→「ワイヤレス デバッグ」をオンにして…その項目をタップする
タップしたらワイヤレス デバッグの設定に入れるので…「ペア設定コードによるデバイスのペア設定」をタップする
すると必要な情報が表示されるので…これをもとに adb で接続設定していきます なお古い adb と混同するをアレなんで ~/Android/Sdk/platform-tools/adb って感じのフルパスでコマンドを起動しています
先ほど表示されてた IP アドレスとポート番号で ~/Android/Sdk/platform-tools/adb pair 192.16x.x.x31:43015 って感じで実行します するとペアリング・コードを聞かれるのでそれを入力します ※ここでは 226441 でした これでペアリング設定は完了です
お次は実際に接続します これは ~/Android/Sdk/platform-tools/adb connect 192.16x.x.x31:40643 って感じで実行します 先ほどのペアリング設定のポート番号とは別のポート番号になるので注意してください
成功すればこれでワイヤレス接続が完了しています 後は ~/Android/Sdk/platform-tools/adb shell するなり色々をネットワーク経由で行えます 少々手順が多くて面倒かなーって思いつつ…まぁ慣れてしまえば USB ケーブルを接続するより楽ちんかなーってイメージです
ただし先述の scrcpy や sndcpy は(20220321現在)対応していない感じでした この辺が早く対応してくれればなーって思います
※ 追記 ※
テストした環境の PATH 設定の都合で Ver. 1.0.39 の adb が参照されていたので…その辺をどうにかしたら sndcpy は動きました Android Studio で入れた Ver. 1.0.41 を優先的に使えるよう PATH を以下のように設定しました
export PATH="/home/$USER/Android/Sdk/platform-tools:$PATH" ※ 標準的(?)な Android Studio のインストールを行った場合
一時的な設定ならコマンドラインで上記のように実行するもよし…再起動後とかも永続的に使いたいのであれば ~/.profile を編集して…最終行辺りに上記のパス設定を追加しておくといいでしょう
ちなみに scrcpy は apt 版(Ver. 1.12.1)と snap 版(Ver. 1.23)のどちらもワイヤレス環境では動作しませんでした(-_-;)
:
そんなこんなな adb の使い方いろいろでした 他にも音量の操作やら特定のイベントシグナルの送信などなどアプリ開発のデバッグに有用な機能が用意されているのですが…まぁ末端ユーザでは概ね必要のない機能なのでその辺はもっとプロの方が発する情報をご参照くださいってことで #Android #Ubuntu #コマンドヘルプ
Tweet ⌚ 2022年3月21日(月) 13:59:13 情報 <6454文字>
M5StickC Plus の開発環境を構築する
elchika公式 @elchika_info さんがリツイートキャンペーンを行っていたのですが…
(ツイート埋め込み処理中...)Twitterで見る
それに応募したら大当選しちゃいました!!
そんな訳で M5StickC Plus を頂きました! 本当にありがとございます!!(>_<)w
こないだから Arduino Pro Micro をぼちぼちとイジり始めてマイコンへの興味が盛り上がってきた所なんで…さらに見識を深めることができそうで嬉しいです!(>_<)w
:
そんな M5StickC Plus の外観をざっくり見てみましょう
裏面には I/O の説明が所狭しと書かれています 何かとよく使う(と思われる)ボタンや LED のピン番号なんかも書かれているんで…ド忘れした時とかでも困らないと思います
USB は Type-C のようです
USB を挿して電源が供給されると起動するようです 何やらセンサーの状況が見れるようなものとかマイクのテストや赤外線の送信(?)のようなものを「M5」ボタンで切り替えながら楽しめるようです
ちなみに電源の ON/OFF は側面のボタンを長押しすることにより操作できるようです 電源を ON する場合には 2 秒位の長押しで電源を OFF にする場合は 6 秒くらい長押しするといいようです
:
そんな訳なんで動作チェックがてら開発環境を整えていきましょう M5StickC Plus (M5Stackシリーズ) の開発環境は Arduino IDE を使ってどうにかできるようなんで手軽っちゃぁ手軽ですよね
その辺の詳細な手順については 公式 に詳しく書かれていたんで…それを実際に試していきたいと思います
まずは Arduino IDE の「ファイル」→「環境設定」を開きます
その中の「追加ボードマネージャのURL」に https://m5stack.oss-cn-shenzhen.aliyuncs... を追加して「ok」します
お次に「ツール」→「ボード」→「ボードマネージャ」を開きます
検索欄に「m5stack」と入れて出てきた「M5Stack」をインストールする
これで「ツール」→「ボード」とした際に「M5Stick-C Plus」を選べるようになります
:
使用ボードの設定が済んだらライブラリをインストールします
「スケッチ」→「ライブラリをインクルード」→「ライブラリを管理」を開きます
検索欄に「m5stickcplus」と入れて出てきた「M5StickCPlus」をインストールします
なんか関連したライブラリ(?)も一緒にインストールするか聞かれるんだけど…よく判んなかったんで全部入れちゃいました(汗
ちなみに…もし間違ったライブラリを入れちゃった時にそれを消したい場合は「ファイル」→「環境設定」で確認できる「スケッチブックの保存場所」で確認できるフォルダを開いて libraries フォルダを開いて
該当するライブラリが入っているフォルダを削除して Arduino IDE を再起動すると消すことができるようです
まぁとにかくコレで M5StickC Plus のライブラリをインクルードできるようになりました
:
それじゃ実際にコードを書いてコンパイルして M5StickC Plus に書き込んでみましょう まぁ本来なら LED を点滅させる…いわゆる「Lチカ」を試すべきトコロなんですが液晶ディスプレイが搭載されているって事なんでそれに文字を出力させてみましょう
----------
# include <M5StickCPlus.h>
void setup(){
M5.begin(); // M5StickC Plus の初期化?
}
void loop() {
M5.Lcd.setTextSize(3); // フォントサイズ
M5.Lcd.setRotation(3); // 画面表示の向き
M5.Lcd.print("Hello World"); // お決まりのやつ
}
----------
ざっくりこんな感じですかね これをマイコンボードに書き込んでみましょう
無事に「Hello World」と表示されて大成功です!
:
ちなみにコンパイル時に…我が家の環境では以下のようなエラーが発生しました
Traceback (most recent call last):
File "/home/nekoyama/.arduino15/packages/m5stack/tools/esptool_py/3.1.0/esptool.py", line 38, in <module>
import serial
ModuleNotFoundError: No module named 'serial'
exit status 1
ボードM5Stick-C-Plusに対するコンパイル時にエラーが発生しました。
これは Python にシリアル通信するための pyserial モジュールが入ってない時に発生するらしいので…
pip install pyserial としてインストールしておけばいいようですメモ
:
さらにちなみに初回起動時に動いていたセンサーの状況が見れるようなものとかマイクのテストや赤外線の送信(?)のようなものは「ファイル」→「スケッチ例」→「M5StickCPlus」→「FactoryTest」で再び入れ直せるようです 他にも参考になりそうなものが用意されているんで…ざっと目を通しておくといいかもです
:
Arduino Pro Micro と M5StickC Plus を比べると…すぐに使える I/O が豊富でいろいろ興味を駆り立てられてしまいますね! 特に ESP32 ってやつですかね Wi-Fi でコネクションを確立したりその後に HTTP としてサーバからドキュメンをを取ってこれたりもできるようなんで Web サーバと連携させて M5StickC Plus をリモートで操作するようなものとか作れるかもしれんですね!
そんな感じで引き続きぼちぼちイジっていきたいと思います #Arduino #M5StickC
Tweet ⌚ 2022年3月26日(土) 15:07:18 情報 <2732文字>
スガキヤ・味噌ラーメン
我らが スガキヤ の新メニューに 味噌ラーメン が登場したんで食べてきました
伝統の豚骨スープに味噌を加えたって感じでしょうか 食べ慣れた味に味噌のコッテリ感が加わって美味しいですね!
そこに別添のバターを入れて更にまろやかさがアップ! モヤシとコーンの相性も抜群ですね
名古屋の血液と云いますか…豚骨スープな白血球に味噌の赤血球が加わったって感じで身も心も癒やされるww
スガキヤ的にはちょっとお値段高めですが…いやいやこれはまた食べに行きたくなるお味です! おすすめです! #外食記録