2025年10月6日月曜日
ELISE ハードトップの吹っ飛び防止
2025年9月21日日曜日
3D プリンタの直角を矯正した話
だいぶん前に買った 3D プリンタの Ender-3 Pro,結構できが良くて今まで不満なく不満があるところは改造しつつ,今のところ満足して使っている.で最近,出力したパーツの直角が出てないんじゃね? ということに今更ながら気づいた.
調べてみたところ,原因は 2つあって,
(1) ボルト穴に遊びがあるので,遊びの分だけフレームの直角・水平がずれる.これはよく考えればわかることで,これに関しては気づかなかった自分のミス.一旦ボルトを緩め,定規で測りながらボルトを締めることで解決.
この手のアルミ角材で組まれている 3D プリンタは巷に溢れているけど,どこもこんな感じなのかなぁ.同社の最新機種でもフレームの傾きは問題になってるっぽい→参考
2025年4月13日日曜日
PICO4 用 メガネレンズ
VR ヘッドセットの PICO4 は,ネガネをかけて使うこともできるけど,メガネの鼻パッドにヘッドセットの重さがかかって鼻が痛くなる.PICO4 専用度付きレンズもあるみたいだけど,使ってないメガネのレンズを貼り付ければいいのでは? と思ってやってみた.
で PICO4 のレンズ部分にピッタリハマるフレームを 3D プリンタで作る.既存の物にピッタリ合うパーツを作るときは,自分は対象物の写真を撮って,曲線等で対象物の形をトレースしたあと,代表長を実物に合わせ込む.
でぎだ (Thingiverse で公開してます).あとはレンズをホットボンドで固定して (急に雑になるwww) 完成.
…と思ったら,レンズが顔から離れすぎて,レンズを通して見える範囲が狭かったので,ホットボンド盛り盛りでレンズを浮かせることで,顔に近づけたら問題なくなった.
鼻が痛くならなくなって超快適ヽ(´ー`)ノ
2025年1月17日金曜日
Android14 で hosts 書き換えが効かないときの対応
●いきなり結論
プライベート DNS 設定を {「OFF」か「自動」} 以外にする
●現象
スマフォの OS を crDroid (Android14) に書き換えたら,hosts 書き換えによる広告ブロックが効かなくなった.
不思議なのが,WiFi では効いているっぽいが,モバイルデータ通信では効いていない.
●Chrome の問題?
で調べてみると,chrome では独自に DNS の名前解決結果を独自にキャッシュしているようで,それをクリアしないといけないらしい.
chrome://net-internals/#dns を開くと,Clear host cache を押したが効果なし.
Lookup ボタンもあるので,hosts に記載のあるアドレスを入力してみたが,やっぱり hosts は効いていないようだった.
●Android の問題?
Chrome の問題なのか Android の問題なのか切り分けるために,Terminal emulator で名前引きしてみたところ,やっぱり hosts が効いていない.この時点で Chrome は関係なくなったが,ググってみても AI に聞いてみてもそれらしい解決策は無し.
●発見
仕方がないので,Android 設定で DNS と名のつくものを探したところ,プライベート DNS なる項目を発見.
デフォルトでは自動になっていたので,OFF にしてみたが,やっぱり hosts は効かない.
そこで,自動・OFF 以外の項目を選んでみたところ,ビンゴヽ(´ー`)ノ 無事 hosts が効いて広告がブロックされるようになった.
素性のよくわからない DNS を使うのはイヤなので,DNS 指定で dns.google を指定しておいた.
●ただし課題が...
このプライベート DNS の設定は,VPN 接続時にも有効らしく,VPN 接続アプリで指定している自宅 LAN の DNS が無視されてしまう (つまり自宅 LAN 配下の機器の名前解決ができない).この場合,プライベート DNS を OFF にすれば VPN の問題はなくなったが,VPN 接続時は手動で OFF にするしかなさそう.
このプライベート DNS,hosts,そしてネットワークから指定された DNS,の優先順位がさっぱりわからん.
2024年11月16日土曜日
Tuya スマートプラグを PowerShell で制御する
前回ブラウザからスマートプラグを制御したとき,URL の情報が見えていたので,後は HTTP リクエストを送れさえすれば制御は余裕と思っていたらそうではなかった.
リクエスト送信前に署名鍵を Tuya から取得し,その鍵で送信するリクエストデータの署名を作成し送信しないとだめっぽい.
で探してみたら,すでに Unix shell から制御するコードはあったので,ありがたくこれを PowerShell に変換してみたのが一番下のコード.
ハマったポイントは,
- UNIX Time を秒数で得る命令 (Get-Date -UFormat %s) はタイムゾーン分の誤差が発生する (PowerShell のバグっぽい) ので,タイムゾーンオフセット分増減が必要.
- 署名を作るために必要な Client Secret (Tuya developer サイトから取得する) は 16進32桁なので,128bit の数値だと思ったら,これはそのまま文字列データとして 256bit の数値として扱わないと,Tuya 側で有効な署名と認められなかった
でやった結果.Powershell で 10秒毎に消費電力を取得してみた.なかなか安価で消費電力のログ取れる環境は無いので,これはかなり満足度が高いヽ(´ー`)ノ
以下 PowerShell コード.
2024年11月10日日曜日
Tuya スマートプラグを PC から制御する
大昔にスマートプラグ (ネットワーク経由で On/Off できるコンセント) を買ったけど,独自の Android アプリでしか On/Off できなかったので,あまり使い道がなく放置していた.
で,最近これは Tuya という IoT プラットフォームに準拠した製品であることがわかったので,PC から制御してみた.
ところが Tuya のチュートリアル通りにやっても画面が説明と異なる等多々あり進まなかったので,自分でうまく行った手順を以下に記載しておく.
【開発者アカウント作成・デバイスのリンク】
●まずはスマートプラグと,Android の Smart Life アプリとの連携を済ませておく.
●Tuya developer でアカウント作成
●Cloud → Create Cloud Project をクリック
- Project Name: てきとう
- Industry: Smart Home
- Development: Smart Home
- Data Center: データが保存されるサーバの場所? よくわからないがとりあえず Western America Datacenter

●Configuration Wizard はそのままで Authorize をクリック
●Devices → Link App Accout → Add App Account をクリックすると,QR コードが表示される
●Android の Smart Life アプリ右上の「+」 → QR コードをスキャン,をタップ後,PC の QR コードを読み込む
●Android アプリの「ログインを確認」をタップ
●以下のような画面が出てくるので,そのまま OK.これで Tuya developer アカウントとデバイスがリンクできた.
【デバイスを PC から制御する】
●どんな操作ができるか (コマンドがあるか) 調べてみる.
ここで表示されている Device ID が後々必要なので控えておき,Devices → All Devices → Debug Device をクリック
●Device Debugging をクリック.
Standard Instruction Set を見ると,使用できる設定系のコマンドがわかる.うちのだと,switch_1 / switch_2 で 2個あるコンセントの On/Off, countdown_n は秒数を設定するとその時間経過後に On/Off を反転する.
Standard Status Set を見ると,状態取得系のプロパティがわかる.うちのだとコンセントの On/Off 状態や,現在の電力が取得できる.
●Cloud → API Explorer をクリック
●Device Control の左の▶をクリック,Send Commands をクリック.
- device_id: 先程調べた Device ID
- code: switch_1 など
- value: true, false など
ここで,Request URL / Response をみると,どういうリクエストを送ればいいかが一発でわかるので,
●Get the status of a single device を実行すると,上の Standard Status Set で調べたプロパティが取得できる.
【最後に】
このスマートプラグ,電力計が付いていたので買ったものだが,電力見るのも専用アプリだけでログも取れないので放置していたが,これからは PC でログ取りできるので,かなり使えるアイテムになったヽ(´ー`)ノ
2024年8月31日土曜日
人生最大のデータ消失危機
約 3年前に買った 6TB HDD の WD60EZAZ に突然アクセスできなくなった.症状としては
- HDD を PC に接続すると,Win 起動中に HDD アクセスに行った時点で進まなくなる
- OS 自体は別 SSD に入っており,OS が読めないわけでない
- つまり,HDD を繋いでいるだけで OS が起動しない
- (あまりおすすめしないけど) 経験的に,OS 起動後に SATA ケーブルを繋いでも HDD は認識するので,それをやってみたら,やはり HDD にアクセスした時点で何も進まなくなる
- HDD アクセスしない他のアプリは動作可能
つまり,Win 用 HDD 修復ツールは一切使用できないことになる.
ここで GParted Live on USB が非常に役に立った.GParted は Linux 用パーティション操作ソフトだが,Linux が USB から起動できて,さらに testdisk (パーティション修復), photorec (削除ファイル復活) 等の HDD リカバリに有用なツールも使える.また Linux では HDD アクセスエラーになったら適当なところで諦めてくれるので,OS ごと固まることがない.
で色々調べた結果,プライマリパーティションテーブルは物理的に壊れているようだが,バックアップのパーティションテーブルは無事なようなので,ダメ元で Linux で NTFS パーティションをマウントしてみたら普通にマウントできたヽ(´ー`)ノ
今回の学びとしては,Windows でだめでも,Linux ならまだワンチャンアクセスできるということを得た.
最後に,HDD を廃棄する際の伝統儀式を実施.可能な限りバラバラにし,ネオジム磁石を取り出して完了w
自分は,Windows 上で Disk エラーを検出すると通知を出すようにしていて,前回の HDD 異常時はそれですぐに気付けて大事になることはなかったけど,今回はなんの前触れもなく突然壊れて困った.3TB / 4TB / 6TB と立て続けで HDD が壊れたので (それ以前は HDD 異常の経験無し),大容量になるにつれて HDD が脆くなってきたのかなぁ.
2024年4月28日日曜日
懸念していたことが現実になった
冠山峠道路のトンネルが開通したとのことで,林道の方に登るついでにトンネル見に行くか,と徳山ダムに向かって出発.で,現地に着いたら,
おいおいおいー,林道封鎖されとるやんけ(;´д⊂)トンネルが開通したら林道の方は廃道にされるかも,と懸念していたが,それが現実のものになってしまった.一時的なものかもしれないけど,積極的に林道を修復する理由もなくなったので,走れるチャンスは確実に減ったはず.封鎖を確認したのは岐阜側で,もしかしたら福井側から登れるのかもしれんけど,景色がいいのは岐阜側の道なので,福井側から登っても意味がない.自分の行動範囲ではピカイチで景色が良かっただけに,ここが走れなくなるのは非常に悲しいなぁ.
あと,冠山峠道路のトンネル開通前はここを走りに来るのはドライブ目的の車しかなかったので交通量は少なかったが,今回は結構交通量多かった気がする.
つうわけで本来は通る予定がなかった冠山峠道路のトンネルを通って,能楽の里牧場なる場所に向かった.
実はあんまり期待してなかったんだけど,山頂は,木が一本もない素晴らしい眺め.しかも,360度全周にわたって視界を遮るものが無い絶景.
冠山峠道の林道が走れなくなった代わりに,いい場所見つけたヽ(´ー`)ノ
2024年3月30日土曜日
天神風の道公園で春の訪れを感じながらバイクツーリング
最近,技術的な話題はともかく,日記的な話題の blog を上げるのがだるくなってきて,めっきり更新頻度が減っている当 blog.
ここで,AI に blog 記事書かせてみたらいいんじゃね? と思ってやってみた.
入力した文章はこれ↓
====================================
次の文章を元にblogの記事を書いてください.
冬は寒かったので全然バイクに乗っていない.
今日は暖かかったので,本年初のバイクのり.
多くのライダーが集まる湖畔の里つきがせはスルーして天神風の道公園に行った.
ここは見晴らしが良く人も少ないのでお気に入り.
桜はあまり咲いてなかった.梅らしきものは咲きかけ.
====================================
出力された記事
===== ここから =================================
天神風の道公園で春の訪れを感じながらバイクツーリング
冬の間は寒くてバイクに乗る機会が減っていましたが、今日は暖かかったので今年初のバイクツーリングに行ってきました。多くのライダーが集まる湖畔の里つきがせはスルーして、見晴らしが良く人も少ない天神風の道公園を目指しました。
公園に到着すると、眼下に広がる景色に感動しました。遠くの山々まで見渡せる絶景は、まさに春の訪れを感じさせてくれます。桜はまだあまり咲いていませんでしたが、梅の花が咲き始めており、春の訪れを告げていました。
公園内を散策していると、気持ち良い風を受けてリフレッシュできました。人も少なく、静かな環境で自然を満喫することができました。
今年のツーリングシーズンは、天神風の道公園からスタートすることができて、とても良い思い出になりました。これから暖かくなるにつれて、色々な場所に出かけたいと思います。
公園情報
- 天神風の道公園
- 奈良県奈良市月ヶ瀬梅林
- 駐車場あり
- 無料
おすすめポイント
- 見晴らしが良く、遠くの山々まで見渡せる
- 人が少なく、静かな環境
- 春は桜や梅の花が楽しめる
まとめ
===== ここまで =================================
すげえよwww 「春の訪れ」とか自分では絶対書かないしそんな文才無いwww
しかも自己満足な記事ではではなく,公園情報や見どころまでまとめられて,ちゃんと他の人にとって役に立つ記事になっている.しょうもない記事を書くライターは廃業だなこれ.
これ見たら,ソースコード書くだけの人もそのうち淘汰されるだろうなぁ,というのも実感が湧いてくるね.
2024年3月24日日曜日
C++ で構造化アセンブリプログラミング
動機
原始的なアセンブラしか無い原始的な CPU のプログラミングをすることになった.でアセンブリプログラミングの一番の萎えポイントとして,例えば C 言語だと
if(a == b){
c = d;
}else{
e = f;
}
みたいに書けるところが,構造化記述できないアセンブラだと
cmp a, b
jnz label0
mov c, d
jmp label1
label0:
mov e, f
label1:
とラベルやら分岐命令やら,自分で生成しないといけないのでめんどくさいし,if がネストすると可読性も悪い.真面目にやるなら bison/flex とかでまともな構造化アセンブリ言語を設計するところだけど,そこまでやるのはなぁ... と思ったところで,C++ のクラス / 演算子オーバーロードをうまいこと使えば,構造化アセンブリプログラミングもどきが出来るのでは? と思った.例えば,C++ で "r0 = r1;" と書いてコンパイル・実行すれば,"mov r0, r1" というテキストが得られる,みたいなイメージ.
まずは代入演算
//////////////////////////////////////////////////////////////////////////////
// Register
class RegisterObject {
public:
RegisterObject(const char* szName) : m_szName(szName){}
const char *Name(void) const {return m_szName;}
private:
const char* m_szName;
};
class GpReg : public RegisterObject {
public:
GpReg(const char* szName) : RegisterObject(szName){}
GpReg& operator=(const GpReg& src){
printf("\tmov\t%s, %s\n", Name(), src.Name());
return *this;
}
};
//////////////////////////////////////////////////////////////////////////////
// Register インスタンス
GpReg r0("r0");
GpReg r1("r1");
GpReg r2("r2");
GpReg r3("r3");
//////////////////////////////////////////////////////////////////////////////
// アセンブリプログラム
int main(int argc, char **argv){
r0 = r1 = r2;
return 0;
}
GpReg class は汎用レジスタをイメージしていて,特殊なレジスタがあれば RegisterObject か GpReg を継承する感じ.C++ ソースコード上の変数名 (r0 とか) は実行時には失われてしまうので,m_szName に変数名をセットしておく.代入演算のキモは言うまでもなく "operator=" で,= が呼ばれたら mov 命令のテキストを出力する.
mov r1, r2
mov r0, r1
おお,いい感じ.アセンブラだと r0 = r2 が直接代入できないので一旦 r1 を経由する,みたいなケースが多々あるが,それが 1行で書けるのはありがたい.比較演算
次に,if-else-endif の構造化をやる前に比較演算子を定義する.class FlagReg : public RegisterObject {
public:
FlagReg(const char* szName) : RegisterObject(szName){}
};
//////////////////////////////////////////////////////////////////////////////
// Register インスタンス
FlagReg f0("f0");
//////////////////////////////////////////////////////////////////////////////
// global な operator
FlagReg& operator==(const GpReg& a, const GpReg& b){
printf("\tcmpeq\t%s, %s, f0\n", a.Name(), b.Name());
return f0;
}
//////////////////////////////////////////////////////////////////////////////
// アセンブリプログラム
int main(int argc, char **argv){
r0 == r1;
return 0;
}
RegisterObject を継承して FlagReg を定義する.
operater== で,== が呼ばれたら cmpeq 命令を出力して,== の返り値として f0 を返す. cmpeq r0, r1, f0
これはなんの問題もない.
if-else-endif
//////////////////////////////////////////////////////////////////////////////
// 構造化構文
int g_LabelCnt = 0;
std::vector<int> g_Label;
void _if(FlagReg& f){
printf("\tjnset\t%s, _L%d\n", f.Name(), g_LabelCnt);
g_Label.push_back(g_LabelCnt);
++g_LabelCnt;
}
void _else(void){
printf("\tjmp\t_L%d\n", g_LabelCnt);
printf("_L%d:\n", g_Label[g_Label.size() - 1]);
g_Label.pop_back();
g_Label.push_back(g_LabelCnt);
++g_LabelCnt;
}
void _endif(void){
printf("_L%d:\n", g_Label[g_Label.size() - 1]);
g_Label.pop_back();
}
//////////////////////////////////////////////////////////////////////////////
// アセンブリプログラム
int main(int argc, char **argv){
_if(r0 == r1);
r0 = r2;
_else();
r1 = r3;
_endif();
return 0;
}
cmpeq r0, r1, f0
jnset f0, _L0
mov r0, r2
jmp _L1
_L0:
mov r1, r3
_L1:
おおぉ,これこれ! これがやりたかったんだよ.この時点でこのやり方はかなりうまくいく感触を得ていたが,念の為 if がネストするケースをテストしてみたら,//////////////////////////////////////////////////////////////////////////////
// アセンブリプログラム
int main(int argc, char **argv){
_if(r0 == r1);
_if(r1 == r2);
r2 = r0;
_else();
r3 = r1;
_endif();
_else();
r1 = r3;
_endif();
return 0;
}
実行結果: cmpeq r0, r1, f0
jnset f0, _L0
cmpeq r1, r2, f0
jnset f0, _L1
mov r2, r0
jmp _L2 ←※ここ
_L1:
mov r3, r1
_L2:
jmp _L3
_L0:
mov r1, r3
_L3:
んー,間違いではないんだけど,jmp _L2 の飛び先は jmp _L3 しか無いので,最適化の観点では「ここ」で jmp _L3 にすべき.それを解決して,あとはメモリアクセスとかラベルへのサブルーチンコールとかを実装すれば,普通に使えそう.























