t-hom’s diary

主にVBAネタを扱っているブログです。

久々にLinuxからGitHubアクセスしたらパスワード認証できなくなっていたので対処した件のメモ

私は普段Windows 10からコマンドラインのGitでGitHubにアクセスしているが、たまにラズパイまわりの開発をする際にOracle VirtualBox上に作成したラズパイOSの仮想環境からGitHubにアクセスしたい場合がある。久々にこれをやってみたらパスワード認証は去年8月以降できなくなったからアクセストークンを使えというエラーが出た。今回は主に自分用のメモとして事象の解決策を残しておくが、一応読者を想定して適宜解説も織り交ぜようと思う。

remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://github.com/thom-jp/health-tracking-pi.git/'

指示どおりアクセストークンを作ってみた結果、push・pullする度にユーザー名とパスワードを聞かれて煩わしい。
もう一つの方法としてSSH接続すればOKということが分かった。

SSHについて

SSH = Secure Shell…リモートアクセスを安全に行うための通信方式(プロトコル)。
暗号化に使う公開鍵と、復号化に使う秘密鍵によって通信の安全や本人確認が担保される。

今回、公開鍵はGitHubにアップロードするが、秘密鍵は自分しか知らない。

閉める鍵と開ける鍵が別というのはよく南京錠に例えられる。
イメージとしてはこんな感じ。
f:id:t-hom:20220114040707p:plain

SSHキーペアの作成作業

次のコマンドでSSHキーのペア(秘密鍵・公開鍵)を作成する。

(1) $cd ~/.ssh
(2) $ssh-keygen -t rsa
(3) Enter file in which to save the key (/Users/(username)/.ssh/id_rsa):
(4) Enter passphrase (empty for no passphrase): 
(5) Enter same passphrase again: 

(1) の説明

sshの鍵は基本的に置き場所が決まっている。
ユーザーのホームフォルダにある.sshというフォルダ内に作成するためまずそこに移動するコマンドがこちら。

(2) の説明

sshの鍵ペアを作成している。-tはタイプ指定オプションで、ここではRSAという暗号化方式を指定している。

(3) の説明

(2)の実行結果としてキー名を質問されるので、何も入れずにEnterを押す。
するとデフォルトで()内に掛かれたid_rsaという名称になる。

(4) 、(5) の説明

秘密鍵にパスフレーズを付加できる。
Linuxログイン用ならパスフレーズを付けた方が良いが、今回はGitHubアクセスで、ここでパスフレーズを付けてしまうとpush/pull操作ごとにパスフレーズの確認が入る可能性がある。(試してない)
今回は趣味開発だし、秘密鍵が流出するリスクも低い※のでパスフレーズは付けずにそのままEnter。

パスフレーズとは

ワードじゃなくてフレーズとなっているのは、かなり長い文字列を付けられるから。
複雑な文字を組み合わせた短いパスワードよりも、アルファベットで構成される超長いパスフレーズのほうが強固で覚えやすいというメリットがある。
例えばこんな感じ「koreharaspberrypikaragithubhenoaccessyoupasufure-zudesu.」※これはRaspberry PiからGitHubへのアクセス用パスフレーズですと書いてる。
長くできる為、逆に覚えやすい意味のあるフレーズを登録できる。

リスクの考え方

A) リスク=資産×脅威×脆弱性

今回の場合、
資産…資産価値のあるものは扱っていないため低い
脅威…昨今IoTを狙った攻撃が多いらしいが、外部公開してるサーバーではないため脅威は中程度
脆弱性…アップデートも定期的にしているので低い
よってリスク低と判断。

B) リスク= 発生確率 × 影響

今回の場合、
発生確率…外部公開してるサーバーではなく、アップデートも定期的にしており、秘密鍵をサーバー外に持ち出すことは無い為、流出の発生確率は低い。
影響…万が一発生したとしても資産的ダメージは無く、風評被害に繋がるような情報も保有していないため、影響は低い
よってリスク低と判断。

完成した鍵

名前を指定しなければ、id_rsaとid_rsa.pubという二つのファイルができる。
このうち.pubとついた方がGitHubに登録する公開鍵(Public Key)である。
※Pubとついてない方は秘密鍵なので外部にアップロードしてはいけない。

公開鍵の登録作業

公開鍵はただの文字列なので適当なテキストエディタで開いてコピーすることができる。
私はxclipというクリップボードツールを導入して内容をコピーした。

次にGitHubにWebからログインしてSSH設定ページにアクセスする。
https://github.com/settings/ssh

右上のNewSSH Keyと書かれたボタンをクリックする。
f:id:t-hom:20220114044016p:plain
※私の場合は既に登録済なので表示されているが、一応伏せておいた。

Title欄は任意なので端末名や用途等を自分でわかるように記載する。
Key欄にはコピーした公開鍵テキストを貼り付ける。
f:id:t-hom:20220114044142p:plain

SSHでのアクセステスト

次のコマンドを実行。

ssh -T git@github.com

初めてSSHで接続する相手の場合は次のように聞かれるのでyesと入力してEnter。
Are you sure you want to continue connecting (yes/no)?

こんな感じで接続成功メッセージが出たらOK。
Hi thom-jp! You've successfully authenticated, but GitHub does not provide shell access.

なお、私は一発成功したので失敗時の対策は説明できない。必要な方がいたらご自身で検索してみると対処方は見つかると思う。

リモートリポジトリへのアクセス手段切り替え作業

前述の設定をしただけではSSHアクセスにならず、引き続きパスワードを聞かれるので、これもちょっとハマりポイントだった。
どうやら最初にGitHubからCloneしてきたときにHTTPSを選択しているとGitクライアントがそれを記憶しているようで、SSHに切り替える必要があった。

目的のリポジトリのCodeボタンからメニューを開き、SSHを選択するとURLが表示される。
f:id:t-hom:20220114045424p:plain

そして次のコマンドでリモートリポジトリを切り替える。

git remote set-url origin ここにコピーしたSSH URLを貼り付け

これで全作業完了。
以降は普通にpush/pullできるようになる。

以上

趣味の開発で使えるGitHubのブランチ運用

今回はGitHubの話。
基本的な使い方は入門書がいくらでも出ているので今更私が解説するまでもないけど、ブランチ運用については腑に落ちるまで少し苦労したので今回は自分流のブランチ運用をメモとして残しておこうと思う。

ガチの開発勢から色々と文句を言わるかもしれないけど、趣味開発なのでご容赦願いたい。

thomの2ブランチ開発フロー

私は次の表の1~8のような流れで開発を進めている。
このブログの読者はExcelマクロ開発者が多いのでバージョン管理システムを使わないExcel開発を例えとして挙げてみた。対比させるとGitでやっている作業が何をしているのか少しは分かりやすいかなと思う。
f:id:t-hom:20220109222609p:plain

本来は2~4を繰り返してこまめにdevブランチを更新しつつ、ある程度キリの良いところで充分にテストをしたうえでmasterへ取り込むんだけど、なんせ一人で開発していてユーザーも大抵自分ひとりというケースが多いので、すんなり動いているうちはdevに保存したらそのままmasterへも取り込むという運用をしている。

そう聞くとdevブランチを使うメリットってよく分からないかもしれないが、開発でソースコードがぐちゃぐちゃになって動かなくなったときに、どこまでバックアップを遡るか等と頭を悩ませることなく、単純にdevの更新をまるっと捨てていつでも完全動作するmasterに戻れるという安心感が大きなメリットとなる。masterがチェックポイント的な役割を果たすので、devの方は思い切った変更ができる。

thomの3ブランチ開発

実際にはmaster/dev以外にfeatureブランチという機能開発用のブランチを作成する場合がある。
この場合はmasterが公開版なのである程度まとまった機能単位でしかmasterは更新せず、devが手元で色々機能追加したりとりあえず自分が使ってみる段階のベータのように取り扱う。
実際の開発の際にはGitHubのIssue機能でIssue番号を発行してそのIssue番号のfeatureブランチを作成し、開発成功してdevにマージした時点でfeatureブランチは削除し、GitHub上のIssueもクローズする。

おわりに

今回私のGitHubブランチ運用を紹介した狙いはGitHubに興味をもって勉強してみたけどイマイチ実際の運用が腑に落ちない趣味勢へ情報を届けることである。(かつての私)

私が困っていたのは、具体的な使い方は書籍が出ているけど、機能紹介・操作紹介にとどまっているものが多くて実際の開発フローが分からなかったから。探せば開発フロー紹介もあるんだけど、ガチすぎて最初のブランチ運用に取り入れるにはちょっと気が重かった。

特によく分からなかったのはローカルにもマージ機能があって、GitHubにもマージ機能があって、それぞれどのタイミングでするのかということ。Gitの書籍読むとローカルでやってるけどGitHubの書籍ではプルリクしていてその後は?みたいな混乱があった。

私はプロの開発者ではないので、もし使い方間違ってたら申し訳ない。
ただ、私は便利に使えてるのでとりあえずこれで満足である。

以上

DualShock2KeyCommandのGitリポジトリPublic化と最近のリファクタリング

今日はPS4コントローラーをマクロキーボードとして使うプロジェクト「DualShock2KeyCommand」のリポジトリをPrivateからPublicに変更した。

github.com

これまでPrivateにしていたのはゴリゴリに私用に特殊な設定をハードコードしてるのでPublicにしても別に誰も見ないだろうということだったんだけど、エゴサでブログを参考にしたという話を見たのでコードも公開することにした。
※ブログでは前からコード全文載せてるので利便性が上がったくらいだと思うけど。

ついでに最近のリファクタリングについて

東方モードと称して次のようなキーバインドを登録していたんだけど、いかんせん縦長で全体の閲覧性が悪い。

void mode_touhou(){
  if (PS4.getButtonPress(CROSS)) {
    Keyboard.press('z');
  } else {
    Keyboard.release('z');
  }

  if (PS4.getButtonPress(UP)) {
    Keyboard.press(KEY_UP_ARROW);
  } else {
    Keyboard.release(KEY_UP_ARROW);
  }
  if (PS4.getButtonPress(RIGHT)) {
    Keyboard.press(KEY_RIGHT_ARROW);
  } else {
    Keyboard.release(KEY_RIGHT_ARROW);
  }
  if (PS4.getButtonPress(DOWN)) {
    Keyboard.press(KEY_DOWN_ARROW);
  } else {
    Keyboard.release(KEY_DOWN_ARROW);
  }
  
  if (PS4.getButtonPress(LEFT)) {
    Keyboard.press(KEY_LEFT_ARROW);
  } else {
    Keyboard.release(KEY_LEFT_ARROW);
  }

  if (PS4.getButtonPress(R1)) {
    Keyboard.press(KEY_LEFT_SHIFT);
  } else {
    Keyboard.release(KEY_LEFT_SHIFT);
  }
  
  if (PS4.getButtonClick(L1)) {
    Keyboard.press('x');
    delay(40);
    Keyboard.releaseAll();
  }

  if (PS4.getButtonClick(TRIANGLE)) {
  }
  
  if (PS4.getButtonClick(SQUARE)) {
    Keyboard.press('c');
    delay(40);
    Keyboard.releaseAll();
  }
  
  if (PS4.getButtonClick(OPTIONS)) {
    Keyboard.press(KEY_ESC);
    delay(40);
    Keyboard.releaseAll();
  }
}

例えば一番上のif文はコントローラーの×ボタンが押されていたらzを押して、押されていなければzを離すという処理をストレートに記述しているんだけど、まだまだマシン寄りの記述なので具体的すぎてノイズが多い。もう少し抽象度をあげて人間に優しいコードを目指した結果、こうなった。

void press_sync(ButtonEnum pad, char key) {
    if (PS4.getButtonPress(pad)) {
      Keyboard.press(key);
    } else {
      Keyboard.release(key);
    }
}

void click_sync(ButtonEnum pad, char key) {
  if (PS4.getButtonClick(pad)) {
    Keyboard.press(key);
    delay(40);
    Keyboard.release(key);
  }
}

void mode_touhou(){
  press_sync(CROSS, 'z');
  press_sync(UP, KEY_UP_ARROW);
  press_sync(RIGHT, KEY_RIGHT_ARROW);
  press_sync(DOWN, KEY_DOWN_ARROW);
  press_sync(LEFT, KEY_LEFT_ARROW);
  press_sync(R1, KEY_LEFT_SHIFT);
  click_sync(L1,'x');
  click_sync(SQUARE,'c');
  click_sync(OPTIONS,KEY_ESC);
}

ボタンとキーを同期させるためのpress_syncとclick_syncという関数を作って、メインコードでは「×ボタンとzボタンを同期させろ」という、より人間目線でのやりたいことに近い書き方に変更。

ちなみにこれによって共通処理が一個所にまとまったが、これは副次的な効果にすぎない。共通化それ自体を目的としたコーディングは依存地獄を生みやすいので十分に注意が必要。

今後のリファクタリングの方向性

昨日ヨドバシで次の書籍を購入したので、Arduinoでもオブジェクト指向を取り入れてメンテナンス性の高いコーディングをしたいと思う。

具体的にはPS4コントローラーを継承して動作モードとLEDカラー設定をオブジェクト側に持たせたり、マウスを継承して小数点以下の移動管理をメインコードからマウスオブジェクト側に寄せたりといったことを考えている。

リファクタリングで気を付けたいこと

関数とかクラスを覚えたばかりで陥りがちなのが、メインコードのシンプル化が目的化して複雑さをほとんどクラスや関数に追い出した結果、関数やクラスが肥大化してメンテナンス性が低下するという事象。

コードには「余計な複雑さ」と「必要な複雑さ」があるので、「上手くやれば複雑さはすべて消し去ることが出来る」というのは誤解で、「必要な複雑さはどこかには残るのでバランスよく分散させて薄める」のが正解じゃないかと思う。

自作PCのメリット・デメリットとパーツの選び方について

パソコン好きな方は一度は自作を考えたことがあると思う。
自作マニアが良質な記事をたくさんあげている中で、人生でまだ3台しか作ったことがない私がこんな記事を書くのもどうかと思うんだけど、まぁ作ったからには語らずにはいられない、それが自作PCというものである。

私が感じたPC自作のメリットとデメリット

メリット

コストパフォーマンスの良いPCを作れる

これはある程度のパフォーマンスを求めた場合に、パフォーマンスの割には相対的に安いという意味であって、絶対的な価格が安いというわけではない。
YouTubeくらいしか見ないという方にはむしろ高くつく。
3Dゲーム・動画編集・機械学習・仮想通貨マイニング・3Dレンダリング等の重い処理をしない場合はコスパは感じられないと思う。

見た目に拘ることができる

ケースが自由に選べるのが大きい。ただ拘ると高くつくので予算に余裕がある方向け。
ケースは五千円~五万円くらいまでピンキリだけど、私が好きなのはシンプルな白いNZXTのケース。

※写真がカラフルなのはLEDコントローラーがついてますよという意味か、そこにガラスがありますよというアピールなので別にレインボーカラーではない。

スペック不足を感じた時にある程度の拡張性がある

ある程度というのがポイント。嘘ではないんだけどちょっと勘違いさせがちな誇張も見られるので注意。
メモリやSSDは簡単に増やせるんだけど、CPUは基本的に同世代の上位モデルのみ、グラボも制限はないけどCPU性能が低いと性能を十分に発揮できないのでCPUの世代交代が進んでいくといつかは対応マザーボード・対応CPU・グラボを交換することになると思う。
とはいえ既製品に比べればかなり自由が利く。

デメリット

高い

既製品が10万以上してたころは作ったほうが安いなんて噂もあったけど、今は安ければ3万くらいで売ってるので動画視聴用とかなら買ったほうが安い。

面倒くさい

パーツをはめ込むだけだから簡単と思ってたら結構時間かかる。
初めての場合は2時間が目安らしいけど、キットでマニュアル完備ならともかく、自分で部品をそろえた場合は3~4時間みといた方が良い。

これは一応デメリットとして挙げておくかというレベルではなくて、マジで面倒くさい。
特に1台目は勝手が分からないなかマニュアルも不親切でよく分からないし、ケース内は暗くてよく見えないし、力加減分からないし、解説動画を途中停止しながらがんばることになる。
ただ裏配線のコツをつかんで綺麗にできるようになると楽しくなってくる。

デカいので邪魔

基本的にデスクトップなので大きい。
初めて組む人はコンパクトなサイズに憧れがちだけど、手が入らなくて作業性が悪いし、熱が籠りやすくてハイスペックに向かないし、拡張スロットも少ないので自作のメリットである拡張性を享受しにくい。ので、あんまりおススメしない。
ミドルタワーサイズがおススメだけど、金に糸目をつけずハイエンドを組みたいという場合は最初からフルタワーが良いかもしれない。
グラフィックボードはファン数が多いほうが冷えるけど、3連ファンの大きなグラボだとミドルタワーで入らないケースがある。

パーツ故障時に困る

既製品が壊れたら、「壊れた、直してくれ」と依頼すれば済むんだけど、自作の場合パーツごとにパーツメーカーとやりとりになるのでとても面倒くさい。こういう症状なら多分この部品って感じで当たりをつけたり、自分で診断したりできない場合はPC専門店に診断をお願いすることになるが、診断料金だけで1万円くらいするようだ。
support.tsukumo.co.jp

まぁトラブル対応は自分で調べれば知識も付くし、その辺も含めて自作の面白さではあると割り切るしかない。
一応、金をつめば救済措置はあるよって話。

パーツの選び方

初めての場合、一番のおススメはキットを利用すること

以前はドスパラで自作のキットを取り扱っていたので私はそちらを利用した。
残念ながら今は販売終了してるようだが、似たようなサービスを展開しているショップがあるのでそういうのを利用すると良いと思う。

(参考)PCデポ
www.pcdepot.co.jp

予算と用途を伝えて基本構成を店員に選んでもらうのもアリ

ショップの選び方

家電量販店も最近はPCパーツコーナーがあるけど、あまりお勧めはしない。
店舗によっては詳しい人がいたりもするんだけど、販売員の知識面でどこまで力を入れているのか分からない為。
個人的にはツクモの対応が良かったのでお勧めしておく。

予算を考える

最低ラインがOS込みで10万円。(モニターは別)
やりたいことが明確で必要スペックを熟知している場合は更に抑えられると思うけど、知識が無い場合はおススメしない。

10万のPCなら、3Dゲームも画質をすこーしだけ落とせばそこそこ動く。建築要素がある3Dゲームとかだと、描画オブジェクトが増える後半でラグが増えてくるけどまぁ我慢すれば遊べるといった感じ。マイクラは素の状態なら余裕で動く。影MODも軽量なやつなら結構さくさく動く。巨大建築は厳しいかもしれないけど。
といってもこれ2017年購入の10万円PCの話なので、今の10万円だともうすこし良いスペックかもしれない。

3Dゲームを高画質で快適に遊びたいなら最低15万円。更に見た目も拘りたいなら20万円といったところ。

店員に選んでもらう

予算がいくらでやりたいことがコレって言えばバランスよく構成してくれる。
あとは今使っているPCがあれば構成と不満点(≒強化したいところ)を伝えると良い。

パーツに拘りがあればそれも伝えると良いけど、知識がなければCPU・GPU・電源・メインボードなどで特定の部品を限定して伝えるのはあんまりおススメしない。

PCは部品同士のスペックバランスがとれてはじめてパフォーマンスを発揮するので、求めるゲームスペックでGPUとメモリ容量が決まり、GPUとのバランスでCPUが決まり、CPUによってマザーボードが決まり、それらの消費電力で電源容量が決まるという風に色々関連しているので下手に口出してバランスが崩れても性能を発揮できない。

見た目の好みと使用シチュエーションの詳細や、将来的な拡張予算や何年使うつもりか等よくコミュニケーションをとりつつ、基本的にはプロにお任せのほうがバランスよく仕上がる。

どうしても自分で選びたい場合

まずは「10万円 ゲーミング 自作PC」「10万円 動画編集 自作PC」等と検索してみると構成を紹介するサイトが見つかるので、それを丸っとパクって仮構成とする。

やりたいゲームや動画編集ソフトの公式サイトから、推奨スペックを確認する。
(必要スペックはあまり参考にしないほうがいい。基本的には、色々我慢すれば動くけどちょっとしんどいよ?って意味なので、ゲームだと最低画質で何とか。通常画質だとすこしカクつく、最高画質だと落ちるかゲームにならない。)

次に性能比較サイトで仮構成のCPU・GPUの位置づけを見る。
btopc-minikan.com
pcfreebook.com

予算と相談してアップグレード・ダウングレードを検討する。
使用したいソフトの推奨スペックを下回らないように注意。また最近のゲームはオンラインでパッチが適用されて機能強化によって重たくなることもあるので少し余裕を見ておきたい。
CPUとGPUのバランスは以下のようなサイトでチェックできる。
bablishe.com

CPUが決まったら対応するマザーボードを選ぶ。
PCに詳しくないとなんでもいいんじゃないかと思いがちだけどマザーボードは対応CPUが明確になっているので使えるマザーボードの種類はCPUのメーカーとCPUの世代で決まる。あとケースをミドルタワーにするならマザーボードのサイズはATXが良い。小さいのも入るけど、あえて小さくするメリットはない。

マザーボードは拡張性を決める部品だけど、性能という意味ではあまり差を感じにくい。
1~2万くらいのもので十分と言われているのでCPUに対応する比較的新しいものであれば、個人的には何でも良いんじゃないかと思う。

拘る必要があるシチュエーションはこんな感じ。

  • Wifi機能が欲しい
  • グラボ2枚指したい
  • 光らせたい
  • USBポートが沢山ほしい
  • CPUをオーバークロックしたい
  • 次の世代のCPUにアップグレードする可能性がある

初期構成としてSSDは最低500GB、メモリは16GBあると安心。
あとハードディスクはお好みで。
CPUクーラーは純正でも良いけど中が見えるケースだとダサいのでお好みで。

電源容量は以下のようなサイトで計算できる。
www.dospara.co.jp

最後にケース。これもマザーボードが入ればなんでも良いんだけど、あとは好みと前面パネルのインターフェース(USBポートとか)で決めれば良いかと思う。

まぁそうやって自分で選ぶのは楽しいけど、失敗しない為にはやはり構成を書きだしてショップにもっていって最後バランス調整を依頼したほうが良いと思う。予算もう少し足せるので強化するとしたらどこ?とか、予算オーバーしたいので削るとしたらどこ?といった相談ができる。

組み立て

組み立ては正直なところ面倒くさいし、最初は全然楽しめなかった。
1台目で何が一番嫌かというと、力加減が分からないこと。結構取り付け・取り外しが硬い部品があって(特にケース)、取れないけどこれ以上力入れて大丈夫か分からない。バキって音がしたけどこれで正解だったとか、逆に壊れたとか色々とトラブルが起きる。
あとコネクタが硬かったり最後カチって音がしないのでこれで刺さってるかどうか分からないのがあったり、なんかモヤっとするシーンが多かった。
まぁ2台目・3台目ともなれば「こんなもんだ」というのが感覚でわかるのでそれほど苦でもないんだけど。

最近はYouTubeとかで組み立て動画があるので、初めての方は説明書だけじゃなくて動画をよく見ながらやると良いと思う。

配線は最初はしんどいだけなんだけど、ケースの設計を理解して綺麗に配線できるようになるとそこそこ楽しくなってくる。

私の自作経験

1台目はドスパラのキットでこんな感じの構成だった。
f:id:t-hom:20211230123713p:plain

ゲーム性能としてはマイクラの軽量影モッドがそこそこ動くかなといった感じ。あとCities Skylinesも序盤はサクサク。後半はCPU不足で車の移動速度がかなり遅くなる。Satisfactoryが30FPSくらいなので滑らかではないけど動く感じ。

一応ゲームも楽しめるしまぁ悪くは無かったんだけど、1点割と不満だったのがケースのデザインが安っぽくてダサいこと。
それでケースだけ買うつもりで探してたらNZXTシリーズを発見し、片面ガラス張りで中身が見えるため他のパーツも拘ることに。

そして考えたのが次の構成。
f:id:t-hom:20211230124614p:plain

予算を20万円ほど確保してとりあえず売り切れ間近だったマザーボードとケースを確保。
さっき書いたパーツの選ぶ順序と全然違うけど、見た目超重視だったのでケース→マザーと選んだあとに1台目からデグレしない程度のパーツを購入予定品に選定し、その後にアップグレード要件と実際の候補を選んだ感じ。)

あとは店員に予算を伝えてバランス見てもらい、CPUはIntel Core i5 9600KF、グラボはNvidia GTX 1660 Super、あとは全部アップグレードしても予定どおり17万円くらいにおさまったのであまった予算で見た目重視のNZXT製の簡易水冷クーラーを購入した。
これが今のメイン機。

3台目は2台目が故障して起動しなくなった際にメモリか・メインボードか・CPUか電源かと切り分けるために別のパーツを購入。どうせならもう1台組んでしまえば。。そうだRyzenにしよう!というノリで作った。結果、どれ変えても直らずグラボのせいでしたというオチ。
3台目はしばらく和室において使ってたけど利用が定着せず結局2台目の再故障に備えたバックアップとして押入れで待機中。

まとめ

  • 面倒だけど楽しい
  • 金がかかる
  • 全部自分で決めなくていい、プロに相談しよう

以上

Arduino LEONARDOでPS4コントローラーをマウスとして使う

今回はPS4コントローラーのジョイスティックでマウスカーソルを操作するArduinoコードのご紹介。

もともとPS4コントローラーはマクロキーボードとして使っていたのだが、シューティングゲーム(東方シリーズ)でも使いたくなってモード切り替えできるようなコードを作成していた。
thom.hateblo.jp

今回はそこにマウスモードを機能追加してリクライニングチェアにもたれながら快適にPC操作ができるようにするのが目的。

コード

モード追加されたコード全量を載せると500行近くになるのでマウスモード単体機能で検証した際のコードを掲載する。

#include <Keyboard.h>
#include <Mouse.h>
#include <PS4USB.h>
#include <math.h>
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
float accm_x = 0;
float accm_y = 0;
float accm_w = 0;

USB Usb;
PS4USB PS4(&Usb);

uint8_t oldL2Value, oldR2Value;
uint8_t oldRightHatX, oldRightHatY;

void setup() {
  if (Usb.Init() == -1) {
    while (1); // Halt
  }
  Mouse.begin();
}

void loop() {
  Usb.Task();
  float r = 0;
  float x = 0;
  float y = 0;
  int dev = 64;
  
  if (PS4.connected()) {
    y = PS4.getAnalogHat(LeftHatY)-128;
    x = PS4.getAnalogHat(LeftHatX)-128;
    r = sqrt(pow(x,2) + pow(y,2));
    if (PS4.getButtonPress(R1)) {
      dev = 64;
    } else {
      dev = 8;
    }
    if (r > 5) {
     accm_x += x / dev;
     accm_y += y / dev;
     Mouse.move((int)accm_x, (int)accm_y, 0);
     accm_x -= (int)accm_x;
     accm_y -= (int)accm_y;
    }
    if (PS4.getButtonPress(CROSS)) {
      Mouse.press();
    } else {
      Mouse.release();
    }
    if (PS4.getButtonPress(L1)) {
      Keyboard.press(KEY_LEFT_CTRL);
    } else {
      Keyboard.releaseAll();
    }
    
    int r2 = PS4.getAnalogButton(R2);
    int l2 = PS4.getAnalogButton(L2);
    if (l2) {
      accm_w += (float)l2/4096;
      Mouse.move(0, 0, (int)accm_w);
      accm_w -= (int)accm_w;
    }
    if (r2) {
      accm_w += (float)r2/4096;
      Mouse.move(0, 0, -(int)accm_w);
      accm_w -= (int)accm_w;
    }
    if (PS4.getButtonClick(OPTIONS)) {
      Keyboard.press('f');
      delay(40);
      Keyboard.releaseAll();
    }
    if (PS4.getButtonPress(UP)) {
      Keyboard.press(KEY_PAGE_UP);
    } else {
      Keyboard.release(KEY_PAGE_UP);
    }
    if (PS4.getButtonPress(RIGHT)) {
      Keyboard.press(KEY_RIGHT_ARROW);
    } else {
      Keyboard.release(KEY_RIGHT_ARROW);
    }
    if (PS4.getButtonPress(DOWN)) {
      Keyboard.press(KEY_PAGE_DOWN);
    } else {
      Keyboard.release(KEY_PAGE_DOWN);
    }
    
    if (PS4.getButtonPress(LEFT)) {
      Keyboard.press(KEY_LEFT_ARROW);
    } else {
      Keyboard.release(KEY_LEFT_ARROW);
    }
  }
}

カーソル移動のアイデアと解説

座標取得

まずPS4.getAnalogHat(LeftHatY)の部分はPS4の左アナログスティックのY軸の値を求めているコード。
0(左端)~255(右端)で取得されるので半分の128を引くことで中央が0となり、-128 ~ 127の座標に変換できる。
(Xも理屈は同じなので説明省略)

r = sqrt(pow(x,2) + pow(y,2))は、三平方の定理を使ってスティックの押し込み距離を求めているコード。
これは以下の記事で紹介したコードと同じである。
thom.hateblo.jp

r値はジョイスティック未入力時の誤反応を防ぐために遊びを持たせる距離を測るのに使っている。

カーソル変速

R1ボタンの押し下げ状態でdevという値を64と8で変えている部分は、カーソルスピードを変更しているコード。
ちなみにdevはスペルミス。。(divisionのdivとするつもりだった) 手元のコードはそのうち修正しようと思う。
座標軸の最大値がマイナス方向に128なのでそれを64で割ると2となる。
これはスティックを左に倒し切っているときループ1回に2ドットカーソルが動くということになる。8で割ると16なので16ドット/ループになる。
つまり変数devが小さい方が速い。

このように高速・低速を切り替えるアイデアはシューティングゲーム(東方シリーズ)からヒントを得た。
これでマウス並みとはいかないまでも速度と精度のバランスを取って扱いやすくなった。

移動時の実数の取り扱い

前述したとおり、スティックを左に倒し切っているときにループ1回に2ドット移動する。
ということは、スティックの押し込みが半分ならループ1回に1ドットであるが、更に半分だとどうなるか。
0.5ドットという単位は存在しないので、移動できない。

十字方向だけなら1ドット単位でもなんとかなるが、任意の角度に移動しようと思うとやはり実数で移動させたい。
そこでaccm_x, accm_yというfloat形の変数に移動距離情報を一旦実数でストックするというアイデアを思いついた。

accm_x += x / dev;
accm_y += y / dev;
Mouse.move((int)accm_x, (int)accm_y, 0);
accm_x -= (int)accm_x;
accm_y -= (int)accm_y;

そして、カーソルはaccm_x, accm_yの整数部だけを参照して移動を行い、移動した整数量はaccm_x, accm_yから取り除く。
そうすれば小数部を捨てずに貯め続けて整数になったら移動に使うということができる。

これは画期的!と暫く自画自賛してたんだけど、よくよく考えたら市販のマウスかOSのドライバー側でも似たような処理をしてるはずで、そうでないと斜め移動できないよな。。

以上

回路基板のエッチングに初挑戦

今回は実際の銅張積層板をエッチングして回路パターンを作成してみる。
つまり過去4記事にわたって準備してきたことの総集編である。

これまで準備してきたこと

thom.hateblo.jp
thom.hateblo.jp
thom.hateblo.jp
thom.hateblo.jp

今回の作業

やってることは過去記事の応用なのでさくっと紹介していく。
写真を取り忘れたステップも多いけど準備記事見ていただければイメージ湧くと思う。

まずは銅張積層板にタミヤの艶消し黒を吹きかけて乾かした基盤をPカッターで傷をつけて半分に割る。
f:id:t-hom:20211105162402p:plain

割ったのは今回初めてだが、結構大変だった。傷をつける段階で40~50ストロークくらいしたかな。。もう少し力を込めれば早かったかもしれない。
それと傷をつけるときに終端部で刃がカッターマットに落ちるが、カッターマットは普通に傷がつく。木か何か敷いた方がよかったかも。

レーザーで回路パターンを書き込む(塗膜を焼く)。
パターンの形に銅がピカっと露出するまで食器用洗剤と指の腹で洗う→タミヤコンパウンド粗目で磨くを何度か繰り返す。やりすぎて必要な塗膜を削りきらないように注意。
f:id:t-hom:20211105162914p:plain

エッチング液を作って基盤を浸す。今回の配合はオキシドール25ml、クエン酸 7.5g、塩化ナトリウム 1.5g。

今回はアジシオじゃなくて本気のやつを準備した。
f:id:t-hom:20211105163546p:plain
ちなみにこの塩は食うなと書いてある。塩化ナトリウム99.5%なのでほぼ塩だけど、たぶん濃度が高すぎるか、あるいは残りの0.5%が食べることを前提にしてないんだろう。実際のところは知らないけど。

たまに容器をごくわずかにゆすりながら仕上がりを待つ。
だいたい1時間くらいするとマスク塗装の無いところが溶けきる。溶け切る直前には、黒線が細いところからマスク塗装が剥がれてくるので焦ったけど、ランドが溶ける前に掘りきれたので割りばしで引き上げた。
f:id:t-hom:20211105163310p:plain

洗浄ボトルの水で基盤表面を軽く洗い流す。このときのわずかな排水にも銅イオンが含まれるので大きめのビーカーで受けてアルミを混ぜてしばらく置き、重曹で中和してから排水。
f:id:t-hom:20211105165628p:plain

メインの廃液にも同じくアルミを混ぜて銅を析出させる。反応がなくなるまでアルミを投下する。
このあとちょっと一度に入れすぎて激しく湯気が出たので慌ててバケツの水にビーカーの底をつけて冷却した。
f:id:t-hom:20211105165904p:plain

析出したら濾過。
f:id:t-hom:20211105170207p:plain

ビーカーにへばりついた酸化銅の屑とボロアルミも洗浄ボトルをうまく使って漏斗へ流し込み、一緒に濾過する。
最後に泡が立たなくなるまで重曹を混ぜてアルカリ性になってきたら希釈して排水。


完成した基盤は無水エタノールをつけたキムワイプで何度も擦って塗膜をぬぐい取り、テスターでパターン各所を導通チェックしたところエラーは無かった。
エッチング前はランドの線幅が少し心許ないかなと思ったけど、意外にうまくできたと思う。
f:id:t-hom:20211105170647p:plain

あとは手持ちのボール盤で穴あければ完成する予定。。。と思いきや。

これハンダ付け考えると裏から部品差し込む形になるということに今更気づき。。裏表逆やん。。orz

以上

あ、嘘ついてしまった。初挑戦じゃなかった。
工業高校出身なので高校でやってた。

以上 ver.2

基板エッチングのテストとして銅線を使ったイオン化と析出(廃液処理)の実験

今回は実際の基盤エッチングを行う前に排水処理についてテストしておく。
基板のエッチングでは銅イオンの溶液が発生するが、2つの問題がある。

  1. 銅イオンは有害なので、下水に流すと公害の原因になる。(銅イオンそのものは人体には無害とする説が多数検索されたため混乱中。不明へ変更。ただし排出基準は存在するので守らなければならない。淡水生物にとっては毒になるらしい。)
    基準値を超える銅を排水することは犯罪行為。
  2. 銅を溶かすために使用した溶液を流すと酸によって配管が溶ける

よって以下の方法で銅を取り除き、pHを中性に戻してから排水する。

  1. アルミニウムを溶かすことで銅を個体に戻し、濾過して取り除く。
    アルミのほうがイオン化しやすいため、銅イオンが銅(酸化銅)にもどるという原理。
    銅の析出という。アルミはイオン化するが、危険性が低いため排水基準はない。
    (飲めるわけではない。下水に基準はないけど、上水の基準は存在する。)
  2. 重曹を混ぜて中和する。

理屈は分かったんだけど、やったことがないので万が一うまくいかないことがあると困ってしまう。
そこで実際のエッチングを行う前にまずは少量の銅を溶かしたテスト廃液を作成してそれを処理してみるというのが今回の記事。

エッチング液の準備からエッチングまで

今回は少量のエッチング液を作る為オキシドール 5ml、クエン酸 1.5g、塩 0.3g を準備する。
f:id:t-hom:20211031232227p:plain

この配合は以下のサイトに記載された100ml:30g:5gの比を参考にしたもの。
pub.fabcloud.io

まずは試験管で混ぜてみたもののクエン酸と塩は沈殿してぜんぜん溶けないので計量後はビーカーに移してかくはんしてから試験管に戻した。
以下、完成したエッチング液と投入予定の銅線。
f:id:t-hom:20211031232724p:plain

投入直後に泡立ってくる。
f:id:t-hom:20211031233024p:plain
我々素人は泡=空気だから危険はないと思いがちなので注意。
泡とは水中に気体が発生したことを示しているだけであって、それが何の気体なのかはケースバイケース。
化学反応で泡が出てきたら、基本的には換気を良くして直接吸わないほうが無難。

反応はけっこうマイルドでそれほど発熱することもないが、しばらく様子を見ているとうっすらと着色してくる。
f:id:t-hom:20211031233054p:plain

ここからが長い。というかこれ結構時間かかるので、そのまま放置してしまった。
そして4時間くらい経ってから見てみると完全に銅がイオン化し、綺麗な青になっている。
f:id:t-hom:20211031233241p:plain

実際に何時間で溶けたのかは不明。

廃液処理

銅イオンが解けたエッチング液に、まずは少量のアルミニウムを投入する。危険な作業なので必ず少量で様子見。今回の廃液の量に対しては、厚み11マイクロメートルのアルミホイルを2cm×5cmくらいにちぎって小さく畳み込んだものを使用した。

銅の腐食と違って反応が早く、すぐに大量の泡が出てくる。
f:id:t-hom:20211031233509p:plain

熱もけっこう出てくる。以下はアルミ3投目くらいの少し反応がおさまりつつあるときに計った温度なので、1投目はもっと高温だったと思われる。写真を取り損ねたけど、試験管が湯気で曇っていた。
f:id:t-hom:20211031234011p:plain

ビーカーに冷たい水を張っておき、あまり温度上昇が激しいようなら試験管をつけて冷やす。

しばらくするとコバルト色になってくる。これは析出した酸化銅が泥みたいに舞い上がって水を汚してる為と思われる。
f:id:t-hom:20211031234314p:plain
ここまでくれば反応速度がかなり遅くなってくるので、少し多めアルミを入れて接触面積を増やして析出の速度を稼ぐ。

最終的にはヘドロみたいな色になり、泡もほとんど立たなくなる。
f:id:t-hom:20211031234513p:plain

これを濾過するとフィルターに黒い汚れがつく。
沈殿物が試験管に張り付くので洗浄ボトルで水を注ぎ入れて浮かし、そのまま一緒に漏斗にうつして濾過する。試験管自体、洗浄ボトルの水で洗浄してその廃液もやはり一緒に濾過。
f:id:t-hom:20211031234956p:plain

あんなに濁っていたのにフラスコの底にたまる濾過済の液は無色透明。
f:id:t-hom:20211031235350p:plain

念のため再度アルミを投入して全く反応が無いことを確かめた。
ここで少しでも泡が出るようなら析出と濾過を繰り返すことになる。

使い終わった酸化銅まみれのろ紙は紙皿にでもうつして自然乾燥させて、そのあと燃えないゴミで廃棄。

ちなみにこの透明の液は酸性なのでこのまま捨てると配管が溶ける恐れが残っている。実際にpH試験してみた。
f:id:t-hom:20211031235723p:plain

重曹をまぜるとこのとおり激しく発泡する。
f:id:t-hom:20211031235913p:plain

pHが安定したら大き目のビーカーに移し、水道水で10分の1くらいに希釈して排水した。
f:id:t-hom:20211101000006p:plain

実際のエッチングではもう少し廃液が増えるだろうし、最後の希釈用に大き目のポリバケツが必要になるかな。

とりあえず今回の実験は成功に終わった。
結局、念のためにと用意した道具のほとんどをフル活用することになったので入念に準備しておいてよかった。

以上

11/1 追記

ろ紙が乾燥したので析出した銅をマイクロスコープで撮ってみた。まぁただの錆屑なので特別面白いものでもないけど。
f:id:t-hom:20211101133250p:plain

少しキラっと光るものが混ざっているので、単体の銅ってよりは中にアルミ屑をが収まってて、取り囲むようにびっしりと酸化銅が生えてる感じかな。
体積は入れた銅線よりも大きい気がするので多分そう。

ろ紙に貼り付いたズタボロのアルミと酸化銅。
f:id:t-hom:20211101133431p:plain

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。