コネクタの種類は実際のところ大量にあって、しかもはっきりしたデファクトスタンダートっぽいものもあまりない。というか異種接続防止のためか意図的に規格の異なるコネクタがたくさん使われている。

よく見るコネクタ (入手性がよい) を調べた

あとは、汎用端子にハウジングをつけたもの T型コネクタ とかがある。

ENGINEER エンジニア 精密圧着ペンチ 圧着工具 オープンバレル バレルが長い 端子 PA-21 - ENGINEER

ENGINEER

5.0 / 5.0

圧着端子の圧着にラジオペンチ使うのはだんだん嫌気がさしてくるのでさっさと汎用品を買いましょう (圧着端子メーカー純正に比べればアホみたいに安い)

  1. トップ
  2. tech
  3. 汎用コネクタ

プリントしないプリント基板 (PCB) とやらです。

現状


ふとやってみよう、と思ったので、0.8mm のエンドミルを使うべきところ (穴あけ) に 1mm のエンドミルを使っており、ランドが消滅していたりする。実際はシミュレーションとほぼ同じように削れたので、0.8mm にすれば解決するだろう。

Eagle -> G-code

Eagle -> G-code は直接出力する ULP が公開されているものがあったので、これを使ってみた。キデッジ メイカーズ ブログ -卓上CNCでプリント基板を簡単に作ろう!- CNCとEAGLEによる片面プリント基板の自作法!, キデッジ メイカーズ ブログ -卓上CNCでプリント基板を簡単に作ろう!- ドリル、外周カット用ULP version2!

これらのうち以下だけを使った。

  • 1_linepattern_gcode_bottom.ulp
  • 2_drill_holes_cutoff_v2.ulp

1_linepattern_gcode_bottom.ulp

  1. スピンドルスピードが設定されておらず回転しないでぶつかるぞ

X軸を中心に反転した座標で吐かれるので、Y軸原点にオフセットが必要 (X軸は+方向に、Y軸は-方向に進む)。左下が (0, 0) なら、左上 (0, +Y) を作業座標としてゼロにセットする必要がある。

--- 1_linepattern_gcode_bottom.txt	2015-09-07 01:19:30.000000000 +0900
+++ 1_linepattern_gcode_bottom.ulp	2015-09-06 23:23:36.000000000 +0900
@@ -42,7 +42,7 @@
 //////////////////// ユーザー設定 ////////////////////
 //////////////////////////////////////////////////////
 
-string  DefaultSuffix   = "_bot.tap";   //お使いのCNC似合わせた拡張子に変更してください
+string  DefaultSuffix   = "_lines.gcode";   //お使いのCNC似合わせた拡張子に変更してください
 real    Width           = .3;           //実際に削る線幅を指定してください
 real	Lift            = 1;            //空中移動時の高さを指定してください
 real	Depth           = .1;          //実際に削る深さを指定してください
@@ -129,7 +129,7 @@
          printf ("G0Z%2.3f\n",Lift);
 //         printf ("G0Z0.23\n");
          printf ("G0X0Y0\n");
-         printf ("M03\n");
+         printf ("S10000 M03\n");
          printf ("\n");
          printf ("(Begin)\n");
 }

2_drill_holes_cutoff_v2.ulp

  1. G90 が指定されておらず、機械側のモードがG91だと死ぬぞ
  2. 最初に原点復帰しないせいで原点以外から再開しようとすると死ぬぞ
  3. スピンドルスピードが設定されておらず回転しないでぶつかるぞ

dtool 以下の穴についてはG-codeが生成されない。cut_up がなんかおかしくてエンドミル一本折ったので少し大きめに指定するといいでしょう……

--- 2_drill_holes_cutoff_v2.txt	2015-09-07 01:19:20.000000000 +0900
+++ 2_drill_holes_cutoff_v2.ulp	2015-09-07 00:16:18.000000000 +0900
@@ -12,13 +12,13 @@
 //////////////////// ユーザー設定 ////////////////////
 //////////////////////////////////////////////////////
 
-string  DefaultSuffix   = "_cut.tap";           // お使いのCNC似合わせた拡張子に変更してください
+string  DefaultSuffix   = "_cuts.gcode";           // お使いのCNC似合わせた拡張子に変更してください
 real    dtool           = 0.8;                  // エンドミルの直径を指定してください
 real    zstep           = 0.4;                  // Z軸のステップ値を指定してください
-real    depth           = -1.5;                 // 基板の厚さを指定してください
-int    fvalue          = 200;                   // XY軸のF値を指定してください
+real    depth           = -1.7;                 // 基板の厚さを指定してください
+int    fvalue          = 80;                   // XY軸のF値を指定してください
 int    z_fvalue        = 50;                    // Z軸のF値を指定してください
-real 	cut_up 		= 1;  			// 空転移動時の高さを指定してください
+real 	cut_up 		= 2;  			// 空転移動時の高さを指定してください
 int     drill_cut       = 1;                    // 取り付け穴のパスが必要ない場合は0にしてください
 int     drill_on        = 1;                    // エンドミルによるドリルのオンオフ
 int     pecker_mode     = 1;                    // キツツキドリルのオンオフ
@@ -764,7 +764,10 @@
   {
     line_counter();
     checkturn_right_or_left();
-    printf("T2 M06 S0 M03\n");
+    printf("G90\n");
+    printf("G0Z2\n");
+    printf("G0X0Y0\n");
+    printf("T2 S10000 M03\n");
     
     if (drill_cut == 1)
     {

他人がつくったG-Code生成器は本当に良く良く確認したほうがよくて(確認したつもりでもつらいことがおきる)、特に以下は絶対にチェックする必要がある

  • OpenSCAM で開いて意図した通りのパスになっているか
  • 冒頭らへんに座標指定 G90 があるか (G90=絶対座標, G91=相対座標)
  • 冒頭らへんに原点復帰 (G0Zxx, G0X0Y0) があるか
  • 冒頭らへんに M3 S10000 とがあるか
  • G-code 全体を見て、X軸Y軸が増えていくか減っていくか。(作業原点の設定位置に関わる)
  • 実行直前に G-Code 実行器 (grbl) をリセットすること

OpenSCAM で確認したから安心、とはいかない。G-Code 実行器はモーダルなため、何かしらの状態が残っていると困ったことになることがある。

そして、座標指定まわりがおかしいと、本当にとんでもないことになるので一旦 Z 軸をあげた状態で動かしてみるといい。

実際の切削

基板をしっかり固定するのが重要なのは言うまでもないけど実際難しい。基板自体が反ってしまっている場合、両面テープで貼ろうとしてもどうしても浮いてしまうし、クランプするとクランプした周辺だけ浮かない状態になって削れなくなってしまう。

切削で楽をしようとするなら、基板作成の段階のデザインルールで0.5mmぐらいのルールをしくのがよさそう。ユニバーサル基板の代わり(自動配線したいだけ) なら、このほうが圧倒的に楽

あと処理

結構バリがでるのでなんらかの方法でとりたい。

  1. トップ
  2. tech
  3. CNC フライスで基板をつくる

CNC フライスで基板をつくる | tech - 氾濫原 の続き

穴開け用の φ0.5mm刃長1mmのエンドミルを入手したので、0.8mm 厚の基板で試した。

条件

配線パス切削:Vカッター (前回と同じもの)

  • S10000 F200 (前回と同じ)
  • 両面テープ固定 (前回はクランプ)

なぜかバリも全くでずに綺麗にできた。やはり両面テープのほうがZ軸が安定する。両面テープは切削対象部分にはできるだけ全部貼ったほうがいい(ビビらないように)

穴開け・外形切削:φ0.5mm 刃長1mm

  • S10000 F80
  • 0.9mm 厚まで切削

で綺麗にいった。

メモ

これとは別にもう一枚切削したが、そちらはちょっとZが安定しなかった。おそらく両面テープ不足。また、バリがかなり出てしまった。ビビったせいかもしれない。とにかく、固定はしっかりしたほうがいいっぽい?

φ0.5mm のエンドミルはかなり扱いが怖い。φ0.8のミルも注文したけどまだ届いてない。

0.8mm厚だと切削したパスが表面から透けて見えるので、部品の配置がやりやすい。1.6mm よりいいかも?

  1. トップ
  2. tech
  3. CNC フライスで基板をつくる 2

ちょっと前に掘った


SketchUp と、歯車描画プラグインで書いて SkechUCam で gcode にしたけど、ぴったりサイズにしたらハメるのが硬すぎて厳しかった。細かい凹部はエンドミルでは削れないというのもありそう。

歯車描画プラグインは、ものによって SketchUCam と相性が悪くて使えなかったりする…… 機能がすくなそうなやつのほうがうまくいくっぽい。

  1. トップ
  2. tech
  3. CNC フライスで遊星歯車装置を掘った

複数シャンク径を使いわけたい場合、都度コレットを交換する必要がある。ググってみてもいまいち正しいやりかたが出てこなくて歯痒いが、以下のようにすると交換できる。

コレットナットを軸からはずす

普通に緩めて外すだけ

ナットからコレットを外す

コレットをちょっと押してみると、ナットの位置によって傾むくほうと傾かないがあることがわかる。

傾むくほうを下にして、そのまま下に少し強めに押すと外れる

傾かない状態

傾いた状態

ナットにコレットをつける

ナットの内側をよくみると、コレットの溝にはまるようにリングがついていることがわかる。そしてそのリングが一方が深く、一方が浅いようになっている (偏心している)

なので、深いほうを先に入れ、浅いほうに向けてコレットを押しこむとつけられる。

ナットを軸につける

普通に締めるだけ

いちいちナットにコレット脱着するのが面倒だ!!

ナットだけ追加で買って、1コレット1ナットをセットにしてしまうのが早い。これなら、緩めて別のナットをつけるだけですむ。

  1. トップ
  2. tech
  3. ER11 コレットの交換方法

Grbl の現在のバージョン(v0.9)にはジョギング(手動で軸を送れる機能)がない。GUI にあったりするが、基本的には偽物である。

理想的な(というか普通の)ジョギングは、スイッチを押している間だけ設定したフィードレートで動くという機能なのだが、Grbl はGコード単位でしか駆動信号が出せないため、このような挙動ができない。

オフィシャルな解決方法

https://github.com/grbl/grbl/wiki/Interfacing-with-Grbl にもFAQ的に書かれている。ここで書かれているのは、planner buffer queue size (設定すると status として出力できる) を見ながら、一定のキューサイズを保つ、という方法である。

しかしこの方法には以下のような問題がある

  • planner buffer queue size を status に表示させるのが面倒
    • 毎回 $コマンド送るの?みたいな
  • キューサイズを決めるのが難しい
    • 少なすぎるとスムーズに送れず、多すぎると止まるまで時間がかかる
  • どっちにしろ入れたキューは消せないため、うまくやらないと止まるまで時間がかかる

Hold & Reset

次に思いつくのは Hold してから Reset するという方法である。Grbl は Hold など一部のコマンドはリアルタイムで処理されるため、キューサイズに影響されない。

つまり、動いているときに Hold させて即時停止させるということは可能。そしてその状態から Reset を行えばキューをクリアできるため、実質的にジョギング相当になる。

しかしこの方法には以下のような問題がある

  • Hold -> Reset の遷移が安定しない
    • Reset during cycle エラーがでたりする (位置がずれてる可能性がありますよということ)
  • Hold → 実際の Hold までディレイがある場合 (ネットワーク経由でHoldするとか) 停止までの時間が安定しない

ということで使えない。

インターバル方式

ということで別の方法を考えた。これは1つのGcodeあたりの実行時間を一定とし、一定時間ごとにキューイングする方式。

理想ジョギングはステップ単位で進むわけではなく、フィードレートのみに依存しているわけで、それに近い挙動をすることができる。

インターバルは Grbl へ送信してキューに入るまでの時間よりも長い時間をとる必要がある。ネットワーク経由だと少し大きめに設定する。

例えば 0.3sec インターバルでフィードレート800mm/minで送る場合、4mm ずつ送ることになる。

この方法のメリットは

  • 一定時間(インターバル)以内に必ず動作が止まる
  • 追加の設定が必要ない
  • 実装が簡単

デメリットは

  • インターバルよりもキューイングに時間がかかった場合スムーズに送れない

ぐらい。

実際のインターフェイス

実際はステップジョギングと可変フィードレートを併用できるのほうが嬉しいため、以下のような挙動にした。

  • マウスダウン直後は1ステップ送る
  • 終了後1秒間そのままでいるとステップから計算した可変フィードレートで上記インターバル方式のジョギングを行なう

かなり自然なジョギングができるようになって満足

  1. トップ
  2. tech
  3. Grbl でのジョギング

シェーダープログラムはGPU内で動く。性質上並列(parallel)に実行される。

vertex shader

頂点ごとの処理内容。線分だったら始点と終点。頂点の最終的な位置を決定する。ついでに頂点ごとの属性 (attribute) から fragment shader に渡すものをどうするか決めたりする。

最終的に gl_Position にスクリーン座標を代入する。

fragment shader

ある断片ごとの処理内容。線分だったら始点から終点までの各要素を分割した1要素 (線分をレンダリングしてピクセル単位にしたときのピクセル単位)

最終的に gl_FragColor に vec4 型で色情報を代入する。

varying として vertex shader から渡された値は、各断片ごとに値が変更されて渡ってくる。

gl_FragCoord という変数があり、これには実際に処理しようとしているピクセル座標が入ってくる (スクリーン座標系)

gl_FragCoord から元の世界座標系を計算するのは面倒なので、fragment shader で世界座標系が欲しい場合 varying で座標を渡すのがてっとりばやい。


varying variables

varying は vertex shader と fragment shader とを繋ぐものだが、vertex shader でセットした値がそのまま fragment shader に渡るわけではない。fragment shader に渡るときに該当する fragment について計算された値が渡ってくる。

https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/varying.php

  1. トップ
  2. tech
  3. GLSL の覚え書き

モバイルバッテリーのロードバランサ | tech - 氾濫原 の続き。5V 2A (10W) 出力のモバイルバッテリー複数使って、30W ぐらいの電力を得ようというやつ。

その後、2個ぐらい専用のロードバランサICを使ったりしてみたが、高負荷時にスイッチングノイズで入力電圧が大きく変動するのをカバーできず挙動が不安定だった。

ということで、改めて基本的な回路で実装したら結構うまくいった。

回路図

前回は 5V バッテリーの出力を直接合成しようとしていたが、それだとバッテリーの個体差によって電圧の差が大きく、うまくバランスできないうえに、損失が大きくなるという問題があった。

今回はバッテリー出力それぞれを欲しい出力電圧付近まで DC/DC で昇圧してから合成することにした。これにより、DC/DC で電圧で調整が効き、かなり近くに電圧をあわせられる。昇圧後に電流制限回路とダイオードを入れ、ロードシェアさせている。

FET は、最大で、許容する電位差×最大電流値だけの損失を発生させる。±0.5V 700mA だと 700mW。空冷でもよさそう。ただ、全体の許容電流を超えた電流を流そうとすると損失が激しく増えて熱くなるので危険。

結果

電圧を高めにして、ゆっくり電流を増やしていくと最大28Wぐらいとれた。

問題点

入力側過電流

不定期に電流をとろうとすると、DC/DC 基板についているコンデンサを放電しきってしまうようで、昇圧の入力側すなわちバッテリー出力側に過電流が流れ、バッテリー側の過電流検知にひっかかることがあった。

これは電流制限を昇圧後に入れているせいなので、昇圧前にも入れれば解決するが、それはそれで面倒くさい。

ESR が大きめのコンデンサを出力につけておけばだいたいいい感じになりそうだったがちゃんと試してない。

実装面積

DC/DC をそれぞれにつけるせいで実装面積が大きい。 DC/DC は小さくしようがないので、ロードシェアの基板を小さくするしかないが、それほど小さくはならなそう。

  1. トップ
  2. tech
  3. モバイルバッテリーのロードバランサ2

http://cho45.stfuawsc.com/GrblServer/browser/gcode-viewer.html



GrblServer で使うために実装を書いた。もともとプログレスバーを時間ベース(パスの長さとフィードレートから求めた値)にしたくてG-codeパーサを書いてたけど、結局ビューワー作るのと同じコストがかかることがわかったので、デバッグがてらビューワーも書いた、という感じ……

three.js を初めて使ってみたけど、かなりお手軽の WebGL 使えて良かった。WebGL の API はかなりローレベルなので 3D 初心者には使えない感じだけど、three.js なら誰でも使えるレベルになっている。

ただ、ちょっと凝ったことをしようとすると自力でシェーダープログラムを書く必要はある。今回 Z 軸が 0 以上ならパスを半透明にしたくてシェーダープログラムを書いた。

そして最近のスマートフォンだと three.js で書いたコードがものすごくヌルヌル動くのですごい。ブラウザゲームとかマジでネイティブ疎遠ないレベルで作れるのでは!!??? と思ったけど、別に作りたくはない。

  1. トップ
  2. tech
  3. G-code での切削パスをブラウザでプレビューするやつを書いた

ちょっと考えごとするとき Google Keep にとにかくタイピングしていく、みたいなことが多々あるが、図を入れようとすると途端に困難になるので、ペンと紙という便利な道具を使うことにしてみた。

できればデジタルガジェットで解決したかったがコストの割に性能で満足いくか微妙に感じた結果、良いペンと紙を使うほうが気持ちいいのではないかと考えた。

マルマン ノート ニーモシネ A5 方眼罫 N182A - マルマン(maruman)

マルマン(maruman)

5.0 / 5.0

別段こだわりがないし思考過程を保存しようとも思わないので、紙とかコピー用紙でいいかと思ったが、思いのほかスムーズに書けずイライラしたので、調べた結果ニーモシネが良いだろうという感じだった。装丁がかっこいいのと、方眼の薄さがちょうどよくて気にならない。

ペンは手持ちにあった LAMY の Safari (なんかのときにもらった) の細字(F)と、kakuno の中字(M)、細字(F) で良さそうなのでこれのまま。(Safari も kakuno も学習用の安い万年筆。LAMY のFはkakunoのMと同じかそれより太い線)

LAMY ラミー 万年筆 F 細字 サファリ ブラック L17-F 正規輸入品 - LAMY

LAMY

5.0 / 5.0

パイロット 万年筆カクノ M ソフトブルー FKA1SRSLM - パイロット(Pilot)

パイロット(Pilot)

5.0 / 5.0

この組み合わせはかなり気持ち良く書ける。ペンは安くても紙はちゃんとしたのを使ったほうが良いということを学んだ。

現状

紙 vs コンピュータという点では、結局筆記で書いていくのは自分の場合長くは続かない気がしている。

今のところ8ページぐらい消費したけど、今やっていることに対してはそこそこ良い感じがする。ある程度以上に複雑になると図がないと厳しいけど、コンピュータ上で図を書くのは、書けないことはないけど今のところペンで書くよりも早く書けない。

一方で書いた図を編集させるのが難しいので図の試行錯誤はしにくいのと、字を書く分にはコンピュータ上に書いたほうが早いので、思考過程を最終的にデジタル化したいなら最初っから Inkscape 極めたほうが有益そうではある。

  1. トップ
  2. tech
  3. 紙とペン

ウェブアプリをスタンドアロンアプリのように表示するため (ようはロケーションバーを消したいという) 試してみた。




「ホーム画面に追加」というメニューに manifest が反映される形になる (わかりにくい)

"display": "standalone" の場合、こうなる。

  1. トップ
  2. tech
  3. Manifest for a web application

そろそろ HTTPS でしか使えない新機能なんかを使いたくなるので、すこしずつノウハウを溜めようという気持ちはあります。

localhost 自己証明書

ググって出てくるコマンドだと対話的インターフェイスでどうでもいい情報を入力する必要があってダルいので一発で自己証明書つくれるようにします。

#!/bin/sh

cd dev

CN=localhost

openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/C=JP/ST=Kyoto/L=Kyoto/O=Example/CN=$CN"
openssl x509 -req -days 1024 -in server.csr -signkey server.key -out server.crt
rm server.csr

server.key と server.crt を使って HTTPS サーバを立てます。

(備考) node で HTTP2 サーバを立てる

HTTP2 は一応暗号化はオプションということになってるようだが (H2C/HTTP2 Over TCP)、実際の実装では TLS に乗っているものしかないので必然的に HTTPS でしか使えない。

node の http.Server / https.Server を使っている場合、Server のインスタンス化コードを替えるだけで HTTP2 にできる (インターフェイスが一緒)

コンストラクタに server.key と server.crt を指定するだけ。

ホスト名解決

localhost だけでの開発ならいいが、LAN 内のスマートフォンなどから HTTPS な開発環境にアクセスしようと思うと、IP アドレス指定してもアクセスできない。Chrome の場合、ERR_CONNECTION_CLOSED (This webpage is not available) になる。

どうやらホスト名でアクセスしないとブラウザ側で強制的に接続を切るようで、どうしようもない。

ということで、一旦 LAN 内に DNS サーバを立てて該当コンピュータを名前でひけるようにする必要がある。(mDNS でいけないかと思ったけどダメだった)

node で DNS サーバを書ける実装もある (node-dns (native-dns)) のでこれを使えばとりあえず簡単に書ける。

/etc/hosts 形式を読んで A レコード返すだけのは雑に書いた。


立てた HTTPS サーバと同じマシン上で良いので、port 53 で起動する。sudo が必要。

端末側でもこの DNS サーバを参照する必要がある。

Android では Settings → Wi-Fi → (接続中のネットワーク名を長押し) → Modify network とすすんで、Show advanced options にチェックを入れ、IP settings を Static に変え、DNS 1 にマシンのIP Addressを指定すれば反映される。

またはルータの設定を書き変えて DHCP 経由で通知する DNS サーバを変えてもいいけど、これはこれで面倒。

  1. トップ
  2. tech
  3. HTTPS 開発環境

link rel="import" によるロードはやはりちょっと時間がかかる。Polymer の場合どうしてもインポート数が増えるのでなんとかしたい。

もちろん vulcanize すれば import 自体は解決するが、created/attached まわりの処理もチリも積もればという感じで、なかなか時間がかかるので、根本的解決にならない。

特に appmanifest によってスタンドアロンアプリ表示させている場合、ロードまでの間完全に真っ白の画面になり、プログレスバーも出ないのでかなり残念なことになる。

ということで、一旦ローディング画面を挟みたい。

問題点:first paint がなかなか発生しない

HTML Imports はポリフィルされていない場合ブロックする (Chrome にしかネイティブ実装されてないから Chrome だけ)。インポート先がインポートしている場合再帰的にインポートするので、依存全部インポートが終わるまで表示が完全にブロックし、head内でインポートしていると画面描画が全く走らない。

Chrome の場合 first paint が走るまで現在表示中の内容を消さないので、リロードした場合特に「全く操作はできないのに表示はされている」状態になって気持ちが悪い。

なので、まずはインポートなしの状態ないし、最低限必要なものだけをインポートしてから、ロード画面を表示する。

ローディングプログレスがとれない

link要素のloadイベントでひとつのインポートの完了はわかるが、再帰的な全てのリクエストのプログレスをとることができない。

どうしようもない?ぽいので、intermidate なローディングプログレス表示するしかない。

CSS でアニメーションさせるのが現状では一番マシっぽい。

コード

		<div class='loading'></div>
		<my-app></my-app>
		<script>
			requestAnimationFrame(function () {
				var link = document.createElement('link');
				link.rel = "import";
				link.href = "src/app.html"; // my-app の定義
				link.addEventListener('load', function () {
					var loading = document.querySelector('.loading');
					loading.parentNode.removeChild(loading);
				});
				document.body.appendChild(link);
			});
		</script>

link rel="import" は作って挿入してもちゃんと動いてくれるのでこれで良い。polyfill もちゃんと動いててうまく動く。

load イベントは再帰的なロードが全部終わってから発火するようになっている。

将来性

HTTP2 化してもカスタムエレメントの初期化処理はなくならないので、大量のカスタムエレメントを使う場合なんらかのローディング表示が必要ではないかという気がする。

appmanifest によるスタンドアロンアプリ化ではコンテナ(ブラウザ)側でそのうちちゃんとローディング出せるようになりそう。

  1. トップ
  2. tech
  3. webcomponentsjs/Polymer、HTML Imports が終わるまでの間ローディングを出したい。