2015年12月15日火曜日

マウスを修理した話

プロローグ

以前から調子の悪かったマウス Logicool G600の中ボタンが、ついに押しても引いても無反応になりました!
多くのソフト(ウェア)でパン(breadではない)操作に使っている中ボタン(ホイール押下げのこと)。これは致命的です(比喩。実際は死なない)。

すぐにでも新しいマウスを用意したいところですが、ボタンが一つ効かなくなっただけで新品に買い替えるのは癪なので、とりあえず分解してみることにしたのでした。

分解

分解に関して特に難しいことはなく、マウスソールを剥がして隠れているねじを外すだけです。あとはツメもなくパカッと開けるだけですが、上部と下部はFFCで繋がっているので開いた勢いで引っ張ってしまわないようにだけ注意。

さくっと分解

中身を観察

いきなり修理から脱線しますが、基板の右側にATmega32U2が載っています。ゲーミングマウスのコントローラがAVRとは意外でした。ファームウェアをダンプして解析したり、オリジナルファームウェアを書き込んで連打・マクロ機能を実装したりとかできそうですね。

さて、基板の中央にタクタイルスイッチが3つあります。ケーブルが出ている側にあるのが中ボタンのようで、試しに分解した状態でPCに接続してスイッチを押してみてもやはり無反応でした。

とりあえずスイッチが壊れただけっぽそうな気がしないでもないので、こやつを交換してみます。


部品の選定

このタクタイルスイッチは一般的な6x6mmサイズで、高さは📏ものさしでテキトーに測ったところ4.5mmくらいでした。もっときちんと測りたいです…。どなたか私にノギスを買ってくれください。

早く修理したかったのでAmazonのプライム対応のものを探して、こちら

 を注文しました。

スイッチの交換

(ぶろぐぶろぐに書き残すつもりはなかったので作業中の写真撮ってないですサーセン)

とりあえず今ついているタクタイルスイッチを外しましょう。
はんだ吸取り線で我左人差指火傷負格闘してみましたが、結局外れませんでした…。
仕方ないのでスイッチのリードの根元部分を基板に傷を付けないように気を付けながらニッパーでちまちま切断したのち、残ったリード部分をはんだごてを当てながら抜き取りました。

こわれたすいっちはきれーにとれました

あとは新しいスイッチをごく普通にはんだ付けするだけです。寝ててもできますね。

安物買いの銭失い

組み立てて動作確認です。緊張の一瞬。
PCに接続して…認識しました!壊してはいないようです。
中ボタンは…と

「カッ!」

…。

「カッ!カッ!!」

…うん。ちゃんと反応するし、中ボタンドラッグしても途中で離したことにもならない。中ボタンは直った。
でも、でもね…すんごい重いし、クリック音うるさすぎ!!
いや、分かってましたよ。届いたスイッチを試しに押したときから「あー硬いな」って思ってましたよ!
はぁ……

部品の選定 2nd ~失敗を乗り越えて~

安い早いは美味しくありませんでした。今度はちゃんと仕様を見てから選びます。
グググった結果、タクトスイッチの商標の持ち主 アルプス電気のSKHHAJA010が良さそうです。

サイズ高さ押下加重
6x6mm4.3mm0.98N

早速RSでポチりました。あまり比較検討していません。はい学習してないです。

組み立て直して、その後…

新しい部品が到着しました。

スイッチ三兄弟
左から、元のやつ、重いやつ、APLSの良さげなやつ

写真では分かりにくいですが、元のスイッチとアルプス電気のスイッチは銀色の部分が鏡面処理されていて、Amazonでポチったやすいスイッチはざらざらしてます。あと黒い部分の形やはみ出し具合がアルプス電気のものは元のスイッチに激似で、これは 当ててしまったのではないかと。

押し心地も軽く、これはいけるんじゃないかと期待しながら組み立て、いざ動作確認!

カチカチ…

…キタコレ!元に戻った!やった!これで作業が再開できるぜ!イヤッゥフゥーー

めでたし、めでたし。

2014年9月6日土曜日

WRTnodeのHack (0)

注文していたWRTnodeが届きました。
WRTnode開封写真
プラスチックケースには本体と、専用USBケーブル、WRTnodeのシールが入っていた

WRTnode本体ボード写真
本体

WRTnodeは無線LANルーターなどに使われているLinuxディストリビューションのOpenWRTが動作する小型ボードです。600MHzのMIPSプロセッサを搭載していたり、OSには標準でOpenCVが入っていたりしているので多少負荷のかかる処理もこなせる程度の性能なのでは、と期待。

早速電源を入れて使っていきたいのですが、残念ながら技適マークがついていないので、そのまま使用すると電波法に違反してしまうと思われます。

ということでまずは有線化改造。本体写真の左側にE3、E4のランドがあるのでここにコネクタを付けるのでしょう。たぶんね。
しかし、Open Hardwareを謳っているにもかかわらずBOMリストが見つからないので、これから適合する探してパーツを買おうと思います。

(追記)
U.FLコネクタが適合するコネクタだと思われる

2014年4月1日火曜日

CPLDで光デジタル出力してみる

最後の投稿が半年前とは時が経つのは早いもので、(ry
とりあえず、作業ログとしていろいろ書いてきたい。ということで、こんなの作った!

これを

こうして

こうじゃ!


単純に興味本位でCPLD(Altera MAX II)で光デジタル出力をしてみました。
一応出力出来たけど、なぜか波形が汚め。たぶん光デジタルのDACが500円くらいの安物だからかな?
VHDL初心者が勢いで作って3日くらいで出来たから、そんなに難しい事でもないんだろうな。

とりあえず完成したときは131ロジックエレメント(LE)で、その後ガリガリ削ったら88LEまで減らせた。ここらへんで満足。

さて、次はなに作ろうか

ソースコード

(あとから見たら恥ずかしくなるんだろうなぁ…)

spdif_top.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity SPDIF_TOP is
 port (
  CLK : in std_logic;
  SPDIF : out std_logic);
end entity;

architecture RTL of SPDIF_TOP is
 component SPDIF_ENC is
  port (
   CLK : in std_logic;
   SPDIF : out std_logic;
   DATA : in std_logic_vector(15 downto 0));
 end component;

 subtype DELAY is std_logic_vector(4 downto 0);
 type DELAY_TABLE is array (0 to 191) of DELAY;
 constant delay_tbl : DELAY_TABLE := (
  "01111","10000","01111","01111","10000","01111","01111","01111","10000","01111",
  "01111","10000","01111","01111","01111","10000","01111","01111","01111","10000",
  "01111","01111","10000","01111","01111","01111","10000","01111","01111","10000",
  "01111","01111","01111","10000","01111","01111","01111","10000","01111","01111",
  "10000","01111","01111","01111","10000","01111","01111","01111","10000","01111",
  "01111","10000","01111","01111","01111","10000","01111","01111","10000","01111",
  "01111","01111","10000","01111","01111","01111","10000","01111","01111","10000",
  "01111","01111","01111","10000","01111","01111","01111","10000","01111","01111",
  "10000","01111","01111","01111","10000","01111","01111","10000","01111","01111",
  "01111","10000","01111","01111","01111","10000","01111","01111","10000","01111",
  "01111","01111","10000","01111","01111","01111","10000","01111","01111","10000",
  "01111","01111","01111","10000","01111","01111","10000","01111","01111","01111",
  "10000","01111","01111","01111","10000","01111","01111","10000","01111","01111",
  "01111","10000","01111","01111","01111","10000","01111","01111","10000","01111",
  "01111","01111","10000","01111","01111","10000","01111","01111","01111","10000",
  "01111","01111","01111","10000","01111","01111","10000","01111","01111","01111",
  "10000","01111","01111","01111","10000","01111","01111","10000","01111","01111",
  "01111","10000","01111","01111","10000","01111","01111","01111","10000","01111",
  "01111","01111","10000","01111","01111","10000","01111","01111","01111","10000",
  "01111","01111");

 signal delay_phase : std_logic_vector(7 downto 0);
 signal delay_cnt : std_logic_vector(4 downto 0);

 signal spdif_clk : std_logic;
 signal spdif_data : std_logic_vector(15 downto 0);

 signal cnt : std_logic_vector(12 downto 0);
begin
 encoder : SPDIF_ENC port map (spdif_clk, SPDIF, spdif_data);

 process (CLK)
 begin
  if (CLK'event and CLK = '1') then
   if (delay_cnt < delay_tbl(conv_integer(delay_phase))) then
    delay_cnt <= delay_cnt + 1;
    spdif_clk <= '0';
   else
    delay_cnt <= (others => '0');
    if (delay_phase < 192 - 1) then
     delay_phase <= delay_phase + 1;
    else
     delay_phase <= (others => '0');
    end if;
    spdif_clk <= '1';

    cnt <= cnt + 1;
    spdif_data <= (15 downto 13 => (cnt(11) xor cnt(6)), 12 => '1' , others => '0');
   end if;
  end if;
 end process;
end architecture;

spdif_enc.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity SPDIF_ENC is
 port (
  CLK : in std_logic;
  SPDIF : out std_logic;
  DATA : in std_logic_vector(15 downto 0));
end entity;

architecture RTL of SPDIF_ENC is
 signal reset : std_logic := '0';

 signal frame : std_logic_vector(7 downto 0) := (others => '0');
 signal channel : std_logic := '0';
 signal cnt : std_logic_vector(5 downto 0) := (others => '0');

 signal preamble : std_logic_vector(7 downto 0);
 signal parity : std_logic := '0';

 signal cell : std_logic := '0';

 constant preamble_b : std_logic_vector(7 downto 0) := "11101000";
 constant preamble_m : std_logic_vector(7 downto 0) := "11100010";
 constant preamble_w : std_logic_vector(7 downto 0) := "11100100";
begin
 process (CLK)
  variable v_logic : std_logic;
  variable v_cell : std_logic;
 begin
  if (CLK'event and CLK = '1') then
   if (reset = '0') then
    preamble <= preamble_b;
    reset <= '1';
   else
    cnt <= cnt + 1;

    if (cnt(5 downto 3) = 0) then -- Preamble
     parity <= '0';
     SPDIF <= preamble(7 - conv_integer(cnt(2 downto 0))) xor cell;
    else
     if (cnt(0) = '1') then
      if (cnt(5 downto 1) >= 12 and cnt(5 downto 1) <= 27) then -- Sample
       v_logic := DATA(conv_integer(cnt(5 downto 1)) - 12);
      elsif (cnt(5 downto 1) = 31) then -- Parity
       v_logic := parity;
      else -- AUX,Validity,Subcode,Channel info
       v_logic := '0';
      end if;
      parity <= parity xor v_logic;

      v_cell := cell xor v_logic;

      if (cnt(5 downto 1) = 31) then
       if (frame < 191) then
        frame <= frame + 1;
       else
        frame <= (others => '0');
       end if;

       channel <= not channel;

       if (channel = '0') then
        preamble <= preamble_w;
       else
        if (frame /= 191) then
         preamble <= preamble_m;
        else
         preamble <= preamble_b;
        end if;
       end if;
      end if;
     else
      v_cell := not cell;
     end if;

     cell <= v_cell;
     SPDIF <= v_cell;
    end if;
   end if;
  end if;
 end process;
end architecture;

参考サイト
ePanorama.net (http://www.epanorama.net/documents/audio/spdif.html)
minidisc.org (http://www.minidisc.org/spdif_c_channel.html)
ボクにもわかる地上デジタル (http://www.geocities.jp/bokunimowakaru/std-spdif.html)

2013年10月9日水曜日

Kuin用3Dモデルファイル knobj 作成ツール

Wavefront objファイルをKuinのknobjに変換するツールです。突貫で作ったのでバグがあるかもしれません。
Blenderで作成したobjファイルでのみ動作確認しています。

ダウンロード

使い方

ダウンロードしたKuinObj.exeにobjファイルをドラッグドロップしてください。メッセージも何も出ないのでobjファイルと同じディレクトリにknobjができていたら変換完了です。

Blenderでobjファイルを作成する場合はメニューの[File]->[Export]->[Wavefront (.obj)]を選択して出た画面の左側 「Export Obj」パネルで
  • Include Normals
  • Include UVs
  • Triangulate Faces
  • Object as OBJ Objects
にチェックを入れ、Upを「-Y Up」にしてから出力してください。

2013年8月16日金曜日

MMDBridge Cyclesスクリプトを作った(新版)

以前作ったMMDBridge with Cyclesスクリプト(MMDBridge Cyclesスクリプトを作った)の構造を変えた新版です。Blenderのアドオンとして動作するようになり、長いシーンも分割する必要がなくなりました。

ダウンロード

使い方

  • 「mmdbridge_cycles.py」をMMDBridgeを導入したMMDのフォルダにコピーする
  • 「mmdbridge」フォルダをBlenderフォルダの"<バージョン>\scripts\addons"にコピーする
  • Blenderを起動します。
  • 「User Preferences」をクリック

  • 「System: MMDBridge」を探してチェックを付けてアドオンを有効にする
  • Sceneプロパティパネルに「MMDBridge Connector」が追加されているので、MMDBridgeを導入した「MikuMikuDance.exe」を指定する。
  • 「Launch MMD」をクリックしてMMDを起動
  • MMDBridgeの設定から「mmdbridge_cycles.py」のスクリプトを選ぶ


  • レンダリングしたいシーンを構成できたらAVI出力する
  • BlenderにMMDのシーンがコピーされる


  • あとは煮るなり焼くなりお好きにどうぞ

2013年5月18日土曜日

MMDBridge Cyclesスクリプトを作った

新しいバージョンを作りました
→(MMDBridge Cyclesスクリプトを作った(新版))


これなに?

uimacさんが開発したMMDからリアルタイムで取り出した描画ジオメトリデータを丸ごとスクリプトで処理できる「MMDBridge」というツール用のスクリプトです。
このスクリプトではBlenderのGIレンダラであるCyclesに最適化したblendファイルを出力することができます。

ダウンロード

2013/5/19更新
ダウンロード

使い方

MMD、MMDBridge、Blenderを準備する。
mmdbridge_cycles.pyをMMDの実行ファイルを同じところに置く
MMDBridgeの設定からスクリプトを有効化
AVI出力をすると開始フレームにダイアログが出てくる

  • blenderのパス
    • blenderの実行ファイルのパスを設定する
  • 解像度
    • 出力解像度を指定する
    • 空欄ならMMDで指定した解像度になる
  • サンプル数
    • Cyclesのレンダリングサンプル数
  • 背景ファイル
    • あらかじめ用意した背景にするblendファイルを選択する
    • 使用しないなら空欄
  • 分割フレーム数
    • 出力ファイル1つに含むフレーム数
    • 200~300くらいがおすすめ
    • 空欄なら全フレームを1つのファイルに出力
    • 1フレームごとに「出力ファイルを開く/保存」を繰り返していて、出力ファイルが巨大になるにつれてファイル操作が遅くなっていくため指定したほうがよい

更新履歴

2013/5/19

  • 裏面消去を設定できるようにした

2013/5/18 初出

FAQ


  • レンダリングしても真っ黒なんだけど
    • 天球がシーン全体を影にしているためだと思われます。以下の方法で対処してください。
      • 裏面消去ONで出力する。背景以外裏面消去したくない場合は先に背景だけを裏面消去ONで出力して、後から設定で「背景ファイル」を指定して背景以外のシーンを出力する
      • 出力したファイルをBlenderで開き、天球のマテリアルを選択してノードエディターを開く
      • 赤枠の部分を追加する


サンプル




2012年3月23日金曜日

3Dディスプレイを試す

「立体視ディスプレイがほしいなー」とかたまに思うのですが、3DコンテンツもPS3も持ってないしちょっと試したいだけでわざわざディスプレイとコンテンツを衝動買いなんて出来ません。こういう衝動って一回使ってみると治まるんですけどねー
やっぱりこういうときは自分で安く作っちゃうのがいいですね!

今回は安価に作れそうなので視差バリア方式で作ります。
ということで材料を買ってきました。



視差バリア方式では有効解像度が液晶の解像度の半分になってしまいますので、元の解像度が高いほうが望ましいです。また画素が大きいと最適な視点が画面から離れてしまい見にくいのでまずは高解像度・高精細なスマートフォンの液晶で試してみます。

1.視差バリアの画像を作る
SVGを作れればいいのでXMLを扱えるライブラリがあればどんな言語でもいいですが、いろいろ調整が便利そうだったのでInkscape用のPythonスクリプトを書いて生成。解像度、ディスプレイサイズ、視差、バリアの距離、目の距離を設定するとバリアが生成されます。

自作やっつけ視差バリア生成スクリプト
 
2.印刷
いきなり印刷して失敗したらもったいないので、このバリアの枠だけを印刷してみたら案の定失敗しました。環境にもよりますが、どうやらInkscapeから直接印刷すると大きさが微妙にずれるみたいです。いろいろ試した結果、 PDFに出力してAdobe Readerから印刷するとぴったりになりました。
早速OHPシートに印刷!

変な濃淡が出た

失敗した…orz
うちのプリンタが9600x2400dpiだっていうから出来ると思ったのにやっぱり細かすぎたんですね。
もちろんこの状態ではまともに立体視できません。

続く