ようやくATコマンドの送受信に成功

ここまで長かったけれど、ようやく、ATコマンドが送受信できるようになりました。
長かった、といっても、前回のblogからちっともいじっていなかったわけだけど。
CommMgrのおかげで、受信の方もばっちり。
まだ実験段階なので、各ATコマンドの発信後に1秒のスリープを入れて送信しているのだけれど、いずれ、「OK」の応答をちゃんと見るようにしなくては。
gps03at
まあ、これでもとりあえず、郵便番号を入手できるから、いいかな。

シリアル通信構想

シリアル通信部の構想がおおよそ固まってきた。
サンプルのシリアル通信クラスは、やはりスレッドを作って受信をやっているようで、受信キューに溜まったら読み込みをしてくれる、様子。
ただし、受信用のメソッドが用意されていないので、どうしてかな?と思ったら、受信したデータを処理するルーチンは実装されていなかった。
これは、ここは自作しなさいよ、ということでしょうな。
ということで、ここに、受信バッファを用意して、受信されてきたものを順次追加していくようにしよう。
バッファはとりあえず256バイト程度の固定値で。
使い方は限定しているから、そんなに無茶なデータも流れないし。
そして、新しく読み込み用のメソッドを追加して、そのバッファからデータを吸い出せるようにする。
読み出す度に、バッファの方は読み出された分を消去して、残りの分を前の方へ詰めていくことにする。
一つ気をつけなくてはいけないのは、1つのバッファを2つ以上のタスクが使うことになるので、セマフォをちゃんと設定してやらないといけないということか。
バッファに書き込もうとするヤツと、バッファを移動させようとするヤツが同時に動いたら、おかしなことになるものね。しかも、その間に受信した分は取りこぼす、とかいうことのないように。
さて、Win32 APIにセマフォの制御はあるのかな?

W-ZERO3 GPS化ソフトの方、ちょっと作業から遠ざかっていたけれど、久しぶりに再開。
Win32用のCommライブラリのソースを見つけたので、それをダウンロードしてきて読んでみて、さらにビルドもしてみたけれど、これ、受信バッファを見たり、イベントを待ったりしているわけではないので、最初に作ったプログラムと変わらない気がする。
次に、24termのソースを呼んでみた。
最初、W-ZERO3用のコードを読んだのだけれど、VC++6用だったので、eVCで読み込めず、解析が難しかった。
ので、Pocket PC用の古いコードを拝見したところ、これはスレッドを使ってイベントを待っていることがわかった。ターミナルソフトだから、受信は完全に分けちゃった方がいいのだね。
しかし、送信−応答がペアになっている通信の場合は、こういうスレッドプログラムにすると、ややこしくなりそうな気がする。一度、状態遷移図とか、まじめに書いてから作成したほうがいいな。
仕事で扱ってるコードは、そういうのを作ってなさそうで困ってるから(苦笑)
今読んでいるのは、 http://www.hidori.jp さんに掲載されていたシリアル通信のサンプルコード。
http://www.users.gr.jp/blogs/hidori/archive/2004/03/23/1734.aspx
WinCEに対応したクラスになっていて、スレッドの作成も中でやってくれている様子。
これなら、比較的簡単に使えるかな?と期待しているところ。

グループボックスは使えない?

ダイアログボックスにラジオボタンを作っているところ。
緯度経度の出力を、TOKYO97かWGS84にするか、という選択肢をつけようとした。
まあ、最初はTOKYO97だけの実装になると思うけど。
「Beginning Visual C++ 6」によると、ラジオボタンを含むときには、「グループボックス」というコントロールを使う、というようなことが書いてあった。
そして、eVCにもグループボックスがある。
ラジオボタンをグループボックスで囲んでダイアログを作って、ビルドして、実機で実行したところ、正しく表示されない。消えてしまうのだ。
これは、おそらく、1つのダイアログではラジオボタンは1組しか使えない、ということなのかな、とも思った。
まあ、いいか。
ラジオ化するのはそのぐらいだし、ほかのコントロールでも代用できるし。

ダイアログボックスのメニューを消す

今日は設定用のダイアログボックスを作ってみよう、と思った。
「Beginning Visual C++ 6」という英語の分厚い本を引っ張り出してきて、ダイアログボックスのあたりとかを読んでいるのだけれど、同じようにしてもリンクが通らない。VC6とeVCとでは、扱いが違うのか?
それとは別に、「このソフトウェアについて」のダイアログが出ているときに、ソフトキーが表示されているのがいやだなあ、と思った。
これを消すために、何かInactiveとかEnableとかHideとか何かのコントロールを使わなくてはならないのだろう、と思っていたのだけれど、どうもそうではなく、消すだけなら簡単らしい。
WM_INITDIALOG メッセージの処理時に、SHINITDLGINFO のフラグとして、

SHINITDLGINFO shidi;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU;

とする。SHIDIF_EMPTYMENUが追加の部分。
これで、ソフトキーが消えてくれる。
AboutDialog
うんうん、こうでなくてはな。

コモンダイアログのテスト

とりあえず、仮アプリケーション名を「W-ZERO3 GPS」としてみた。
実際は、かなり精度の悪いGPSになりそうで、トラッキングツールとしてもまったく役に立たなさそうだが。
職場で「ちず丸 for Willcom」を使ってみたら、500mぐらい離れた位置になっていたし。
ちなみに、うちからだと250mぐらいずれている。
どういう計算をしているんだろうかなあ?
さて、今日は「コモンダイアログ」に関するテスト。
ログを保存する先を指定するところを先に作ってしまおうと。
ザウルスだと、その手のダイアログがなかったので、結局、手入力だったのだけれど、さすがWindowsというかMFCというか、コモンダイアログを呼ぶだけでファイルを書くところを指定できるようだ。開発者さん楽々。
しかし、やっぱりどうしたらいいのかわからないので、リファレンスとして、Windows CE Fanの開発者向け情報にあったサンプルコードを参考にしてみた。
http://www.wince.ne.jp/frame.asp?/review/kappy/tips4.htm
ここでは、「GetOpenFileName」という関数を使っていた。
これをそのまま使って作ってやると、エクスプローラのファイルダイアログが開いて、ファイルを選択できるようにはなるのだけれど、保存先を新しく作ることができない。
関数の名前からして、「GetSaveFileName」ってのもあるんじゃないの?と補完で検索してみたら、あっさりとあった。しかも、ほとんどそのまま使えた。
ただし、フィルタだけ修正する必要がある。
TCHAR型や、TEXTは不慣れなのだけれど、
filter[]=TEXT(“JPEG\0*.JPG\0\0”);
という表記からして、「\0」を区切り文字にして、前がダイアログボックスに現れる表記(「JPEGファイル」など)、後ろがワイルドカードの様子。GetSaveFileNameの場合は、後者の拡張子が反映される様子。
最後に、この得られた結果を表示するように、「Hello World」を表示している部分をそのままいただいて実装してみた。
GetSaveFileName
今日はもうひとつ、メニューボタンの非表示にも挑戦しようとした。
しかし、まったくわからない。
DISABLEとかENABLEとかを設定するところがどこかにあるとは思うのだが、あるのは、メニューのIDだけ。これだけでどうやって非表示とかにすればいいのやら?

W-ZERO3向けソフト開発開始

eMbedded Visual C++ 4.0 (以下、eVC++)をインストールして、W-ZERO3用のソフト開発に着手し始めた。
本職は、自称・ソフトウェアアーキテクトということにしているのだが、このごろはすっかりデバッガだったり、ポーターだったり、あんまり自分でコードを書くことはしていない今日この頃。
さらには、作るアプリケーションはGUIを使わないので、その手のプログラムもかなり久しぶり。
実は、数年前にVisual C++ 6.0で仕事をしたことがほんのちょっとだけあるのだが、すっかり忘れてるし。
本格的にGUIプログラミングをしたのって、「ざうちゃっ」が最後かしら?
前置きは長くなったけれど、まずは、MFCの作法とかを学んでいかないといかんなあ、と思うのだった。
まず、eVC++を起動して、最初にアプリケーションの雛形を選ぶ。
いくつか試したところでは、Pocket PC 2003用の「Hello World」アプリがよさそうだった。
これをビルドして、W-ZERO3で動かしてみたところ、「ソフトキー1」にきちんとメニューが割り当ててあった。
そう、Pocket PC用のソフトをインストールしても、多くはこのキーに対応していなかったりして、対応するのは難しいのだろうか?と思っていたのだ。探し方も見当もつかなかったし。
しかし、あっさりと、「Menubar」のリソースの中にあった。これはありがたい。
「IDM_MAIN_COMMAND1」 というのがそのキーイベントのIDで、左側の「ソフトキー1」に相当するらしい。
同じく、「IDM_MAIN_COMMAND2」というのが右側の「ソフトキー2」に相当する。
キーがわかれば、次は、そのキーイベント、ここではメニューバーなので、メニューイベントになるが、それを処理している部分を探して、お好みの処理を入れてあげればいい。
Pocket PCでは、右上の「×」ボタンを押しても、ウィンドウを閉じるだけでプロセスは動いたままになってしまって、終了させるのが面倒くさい。なので、メニューに「完全に終了する」という処理を入れたかった。
これは、「WndProc」というコールバック関数で処理されていた。
ちょうど、ヘルプダイアログを出すメニューイベントが記述されていたので、同じところにcase文を使って記述しておいた。
プログラムを終了する方法は実はよくわからないのだが、WM_DESTORYメッセージを自分のウィンドウハンドラに投げてやればいい、のかな?と思って、その処理を入れてみた。
SendMessage (hWnd, WM_DESTROY, 0, 0);
というのは、同じように、OKボタンが押されたときの処理で、WM_CLOSEメッセージを投げていたからだ。
で、実際、WM_DESTROYメッセージを投げたら、アプリケーションは完全に終了してくれた。
ま、これでいいか。
あとは、おまけで、W-ZERO3の高解像度(Hi Resolution)対応するためのリソースも追加した。
これは、Pocket Streets 2002のVGA化でも使ったのと同じ手法で、「CEUX」というリソースを追加して、そこに適切な値を設定してやると、アプリケーションがVGA対応であると認識するのだそうだ。
その方法については、「Windows Mobile 2003 Second Edition Developer Resources」に含まれるドキュメント「DPI_Awareness.doc」に書いてあった。
とりあえず、何もできないけれど、「Hello World」が表示されるだけのアプリが完成。
HELLOAPP
さて、次は、「Hello World」を書き換えるところかなあ。
追伸: せっかくなので、W-ZERO3のカテゴリを作ってみた。