2013年11月9日土曜日

鼻ホタル(充電版)の回路図を公開しました。



前のエントリで販売開始したよって言っていた、鼻ホタル(充電版)の回路図を公開しました。


https://drive.google.com/file/d/0B2MvWvAFndBdMk1hYkU4N2Jyd1U/edit?usp=sharing


鼻ホタル本体、充電器ともに公開しています。


gerberデータもつけてるので、基板やさんにわたせば基板も起こせるはずです。(やってないけど)


私は、トナー転写t=0.3mmの基板に焼き付けて基板をつくっています。(充電器はt=0.8)


勝手にキット販売してもOKですが、なにか間違いがあっても責任は取りません。


ということで。





2013年11月4日月曜日

鼻ホタルの販売はじめました



2年前に作った鼻ホタル、割とネタになって、中国でキット販売されたり、それをamazonで転売してる人がいたりするものの、「買った」という話は一切聞かない謎の装置です。


詳しくはこちらをご覧下さい。


http://www.youtube.com/watch?v=CQJDa41mKwA





私自身も鼻ホタルのキット(Nose LED Kit)は万人にはお勧めってわけじゃなくて、半田付けに自信がある人向けのキットだなーとは思っていたのです。実際に、組立済みを売ってっていう話が3件ほどありました(東京・英・米と無駄にグローバル)。


なんで、今回組立済みの鼻ホタルを数量限定で販売しました。


さらに、今まで電池が米粒のように小さい電池を2個まとめてセットするという至難の業が必要だっのを改めて、コネクタで抜き差しできる充電池に変えました。これでだいぶ簡単に使えるようになったはずです。





全て手作りで割と大変でした、本当に、自分で使う人にだけ買って欲しいです。


なんで、転売屋がパスしそうな、ちょっと強気な値段に設定してます。


転売屋は好きではないですが、鼻ホタルのバッタもんを作るのは歓迎していて回路図も公開しています。


みんなでクレイジーな世界を作りましょう。


http://www.creema.jp/c/akira_you





2013年10月8日火曜日

浮動小数点の罠:「a==b」を「fabs(a-b)<E」に書き換えるは間違い。</pp>



a==bで比較してはいけない理由は計算精度都合で「1/10*10 != 1/2*2」となる場合があるからです。



その対策として、微小値E(doulbeだと約1E-15,float 1E-7ぐらい)を使って、


「fabs(a-b)<E」と実装しなおしている人が多いかと思います。



(サラリーマンとしてコード書いていると、a==bってコードは機械的に禁止されてる。)


多くの場合は上のやり方で動くんです。でも以下の例を見て下さい。



fabs( (a-b)*1.0E+100) <E



実はこないだ、ぼーっとコードを書いていてやってしまったんですがこいつは正しく動かない可能性が高いです。だって1.E-15*1.0E+100=1.0E+85ですから。


私の場合は、数学的にはf(x)<g(x)をやりたくてf(x)-g(x)<Eと書いていました。そして同じ問題にぶつかりました。



実際にはf(x)もしくはg(x)のオーダに合わせてEを定数倍する必要があるんですね。


さらに、浮動小数点を「==」だけじゃなく「<」でも考えなきゃいけないんです。



ただ、厄介なのはオーダってどないして調べようという話があります。例えば「a-b == c-d」においてEの定数倍を考える時必要なオーダはaやbのオーダであってa-bのオーダではない。という問題があります。


この問題は、大きな値同士を引き算(or足し算)した結果が元のオーダより小さくなる場合(桁落ち)の時に起きます。


かけ算しかないような場所なら桁落ちの心配はいらないので、単純に以下の様にしてOKです。



fabs(a-b)<E*max(fabs(a),fabs(b))



ここで、再び桁落ちについて考えます。計算途中に桁落ちでおちる桁数をdとすると以下の数式のようにも解釈できます。



fabs(a-b)<E*1.0E+[桁落ちした桁数] *max(fabs(a),fabs(b))


桁落ちした分だけ誤差範囲Eを定数倍して、さらに比較対象のオーダにあわせてEを定数倍する。



上の様に浮動小数点の比較(==だけじゃなく<も)ってのは計算を追わないと解らない根が深い問題なんです。世の中のコーディング規約(MISRA-C) なんかではさくっと無視されたりする問題だけど、すっごい希に見つかるので謎のバグとして頭なやます事になります。気をつけてね。














書いていて自信がなくなったぞ、、、いつもは深い事考えずにEは許される精度の範囲でできるだけ大きくとって逃げてるので。。。orz。だれか詳しい人まともな解説お願い。





2013年10月6日日曜日

上限・下限制限つき最小二乗を実装した



最小二乗といってもy=ax+bに近似するタイプではないです。


ベクトルA1,A2,A3・・・を適当な比率x1,x2,x3,・・・で足し合わせて、入力されたベクトルBを近似しようというものです。



B≒x1*A1 + x2*A2 +x3*A3



このときにx1~x3が取り得る範囲をそれぞれ制限してあげようというのがこのアルゴリズムです。





論文とかあたってると、飛行機だとか自動車の制御等で、ラダーや各タイヤの出力を制限範囲内で最適に配分するってのに使われてるらしいんですが・・・・制御系の人間じゃないので、興味わかず。


純粋に音声などの信号の解析に使えるかな~と思って作りました。


音声はMFCC等の20次元ぐらいのベクトルで表す事ができて、それが時系列で変化していきます。でコレが「あ」とか判断するのが普通なんですが、「あ」と「い」の中間って普通に考えるとあるわけじゃないですか。だから、「あ」20%+「い」80%とかも有り得るのかなと。


これで制限なしの最小二乗で解いちゃうと「あ」1000%+「い」-9900%とかとんちんかんな事言い出したりするんですね。これだけなら非負という制限かければいいんですが、前後の関係から「あ」は20±20%、「い」は80±20%ぐらいだな~ってあたりが付いてることもあるんですね。そんなときに上限・下限制限つきの最小二乗が必要になっちゃうんです。


ちなみにMatlabには搭載されてるらしいです。C++の実装がみつかんなかったので、実装してみました。





このアルゴリズムは以下の論文の内容を実装したものです。


http://www.nt.ntnu.no/users/skoge/prost/proceedings/acc08/data/papers/0854.pdf


ソースはこちら。(行列ライブラリとして「Eigen」使ってます、別途DLしてください。)


https://drive.google.com/folderview?id=0B2MvWvAFndBdNG9YY0tOenRZejQ&usp=sharing





2013年10月4日金曜日

道具に拘るエンジニアは無能なのか?



道具に拘るエンジニアはだいたい無能だという主張があるらしい。


引用:http://anond.hatelabo.jp/20131005004542


しかしながら本文中にもあるように、深く考えるために、落ち着く「環境」は大切だと思う。



出来るエンジニアが最も求めるのは、深く考える事が出来る環境と、


周到な議論を繰り返せる優れた同僚に他ならない。



環境というと、静けさだとか暑さ・寒さとかだけを指す言葉のような気がするけれども、目的は「深く考える」ためで、私の場合はそれは「落ち着く」事でなんです。そのための「環境」が必要。その上で、その「環境」に「道具」が含まれるか否かだけでの話にすぎないだけだと思う。


ちなみに多くの工学部の人は、自分の研究とかに対して「何故その手法を用いたのですか?」という質問をすると、最初は理性的な答え(速度が速いから等)を返してくる。その答えに対してさらに、何故その答えなのか?と細かく突き詰めていくと、結構な頻度で「xxでもできるのですが、ooの方が美しいからです」という答えが出たりする。多くの場合、これはコンセンサスを得られる答えではない。しかしながら、これは責められる事ではなくて、大切な個性、所謂その人のセンスだと思う。


表面上は理論武装してても、一皮一皮丁寧に向いていけば、「好きだから」「美しいから」といった本能むき出しな価値観で仕事に取り組む。それが工学系の実態だし、だからこそ多様性のある技術進化の模索ができると信じてる。


だから、大まじめには他人の道具(環境)にケチ付けないほうがいいと思うんだ。emacs派とvi派は犬猿の仲に見えて同じ穴の狢なのです。もちろん、気の知れた中でお互いの道具の自慢(≒ケチの付け合い)をするのは楽しいってのはわかりますよ。えぇ。


ちなみに私の場合


私は信号処理のソフト開発がメインなので、引用元が言っているエンジニアに近い仕事だと思う。


そんな私の落ち着く環境は思いつく限り以下のようなもの。




  • OS:FreeBSD メモリを使い過ぎた時も、ディスク溢れさせた時もそっと動いてくれる頼もしい存在。

  • エディタ:emacs ぶっちゃけオートインデントが付いていればどんなエディタでも良いと思いながら、手に馴染んでるのはコレしかない。

  • グラフ描画:gnuplot 100ぐらいの大きさの信号中の0.1ぐらいの変動を目視で見たい!って感じなので、拡大縮小が気持ちよく動く事は個人的に大切。一度だけソース覗いた事あるけど、データ入力・保持周りを頑張ればもうちょっと描画速度あげれるよね・・・・という不満はあるんだけどね。

  • キーボード: Realfoce 89 フルサイズのキーボードはマウスが遠いのが気になる。

  • ボールペン:インクどばどばでちゃう感じのをサラサラインク系のボールペン

  • 紙:薄いノートorプリンタからパクってきた紙。基本殴り書きでグラフ書いてる時間が長い。分厚いノートは苦手。偶に数式解くけど、Maxima(数式処理ソフト)に出来るだけやるようにしてる。

  • 音楽:コーディング中等アウトプット作業中は音楽があると集中できる、論文読んだりのインプット作業中は音楽なしが集中できる。考え中はどっちでも。自分でも不思議なぐらい作業によって効用が違う。





2013年6月29日土曜日

VirtualBoxのBiosRomファイル



VirtualBoxはBiosを入れ替える機能を持ってるんだけれども、BIOSファイルのフォーマットってなんやねん。で止まってた。


結論から言うと、アドレス 0xf0000から始まる64KbyteがBIOSってことらしい。


なんでFreeBSDでBIOSを取得するには以下のコマンドをrootで実行すればいい。



dd if=/dev/mem bs=64k of=bios.bin iseek=15 count=1



基本的にはVirtualBox上でBIOSをダンプして、それを書き換えて起動できないBIOSを作って泣くのが主な使い方みたいだね。





LAN DISK HDL2-Aでリモートシャットダウン



CSRF対策でruby使わないと簡単にはリモートシャットダウンできないようになってるのね。ということで書きました。


urlとpassの行を適宜自分の環境に書き換えれば動くはずです。


ただしruby mechanizeを使っているのでFreeBSDな人はwww/rubygem-mechanize をあらかじめインストールしておいてください。






#!/usr/local/bin/ruby
# -*- coding: utf-8 -*-
####### 設定内容
url="http://10.0.0.1"
pass="your password"

####### 以下処理内容
require 'rubygems'
require 'mechanize'
agent=Mechanize.new
page=agent.get(url);
# ログイン
page.form_with(:name => 'form') { |f|
f.field_with(:type => 'password').value=pass}.submit
#シャットダウンページ取得
page=agent.get(url+"/system/detail/system/shutdown.php");
#デフォルトで再起動ではなく、シャットダウンに選択されてるはず、そのままsubmit
page=page.form_with(:name => 'form').submit
#確認画面(本当はjavascriptで確認画面処理してるので、飛ばして最後のシャットダウン実行
page=page.form_with(:name => 'form'){|f| f.default_event="shutdown" }.submit






2013年6月27日木曜日

GPTパーティションのUSBメモリをwindowsで使おうとしてはまる。。。。



MacやFreeBSDなどUSBメモリからのOS起動のときって旧来のMBR形式じゃなくて今風のGPTでディスクを初期化することになる。


それはそれでいいんだけど、問題は市販のNASだとかは特許のからみでイニシエのフォーマットであるFATフォーマットが必要とされている。


windowsのFATは実はGPTパーティションに対応していない。


なのでGPTをMBRに変更する必要があるんだけど、、、こんな方法普通に思いつくかよ!なんで管理ツールからいけへんねん。





http://www.atmarkit.co.jp/fwin2k/win2ktips/1378clngpt/clngpt.html





LAN DISK HDL2-Aでフォルダ間バックアップ



バックアップ用フォルダにどんどん上書き追記するという原始的なバックアップをとりたい場合あるよね。


そんな機能ないな~と思ったけれども、「ネットワークバックアップ」でバックアップ元のIPアドレスを127.0.0.1に設定できる事に気がつく。


それだけなんだけど、気がつかないと悩む事になる。





2013年6月25日火曜日

エクセル2013が落ちまくる時はマルチスレッドOFF



ぐぐると「オートコンプリートOFF」で対応できるという話が出てくるけど、


オプションの詳細設定にある「マルチスレッド」をOFFにする事でも効果があるようです。


ただし、マルチスレッドの設定は「計算」のマルチスレッドと「全般」のマルチスレッドの2つがあるので要注意。多分「全般」のほうが効いてくるけれども。念のため両方OFFのほうが安心かも?


マルチスレッドは、複数のCPUを使って高速化する機能なので、


処理速度がちょっと落ちるけれども、機能面では全く差はないです。





2013年6月14日金曜日

ガウス関数の最小二乗(最小自乗)フィッティング と ガウス窓ミーンシフト



最初に一言



ガウス関数(exp(-x^2))の最小二乗フィッティングの際に、「対数取ってから2次関数近似すればよい」とか嘘だから。



ノイズというのも貴重な情報です。ノイズの分布を考慮せずに空間を安易に変換してはいけません。最小二乗法ではノイズの分布が時刻によって変動しない事を前提としています。


例えば有る時間で信号が1でノイズ幅が1だったとします。べつの時刻で信号が100でノイズ幅が1だとします。これは最小二乗法でフィッティングしてOKです。


ここで対数を取るとざっくりlog(2)-log(1)=0.69とlog(101)-log(100)=0.0099となって小さい信号の上にのったノイズにひっぱられて、大きな信号の上のノイズを見逃します。


同様に、多くの場合で最尤推定!=最小二乗です。


あーーー、すっきりした。 


では本題


ということでガウス関数の最小二乗をやろうと思ってググってたんですが、なんか良いサンプルが見つからないんですね。で、頑張って自分で微分して、解を求めようとしたんですが、どーも計算できない。(微分・積分苦手)


最尤推定のときは解析解が求まるけど、最小二乗だと解析解がもとまらないのかな?という事で普通はニュートン法に逃げる訳だけれども、微分式を見るとなんか既視感。



g(t)をガウスモデル関数とする(なお、Σ時間tでの積算)


振幅aで微分: Σa*g(t)*g(t) =Σg(t)*i(t)


平均uで微分: Σa*g(t)*g(t)*t =Σg(t)*i(t)*t


標準偏差sで微分:Σa*g(t)*g(t)*t*t =Σg(t)*i(t)*t*t



モーメントの形に成っちゃってるけれども、ざっくりと言うと。



入力信号にモデル関数を掛けた平均値が、


モデル関数にモデル関数をかけたものの平均値になるようにパラメータを決めなさい。



ってこったね。


ん?ここではガウス窓で見てるけれども、矩形窓だと考えて平均値のみを考えるとミーンシフトそのものだよね?



1.適当な矩形範囲で重心を求める


2.上で求めた重心を中心にした矩形範囲で重心を求め直す


3.落ち着くまで2を繰り返す



ということで、ミーンシフトとして解釈して実装してみた。ただし、全体を最小二乗マッチングする必要あるので窓範囲=入力信号範囲。そのため、窓関数の重心が中心にくるとは限らない状況。


なんでモデルの重心も意識しながらコーディングする必要があるのがオリジナルのミーンシフトと違うという解釈。


結局は原始的な山登り法なんじゃね?という疑惑がふつふつと自分の中でわき上がるけれども、今後非対称重みのミーンシフトを実装する自信がついたのでよしとする。


以下rubyのサンプルコード(標準偏差もうごいてるけど真面目に考えてない)






#!/usr/bin/ruby
# -*- coding: utf-8 -*-
include Math

#テスト用入力信号
input=Array.new
100.times do |i|
signal = exp(-((i.to_f-75)/30.0)**2/2.0)*4.0;
signal += 0.1 * rand #-0.5;
input.push(signal)
end

#ガウス関数
##t=time u= center s=stddev
def gauss(t,u,s)
return exp(-((t-u)/s)**2/2)
end

#初期値を適当に設定(対数とって最小二乗でもいいよ)
m0=0.0
m1=0.0
m2=0.0
input.size.times do |t|
m0+=input[t]
m1+=input[t] * t
m2+=input[t] * t**2
end
u= m1/m0;
s= sqrt(m2/m0 - u**2);

#振幅を求める
def detectA(input,u,s)
gg=0.0
gi=0.0
input.size.times do |t|
g=gauss(t,u,s);
gg += g**2;
gi += g*input[t]
end
return gi/gg;
end

#平均と標準偏差更新(ついでに振幅)
def detectUS(input,a,u,s)
mg0=mg1=mg2=mi0=mi1=mi2=0.0
input.size.times do |t|
g=a*gauss(t,u,s);
gi=g * input[t]
gg= g* g
mi0+=gi
mi1+=gi * t
mi2+=gi * t**2

mg0+=gg
mg1+=gg * t
mg2+=gg * t**2


end
ui=mi1/mi0 #実際の重心候補
ug=mg1/mg0 #理論上の重心 (データ打ち切りの影響で中心!=重心)
vi=mi2/mi0 - ui**2 #実際の分散候補
vg=mg2/mg0 - ug**2 #理論上の分散
a=detectA(input,u,s)
return [a,u+ui-ug,sqrt(s**2 + vi-vg) ]
end
a=detectA(input,u,s)

#更新処理
100.times do |i|
d=detectUS(input,a,u,s)
a=d[0]
u=d[1]
s=d[2]
puts "#{a}\t#{u}\t#{s}";
end

#結果出力
open("o","w")do |f|
input.size.times do |t|
f.puts "#{input[t]}\t#{ a * gauss(t,u,s)}"
end
end






実は大切なノイズ



理想的な計測装置はノイズのない回路と、無限段階のADコンバータだけれども、現実にはADコンバータは有限段階です(例えば256段階とか)。



Q:ノイズはゼロが望ましいんでしょうか?


A:違います。



測定対象の信号の変動具合と、ADコンバータのサンプリングレート・分解能によって最適なノイズ量ってのがあります。例えば、測定対象が時間によって変動しないと見なせる場合で。かつ、測定値がADコンバータの換算値で0.5の場合。ノイズなしでは測定値は0です。ここでノイズが乗っている場合測定値のヒストグラムは0.5を中心とした正規分布になります。


ヒストグラムの幅がある程度あるほうが、正確に中心が求まるのである程度ノイズが大きい方が嬉しいですが。算出される計算結果には ノイズ幅xsqrt(測定回数)の誤差が含まれます。


そんな感じでノイズを活用すると、計測時間と精度をトレードオフではあるけれども、性能向上ができるんですね。なんで、ノイズを0と見なした信号処理はもったいない上に、上の対数変換で説明したあような誤りを誘う邪教なんです。





2013年6月12日水曜日

Audacityで現在の録音レベルを知りたいとき。



知りたい領域を選んで「エフェクト→増幅」で表示されるデシベルが現在クリップなしで増幅可能なデシベル数。


なんで4.2とか書いてあったらその領域の最大dBは-4.2


知らないと「解析」とか探して。なんでこんな基本機能ないんだ?って焦るよね。





2013年6月9日日曜日

FreeBSDで起動時に我武者羅に SSHを公開する。



用途「 遠隔地のFreeBSDマシンが HDD障害などで起動しなくなった時に、USBメモリから起動して、遠隔からSSHで入る」


USB起動ディスクを作るのは前回示した通り。


あとは、 なんのNICが刺さってるかわからないマシンで、いわゆる「BBルータ」の後ろにいるマシンに繋ぎたい。


結論から書くとこれをrc.localにつっこむ



ifconfig -l | tr " " "\n"|grep -v lo0 |xargs -n 1 dhclient


ifconfig |grep "inet 192"|awk '{print $2}' |sort |uniq |cat -n|awk '{print "/usr/local/bin/upnpc -a "$2" 22 8"$1"22 tcp"}' | sh



miniupnpcがインストールしてあることが前提なので注意。


これで適当に、 8122 ,8222,8322番のポートにSSHが公開されるようになるはず。


やっていることは、1行目で、 NICの一覧を取得してそれぞれにDHCPクライアントを実行しています。


2行目は、192.から始まるアドレスの22(SSH)ポートをUPnP を使ってルータの外に公開しています。





現実的な運用としては更に、自分のサイトにpingを打ち続けるなどの対処をしておいてIPアドレスを自分の端末から調べられるようにしておいたほうが無難ですね。





2013年6月2日日曜日

FreeBSDからUPnP IGDのポートマッピングを設定する(with miniupnpc)



以下を参考にちょっとしたノウハウの追加


http://d.hatena.ne.jp/konbunori/20110328/1301250660


説明を足したい


NAT設定の説明は-eオプションで足せます



upnpc -u ${ROOT_RUL} -e "my main server ssh " -a 192.168.1.3 22 8022



動作が遅い


ルータを探すのに2秒ほど待つので遅いです。



upnpc -l



とやってdesc:で始まる行がルータのURLなのでソレをメモしておけば高速に実行できます。


シェルスクリプトなんかではこんな風にするといいんじゃないでしょうか?



ROOT_URL=`upnpc -l | grep "desc:" | head -n 1 | sed -E 's/ +desc: +//'`


upnpc -u ${ROOT_URL} -e "my main server ssh " -a 192.168.1.3 22 8022






簡単な実運用方法


同じ設定を何度やっても特段弊害はなさそうです(試したルータはPR-400KI)。


なんで単純にこんなスクリプトをcronで回しまくれば大丈夫です(多分)



#!/bin/sh


ROOT_URL=`upnpc -l | grep "desc:" | head -n 1 | sed -E 's/ +desc: +//'`


upnpc -u ${ROOT_URL} -e "my main server ssh " -a 192.168.1.3 22 8022 tcp >/dev/null


upnpc -u ${ROOT_URL} -e "my main server ssh " -a 192.168.1.3 22 8023 tcp >/dev/null



なんでこんな事しらべたの?


多くのFreeBSD使いは、実家だとか知り合いのマシンのリモートメンテしてたりする事が多いかと思うんです。そんなとき「ルータの設定飛んじゃった」とか困りますよね。


ルータ故障に関しては、インターネットが繋がるって所までは電話屋呼びつけて修理させればOK。ただ、田舎のNTT系列会社にNATが理解できるとは思えない。最近はUPnPデフォルトONみたいなんで、これで設定しとけばとりあえず安心だよね~という事で。。。


変なソフトに先に取られちゃうリスクはあるので、静的に設定しとくのも大切っちゃ大切なんですが。





メモ:cdrdao(gcdmaster)で音楽CDを焼くときのドライバの設定(CD-TEXT有効化)



ドライブがgeneric-mmc-rawドライバに対応していれば問題ないけど、


generic-mmcを使う場合はデフォルトではCD-TEXT(曲タイトル等)を無視する。


ドライバのオプションとして0x50を指定するのが吉。


gcdmasterでは0x00と書いてある欄を0x50に書き換え、コマンドラインなら「--driver generic-mmc:0x50」と指定






2013年3月20日水曜日

FreeBSDをUSBメモリからブートするための最低限のインストールスクリプト。





  • 予め/tttディレクトリにFreeBSDのサイトにあるkernel.txz base.txzをダウンロードしておく

  • 以下のスクリプトを実行(以下スクリプトの実行内容)


    • パーティションを削除

    • パーティション作成・設定

    • newfsでフォーマット

    • tarでFreeBSDインストール

    • 日本語キーボード、タイムゾーン設定





DISK=da0
gpart delete -i 1 ${DISK}
gpart delete -i 2 ${DISK}
gpart delete -i 3 ${DISK}
gpart delete -i 4 ${DISK}
gpart destroy ${DISK}
gpart create -s gpt ${DISK} ||exit
gpart add -t freebsd-boot -l stickboot -b 40 -s 512K ${DISK} ||exit
gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ${DISK} ||exit
gpart add -t freebsd-ufs -l stickroot -b 1M ${DISK} ||exit
newfs -U /dev/${DISK}p2 ||exit
tunefs -t enable -j enable -o space /dev/da0p2
mount /dev/${DISK}p2 /mnt || exit
cd /mnt || exit
tar vxypf /ttt/kernel.txz || exit
tar vxypf /ttt/base.txz || exit

echo "/dev/gpt/stickroot / ufs rw,noatime 1 1" >/mnt/etc/fstab
echo 'hostname="i3.local"' >/mnt/etc/rc.conf
echo 'keymap="jp.106.kbd"' >>/mnt/etc/rc.conf
cp /mnt/usr/share/zoneinfo/Asia/Tokyo /mnt/etc/localtime
cd
umount /mnt





2013年2月17日日曜日

人間臭い温度計の作り方案



課題


インタラクション作品で温度を測る場合に、水の30度と空気の30度って感じ方が全然違うよね?という問題がある。


本案の解決策


ヒータと温度計を貼り合わせて、PID制御等適当な温度制御をかける(人間でいえば体温を保つ)。その際のヒータへの投入電力量を量り、それをもって寒さ(冷たさ)を定義する。単純な抵抗を用いたヒータである場合、電圧を一定にしPWM制御をかけることで、電力量を直接測る事なく投入電力量を算出する事が可能である。また温度に関しても、コンパレータのみを搭載しADコンバータを搭載しないような安価な装置であっても利用可能となる。


当然ながら、暑さを測る場合はヒータの代わりにペルチェ素子・ヒートポンプなど制御可能な冷温源を使う事が考えられる。





種明かし


実は類似の技術は電子天秤でつかわれてます。


バネばかりだと、理想的にはバネののび量と重さは比例するんだけど、厳密にはちょっとずれちゃう。


なので高い電子天秤ではバネばかりが0gを指すように下からコイルと磁石でキャンセルする力を生み出します。そしてコイルに流した電流量を測ります(電流→コイルで作る力→質量という関係)。


こうすることで機械的な位置関係は完璧に同じなので、機械の加工精度等で結果がずれる危険性がかなり低減されます。


なので、たぶん探せば上案のような装置はあるんだろうけど(すくなくとも風速計はかなり似てる)、不思議とインタラクション作品などで温度センサーはわりとみても、上のような工夫ってあまりみないな~とおもったので書いてみた。