でんげき☆ Network Service

Raspberry Pi 4 で運用実験中 Connect checker

No.23, No.22, No.21, No.20, No.19, No.18, No.177件]

Android と PC のための adb メモ

20220321135913-admin.png
 
Android Debug Bridge(adb)なるものがあります Debug Bridge なんて聞くと「なんか面倒くさそうだな…」って思いがちだけど…一般利用者的な使い方でも「知っておくと得をする」ような便利な機能があるっていうか忘れがちな使い方をまとめて忘れ物防止メモって感じで書き留めておきます

  :

一般的には Android 端末と PC を USB ケーブルで繋ぎます なんかここんとこ Wi-Fi を使ってケーブル無しで繋ぐ手法が確立されてきてるようだけど…その話は後述って感じで

2022032113591336-admin.png 2022032113591335-admin.png
まずはスマホ側の設定ってことで「設定」メニューから「システム」→「端末情報」と進みます ※機種により若干の操作法の違い有り

2022032113591334-admin.png
その中にある「ビルド番号」を連打する

2022032113591333-admin.png
既に有効にしてあったんでアレだけど…これで「開発者向けオプション」を有効にできます

※機種によっては「設定」メニューからいきなり「デバイス情報」って入る場合や「詳細設定」の中に入っている場合とかがあるようです まぁその辺はそれっぽい項目を選びつつ「ビルド番号」を探し出してそれを連打してください(汗

2022032113591332-admin.png 2022032113591331-admin.png
次に「設定」メニューから「システム」→「詳細設定」と進むと「開発者向けオプション」が現れます ※これも機種によって進むべきメニュー項目が違う場合があるんで…あちこち探して辿り着いてください(汗

2022032113591330-admin.png 2022032113591329-admin.png
「開発者向けオプション」内にある「USBデバッグ」をオンにして許可する これで端末側の設定は概ね完了です

  :

お次は PC 側の設定ってことで…本来 adb ってやつは Android Studio って開発ツールに含まれているものなんでそれをセットアップする必要があるんだけど単に adb だけを使いたい人向けにシンプルなパッケージが用意されているんでそれを入れることにします

2022032113591328-admin.png
sudo apt install adb

なお動作検証っていうか…基本的に xubuntu 20.04 LTS を USB メモリに書き込んだものをお試しモードっていうかライブ起動して諸々を試しています 画像の撮り忘れなんかで…本番環境の Ubuntu MATE 20.04 LTS を使う場合もありますがその辺はご了笑ください汗

2022032113591327-admin.png
インストールが完了したら先ほどの「USBデバッグ」をオンにした Android と PC を USB ケーブルで繋ぎ adb start-server してみましょう daemon started successfully と出れば成功です
この操作は省略してもいいのですが…接続した Android 機と PC とのやりとりを管理するデーモン(adbd)の起動を明確に確認できるので知っておいていいと思います
ちなみにデーモン(adbd)を終了する際には adb kill-server します いろいろな端末を繋ぎつつ作業してると稀に動作が不安定になる場合とかあるようなので…いったんデーモンを終了させて再び起動させるとうまくいく時があります

2022032113591326-admin.png
そんな adb ですが 1 台の PC に複数台の Android を接続することができます 接続した Android(のシリアル) は adb devices で確認することができます

2022032113591325-admin.png
そのシリアルを adb の -s オプションを使って指定するとその Android 機を操作できます 画像はそれぞれの Android 内の proc フォルダ内にある cpuinfo ファイルの末尾 10 行くらいを表示させた一例です
なお PC に 1 台だけ Android 機を接続して使用する際にはこの -s オプションは不要です 今後は説明の簡略化っていうか 1 台だけの接続にして -s オプションは省略した感じでいきます

  :

それでは adb のよく使うコマンドの説明をちょびっとだけ…

2022032113591324-admin.png
adb shell で接続した Android 機にログイン(?)できます コマンドライン上の操作で Linux 系のコマンドが使えます

2022032113591323-admin.png
adb shell コマンド名 だと PC 側の端末上で接続した Android 機のコマンドを実行できます 実行結果を PC 側のファイルにリダイレクトしたりパイプに送り込んだりできます
ちなみにここで試している pm コマンドはパッケージ・マネージャ系のコマンドですね これに list package なる引数を与えて起動するとその端末にインストールされているアプリの一覧を確認できます ここではその結果から grep を用いて必要な行だけ抽出して表示させています

2022032113591322-admin.png 2022032113591321-admin.png
パッケージの一覧を確認できたってことで…それじゃ 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 です

2022032113591320-admin.png 2022032113591319-admin.png
モノは試しに 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 に保存するなんてこともできるようです

2022032113591311-admin.png
例えば adb exec-out screencap -p > ss$(date +%Y%m%d%H%M%S).png なんてすると実行した日時を付加した ss が PNG で PC に直接保存できます スマホの「電源 + 音量ダウン」のボタン同時押しがそれなりに使いにくいんで…微妙なタイミングを要するスクリーンショットを撮りたい時などに重宝すると思います

  :

Android 機の画面を PC 上で表示させられる scrcpy ってのがあるらしいです これは sudo apt install scrcpy で入れることができるようだけど…

2022032113591318-admin.png
我が家の環境ではエラーが出て動きませんでした

2022032113591317-admin.png
それじゃ別の手法で!ってことで snap 版の scrcpy を sudo snap install scrcpy で入れてみました ちなみに apt で入れる scrcpy の方が PATH の優先順位が高いんで /snap/bin/scrcpy って感じのフルパス指定で起動してみます

2022032113591316-admin.png
snap 版の scrcpy だとうまく動きました! 思ってたより動きもスムーズでいい感じです!(>_<)w
そんな snap 版の scrcpy を毎回毎回フルパス指定で起動するのも面倒だな…って事なんで snap の別名設定を使ってみることにします

2022032113591315-admin.png
設定は sudo snap alias 元のコマンド名 新しいコマンド名 でできるようなんで sudo snap alias scrcpy Scrcpy って感じで頭文字を大文字にしてみました エイリアスを確認する際には snap aliases とするようです

  :

同様に Android 機の音声を PC 上で再生させられる sndcpy ってのがあるらしいです これは rom1v / sndcpy の Get the app から sndcpy-v1.1.zip (※20220321現在) を落としてきて展開して…その中の sndcpy (シェルスクリプト) を実行すればいいようです

2022032113591314-admin.png
先ほどの Scrcpy と sndcpy を同時に使ってみた例 音声は 0.5 秒くらい(?)遅れてきてるみたいですね あーあと sndcpy を使用する場合には PC に vlc (メディアプレイヤ) を入れておく必要があるようです
スマホとかの小さい画面とショボいスピーカーの音声を PC 側に出すと見やすくて音もよくてとてもゴキゲンです! 追加投資は USB ケーブルだけ!って手軽さがいいですね!

  :

そんな USB ケーブルで PC と Android 機を繋ぎっぱなしってのもなんか邪魔くさいんで…その辺をネットワーク (Wi-Fi等) でどうにかする手法があるようです ※使用するにあたり…最初の設定段階では USB ケーブルで繋いでおく必要があります

2022032113591313-admin.png 2022032113591312-admin.png
まず 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 も新しいものが必要になります

202203211359136-admin.png
sudo apt install adb で入れたものは Ver. 1.0.39 で…これは古いので使えません じゃぁどうしよう?ってことで…それじゃ Android Studio を入れてみましょう

202203211359135-admin.png 202203211359134-admin.png
Android Studio のダウンロードページ のダウンロードボタンを押下して…お決まりの了解したぜ!チェックした後にダウンロードします ダウンロードしたファイルを解凍して android-studio/bin/studio.sh を実行するとインストールが開始します 本気で使う気がないのなら…まぁこの辺は適当でいいと思います(汗

202203211359136-admin.png
標準的なインストールを行うと ~/Android/Sdk/platform-tools/ の中に adb が用意されるのでこれを使ってみます Ver. 1.0.41 でした

2022032113591310-admin.png
お次は Android OS 11 以降の設定を行います 「設定」→「システム」→「開発者向けオプション」→「ワイヤレス デバッグ」をオンにして…その項目をタップする

202203211359139-admin.png
タップしたらワイヤレス デバッグの設定に入れるので…「ペア設定コードによるデバイスのペア設定」をタップする

202203211359138-admin.png
すると必要な情報が表示されるので…これをもとに adb で接続設定していきます なお古い adb と混同するをアレなんで ~/Android/Sdk/platform-tools/adb って感じのフルパスでコマンドを起動しています

202203211359133-admin.png
先ほど表示されてた IP アドレスとポート番号で ~/Android/Sdk/platform-tools/adb pair 192.16x.x.x31:43015 って感じで実行します するとペアリング・コードを聞かれるのでそれを入力します ※ここでは 226441 でした これでペアリング設定は完了です

202203211359132-admin.png 202203211359137-admin.png
お次は実際に接続します これは ~/Android/Sdk/platform-tools/adb connect 192.16x.x.x31:40643 って感じで実行します 先ほどのペアリング設定のポート番号とは別のポート番号になるので注意してください

202203211359131-admin.png
成功すればこれでワイヤレス接続が完了しています 後は ~/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 #コマンドヘルプ

情報 <6454文字>

和洋食レストラン&喫茶「かかし」の鉄板ナポリタン

20220306082449-admin.jpg
 
名古屋市北区金城にある昔ながらの喫茶店「かかし」に行ってきました
麻雀のテーブル筐体が置いてあったりして昭和の雰囲気が色濃く残る雰囲気はなかなかに趣があっていいですねw

202203060824491-admin.jpg
そして頂くのは鉄板ナポリタンです
これまた昭和から何も変わっていない!って雰囲気のごくごくありふれたナポリタンだけどそこがいいww
タバコの臭いが漂う…そんなノスタルジックな気分を味わいたくなった時におすすめの喫茶店ですね

  :

そして特筆すべき点は「栄光の24時間営業の喫茶店」だって事ですかね
真夜中に…ふと何処か徘徊したい気分になった時とかに訪れるとなお雰囲気があっていいと思います

ただし午後 10:00 〜午前 6:00 の間は深夜料金として 1 品につき 100 円が加算されるんでご注意を!
でもまぁその分っていうか客入りまばらな深夜の店内でだらりゆっくり雰囲気を楽しめる訳なのですがww #外食記録

日記 <426文字>

Arduino とマトリクスキーボード

202202201020325-admin.jpg
 
以前にどうにかしてたっていうか「Arduino Leonardo (Pro Micro) でマルチメディアキーボードを作ろう!」の後ぐらいにいろいろ調べてたら…なんかマトリクス・キーボードっていうの? 少ないピン数で多くのスイッチを読み取れる方法があるらしい??ってのを見つけて気になってたんで勉強がてらその辺を試してみることにしました

そんなマトリクスってのを日本語的に云うと…碁盤の目みたいなものって感じになるっぽい? それをキーボード的に実装すると…例えば横方向にマイコンから何本かの出力線を這わせておいてそれと何本かの入力線をスイッチを介してあたかも碁盤の目のように配置したもの?ってなるらしい??

202202201020324-admin.jpg 20211113072346-admin.jpg
そんな感じで Arduino VKLSVAN Pro Micro USB ATmega32U4 (※以下 Arduino と略す)を使って実際に作ってみました ちなみに Pro Micro のピン配列図はこんな感じです つーかブレッドボード(?)が狭くて碁盤の目になってなくてアレですよね(汗

202202201020325-admin.png
回路図的なものにするとこんな感じです つーか回路図なんて描いたことないんで正しくない図かもしれませんが…まぁ概念的な絵だと思って見てください(滝汗

202202201020324-admin.png
ここでは Arduino の 6 番ピンと 7 番ピンを出力として使い 14 番ピンと 15 番ピンを入力として使います
そして 6 番ピンのみに信号を出力します その状態で A もしくは B のスイッチが押されればそれぞれ対応した 14 番ピンか 15 番ピンで信号を読み取ることができます それにより A もしくは B のスイッチが押されたかどうかを特定できます
※なんか PULLUP 回路の都合上っていうの?
※普段は HIGH にしてあって…「出力する」としたものを LOW にすることで動作する仕組みです ちょっとややこしいですね(-_-;)

202202201020323-admin.png
引き続き今度は 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); // 適当に待って繰り返し
}

----------

202202201020322-admin.png
シリアルモニタとテキストエディタを並べて動作テストしてみましょう スイッチに対応した文字が表示されれば成功です ちなみに今回はシリアルモニタとテキストエディタの両方に出力するようにしてますが…初期のテスト段階ではシリアルモニタだけを使ったほうがいいかもですね

  :

さてそんな感じでマトリクス・キーボードの大まかな動作を理解できた気になったんで…ぼちぼちマルチメディアキーボード的なやつを作るか!って思いたいトコロなんだけどスイッチ類を買い揃えて配線したりとかとかしょーみ面倒くさいなぁと思ってたんですよね そう思いつつ某Aマゾンを眺めてたら気になるものを見つけました

Ren He 5個セット 16キー 4*4 マトリックス フィルム ボタン キーボード マトリックススイッチ キーパッド メンブレン式 マトリックスキーボード Arduinoに対応

かなり怪しげな感じだけど 5 個入りなのに 600 円でお釣りがきちゃうお値段に釣られてポチっちゃいました 初期不良でいくつか動かなかったとしても十分にお値打ちっポイネ!!

202202201020323-admin.jpg
なんか適当なプチプチに包まれた荷姿で届くと思ってたのに…郵便受けをギリ通る厚みのプラケースに入れられて来ましたw やるじゃんww

202202201020321-admin.png
ちなみにデータシートの類は入ってなかったんで自力で配線を解析する必要があったけど…まぁわりと素直な作りだったんで簡単に判明してよかったです そして Arduino と接続したピン番号とかも

20220220102032-admin.jpg 202202201020321-admin.jpg 202202201020322-admin.jpg
実際に接続してみました まぁ毎度のごとく「接続例」って感じなんで…この辺は各人のお好みでどうにかしてもらえばいいかと思います

それでは早速スケッチを書いて動作を確認してみましょう

----------

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 キーボードでの実験ではテキストエディタへの文字出力を行っていないんですが…これを実際に行うと不具合が出るものがあります

20220220102032-admin.png
キーボード上の「*」 なんですけどね シリアルモニタではちゃんと「*」が出力されているのに…テキストエディタ上では「(」になってしまいます
※別のスケッチでテストした際の画像です

これは #include "Keyboard.h" した際のキーボードレイアウトが KeyboardLayout_en_US になってて…まぁいわゆる US キーボードってやつですかね これが日本で一般的に使われている JIS キーボードとレイアウト(キーの配置)が違うから起こる現象のようです
アルファベットと数字に関しては問題ないのですが…記号はその多くが US と JIS とで配列が違うんで問題になります

202202201033061-admin.png
先ほどの「*」を例にすると… US キーボードでは「*」が「8」のキーに割り当てられています

20220220103306-admin.png
そのキーコードを 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

情報 <7955文字>

イワタニ CB-JCB ジュニアコンパクトバーナー

20220207163518-admin.png
 
クレジットカードの使いすぎっていうか…ポイントがどっさり貯まっててそれが失効しそうってご連絡を頂いたんで慌ててポイント交換して イワタニ CB-JCB ジュニアコンパクトバーナー をげっちゅしました

2022020716351811-admin.jpg
ハードケース入りのコンパクトなやつ

2022020716351810-admin.jpg
このテのバーナーは 新富士バーナー の SOTO ST-300 ってのを永らく愛用しています セパレートなんで置き場所の自由度が高くてよかったんだけど…頑丈なバーナー部が災いしてなのか 600g というずっしり感のある重さがちょっとネックだったんですよね セパレートの自由度は利点である反面…セッティング/片付けがちょっと面倒なんもあって愛用してたと云いつつ使用頻度はそれほど高くありませんでした(汗

そんな訳なんで…半分以下の重量の CB-JCB には期待しちゃってます!(>_<)w

202202071635188-admin.jpg
それでは早速セッティングしてみましょう まぁ脚をパタパタパタと広げて…ゴトクをパタパタパタパタと広げて CB 缶をブッ挿してねじって完成!って感じなんで説明する間もありませんが

202202071635186-admin.jpg
せっかくガスバーナーを持ち出してきたのにカプ麺じゃ少々味気ないかな…って事なんで今回は袋麺を作っちゃう!

202202071635184-admin.jpg
できたw おいしいwww この日は強烈な伊吹おろしが吹き荒れる天気で…まぁ物陰に隠れてはいたもののそれなりに風が巻き込んできてたけど問題なく使用できました

202202071635183-admin.jpg
今回は丸型のコッヘルを使ったのですが…このゴトクの使い勝手がいいっていうかコッヘルの座りがよく安定感を感じました

202202071635185-admin.jpg
段々にカットされているのでスッポリと納まる感じですかね

202202071635182-admin.jpg
ざっくり測った感じでは 15cm のコッヘルまではズバピタに収まって使えるみたいです 逆に…長方形のコッヘルっていうかメスティンとかだとどんな使い勝手になるんだろ?って思ったりしていました

  :

202202071635189-admin.jpg
使い終わったらお片付けって事なんだけど…付属のハードケースに入れた際に数ミリ程度の隙間があって「ガタゴト」と揺れまくるんですよね 現実的な対策として軍手で包んだ後にハードケースに納めるといい感じになりますね

202202071635181-admin.jpg 20220207163518-admin.jpg
そう云いつつ…我が家では某Dイソーで買ってきた重ねられる箱に CB 缶と共に入れて使おうかと思ってます カバンやザックのなかでゴロゴロしがちな CB 缶をスマートに持ち歩けるようになると期待しています

202202071635187-admin.jpg
あとオマケ的な話だけど…安っすい 遠赤ヒーターアタッチメント も持ち歩くようにしています これをゴトクにセットして燃焼開始すると…遠赤外線が発生して程よい暖房になるって感じらしいです まぁ確かに直火に手をかざしているより段違いに暖かいような気がします なんならこの上にコッヘルを載っけてお湯を沸かしたりとしても使えるようです

どうなんだろね よっぽどな時の非常用なのかなーってイメージですが…むっちゃ寒い真冬のキャンプツーリングなんかで威力を試せたらなぁって思います #アウトドア

趣味 <1266文字>

Arduino の シリアル通信

20220130153543-admin.png
 
Arduino VKLSVAN Pro Micro USB ATmega32U4 (※以下 Arduino と略す)で開発してる際のデバッグとかで「変数がどうなってるのか」を見たくなることはありませんか? 私はあります いやむしろ見ないとやってられません!!(>_<)wって感じなんだけど Arduino にはモニタ出力がありません

20220130153543-admin.jpg
なんか LCD ディスプレイとやらを接続すれば文字なんかを表示させられるっぽいけど…接続とか面倒そうだし手が出ないなぁと思ってたけど何やら「シリアル通信」ってので PC と文字のやりとりができるらしいじゃん!? まじか!!

そんなシリアル通信は Arduino IDE から使えるようです

202201301535436-admin.png
[メニュー] → [ツール] → [シリアルモニタ] と操作するか…

202201301535435-admin.png
もしくはツールバーにある虫メガネみたいなアイコンを押下すると出てきます

202201301535434-admin.png
出てきた「シリアルモニタ」はこんな感じです
我が家の環境では「改行コード = 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 秒待って繰り返し
}

----------

202201301535431-admin.png
これは 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");
    }
  }
}

----------

202201301535433-admin.png
シリアルモニタに適当な適当な文字(列)を入力して「送信」します

202201301535432-admin.png
送信した文字に「数値」があればその数だけ 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

情報 <3825文字>

吉野家・豚生姜焼き丼

20220123055712-admin.jpg
 
生姜の刺激的な味がとにかく効いてる 吉野家豚生姜焼き丼 を食べてきました
生姜の風味がたっぷり味わえる生姜焼きが丼でお手軽に頂けちゃう! そこに更におろし生姜まで載っててイイネ! 寒い時期にうれしい身体がポカポカ温まる美味しさです
大きめカットの白ネギの風味もアクセントとなり最後まで飽きること無く楽しめる!

定番メニューなのか季節限定メニューなのかはちょっとよく判らない感じですが…冬に嬉しいお味なんでまた早いうちに食べに行きたいです! #外食記録

日記 <243文字>

かつや・デミチキンカツ丼

20220116101003-admin.jpg
 
かつや の期間限定! 濃厚デミグラスソースにチーズのコクがたまらない デミチキンカツ丼 を食べてきました
オーダーして…厨房から漂ってくるデミグラスソースの香りからして気分が盛り上がってきます そして丼を覆い隠さんばかりのチキンカツが 2 枚! そこに豚肉たっぷりなデミソースがかかっています!

最初はデミソースがかかってないサックリした部分のチキンカツから楽しみ…お次はデミソースがかかったしっとりした衣を楽しむ流れがイイネ!
たっぷり豚肉も食べ応えあってたまりません! もちろん刻みキャベツも入っているし飽きること無く最後まで楽しめます
いやむしろ具だくさんすぎてご飯とのペース配分が困難すぎますねw これは丼より…ちょっと奮発して定食にしたほうが余すとこなく味わえるのかなーって思いました

期間限定なのが惜しい逸品です! また近いうちに食べに行きたいです #外食記録

日記 <404文字>

DASHBOARD

■複合検索:

  • 投稿者名:
  • 投稿年月:
  • #タグ:
  • カテゴリ:
  • 出力順序:

■ハッシュタグ:

■カテゴリ:

■日付検索:

■機器状態:

Raspberry Pi 4 Status

編集

RSSフィード