SISO-LAB不定期TOPIC Sep.2004


2004/09/30

GWS MICRO-MGのウンチク

MICRO-MG
電脳壁新聞のONOさんのところのトップページに、ロボットの3D画が載っていますが、作業日記の方を読ませて頂いたら、「ドリーム仮面」の文字が!な、謎が解けた〜、うれし〜。実は、以前より、ドリーム仮面プロジェクトという名前がかかれていて、ず〜っと気になっていたんです) どうやらMICRO-MGが使われている模様。きっとあのロボットには、かっちょいい「仮面」が実装されるに違いない。

自分が使い始めたのは先代のG-Tuneからなんですが、あれは、姫路ソフトワークスさんのペンギンくんが発表された時に、「ん?このサーボなんだろう?」と思い、浅草ギ研さんで販売されているのを見つけて使い始めた、というのがきっかけです。

きっと、これからもMICRO-MGを使う人が多いだろうな〜ということで、たいしたものではありませんが、使うとわかるMICRO-MGの情報など。

  • MICRO-MGをM3のネジで固定する場合
    広杉計器などで取り扱っている、ブッシュがピッタリです。D3037-6120をはめると、かなりいい感じで固定することができます。
  • サーボホーンを止めるネジ
    標準でついているネジは、M2-4mmの低頭精密ネジですが、実は、6mmのM2ネジが入ります。どうしても緩みやすい!という時は、6mmのネジを使っています。トラスビスでも入ります。長い方が、ネジロック剤も楽みたいです。
  • 熱くなってくるとグリスが染み出る…
    高負荷可動とかさせて温度が上がってくると、グリスが染み出してきます。メンテするときは、ギアにグリスをつけすぎないように注意です。
  • サーボケースのネジを締めすぎると… (2004/10/15修正)
    一番上のケースが変形してくることがあります。ファイナルギア側のネジ受けの部分が「ふにゃっ」っとなりやすいのですが、実は、ファイナルギア側のネジ貫通穴は完全な筒状になっておらず、ケース内部では「C」の断面になっています。そのため、締めすぎには注意しましょう。
  • サーボホーンは消耗品
    サーボホーンのセレーション部分は、割とすぐに広がってきてしまうので、たまには診てあげてください。また、サーボホーンを加工して使っている場合は、予備部品を用意しておきましょう。G-Tuneでも、たまに「カキン!」とか言って、「おお、なんか基準位置がずれたぞ?ポテンショが壊れたのか〜!?」と思ってチェックすると、サーボホーンがずれていた、なんてことがあります。
  • ポテンショとファイナルギアに隙間がある
    現在、手軽にこれを直す方法を考えていますが、「数度」ずれます。たぶん、ギア部分をバラして、ポテンショの頭にテープでも貼ってファイナルギアを押し込んでやればいいと思うんですけど。ぼちぼちっとテストしていく予定です。やり方が確立できたら、またアップします。金属(ギア)とプラスチック(ポテンショ)の組み合わせなので、接着剤を軽く盛ってやってもいいかも。接着剤にもよりますが、この組み合わせならはずすのも問題なさそうですね。
  • 保護抵抗には1.5kΩ程度のものを入れる (2004/10/01追加)
    マイコン信号線とサーボ制御信号の間には1.5kΩの保護抵抗を入れています。どうも、新旧のMICRO-MGを一緒につなぐと、負荷が上がった時にマイコンの方に電流が流れこむようです。旧タイプのみ使用している時にはありませんでしたが、これでマイコンがフリーズしたりすることがあります。新タイプのみは、今のところやっていません。
    1.5kΩにした理由なんですが…もともと、100Ωを入れていたんですが、どうもこのフリーズ現象が多発し、状況、タイミングから推測(ヤマカン)して、マイコンに
    電流が流れ込んでいると決めつけ、保護抵抗を1kΩぐらいから10kΩまで試してみました。実は10kΩでも問題なかったのですが、いくらなんでもそりゃないだろ〜的なノリ(電流少なすぎかな〜って)で、1.5kΩにしました。

こんなところですが、参考になりますでしょうか?

 

2004/09/28

足首ピッチ発振が最近ひどいな〜と思ったら…

足首ピッチ発振
どうも最近、G-Tuneの足首ピッチ発振(と、うちでは呼んでいます)がひどい。どういうことかというとですね、足首のピッチ軸ってのは、左右、同軸上にあるわけでして、ちょっと変な前後振動が入ると、サーボが「あ、行き過ぎた、戻さないと」とがんばり、そして反対側に行くと「また行き過ぎた、戻さないと」と頑張るわけです。

腕等の、比較的振動周期の短いものは倒れるほどの事態にはならないのですが、足首から見ると重心は大きくて遠いので、ひどい時は、前後に逆ブランコの如くブンブン振って、転ぶまで頑張ります。MICRO-MGのギアの遊びが、他と比べてちょっとイマイチかな?ということで、ちょっとハデ目にでているような気がしますが、他の方でも、スペーサを噛ましたり、立っているときに脚の位置を少しずらしたりされているようです。

20040928P00.JPG - 19,616BYTES20040928P01.JPG - 12,800BYTES

そうそう、思い出しました。G-Tuneにもこんなものをサーボ軸にはさんでいます。これは、MICRO-MGかS03Tについていたゴムブッシュを、ニッパでプチプチ切ったものです。もう、ぼろぼろになってしまっています。そうか〜、これがヘタってきたんで、最近足首ピッチ発振がひどいんだ。

新しいのにしようか悩んだんですが、せっかく次までは期間がありますので、実験ということで、手持ちであったポリスライダーワッシャ(材質で選んだのではなく、単に手持ちで、厚みがいろいろあって、硬いものということで)を噛ませてみました。MICRO-MGのホーン付け根とサーボケースの隙間は約0.6mmなのですが、手持ちの都合上、約0.8mm(薄いものの組み合わせ)を入れてみました。

おお、効果抜群!今まで「増幅してってるよ〜」な状態から、1〜2回で振れが納まります。でも、心配はネジのゆるみです。もともとここは、ネジロック剤を塗っていても緩みやすいのですが、なんとなく、さらに緩みやすくなるような気がします。ま、様子見ということで。緩みがひどいようならば、標準品より長めのビス+ネジロック剤にしてみようと思います。これでロック力が少し上がるのは、腰のヨー軸で確認しています。

発振を防ぐ効果はかなりあるので、今度はテフロン(ポリスライダーより軟らかいのでなんとなく良さそう…直感です。理屈はありません)で試してみようと思います。

MICRO-MGの新基板と旧基板の制御の違い
実は、この足首ピッチ発振、G-Tune 2004Fの時はサーボ制御信号を「数十msecOFFにする」ことによって止めていました。以前、Omoriさんという方が、浅草ギ研さんの自作ロボット掲示板(記事番号617)でMICRO-MGの新基板と旧基板の動作の違いについて書かれていまして、うちでも確認してみたのですが、制御信号を入れないと、新では脱力、旧ではブレーキ動作になっているようです。

ということで、制御信号をOFFにすると、新基板のMICRO-MGでは支えきれなくなって倒れてしまいます(制御方法は新、OFF時の動作は旧というのが欲しい〜)。足首を旧基板のMICRO-MGに入れ替える、という手もあったのですが、入手はもう無理だと思いますので、あきらめて現在に至ります。

 

2004/09/23

OAKS16-MINIで割り込み無しシリアル通信・送信

送信処理、結局こうなりました。
え〜、OAKS16-MINIネタを書くのは久しぶりですが、送信バッファレジスタの意味もわかり、また、_farの謎がわかり、無事、ビルド完了となったのですが、連続したデータ(要は文字列)を送信したら、変なデータが出てきてしまいました。1文字ずつ送ると問題無いんですが、連続して送ると、「ABCDEFG」が、「ADF???」みたいな感じで、データが飛び飛びになってしまいます。書いたプログラムは、以前お見せしましたこれです。

void    RSCsend( unsigned char bData )
{
    while( txept_u1c0 == 0 );        //  送信レジスタが空になるまで待つ
    u1tb = (_WORD)bData;             //  送信バッファレジスタにセット
}

んで、考えたんですが…実は、「送信バッファレジスタから送信バッファに送る速度は、実は超高速ではない」のではないか?と推測しています。良く考えてみれば、送信レジスタが空になったからといって、送信バッファレジスタにデータ突っ込むのは紳士じゃないですね〜。

ということは、「送信レジスタ空フラグ(UiC0/TXEPT)」と、送受信制御レジスタ1の「送信バッファ空フラグ(UiC1/TI)」の両方をチェックしてやるのがベスト!ということになるのですが、ま、そこまではいいかな?ということで、送信バッファレジスタをチェックするだけにしておきます。

void    RSCsend( unsigned char bData )
{
    while( ti_u1c1 == 0 );           //  送信レジスタが空になるまで待つ
    u1tb = (_WORD)bData;             //  送信バッファレジスタにセット
}

今は、puts()とかgets()とかを作っていますので、もう少しテストができてきたら、まとめてアップします。
(やりだめしていた家のこととか、仕事とか忙しいのもあるんですが、実はH8/3664の方もいじっているので進みが遅いというのはヒ・ミ・ツ)

 

2004/09/21

たまには動画なんぞ…変形

動画はとりあえず、これで打ち止めです。最後はやっぱり変形!今回は、変形後のポーズというのも考えてみました。やっぱり、キメが欲しいかな〜なんて。あはは。ほら、アニメなんかでも、なんとなくポーズとか、キメのカメラワークとかあるじゃないですか〜。

GT2004FI_MOVIE_MODECHAGETOB.JPG - 7,798BYTES
クリックで動画再生

変形そのものは、メカデザインによって決まっているわけなんで、後は、手を先に動かすとか、脚を先に動かすとかっていうのが「見せ方」になるわけなんですが、なるべく大きく、開いていくように見えるよう、気をつけて動かしています。

ONOさん、いつもいつも紹介してくださっている上に、お褒めのコメントありがとうございます。カンファレンスではお会いできるかな?

 

2004/09/20

たまには動画なんぞ…続き

全部、編集できました。慣れてくると、編集も楽しいです。でも、きっと次に動画取り込みやるころには忘れてしまいます…。デジカメの方がやっぱり簡単…かといって、うちのデジカメだと、やっぱDVの方が画質がいいんで、DVで頑張ってしまうのです、はい。

とうわけで、「始めのご挨拶」。少ない関節で、なるべくそれっぽく見えるようにがんばってみました。

GT2004FI_MOVIE_GREETING.JPG - 7,674BYTES
クリックで動画再生

次に「愛想」。これのポイントは、足首のヨー軸を使って、身体全体を左右に捻っているところです。こういう動きは、「SIPHA TERM」の動作設定機能が良くなってきたおかげで、ようやく簡単に設定できるようになってきたという感じです。G-Tune 2004F(前回)の時は、ほとんどソフトが間に合ってなくて、NCの数値入力みたいなやり方でやってましたんで…。ソフトが違えば、動きも違うってことですね!

GT2004FI_MOVIE_INCENSE.JPG - 7,651BYTES
クリックで動画再生

そして「歩行」です。これは、前回の動作パターンを見直して2〜3割ほど高速化しています。単に歩幅を少し広げたのと、運びを速くして、時間配分を若干調整しているだけです。本当は、「膝曲げなし」歩行をやりたかったのですが、断念し、これを正式採用としました。まだまだ、いろいろ改善の余地ありですね〜。せっかくのグリップ足裏が役に立っていない感じです。

GT2004FI_MOVIE_WALKING.JPG - 8,000BYTES
クリックで動画再生

最後に「横歩き」です。横歩きは、「しっかりと脚が上がっているのがわかるように移動させる」のが意外に難しく、結局、「グリップ系足裏」を利用して、このような、制動力で最後に脚を引っ張り上げるような動きとなりました。このあたり、「グリップ」が役に立っているような気がします。グリップ系は、すごくよかったので、次回も採用予定です。

GT2004FI_MOVIE_SIDESTEP.JPG - 7,579BYTES
クリックで動画再生

変形動画もできているんですが、容量が結構あるんで、いちおう、サーバの負荷を考慮して、今日はこれぐらいにしておきます。

 

2004/09/19

たまには動画なんぞ…

今日はDV出してきて、G-Tune 2004FIのビデオ収録。

とりあえず、予選で出せなかった技を…

GT2004FI_MOVIE_LATEROVERSION.JPG - 7,749BYTES
クリックで動画再生

ついでに、出せたけど、一回しか出せなかった技も…

GT2004FI_MOVIE_FORWARDROLL.JPG - 6,762BYTES
クリックで動画再生

他の、地味なやつも現在編集中で、随時アップしていこうと思います。お楽しみに。

 

2004/09/17

nearとfarポインタ、いよいよ解決かな?デバッガで変数チェック

_farですよ、_far
いずみかわさんからのヒント、わたなべさんからの助言から、"_far"なるものが必要では?ということがわかってきた今日この頃ですが、ハタと思ったことがありました。

「標準関数はどのように定義されているんだろう?」

NC30は、標準関数ライブラリが用意されているので、このヘッダを覗いてみることに。探してみると「MTOOLS\INC30」にヘッダが入っていました。

char _far * strcpy(char _far *s1, const char _far *s2);

う、ここにそう書いてあるではないか…。先に、こういうところからチェックすればよかった…。みなさん、すいません。わたなべさんのいわれるように、"far"は、"_far"なんですね。うむうむ。というわけで、宣言を修正(ついでにヘッダファイルに書いてあるように、変数名を書かないタイプに修正)して、実体の方も修正して…と。

void strCopy( char _far *, const char _far * );
        :
void strCopy( char _far *szDest, const char _far *szSrc )
{
        :

りびるど〜!
ほとんど呪文のように…

 あ、ビルドできました。

よし、デバッガで確認だ!strCopy()を呼び出しているところでブレークポイントを仕掛けて

「りせっとよぉぉしぃ、ごぉぉぉっ!すてっぷ、すてっぷ、すてぇ〜っぷぅぅぅ!」

お、いいですね。ちゃんとデータが設定されるようになりました。よし、これでまた一歩、この環境へ馴染みました。というわけで、明日は、シリアル通信プログラムに戻ることにします。

みなさん、どうもご指南ありがとうございます〜!

というわけでデバッグのやり方・変数内容チェック
と、喜んでいる様子をお伝えするだけでは、申し訳ないので、デバッグ方法についてのお話です。デバッガを起動すると、まず、Program Windowという画面が出てきます。この画面で、「View」ボタンを押すと、表示するソースファイルの指定をすることができます。

20040917P00.JPG - 24,922BYTES 20040917P01.JPG - 5,710BYTES

はい、ここで、表示するソースファイルを指定します。

20040917P02.JPG - 11,352BYTES

で、ソースファイルが表示されたところで、変数を選択状態にして、右クリックメニューを表示し、「Add C Watch...」を選択すると、「C Watch Window」が開き、変数が追加されます。もちろん、「C Watch Window」をあらかじめ開いておいて、「Add」操作で開いても構いません。

20040917P03.JPG - 15,789BYTES 20040917P04.JPG - 9,545BYTES

「文字列データじゃわからない〜」ってことはありません。この「C Watch Window」で変数を選択してダブルクリックすると、中身を見ることができます。よくできてる、うんうん。

20040917P05.JPG - 30,243BYTES

というわけで、先ほど修正したソースコードで、ステップ実行させた時の変数表示です。思ったとおりの値が入っていることがわかります。

20040917P06.JPG - 32,551BYTES

また、このように、グローバルなデータだけではなく、ローカルなデータも表示することができます。

20040917P07.JPG - 35,079BYTES

ふぅぅ、長かった〜。でも、偉大なる第一歩!

 

2004/09/16

nearとfarポインタ、相変わらず悩んでいますが…

いろいろ考えていたんですが、なんか、根本的に理解しないといけない部分がある(ようは知らないコトがある)ような気がしてきました。というわけで、オークス電子さんがアップされている、自習用テキストを読み始めました。今はOAKS16プログラミングテキストの方を読んでいます。ふむふむ。NC30が管理するセクションがウンたらかんたら。何はともあれ、環境(クセとか決り文句)を覚えて慣れないとね!

ところで、デバッガでデバッグするのって、フラッシュROMの書き込み回数にカウントされるのかな?素朴な疑問です。

 

2004/09/15

nearとfarポインタ

2004/09/06のTOPICの最後にボソボソっと書いた、「関数に文字列を渡すのに警告が出て、あげくの果てに渡されていない模様」みたいな話ですが、未だに解決してなかったりします。たぶん、コンパイラのクセだと思うんで、解決すれば早いんでしょうけど…。

というわけで、ちょっとシンプルなコードを作ってみました。デバッガ前提なので、シリアル出力処理はつけていません。

#include	"sfr26.h"

void main( void );
void strCopy( char* szDest, char* szSrc );

char szWorkG[32];

void strCopy( char* szDest, char* szSrc )
{
    int	nCnt;
    for( nCnt = 0; szSrc[nCnt] != '\0'; nCnt++ ){
        szDest[nCnt] = szSrc[nCnt];
    }
    szDest[nCnt] = '\0';
}

void main( void )
{
    char szWorkL[32];

    strCopy( szWorkG, "ABC" );
    strCopy( szWorkL, "ABC" );
    strCopy( szWorkG, szWorkL );

    while( 1 );
}

これをコンパイルすると、無情にも、

[Warning(ccom):StringSetTest.c,line 21] far pointer (implicitly) casted by near pointer
   ===>         strCopy( szWorkG, "ABC" );
[Warning(ccom):StringSetTest.c,line 22] far pointer (implicitly) casted by near pointer
   ===>         strCopy( szWorkL, "ABC" );

といわれます。さらに、デバッガで動作を追いかけてみると、思ったような値がstrCopy()のszSrcに入ってないようです。警告を読むと、なんかnear pointerのところに、far pointerを無理やり入れてしまったようです。このnearとfar、直訳で「近い」と「遠い」という意味でなんのことやら?ですが、実はポインタ(データや関数のアドレスを指す変数)には2種類あるようで、nearは2バイト - FFFFのアドレス空間を指せる、farは4バイトだけど実は3バイトで 0 - FFFFFFのアドレス空間を指せるポインタになります(わたなべさん、説明ありがとうございました)。で、ハードウェアマニュアルを読むと、RAMは前の方、ROMは後ろの方にあって、ROMがfar pointerなようです。対して、RAMは前の方なのでnear pointerになると。

これをコードで意識するとなると、結構、大変な気がするのですが、みなさんどうされているんでしょうか?例えば、strcpy()のコピー元って、"ABC"と渡したい時もあれば、文字列を編集して渡す(RAM上の変数)こともあるわけです。どうしたらいいんでしょう?悩んだあげく、コンパイルオプションを試してみることにしました。

-ffar_RAM

「RAMデータのデフォルト属性をfarにします。」というオプションです。意味が良くわかりませんが、それっぽいので、試してみることにしました。どうやってTM上でコンパイルオプションを変えるのか、わからなかったので、makeファイル(〜.tmk)のCFLAGSの行を直接編集しました。

リビルド〜!

何か、深そうなもの変更した時は、何はともあれリビルドしましょう。

StringSetTest.c 21 Warning (ln30): .\StringSetTest.r30 : '_szWorkG' value exceed 0FFFFFH
StringSetTest.c 21 Warning (ln30): .\StringSetTest.r30 : '_szWorkG' value exceed 0FFFFFH
StringSetTest.c 23 Warning (ln30): .\StringSetTest.r30 : '_szWorkG' value exceed 0FFFFFH
StringSetTest.c 23 Warning (ln30): .\StringSetTest.r30 : '_szWorkG' value exceed 0FFFFFH
Warning (ln30): .\StringSetTest.r30 : 'bss_FE' data exceed 0FFFFFH

う、また難しそうなものが…。0FFFFFHを越えているぅ???う〜む、なんか違うっぽい…。

 

2004/09/14

BBS修正

今まで気づかなかったのですが、うちのBBS、URL入力する時に、40文字まででカットされていました。ひょっとしたら、以前にも切れていたことがあったかも、いや、あったような…。切られてしまった方、すいませんでした。気づかせてくれたイカガワさん、ありがとう〜。OLMECA、りりしいぞ〜!(どうやって、いきなりあんなすごいロボットを作ったのか教えて欲しい…万年試行錯誤のSISO JUNK STUDIO)。

というわけで、初めてPHPなるものを編集してみました。これで80文字になりました。よろしくです。

 

2004/09/12

今週末は渋さ知らズに燃えすぎたのでロボットはお休み。

昨日のことですが、なぜか近所に

大好きな!!!

「渋さ知らズ」が来ていました。来ることは知っていたのですが、まさか、ダンサーまで来ているとは…。燃えすぎたので、ロボットはお休みです。ハイ。

 

2004/09/09

続・OAKS16-MINIで割り込み無しシリアル通信

送信処理続編
前回、シリアル通信の送信処理で、「2つ、同じ意味と思われるフラグが存在します。」ということを書きましたが、メカトロ仙術のほりさんからの助言でやっと理解できました。プログラム側からみると、「送信レジスタ」の手前に「送信バッファレジスタ」が存在するということです。

ハードウェアマニュアル(rjj09B0033_m16chm.pdf)の「図13.2 UARTi 送受信部ブロック図」をよく見ると、「UiTB(送信バッファレジスタ)」から「送信レジスタ」データが転送され、そこからデータが送信されている図画描いてあります。つまり、送信処理は、プログラムから「送信バッファレジスタ」にデータを書き込み、それが「送信レジスタ」に転送され、そこからシリアル化されて送信されるわけですね!

そんなわけで、送受信制御レジスタ0の「送信レジスタ空フラグ(UiC0/TXEPT)」は、実際にデータを完全に送りきった場合にフラグがセットされ、送受信制御レジスタ1の「送信バッファ空フラグ(UiC1/TI)」は、「送信バッファレジスタから送信レジスタにデータが転送された時」にセットされるということみたいです。図で書くと、次のような感じでしょうか。

プログラム
処理

送信バッファ
レジスタ

送信
レジスタ
UiC1/
TI
UiC0/
TXEPT
動作
Step 1 'A'を送信 プログラムで、'A'を送信する処理開始
Step 2 'A' 送信バッファレジスタに'A'をセット
Step 3 'A' 送信レジスタに、転送されて送信開始。
Step 4 送信完了されてレジスタが空

そんなわけで、「UiC1/TI」をチェックして送信バッファレジスタにデータを設定すると、「データは送っているとは限らないけど、プログラムからみたら、新データを設定していいタイミング」で設定することになり、「UiC0/TXEPT」をチェックして送信バッファレジスタにデータを設定すると、「完全にデータを送りきった後のタイミング」で設定することになりますね。

実際、送信レジスタが空であれば、Step 2からStep 3は一瞬だと思いますし、プログラムでのフラグチェックも、シリアル通信速度から見ればぐっと速いので、一番確実そうな「UiC0/TXEPT」でのチェックで送信するようにしようと思います。なんとなくもったいないのですが、ベーシックなものとしては良さそうです。文字列送信とかでスピードが気になることがあったら、連続データ送信用に別途用意すればいいかと思います。というわけで、割り込み無しの送信処理は、

void RSCsend( _BYTE bData )
{
    while( txept_u1c0 == 0 );   //  txept_u1c0が1になるまで(送信レジスタが空)待つ
    u1tb = (_WORD)bData;        //  送信バッファレジスタにセット
}

としておくことにします。

と、書いていたら、TWO LEGSのわたなべさんからもフォローの記事が…みなさん、ありがとうございます〜。

 

2004/09/06

OAKS16-MINIで割り込み無しシリアル通信

うぅ、夏ばて?
夏ばてかな〜。先週の出張から帰ってきてから、調子がイマイチ。みなさんはお元気ですか?

OAKS16-MINI、引き続き、シリアル通信です。新しいものをやるのは、実に楽しいです。でも、オークス電子さん、こういう誰でも作りそうなものは、サンプルライブラリみたいな形で用意しておいた方が、よく売れると思います(ひょっとして、もうある???)それか販売してる方とか…最近、OAKS16-MINIも取り扱っている、チャーリーさんとことかでやってくれないかなぁ〜。

シリアル通信の初期化方法
というわけで、まずは初期化ルーチンです。今回の目標は、割り込み無し、通信速度は2400、4800、9600、19200、38400、57600をサポートすることです。最初は9600bpsぐらいまででいいかなって思ったんですが、KOのシリアル無線機が2400bpsみたいなので、これもできるようにしてみました。

それでは、先日の式で、転送速度レジスタにセットする値を計算してみます(四捨五入してます)。

式は、(20,000,000/速度/16-1)ですね。

57600 = 21
38400 = 32
19200 = 64
9600  = 129
4800  = 259
2400  = 520

うむ。4800bpsと2400bpsは255をオーバーしてしまいました。転送速度レジスタ(UiBRG)は、8ビットですから、セットできません。う〜ん。どうしましょう。てぃろりろりん♪送受信制御レジスタ(UiC0)で、f1sioを使用しているのを、f8sioにすれば、さらに1/8になりますから、それでOKです。

というわけで、4800、2400bpsの場合は、こんな式になります。

20,000,000/速度/16/8-1 (f8sioを使用する)

でも、これはプログラムで切り替えることにします。というわけで、まずは、転送速度を定義します。ついでに、GDLに慣れてしまっているので、_BYTEと_WORDも定義してしまいました。

typedef	unsigned short	_WORD;
typedef	unsigned char	_BYTE;

typedef enum {
    BPS2400  = 521,
    BPS4800  = 260,
    BPS9600  = 130,
    BPS19200 = 65,
    BPS38400 = 33,
    BPS57600 = 22
} RSCbps;

はたと、「H8/3664の時みたいに、charが実はunsignedとかでハマることは無いだろうか?」と心配になりました。どうやら予感的中です。M16もunsignedみたいです。ま、でも、わかっていればそれまでなので、気を取り直して、今回作った初期化ルーチンです。ポイントは、渡された値をチェックして、f1sioかf8sioを再設定するようにしてみました。

void RSCinit( RSCbps tBps )
{
    u1mr = 0x05;                        //  送受信モ−ドレジスタ 内部クロック、非同期、
                                        //  8ビット、パリティなし、スリープなし

    if( tBps > 0xFF ){
        u1c0 = 0x11;                    //  送受信制御レジスタ クロックはf8SIO
        u1brg = (_BYTE)( tBps/8 - 1 );  //  CLKが1/8になるので、BRGも1/8にする。
    }
    else{
        u1c0 = 0x10;                    //  送受信制御レジスタ クロックはf1SIO
        u1brg = (_BYTE)( tBps - 1 );    //  転送速度レジスタ
    }

    u1c1 = 0x05;                        //  送受信制御レジスタ1 送受信許可
}

送信処理
送信は、mini5.cだと、いきなり送信バッファレジスタにいれてまして、結構強引な感じですので、今回は、ジェントルマンに、ちゃんと送信可能かどうかをチェックしてから送信バッファレジスタに入れることにします。しかし、ここでハタと困った。

2つ、同じ意味と思われるフラグが存在します

送受信制御レジスタ0の「送信レジスタ空フラグ(UiC0/TXEPT)」と、送受信制御レジスタ1の「送信バッファ空フラグ(UiC1/TI)」は、説明文は違うのですが、どうやら動作は同じようです。ただ、割り込み要因として指定できるのはTXEPTの方みたいなので、こっちの方が由緒正しいのかもしれません。試しに、両方やってみたのですが、どちらも結果は同じでした。

void RSCsend( _BYTE bData )
{
    while( ti_u1c1 == 0 );      //  ti_u1c1が1になるまで(バッファが空)待つ
    u1tb = (_WORD)bData;        //  送信バッファレジスタにセット
}

受信処理
んでは、受信処理の方、行ってみたいと思います。mini5.cでは、割り込みを使って受信処理をしていましたが、今回は、「割り込みを使わない」のが目的なので、やはり、レジスタで状態チェックをして受信バッファレジスタからデータを取り出すようにします。 これには送受信レジスタ1の「受信完了フラグ(UiC1/RI)」をチェックしていればいいみたいです。というわけで

_BYTE RSCrecv( void )
{
    _WORD   wData;

    while( ri_u1c1 == 0 );              //  受信完了が1になるまで待つ
    wData = u1rb;                       //  受信バッファから取り出す。
    return((_BYTE)( wData & 0xFF ));
}
      

ふむ。これでOKって感じです。今回、バッファチェックは、それぞれの処理中に書いていますが、これを、チェックルーチンとして独立させると「受信待ちせずに、データがある時だけ受信する」という処理ができます。SIPHA COREでも、送受信両方とも、このような使い方をしています。

こんなんでいいのかな???間違ってたら教えてくださいね〜。

で、この後、まだ未解決のよくわからない問題にブチあたるのであった。う〜ん。また後日。

いや、文字列送信関数RSCputs( char* )なんてのを作ってね、RSCputs("abc....")って書いてみたらコンパイルで警告(far pointer (implicitly) casted by near pointer)がでるんですよ。んで、よくわかんないんで、RSCputs( const char* )にしてたら出なくなったんですが、端末に表示されるはずのデータが表示されないわけです。う〜む。現在、調査中です。

 

2004/09/05

充電期間ということで

ROBO-ONE DVD、予選まで観ました
予選まで全部観ました(実は、また出張してて、なかなか時間が取れなくて…)。う〜む、すごい。A-DOもすごいけど、「観ている人の心をつかむ」という意味では、クロイノのデモも、かなりレベル高い!ロボデザインもありますが、それにも勝る動きの可愛さに、思わず引き込まれてしまいます。DVD見ていたら、クロイノの歩き方、なんとなくわかりました。そ〜か〜、なるほど。そうなっているのか〜。G-Tuneにはできないな〜。

次は本戦だ〜!「次期G-Tuneはやらなくていいの〜?」とか言われそうですが、いいんです。今は「だらだら」しながら、現行のアーキテクチャにとらわれず楽しむフェイズと、SISO-LABのスケジュールシートに書いてありますから。ビール飲んで、DVDを楽しむ、いや、研究する。うむうむ。

 

2004/09/02

UART1でシリアル通信

OAKS16-MINIのサンプルmini5.c
どこから手をつけていこうかな〜といろいろ考えていたんですが、まずはシリアル通信をやってみることにしました。UART0に新しいコネクタをつけようかなと思ったんですが、手持ちが無かったので、練習がてらサンプルのmini5.cをUART1用に変更してみました。

シリアル通信速度の設定
シリアル通信速度の設定は、転送速度レジスタ・UiBRGにするのですが、mini5.cについているコメントを読むと、

20,000,000/19,200/16 - 1
(Clock/bps/16) - 1

とあります。20,000,000は20MでCPUクロック、19,200は転送速度、じゃあ、この「/16」はいったいなんなんだ〜?ハードウェアマニュアルを読んでも、周辺クロックを使用するようなことは書いてありますが、「1/16」なんてのはでてきません。

そういうものと覚えておけばいいのかな〜?と悩んでいたら、TWO LEGSのわたなべさんがヘルプしてくれまして、手元のマニュアルでも確認してみました。転送速度レジスタのところには書いてないのですが(そもそも、これが原因)、「rjj09B0033_m16chm.pdf」のP118のブロック図をよく見ると、「UiBRG」の前に、「1/16」と書いてある箱があるのを発見しました。そして、遂に!P133に「fj/16(n+1)」の計算式を見つけたのです。ふうふうふう。大変でした。きっと、わたなべさんからの書き込みが無ければ、一生、「そういうもんだ」とあきらめていたに違いないです。

よし、これで、「u0mr」とかを「u1mr」に変更すればOK!(UART0とUART1は、たぶん同じ機能)

そう簡単にはいきませんでした。

割り込みベクタテーブル???
mini5.cというサンプル、受信に割り込みを使っているのですが、これのテーブルを書き換えないといけないようです。GDLを使っていると、このあたり、何にも気にしませんでした。「じゃあなぜ気が付いたか?」といいますと、まず、ソースファイルを眺めていて、「このreceive()って関数、割り込み関数みたいだけど、マイコンはどうやってこの関数の位置を知るんだろう???」と思い始めました。そして、あとは「grep」攻撃。で、「sect30.inc」に書いてあるのを発見しまして、他のサンプルも確認して確信しました。

ロボットやり始めの頃、ちょっと秋月電子で扱っているコンパイラを触った時に、そんなようなことがあったような気がしました。というわけで、「sect30.inc」に書いてある

  .lword  dummy_int    ; uart2 receive(for user)(vector 16)
  .lword  dummy_int    ; uart0 transmit(for user)(vector 17)
  .glb    _receive     ;
  .lword  _receive     ; uart0 receive(for user)(vector 18)
  .lword  dummy_int    ; uart1 transmit(for user)(vector 19)
  .lword  dummy_int    ; uart1 receive(for user)(vector 20)
      
こんなふうに修正します。
  .lword  dummy_int    ; uart2 receive(for user)(vector 16)
  .lword  dummy_int    ; uart0 transmit(for user)(vector 17)
  .lword  dummy_int    ; uart0 receive(for user)(vector 18)
  .lword  dummy_int    ; uart1 transmit(for user)(vector 19)
  .glb    _receive     ;
  .lword  _receive     ; uart1 receive(for user)(vector 20)
      

これによって、M16マイコンは、receive()という関数が、UART1の受信割り込みになっていることを知るわけです。「sect30.inc」を眺めていたら、一通りの割り込みが書いてありますので、必要に応じて書き換える必要がありますね。

よく考えてみると、これって、マイコンプログラミングをしていたらあたりまえのことなんですよね?う〜む。いやいや、何事も勉強勉強!

 

2004/09/01

J-Class DVD、やっと全部観ました。 

う〜ん、みなさん、すばらしい!
J-ClassのDVD、観破しました。自分が出ていると、なかなか、他の人の試合とかって観てる余裕がないのですが、DVDで観るとばっちりですね!チャプターもついていてさくっと出てきますし(三月兎さん、ありがとう!)。

予選上位陣、歩行、かなり速いのですが、3位ながら「リトル・トライダーG1」、歩行、すごい。な、なぜだ…。G-Tuneと同じサーボモーターなのに。すごく安定感があります。じっくり研究させてもらっちゃおうと思います。G-Tuneとは前後バランスがだいぶ違う感じです。

さて、次はROBO-ONE予選だ〜。

っと。ちょい書き足しです。

まだJ-Classだけなんですが、何度か見直して思ったのが、意外に自分が攻撃を仕掛けて、思わぬ反作用を受けて転んでしまう、というケースが結構あります。簡単なケースだと、出したパンチが相手に引っかかってすくわれるとか、ちょっとわかりにくいケースですと、下からパンチを出して相手が倒れず、そのまま自分が反作用でずるずると倒れてしまうとか。

今回用意した攻撃パターンが、出した後、0.5秒ぐらい伸ばして押し込んでおくのが多いので、これを速く引っ込めるようにするだけでも、だいぶ自爆パターンが減るかもしれません。でも…同時に、倒せる率も減るんですよね〜(SISO-LABの極秘研究レポートによる)。難しいところです。

 


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

Top Page