2017年2月17日金曜日

超音波風速計(番外編) 温度計を考える


昔買ってあったサーミスタの特性をグラフにしてみた。R, C, Zoutは中央の対数スケール、Voutは右の線形スケール。
 25℃の時に0.12mAになるよーに、という指定を守ると、だいたい0℃から35℃あたりで線形近似できるっぽい?電圧がだいたい0.5V-2.5Vというのも能動的アナログ素子禁止縛りプレイ中の今回は便利。出力インピーダンスは最大で25kΩあたりだが、この程度ならSTMに直結できるのでインピーダンス変換の必用もなし。

 しかし、このサーミスタ、時定数を下げるためかやたらと小さい。米粒よりも小さいぞ。それでも時定数4secだから、超音波風速計で測るより数桁遅い。超音波ってすごいねぇ。ナミ、スゴイ。

超音波風速計 とりあえずそれっぽい感じの何か


 C#のChartでリアルタイムに風速を表示してみた。息を吹いたりヒートガンで風当てたりすると波形が動くので気分が高揚します。途中で尖いピークが有るのはノイズだと思う。ほとんどのパラメータは固定だし、風速計としての性能はろくなもんじゃないが、とりあえずこういう画面があれば多少はモチベーションが維持できる。といいな。

 いまは2chしか計測してないので、10Hz近い速度で更新できてると思う。可動部がないので、回転式とくらべてもはるかに追従性が高いと思う。少なくとも手持ちの安い風速計じゃ「すごく熱いものを食べてホフホフする」くらいの息遣いではセンサの回転が止まらないし、超音波風速計ならちゃんと山と谷が見える。


 ちゃんと動作してるか確認するのは、やっぱり風洞とかほしいなぁ。あとはやく3軸化したい。

2017年2月16日木曜日

超音波風速計 時間を測りたい



 青のRAWがADCから受け取った値をFIRに通してAC結合した値、赤のETSが等価時間サンプリングで時間分解能を14倍にした値です。2枚目と3枚目は1枚目の一部を拡大した図になります。
 横軸はマイクロ秒単位です。縦軸にも数字がありますが、高さを示すラベル以上の意味はありません。

 実時間サンプリングの青に比べ、等価時間サンプリングの赤は横方向の分解能が高いのがわかると思います。
 縦軸はFIRの処理の関係で1bitあたりの分解能が決まりますが、結果をS16bitの変数に入れてるので、まだ5bitの余裕があります。32倍くらい分解能を上げられます。


 超音波がマイクに届くまでの時間は、RAWの値が500を超えるくらいを閾値にして検出すると、おおよそそれっぽい値が取れそうな気がします。波形の振幅幅によって閾値に達する時間が変わりますが、正確な数字はETSのゼロクロスで補正できると思います。


 遅まきながら、先人たちが超音波風速計を作ったときの方法を確認してみたところ、アナログ回路で増幅とAM復調を行い、閾値を超えるタイミングをタイマで検出しているようです。
 タイマでパルス幅を検出するのであれば、ADCよりケタ違いに時間分解能が高いので、AM復調でも充分な分解能が有るようです。
 しかし、今回はすべての処理をデジタルで行っているので、ADCの時間分解能がそのまま分解能になってしまいます。ETSは正弦波の立ち上がりには使えないので、単純なAM復調では処理できません。ハードウェア楽な分、ソフトウェアで苦労しているといえます。
 某社が作っている自衛隊向け無線機もソフトウェア無線化されており、機材の低価格化等を行っているようですが、ソフトウェア開発は大変だろうなぁ。ま、超音波はRFとくらべて周波数が5,6桁低いので、こっちは比べるまでもなくかなり楽なんでしょうが。

***追記
 

 3枚目の図の階段グラフを作ってみた。こっちのほうが実時間サンプリング(RTS)と等価時間サンプリング(ETS)の差がわかりやすい。
 RTSの分解能は1.556...マイクロ秒、ETSの分解能は0.111...マイクロ秒。風速換算でRTSが1.3m/s、ETSが0.088m/s程度となる。

*** 追記


 今更になってデータのとり間違いに気がつくなど。。。
 一番上の画像の波形の立ち上がりは、マイクの立ち上がりじゃなくて、FIRフィルタの立ち上がりである。ETSを行う上で波形が安定するまで(1.5msecくらい)待ってからADCを開始していたのを忘れていた。
 ということで、正しいマイクの立ち上がりはこの画像。青がADCの値で右軸のが電圧。赤がFIRを通した後。FIRの遅れは補正済み。
 ADC直後の生データは小さなノイズが乗っていて、FIRでだいぶ消えている。図らずもバンドパスフィルタの動作確認をしてしまった。

 FIRを通した後の波形は安定時で30000くらいだが、立ち上がりでは1フェーズあたり2000くらいのペースで15-20フェーズくらいかけてゆっくりと立ち上がってる。しかし風が当たれば波の高さが変わるから、特定の閾値で到達時間を測るのは無理そう。


 前回も少し触れたが、気温が30℃ほど変化すると1位相変化する。例えば25℃と-7℃では1位相変化し、25℃と-35℃では2位相変化する(センサ間150mmの場合)。北海道においては、-35℃というのはほぼないが、-7℃くらいはよくあるし、-21℃あたりも無くはない。位相差のみで音速を計算しようとすると大きな気温の変化に対応できないため、位相差以外で音速の変化を計測できないかと思ったわけだが、波形の立ち上がりを見る限り、結構大変そうだ。
 とりあえず、STMのADCにサーミスタでもつないで外部の温度を測って、その上で細かいところは位相差で計測、という感じになるかな。外部の温度を5℃程度の精度で計測できれば、位相差から音速を測り、音速から気温を求めることで、もう少し細かい気温が把握できるはず。どうせ風速計を作るなら温度センサを内蔵した気圧センサとか付けたほうが良いかも。でもそうすると湿度も測りたくなるという罠。まぁ多機能化はのちのち。

超音波風速計 ぶれっどぼーど


 写真を撮った後に間違いに気づいて修正したところがあるけど、だいたいこんな感じ。入出力ともに4ch分を配線してあるが、ADCは分圧抵抗が2ch分しかついてない。
 PWM出力はパスコンでDC成分を消した上で超音波SPに接続、アナログ入力はパスコンでAC結合して分圧抵抗でレベルを移動した後ADCに直結。PWM側はソフトウェアでDC成分を消せるので、SPと直結も可能。この回路で一番複雑なのは分圧抵抗じゃないかなぁ。

 SPとMICを並べて双方向で時間を計測できるようにしてある。それぞれの組み合わせでセンサの距離が微妙に違うので、その分の差はあるが、2LSB程度の差なので誤差の範囲な感じ。2LSBだと0.08mmくらいの精度。インシュロックでぐいっと引っ張って固定してこんな精度になるのかなぁ。
 もしも、12.5±5usecくらいずれてるなら、それはマイクの位相が逆なので、配線を入れ替えること。

 試しに1回吹いてみたら、時間差は4.3usecくらいだった。およそ3.5m/sに相当。軽く強めに息を吹いたらこれくらいかな、という感じ。


 今のところ、計測しているのは位相差だけで、「Time of Flight」みたいな値は取っていない。でも、双方向を平均して音速を計算してから風速を計算する、ということをやるなら、ToFは必須だと思う。どうやって正確な時間を測れば良いんだろうか。少なくとも10usecの精度で計測する必要がある。
 例えば25℃から15℃変化すると、風速が150mmで10usecほど変化する。つまり、双方向の平均と校正値のズレから風速を計算した場合、位相差を見るだけでは校正した気温±10℃程度の範囲でしか使用できない。北海道だと真夏と真冬でΔtが50℃くらいあるので、通年で使うなら位相差だけでは足りない。
 解決策が無いわけではなく、例えば精度が10℃程度で温度を測れる手段があれば、それで位相の変位量を補正して音速を計算する、とかできるはず。
 もっとも今の段階でそんな話をしてもとらぬ狸のなんとやら、なわけだが。

2017年2月15日水曜日

超音波風速計 マイコンでFIRとETSしてみた


 タイトル通りです。マイコン内でADCから読んだ値をFIRでAC結合し、それを等価時間サンプリングで9Msps相当にしてUARTにダンプ、未加工でグラフ化です(横軸のナノ秒だけExcelで計算してますが)。
 青が無風、赤と緑が息を吹いているときですが、安物の風速計を信用するならこの時の風速はそれぞれ2m/s程度だと思います。
 最初の1フェーズくらいは波形が安定せず、繰り返し信号とならないため等価時間サンプリングが異常値となります(波形の安定以外にも、フィルタの初期値の分もありそう)。ただ波形が安定してしまえば、マイコン内の処理でもかなり綺麗にできてる気がします。
 FIRは整数処理の関数を作って、次数は63です。2000サンプルを通すのに70msecかかっているので、PWM-ADCの5msec程度を大幅に超えています。もっとも、結構綺麗な波形なので、もっと短い期間でも充分な気がします。


 超音波風速計はいままで散々苦労したので、今回ももっと大変だろうなぁと思っていたのに、なんか拍子抜けするくらい簡単にここまで来ています。心配になってくるレベル。あと何日かすれば1次元の簡易風速は出せそう。そこから多軸化するのが大変だろうけど、それにしたって回路の追加はほとんど無いし。気を抜いてやる気を失ったりしないように気をつけて、もうちょっと頑張ろう。

超音波風速計 贅沢にペリフェラルをつかってみた



 TIM1本をディレイに使ってみた。結論から言うと、あんまりよろしくない気がする。ADC変換を行っていないときと、ADC変換を行っているときでは、マイコンに吸われる電流が違い、それが波形を乱している気がする。なので2000サンプルで8組分の等価時間サンプリングが可能だが、少なくとも最初の1組は読み捨てる必要がありそうだ。
 次のテとしては、ADCのDMAをサーキュラモードにして、最初の1周3ミリ秒を読み捨てて、次の3ミリ秒(2週目)を使う、といった感じかな。でも本来読み捨ては1msec程度で充分なので、無駄に2msecかかることになる。ま、それでも1chあたり10msecで8ch測ったとしても0.1秒未満なわけだが。

 あと等価時間サンプリングにこだわる必用はない気がする。うまく位相を計測するアルゴリズムを考える必要があるが。
 PCで処理するならBPF通してDC成分抜いてから位相を90度ずらしてAtan2に突っ込んで直線に変換して、とかいろいろできそうなんだが、浮動小数点演算を使いたくないのでもうちょっと軽いアルゴリズムが必用。こういうところはF4を使いたくなるねぇ。

 位相を検出したりするのはいろんな用途が有るので、方法もいろいろあるのだが、ADCからの生データはDCオフセットがあるのがつらそう。デジタルフィルタを通してAC結合してから位相比較になるのかな。


 現在使ってるハードウェアリソース
・TIM2(PWMのタイミング:80kHz)
・DMA1-2(PWM波形の転送)
・TIM4(ADC開始タイミングのディレイ:1MHz、TIM2のスレーブ)
・TIM3(ADCトリガ:642.85714kHz:TIM4のスレーブ)
・DMA1-1(ADCの転送)

 もーちょっとTIMが柔軟だったら、と思うんだが、できないことはしょうがないから他の方法で工夫しないと。
 でっかいホワイトボード欲しい。ある程度の広さの作業空間とセットで。

2017年2月14日火曜日

超音波風速計 つずき

 

 等価時間サンプリングっぽい方法で約9Mspsでサンプリングした波形。波形の立ち上がりは綺麗な繰り返し信号じゃないので等価時間サンプリングが成立しない。0.125ミリ秒くらい経過するとある程度安定するが、それでものいじー。今回は16x 562.5kspsで9MHzにしたが、14x 642.85714...kspsで9MHzのほうが良かったかも。
 図中のaとbは無風状態で、ほぼ位相ずれが無い。cとdはそれぞれ逆から息を吹いてる。息だと再現性がないのであんまりよろしくない。とはいえ乱れの少ない流れを作るのも結構大変。
 閾値での立ち上がり・立ち下がりを分けて計測すれば最大180度までの位相ずれを計測できる。超音波風速計の動作レンジ内ならここまで位相がズレることは無いっぽいので、それ以上は考える必用はなさそう。

 超音波風速計の場合、位相ずれは風速に影響を受ける。他に、位相が動く速度は風速の変化に関係がある。例えば超音波の連続波を常に送信して、位相のズレを16波毎に計測し続けると、0.4ミリ秒毎の風速の変化量がわかる。1.25マイクロ秒の精度で位相を検出できれば、空気の0.5mmの移動を検出できる。と電卓は言ってるが、計算が正しいかは不明。でも空気の移動速度・加速度をミリメートル単位で把握できたら何かに使えるかも。

 超音波風速計は波で測る手段だから、レーダー技術と結構近い気がする。符号拡散超音波風速計とかどうだろうか。複数チャンネルを完全に同時に計測できるから高レート(2kHz前後?)で風速ベクトルと気温を計測可能、とか。そんなもん何に使えるんだか。


 RAM20kにRTOS乗っけてさらにアナログデータ大量計測はちょっと厳しい感じ。もう1本タイマを使えればPWM発振から一定期間待たせてADCを開始とかできるんだが。
 どうせSTBee Miniなら風速計以外に機能載せられないだろうし、使えるタイマは全部風速計に使ってしまう、というのも有りかもしれない。人間を相手にする程度の、せいぜい数十ミリ秒くらいの精度ならRTOSで作れるし。
 あるいはRAMにもペリフェラルにも余裕のあるSTM32F103VETを使うか。メモリが3.2倍あるからかなり余裕。でもちょっと大げさな気がする。
 そもそもとっととSTM32F4に移行しろよ、という気もするんだが。まぁSTBee Miniでもなんとかなりそうな気がするし、しばらくはこっちで頑張ってみる。