20120604

「越境する脳」読了。

BMI(Brain-Machine Interface、脳の感覚・中枢・運動機能を電気的人工回路で補綴・再建・増進することを目的とした技術)の研究で有名なミゲル・ニコレリス博士の著作。
読み終わるまでに結構時間がかかっちゃいました。

科学読み物ではありますが、博士の学生時代から現在までの思い出、研究のきっかけ、その裏側、思考、夢etcを綴ったエッセイという感想も持ちました。
将来、神経工学分野に進みたい(且つちょっとマッドな研究をしてみたい)と考えている自分にとっては興奮しっぱなしの内容でした。
Brain-to-Brain Interfaceって何それ!?
すんごく面白そう!!
このラボに移りたい!!

最終章で述べられていた、博士の持つ未来予想図はとても攻殻機動隊チック。
いいよね〜、それ。
どこかで本気で研究されてないだろうか?
今後、博士が研究しないだろうか?

20120528

腕時計落として風防割っちゃった…

どうもお久しぶりです。

ここ最近、グルーガンの先端で腕を火傷したり、ハンドドリルのギアで指を挟んで血豆作ったり、そしてExtreme IIを落として風防(という呼び名を今回初めて知ったよ!)を割ってしまったり…
どうにも駄目ですね。
疲れて注意散漫なのかしらん。

さてさて。
これを機にストックとして眠っていたこいつを使おうかなと思っています。
フィリップ・スタルクデザイン、フォッシル社の…名前忘れた。
液晶画面でアナログ針を表示する、という仕様です。
今は電池が入っていないので何も映っていませんが。

割ってしまって気付いたのですが、風防が球面だと出っ張ってしまって今回みたいに落とした場合にクリティカルな事態になっちゃうんですね。
平面か、もしくは周辺のほうが土手みたいに出っ張っているほうが自分みたいに荒っぽいヤツには向いていますね。

しかし、今回割っちゃったExtreme II、風防修理したいな、いつか自分で。

20120405

なんちゃってオシロスコープ

久しぶりのUSB-1608FSネタ。

前回LEDを点滅させた頃には、実は既に取り込み自体は出来てたんですよ。
SnoopyProの結果から「使用チャンネル: 0番、サンプリングレート: 1Hz、レンジ: 10V」で取り込む場合には、色々省略すると
USB1608FS.ctrl_transfer(0x21, 0x09, 0x0, 0x0, [0x43, 0x01])
USB1608FS.ctrl_transfer(0x21, 0x09, 0x0, 0x0, [0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
USB1608FS.ctrl_transfer(0x21, 0x09, 0x0, 0x0, [0x11, 0x00, 0x00, 0xc0, 0x03, 0x10, 0x00, 0x08, 0x95, 0x98, 0x04])
取り込みストップ、レンジ設定、チャンネル・サンプリングレート設定?した後に
USB1608FS.read(0x83, size, interface=1)
ただ、これで返ってくる値は
array('B', [238, 141, 240, 141, 240, 141, 239, 141, 239, 141, 239, 141, 239, 141, 239, 141, 239, 141, 239, 141, 240, 141, 87, 138, 203, 4, 117, 7, 171, 8, 248, 8, 129, 9, 42, 10, 161, 10, 219, 10, 99, 11, 33, 14, 0, 14, 159, 14, 9, 14, 133, 13, 99, 13, 170, 10, 143, 10, 8, 11, 11, 11, 134, 1])
例えばこんな感じで、どれが目的の値なのか分からない。
というのも、今回用いているUSB-1608FSは解像度?量子化レベル数?が16bitなもんで、2進数なら16桁、16進数なら4桁、10進数なら…まあ桁で表現しづらいですが0-65535の値を取り得る訳ですよ。
どうみても過剰な要素数(=64)の値が返ってきてるんですよ。


ここでSnoopyProに戻ると、値は異なりますが、先程の値に対応しそうな結果はこちら。


どうやら、個々の要素は16進数の2桁分みたい。
ということは、2個の要素をくっつければ1個分になるのではないかと。
それでも32個分のデータがあるわけですが…アナログ8チャンネル+デジタル8チャンネル…で、あ〜まだまだ余りますね。
よく分からないので、この点に関してはまた追々。


さてPythonの方に話を戻すと、目指すは、10進数*2要素→8bitの2進数*2要素に変換・結合→10進数(0-65535)→電位(V)。
10→2進数変換はbinを用いていい感じのヤツ作りました(下記のソースコードのdec2bin参照)。
2→10進数変換はPythonが勝手にやってくれる(0b10とか入力すると2とみなして処理してくれる)ので気にする必要はなし。
0-65535の値を電位に変換するにはサードパーティ製ドライバのソースコード(C言語)を参考に
Volt = (Decimal-32768)*10.0/32767
すると良さ気。
つまり32768(65535+1の半分)が0になるようにベースを調節してやって、レンジに合わせて1量子化レベルあたりの電位を掛けてやる、という具合。
図解するこんな具合。
公式の取扱説明書から拝借。


本当は、ソースコードでは更に補正値として1.17が掛けてあったのですが…まあとりあえず無視。


以上を踏まえ、サードパーティ製ドライバのソースコードを参考にしまくって作ってみたのが、タイトルにある「なんちゃってオシロスコープ」

usb1608fs_oscillo.py
import usb

def Initial():
     USB1608FS = usb.core.find(idVendor=0x09db, idProduct=0x007d)
     for i in range(7):
     if USB1608FS.is_kernel_driver_active(i):
          USB1608FS.detach_kernel_driver(i)
     USB1608FS.set_configuration()
     # ch0-0 1Hz 1sample 10V
     USB1608FS.ctrl_transfer(0x21, 0x09, 0x0, 0x0, [0x43, 0x01])
     USB1608FS.ctrl_transfer(0x21, 0x09, 0x0, 0x0, [0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
     USB1608FS.ctrl_transfer(0x21, 0x09, 0x0, 0x0, [0x11, 0x00, 0x00, 0xc0, 0x03, 0x10, 0x00, 0x08, 0x95, 0x98, 0x04])
     return USB1608FS

def dec2bin(decimal, digits):
     binary = bin(decimal)[2:]
     if len(binary) < digits:
          binary = '0'*(digits-len(binary))+binary
     return binary

USB1608FS = Initial()

i = 0
while True:
     PIPE = i%6+1
     O = USB1608FS.read(0x80+PIPE+2, 0x40, interface=PIPE, timeout=1000+100)
     V = (int(dec2bin(O[1],8)+dec2bin(O[0],8),2)-0x8000)*10.0/0x7fff
     Vdisp = int(round(V*5.0+50))

     print ' '*(Vdisp-1)+'|'

     i = i+1


取り込みで沢山返ってくる値の内の第1、第2要素だけを抜き出してきてます。
ただ、他の要素も大体連動して同じような値になるので、結局のところどの要素に着目すればいいのやら…
チャンネル数を増やして、別々の値を掛けて…とかすれば分かるのでしょうけれども…それもまた追々。


matplotlibとか使って見栄えよく作ろうとしたんですけどね…アニメーション化の方法分からない…
でも、これはこれでシンプルでいいですよね?
16bitを全く活かせていない、7bit程度で十分な感じですけど。
ただ、こうなると、横スクロールさせたくなってしまいます。