SISO-LAB不定期TOPIC Oct.2003


2003/10/30

プログラムに疲れた〜そんなときは…スプラッシュなんてどう?

Windows側のテストプログラムをせこせこと作っていますが…あ〜疲れた。なかなかめんどくさいです。だんだんパワー切れになってきました。そんなときは、気分転換にお遊びに走りましょう。じゃ〜ん。「Splash Window」です。アプリを起動するときに、「ロゴ」が出てから本Windowが開くやつがあるじゃないですか。あれです、あれ。邪魔な時が多いんですが、結構、派手めでいいですよね。これでもいちおう「Biped Robot Entertainer」のハシクレ、機能も大事だが、こういうところも大事(と自己弁護)。

今、VC++を使ってWindows側のソフトを作っています(本当はなんでもよかったんだけど、以前、使ってたことがあったので)。Splash Windowつけるには「SPLASH Windowコントロール」とやらがあって、それを使うのが簡単らしいんですけど、その手のやつってActive Xが多いのでなんとなく気が引けまして、ちょちょっと作ってみました。使うのが難しいという意味ではなく、知らない間に、いろんなモジュール(DLL)が必要になっていると嫌なんで。もし、やり方が間違っていたら、ご指南ください。以下、ダイアログベースのアプリケーションに実装したやり方を紹介します。

まずはビットマップファイルの作成
20031030P00.GIF - 2,672BYTESまずはBitmapファイルを作ります。ペイントブラシでもなんでもいいです。ただし、保存するときに「16色」または「256色」のビットマップを選択してください。ファイルサイズ的には「16色」の方が、だんぜんパフォーマンスいいです。ここで懲りすぎて、バカでかいビットマップファイルを作ってしまうと、アプリケーションの起動がさらに遅くなるので、ほどほどにしましょう。作ったファイルは、追加先のVC++のプロジェクト内に「res」というフォルダがありますので、ここにいれておきましょう。とりあえず、左のようなものを作ってみました。うっ、どっかで見たようなデザイン…。まあいいや。ホームページにアップする関係上、「GIF」ファイルにしていますが、VC++に入れるときは必ず「BMP」にしてください。

ビットマップファイルをVC++のプロジェクトに追加
20031030P02.GIF - 3,836BYTESVC++の「Resouce View」にて、新しく作成したビットマップファイルを追加します。追加するには、「Resouce View」の「…リソース」と書いてあるところで、マウス右クリックしてポップアップメニューを出し、「インポート」を選択して下さい。これで「リソースのインポート」という、ファイル選択ダイアログが開きますので、「ファイルの種類」を「すべてのファイル(*.*)」にしてください。これで先ほど作ったビットマップファイルが表示されます。ビットマップファイルを選択して「インポート」を押してください。これでOKです。IDは適当に好きにつけておいていいです。

スプラッシュウィンドウをダイアログで作成
スプラッシュウィンドウとして表示するウィンドウを、お手軽にダイアログで作ります。「Resource View」から新しくダイアログを作ります。IDは何でもいいんですが、説明の都合上、「IDD_SPLASH」しておきます。ビットマップより、大きめにしておいてください。わからなければ、とにかく大きくしておいてください。「ダイアログプロパティ」の「境界線」を「しない」にします。「システムメニュー」もOFFします。そうすると、すごくのっぺりんとしたダイアログボックスができます。「OK」ボタンと「キャンセル」ボタンもとっちゃいましょう。
つぎに、ダイアログのツールバーから「ピクチャー」を選んで貼り付けます。「ピクチャープロパティ」を開いて「ビットマップ」にしてください。そうすると「イメージ」が選べるようになりますので、先ほど追加したビットマップファイルのIDを選択して下さい。これでぼぼーんとビットマップサイズになります。あとはダイアログボックスのサイズを適当に調整して、見栄えよくしてくださいね。

プログラムへの実装
先にも書きましたが、今回のお話は「ダイアログベース」が基本です。さて、メインのダイアログのクラスがあると思います。プロジェクトを新規作成したときに、自動的にできたやつです。これのメッセージハンドル関数で「OnInitDialog()」というのがあります。ここに以下のようなソースコードを書いてください。いろいろやり方はあるとは思いますが、今回は、こんな感じで実装してみました。

    HWND hWndSplash = ::CreateDialog( m_pcTerminalApp->m_hInstance,
                                      MAKEINTRESOURCE(IDD_SPLASH),
                                      m_hWnd, NULL ); 
    if( hWndSplash ){
        CWnd    cWnd;
        cWnd.Attach( hWndSplash );  //  CWndの便利機能を使いたいため、Splash WindowをAttach
        cWnd.CenterWindow();        //  Splash Windowを画面の中央に移動(便利〜)
        cWnd.ShowWindow( SW_SHOW ); //  やっとこさこれで表示
        cWnd.UpdateWindow();        //  おまじないおまじない
        cWnd.Detach();              //  もうCWndの機能は使わないので「さよなら〜」する。
        ::Sleep( 500 );             //  このプログラムの初期化はあまりにも早く終わってしまい、
                                    //  せっかくのきれいなSplash Windowがすぐに消えてしまう
                                    //  ので、ちょっと(500msec)「待ち」する。
        
        //    このあたりにいろいろ初期化書いてください。

        ::DestroyWindow( hWndSplash );          //    Splash Windowの破棄 
    }
      

はい、これでOKです。起動すると、おぉ、いいじゃない。「あぷりけ〜しょん」って感じです。みなさんが作られているプログラムにもおひとついかがですか?

 

2003/10/28

やっぱり『ぷるぷる』が気になる〜…えぇい、ならば!

20031028P00.JPG - 15,524BYTESどもです。やっぱ「ぷるぷる」が気になる今日この頃ですが、みなさまいかがお過ごしでしょうか?

唐突ですいません。なにが「ぷるぷる」かと言うと、サーボです。前回のTOPICでも書きましたが、いろいろいじってみたものの、タイマVでR/C受信機のパルスカウントをしているとどうしても「ぶるるん」としてしまいます。試しにタイマVを止めると、しゃきっとなります。角度によっては出なかったりもするのですが、単に、タイマVとぶつかっていないだけなんでしょう。ああ、悔しい。そんなわけで、さらなるチャレンジです。

左の写真は、H8/3664とR/C受信機を無理やり載っけられて実験台になっているG-Tuneです。PCの画面の方は、R/C受信機信号テストモニタプログラムの画面です。

R/C受信機信号の取り込みプログラム
ぶっちゃけた話で、ソースコードを載せてしまうと、以下のようなソースコードをタイマVの割り込みルーチンに書いています(お恥ずかしい)。このコードが4セット(つまり4chのR/C受信機信号に対応)書いてあります。

    if( IO.PDRB.BYTE & 0x10 )	abCountWrk[0]++;
    else{
        if( abCountWrk[0] ){
            abCountDtc[0] = abCountWrk[0];
            abCountWrk[0] = 0;
        }
    }

これは、ポートBを使用して、R/C受信機からの信号を取り込むようになっており、0.128msecの割り込みによって起動されたこのプログラムが、信号が立っていたらカウントアップし、信号が落ちたらabCountWrk[0]からabCountDtc[0]に移す、というプログラムです。メイン側からabCountDtcをチェックすると、カウント数によってプロポのスティック位置がわかるという仕組みです。だいたい9〜15カウントぐらいで変化します。

これが、結構、時間食うようでして…(あたりまえか)、タイマWで作っているサーボ信号のON/OFFのタイミングを狂わせているようです。

それにしても、制御状態でもシリアル通信できるようなプログラムにしたので、シリアル通信ガンガンやってもサーボ制御信号に影響無し…でも、たかだかプロポの信号のON/OFFの時間カウントするだけでぷるぷる。なんだか理不尽な感じです(笑)。

オトコの浪漫・R/C受信機信号取り込み編
ならば、H8/3664で突き進むという、オトコの浪漫?(よく考えるとなんでロマンなんだろう???)のため、ここはひとつソフトで解決しようと思います(先日、バーニング宮田さんの掲示板に、「H8/3664で行きます」と書いたら、「ロマン」と言って頂いて、妙に気に入っているSISOです)。

さて、なぜタイマVの割り込みによってサーボ制御信号が乱れるか?それは「タイマVの割り込み処理がサーボ制御信号に影響を与える程、長い」からです。ならば短くすればよいのです。試しにオーバーフローフラグのクリアだけするプログラムを書いてみたら、ほとんど「ぷるぷる」しないことが確認できました。ここでアセンブラとか使えたらかっこいいんですが、残念ながら、まだどうやるのかわかりません。そのうち勉強すると思いますけど、今はまだです。そこで、こんなコードにしてみました。

    if( IO.PDRB.BYTE & 0x10 )	abCountWrk[0]++;

うーむ。とてもシンプル。これが4つ書いてあるだけです。これだと、気になっていた「ぷるぷる」も、ほとんど気になりません。 よしよし。いい感じです。読み取りとクリアはタイマWを併用することで実装しました。で、冒頭の実験中写真になります。あ〜よかったよかった。これにてステップ2クリア?(いったい、いくつまであるんだろう?次のROBO-ONE間に合うんだろうか?)

 

2003/10/26

R/C受信機信号取り込みOK

SISOにとっては「進みそうで進まない魔の週末」ですが、いかがお過ごしでしょうか?今週も進んだような進んでないような…。ONOさんの「ONO電脳壁新聞」で、H8/3664のみによるサーボ制御の話を、掲示板にてさせていただいてたんですが、OMNIHEADの前田さんからも情報がありまして、びっくりな週末でした。今日は、そのネタです。

サーボのプルプルとR/C受信機信号の取り込み
サーボ制御、結構、うまくいってるようなことを以前書いたんですが、実はR/C受信機信号の取り込みプログラムがバグってて、昨日、ちゃんと動くようになったら…きました。サーボぷるぷる。かなりひどいです。数度ぐらい平気でプルプルします。こわ〜。

現在のプログラムは、タイマWでサーボ信号作って、タイマWのGRA...GRDでクリアするようなプログラムになっています。GRA...GRDのぶつかりによるサーボ信号のブレは、「無視してもいいかなぁ」ぐらいのもんだったんですが、タイマAを使った方のプログラムがデバッグの結果、結構立派(処理が多いということ)になっちゃいまして「あらら〜」なもんです。

そんなわけで、タイマAでやっていた処理をタイマVに処理を移しました。これはこれで不安だったんですが、結果としては割とよくなりましたが、まだ結構ぷるぷるはするので、対策要です。

割り込みの優先度
なんでタイマVに移したかといいますと…割り込みには優先度というのがあって、タイマWよりタイマAの方が優先度が高いんです。これは「ハードウェアマニュアル」を読むと書いてあるんですが、よく使うものですと、IRQ→タイマA→タイマW→タイマV→SCI3→I2Cの順に割り込み優先度があると書いてあります。優先度っていうのは、簡単に言えば、同時に割り込みが発生した場合、どれから実行されるかというものです。SH7047Fは、これを変更することができたんですが、H8/3664はできないようです。ああ、こういうところとかって、SH7047Fってやっぱさすが〜って感じですね。これで電気食わなかったら絶対採用なんだけどなぁ〜。

で、タイマAで行っていた処理を、タイマVに移すことにより、サーボ制御信号を作っているタイマWの動作タイミングに影響を与えない(つまりサーボ制御信号がプルプルしない)ようにしました。そのかわり、タイマVの方の動作タイミングがタイマWの動作に影響を受けることになります。

現在作っているプログラムですと、タイマWの処理は軽めですので、R/C受信機信号読み取り(0.128msecで割り込み)は、誤差の範囲でいけそうです。

動作状態
なんででしょう?本当は、ここで動画を撮ってアップしたかったんですが…サーバに上げるときにエラーが出てしまいます。うーん、サーバの仕様か?そろそろちゃんとホームページスペース、どっかに取ろうかなぁ。

R/C受信機のパルス周期
ついでなんで、GWR-4Pの制御周期を測ってみました。よく、R/C受信機の制御パルスは16〜20msecといわれているんですけど、実際、自分の持っているものはどんなもんかと思いまして。きっとオシロスコープとやらがあれば、すぐにできるんでしょうけど、SH7047Fでプログラム書いて計測です(笑)。結果、16msecでした。結構、速いのね。でも、うちのサーボ(HPX-PARK BB)って、制御周期を15msecにするとちょっと「プルプル」気味になるんですよ。1msecが余裕があるとかないとか、どう言っていいのかはわからないんですが、こんな感じです。

 

ところで、風邪気味です。うぅ、寒い。みなさんも気をつけましょう。

 

2003/10/23

最適化オプションをつけてコンパイル

なんか、仕事が疲れる今日この頃…今日は出張でしたが、だいぶ寒くなりましたね〜。帰りのバス待ちでブルブル震えていました。

最適化オプションをつけてコンパイルしてみたら…
先日、コンパイラの「最適化オプション」の話を教えていただきまして(SH7047Fの話だったんですが)、H8/3664ではどうかな?という実験をしてみました。先日のサーボ制御したプログラムに、最適化オプションをつけてみました。「最適化レベル」をまずはいきなり?レベル2に…おお、プログラムサイズが小さくなりました。7.5kByteあったプログラムが、あぁっというまに5.4kByteになりました。これはびっくり。ご機嫌な気分でROM焼きしたんですが…動きが変。割り込み処理をスタートさせると暴走?しているような感じです。じゃあレベル1にしたらどう?ってやってみたら、今度は動くんですが、ちょっとだけおかしい。変数初期化をするとこが、できていないような感じ…。やっぱり割り込みまわりです。プログラムサイズは、ちょっとだけレベル2より大きいぐらいです。

最適化って、具体的にどのようなところまでやっているか?っていうのは、よくわかんないんですが、割り込みとメインプログラムで共有しているようなデータに関しては、いろいろ起きるような気がします。というわけで、いつもの「ぼ〜らてぃるぅ(volatile)」。両側からアクセスする変数はこれで宣言してみました。レベル1ではばっちり動くようになったのですが、レベル2ではよろしくないです。プログラムサイズ的にはあまり変わらないので、当面、レベル1にしておこうと思います。ありがたや〜。

メモリのアライメント
「奇数番地からWORDデータは配置できない」、との情報を頂きまして、H8/3664のハードウェアマニュアルを調べてみたところ、ありましたありました。「2.3.2 メモリ上のデータ形式」に、「ワードデータ」と「ロングワードデータ」は偶数番地から始まるデータに限定されるとあります。ああ、これですっきりしました。すっきりしたところで、奇数番地からWORDデータが並んでくれるわけではないですが、すがすがしい気分でプログラムが組めるってもんです。

でも、今日はなんだか疲れたので、寝ます〜。

 

2003/10/21

H8/3664にサーボを12個つないでみました。

20031021P00.JPG - 24,257BYTESソフトウェア進捗状況
超基本部分ですが、H8/3664でのサーボドライブ+パソコン通信ができましたので、サーボをつないでみました。とはいえ、ストックでフリーのサーボをたくさん持っているわけではないので、そのまま現行G-Tuneに載せてみました。というわけで12個です。スペックとしては16個までつなげれるようにしてあるんですが、手持ちが無くて・・・。つなげちゃうと「お〜できたんか?」と誤解されるかも知れませんが、完成とは全然関係なく、単なるマイルストーン記念式典みたいなもんです。テストボードを作るときに、現行G-Tuneにインターフェイスを合わせておいたのが役に立ちます。ちょっと不恰好で、思いっきり背中に張り付いていますが、そのままコネクタオン(ボルトオンをもじってみました)で取り付け完了です。プログラムは、サーボ制御、シリアル通信、プロポ信号取り込み(これはコードだけど割り込みちゃんと使っている)の豪華3本立てです。

結果は、「おっけ〜」です。ちゃんとパソコンから指示値を入力したら、そのとおりに動いてくれました。ぐぅれいとぉ。う〜ん、ここまで苦労しました。これで基礎要素部分はOKって感じです。

でも、サーボの停止位置によっては「ぷるぷる」します。なぜでしょう?想像では、サーボ制御に使っているタイマWの割り込みより、プロポ信号取り込みに使っているタイマVの方が優先度が高い(すいません、間違い。ということは他の原因 2003/10/22修正)ので、これがぶつかってサーボ信号OFFのタイミングが少しずれるパルス幅があるのかな〜?と思っています。だんだんわかってくるとは思いますけど。それほど深刻でもないような気がするので、よしとします。いーのかなー。

ま〜、これからがまた大変なんですが、とりあえず第1ステップOKって感じですね。

データ構造見直し開始
パソコン通信プログラムを作っていて、また見つけたんですが、H8/3664+GDLでコンパイルすると、バイト境界(構造体メンバのアライメント)が2バイトなんですね〜。きっと何かコンパイルオプションがあるのかもしれませんが、基本的にあまりCPUにとって得意なことではないような気もするので、追求はしません。以下に、簡単に説明つけます。

      struct {
          _BYTE bTest1;
          _WORD wTest2;
      } ST;
      

という構造体を宣言したとき、以下のようにメモリに配置されます。

アドレス データ
0xF000 bTest
0xF001 ???
0xF002 wTest2の上位バイト
0xF003 wTest2の下位バイト

「???」はなんでしょう?使われない領域です。VC++ですと「構造体メンバのアライメント」ってやつです。VC++ですと「1,2,4,8,16」から選べるんですけど、GDLの方はよくわからないです。でもまあ、CPUが16Bitということで、あまり得意じゃないだろうし、構造体の並べ方を考えれば無駄なく使えるので、データの順番を見直すことでクリアとします。

誘惑に負けて…
開いてしまったロボコンマガジン。煙が出てきておじいさんに…ということは無かった。とはいえ、折り目をつけたりしないように、そ〜っと開いています。なかなか豪華な本です。ちょっとびっくりしました。OMNIHEADもありますし、JinSatoさんの記事も載っています。そっか〜、JinSatoさんは本で執筆もされていたんだ〜。おっと、手が汗ばんできた。すぐに本を手から離して手を拭き拭き。少しでもコンディションをキープせねば。

 

2003/10/20

ロボコンマガジン初購入

本日、初めてロボコンマガジン購入。というのも、第5回ROBO-ONEでは、踏絵のごとく、このロボコンマガジンをロボットで昇降しなければならないため、チェックのためです。いや、まだロボットはぜんぜんできていないんですが、設計参考用です。まず、売っている店を探しまして、2件目でヒットしました。そして、2冊置いてあったうちの、人が触っていなさそうな方を選んで買ってきました。

買ってきたロボコンマガジンですが、厚みなどに影響がないよう、読みたいのを我慢して丁重に保管してあります。さて、厚さの計測ですが、閉じ側8.5mm、開き側8.6mm…ということで、0.1mmの差があることがわかりました。ああ、読みたい。でも表面が汚れたりとかしてコンディションが変わったら、後でテストするのに影響があるかも…そう思うと開くことすらできません。ああ、でも、今月号はA-DOが表紙だし、OMNIHEADの特集記事もあるようですし。うわぁぁぁ(自己崩壊)。

 

2003/10/19

なぜか週末は作業が進まない…(先週もそうだった)

今週末は地元がお祭りでして、妻とともにパレードとか見に行ってきました。めったにいかなかったんだけど、大道芸やってたりして結構おもしろかったです。のぞいてみるとおもしろいもんですね〜。

20031019P00.JPG - 14,107BYTESシリアルデータ通信・その後
さて、WindowsパソコンとH8/3664の通信プログラムですが、結局、ベタベタと、WORDデータの前後をひっくり返すプログラムを書いて、とりあえず、通信できるようなりました。まだ、制御らしい制御はやっていないんですが、ぼちぼちっとサーボ位置をパソコンから、というところまでたどり着く予定です。

う、うぅぅ、画面ダサいです。テストプログラムだからよしということで…。まじにWindowsプログラミング、ほとんど忘れているんで、結構、時間かかっています。でも、ここ数日で、だいぶ思い出してきたかな。きっと、これからスピードアップするでしょう(たぶん)。

 

2003/10/16

SH7047Fでも10M回ループしてみました。

SH7047F
先日、nisiken2002さんという方の「普通の会社員の日記」というホームページで、SH7047Fについていろいろ書かれていたのを見つけまして、うんうん、なるほど〜と思ってしまいました(nisiken2002さんの文章はとても朗らか?な感じがとてもぐーで、よく見ているホームページの1つです)。というのも、自分がSH7047Fを使ったときは、何もかも初めてでしたんで、「こういうもんなんだぁ、ふ〜ん」って感じで使ってまして、逆に何も感じなかったというか。それがすべてでしたから。

んで、そういえば…と思って、H8/3664のパフォーマンスチェックをしたときに使ったルーチンをSH7047Fで走らせてみました。SRAM上でプログラムを走らせてますので、CPUそのものの評価にはなりませんが、ボードの評価の足しにはなると思います。プログラムはいつものこれです。GDLでコンパイルしてます。

volatile unsigned long ulBCnt;
for( ulBCnt = 0; ulBCnt < 10000000; ulBCnt++ );

う〜む。25秒ぐらいした。H8/3664でやったときは32秒ぐらいでしたので、意外に遅いというの正直な感想です。もちろん、この評価はもっとも単純な部分なんで、これだけで評価するのはなんなんですが、やっぱ、SRAMが8ビットバスで接続されているのが原因なんでしょうか?森永さんが「外部RAMは飾りだと思いましょう。」と言われるのがわかります。きっとROMに焼いたら倍速以上なんだろうなぁって思います。でも怖くてやってません(^_^; もしチャンスがあれば、いろいろなCPUボードでやってみたいですが…最近焦り気味です。ソフトはなかなか進んでないですし、メカの方なんてアイデアだけで図面引いてないですし…あせあせあせ。おっと、かくのは冷や汗じゃなくて、プログラムと図面でした。お後がよろしいようで。とほほ。

シリアルデータ通信
あれから(2003/10/14不定期TOPIC)、うまいやり方が無いものかいろいろ考えていたんですが…今のところ、いいアイデアがありません。やっぱ、ベタベタ書くしかないんでしょうか。うん。きっとベタベタと書くしかないに違いない。時間も無いことだし、こんなときは黙って指を動かすことにしようっと。

 

2003/10/14

ぐ、くぅぅ、通信したけどデータの順番が違うゾ。

インテルVSモトローラ問題、我が家で復活?
通信プログラムなんて久々に作ったせいか、やっているうちに、むか〜し昔、苦労したこと、いろいろ思い出します。今日は、インテルVSモトローラ(というわけではないんですが、代表どころで)な部分を思い出してしまいました。そして、現在、気分転換にホームページ書いていたりします。

unsinged short usTest = 0x1234;

これ、C言語で、符号無し2バイト長変数「usTest」というのを宣言し、「0x1234」(16進数です)を代入しているものです。今回は、とてもC言語な表記ですいません。これを、1バイトずつアクセスすると、どうなるかご存知ですか?こんなソースコードでアクセスできます。

unsigned char* pbTest;
pbTest = (unsigned char*)&usTest;
printf( "%02X %02X\n", pbTest[0], pbTest[1] );

「pbTest」というのが、1バイトづつアクセスするための仕掛けで、「usTest」の「0x12」と「0x34」の部分にアクセスすることができます。さて、このプログラムをVC++等でコンパイルしてWindows上で実行すると、どんな表示が出るでしょう?答えは、「34 12」です。お、ひっくり返ってますね。これをGDLとかでコンパイルしてH8/3664で動作させるとどうなるでしょう?「12 34」です。あらら。どうしてでしょう?ちなみに、モトローラ系のCPUを載せたパソコンで実行させても「12 34」になると思います。

これは、CPUによって、複数バイトにまたがる数値データをどういう順番でメモリに書き込むかが違うためです。インテル系は桁の小さい方から書き込み、モトローラ系は桁の大きい方から書き込みます。Z80系はインテル系です。これをインテル系とかモトローラ系と呼んでいいのかどうかは定かではないんですが、あ〜、懐かしい。できればお会いしたくなかった。というのが本音です(苦笑)。

さて、どうしてこのような問題にぶつかったんでしょう…今回、プログラムの小サイズ化目的で、シリアル通信で流したデータを解析するルーチンも小さくなるように工夫しようと思いまして、メモリアクセスイメージの、ちょっとベタベタなデータの流し方をしてみたんです。そしたら見事、ヒット!すっかりバイトの順番なんで忘れていましたんで、かなりショックです。

今回はシステムにも名前をつけてみよっと
今回は、端末ソフトも作るということで、ちょっとしたシステムっぽくなりますので、一応、名前を考えてみることにしました。名前があると、やっぱ気分が違うかなぁと思いまして。そんなわけで、でで〜ん。発表です。その名も「SIPHA」。「SISO JUNK STUDIO (LAB) INTELLIGENT PUPPET HANDLING ARCHITECTURE」の略です。なんか、どっかで聞いたような感じとか、英語が少々無理っぽい気もしますが、語感がいい感じなので、気にせずに行きたいと思います。うぅ、ほんとに「INTELLIGENT」になるかどうか、すごく心配。いやいや、名前に負けないよう、頑張ります。

 

2003/10/13

あっという間に3連休終了。端末ソフトなかなかはかどらず。

いや〜3連休
なんか、買い物行ったり、ごそごそ家事関係やっていたら終わってしまった三連休。家族がいると、やっぱ普通に過ごすのも楽しくて、ついつい。とほほ。そんなわけで、シリアル通信で、Windowsパソコンとマイコンが通信するところまではできたんですが、そっからがまだまだって感じです。シリアル通信そのものは、思いのほか簡単にできたんですが、イージーなミスで悩むこと丸っと一日。

VC++を触っているとよくある話なんですが、デバッグモードで動いていたプログラムが、リリースモードにしたとたんに動かなくなるってやつです。変数初期化の状態が異なっていたり、最適化がかかったりして、動作結果が変わることがあります。そう思い込んで、テスト用のサンプルやらなんやら作ってたんですが…テストサンプルでやると動きます。も、もしや・・・、いやそういえば…あ〜!!!

原因は、ぜ〜んぜん関係なくて、プログラムが読む込む初期化ファイルを、実行ファイルと同じフォルダに作るようにしてたんですが、これが当然、デバッグモードで動作するときとリリースモードで動作するときではフォルダが違いまして、定義ファイルが読めてなくて、しかも読めないときはデフォルトデータを作るようなコードにしていましたんで、何気にそれらしく動いてしまっていまして。あ〜あ。

というわけで、また明日からがんばろうっと。

 

2003/10/11

専用端末

Windowsでのソフト開発
ふぅ、とまずは一息。ロボット側のソフト構想ができてきたところで、今度はWindows。今回は、Firmwareの方にはUser Interfaceは載せない予定ですので、専用の端末ソフトウェアを作ることにします。そんなわけで、開発言語は何がいいかなぁとチェックしていたんですが(って、HSP見ただけだけど)、久々にMicrosoftのVisual C++を使ってみることにしました。HSPも良かったんですが、ちょっとオブジェクト配置がめんどくさく感じたので、昔使ったことのある(最後に使ったのは6年前ぐらいか?)、という理由だけでVisual C++(以下VC++)にしました。

うっ、どうやってプログラム作るんだっけ???記憶をたどって…と、とりあえず、プロジェクトを作るんだよな、うんうん。それから、プロジェクトは、「MFC AppWizard」にするとMFCが使えるからこれを選んで…と。あとは、こういうツール物は、なんとなく「ダイアログ」タイプの方が簡単だった気がするから、ダイアログを選んで、よし、ビルド!おお、とりあえず、ダイアログボックスは出てきたぞ。ほんと、ここまでは超簡単です。

シリアル通信
シリアル通信ですが、Visual Basicの方は割と簡単にできるようになっているようですけど、VC++の方は相変わらずWinAPIを直接使わないとできないみたいですね。よし、検索検索。わかりやすく説明してくださっている方のホームページを見つけました。結構有名どころかな?CREATORS BANKです。なかなかいいところ、押さえてる感じです。よし、これで勉強しなおしです。とりあえず、自分用のシリアル通信クラスを作ろうっと。

 

2003/10/09

I2CシリアルEEPROM調査、とりあえず最終回(のつもり)

I2CシリアルEEPROMと割り込みについて
マニュアルやらI2Cやら調べてみましたが、これだ、というところには達していません。ただ、察するに、I2Cは、H8/3664からクロックを出して、それによってシリアルな通信によってデータの受け渡しを行うわけですからタイミングが厳密であり、割り込みがかかると信号のお相手をするのが間に合わなくなる→うまくいかなくなる、ということではないか?と思えてきました。具体的には、例のIIC.ICCR.BIT.IRICってのは、なんかI2Cでやった直後にクリアして、セットされるのを待つという手順があるんですが、このとき、割り込み処理とかが入ってきちゃうと、クリアの手順が遅れて、実は既にセットされているのにクリアしてしまい、その後、いくらセットされるのを待ってもダメであるという推測です。

というわけで、EEPROMに読み書きするときは、割り込み禁止にして行おうと思います。これ自体のソースコードは簡単です。GDLの場合、最初に割り込み禁止「DI;」(Disable Interruptの略と思います)をつけて、最後に「EI;」(こちらはEnable Interruptの略でしょう)をつければOKです。これにより、この処理の間、割り込みがかからないようになります。NMIだけはかかりますので、使っている方は注意してください。

ほんとは、割り込みルーチンを高速化して、EEPROMの読込ルーチンも要所要所だけをDI/EIで囲うのがベストであると思うんですけど、H8/3664がローパワーというところもあって、その域に入ろうとおもうと、これまた敷居が高そうなので、どうにもこうにも困ったときに考えようと思います。

さて、それでロボット制御ソフトウェアが成り立つのか?という話なんですが…(しばし考え中)…いけそうですね!例えば、サーボの制御信号は、16〜20msecに一度、最大2.5msec程度のパルスを出せればいいことになります。現在、設計中のソフトウェアは、このパルスを2.5msecの間に4ch分出力し、それを4回行います(合計16chまで制御できる仕様で設計しています)。ということは、タイムテーブルは、次のようになります。

時間 所要時間 処理
0.0msec 10msec 割り込み無くてもOK時間。EEPROM読み出しでもなんでもOK。
10.0msec 2.5msec サーボ信号4ch出力
12.5msec 2.5msec サーボ信号4ch出力
15.0msec 2.5msec サーボ信号4ch出力
17.5msec 2.5msec サーボ信号4ch出力

次はR/C受信機の信号取り込みですが、これはどうしましょう?1〜2msecのパルス信号が、やはり16〜20msec毎に入ってきます。これの幅をどうカウントするかが難問です。今のところ、「外部回路無し」という条件では効率的な方法が思いつきません。う〜む。困りました。ま、開き直って、EEPROMから読み取りしているときは、R/C受信機の信号取り込みはスパっとやめて、読取に専念することにしましょう。

20031009P00.GIF - 9,174BYTESH8/3664のROMに書き込むサイズって???
前から、H8/3664に実際に書き込むサイズって、どれくらいなんだろう?って思ってたんですけど、最近、やっと書き込み前にそれがわかる方法に気が付きました(今ごろか?って言われそうですが…)。フラッシュライタで書き込むときに、サイズが表示されるじゃないですか。だから、ずっと書き込むまでサイズがわからないもんだと思ってました。でも、そんなわけないよな〜と思いつつ、GDLをごちゃごちゃいじっているときに、GDLにて、出力ファイルを「BIN」にしてみたら、書き込むときと同じサイズのファイルが出力されるではないですか。そうか〜。MOTファイルがテキストファイルというのは知っていたんですが、きっとBINファイルは、書き込みイメージそのものなんでしょう。これで、書き込む前に事前チェックできそうです。え?あたりまえ?すいません。マイコン素人で日々勉強です。もし私の理解が違っていたら、どなたか教えてくださいませんか?

 

2003/10/08

タイマ割り込みを入れたらI2CシリアルEEPROMが読めないゾ?

さてさて、パワーには非常に不安のあるH8/3664ですが、タイマ割り込みを入れたらどれくらいパフォーマンスが落ちるかというチェックをしてみました。タイマ割り込みは2種類使用する予定です。1つはR/C受信機のパルス読込です。これはタイマVを使うこととしました。タイマVでφ/16にてカウントアップするようにしておくと、タイマVのカウンタは8ビットなので、オーバーフローによって0.256msec毎に割り込みがかかるようになります。2つめはサーボ制御信号の生成です。これはタイマWで処理しようと思います。理由は、8ビットでは分解度に不安があるので16ビットカウンタであるタイマWの方が安全パイであるというのと、タイマWにはコンペアマッチレジスタが4つついており、多数のサーボ信号を扱う上で便利そうです。

SH7047FのときのR/C受信機パルス読込処理
ちなみに、R/C受信機のパルス読込処理ですが、SH7047Fの時はIRQ0〜3を使ってやっていました。あのCPUのIRQは、立ち上がりエッジ、下がりエッジ両方で割り込みを掛けることが可能となっており、フリーランで走らせているタイマ値を、立ち上がりで読み取っておいて、下がりでもう一度読み取るだけでパルスの幅を取ることができました。よって精度も高く、しかも負荷がかからない(1つの信号につき、2回の割り込みだけでパルス幅を取ることができる)という、非常に良い仕掛けになっていたんですけど、H8/3664は残念ながら両エッジ割り込みができないので、あきらめです。

タイマ割り込みが入っている時のH8/3664負荷測定
とりあえず負荷だけわかればいいので、割り込みルーチンの方には、それらしい簡単なコードを書いておきました。タイマVの方は0.256msecに一度オーバーフローして割り込みがかかるようにしました。またタイマWの方は、カウンタ(TCNT)の初期値を調整して2.5msecでオーバーフローがおきるようにし、それぞれのコンペアマッチレジスタにも値を設定し、タイマWだけで、オーバーフロー、GRA、GRB、GRC、GRDそれぞれのコンペアマッチにて、計5回の割り込みがかかるようにしました。

まずは全体のパフォーマンスから。測定用のソースコードはいつものこれです。

volatile unsigned long ulBCnt;
for( ulBCnt = 0; ulBCnt < 10000000; ulBCnt++ );

結果は、約36.5秒でした。割り込み無しで約32秒ですから、割り込み処理によって14%程のパフォーマンス低下が起きています。いいのか悪いのか良くわからないんですが、まあこんなもんでしょう。タイマVの方が結構速い周期?で割り込みを掛けているにしてはいいかな?っていうのが正直な感想で、メインルーチンの方で動作データの生成等の処理をするには問題なさそうです。

プロポからの信号は、SH7047Fで計測したとき、実測値で1.5msecを中心として1〜2msecでした。そのため、タイマVの割り込み周期を、スティックの動きを検知できる最低値の0.256msecにしているのですが、せっかくなのでもう半分の倍速0.128msecとさらに半分の倍々速も試してみることにしました。

タイマV割り込み数(+タイマW)と処理能力の関係
タイマV分周 割り込み周期 10M Loop時間 処理比(割込無し/割込在り)
φ/16  0.256msec

約36.5sec

約86%

φ/8 0.128msec 約40.2sec 約79%
φ/4 0.064msec 約50.4sec 約63%

う〜ん、今後のソフトウェアの出来具合によりますけど、とりあえずφ/8ぐらいでいってみようかな。R/C受信機の信号取り込みには、なんかもったいない使い方です。なんかいい方法ないか、もう少し考えてみることにします。

タイマ割り込みとI2CシリアルEEPROM
せっかくなので、I2CシリアルEEPROMの方のパフォーマンスもチェックしてみることにしました。
「およ?」第一声です。Read Errorやらなんやらいろいろ出ます。あらら〜。ど、どうしよう。というわけで調査開始です。本格的にプログラミングする前にチェックしておいてよかった…ということで気を取り直して。

ひとつずつつぶしていくと、EEPROMアクセスルーチン中の次のようなソースコードのところで引っかっていることがわかりました。

while (IIC.ICCR.BIT.IRIC == 0);

このwhile文の中の条件がいつまでも満たされている(IIC.ICCR.BIT.IRICが1にならない)ことがわかりました。これは何の信号だろう???さ〜こまった。どうしたもんでしょう?な、なんで1にならないんでしょう?おお〜、やばい、やばいです。いやいや、こんなときでも落ち着いて…マニュアル100回読めばなんとやら〜。むむむ?

 

2003/10/07

H8/3664にAT24C1024を接続すると24LC256より読取速度アップする?

どうしようかな〜と悩んでいた、24LC256にするかAT24C1024にするかの問題ですが、とりあえず結論を出しました。結論としては、H8/3664においては、24LC256の方がよさげである、ということです。

まずH8/3664ってどれくらいの処理ができるのかチェックしてみました。こんなソースです。

volatile unsigned long ulBCnt;
for( ulBCnt = 0; ulBCnt < 10000000; ulBCnt++ );

「volatile」は、コンパイル時、最適化しない変数という意味です。コンパイラによっては最適化するとき、「むむ、このループ(for文)は意味無いじゃん。」といって、最適化の名のもとにとっぱらってしまうものがありますので、一見、無意味そうな時間待ちループをする場合は、これをつけておくのがよいです。

さて、この単純な10M回のループ、何秒かかると思いますか?(割り込み処理などはありません)
H8/3664で実測してみたところ、約32秒かかりました。ということは、1秒間に312,500回ループしていることになります。ということは…仮にAT24C1024を読み取るための処理が単純なものだったとして、このループ1回に1ビットずつ処理をしていったとしても、このループ数より速くは動けないと想像できます。ということは、312.5kHz以上のクロックによる処理は少なくとも不可能です。実際はそれなりの処理がありますので、もっと遅くなることが予想されます。

I2Cの場合、専用のハードウェアがついていて、そちらの方でバイトデータへ組み立てたり、ビットデータにばらしたりしてくれるので、前回実験のような速度がでるのですが、AT24C1024の場合はプログラムでやることになります。ひょっとしたらH8/3664の「クロック同期式シリアルフォーマット」とやらの機能を使えばできるような気もしますけど、仮にそれができたとしても571kHzが限界(H8/3664 16MHz駆動時に生成できるシリアル用同期信号の仕様)となります。この場合、SCL/SDAの出力電圧が2.5Vであるという問題に引っかかりそうですので、何か対策がいりそうです。

そんなわけで、思いっきり推論込みですが、AT24C1024を載せても、容量アップはするものの、CPUパワーの問題であまりメリットはなさそうです。

 

2003/10/06

うーむ。悩むI2CシリアルEEPROM。勉強勉強。

ちょっと、TOPICの日別サブジェクトフォーマットを変えてみました。少しは見やすいかな?10月分だけ直してみました。というわけで相変わらず悩んでいるI2CシリアルEEPROMです。

そういえば、な〜んで悩んでいるかという話を書くのを忘れていました。GDL(GCC Developer Lite)でこのアクセス関数が用意されており、また私のような中身も良く知らずに適当なシリアルEEPROMをつなげているのに、ちゃんと動作してくれているということは、非常にありがたく思っています。データのバックアップなどに使用するのであれば全然問題無い状態ですので、誤解されませんよう、お願いいたします。

自分が狙っている使い方というのが、ロボットの動作データをリアルタイムに読み出すってやつでして、サーボ制御周期である20msecの中で、次の動作データを読み出したいからなんです。20msecの周期の中で複数のサーボ動作データを読み出し、計算して制御パルスを送り込む、これが必要なわけでして。従来どおり、サーボ動作の補間計算とかはする予定ですので、20msec毎にガンガン読み出すのは、もっとも速度が要求されるケースの話ですが、考慮しなければならない問題です。

SCL/SDAのプルアップしている抵抗を2kΩに変更
結果から言えば…測定誤差以上の変化はないような、全般的に遅くなったような…な結果に終わりました。でも、推奨値ですので、このまま2kΩで行くことにします。

I2CシリアルEEPROMとはなんぞや?
さてさて、ちょっと頭冷やして考え直してみることにしました。そもそもシリアルEEPROMとは?EEROM(電気で書き込みできるROM)のひとつで、I/Fがシリアルバスのものです。普通、SRAMとかをマイコンに外付けすると、アドレッシング用に16本以上、データ読み書き用に8本、または16本の線をマイコンとの間に接続して、マイコンからは、アドレス信号をどど〜んと一度に並列で出して、データも、どど〜んと並列に取り込みます。パラレルI/Fってやつですね。

対してシリアルEEPROMは、RS232C通信のようにタイミングよく、マイコンから「10010...だよ〜ん」と言うとEEPROMから「11001100...だよ〜ん」と返ってきます。H8/3664と24LC256の場合、この「10010...」というデータを順番に読み上げていくタイミングが400kHz、1秒間に40万回。すごく早口です。さすがマイコンです。これと同じような感じで、特に別電源も必要なく書き込みもできてしまうというんだから、すごいですね〜。

I2C通信とは…実はこれがよくわからないんですよね〜。よくわからないんですが、複数のI2Cデバイスを1つの通信線上に接続で接続できますので、まずは誰かがマスタになって、デバイス指定して、その後アクセス云々という感じになっていると思います。アクセスそのものは、先に書いたような「10010...だよ〜ん」と同じなようです。これが、I2Cという規格上で流れているだけだと思います。H8/3664は、この順番に流れてきたビットデータを、バイトデータにくみ上げたり、逆にバイトデータをビットデータに直して送信する機能がついています。GDLには、以下のようなアクセス関数が用意されています。

EEPROM_ByteWrite  (TEEPROM *, _BYTE);
EEPROM_BlockWrite (TEEPROM *, _BYTE *, long);
EEPROM_EraseAll   (TEEPROM *);
EEPROM_ByteRead   (TEEPROM *, _BYTE *);
EEPROM_BlockRead  (TEEPROM *, _BYTE *, long);

書き込みの方はこんなもんかなぁって思っていますので、EEPROM_BlockRead()のソースコードを読み直してみました。括弧内は、GDLで用意されているシリアルEEPROMアクセス関数の、実際の関数名です。

1. EEPROMが書き込み完了状態かチェックする(EEPROM_Idle())。
2. I/OポートをI2C用にセットアップする。
3. I2Cバスが空いているかチェックする(_iic_busbusy())。
4. I2Cバスマスタ設定をする。
5. I2Cバスの使用を開始する(_iic_start())。
6. アドレスを設定して、データ読み取りをする。
7. I2Cバスの使用を停止する(_iic_stop())。

24LC256のデータシートを読むと、どのような通信によってデータが読み出されるかが書いてあります。う、うぅ、みなさん、こんな難しいものをよんでらっしゃるんですね…。いやいや、どんな難しい書物だって、百回読めばなんとやら。15回ぐらいでなんとかです。読み合わせてみると、データシートに書いてあるのは上記6の「アドレスを設定してデータ読み取りをする」部分だけのような感じです。そんなわけで、6-xで番号を振って、以下に書き出します。

6-1. H8/3664から24LC256へ「君だ!」に 9クロック(24LC256は、同じ線に8個接続可能です)。
6-2. 24LC256からH8/3664へ「了解!」に 1クロック。
6-3. H8/3664から24LC256へ「アドレスはここだ!」に 8クロック。
6-4. 24LC256からH8/3664へ「了解!」に 1クロック。
6-5. 3と4をもう一度繰り返し(アドレスは上位下位の2回に分けて送られますので)。
6-6. 24LC256からH8/3664へ「データはこれだよん!」で 8クロック。
6-7. H8/3664から24LC256へ「了解!」に 1クロック。
6-8. 連続で読み出す場合に6,7を繰り返し(6-7.をやると、次のデータを送ってくるようである)

まあ、よくわかっていないところは置いておくとして(いいのか?)、400kHzで動いているわけだから…8バイト読むのに必要なクロック数は、全部さらっと動いたとして、100クロックで読み出せることになります。ということは、400kHzですから、0.25msec+αで読み出せるような気がします。I2Cには、通信のお作法があるようなので、+αを見ています。しっかし、ここまでデータシートをしっかり読む羽目になるとは…(速度を求める自分が悪いのかもしれませんが)。だったらI2CじゃないシリアルEEPROMを使っても同じでした(笑)。AT24C1024の方は、1MHzまでいけるようなので、速度問題が復活してきたらこちらも試してみることにします。

まずは一発簡単に改造(危険度レベルちょっとアップ?)
というわけで、アクセスルーチンを見直してみることにします。読込時、EEPROMが書き込み完了状態かどうかチェックしていますので、これを取ってしまうことにします。安全な方法とは言えないのですが、実際に使うときは、ロボット動作情報のメンテナンス時は書き込みをしますが、通常の動作状態に入ると、書き込みは行わない予定です。よって読込時、書き込み完了状態をチェックする必要は無いような気がします。読み書き両方行う場合は、アプリケーション側にて、書き込み後に5msec以上必ずあけるようなプログラムにするということにして、すかーんとはずしてみました。

結果は…

32kByteアクセスするのにかかった時間
テスト内容 32kByteアクセス時間 1アクセス時間 コメント
64バイト読込 約2.2秒

約4.3msec

8バイト読込 約10秒 約2.4msec
お、ぐぐっと速くなりました。いい感じです。

調子に乗ってさらに改造(危険度レベルぐぐっとアップ?)
さらにもう一歩ということで、「どうせH8/3664がマスターに決まってるじゃん。」という理屈で、一度マスタになったらずっとマスタになるようなソースコードに変更してみました。先の説明で行くと、2〜5のセットアップから使用開始までを一度やったら、読込動作している限り、ずっとこの処理をすっとばして、終わるときに7の「I2Cバスの使用を停止する」を実行するようにしてみました。また、せっかく、ソースコードへの理解もちょっと深まったので、24LC256(256kBitのEEPROM)専用のソースコードにして、プログラムサイズも小さくしてみました。さてさて結果は???

32kByteアクセスするのにかかった時間
テスト内容 32kByteアクセス時間 1アクセス時間 コメント
64バイト読込 約0.9秒

約1.6msec

8バイト読込 約1.8秒 約0.44msec
おぉ、はや〜い。ほぼ10倍速!ほ、ほんとか?と思いつつ、これです。これが求めていたものです。でも、ひょっとして、すごく危険なことをしている???I2Cの世界から見たら、雷が落ちるようなことをしていたりして…。まあ、とりあえずこれで行こうと思います。

う〜ん、でも、AT24C1024の方がいいかなぁ。なんか、24LC256とデータシート見比べていたら、なんとなく使い方わかってきちゃったし。うーん、どうしよう。結論は…気軽に使うなら、24LC256、GDLについているライブラリでばっちり動作。ちょっとプログラムを改造すれば、ぐぐっと10倍速。さあどうする?は、結論持ち越しということで…。ま、ま、充分なところまでは来てますんで、ゆっくり考えようっと。でも、余裕があった方がいいよなぁ。みなさんならどうします?

 

2003/10/05
ロボット進まず。うるる。

今週末は、会社関係の音楽イベントやってましてロボット特に進まずです。昨日は久々に飲みまくってばたんきゅ〜でした。今は今で会社の宿題やってま〜す。まあ、そういう週末もよかろう。うんうん。

最近、よくチェックしているホームページで、「ONOの電脳壁新聞」というホームページがあります。H8/3664関係のページを探していたら見つけたんですが、よくみたら、Fさんのところからもリンクされてたんですね〜。なんかコメントがとっても楽しい!いいですね〜。

 

2003/10/03
I2C EEPROM 24LC256をAKI-H8/3664へ接続。

20031003P00.JPG - 13,697BYTES

20031003P01.JPG - 14,020BYTES

課題の一つであるシリアルEEPROM 24LC256をH8/3664に接続する実験を行ってみました。24LC256は、秋月電子にて購入しました。\400-でした。I2Cでなければ?(実はそうかどうかも良く知らないのです)1MBitのものもあったのですが、よくわからなかったので、I2Cと書いてある256KBit(32KByte)のものにしました。その他、理由は以下のようなものです。

■H8/3664のSCL、SDA兼用端子について
H8/3664のSCL、SDA端子は、もともとハイレベルが2.5Vしか出せないそうです。マニュアルのI/Oのところには、「Highレベル出力特性が違います」とさらっと書いてあります。I2Cのことは良く知らないのですが、I/Oとして使っても2.5Vなようで、どう影響するかが良くわからないため、I2Cとして使うことにしました。いやいや、そもそも2.5Vというのが、I2Cの規格かどうかも良く知らないんですけどね(^_^;。入力ポートとして使う手もありますけど、せっかく用意されているので、I2Cとして使う方が得策かと思いまして。
■I2C シリアルEEPROM
インターネットでざっとみて、買えそうなもので一番大きなものということで24LC256を選びました。書き込みは100万回、書き込みサイクルタイムは5msec。新Firmwareは、データ構成をコンパクトになるよう見直していますので、32KByteあれば十分そう(というか、32KByteに収まるように見直したのデス。わらかんことはソフトでカバー)。

という感じで、一番、簡単そうな路線を選んでいます。1MBitの方も、コストパフォーマンスが良さそうなので、時間ができたらやってみようと思います。Best Technology社のH8 Tinyでも同じようなもんだと思いますので、参考になるかもしれません。これができるか?またアクセス速度は?というあたりが、H8/3664の換装できるかどうかの判断基準になりますので、ドキドキしてやりましたが、ドキドキしたぶん、ちょっと怪しい雲行きな結果になりました。

20031003P02.GIFハードウェアの説明
基本的には、24LC256とH8/3664を普通に接続するだけです。左図が回路図です。SCLとSDLですが、手元の資料ですと、Best Technology社のH8 Tinyの場合は、CN2-10とCN2-11になるようです。
■A0〜A2
24LC256に対してアドレスを指定するピンです。すべてGNDにつないで0としています。1つのI2C I/Fに複数24LC256を接続する場合、変更する必要があります。
■WP
Write Protectの意味で、Vccにつなぐと書き込み不可となる。内部でプルダウン(抵抗経由でGNDに接続)されているようです。よって何もつないでいません。
■SCL/SDA
I2C 通信線です。SCLはクロック、SDAはデータです。たった2本でなんで通信できるのでしょう?不思議です。マニュアルを読むと、SDAの方は「通信速度に合わせて抵抗でVccに接続してください」とありますが、SCLの方は何も書いてありません。でもどこかで両方ともVccに接続するようなことを読んだ記憶がありますので両方とも接続しています。ちなみに、100KHz動作時は10KΩ、400kHzと1MHzは2kΩとあります。む、1kΩをつけてしまった…まあいいや、これで実験してみることにします。

ソフトウェア
GDLには、I2C EEPROM用のアクセス関数が用意されています。すばらしい〜。ソースコードもついていたので、ちょっと見てみたのですが、初期化関数は無く、それぞれのアクセス関数の先頭に、必ず初期化してから使うようなソースコードになっています。また、どの関数も、前回書き込みがあった場合、書き込み完了するまで待ってから次の処理に移るようになっているようです。そんなわけで、自分でタイマ待ちなどを組む必要は無さそうですが、逆にいうと、書き込み関数と消去関数は、呼び出すと時間待ちも含めて終了するまでReturnしないことになります。
転送速度ですが、400kHzで書き込むようになっています。使い方は、TARGETの中の3664.txtに、サンプルは、H8 Tinyのサンプル7にあります。「メーカ・メモリサイズによっては完全に対応し切れていない場合がありますのでご注意ください」なことが書いてありますので、一応、注意して下さい(だから「できた」「できない」の参考情報をHPで流しているのさ〜)。

今回のEEPROMは、256kBitでアドレスが0になりますので、TEEPROMの初期化は次のようになります。
TEEPROM SFM_eep = { ep256k, 0, 0 };

実験結果
さてさて、こんな感じで回路とソフト(サンプルからベンチマーク用にちょっと改造)を作って試してみました。一発目…書き込み異常。5秒に一回ぐらいこれがでる。どうしたのかとチェックしたら、1kΩの抵抗と信号線のつなぎ忘れを発見。おっと、勇み足で足滑らしました。今度はちゃんと結線チェックして再度チャレンジ。二回目はばっちりしでした。おお、簡単!

では、せっかくなので参考程度ですが、速度テストをいってみようと思います。

32kByteアクセスするのにかかった時間
(EEPROM_BlockRead()及びEEPROM_BlockWrite()を使用)
テスト内容 32kByteアクセス時間 1アクセス時間 コメント
全消去 約4秒 よく見たら0xffで書込してるだけでした。
64バイト書込 約4秒 約8msec
64バイト読込 約3秒

約6msec

8バイト書込 約23秒 約6msec
8バイト読込 約16秒 約4msec

う、う〜む、書き込みは想像以上に速いような気もするけど(特に64バイト書き込み)、読込が、お、遅い…。こ、こんなもんなんでしょうか?何かやり方がまずいんでしょうか?この時点で、H8/3664計画の先行きに不安が〜!それにしても、8バイトと64バイトアクセスの差を見るとわかるのですが、オーバーヘッドがなんか大きい感じですね〜。64バイト読込と8バイト読込の時間差が約2msecですから、2msecの間に56バイト転送できていることになります。そう考えると、ほぼ4msec近くがオーバヘッドになっていることになります。

読込は書き込みの100倍ぐらい速いのを期待していたんですけど、全然ダメっぽいです。いや、100倍は期待しすぎですね。う〜ん、何か別の原因があるのでしょうか?やっぱ、抵抗は2kΩにしないとダメ?

この先どうしましょう?こまりました。まずは指示どおり、SCLとSDAの抵抗を2kΩにしてみようと思います。後はI2CじゃないシリアルEEPROMも試してみるか、アクセスルーチンを見直してみるか…いずれにせよ、最初のようなあま〜い考えではダメなようで…とほほ。

H8/3664 フラッシュROM書き込み回数
そんなわけで、デバッグやらなんやらで、本日3回書き込み、総計9回書き込みということになりました。100回で収まるんでしょうか???というわけでマニュアルをよく読んでみたら、1000回って書いてありました。おお、急に安堵の色にカメレオンチェ〜ンジ。まあ、あまり気にせずに、でも他の方法でのデバッグをちゃんとやりつつ〜の進めたいと思います。

 

2003/10/02
部品調達状況

白ABS
白ABSが一昨日、到着しました。おお、いい白です。G-Tuneの基本色は黒なんですが、理由がありまして、実は、最初はナチュラルで組む予定だったんです。ただ、あのナチュラルという色はなかなか微妙な色でして「どうしたもんかなぁ〜」って思っていたところ、たまたまその時、在庫切れでして、それで迷わず「黒」にしたんです。結構なりゆきでして(笑)。結果オーライ(結果的に良かったという意味)です。

で、この間のROBO-ONEでFさんに会ったとき、Fantom_aが白ABSを使っているのを見て、後で欲しい欲しいとお願いしたら、Fさんのところで、「白」のABSを取り扱ってくれるようになったので、さっそく購入しました。感想。う〜ん、すばらしい。ABSとは思えません(どうもABSにはカラフルというイメージが無くて・・・)。きれいですね〜。というわけで、次期G-Tuneは、白と黒のツートンで、色でスマートに見せる作戦でいきます。

距離センサ
以前、ないないと書いていたシャープの距離センサですが、メカトロ仙術のほりさんからの情報で、千石電子にてちょっと前に購入できました。ROBO-ONE決勝に出ていたロボットで、相手との距離を見てLED表示をしているというのがありまして、おもしろそうだな〜と思ったので、ちょっとやってみたかったんです。できれば2つくっつけて、さらに進化バージョン試したいなと思っています。これから2つでも干渉しないか等のテストをしてみようと思っています。

このセンサ、接続ピンピッチが2mmであることは以前から情報入手していたので、コネクタも一緒に購入しました。実は、以前、千石電子のホームページでも探したことがあったのですが、サーチエンジンで半角入力していたようで、ひっかからなかったようです。買ってみて思いましたが、ロボットの顔みたいです。目があって口があって…。

今、はたと思ったのですが、もし、相手もこのセンサをつけていたらどうなるんでしょう???よし、新アイテム、ブレッドボード、早速出動だ!実験したら報告しますね。というわけで、
  ■ まずは1つで距離計測
  ■ 2つ並行に並べて距離計測(縦、横)
  ■ 2つ向かい合わせて距離計測
ぐらいでテストしてみます。

ホームページ整理
本日、月変わりということで「不定期更新TOPIC」を整理しました。今回は、Knowledgeというページを新しく作成し、そこに「R/Cレシーバ」に関するTOPICを入れました。今後は、整理するときに、おもしろそうなものをPickupして、こっちの方へ移していく予定です。

第5回ROBO-ONE競技規定
ROBO-ONEのホームページにPDFファイルで掲載されました。ふむふむ。予選デモで昇降する本は「ロボコンマガジン」!?です。い、いいんでしょうか?ふ、踏絵みたいですが…。「わ、ワタシにはふめませ〜ん」なんていうギャグはOK?ロボコンマガジン、実は買ったこと無いんですが、月によって厚さが違うなんてことはないんでしょうか?ちょっと本屋さんにノギスを持っていって調べて…なんてしたら怪しすぎます(笑)。測らないにしても、近くの本屋さんで売っているか見てくることにしよう。

 


Back Number of SISO-LAB FUTEIKI TOPIC
2003 Jan. Feb. Mar. Apr. May. Jun. Jul. Aug. Sep. Oct. Nov Dec.

Top Page