2017年6月30日金曜日

InterpolationMode

 C#のGraphicsで画像を拡大する際の補完モード。









 128x32pxを1024x256pxに拡大した際の、処理時間を計測してみた。計測方法は、DrawImageをforで500回行って、forの前と後にDateTime.Nowで時間を取って、その差を500で割った。
 NearestNeighborは明らかに軽い。Bicubicはケタ違いに遅い。あとは2msec中盤のグループと、3msec後半のグループに分けられる。
 このサンプルでは、HighかHighQualityBicubicが好みかな。ただし遅いグループ。
 用途によって、例えば1ピクセル毎をちゃんと識別したい、という場合はNearestNeighborが最適解。画像を自然に拡大したい場合はHighQualityBicubicあたりかなぁ。Bicubicは処理時間の割にあんまり綺麗じゃない気がする。コレは画像データのタイプにもよるんだろうけども。

2017年6月29日木曜日

2017年6月20日火曜日

4k液晶を買った

 DELLの4k液晶を買ってみました。


 色んな所でレビューされてるので、詳細は割愛。

 とりあえず、スケーリング無しで表示すると、文字がかなり小さいです。そりゃFHD液晶の半分、あるいは4分の1ですから。
 もちろんスケーリングすれば文字は大きくなりますが、画像のスケーリングが綺麗にできないので、どっちもどっちですね。
 この液晶はピボットがついていて、縦置きにするのも比較的簡単(VESAマウント組み換えよりは)ですが、そもそもFHD液晶4枚置きと同じ空間があるので、縦置きにする必要がない感じです。画面3分の2くらいでVS Codeを表示して、2分割でソースとヘッダを表示、残りの領域にPDFを表示して1ページ丸ごと表示したり、Webブラウザでオンラインドキュメントを表示したり、といったことが無理なくできます。このような表示は、以前だとFHD画面にエディタ、サブ画面にドキュメント、と言った感じで表示していました。


 Webブラウジングも、画面半分でFHDの幅とFHDの倍の高さが有るので、1ページでかなりの情報量を表示できます。Googleの検索結果も、スクロールせずに全件を表示できます。
 だいたいのWebサイトは横幅1920pxは必要ないので、4k液晶なら3ページくらいを並べて表示することもできます。ただし、Windowsは左右2分割、上下左右4分割、くらいしかできないので、4kスケーリング無しに最適化されてるとはいえません。

 ピクセル密度は僕が持ってる初代Kindle PWと同程度です。つまり、PC上の電子書籍リーダーでも、Kindle PWと同程度の解像度で読むことができます。ノングレアということもあり、かなり紙に近い質感です。ただし、現行のKindle PCアプリでは、スケーリングすると正常に表示できない感じがします(僕が100%スケールで表示してる理由もこれが50%くらい)。追記1

 物理的な大きさは23.8インチなので、横においてある23インチFHDの液晶と、見た目は同サイズです。しかし、4kは1辺のピクセル数が倍あるので、マウス移動は違和感があります。
 マウス移動速度も、マウス移動量に対して何ピクセル動く、という速度なので、4kとFHDが同じ大きさなら、4kはFHDの半分の距離しか動きません。
 過渡期では4kとFHDが混在するので、マウス速度だったり、画面間の位置は、実空間ベースで実装して欲しいところです。とはいえ、そもそもマルチスクリーンで使う人はそんなに多くないだろうし、明らかにPPIが違う画面を併用する人はさらに少ないから、この機能は期待薄かなぁ。

 液晶自体の欠点はそんなに多くないと思いますが、ピボットで回転させるのがちょっと面倒、入力インターフェースが少なめ、HDMIが4k非対応(追記)、といったところでしょうか。


 買ってしまったので、今更使いづらいとも言えませんが、そういうのを差し引いても、便利になったと思います。
 FHD映像コンテンツを表示しても、画面の4分の3がスッカスカなのはかなり圧巻です。


*** おまけ ***

 

 分解能が高いので、Armaとかで敵を見つけやすくなるかな、と思ったけど、GTX950で4kだとポリゴン最低にしても30fpsくらいしか出ないので、全然ダメでした。どっちにしろプレイヤーキルが足りませんが。GTX1080とか欲しくなりますね。沼。


追記1:2017/06/20
 最近のアプリは起動時にスケーリングとかを読み込んで適切に表示できるようです。Kindleアプリも再起動したら綺麗に表示できました。ただスケーリングの異なる液晶間で移動移動させても、スケーリングは変化しないので、微妙なところ。
 あとスケーリングした上でフォントを小さくすると、VS Codeの表示がクッソ見づらい。スケーリングして通常フォントだと情報量は増えないし。


追記:2017-06-21

 4k縦置きにすると、だいたい270行くらい表示できる。文字サイズを小さくすれば、350行くらいは表示できる。どちらにしても文字はかなり小さいが、解像度はかなり高いので、全体をざっくりと見渡して、気になるところを注視して文字を読み取る、みたいな使い方はできる。適切にインデントされたソースコードなら、おおよその文字列の形でもブロックの大きさとかは見えるから、意外と便利。

 ただ、液晶の縦横を変えるのはOSから制御する必要があるので、ちょっと面倒。解像度を変えるとウインドウのスナップも動いてしまう。
 あとこの液晶で地味に不便なのは、PCをDisplayPortで接続し、AV機器をHDMI接続している場合に、液晶ソースをHDMIにすると、OS側で瞬断?みたいな挙動をする点。やはりこれもウインドウのスナップが外れるので、ちょっとつらい。
 amazonのレビューとか読んでると、ファームウェアアップデートとかできるみたいなので、付属CDのソフトを入れればそこら辺改善できるのかも。
 液晶の標準化が進んで、ドライバとか一切気にせずに、本当にPnPができると、付属ソフトウェアとか入れなくてもある程度は動いてしまうので、便利機能とか結構逃してそう。
 業務用とかで、縦置きなら縦置き!横置きなら横置き!で動かさないで、かつ入力ソースも動かさないみたいな使い方ならかなり便利そう。ただ24インチ縦置きだと首が痛くなるけどね。


追記:2017-06-27
 だいぶ4k液晶の小さな文字にも慣れてきた。
 購入当初の、液晶表面の幾何学的なパターンはほとんど気にならなくなった。やはり一時的なものだったようだ(という予想だったので、欠点とかには書いていなかった)。おそらく梱包材のパターンが長時間接触していたことによって写ってしまったのだろう。
 あと液晶表面の保護パネルは結構柔らかい気がする。触ると簡単に液晶みょんみょんする。
 付属CDにはDisplay Managerが入っていた。モードの設定(色温度?)とか、Easy Arrangeという、ウインドウを自由にスナップする機能があったりする。
 色温度は手動と自動があり、自動はソフトウェアに合わせて色温度が変化する。文章を読むなら色温度を下げるとか、映像関係は色温度を上げるとか、いろいろできる。が、当たり前だがソフトウェアを切り替えるたびに変化し、一瞬画面がブラック・アウトするので、かなり使いづらい。基本的に手動で設定する感じかな。色温度は液晶のOSDでも設定できる。そういえば、液晶のUSBを接続しなくても色温度とか設定できた。DDCみたいなので設定してるのかな?
 Easy Arrangeは、画面を3分割してスナップとか、いろいろ自由にできるのだが、てきとーな位置にウインドウを移動しても勝手にスナップされるようで、かなり使い勝手が悪かった。

 最近になって、PowerDVDのLAN経由でチューナーから再生するのが、かなり快適になった。ちょっと前にDIGAのファームウェアアップデートが来てたので、ネットワーク周りが改善されたのかな? 今まではなんとなくフレームレートが低かった感じがしたが、ちゃんと表示されるようになった。今使ってるのはPowerDVD 16だが、セカンダリ液晶を縦置きにしてても、問題なく動作する。BDドライブにバンドルされていたのはPowerDVD 10だったが、これは1つでも縦置きの液晶が有ると再生ができなかった。

 ということで、4k液晶の隅に録画を再生したりしつつ、残りの領域でエディタを開いたり、コンソールを開いたり、と結構快適な感じ。4k液晶はよいぞ!
 でもLr5はさすがに動作が重い。ゲームはGPUがネックになりやすいけど、その他のソフトウェアはCPUで画面を書いてるので、解像度が高くなるとCPUがネックになる。個人開発のCADとか、あんまり最適化が行われておらず、全領域の書き換えが頻発するようなソフトとかだとちょっと辛い。
 

追記:2017/09/24
 この液晶、4k60pのHDMI入力が可能なようです。
 曰く、電源ケーブル意外をすべて抜いて、入力ソース切り替えでHDMIを選択してチェックマークを6-8秒長押しする、とのこと。僕の液晶では長押しした時にダイアログが出ますが、このダイアログがかなり分かりづらかったです。HDMIを選ぶと、最大の入力サイズが表示できるので、それで4k60pになるまで何回か切り替えてみると良いと思います。
 HDMIの4k60pは諦めてたけど、これで動くようになった!やったね!Xbox One Xが活躍できるよ!!

2017年6月18日日曜日

気分転換に、


 気分転換に、STBee Miniである種のトリガモジュールを作っています。
 ほとんどのソースは以前に作ったFreeRTOSポーティング済みのStdPeriphLibなF1向けプロジェクトをコピーしているので、最低限の動作はすでに作り込んであります。それでも、タイマ回りの初期化とかかなり面倒だなぁと思ってしまいました。なんだかんだいっても、やっぱりHALは便利です。前にStdPeriphLibを使ったのって2ヶ月位前なんだけどなぁ。

 とりあえず、カメラのレリーズとして使いたいのですが、モノとしてはフォトカプラで簡単に絶縁したパルス発生器みたいな感じなので、カメラ以外にもいろいろ使えると思います。タイミングソースは12MHzの水晶、時間はタイマ2本を直列にし、最大1/72M*2^64秒(8000年)周期くらいでパルスを作れます。完全に過剰スペックですが、精度を求めると1/72M*2^32秒(59秒)しかありません。このあたりはある程度自由に設定できるので、用途に合わせて何パターンか周期を設定できるようにしようと思っています。1時間毎に1パルスとか、1日毎に1パルスとか、自由に作れます。定点観測とかにも使えますね。
 パルス数は、とりあえず最大2^16-1パルスくらいまでになると思います。例えば5秒毎にシャッターを切る場合、2^16枚だと3日以上ですから、僕の用途としては充分だと思います。2^16以上必用なら、パルス数のカウントをとめて、電源が入ってる間はずっと回してもいいですし。

 自由にプログラムを書けますし、I2CやSPIやUARTやADCといったインターフェースが有るので、プログラマブルなトリガソースとして使うこともできます。とはいえ、STBee Miniのメモリ量だと、かなりカツカツな感じです。
 本当はSTBee F4miniで作りたかったんですが、前回買った2個は届く前に使いみちが決まってしまったので、現状、自由に使えるF4miniボードがありません。F4miniだとCubeで初期化できたりとか、楽なんですけどね。近いうちにF4miniを買い足しておかねば。


 ペンタのデジイチはレリーズに2.5mmのステレオプラグを使っていますが、オーディオ用の2.5mm-3.5mmステレオ変換プラグを使えば3.5mmのステレオプラグとして使えます。3.5mmのステレオプラグなら電子工作的にも簡単に扱えますし、フォトカプラで簡単にシャッターを制御できるようになるので、いろいろと遊べそうです。
 マニュアルやらAvやらTvやらなら、てきとーにパルスを入れれば撮影できますし、バルブモードならシャッタースピードを自由に制御できます。本当はUARTやCANでISO感度・F値・シャッタースピード等を自由に制御できるカメラがあれば理想なんですけどね。PK-Tetherとかあるので、技術があればF4miniでUSB Hostを作って制御とかもできるのかもしれませんが。

2017年6月16日金曜日

小ネタ:超音波風速計向けのADC


 STM32F4を使った超音波風速計のために、矩形波出力やADCのタイミングを合せたりしていました。たぶん6ch(3軸双方向)の生データは取れるようになったはずです。相変わらず1つのチャンネルはゲインが低いですが。このまえ秋月で買い物した時に超音波TRも買っとけばよかったな。。

 上のグラフは40kHzのパルスを出した時のADC波形です。縦軸は電圧、横軸は時間(マイクロ秒)です。サンプリングレートは1.5Mspsで、2000サンプルなので1.33...msecの期間です。矩形波は時間0から20パルス出しており、0.5msecの期間です。
 おおよそ気温と風速が安定した状態で、6回ほど試してみましたが、位相はかなり一致していました。

 開始時点で1.65Vくらいで、0.2msecあたりで1.58Vあたりまで落ち込んでいるのは、分圧抵抗のインピーダンスに対して、入力インピーダンスが低いためだと思われます。分圧抵抗が47k2個なので、マイコンの吸い込みは490k(1.575V時)くらいでしょうか。

 0usecから450usecあたりまで、下側にノイズが出てます。また、500usecあたりにも上側にノイズが出てます。80kHzや40kHzなら矩形波がそのままアナログラインに入ってるとわかりますが、20kHzってどういうことでしょうか。

 ノイズはだいたい20kHzなので、AD変換のタイミングは正しそうです。しかし、超音波の波形は微妙に40kHzとずれているのが気になります。おそらくADCの変換タイミングのジッターではないと思うんですが。AC結合のキャパシタや分圧抵抗で発振回路みたいになって位相ズレが起きてるのかもしれません。だとしたらマズイ。


 AD変換は12bitですが、レジスタ的には16bitなので、2000サンプルだと4KiBになります。前回の超音波風速計はSTM32F103CBTで、RAMは20KiBしかありませんでした。一方、今回はSTM32F405RGTで、RAMは192KiBあります。ねむいさんの教えに従い、64KiBはスタックに当てていますが、それでも128KiBあります。約6倍ですね。かなり余裕あります。
 FreeRTOSのスタックってどこから取られてるのかな。ヒープ領域っぽいけど、そうすると64KiBのスタックはがら空きですね。まぁ使わないよりは多少なりとも使われてる方が無駄が少なくて良いのだろうけども。


 なんか位相ズレがヤバそうな感じがして、超音波風速計としての精度がとても怪しいところですが、どうなることやら。


 相変わらずアナログ回路は最小を目指していて、今回はマイコンボードが大きくなっていながら、ユニバーサル基板はC型で収まってます(前回はB型 / 今回は液晶とか温度センサとか載せる余裕は無いですけども)。
 送信機と受信機のAC結合に1632のチプコンが1個ずつ、受信機の電圧レベルの調整に同サイズのチップ抵抗が2個、ということで、1chあたり受動素子は1632サイズが4個、能動素子が0個、という超お手軽回路です。
 受信素子は片側をGNDに落とし、もう片側をAC結合してからマイコンに接続、マイコン側に分圧抵抗を入れてますが、片側に分圧抵抗、もう片側はマイコンに直結、という構成のほうがよかったかも。これなら受信側にCL負荷が増えることもないし。
 ということで次作る時はそういう回路にしてみようかな。今の基板を改修するのはかなり大変。でもコネクタの手持ちが少ないので、あんまり無闇矢鱈と試せないのよね。ま、モノタロウで売ってるのは確認済みなので、イザとなれば買い足せるのでマシですが。

 受動素子限定縛りはなんとかしたいなぁ。とはいえ基板を発注するようなモノでもないしなぁ。ムラタあたりの素子が入手できるようになれば、アナログ回路ちゃんと作り込んで、1素子で送受信して小型化、とかいろいろできるんだけども。

DSP_Libを使う

 Cubeでは ./Drivers/CMSIS/DSP_Lib/Source/hoge フォルダの中に各種演算命令が入っている。FIRを使いたかったので、試してみた。

 とりあえず、makefileに必用な関数のソースを追加し、arm_math.hを変更すれば使用できた。

 今回使ったのは arm_fir_f32.c にある arm_fir_f32 という単精度浮動小数点を使った有限インパルス応答のフィルタ。この arm_fir_f32.c をmakefileに追加し、処理を行いたいコードで arm_math.h をインクルードしておく。そうすれば演算関数を使うことができる。
 ただし、僕の環境ではエラーが出てコンパイルすることができなかった。必用な定義が足りないためなので、その定義が含まれているヘッダを arm_math.h に追加する必要がある。
 arm_math.h 先頭の _ARM_MATH_H 直下に、以下のインクルード文を追加した。

#ifdef STM32F405xx
#include "stm32f405xx.h"
#endif

 今回はSTM32F405RGT6で動いているので、stm32f405xx.h をインクルードしている。
 定義自体は数個なので、自分でdefineを書いても良いのだが、とりあえず今回はヘッダをインクルードした。


 FIRに擬似乱数とLPFのフィルタを与えて、結果をPC側でFFTに通すと、LPFっぽい感じになってるし、ちゃんと動いてるんじゃないかなぁ。
 タップ数31、データ数8192でだいたい9msecだった。ただしコアが120MHzで動いてるので、通常の速度なら6.5msecくらいかな?

 DPS_Libには各種の関数があるが、単精度浮動小数点・32bit固定小数点・16bit固定小数点のバリエーションが有る。32bit・15bitのfixedはそれぞれq31・q15と書いてあるので、符号1bit・整数0bit・小数31bit みたいなフォーマットなんじゃなかろうか(未確認)。

 いろいろとクセがありそうなのと、いまいち何をやってる関数なのかわかりにくいので、使うのはちょっと大変かも。とはいえ、中身はただのC言語ソースなので、ARM以外のプラットフォームでも動きそう。とりあえずPC上で動きを確認してみるのもアリかも。

2017年6月15日木曜日

CMSIS-RTOSが面倒くさい

 Cubeで出力されるFreeRTOSはCMSIS-RTOSのラッパーが含まれているし、Cubeでタスクやキューの設定をすると、CMSIS-RTOSに準拠した?コードが出力される。ということでCMSIS-RTOSってどうやって使うんぞ?とちょっとドキュメントのサンプルソースを見てみた。
 とりあえずQueueを使ってみたかった。

 Message Queue

 かなり面倒くさいようだ。
 つま先でつついた程度で泥沼っぽいぞ、という気がしてきたので、とりあえず今回は違う道を通ることにした。

***

 ざっくりと流れを予想してみると、初期化時にQueue以外に、mallocで使うスペースも準備する。
 Queueに渡す(Putする)時は、予め用意したスペースからosPoolAllocでメモリ割り当てを受ける。そのメモリに情報を入れて、osMessagePutで割り当てられたポインタをQueueに入れる。
 Queueから受け取る(Getする)時は、osMessageGetでQueueから受け取り、必要な情報を取り出す。操作が終われば、osPoolFreeでメモリ割り当てを開放する。

 Queueの準備や、メモリ割り当ての準備は、マクロでいろいろ操作する必要があるので、いちいち書くのは結構面倒。
 Cubeではメモリ割り当ての初期化を行うことができないので、CMSIS-RTOS風の書き方をするなら、自分で初期化を追加する必要がある。またメモリ割り当ては固定長だが、CubeでQueueを大きくした場合は、ソースコードのメモリ割り当て初期化も修正する必要がある。誘蛾灯の雰囲気がプンプンするゾ。

 で、どうしてこういう面倒なことになっているのか。

 FreeRTOSのQueue回りは、ポインタを受け取って、構造体分全体をQueueに割り当てられたメモリにコピーするという処理が有る。おおよそmemcpyのような処理が行われるはずだが、構造体が大きくなればmemcpyに要する時間も長くなるので、処理時間の予測ができない。一方、ポインタだけをQueueに入れる場合、せいぜい4バイトか8バイトの転送で済むので、OSでの処理時間はある程度予想ができる。
 ただし、ただmallocを使う場合は、メモリのフラグメンテーションが問題になる可能性がある。実行時間に制限の付けにくいRTOSでは、フラグメンテーションの可能性は可能な限り避けたいところ。
 ということで、osPoolが出て来る。osPoolは固定長のメモリを小数割り当てるための機能であり、フラグメンテーションは発生しない。また、割当の組み合わせ数はかなり少ないので、空きメモリの検索も高速で行われることが期待できる。


 ということで、CMSIS-RTOSは個人レベルでプログラムを書く場合はかなり面倒だが、安定性を重視して作られている感じがする。

 とはいえ、例えばUARTのような、1回の処理で1バイトしか転送されないと行った場合は、FreeRTOSのような直接転送する方が早そうな気がする。このあたりはCMSIS-RTOSでもちゃんと用意されてるんだろうけども。

 あくまで業務用でも使えるRTOSなので、自分で楽しむレベルの電子工作では過剰かな、という気がする。なので、僕はしばらくFreeRTOSらいくな使い方を続けると思う。いざCMSIS-RTOSが必要になった時に、相当苦労しそうだけど、まぁそれはその時に考えるということで。

2017年6月14日水曜日

Altis Tidesystem

 Arma3でAltis TidesystemというModを試してみた。
 Tideは潮の意味。潮位を変更するMod。

 Steam ワークショップ :: Altis Tidesystem
 





 Arma3のアルティスやストラティスでは水路侵入できるような水路がないので、Tidesysで潮位を上げると、谷間に水が入り込んできて、ボートで侵入するにはいい感じのマップになる。
 SEALsやSWCCも好きな僕としては、かなり面白いMod。
 水路侵入する際の注意点としては、木や陸地が障害物として存在するので、進行方向の水中をよく見て進む必要がある。
 また、インベントリに入れられる地図は海面上昇(or低下)前に作成された地図なので、Tidesysで潮位を動かした場合は海岸線が正しくない。ま、これはこれで気候変動後にやってきた調査隊、みたいな感じで面白いのだけど。
 島に残るゲリラの対応をしつつ、民間人を救出していく、みたいなミッションを作っても面白いかもしれない。


 Tidesysを使う際の注意点として、潮位をエディタ(orミッションファイル)で変更することができない。
 潮位はMod自体にべた書きされているので、潮位を動かしたいならModの設定を変える必要がある。
 設定ファイルは C:\Program Files (x86)\Steam\steamapps\common\Arma 3\!Workshop\@Altis Tidesystem\addons\altis_tide.pbo になるが、これはテキストファイルの前後にバイナリのヘッダ・フッタを追加した構造になっているので、テキストエディタで書き換えることができない。書き換える際はバイナリエディタを使うこと。
 それと、テキストエリアの大きさはヘッダかフッタで固定されているようなので、オリジナルの文字数と、変更後の文字数が一致するように工夫する必要があるらしい。とりあえずコメントの文字を削ったり追加したりで一致させればいい。


 みんなもAltis Tidesystemで快適な水路潜入を! いや、Apex買えっていいたいのはわかります。。。やっぱタノア買うべきだよなぁ。

2017年6月13日火曜日

STBee F4miniヤバそうなピンまとめ


PA0 PD10k USR-SW ActH
PA11 FL USB D-  
PA12 FL USB D+  
PA13 PU10k JTMS/SWDIO  
PA14 PU10k JTCK/SWCLK  
PA15 PU10k JTDI  
PB2 OD4.7k BOOT1  
PB3 PU10k JTDO  
PB4 PU10k NJTRST  
PC14   水晶32k IN ピンヘッダ無し
PC15   水晶32k OUT ピンヘッダ無し
PD2 USR-LED ActH

 やばそうな、というか、ボード上でピンアサインが固定されてるピンまとめ。だいたいSTBeeと似た感じかな(未確認)。

 とりあえず、PA0は使わない方向で、PA11-12は可能な限り避け、PA13-15もできたら避ける。PB2も可能な限り避け、PB3-4もできたら避ける。PC14-15とPD2はピンヘッダへの接続はないので、そもそも使えないという点に注意すれば問題なし、という感じか。

 PA0はアナログ入力だが、システムスリープ時にシステムを起動するための機能が接続されている。その関係でスイッチもここに接続されており、アナログ入力ピンとしては使わないほうが良い。入力インピーダンス10kΩで問題ないような使い方なら御事由にという感じだけど、スイッチを押すと地絡するので、あまり出力インピーダンスの低い回路を接続するのも問題。まぁ、使わないほうが無難。

 PA11-12はUSB回りなので、少なくともUSB DFUを使う場合は、PA11-12は使うべきではない。JTAGなり、USB以外のDFUなりで書き込む場合は自由に使ってもかまわないだろうが、USBコネクタから給電する場合は、PCを誤動作に巻き込むおそれがある。PA11-12をUSB以外の用途で使いたいなら、USBコネクタを殺す等の処理をするほうが無難。

 PA13-15とPB3-4はJTAGで使われており、10kでプルアップされている。JTAGを使わず、かつプルアップされていても問題ないなら、使ってもよろしい。

 PB2はユーザーFlashからプログラムを起動する限りでは、ピンを評価されることはないが、STBee F4miniはUSB DFU接続時にシステムFlashを起動するので、その際に外部の回路がPB2をHに引っ張ると正常に起動できない。ということで、PB2は可能な限り開放で使い、どうしても接続が必要な場合は、マイコンリセット時は確実にLに引っ張られるような使い方をする。

 PC14-15はピンヘッダへ接続されていないので、そもそも使うことができないという点に注意。あと水晶が直結されてるので、PC14をH、PC15をLみたいな、水晶に直流電圧がかかるような状態で放置するのはよくないはず。ということでPC14-15は使わないほうが無難。

 PD2はLEDが接続されているので、ちょっとした動作確認にチカチカさせたり、ROMのアクセスランプみたいに使ったり、いろいろ自由に使える。ただボード上にはパッドすらも無いので、ロジアナとかオシロでパルス幅を見るようなデバッガをするのは大変。ただ小さなビアが有るので、ジャンパワイヤを載せたりとかは比較的楽(パッドと違って滑りにくい)。

STM32F4のADC(DMAと連続変換)


 1kHzの正弦波をADCに通してみた、の図。
 横軸の単位はミリ秒、縦軸の単位は電圧Vで、3000サンプル取っている。サンプリングレートは2Mspsのようだ。
 今回はADC1のみで変換している。デュアルADCをやりたいんだけど、うまく動いてくれないので、とりあえずシングルADCでどこまで取れるかを試した次第。
 入力自体は単純な正弦波だが、サンプリング開始直後の波形は結構乱れている。おそらくCR LPFの特性やDACの出力インピーダンス、それからADC変換を行っていない時と変換を行っている時の入力インピーダンスの違い、といった点の関係だと思う。コレ自体はF1超音波風速計の時にインピーダンスの差から波形が乱れる事はわかっていたので、ある程度は想定内。風速計の場合、波形の高さは問題ではなく、位相が正しければ充分なので、インピーダンス変換等は必要ないはず。
 システムクロックは12MHzの水晶を12分、240倍、2分で120MHzにし、PCLK2はさらに2分周して60MHzが供給されている。ADCはさらに2分周した30MHzが供給されている。解像度は12bitで、1回の変換が15クロックなので、30MHz/15=2Mspsということになる。
 ADCの変換は3サイクルのサンプリング+15サイクルの変換で計18サイクルが必用なのかな、と思っていたけど、そういうことではないようだ。

 超音波風速計は位相が取れれば充分なので、ビット数を減らしてサンプリングレートを上げることもできるかもしれない。とはいえただでさえ弱い圧電素子の出力を、さらに分解能を下げてしまうと、正常に位相を計測できないかもしれない。このあたりは実際に試してみないとわからないな。
 本当は外に10倍か100倍くらいのオペアンプを1段付けておけば楽なんだが、手持ちに40kHzが通るオペアンプがないので、とりあえず直結で。


 超音波風速計ではどれくらいのサンプリングレートが必用か。
 風速で0.05m/s、気温で0.1degCの分解能を得ようとすると、位相差を60ナノ秒くらいの分解能で測る必要があるらしい。20Mspsくらい必用ってことか。シングルADCだと2Mspsまでなので、何らかのフィルタリングで時間分解能を稼ぐか、等価時間サンプリングで時間分解能を稼ぐか。
 僕が使ってるオシロスコープは100Mspsだが、まぁ大体これくらいの性能があれば充分、って感じか。DSO Touchで10Msps、市販のポータブルオシロスコープで40Mspsくらい、らしい。DSO Touchだとちょっと分解能足りないなー、くらいかな。
 やっぱりアナログ回りはしっかり作る必要ありそうだなぁ。メンドクサイ回路は嫌だなぁ。耐ノイズ性とか考えると受信素子の直近にオペアンプを1個入れるのが良いんだろうけど、そうすると相当面倒なことになりそうだなぁ。


追記:2017/06/13
 現行のバージョン(2017年4月版)のHALではデュアル(orトリプル)ADCは使えないようだ。D/T ADCではデータの読み込みはADC1->DRではなく、ADC123_COMMON->CDRを使う必要があるらしい。しかしHALではCDRを使う関数(orマクロ)は存在しない。
 LLではCDRのアドレスを探す関数が有ったりするので、D/T ADCがどうしても必用ならそっちを使う必要がある。
 HALはこういうところが作り込まれてない。真面目に作れよ、とも思うが、デュアルや、特にトリプルADCだと対応するマイコンが少ないはずなので、抽象化という意味ではあんまりやらないほうが良いのかも。

2017年6月12日月曜日

STM32F4のADC

 いつものようにCubeでADCの初期化を行う。
 ADC変換を行いたいところでADC_Startを呼び、ADC_PollForConversionで変換終了までループさせる。PoolForConvの戻り値で変換できたかどうかがわかるので、HAL_OKならGetValueでデータを受け取る。
 VREF+が3.3Vの場合、value * 3.3f / 4096で電圧になるはずだが、ウチの環境ではprintfの浮動小数点が正常に動作しないので、未確認。スタックサイズをいじっても変わらないし、いよいよコンパイラなりライブラリの異常を疑いたい感じ。あとでコンパイラのバージョンを変えて試してみたい。

 他のペリフェラルと違い、ADC_Startで開始した後に、ADC_Stopで停止する必用はない。消費電力を可能な限り下げたい場合は、ADC_StopでADCペリフェラル自体を停止することが可能。ただしADC停止中にADC_Startを呼ぶとウェークアップ時間のループが有るので、タイミングクリティカルな部分ではStopしないように。そもそもタイミングクリティカルな部分では外部トリガ使えという話だが。


HAL_ADC_Start(&hadc1);
HAL_StatusTypeDef status = HAL_ADC_PollForConversion(&hadc1, 10);

if (status == HAL_OK)
{
    uint32_t value = HAL_ADC_GetValue(&hadc1);
    uint32_t tmp = value * 3300 / 4096;

    printf("%4d %4d\n", (int)value, (int)tmp);
}
else
{
    printf("ERROR:%d\n", (int)status);
}

***

 次はTIMで定期的に変換と、DMA転送かなー。それができるようになればADCである程度高速な波形(数kHz)のサンプリングができる。
 超音波風速計のリベンジ。さすがにF103CBではRAMがもうちょっと欲しい感じだし、FIRとか通すなら浮動小数点演算ができるF4のほうが良いはず。あとF4のほうが時間分解能が高い。
 おそらくF4のDACで正弦波を出して、ということはやらなくて良いはず。矩形波でもある程度ちゃんと動くのはF1で確認済み。もっとも、全く悪影響が出ていないとは言い切れない感じなのだけど。

***

 Windows10のWindows Subsystem for Linux(WSL)が開発者モードでなくても使えるようになる、らしい。STM32の開発環境をWinに構築するのは、おそらくWSLを使うのが一番楽だと思うので、これは良いな。WSLならaptでARM GCCを入れられるし、Unixライクコマンドも当然のように使えるし、仮想マシンと違ってWin10で管理するファイルもLinuxから使用できる。
 クリーンなWin10でSTBee F4miniのLチカやUART通信ができるようになるくらいの薄い本があればSTM32ユーザーが増えるかな? どうだろうか。やる気がある人は勝手にやるだろうし、やる気がない人はそもそも電子工作をやらないだろうし、嫌々やってる人はArduinoやmbedやRasPiを使うだろうし。STM32じゃなきゃダメ!といったウリはあんまり無いからねぇ。
 Arduino比ではかなり高速、mbed比ではGPIOが多い、RasPi比では気軽に電源ブッチできる、あたりかな。あとArduinoやmbedやRasPiに比べて安価、といったところか。ただし手間がかかる。ArduinoやmbedやRasPiは手間をお金で解決する感じのスタイル。
 F4miniでNETMFが動けばArduino・mbedキラーになりそうな感じだけど、NETMFはやる気ないみたいだし。Win10IoTはさすがにワンチップで走る規模ではないだろうし、細かいところにチップ1個入れてネットに流すという用途なら、NETMFをしっかり育てていったほうが良いと思うんだけど。

STM32F4のDAC(TIMとDMA)

 前回はリアルタイムにソフトウェアでDACのデータを生成していたが、予め生成したデータをDMAで渡すようにしてみた。
 Cubeでの変更点は、DACのトリガ入力にTIMのイベントを指定したことと、DACのDMAを有効化したこと、それから、TIMの初期化を行った事。今回はTIM7を使用した。
 DMAは16bit(HALFWORD)のサーキュラを指定した。デュアルDACの場合は32bitバスが必要になるが、HALではそもそもデュアルDACという使い方は想定していないらしい? デュアルDACが必用なら、それぞれにDMAを用意するか、あるいはLLで初期化するか。どっちも未確認だけども。

 とりあえず、Cubeで初期化コードを作ってしまえば、あとはデータを作って、ペリフェラルを起動するだけ。
 今回はTIMのカウンタを20に設定し、クロックが86MHzなので、DACは4Mspsで出力される。データ長は4000なので、ちょうど1kHzの正弦波が出力される。

 今回のデータは12bit分フルには使っていない。どうもVSS付近とVDD付近は波形が歪んでいる気がする。出力バッファをDISにすれば改善するので、内蔵されたオペアンプの問題だと思う。おそらくレールツーレールオペアンプが入っているはずだが、理想的なオペアンプではないということだろう。
 チップのデータシートによると、buffer ONの場合は最小出力が0.2V、最大出力がVDDA-0.2Vの範囲となる。一方、buffer OFFの場合は最小出力が0.5mV、最大出力がVref+ -1LSBの範囲となる。3.3Vの場合はbuffer ONで0.2Vから3.1Vまでの2.9Vの範囲となる。buffer OFFの場合はほぼ制限なしに使うことができる。
 ただし、buffer ONでは出力インピーダンスがmin5kΩに対し、buffer OFFでは出力インピーダンスがmax15kΩとなる。どちらを使うかはアナログ波を入れる相手に応じて選択するように。

 以下、データ生成とペリフェラル起動のソース。

int i;
static uint16_t pData[4000];
uint32_t Length = sizeof(pData) / sizeof(pData[0]);

for (i = 0; i < Length; i++)
{
    uint32_t tmp32 = (uint32_t)(2048 + 1800 * sinf((float)i / Length * 2 * (float)M_PI));
    pData[i] = tmp32;
}

HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *)pData, Length, DAC_ALIGN_12B_R);

HAL_TIM_Base_Start(&htim7);

 これ以外はGUIで作るだけで良い。楽っちゃ楽かな。Cubeだといちいちパラメータの名前とか探さなくていいし。Cubeのどのパラメータがマイコンではどのパラメータになるかというのがわからないと余計ややこしいけど。


 ある程度高速な正弦波元ができたので、次はADCをやりたい。でもその前にUARTの初期化を追加してデータを吐けるようにしておかないと。いっそもう一個のDACでADCの値を吐き出して…。。。
 高速なアナログ波形を読み込んで、リアルタイムに波形をいじって、という処理をやってるシステムだと、DACで途中の波形を吐いてオシロで確認、みたいな方法が使われてるらしいですね。UARTデバッグだと速度が全然足りないし、高速でデータを読み出すインターフェースを追加するのは高コストだし、ということで、マイコン内臓のDACを使うんだそうな。数十サンプルとか数百サンプルをまとめて処理するとなるとその途中の波形が出せなそうだけど、入力サンプリングレートの数十分の1とか数百分の1程度の間隔で問題ないなら良さそう。

2017年6月11日日曜日

STM32F4のDAC

 DACを使ってみたかったのでとりあえずソフトウェアで出力。
 基本的に初期化はCubeで作成する。ソフトで出力するだけならGPIOでDAC出力を設定するだけで、ペリフェラルの細かい設定は不要だった。FreeRTOSで1msec毎に値を設定し、10Hzの正弦波を出力している。

float span = 100; // 1000msec / freq

HAL_DAC_Start(&hdac, DAC_CHANNEL_1);

/* Infinite loop */
for (;;)
{
    uint32_t tmp32 = (uint32_t)(2048 + 2047 * sinf(fmodf(HAL_GetTick() / span, 1) * (float)M_PI * 2));
    HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, tmp32);

    osDelay(1);
}

 DACも色々と機能があり、外部トリガやDMAトリガ等がある。
 例えばバッファに正弦波1周期分のデータを入れておき、DMAのサーキュラ転送を設定し、TIMで生成したタイミングで出力する、といったことができるらしい。

 数十kHz程度までのデジタル変調とかができるはず。もっともあまり周波数を高くできないので、現代の高速デジタル変調のような速度には遠く及ばない。それでも10kbaudくらいは出るだろうけども。
 とりあえず数kHzの正弦波を出したい。んでADCを試してみたい。

2017年6月7日水曜日

QZS-2


 JS Orbit

 ほぼ8の時っぽくなってきました。
 QZS-2は10軌道分の予測を表示しています。まだ完全な準天頂軌道ではないので、東西方向の移動が見られます。現在は西に向かって動いており、18周くらいするとQZS-1と似たような経度になりそうです。東西の位置が決まれば、そこから高さを調整したりして、いよいよ準天頂軌道に入ることになります。準天頂軌道に入ってからも、正しいデータを送信できるか等を一通りチェックした上で、いよいよ準天頂衛星として使用できるようになります。
 1日およそ1周ですから、18周には18日かかります。まだしばらくかかりそうですね。うまく軌道を動かしてあっという間に移動してしまうのか、移動中にゆっくりと搭載機器のチェックも行うのか、あるいは軌道情報が不正という可能性もあります。

 QZS-1はQZSS/PRN 183という登録がありますが、別のファイルではMICHIBIKI 1としても登録されています。QZS-2の場合はまだ測位情報の送信を行っていないため、愛称のみしか登録されていません。


 とりあえず、JS Orbitのデフォルトで表示する衛星にQZS-2を加えておきました。現在のところ、ISS, QZS-1, HIMAWARI-9, QZS-2がデフォルトとして表示されます。
 準天頂軌道は軌道としても面白いので、デフォルトの表示に追加していましたが、今後もコンスタントに上がっていくとかなり密集しそうなので、もしかしたら準天頂軌道1機、静止軌道1機くらいにするかもしれません。でも静止軌道はすでにひまわりを表示してるので、これを残すか、これと入れ替えになるか、まぁ打ち上がってから考えます。

2017年6月6日火曜日

QZS-2他


 JS Orbit

 とりあえずQZS-2の名前が確定しました。Arian 5も、R/BとSYLDAは確定していますが、衛星2機はまだ確定していません。それと、DRAGON補給機とFalcon 9 DEBも出ていました。Falcon 9 DEBが2個ありますが、2個ともFALCON 9 DEBとしか書かれていません。
 名前が出たからと言ってそれで確定というわけではなく、例えばキューブサットなんかはコロコロ名前が変わったりしてます。とはいえ商業衛星クラスだとそう頻繁に変わったりすることはないでしょう。

 QZS-2は軌道傾斜角の変更はほぼ終了しており、今は軌道を持ち上げている段階です。
 QZS-1は近地点が地心から45000kmほど、遠地点が同39000kmほどです。QZS-2は近地点42000kmほど、遠地点16000kmほどです。とはいえ軌道情報が3日ほど前ですから、現在ではかなり動いているかもしれません。

 Arian 5のデブリ2個と衛星2個は、1日ほど前の軌道情報でほぼ同じ場所です。近地点が地表から260km、遠地点が同36000kmの、典型的な静止トランスファ軌道です。

2017年6月5日月曜日

Microsoft Visual Studio Express 2015 for Windows Desktop - JPNが欲しい

 Visual StudioはCommunity推しでExpressを入手するのが大変。
 素直にExpress欲しいですっ、って面倒なリンクを辿っても、手に入るのはENU(ENgrish-Usa)版で、日本語表示されない。VS Language Packを入れようにも、Expressは言語パックを始めとした追加を入れることができない。

 日本語版を入手するには、VS downloadページの下にある「以前のバージョン」から「今すぐ無料で参加する」でサブスクリプションに参加し、FeaturedのVisual Studio CommunityのDownloadリンクをクリックし、Download ResultsのVisual Studio Community 2017はガン無視して、その上の検索窓に「Visual Studio Express 2015 for Windows Desktop」と入力して、Detailsのドロップダウンに左からOSのビット、言語、ファイルタイプを設定する。言語はEnglishがデフォルトだが、Japaneseを選択する。2015のISOは提供されていないので、EXE(オンラインインストーラ)を選択する。あとは右側にある緑の下矢印アイコンをクリックすれば、ja_visual_studio_express_2015_for_windows_desktop_x86_x64_web_installer_version.exeがダウンロードされる(x64の場合)。

 素直にCommunity入れろよ、ってのがひしひしと伝わってくる。

 オープンソースにする気も無いし、遊びで作ってるけど、あわよくばガッツリ儲けたいな~って願望が有るので、Communityはちょっと、って感じ。
 でも、完全に個人で使うならCommunityで商業利用しても問題ないみたいね。グループでも5人未満かつ年間収益1億円未満ならCommunityで良いらしい。さすがに1億も売り上げる未来は見えないから、Communityで問題ないのかも。

 環境にもよるだろうが、僕のPCではENUが入った状態で日本語版をインストールすると、VSを起動した時に落ちて、全く起動することができなかった。ENUだけをアンインストールしたり、日本語版を修復しても変わらず、一端Visual Studio Express 2015をすべてアンインストールした上で、再び日本語版をインストールすると正常に起動できた。
 アンインストール・インストールの作業を経ても、プロジェクトファイル等もすべて維持されるが、きになる人は予めバックアップをとっておきましょう。
 最初にバックアップを取ろうと思ったら60GBくらい有って予想12時間とか表示されちゃった。オカシイナー。プログラム内でキャッシュにちっちゃいファイルを大量に生成してたやつが有って、そいつは容量の割にファイルシステムの書き換えが多いので、スループットが非常に悪い。こういうチマチマしたキャッシュファイルは避けるべしという教訓。でも楽なのでついついやっちゃうよねー。

/***

 結局、当初の「Windows コマンドプロセッサ は動作を停止しました」という不具合を解決しようという目論見は、達成することができなかった。
 コマンドプロセッサってcmd.exeらしいんだけど、sfc /scannowを実行しても何も問題ないらしくて、よくわかんない。だれか~Win10x64CreativeUpdのcmd.exeのハッシュ送ってくりゃれ~。

 今使ってるマシンは13年8月に組んだモノで、その後Win10が配布された時にクリーンインストールして以降、ずっと使ってる。Win10のときが2年前なので、そろそろクリーンインストールしたいな、という頃。でもHDD変えるとライセンス認証が面倒とか噂を聞くので、ちょっと躊躇。あとデータバックアップがひじょーに面倒。最低限ドキュメント・ミュージック・ピクチャ・ビデオあたりをHDDにコピーしておけば、なんとかなるかな?
 基本的にOSのクリーンインストールは動作の軽量化以外に、HDDの更新(寿命をリセット)という狙いが有るので、古いHDDは消さずに保存してる。なので必用なデータが有ればそっちのHDDで起動して持ってくればいい。一番手っ取り早いのは新しいPCを組んでネットワーク経由でコピーすりゃいいんだろうけどねぇ。
 落雷とか、瞬断とか、いろいろハードウェアにもストレスかかってるし、CPUリプレイスと不良品騒動で何回もCPUやCPUクーラーを交換して、MBにも相当に物理的ストレスを加えてるし、いっそ新しいMBやCPU、RAM、HDDを買ってきて、古いMB、CPU、RAM、HDDをバラックで組んで、という手もなくはない。でもそうすると残るのがケース、グラボ、光学ドライブ、くらいしか無いのでなぁ。
 そこまでやるなら多少データ不足で不便しても、HDDだけ買ってきて、ついでに4K液晶を買いたい。

*/

2017年6月3日土曜日

久しぶりの

 久しぶりの衛星ネタです。


 JS Orbit

 ご存知の通り、数日前にH-IIAロケットの打ち上げがあり、無事にQZS衛星が打ち上げられたようです。
 新しいTLEがいくつか登録されていますが、2017-28系が2個、2017-29系が4個、登録されています。おそらく28がH-IIAで、29がアリアンだと思います。28は衛星本体とH-IIAのロケットボディで2個、29は2個同時打ち上げの衛星2個とロケットボディ、衛星を接続するフレーム(sylda)で計4個、という感じだと思います。

 準天頂軌道も静止軌道も離心率の違いが有る程度で、それ以外はほとんど同じ軌道です。しかし、アリアンは北緯5度からの打ち上げ、H-IIAは北緯30度からの打ち上げ、ということで、初期の軌道傾斜角が大幅に違います。
 29系はまだ軌道傾斜角が5度前後ですが、28系はA(衛星)が40度あたり、B(ロケット)が30度あたりで、ロケットは射点の緯度を表していますが、衛星はすでにかなり離れた位置に居ます。軌道傾斜角は準天頂軌道のそれに近づいてきており、もうすぐ一致するようになるはずです。その後は軌道を大きくして、いよいよ準天頂軌道に入るという感じになると思います。QZS衛星は軌道の変更が行われてることからして、特に大きな問題もなく動作しているのでしょう。


 今の両者のTLEは射点の違いや軌道の違いが手に取るように見えて面白いです。