2014年12月27日土曜日

コーリニアアンテナを作ってみた

ADS-Bを受信するためにコーリニアアンテナを作ってみました
基本的には 半田最小限改め!半田なしでADS-B用多段コリニアアンテナを作るHP発見(N先輩情報提供)半田なしでも作れます。 の方法です
手持ちのケーブルの関係でS-5C-FB(テレビ用の75Ω)を使用しました
短縮率とか作りやすさとかを考慮し、シールドを残す長さを11mmに変更しました
また、ケーブルは最後まで突き刺すのではなく、メジャーなどで端からの長さがn*11mmになるように調整しました
これは作ってる最中の長さ誤差が積算されるのを防ぐ目的があります
ただし短縮率等の計算が間違っているとコンスタントに誤差がどんどん増えていくので、可能であればパラメータを変更して各種作ってみるのがいいです
仕様としては6段+1/4λの短絡 という感じです
一番下のエレメントに直接BNCコネクタを接続することによりインピーダンスの違いを減らせないかなと考えていますが、実際どうなのかは不明

さて、その能力についてですが
窓から外に向けてこんな感じです
大したことねーじゃんと思うでなかれ、受信地点は富良野のあたりなので最大で160kmくらい受信できています

カーテンにぶら下げているので、窓の方向南西方向しか見えなくて、旭川空港の方はすぐにロストしてしましますが
もうちょっと段数増やして屋根の上に置いておきたいなぁ と思う次第…
長い塩ビパイプに突っ込んでベランダから立てれば屋根より高く上げれそうですが、まぁ暖かくなってからですねぇ

どうせならディスコーンを置いてエアバンドも受信できるように とか QFHを置いてNOAAとかも… と考えてると楽しいですが、どんどん現実的じゃなくなってくるので面倒

mbedでブラックベリーのトラックボールを使う

mbedでブラックベリーのトラックボールを使う方法です


配線が面倒なので、ブレッドボードに直載せです
トラックボールに使用するのをピンヘッダではなくピンソケットにすればブレッドボードすら不要です
トラックボール以外何も載せられなくなりますけどね

下記のソースコードはトラックボールで色を変更するというものです
色はHSVで管理され、横に動かすとHが、S,Vは縦に動かすと変更できます
SとVの選択はボタンを押すことにより行います
LEDはPWMで調光していますが、輝度を直線的に見せる部分の関係でV0にしても完全には消灯されません
また白色LEDは使用していません

とりあえずこんな感じで動くよ 程度なので ソースコードはごちゃごちゃしてますが まぁ参考までに…

また、HSVからRGBへ変換するソースコードはwikipediaより引用しています

2014年12月20日土曜日

緯度、経度、高度から直線の距離、方位、仰角を計算する

GPS等から得られる緯度経度高度から直線距離を計算したい場合は単純に三角関数でxyzの直交座標にしてから計算するだけでいいですが、方位や仰角を求める式はあまり見つかりません

で、いろいろな本を読んでいたのですが、"GPSのための実用プログラミング”(ISBN9784501325503)という本の30ページあたりに書いてありました

この本はGPS衛星から受信した情報から自分の位置を計算する という内容ですが、ソースコードのサンプルを多数掲載しているので色々と参考になります
ただ、amazonのレビューにもありますが、ソースコードには著作権が主張されているので、何かに使う場合は注意が必要です

GPSの仕組み(超低レベルな、衛星の中で何をやっているか、の部分)を知りたい場合はこの本は向いていないと思いますが、読み物としては面白いのでどういう計算をしているのか興味がある人は読んでみると良いと思います

2014年12月15日月曜日

AN/PRC-152ダミーラジオ

EMERSONのAN/PRC-152ですが
思いつきでBNCケーブルを付けてみました


予想以上にいい雰囲気…

とりあえずTNCP-TNCPとTNCJ-BNC-Jアダプタを組み合わせてTNCP-BNCJとしています
車載や基地内での運用では外部に設置したアンテナを使用することによりゲインを確保したりしていますが、そんな感じの雰囲気が出ます

サバゲで使うだけならブレードアンテナ1本で十分ですが、一工夫するだけで自室に置いた時や車に置いた時の雰囲気が向上します

mbedのSerialから1行読み出す

最近mbedでプログラムを作っています
で、ノンブロッキングな1行読み取り関数が欲しかったの、とりあえず作ってみました

本来であればmbedのWebページで公開するべきですが、とりあえずこちらに書いておきます

とりあえずコンストラクタとデストラクタ、それ以外にAdd,Getc,Getsの3個の関数が用意されています
mbedのSerialで使いたい場合はSerialの受信割り込みハンドラで1文字を読み出したらAddに渡す というコードを作っておけば、メインループスレッドでGetcで1文字読み出すこともできるし、Getsで1行読み出すこともできます

現在はASCIIコードの英数しか対応していません 半角カタカナとかも非対応です
また改行コードは\rと\nに対応しており、改行コードしか無い文字列は無視されます

いちおう動作はしていますが、本当に問題なく使用できるかは確認していないので、自己責任でご使用ください


mbedって「コピペでなんでも作れる!」みたいなことを言われているイメージだったんですが、Serialから1行読み出すって何度ググってもやり方が出てきませんでした
やっぱこの程度なら自分で作ったほうが早いよ(´・ω・`)

2014年12月14日日曜日

10HzGPSのステータスLEDについて

10HzGPSから出力した1PPS出力でLEDを光らせていて気がついたのですが、このGPSモジュールのLEDは1PPS出力とは非同期のようです

赤が1PPS信号 黄色がLEDパルスです
PPSは正論理、LEDは負論理です

1PPSを信用した場合、LEDのパルスは約220msec後に50msecの間有効になっているようです

これについてGPS受信チップのデータシートを確認した所、Pin7 GPIO6に
General purpose I/O (Default status indicator. When GPS position fix is available, it output 50ms high per second, otherwise it output low.) 
多目的I/O(デフォルト地位指標。 GPS位置フィックスが利用できるとき、それは1秒につき高さ50msを出力しました、さもなければ、それが低く出力されました。) 
という記述があります(日本語はYAHOO翻訳より)

10HzGPSモジュール自体のデータシートによるとLEDはx.000秒に正確に同期しているようですが、実際にはそのような記述はなく、図による解説だけです

本来であればもう少しオシロなどで確認しておきたいところですが、僕の部屋はPC等のノイズでGPSが受信しづらい状況であまり詳しく確認できていない状況です


さて、1PPSとLED出力 どちらが正しいのか
とりあえずケータイで117に電話して耳と目で同期を確認してみましたが、どちらもずれているような気がします(そもそも117がどれくらい正しいか という問題があります 電話網での遅延とか)
確認には高精度にUTCに同期したクロックソースが必要ですね
トライステートのGPS時計でも買おうかと思ったんですが、時間専用GPSレシーバーとか謳っていながら1PPS出力端子を持っていないようなんですよね なんだかなぁ…

このGPSモジュールとの格闘はしばらく続きそうです
比較的入手性がよく比較的使いやすいGPSモジュール となると数少ない選択肢ですが、缶サットに使った際はあっさり現在位置を見失いやがりましたので、あんまり使えるモジュールでも無いのですよね

早くITAR規制外れた使いやすいGPSが輸入されてこないか…と思う今日このごろです

2014年12月13日土曜日

10HzGPSの出力タイミング

10HzGPSがNMEAデータを出力するタイミングについてです

この画像はGPSのTXとPPSをロジアナで表示したものです

1PPSの立ち上がりはUTCのx.000秒に正確に同期していると予想されます
それに対し、NMEAの出力はかなりズレています
というか1PPSが立ち上がった時点でx-1.900のデータの出力が終わっていません

このタイミングはコンスタントにこの時間分ズレるわけではなく、常に変動しています
もしかしたら捕捉した衛星の数によって処理時間が変わる…という可能性もありますが、そこまでは測定していないです

問題はNMEAの出力がPPSと非同期という点です
NMEAが送られてきた点に同期してマイコン内の時間を校正するといつまでたっても校正が終了しません

±100msec程度でいいならNMEAを受信するだけでもいいですが、±50msec以下でタイミングを合わせたい場合はPPS信号を使用する必要があります

2014年12月12日金曜日

ストリナ10HzGPSの改造

ストリナで売っている10Hz出力なGPSモジュールですが、このモジュールで使用されているGPS受信チップには1PPS出力端子があります
この出力端子は"±11ns high accuracy time pulse"(データシートより)だそうで、正確な時間が必要になる電子工作では十分な精度のタイミングソースとして使えます
しかしこのGPSモジュールではPPS出力はLEDをドライブしているだけで、コネクタには引き出されていません(そもそもコネクタは未実装ですが)
ということでPPSを引き出しつつ、他にもちょっと説明を


まずコネクタですが、4極、5極、6極のいずれかを使用します
4極の場合は電源とデータだけなのでPPSは引き出せません
5極の場合はGND2本を使用してPPSを使わない or GND1本にしてPPSを出力
6極の場合は全てのPADを使用しつつPPSを出力
という感じです

ピンアサインは画像に書いてあるので一目瞭然だと思いますが
「TXってどっちから見た送信だよ!」
と言う人がいるようなので念の為に矢印を書いておきました
GNDの隣にあるTXピンはGPSからマイコン等へ流れる位置情報データ
VCCの隣にあるRXピンはマイコン等からGPSへ流れるコンフィグデータ
となります

PPSピンはGPSデコードチップから直接ジュンフロン線などで引き出します
パターンが狭いので隣のPADと短絡しないように注意してください


それと使用する際の注意点ですが、画像に見て右上にある円形の物体ですが、これがバックアップバッテリで、ちょっと見た感じではちゃんと固定されているような気になるのですが、実際には2箇所の薄い電極で基板に乗っているだけです
なので何かに引っ掛けると簡単に剥がれてしまいます
ということで実際に使う場合はGPSモジュールをテープでグルグル巻にして置いたほうが安心です

それと同じく脆弱な場所として、アンテナの横にあるLEDも簡単に壊れてしまいます
LEDなんていらない!という場合はとっとと壊しちゃってもいいですが、GPSのFIX確認にLEDを残しておきたい場合は接着剤などを盛って保護してやる必要があります


とりあえずハードウェア面はこれくらいでしょうか
ソフトウェア面では、GPSチップに内蔵されたEEPROMの書き換え回数が少ないので頻繁に設定を変えていると設定を焼けなくなる… くらいでしょうか


それではみなさんも快適な測位ライフを!

2014年12月11日木曜日

BNCコネクタの取り付け

秋月で買ったBNCコネクタを使う方法

今回使ったコネクタ
http://akizukidenshi.com/catalog/g/gC-00095/

使った同軸ケーブル
http://akizukidenshi.com/catalog/g/gC-00007/

同軸ケーブルはBNCPが両端についたケーブル
以前アンテナを作った時に半分に切った残り

組み立て方は↓のページにわかりやすく書いてある
http://www.sun-ele.co.jp/explain/bnc_connector.html

BNCコネクタを分解するとこんな感じになっている

左から BNCコネクタ本体・傘(?)・ゴム・円盤・ボルト(?)・ピン という感じ

次に組み立てる準備
ボルト・円盤・ゴムの順番で挿入する
画像で見て右側にBNCコネクタを設置することになる
この3個はケーブルに入っているが、なくしたりしないように両側にテープを貼っておくといい
この3個を通すときはケーブルを切り落としたままで被覆を剥かない状態でやった方がいい

次に被覆をむいて傘を通す
傘は被覆を剥かないと入らない 被覆は余裕を見て10mmくらい剥いておく
被覆を剥くと網線がほどけてくるので、テープで解けないようにすると傘をスルッと入れられる

傘を通したら網線を折り返す
折り返した網線は傘の端で切りそろえる
そして芯の被覆を剥がす
この被覆は傘の折り返しから3mm残して被覆を剥く
そして被覆を剥いたところから芯線を3mm残して切り落とす
全体として、傘の端から芯線の端までが6mm位になる
(長さについては上記URLページの図がわかりやすい)

そしてピンをハンダ付けする
ピンの穴は小さいのでハンダ付けは大変
そもそもピンの外側にどんどんハンダが広がっていくし…
外側はカプトンテープとかで養生しておくといいのかも
予想するにこの部分のハンダ付けがうまくできないとインピーダンスが合わなくて高周波特性が悪化すると思う
とりあえず今回は初めてということで、あまり特性は気にしなかった
引っ張って抜けなければ良い という基準で終わらせた
ピンのハンダ付けが終われば後はねじ込むだけ
ゴムを押しつぶして、左右に広がることによってケーブルの被覆を押し付けて固定する感じだと思う
なのでボルトは締めればどんどん入っていく モンキーレンチで締め込んでいくとなんとなく硬くなるところがある その辺りで終了しておく
とりあえず壊れない程度に締め込んでおく

動作確認はオシロスコープとプローブの間に挿入して行った

時間軸を拡大するとこんな感じ
赤が今回作ったBNCケーブルを使用、水色がプローブを直結
立ち上がりが遅くなっているのがわかる
ケーブルを延長しているためなのか、コネクタの作りなのかは不明

まぁ断線しているわけではないと思うので大丈夫ということにしよう

2014年12月7日日曜日

mbedで正弦波を出力

ちょっとやってみたいことがあり、STM32F1でADCを動かしています
データシートを見る限りでは無理そうですが、ものは試しということで
で、ADCの動作確認にてきとーなサンプルがほしいのですが、うちにはファンクションジェネレータは無いし、それらしいものもありません
ということでmbedから波形を出力してみました

mbedのp18は10bitのDACが接続されており、任意の電圧を出力することができます
波形はSIN関数を使うことでテーブルを持つ必要はありません
今回はテストに使うだけなので波形を出力する機能しかありません

Timerで現在の時間を獲得し、時間にほしい周波数を掛けて、1とのmodを取ることによりほしい周期で0-1になります
あとはこの0-1にPI*2を掛けてやれば0-2piの間を直線で移動します
この直線をsinに渡してやれば-1から1の間を取る波形になるので、これを2で割ってから0.5を足しています

多分ソースコードを見たほうがわかりやすいと思うので、貼り付けておきます

#include "mbed.h"
#include <math.h>

DigitalOut myled(LED1);
Timer tim;
AnalogOut aout(p18);

int main() {
    const float freq = 250;
    tim.start();
    
    while(1) {
        float s = tim.read();
        myled = ((int)s) % 2 == 0; /* LED output(0.5Hz) */
        aout = 0.5 + (sin(fmodf(s * freq, 1) * 3.14159265359 * 2) / 2);
    }
}

このサンプルでは250Hzの正弦波を出しています
三角波とか矩形波が欲しい場合は、もう一工夫が必要ですが、気が向いたら実装します

で、この波をSTMのADCで読んでFFTを通してみました
250Hzのあたりに結構鋭い尖りがあります
結構綺麗な波が出ているようです

2014年11月28日金曜日

L64x0 ステッピングモータドライバ

L6470とL6480で遊んでいます



大きいほうがL6480 小さいほうがL6470で制御しています
このドライバは絶対位置をレジスタに書き込むと加速・定速・減速を自動で制御してくれます
停止・加速・定速・減速のモーター電圧はそれぞれ設定できます
例えば、12Vのモーターを24Vの電源で駆動する といったことも可能です

ただ、L6480の方の電圧設定はちょっと微妙です
L6480は外部にFETを持っているため、モーター電圧を知る術がありません
1Ωのコイルに3Vをかけても9Wも消費されていません
この辺りの校正はレジスタの設定でできそうですが、とりあえず電圧の設定を変えて対応しています


L6470とL6480は型番が似ており、レジスタ設定も似ていますが、完全に同じではありません
この図はそれぞれのレジスタ名と、ビット長を書きだしたものです
1ビット違う 位ならまだいい方で、名前もデータ長も同じだから同じレジスタだよな?と思ったら方やアンペア、方やボルト みたいな設定になっていたりします
またL6480のレジスタ一覧では15hは10bitですが、レジスタの説明では12bitになっています


L6470は比較的使いやすいステッピングモータドライバですが、L6480の方はもうしばらく様子を見たほうがいいかもしれません
L6480のデータシートは4回ほど更新されていますが、一体いつになれば修正されるのか…

2014年11月25日火曜日

Webカメラを買った

BUFFALOのBSW32KM03というWebカメラを買ってみました
現在1800円ほどです
安かろう悪かろうな製品かとおもいきや、予想を完全に裏切ってきます

1)FHD対応
2)FHDで20fps出る
3)分解すればすごく小さい
4)UVC対応なのでOpenCvで遊べる

つまり「1920x1080@20fpsを使った画像処理」ができます
ただ、帯域は十分にあると思うんですが、解像度を下げればfpsが上がるということでは無いようです
640x480なら30fps以上出ますが、1280x800だと20fpsとなり、FHDと変わりません

それと、十分にマシンスペックのあるPCならFHD20pで画像処理もできると思いますが、RasPiとかと組み合わせるとどうなるのかはまだ試してないのでわからないです
画像認識で導体追跡とかやってみたいので、RasPiでもある程度のパフォーマンスが出ると嬉しいのですが




とりあえず、このWebカメラは「買い」だと思います

2014年11月14日金曜日

IC-R6リモート


こんな感じになりました
COMポートの選択はテンキーで行うように変更されています
それとスケルチロードはdisconnectの横にある緑の丸がフラグになっています
緑でロード 灰色でロードせず ですが、OFFではSメーターと同じなので、悪いUIの見本みたいな感じになっています

それとdisconnect(COMポートの開放)はまだC#のボタンです

全体的に最適化して、下側を使ったリスト選択を自由に作れるようになったら、メニュー操作も突っ込もうと思います

それと地味な追加機能として、スケルチオープンのフラグを作りました
S00の左にある丸を触るとOpen/Closeが変化します


とりあえず右下の選択画面は1ページに5項目を表示でき、項目数が5よりも多い場合は1で前ページ、7で次ページ という感じにスクロールできます
現在は数字を選択するとすぐに確定ですが、7セグは文字色を自由に設定できるので、数字で選択し、Eで確定 という感じの実装もアリかなと思っています

とりあえず、全体的に複雑なコードなので、もうちょっと最適化を進めてからになります
最初はこのコードで問題ないだろ と思っても 機能追加していくとどんどん不便になっていきます
いままでまじめにプログラミングやってなかったツケを払ってる感じです
次に似たようなものを作るときはもっと上手く作れる と信じて書き直しではなく、修正で頑張っていますが、こんなUIもう二度と作らないと思います。。。

IC-R6リモート

こんな感じになりました


操作の雰囲気は動画で



イメージとしてはF/A-18(インテークが丸い方)の操作パネルですが、まぁ雰囲気だけです

使い勝手は悪いですがw 雰囲気は最高です

まだ正常に転送できなかった場合の動作に不安が残りますが、とりあえず最低限使うことはできるようになりました
あとは細々と作りこんでいく感じになりますが、コードが必要以上に複雑なので、結構大変です

IC-R6をリモートで

(コマンドの叩き方を調べて見てる人がいたら、前回のエントリを参照してください)

IC-R6の周波数とモードを表示するソフトを作ってみました
とりあえず周波数と、下にSメーターがありますが、基本入感したらメーター振り切るのであんまり意味無いです せいぜいイヤホン外してる時に入感してることを知る程度
それと現在の時刻も表示しています

今は表示だけですが、モード・周波数の変更と、スケルチオープンを操作できれば結構使えるようになりそうです

今回はマウスホイールなどで文字を操作したくて、となるとかなり厳密にマウスの位置と文字の位置を比較する必要があります
ということで自分でフォントを作ってみました
本来は固定幅フォントをキャプチャしてビットマップフォント化とかをするべきなんですが、今回は16segLEDっぽい表示にしてみました
謀らずもレトロな感じです

とりあえずもうちょっと機能を作りこんで、その後はマイコンに移植かな
といっても、C#をCにするので全く互換性がありませんが

マイコンから操作できればテンキーみたいなインターフェースを作れるので、便利になると思います
ま、基本メモリに入れちゃえばいいので完全にネタになっちゃいますが

2014年11月12日水曜日

IC-R6のコマンド

/*
 バイナリビューアはしばらくお休みします
 ネタ切れしてます
*/

IC-R6を買ったので、早速コマンドを叩いてみました


FE FE 7E 00 03 FDを送ると、FE FE 00 7E 03 00 00 60 32 01 FDが帰ってきました
コマンド03は表示周波数を返すコマンドです
03コマンドのリターンはBCD(二進化十進表現)で下位桁からです
そのまま表示すると下位の桁が左に表示されるため
順番を入れ替えると01 32 60 00 00となります
数字としてみると0132600000で、MHzにすると132.6MHzです
IC-R6で北海道東セクタの管制を聞いているので、ちゃんと表示している周波数が帰っています

ボーレートは1200で上手く行ったので、気を良くして9600にしたら帰ってこなくなりました
結構ゆっくり送る必要があります


また、最初はC#ではなく、X-CTUのアセンブリパケットで送っていました
が、ボーレートを変えようが何しようが戻ってきません
もしかしたらX-CTUは1バイトごとに適当なdelayが入っていて、IC-R6でタイムアウトしているのかもしれません
IC-R6に限らず、X-CTUでコマンド叩いて上手く動かない場合は別の方法でコマンドを叩いてみるといいかもしれません
気が向いたらロジアナでタイミングを確認しようかと思っていますが…


とりあえずコマンドは正常に機能しているようなので、まずはC#でGUIで動くプログラムを作ってみようと思います
その後でてきとーなマイコンでスタンドアロンで動く表示・変更用の機材を作ってみようと思います


IC-R6を買った時に一緒に買ったオプションや、運用環境についてはまた改めて別のエントリに書きたいと思います

2014年11月7日金曜日

バイナリビューアを作る(4日目)

細々と修正を重ねているのですが、自分でもどこを変えたか思い出せません。。

とりあえず表示するエンディアンの選択と、表示する変数型の選択は実装しました

あと、ファイルサイズの表示等は昨日のバージョンにはなかったはず…
とりあえずByte,KiB,MiBで表示できるようにしてあります
1024Byteを超えるとKiBで 1024KiBを超えるとMiBで という感じで自動的に表示しています

それとアドレスのオフセットを実装しました
とりあえず今はオフセット後のアドレスをステータスバーに10進で表示しているだけです
オフセットを設定するにはカーソルを移動してF2キーを押すとカーソルの位置を0とします
(F2は検索機能とかがついてるのが普通ですね 多分変更します)

あと、ステータスバーの最後の(0.006)は1フレームを描く時間を示しています
あまりに大量のデータを表示するともっさりしてくるため、目安として表示しているだけですが
といっても、FHD画面1枚に最大で表示しても20fpsくらいは出ます
FHD2枚に最大で表示すると10fpsくらいになるので、スクロールとかの追従性は悪くなります


とりあえずはこれくらいでしょうか
あとは細かいところを作りこめば僕が欲しい機能は粗方実装が終わります
多分ここからが長いんですが。。。
間に合わせで作った部分とかは、ちゃんと作る方法を調べながらになるので 結構面倒な気がします

2014年11月6日木曜日

バイナリビューアを作る(3日目)

だいぶ横長になりました

現状の機能として
・ファイルの読み込み(800MB程度までは確認済み/1.6GBのファイルではメモリ不足エラー)
・任意の場所・任意の長さの選択
・選択した場所のコピー(16進2桁+スペース区切りの連続)
・0x00を強調して表示
・フォントの選択(インストール済みの等幅フォントのみ)
・カーソル位置・選択したデータ数の表示
・選択した箇所から各種変数型で値を表示
という感じです

読み込めるファイルサイズは800MBあたりまでは確認しました
ただこれ以上だとちょうどいい感じのファイルが無くて、確認していません
1GBを超えたあたりでメモリ不足エラーが発生すると思いますが、RAMは32GBで一部RAMDISKにしているとはいえ20GB以上あるので、もうちょっと大量に確保できても良さそうな気がします
C#側で大量にメモリ確保しすぎないように制限かかってるのかも?

ファイルの読み込みは800MBで7秒くらいでした
秒100MB位を読んでるので、HDDのシーケンシャルリード(120MB/sec)に近い速度です
これ以上の高速化はおそらく無理でしょう


変数型ですが、8bit 16bit 32bit 64bit float doubleの6種類を、前者4種類は符号有り・無し含め、リトルエンディアンとビッグエンディアンで表示しています
doubleは精度が約15桁で、それに指数を含めても20桁程度なのですが、64bitを3桁カンマ区切りで表示するとそれ以上の文字数になってしまい、変数表示エリアがかなり広大になります

変数は選択した場所で作れる変数ではなく、選択した部分の一番若いアドレスから1,2,4,8バイトを変数として表示しています
なので16バイト分選択したからといって128bit変数として扱うわけではありません


昨日のバージョンでは、文字列を画面に書き込むたびに書いたサイズを積算していました
が、それでは等幅フォントを使用していても少しずつズレが発生していました

今日のバージョンではフォントをロードした段階で、1文字の大きさを計測して変数に保存しておき、文字を書いたらその大きさを積算していく という感じにしています


既知の重大な問題としては、ウインドウを最小化するとPictureBoxのSizeが0x0になり、Bitmap変数のコンストラクタでエラーが発生してしまいます
とりあえずの解決策としては下位関数に画像を要求する前に解像度を調べて、解像度が1バイト表示できる最低サイズよりも小さい場合は処理を中断する という感じにしようかな と思っていますが、あんまりスマートな方法じゃないのでなぁ


とりあえず、変数の表示ができれば色々と便利ですが、更に便利にすべくアドレスのオフセット表示を実装したいと思っています
この機能があるとファイルコンテナ内のアドレスとかを考えるときに脳内オフセットしなくていいので、非常に楽です
しかしオフセットをさせるには数字の入力UIを作る必要があり、結構面倒です
とりあえずはカーソル位置を0として扱う というボタン?キー操作?を実装すればいいかな と考えています

後はマーカー機能とジャンプ機能とか

まぁ今のUIだって使いやすいわけじゃないし、欲を言えばきりがないので 程々に色々追加しようと思います


/*
しかし、C#は結構昔から使ってましたが 真面目に使ったことはありませんでした
それでも3日 必要な関数を探しつつ、少しずつ作業してここまで形になるんだなぁ
*/

2014年11月5日水曜日

バイナリビューアを作る(2日目)

マウスクリックでカーソルを移動 クリックしたまま動かして範囲選択 を実装した
それと文字列を表示する関数を変更した

今までの関数では1文字書く毎に数ピクセルずれているような雰囲気があった
ということで新しい関数を作ったのだが、画像の通り、こっちのほうが酷い

一番簡単に解決するにはビットマップフォントを作ればいい
これなら大きさが固定なので並べるだけ

ただ、自分しか使わないとはいえ最低限文字サイズの変更くらいは実装しておきたい
まだ今日は1日の4分の1が残ってるので、文字表示関数を作りこもうと思う

2014年11月4日火曜日

バイナリビューアを作る(1)

暇つぶしとか気分転換を兼ねてバイナリビューワを作り始めました

1日目の作業はこんな感じ

フォームの上下サイズを変更すると表示量が増えます
フォームの左右サイズを変更すると1行に表示できる量が増えます
また0x00を強調して表示する機能を実装しました

既知の不具合としては、スクロールバーの動作がおかしいです
しかしこれはC#側の問題な気もします
しばらくは最低限必要な機能を実装することが重要で、それが終わってから動作確認をすることになると思います
また横幅を変更するとスクロールできる行数も変化しますが、その部分もまだ実装していません

まだ実装していない機能としては、クリックしてカーソルを移動 でしょうか
バイナリエディタではないのでカーソルは必須ではないですが、マーカーとして便利です

他に実装したい機能として、カーソルの位置の表示+オフセットを設定したアドレスの表示
8,16,32,64bitの変数として扱った場合の値の表示
あたりを作りたいと思っています

右側に表示される文字はとりあえずASCIIだけの予定です
文字コードを扱うのは面倒なので


プログラムの作りとしては、上にメニューバー 真ん中にピクチャボックス 右側にスクロールバー という感じです
表示はBitmap Graphicsでリアルタイムに作っています
最終的には必要なときに画像を生成するようにするかもしれませんが、今のところはTimerで一定間隔ごとに作っています
必要なときに生成 の利点はCPUリソースを無駄に浪費しないという点ですが、欠点として「何かイベントがあると必ず呼び出す必要がある」という点があります
チェックボックスを作って、画像生成処理でチェックボックスを参照しているのに、なぜか正常に動作しない と思ったらチェックボックス変化割り込みで画像を更新していない みたいなことが発生する可能性があるわけです


データの読み込みは、一旦全て配列に読み込んでから必要な部分を表示します
なのでデータサイズが数百MBとか数GBになるようなファイルは扱わないほうがいいと思います


現状はこんな感じです
個人的に使いたいだけなので、あまり多機能性は求めませんが、自分が欲しい機能は載せていく予定です
いずれはバイナリエディタ機能も欲しいなぁと思いつつ、メモリ配列の途中にデータを追加って結構面倒なので
ただ表示は中のメモリを表示しているだけなので、置換(上書き)は簡単に実装できる気がします
この辺りはあんまり重要性が高くないのでしばらく放置になると思いますが


とりあえず、表示だけでもまともに動くようになるまでは作り続ける予定です

2014年10月11日土曜日

PDS5022Sのキャリブレーション

ウチにあるオシロスコープ OWONのPDS5022SのCH1がかなり変な電圧を示すようになってしまった
200mV以上のスケールではオフセットが450mVもある
ということで校正の方法を

まず全てのプローブを取り外す
CH1とCH2を外せばいい 念のためEXT TRIGも外しておく

次にスイッチパネル左上の方にある6個のメニュースイッチの内、左下にあるUTILITYを押す
そしてファンクションキー3に割り当てられているAuto calibrationスイッチを押す
でもこの文字はロットとかによって違うみたいなので、とりあえずF3キーを押せばいいとおぼえておけばOK
ロットとかによっては場所自体変わってるかもしれないけど、CalibrationとかCalとか書いてあると思う

するとこんな画面になる
「オートキャリブレーションをするよ CH1とCH2につながってるすべてのケーブルとプローブを外してね Auto calibrationを押すとキャリブレーションを始めるよ それ以外のキーを押すと終了するよ」みたいなことが書いてある
ちなみにウチのオシロは数秒でこの画面が消えてしまうので書いてある字を読む暇すらくれなかった

すでにケーブル類は全て外されていると思うので、もう一度F3を押す
画面がすぐに消えてしまうようならF3を2回連打する必要がある

しばらく黄色い画面に文字が出ているので放置する
数分もあれば終わるはず
黄色い画面が消えたら終了


終了したらオフセットが綺麗に消えているはず
あとは念のため1kHz端子でも覗いてみてちゃんと計測できるか確認する

自動校正はそんなに頻繁にやる必要はないと思うけど、時々オフセット電圧が乗ってないか確認してやった方がいい
このオシロ、11年に買って3年位、ずーっと校正してなかったかも

オシロはあんまり使わないけど、いざというときにあると便利なので一家に一台ぜひ…
個人的にはオシロよりロジアナのほうが出番多いけど

NS73Mを試してみる(とりあえず搬送波だけ)

NS73MというFMトランスミッタモジュールを試してみた
画像はSDR#で見た送信周波数あたり


結構あちこちにいらない電波が飛んでいるようだ
あんまりよろしくない…
しかし、SDRだとこうやって目で見て余分な電波がわかるので便利

このトランスミッタモジュール もちろん技適なんて取ってないし、最小出力でも出力は強すぎるらしい
トライステートがこのモジュールを使ったFMトランスミッタキットを出してるけど、簡易的なアッテネータが入ってる(インピーダンス合わせてるだけな気もするけどよくわからない)
ネットで出てきた例でもまじめなアッテネータが入っているのがある
今は2.4GHzかと思うような短いアンテナで出してるし、迷惑かけるような周りの人がいないような場所だけど、缶サットとかに載せてテレメトリ出すならちゃんと考える必要がありそう

このモジュールはI2Cで制御ができて、内部の1ビットをON/OFFすることにより送信したり止めたりできる
ラインイン端子をGNDに落としていても送信すれば無音としてラジオで受信できるし、送信を止めればラジオからはノイズが聞こえてるく
さながらバーティカルリミット(映画)のワンシーンのよう


久しぶりにチューナにQFHアンテナを付けたのだけど、PCのノイズとかが多くてあんまり綺麗に受信できない
エアバンドを受信できるほど空港に近いわけじゃないし、アマチュア無線が常時飛び交うようなことも無いし、ローカルFMも面白くないし
ベランダの上にディスコーンアンテナとか立てればもうちょっとエアバンドとか受信できるかもしれないけど、そこまでするのもねぇ…

2014年10月10日金曜日

皆既月食を撮ってみた

K-5で皆既月食を撮ってみました

途中で勘違いとかで撮影を終了してしまったので、完全に食に入ったあたりで終了しています
左下から登ってきた月が右上に移動しつつだんだん欠けています

撮影条件はISO160でSS1/50sec F3.5 という感じです
皆既月食はかなり暗くなるので、明るさは2-4倍くらいで撮影したほうが良かったかも

何年か前に日食を撮影した時は綺麗に撮れましたが、月はぼやけてあんまり綺麗に撮れないです
夜露とかが影響するのかも


2014年10月2日木曜日

C#+OpenCvで静止画を動画にする

タイムラプス撮影とかした場合に問題になるのが、大量の静止画をどうやって動画にするか
安い動画編集ソフトだと静止画は最短で0.1秒表示みたいな感じで望む再生速度にならない

ということでC#で動画化するアプリを書いてみた

今回はC#のコンソールアプリとして作る
もちろんフォームアプリを作ってオープンファイルダイアログでファイルを選択するようにしてもいいわけだが、今回は上位のプログラムから起動して処理させたかったのでこのような方式にした

それと動画ファイルを作るのにOpenCvを使う
C#で走らせるのでOpenCvSharpが必要になる
これの準備は他のブログとかにちゃんと説明されてるのでそっちを参照。。

/* *** */

まず静止画の一覧を獲得する必要がある
今回はコンソールアプリの1個目のオプションに画像の一覧を書いたテキストファイルを渡すようにする


画像ファイルはList<string>で扱う
リストに突っ込むときは片っ端から突っ込んでそのファイルが存在するかとか、そもそもそれは正しいファイルパスなのかとかは気にしない

それとdouble型でフレームパーセックの変数を用意しておく
とりあえず double FPS = 30; を作り、オプションが2個以上であれば2個目をdoubleの文字列として読ませるようにした これでファイルのリストだけが与えられたら30fpsの動画を作り、それ以外の速度にしたければ引数で与えればその速度になる


それと画像ファイルの解像度を獲得する関数を作る
引数に渡された画像をBitmapで開いてWidthとHeightを返すだけ
そして GetPictureSize(PictureFilePaths[0], out SizeX, out SizeY); のような感じで画像の解像度を得る
この解像度で動画を作成することになる


最後に動画ファイルを作成する

最初に処理時間の目安を計測するためにStopwatchを確保する

次にCv.CreateVideoWriter関数を呼ぶ
第一引数:ファイル名
第二引数:エンコード方式
第三引数:フレームパーセック
第四引数:解像度
なのでそれぞれに変数を渡すなりして適切な値を与えてやる
なお、FileExte = "avi"; EncodedFormat = "MJPG"としてstringの変数を作ってある
これはAViコンテナにモーションJPGの動画を入れるということ
エンコードはH.264とかやろうと思ったけどどうやらウチのマシンは対応していないようなのでMJPGになった
fpsはさっき作ったdoubleをそのまま渡す
解像度もさっき調べた解像度をそのまま渡せばOK

あとはCv.WriteFrameで動画を書き込んでいけば動画ファイルを作成することができる

forで0からPictureFilePaths.countまでを回して、まずFile.Existsでファイルが存在するかを確認する
そしてCv.LoadImageで読み込んで渡す


本来はもっとまじめにエラー対策とかする必要がある
けど面倒なので読み込むファイルのチェック程度しかしていない

出力されるコンテナはaviなので、youtubeに投げる場合は別のコンテナにエンコードし直す必要がある
その辺りは動画編集ソフトに突っ込んでBGMつけて書き出せばいいので気にしないで置く


ということで、面倒な大量の静止画を動画にする作業が簡単になった
静止画のリストはCygwinとかで ls *.jpg > list.csv とかで簡単に作れるし、あとはそれを引数に渡せばいい
もしもGUIが必要なら最初からGUIで作ってもいいし、GUIはファイルの選択とリストの作成だけで、それ以外はCUIに投げてもいい

今回はコンソール用に作ってるのでファイルが存在するかの確認とか、解像度を調べるとかを除けばそのままCとかC++のOpenCvにも移植できるはず

2014年9月25日木曜日

金貨の価値

小説家になろう とかの転生物を読んでると、いくつかの貨幣が出てきます
銅貨が何枚で銀貨 銀貨が何枚で金貨 というのが あまりにもキリがいいので、んなわけないだろ と思い計算してみました

まずお金の価値についてですが、これは"使用している金属の価値"がそのままお金の価値となります
金貨はそもそもお金の形をしている必要はなく、金の粒はそれの価値と等価の物と物々交換ができます
金貨の絵柄を国が決めているのは、国が「この高価は純粋な金ですよ 混ぜ物はありませんよ」と価値を保証しているに過ぎません
ということで、図柄の美術的な価値とかは無視して計算します

今回の計算に使用する金属は金(Au)・銀(Ag)・銅(Cu)の3種類ですが、この金属の価値は今日時点で調べたおおよその価格を使用しています
時代による価値の変化は考慮していません
中世ヨーロッパ的世界観なのに金属の価値が現代と同じなのは(ryみたいなツッコミはご遠慮願います


さて、計算をしてみたいと思いますが、その前に前提となる数字を用意したいと思います

まずそれぞれの金属の価値
金:4650円/g
銀:73円/g
銅:0.7円/g
という感じです
この時点でいい感じに50や100で割れそうですねww でももうちょっと計算します

次に必要な数字ですが、硬貨の大きさを決める必要があります
とりあえず500円硬貨より一回り大きいサイズとして、直径30mm*厚さ2mmとします
円筒と考えると体積は1.4cm^3です

金・銀・銅の密度はそれぞれ19.3g/cm^3,10.5g/cm^3, 8.94g/cm^3です
1.4cm^3で計算すると重量は27.3g, 14.8g, 12.6gになります

これに先ほどの価値をかけると
金:12万7千円
銀:1千円
銅:8.8円
となります

微妙にキリが悪いので、銅貨を大きく、金貨を小さくし、10万円・1千円・10円とすると、それぞれ100倍になります

結論:銅貨100枚で銀貨1枚 銀貨100枚で金貨1枚 という換算レートは現代の価値で考えると結構ピッタリ



作中では商人同士で使うようなやたらと価値の高い硬貨もありますが、金の数十-数百倍の価値を持つ金属というと、何があるんだろう?
たぶん同じような硬貨だと紛失しやすいと思うのでw 実際に使うんであれば金のインゴットとかになる気がします


なお、この計算は金属の価値が現代の地球と同等と仮定して行っています
やたら大量に金が採掘されるとか、銅がめちゃくちゃ貴重だったりすると、全然違う価値になるので注意が必要です

そもそも地球と同じ国際単位系が使われてるとか ご都合主義にも程があるので、そのあたりは気にせずに物語を読むが吉だと思います

2014年9月22日月曜日

コズミックin赤平とかを見学とか参加してきた

9月20日に赤平の植松電機で開催されたコズミックカレッジin赤平とかに参加してきました

"とか"と言うのは、コズミック後の北海道スポーツシューティングクラブの例会にも参加したためです

・コズミックカレッジ

コズミックカレッジの対象は小3-中3なので、僕は見学です

今回のコズミックカレッジは参加者が5チームにわかれ、その中で2班を作り、モデルロケットを作る班とmbedを使った缶サットを作る班になります

モデルロケットは紙に印刷されたもので、それを切り出したり接着剤で貼りあわせたりしてC11-3を2本使って打ち上げます

缶サットチームはmbedに気圧センサ(LPS331AP)を接続し、打ち上げ時の高度を計測しました
高度の解析は後日植松電機の人が解析しWebページに掲載するようです
(1機はコズミックの最後に解析方法を説明し高度の速報値を出していました)

モデルロケットチームも缶サットチームも午前中の2時間程度で作り上げていました
ただ缶サットについては予め用意されたLチカコードの点滅周期を変更したりにとどまり、気圧を計測するプログラムは予め用意したものをそのまま使用していました
小学生3年生から参加し、ハードウェアの作成も含めて2時間という制限の中ではこれくらいがちょうどいいと思います

昼食の後、午後は実際にモデルロケットの発射を行いました

打ち上げ直前の説明の時に少し雨がパラパラと降ってきましたが、いざ打ち上げという時になるとほぼ快晴になっていました

晴天の中、C11x2の白煙を伸ばして飛んで行くモデルロケットはすごく綺麗でした

中盤からは雲が増えてきて、最後にはテントが飛ばされるのではと心配するほどの風も吹いていましたが、ちゃんと空力設計を行われたロケットはまっすぐ上昇していき、ロケットも缶サットも全て会場内で回収出来ました

その後植松さんの話が少しあり、コズミックは終了となりました

ただ、コズミック後に時間がある人は植松電機に残り、マルイBOYsを使ったサバゲを行っていました(後述)

・スポシュー

スポシューはコズミックが終わってから植松電機内で行われています
いつもは暗くなってからでしたが、今回はコズミック参加者に声をかけて、明るい内に打ち合いをしました
大人も子供も全員に10禁電動ガン(一部はエアコキ)を配り、バリケードを設置して打ち合います
チーム分けは大人対子供の2チームで、保護者は子供との遊び方を知っているためか、みんな楽しそうに遊んでいました

そして日が暮れてコズミック参加者が解散した後に、スポシューの参加者が集まりました
今回のスポシューは参加者が少なめでしたが、いつもどおり屋内で色々打ったりした後に、真っ暗になってから屋外で打ち合いをしました

真っ暗と言っても、今回は水銀灯を点灯させていたためにうっすらと何処にいるかはわかります
前回は真っ暗な中でしたが、フルオートトレーサーを全員装備していたため、マズルフラッシュ等で何処にいるかが一目瞭然でした
今回はそれが無いためにどこから打たれてるかがわからず、弾道も見えないためにいきなりヒットすることがありました
「弾道が見えないから狙いづらい」という声もありましたが、本来の打ち合いは弾道は見えないので、これもアリかなと思います あとトレーサー使うとすぐにヒットして楽しくないですし


僕もいつもは銃を持って打ち合いに参加しましたが、今回は途中途中でカメラを持って撮影を行っていました
上の写真はISO51200 SS1/2 F3.5という感じです
真っ暗なのでファインダーでは見えず、フォーカスはマニュアルでてきとーな位置に固定です

ノイズだらけでピントも甘いので緑一色にすると意外とそれっぽく見えるのが面白いですw

とりあえず今回わかったのは、この程度の人数(8人くらい?)だとほとんど誤射されない ということです
ということで次は僕の位置をバレやすいようにケミカルでも持って、α7sで挑みたいと思います
さすがに誤射されてレンズとかに当たったら悲しいので

ISO51200 SS1/2 F3.5をα7SのISO409600 F1.8に当てはめると、シャッタースピードは1/60くらいまで稼げるようです
ということで次は動画にチャレンジです


今回僕が使用したARはこんなかんじです
KeyModベースにアングルグリップとライト 反対側にContour ホロサイトとバックアップアイアンサイト と、ちょっとタクトレっぽい感じです
短時間しか使ってないですが、KeyModにグリップは不要な気がします
ライトも屋外だとほとんど使いものにならないので、不要か、物凄い明るいライトを付ける必要がります
ホロサイトはEoTechの実物を借りたため、レティクルも綺麗だし透明度も高いので使いやすいです

ただ中華の買ったまんまらしく、セミオートで撃てない(!)という不具合がありました
弾ばら撒くのはすきじゃないんだけどなぁ…


次回のコズミック&スポシューは11月15日です 真冬です 寒いと思います

スポシューは去年の11月に1回目を行ったので、次回が1周年です

2014年9月18日木曜日

MD5からデータを予測する

ちょっと気になったので実験
MD5から元のデータを予測することはできるか? という事

まず必要なデータを用意する
テストデータとしては"abc"と書かれた3バイトのテキストデータを用意する
このデータのMD5値は900150983cd24fb0d6963f7d28e17f72になる

次にC#で作ったプログラムにこの値を設定する
そして起動

input MD5が与えたMD5値
sizeが"たぶんこのバイナリだろう"と予想した大きさ
dataはそのバイナリを文字列として扱った結果(今回はバイナリファイルは想定していない)
timeは処理時間

無事に元の"abc"を得ることができた

3バイトを得るのに30秒
2バイトだと0.11秒くらいだった
1バイト増える毎にループが256回増えるので、まぁ計算通りかな
たった5バイトでも1ヶ月近くかかる計算
ネットの配布物に付属するMD5値から実際のデータを取り出すのは現実的に不可能

しかしこれにも抜け道は合って、バイナリデータとMD5の変換テーブルを作る というのがある
CPUリソースが開いている時にバイナリデータのMD5をどんどん計算しておいて、MD5値が入力されたら今までに作ったテーブルと比較する
これなら過去に計算したバイナリに同じものがあれば正常なバイナリを答えることができる

ランダムに全ての組み合わせのバイナリを作った場合
数kBくらいで何らかの画像データを得ることができる
数MBであれば何らかの音楽データになり得る
数GBあれば何かの映画を見ることができる

2014年9月16日火曜日

二重スリット実験 みたいなの

レーザーモジュールと厚紙を使って二重スリット実験のようなことをやってみました

使用したのは秋月電子で売られている緑色レーザーです
赤色(=長波長)のほうが間隔が広いのですが、手持ちに有る赤色は安物のためか干渉縞が全く現れませんでした


なんかもやっとしてますが、数珠のように干渉縞が見えます

今回使用したレーザーの波長は532nmで、スクリーンまでの距離はおよそ283cm スリットの間隔は0.5mmくらいです
これを元に干渉縞の間隔を計算すると
間隔 = (0.000532*2830)/0.5 = 3.01
で、3mmくらいになるはずです
実際、目安の定規と比較するとそれくらいになっています

レーザーモジュールさえちゃんとした性能のものがあれば、他は特に特殊なものはないので、結構簡単にできる遊びだと思います

2014年9月15日月曜日

strtokっぽい関数

C言語のstring.hにはstrtokという関数があって、文字列を指定した区切り文字で分割することができます
しかしこの関数では区切り文字が連続した場合、その部分をまとめて次のデータに飛んでしまいます
この場合、CSVのヌルデータ等は正常に処理できません
ということでそのような連続した区切り文字が存在する場合も次に飛ばないような関数を作ってみました

#include <stdio.h>
#include <string.h>

char *strtoks(char *s1, const char *s2) {
    static char *str = 0;
    register int i, j;

    if (s1) {
        str = s1;
    } else {
        s1 = str;
    }
    if (!s1) { return(0); }

    j = strlen(s2);

    while (1) {
        if (!*str) {
            str = 0;
            return(s1);
        }

        for (i = 0; i < j; i++) {
            if (*str == s2[i]) {
                *str++ = 0;
                return(s1);
            }
        }

        str++;
    }
}

char *strtokc(char *s1, char s2) {
    static char *str = 0;

    if (s1) {
        str = s1;
    } else {
        s1 = str;
    }
    if (!s1) { return(0); }

    while (1) {
        if (!*str) {
            str = 0;
            return(s1);
        }

        if (*str == s2) {
            *str++ = 0;
            return(s1);
        }

        str++;
    }
}

int main(int argc, char *argv[]) {
    char str1[] = "10,20,30,,50,60,,,90";
    char str2[] = "10,20,30,,50,60,,,90";
    char str3[] = "10,20,30,,50,60,,,90";
    char *p;

    printf("strtok\n");
    p = strtok(str1, ",");
    while (p) {
        static int cnt = 0;
        printf("%d:\"%s\"\n", ++cnt, p);
        p = strtok(0, ",");
    }

    printf("\nstrtoks\n");
    p = strtoks(str2, ",");
    while (p) {
        static int cnt = 0;
        printf("%d:\"%s\"\n", ++cnt, p);
        p = strtoks(0, ",");
    }

    printf("\nstrtokc\n");
    p = strtokc(str3, ',');
    while (p) {
        static int cnt = 0;
        printf("%d:\"%s\"\n", ++cnt, p);
        p = strtokc(0, ',');
    }

    return(0);
}

上記のstrtoksとstrtokcが今回作った関数です
strtoksは複数の区切り文字のいずれかが出てきたらそこで区切ります
strtokcは区切り文字は文字列ではなく文字として渡します そのため若干パフォーマンスが向上します

実行結果は
strtok
1:"10"
2:"20"
3:"30"
4:"50"
5:"60"
6:"90"

strtoks
1:"10"
2:"20"
3:"30"
4:""
5:"50"
6:"60"
7:""
8:""
9:"90"

strtokc
1:"10"
2:"20"
3:"30"
4:""
5:"50"
6:"60"
7:""
8:""
9:"90"

という感じです
strtokではスキップしてしまうところも正常に処理しています
なお、strtoksおよびstrtokcのヌルデータはptr[0] = '\0'となっています
例えば整数型が入っていると仮定し、整数型から変換する関数に渡した場合、場合によっては問題が発生する可能性があります
その可能性が有る場合は最初にヌルデータか否かを確認する必要があります

あと、わざわざ説明する必要もないと思いますが、strtokや上記の関数は受け取ったデータを破壊します
char *str = "123,456,789"; p = strtok(str, ","); とかやらないよーに

2014年9月5日金曜日

STM32F4

STM32F4の生チップを買ったので、とりあえずLチカをしてみました



STM32F401RBTとSTM32F429IITの2種類です

401RBTはF4で一番安いチップ F429IITはF4で一番高いチップ となります
(F4では429の上に439というシリーズが有りますが、RSでは176pinは扱っていませんでした)

/*
蛇足ですが、秋月のQFP176変換基板 コネクタの配置が1.27mmピッチです
つまり2.54mmピッチのユニバーサル基板に乗りません
秋月さん!!!何やってるの!!!!!
*/

さて、扱いやすさで言えば64pinパッケージは非常に簡単です
パスコン6個と短絡1箇所で動作します
アナログ電源(VDDA)すら不要です

次に176ですが、こちらはちょっと手間取りました
パスコンが15個くらい必要です


・BOOT0
これは起動するプログラムを選択します
F1であればBOOT0はGNDに短絡でもいいのですが、F4はシステムROMにUSB接続プログラムが書かれているため、BOOT0をH BOOT1をLにする場合があります
ということでBOOT0は47k程度でプルダウンとしておきます
もちろんST-Link等のデバッガを使う場合はその限りではないので、BOOT0をGNDに短絡しても構いません

・BYPASS_REG
このピンは内蔵されたレギュレータのON/OFFを行うようです
レギュレータ止めてどうするんだよ… と思いますが、その場合は外部電源でコアを走らせることができるようです
で、内蔵レギュレータを使用する場合はBYPASS_REGをLにします
Hにすると停止です

・PDR_ON
このピンも電源周りのようです
DISCOVERYの回路図を見るとGNDに落ちているので、これを真似ることにします

・NRST
リセット端子です
例に漏れず負論理なのでプルアップで処理します… といいたいところですが、オープンで問題ないようです
これは内蔵プルアップ抵抗(min30/typ40/max50)で釣り上げられているためです

・VCAP
64pinではVCAPが1本 それよりも大きいパッケージでは2本あります
これは内蔵レギュレータのコア側のパスコンのようです
データシートには2.2uFと0.1uFの接続を指定されています
とりあえず2.2uFを使用しています

・VREF+
ADCのリファレンス電圧だと思います
なんか別にも使われてる気がしますが、そこまでまだ調べていません
これはVDDAに短絡させています

・VSSA
アナログ電源のGNDです とりあえずVSSに短絡しています

・VDDA
アナログ電源です この電源はかなり綺麗にする必要があるようです
とりあえず47Ωと47uFでLPFを形成していますが、本来はインダクタとかを使ったほうが良いと思います

・VSS/VDD
電源です
各VDD・各VSSは内部で接続されています
なので最低限動作させるだけであれば1組のVDDとVSSに適当な電圧を入力すれば動作します
しかしダイとボンディングワイヤで接続されているだけなので、抵抗値はそこそこ高いようです
なのでQFP176で例えれば136のVDDに3.3Vを入れて、36のVDDからLPF経由で39のVDDAに入れる ということをするとドロップ電圧が無視できません


確実に動作させるコツは「確実な電源ライン」です


それとソフトウェア的なことですが
Cubeの出力するファイルにはSTM32F401RBTに使えるスタートアップコードがありません
とりあえずSTM32F401RETのバイナリを焼いています
またCubeが生成したLDファイルでは配置があまりよろしくないようです

この辺りは追々修正することを期待するか、自前でなんとかする必要があります



F401RBTやF429IITは結構扱いづらいです
QFP176なんて簡単に扱えないですし F401RBTは正直機能が… という感じがします

個人的にはSTM32F415RGTあたりが使いやすそうな気がします
QFP64なので簡単に扱えますし、内部ペリフェラルも豊富です

2014年8月27日水曜日

正方形のボケ

基本的に写真のボケは円形ですが、場合によっては非円形の場合があります

この画像の場合は正方形のボケになっています

このような写真を撮りたい場合、正方形のボケになるレンズを探してもいいのですが、面倒なので自分でフィルタを作ってみましょう

と言っても非常に簡単で
このように正方形の穴を開けた厚紙をレンズの前に置くだけです

こうすることによりボケは円形ではなく、切り抜いた穴の形になります

というかこれ、街灯などを星形に撮影する方法と全く同じです


この方法の問題として
1) レンズの前に不適合の絞りがあるためにケラレが大きい
2) 隅の方はレンズ内の絞りが支配的となるために狙った形にならない
という点があります
これはどちらも「周りに影響がある」ということなので、広角気味で撮影して中央部分をトリミングして使うことにより解決できます

それと別の問題として、絞りの形は画像に写しこむために、後から修正することができません
そのため後から水平補正を行うと四角形のボケが不自然な角度になる可能性があります

あと、当たり前ですがレンズの口径が減るのでF値が増えて暗くなるという影響があります
ただ、ボケの形をある程度自由に制御できるので、使い方によっては色々な表現ができると思います

2014年8月20日水曜日

STM32Cube

ここ数日、STM32Cubeを使ってコードを書いています

とりあえず手持ちのNucleoF401のコードですが、GUIで使用するペリフェラルを選択し、各パラメーターを設定して、出力されたソースファイルをビルドすればそのままバイナリを使うことができます

例えばSDIOのIPコアとFATFSのIPコアと、それらを連携させるコードを出力する場合は
SDIOで使用するハードを選択し
FATFSでSD Cardにチェックを入れる
たったこれだけで使用できます

一部のシリーズはGUIでクロックの供給を設定できます
(ただ、本当に設定するだけなので、どの組み合わせをするのがいいかという事は総当りで一覧を作るとかする必要があります)

まだできないこととして、makefileとリンカスクリプトは自前で用意する必要があるので、そのあたりは面倒です

CUIベースのGCCに対応して、リンカスクリプトも自動で書くように成ってくれれば相当使いやすいと思います
IPコアをユーザーが作成できるようになればmbedと同じくらい簡単に使えるようになると思います

UARTの送受信バッファが使いたい とか 細かいところでは色々と欲しい機能がありますが、現状でもかなり便利です

2014年8月18日月曜日

ズールータイム

標準時を示すための記号で、アルファベット1文字を使ったズールータイムと言われる表記があります
これはUTC±0hにアルファベットのZを割り当てているために、フォネティックコードのZからズールーと呼ばれているようです

タイムゾーンが違う地域を移動する、船舶や航空機などで使われることが多いようです

例えば、以下のURLに示す画像はF/A-18のHUDですが、左下に時計が表示されており、最後にZが表示されています
これは世界標準時±0時間でのタイムゾーンで時間を表示しているということです
https://en.wikipedia.org/wiki/File:F-18_HUD_gun_symbology.jpeg


このタイムゾーンのリストは米wikipediaに"List of military time zones"というページで紹介されています
https://en.wikipedia.org/wiki/List_of_military_time_zones

この表を引用するとこのような感じです
-12 Y
-11 X
-10 W
-9 V
-8 U
-7 T
-6 S
-5 R
-4 Q
-3 P
-2 O
-1 N
0 Z
1 A
2 B
3 C
4 D
5 E
6 F
7 G
8 H
9 I
10 K
11 L
12 M

Zを0とし、+1時間がA +2時間がB と言うのは直感的に理解できます
しかし-1時間はYではなくNが割り当てられています
またIの次はJではなくKが割り当てられています

/* 追記:2015/02/18 */
Iの次にJが使われていない理由は上記Wikipedia内に書いてありました
手書きでメモをした場合、iとjの見分けがつかない可能性があるため とのことです 言われてみれば納得の理由です
また、現在ではJは現地時の意味で使われることがあるそうです
/* 追記ここまで */

この表記方法はNathaniel Bowditch(ナサニエル ボーディッチ)という人が1800年頃に考案したようです
アルファベットの歴史とかその他諸々の歴史をよく知らないので、昔はこの並びが普通だったとか、そういう理由があるのかもしれませんが、使いづらいことに代わりは無いです

ただタイムゾーンを正確に表記することが目的なら"UTC+9"とか、正負記号1文字+数字2文字が一番確実ですね

2014年8月7日木曜日

F-35のコックピット

昨夜からF-35のコックピットの表示を調べています
ということで備忘録

まずF-35のコックピットと、以前のコックピットの大きな違いですが
F-35は目の前に大きなタッチ液晶があります
今までの戦闘機でもF/A-18E/Fなどはタッチ液晶を使っていましたが、それとは根本的に違います

F-35はパイロットが使いやすいように表示の大きさだとか場所を変更できます

この変更できるというのが非常に厄介で、出てくる画像で全てインターフェースが違うわけです
これアビオニクス担当の整備士は大変だよなぁ と思います 1機に専任の担当者がいるのかな…

しかし表示にはおおよそのパターンがあって

このような感じで分割できるようです
また、G-Nまでは個別に非表示にでき、例えばG,Hを非表示にしてCの領域を広くすることができます
また、G-Jを非表示にして、C-DとG-Jをまとめて大きな領域を作ることもできます

C-Nの表示内容は
・水平儀
・燃料
・兵装
・レーダー
・エンジン
・コンパス
等があり、それ以外にもたくさんあります
それぞれは上記画像の領域に自由に配置することができるようです
なので画像によってはG-N領域に水平儀が有ったり、別の画像ではC-Fにあったりします
レーダーはC-Fの領域に配置したり、C-D,G-Jをまとめて大きく表示したりできます

C-FとG-Nはただの大きさ違いではなく、表示方法にも若干の変更がされています
例えば水平儀はC-Fの領域には対気速度と高度等が表示されていますが、G-Nの領域には水平だけが表示されています
また、画像によって若干違うので、開発時期などにより違うのか、自分で選べるかのどちらでしょう


調べれば調べるほどどんどん違う表示が出てきます 頭痛くなってきました。。。
こりゃ値段も高くなるわけです。。。

2014年8月5日火曜日

WinにOpenCV環境を作る

1) OpenCVのダウンロード

プロジェクトサイト http://sourceforge.net/projects/opencvlibrary/ からEXEファイルをダウンロード
EXEを起動すると展開先のパスを聞かれるので適当な場所を指定する
ちなみに2014/08/05時点でバージョンは2.4.9だった

2) OpenCVの移動

OpenCVを適当な場所に移動する
今回はC:\直下にした
こんな感じになってる

3) PATHの設定

OSの環境変数にバイナリのパスを通す
今回の例では"C:\opencv\build\x86\vc10\bin"

4) プロジェクトの作成

VisualC++を起動してプロジェクトを作成する
種類はWin32コンソールにする

5) プロジェクトの設定

プロパティマネージャでMicrosoft.Cpp.Win32.userをダブルクリックする

プロパティページというダイアログで共通プロパティ->VC++ディレクトリを選択
インクルードディレクトリにopencv\build\includeのパスを
ライブラリディレクトリにopencv\build\x86\cv10\libのパスをそれぞれ設定する


あとはてきとーにソースコードを書いていけばいいらしい
VisualC++のディレクトリ配置が結構面倒なので、あんまり簡単にはいかない

Ubuntuのほうが簡単な気がする
でもUbuntuは使い慣れてないのと、アプリの関係で移行する気にはならない
Ubuntu入ったノートPCとか欲しいかも  でもどーせ買うならSurfacePro3のほうが楽しそう…

2014年8月3日日曜日

スミソニアン天体物理観測所星表

ちょっとやってみたいことがあって、恒星カタログが欲しくなったのでスミソニアン天体物理観測所星表というデータを落としてみました
NASAのWebサイトからダウンロードでき、展開後のデータは約50MBです

このデータは固定長文字列で表現されていて、フォーマットはWebサイトに公開されています
が、あんまり扱いやすいデータではないと思います

とりあえず構造体と、文字列から構造体へ変換する関数、それとそれに必要となる関数を作ったので、最後に置いておきます


スミソニアン天体物理観測所(SAO)星表は1行204文字の文字列で表され、それぞれのデータは\nで区切られます
つまり1つのデータは205バイトです
現在のカタログには258997個の恒星が登録されていて、データファイルの大きさは正確に53094385バイトです

※約26万個の中には削除フラグが付いているものがいくつかあります


1行205バイトのデータには52種の値が格納されており、その値は整数だったり、浮動小数点だったり、文字だったり、文字列だったりします

とりあえず簡単に使えそうなデータは赤緯、赤経、視等級くらいでしょうか
ただこのカタログにはどこにどれくらいの明るさの星がある ということしかわからず、星座の星を探す場合は何らかの方法で星座とそれに使われている恒星、恒星からSAO番号を関連付ける必要があります


このデータをどのように加工すれば欲しい情報が手に入るか… まだ不明なところも多いですが、もうちょっと色々調べてみようと思います


2014年7月28日月曜日

RAMを交換してみた

メインマシンのRAMを交換してみました
このマシンは組むときに最低構成で作って、後から更新していく という方針で組んだものです
RAMは8GBありましたが、ちょっと足りないなぁという感じだったので、思い切ってTranscendの16GBキット(2x8GB)を2組買ってみました
今回買ったもの(AA):Transcend JetRam デスクトップPC用増設メモリ PC3-12800(DDR3-1600) 16GB KIT(8GB×2) 永久保証 JM1600KLH-16GK

8GBからの増設ではあまり大きな変化はありません
ただアプリケーションの切り替えでHDDからの読み込みが発生しないので、さくさく切替できます

RAM増設後のメモリ使用量は10GB程度で、8GBに入らない2GB分はHDDに退避されます
そのためこの2GB分に入っているデータを使用するアプリケーションを開く際には
1) RAMのデータをHDDに退避
2) RAMの空いた領域に必要なデータをHDDから戻す
3) アプリケーションの処理を開始する
という動作が行われます
1と2が無駄な動作で、しかも非常に時間がかかります


とりあえずRAMは32GBになって20GBくらい余裕があるので、8GBだけRAMDISKにしてみました
上がHDD 下がRAMDISKです

シーケンシャルライトは43倍 シーケンシャルリードは0.9倍
512ランダムリードは120倍 512ライトは1.1倍
4kランダムリードは1000倍 4kライトは0.6倍
という感じで、ランダムリードは爆速 ライトはほとんど変わらず という結果です

データ処理の元データとかをRAMDISKに入れると早いかもしれません
といっても、等高線データとか40GBくらいあるのでメモリは64GBくらい無いと足りないですがw


正直、RAMDISKって微妙な気がしてきました
Chromeのキャッシュでも突っ込んでおこうかと思います