1: 2011-07-11 (月) 14:05:38 yoshida | 2: 2011-07-11 (月) 18:39:16 yoshida | ||
---|---|---|---|
Line 5: | Line 5: | ||
SIMPLE TERMからのキー入力によって、カメラを動かす方向を変えます。 | SIMPLE TERMからのキー入力によって、カメラを動かす方向を変えます。 | ||
- | キーボードのテンキーを使って6なら右、4なら左、8なら上、2なら下へ動き、0でブートローダへ移行します。 | + | キーボードの十字キー、又はテンキーの'8'、'2'、'4'、'6'を使って上下左右に動き、[ESC]キーでプログラムを終了します。 |
- | #ref("camera_block.png") | + | #ref(flow.png,100%) |
- | **準備 [#m41943fd] | + | **初期化 [#m41943fd] |
- | GCC Developer Liteを起動します。以下基本的な部分を入力します。 | + | GCC Developer Liteを起動し、初期化部分を記述します。 |
- | #include <fd.h> | + | #ref(gcc_edit_1.png, 100%) |
- | void main (void) { | + | **キーボード入力関数の作成 [#y215f66b] |
- | fd_Init (0, BT_CONSOLE, FD_BEEP_MMI | FD_BEEP_PACKETERR | FD_BEEP_LOWVOLTAGE | FD_BEEP_BOOTUP, 7.4); | + | |
- | } | + | |
- | #define KEY_QUIT { if(fd_rx_buff()) fd_SoftReset();} | + | 通常のキー入力では1回の押下で1バイトが入力されます。十字キーの場合は、1回の入力で3バイトも入力されます。 |
- | は、何かキー入力があったらブートローダに戻るという記述ですが、今回はキー入力を使うのでKEY_QUITは使えません。 | + | | 1バイト目 | 2バイト目 | 3バイト目 | キー | |
- | キー入力が0ならfd_SoftReset関数を実行するようにします。 | + | | 0x1b | 0x5b | 0x41 | 上キー | |
+ | |^ |^ | 0x42 | 下キー | | ||
+ | |^ |^ | 0x43 | 右キー | | ||
+ | |^ |^ | 0x44 | 左キー | | ||
+ | 十字キーをテンキーの数字に合わせます。 | ||
+ | #ref(gcc_edit_2.png,100%) | ||
- | **変数の用意 [#y215f66b] | + | **変数 [#nfde1082] |
- | + | パン(横振り)・チルト(上下振り)のポジション用に使う変数PanPositionとTiltPositionを用意します。AX-12+のホーンが真ん中になるよう、初期値を512とします。 | |
- | 入力された文字を取得する変数cと、パン(横振り)・チルト(上下振り)のポジション用に使う変数PanPositionとTiltPositionを用意します。 | + | |
- | + | ||
- | char c; | + | |
- | uint16_t PanPosition = 512, TiltPosition = 512; | + | |
- | + | ||
- | AX-12+のホーンが丁度真ん中になる512に初期化します。 | + | |
**トルクリミット [#b23b37f8] | **トルクリミット [#b23b37f8] | ||
- | ID=1と2のAX-12+のトルクリミット(アドレス34,35)を400にします。 | + | ID=1と2のAX-12+のトルクリミットを154にします。 |
- | fd_Initの後に以下を入力します。 | + | **初期ポジションへ移動 [#n7949229] |
+ | トルクリミット設定後、ID1とID2のゴールポジションを変更します。 | ||
- | fd_DXWriteWordData (1, 34, 400); | + | #ref(gcc_edit_3.png,100%) |
- | fd_DXWriteWordData (2, 34, 400); | + | |
- | + | ||
- | **初期ポジションへ移動 [#vfd65e43] | + | |
- | + | ||
- | AX-12+のホーンを最初のポジションへ移動します。ゴールポジションはアドレス30,31です。 | + | |
- | + | ||
- | トルクリミットの設定の後に以下を入力します。 | + | |
- | + | ||
- | fd_DXWriteWordData (1, 30, PanPosition); | + | |
- | fd_DXWriteWordData (2, 30, TiltPosition); | + | |
- | + | ||
- | **文字入力を取得する [#a6155ad4] | + | |
- | + | ||
- | 文字入力を一文字取得します。 | + | |
- | + | ||
- | 初期ポジションへの移動の後に以下を入力します。 | + | |
- | + | ||
- | while (1) { | + | |
- | if (fd_rx_buff() > 0) c = fd_getc (); | + | |
- | } | + | |
- | + | ||
- | fd_rx_buffは、入力された文字数を返す関数です。fd_getcは入力された文字を1文字取得する関数です。 | + | |
- | つまり、「もし入力された文字数が0より大きければ(文字が入力されたら)、1文字取得して変数cに代入する」となります。 | + | |
- | + | ||
- | ** switch文 [#r4473797] | + | |
- | 取得した文字によって条件を分岐するために[[switch文>http://www.besttechnology.co.jp/modules/knowledge/?FDIII-HC%20Starter%20Kit%20Guide%20Chapter1.4#x577fb19]]を使用します。 | + | |
- | キーボードのテンキーを使って上下左右にカメラを動かします。 | + | |
- | + | ||
- | while文内の文字取得の後に以下を入力します。 | + | |
- | + | ||
- | switch (c) { | + | |
- | case '6' : | + | |
- | // 右へ | + | |
- | break; | + | |
- | case '4' : | + | |
- | // 左へ | + | |
- | break; | + | |
- | case '8' : | + | |
- | // 上へ | + | |
- | break; | + | |
- | case '2' : | + | |
- | // 下へ | + | |
- | break; | + | |
- | case '0' : | + | |
- | // ブートローダへ | + | |
- | break; | + | |
- | } | + | |
- | + | ||
- | キーボードで6を入力すると右へ、4で左へ、8で上へ、2で下へ動くように、0でブートローダへ移行するようにプログラミングします。 | + | |
- | + | ||
- | **パン [#k17bc189] | + | |
- | + | ||
- | もし6が入力されたらPanPositionを1マイナスし、ポジションを送信します。~ | + | |
- | もし4が入力されたらPanPositionを1プラスし、ポジションを送信します。 | + | |
- | + | ||
- | switch文内のcase '6'とcase '4'に以下を入力します。 | + | |
- | + | ||
- | case '6' : | + | |
- | PanPosition --; | + | |
- | fd_DXWriteWordData (1, 30, PanPosition); | + | |
- | break; | + | |
- | case '4' : | + | |
- | PanPosition ++; | + | |
- | fd_DXWriteWordData (1, 30, PanPosition); | + | |
- | break; | + | |
- | + | ||
- | + | ||
- | + | ||
- | 取り付け方によってはプラスマイナスが逆になるかもしれません。 | + | |
- | + | ||
- | **チルト [#db024f9a] | + | |
- | + | ||
- | もし8が入力されたらTiltPositionを1マイナスし、ポジションを送信します。~ | + | |
- | もし2が入力されたらTiltPositionを1プラスし、ポジションを送信します。 | + | |
- | + | ||
- | switch文内のcase '8'とcase '2'に以下を入力します。 | + | |
- | + | ||
- | case '8' : | + | |
- | TiltPosition --; | + | |
- | fd_DXWriteWordData (2, 30, TiltPosition); | + | |
- | break; | + | |
- | case '2' : | + | |
- | TiltPosition ++; | + | |
- | fd_DXWriteWordData (2, 30, TiltPosition); | + | |
- | break; | + | |
- | + | ||
- | 取り付け方によってはプラスマイナスが逆になるかもしれません。 | + | |
- | + | ||
- | **ブートローダへ移行 [#a7bbd317] | + | |
- | + | ||
- | ブートローダへ移行する関数はfd_SoftResetです。 | + | |
- | + | ||
- | switch文中のcase '0'にfd_SoftReset関数を入力します。 | + | |
- | + | ||
- | case '0' : | + | |
- | fd_SoftReset(); | + | |
- | break; | + | |
**ポジションリミット [#i21b9509] | **ポジションリミット [#i21b9509] | ||
- | フレームが干渉してしまうようなポジションを送信すると、AX-12+に過大な負荷がかかり、破損する場合があります。そのようなポジションを送信しないよう、ポジションにリミッターを設けます。 | + | フレームが干渉してしまうようなポジションを送信すると、AX-12+に過大な負荷がかかり、破損する場合があります。そのようなポジションを送信しないよう、ポジションにリミッタを設けます。 |
- | 各caseに対し以下のように追記します。 | + | | 条件 | 移動方向 | リミッタ | |
+ | |右へ移動 | パン位置減算 | パン位置 > 0 | | ||
+ | |左へ移動 | パン位置加算 | パン位置 < 1023 | | ||
+ | |上へ移動 | チルト位置減算 | チルト位置 > 200 | | ||
+ | |下へ移動 | チルト位置加算 | チルト位置 < 800 | | ||
- | case '6' : | + | 取り付け方によっては、移動方向やリミッタの数値が異なります。フレームが干渉しないように十分確認して下さい。 |
- | PanPosition --; | + | |
- | if (PanPosition < 0) PanPosition = 0; | + | |
- | fd_DXWriteWordData (1, 30, PanPosition); | + | |
- | break; | + | |
- | PanPositionが0より小さいなら、PanPositionを0にします。 | + | **メインループ [#vfd65e43] |
- | case '4' : | + | プッシュボタンが押されるか、ESCが押されると終了するwhile文を作成します。~ |
- | PanPosition ++; | + | キー入力の有無を[[fd_rx_buff>FDIIILIB#c1552bcf]]関数で確認し、キー入力があれば作成したキーボード入力関数を呼出します。十字キーはテンキーに置き換えられていますので、テンキーの数字でパン位置とチルト位置を変更します。~ |
- | if (PanPosition > 1023) PanPosition = 1023; | + | パン位置とチルト位置を設定した後、現在の座標を表示します。 |
- | fd_DXWriteWordData (1, 30, PanPosition); | + | |
- | break; | + | |
- | PanPositionが1023より大きいなら、PanPositionを1023にします。 | + | #ref(gcc_edit_4.png,100%) |
- | case '8' : | + | **プログラム完成 [#d361e94a] |
- | TiltPosition --; | + | |
- | if (TiltPosition < 200) TiltPosition = 200; | + | |
- | fd_DXWriteWordData (2, 30, TiltPosition); | + | |
- | break; | + | |
- | TiltPositionが200より小さいなら、TiltPositionを200にします。 | + | 以上で完成です。まず、名前を付けて保存します。名前はCameraPlatform.cとします。保存後、ビルドして実行してみましょう。 |
- | 取り付け方によっては、数値が異なります。フレームが干渉しないように十分確認して下さい。 | + | #html{{ |
- | + | <pre class="brush:c"> | |
- | case '2' : | + | #include <fd.h> |
- | TiltPosition ++; | + | // キーボード入力関数 |
- | if (TiltPosition > 800) TiltPosition = 800; | + | int getCrossKey () { |
- | fd_DXWriteWordData (2, 30, TiltPosition); | + | int result = -1; // 戻り値 |
+ | int cnt = 0; // ループ用カウンタ | ||
+ | int rcv = 0; // 入力文字バッファ | ||
+ | while (fd_rx_buff () && cnt < 3) { | ||
+ | rcv = fd_getc (); | ||
+ | switch (cnt) { | ||
+ | case 0: if (rcv == 0x1b) cnt++; break; // 1バイト目が0x1bか確認 | ||
+ | case 1: if (rcv == 0x5b) cnt++; break; // 2バイト目が0x5bか確認 | ||
+ | default: | ||
+ | switch (rcv) { // 十字キー以外は読み飛ばし | ||
+ | case 0x41: result = '8'; break; // 上キー | ||
+ | case 0x42: result = '2'; break; // 下キー | ||
+ | case 0x43: result = '6'; break; // 右キー | ||
+ | case 0x44: result = '4'; break; // 左キー | ||
+ | } | ||
+ | cnt++; | ||
break; | break; | ||
+ | } | ||
+ | } | ||
+ | if (cnt != 3) result = rcv; // 通常のキーボード入力 | ||
+ | return result; | ||
+ | } | ||
- | TiltPositionが800より大きいなら、TiltPositionを800にします。 | + | void main (void) { |
- | 取り付け方によっては、数値が異なります。フレームが干渉しないように十分確認して下さい。 | + | int inkey, iend = 0; |
- | + | uint16_t PanPosition = 512, TiltPosition = 512; | |
- | **値の表示 [#a7519300] | + | |
- | PanPositionとTiltPositionの値を表示します。 | + | |
- | + | ||
- | while文内に以下を入力します。 | + | |
- | + | ||
- | fd_printf("Pan:%5d Tilt:%5d\r", PanPosition, TiltPosition); | + | |
- | + | ||
- | ここでプログラムを実行してみましょう。 | + | |
- | + | ||
- | **uint16_tの範囲 [#z2df0429] | + | |
- | + | ||
- | 6を入力すると、PanPositionがだんだん減って0になり、その後65535という大きな数字になってしまいます。 | + | |
- | これは変数の型がuint16_tだからです。uint16_tはC言語でいうところのunsigned shortと同じで、値の範囲は0~65535です。そのため0から1マイナスすると65535になるのです。 | + | |
- | + | ||
- | 以下のように、if文の条件を「PanPositionが60000より大きければ」に変えてみましょう。 | + | |
- | + | ||
- | case '6' : | + | |
- | PanPosition --; | + | |
- | if (PanPosition > 60000) PanPosition = 0; | + | |
- | fd_DXWriteWordData (1, 30, PanPosition); | + | |
- | break; | + | |
- | + | ||
- | **プログラム完成 [#d361e94a] | + | |
- | + | ||
- | 以上で完成です。実行してみましょう。 | + | |
- | + | ||
- | #include <fd.h> | + | |
- | + | ||
- | void main (void) { | + | |
- | char c; | + | |
- | uint16_t PanPosition = 512, TiltPosition = 512; | + | |
- | fd_Init (0, BT_CONSOLE, FD_BEEP_MMI | FD_BEEP_PACKETERR | FD_BEEP_LOWVOLTAGE | FD_BEEP_BOOTUP, 7.4); | + | fd_SetBeepCondition (FD_BEEP_MMI | FD_BEEP_PACKETERR | FD_BEEP_LOWVOLTAGE | FD_BEEP_BOOTUP); |
- | fd_DXWriteWordData (1, 34, 400); | + | fd_SetUVThreshold (7.4); |
- | fd_DXWriteWordData (2, 34, 400); | + | DX_ChangeBaudrate (1000000); |
- | fd_DXWriteWordData (1, 30, PanPosition); | + | |
- | fd_DXWriteWordData (2, 30, TiltPosition); | + | |
- | while (1) { | + | fd_DXSetTorqueLimit (1, 154); // ID1のトルクリミットに154を設定 |
- | if (fd_rx_buff () > 0) c = fd_getc (); | + | fd_DXSetTorqueLimit (2, 154); // ID2のトルクリミットに154を設定 |
- | switch (c) { | + | fd_DXSetPosition (1, PanPosition); // パン位置の設定 |
- | case '6' : | + | fd_DXSetPosition (2, TiltPosition); // チルト位置の設定 |
- | PanPosition --; | + | |
- | if (PanPosition > 60000) PanPosition = 0; | + | |
- | fd_DXWriteWordData (1, 30, PanPosition); | + | |
- | break; | + | |
- | case '4' : | + | |
- | PanPosition ++; | + | |
- | if (PanPosition > 1023) PanPosition = 1023; | + | |
- | fd_DXWriteWordData (1, 30, PanPosition); | + | |
- | break; | + | |
- | case '8' : | + | |
- | TiltPosition --; | + | |
- | if (TiltPosition < 200) TiltPosition = 200; | + | |
- | fd_DXWriteWordData (2, 30, TiltPosition); | + | |
- | break; | + | |
- | case '2' : | + | |
- | TiltPosition ++; | + | |
- | if (TiltPosition > 800) TiltPosition = 800; | + | |
- | fd_DXWriteWordData (2, 30, TiltPosition); | + | |
- | break; | + | |
- | case '0' : | + | |
- | fd_SoftReset (); | + | |
- | break; | + | |
- | } | + | |
- | fd_printf ("Pan:%5d Tilt:%5d\r", PanPosition, TiltPosition); | + | |
- | } | + | |
- | } | + | |
+ | while (!fd_GetPB () && !iend) { | ||
+ | if (fd_rx_buff ()) { | ||
+ | inkey = getCrossKey (); | ||
+ | switch (inkey) { | ||
+ | case '6': // 右へ移動 | ||
+ | if (PanPosition > 0) PanPosition--; | ||
+ | break; | ||
+ | case '4': // 左へ移動 | ||
+ | if (PanPosition < 1023) PanPosition++; | ||
+ | break; | ||
+ | case '8': // 上へ移動 | ||
+ | if (TiltPosition > 200) TiltPosition--; | ||
+ | break; | ||
+ | case '2': // 下へ移動 | ||
+ | if (TiltPosition < 800) TiltPosition++; | ||
+ | break; | ||
+ | case 0x1b: // 終了 | ||
+ | iend = 1; | ||
+ | break; | ||
+ | } | ||
+ | fd_DXSetPosition (1, PanPosition); | ||
+ | fd_DXSetPosition (2, TiltPosition); | ||
+ | fd_printf ("Pan:%5d Tilt:%5d\r", PanPosition, TiltPosition); | ||
+ | } | ||
+ | fd_Wait (10); | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
+ | }} | ||
[[次のチャプターへ>FDIIICHAPTER7.4]]~ | [[次のチャプターへ>FDIIICHAPTER7.4]]~ | ||
[[FDIII-HC Starter Kit Guide>LEARNINGGUIDE]]に戻る | [[FDIII-HC Starter Kit Guide>LEARNINGGUIDE]]に戻る |