Blog Archives

マイクロマウス研修 Part13(岩本)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

マイクロマウス研修(岩本)一覧
Part1Part2Part3Part4Part5Part6Part7Part8Part9Part10Prat11Part12、Part13

番外
Part8.1

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

こんにちは岩本です。
今回は、前回やりきれなかったサンプルプログラムSTEP6-3(run_ROT_PWM)の中身を確認していきたいと思います。
run.cに新しくプログラムは旋回のプログラムが追加されています。
49行目~57行目で直進の時と同様に目標ステップ数や加速度を決めて、60行目~74行目で右に曲がる時と左に曲がる時で、switch関数で分けてます。
その他は、直進と同じなので、省略します。

 

このまま、step7(P_control_run_usb)についても確認していきます。
このステップでは、センサでフィードバック制御をして、迷路の真ん中を走らせます。interrupt.cにcmt0とcmt1のプログラムが追加されています。
cmt0では、フィードバック制御について記載されています。

色々書いてありますが、使っているのはP制御のみです。下図に式の部分のみ抜き出してみました。
偏差は、左右のちらかの壁がなかった場合、計算が合わなくなってしまうため、壁がなかった場合、センサーの値が無効になります。そのため、片方のセンサーの値のみが有効な場合は、片方のセンサーの値を2倍にして帳尻を合わせています。
なお、上図52行目から63行目でD制御とI制御用の計算だけしてますが、制御では使ってません。ここから先は、自分で頑張ってやってみようということのようです。

また、P制御の操作量についてですが、通常の式では、”操作量 = 比例定数 × 偏差” で求められます。
しかし、速度が速い時と速度が遅い時で操作量が同じ場合、遅い時の方が急カーブになってしまいます。(スリップの可能性が出てくる。)
そのため、操作量に速度が掛けられています。0.001は速度を掛けた為、そのままだと操作量が大きすぎるため、調整しています。

cmt1では、4つのセンサの値を記録し、左右に壁が有るか無いかの確認をしています。

今回はここまでです。

続きを読む ›

Posted in Pi:Co Classic3 製作記


マイクロマウス研修 Part12(岩本)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

マイクロマウス研修(岩本)一覧
Part1Part2Part3Part4Part5Part6Part7Part8Part9Part10Prat11、Prat12

番外
Part8.1

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

こんにちは岩本です。
今回は、サンプルプログラムSTEP6-1~6-2(run_wait・run_ST_PWM)の中身を確認していきたいと思います。
STEP6-1は、180㎜進むためのサンプルです。
MOT_CWCCW_R(L)は、回転方向を決めており、portdef.hでポートの設定がされています。そして、MOT_FORWARDはstatic_parameters.hで0となっています。
MOT_CWCCW_R(L)に、0を出力すると、前進する方向に回転するようになっています。逆に1を出力すると後退する方向に回転するようになります。
43行目でMOT_POWER_ONでモーターを励磁させています。44行目は、いきなり回すと脱調することがあるため、脱調防止の為の待ち時間です。
48行目から52行目で、ブザーとモーターにパルスを出力しています。

 

上図46行目のLEN2STEP(180)の中身ですが、下図のmacro.hで定義されており、180㎜進むためのステップ数を求めています。タイヤの直径(TIRE_DIAMETER)は、parameters.hで定義されています。
PI:COで使われいるタイヤは直径48㎜、モータは1ステップで0.9度ずつ回転するモータ(1回転に400ステップ必要)を使用しています。
そのため、1ステップ辺りの移動量は、 48×PI/400 となり、
180㎜進む時に必要なステップ数は、 180/(48×PI/400)= 400×180/(48×PI) となります。
while文のカウントは、1回で2進むので、2倍されています。なぜ2倍しているかは後々解説します。

 

 

STEP6-2は、PWMでモータを回します。
今回メインプログラム部分は、part9で説明したモード選択しているだけなので、飛ばします。
モード選択の内容は下図のようになり、モータを励磁させた後122行目から123行目で最高速度・加速度を指定しています。
124行目でstraightが直進走行用の関数で、括弧内の180が移動距離を表しています。

 

続きを読む ›

Posted in Pi:Co Classic3 製作記


マイクロマウス研修 Part11(岩本)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

マイクロマウス研修(岩本)一覧
Part1Part2Part3Part4Part5Part6Part7Part8Part9Part10、Part11

番外
Part8.1

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

こんにちは岩本です。
今回はサンプルプログラムSTEP5の中身を確認していきたいと思います。
まずは、メインプログラムの全体像からです。

 

__cplusplusですが、ファイルの中を全部探しても、定義がどこでされているのか見つかりません。
これは、もともとコンパイラに定義されているマクロであり、C++のコンパイラから読まれたときは有効になり、Cコンパイラから読まれたときはスルーされます。
もう一つextem ”C”もどこにも定義されていません。これは、extem ”C”{} 内に書かれた内容をCでコンパイルするための設定です。
なぜ、こんなにめんどくさい処理をするのかと言うと、C++では、同じ名称でも型などを変えると、違う関数を作ることが出来るため、関数をコンパイルすると内部では関数が修飾されて、名前が変わってしまうためです。(このことをマングルという。)
最後にabortですが、これは、プログラムに何らかの異常が発生した場合、プログラムを終了終了させるための関数です。
この関数は、Cでコンパイルする必要があるため、extem ”C”{}を使っています。

 

今回のメインプログラムは、init_all()とview_adc()です。
なんか見た目、すごく少なく見えますが、関数の中で結構いっぱい処理があります。

 

init_all()の中身はinit.hに記載されていますが、新たにinit_adcが追加されています。

 

続きを読む ›

Posted in Pi:Co Classic3 製作記


マイクロマウス研修 Part10(岩本)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

マイクロマウス研修(岩本)一覧
Part1Part2Part3Part4Part5Part6Part7Part8Part9、Part10

 

番外
Part8.1

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

こんにちは岩本です。
今回は、Part9の解説に一部追記+後々のモータのPWMについて解説しときます。

 

まず、MTUの設定は、init.cで定義されています。

 

126~128行目は、プロテクト解除⇒MTUモジュールをON⇒プロテクト保護を行っています。
MTUの機能は、CMTと同様に省エネの為、初期状態では、電源供給されないようになっています。
また、130行目、タイマストップしているのは、TCRレジスタの設定を行う際、止める必要があるためです。

 

スピーカー用MTUの設定は下図のようになります。
133行目は、PWMのカウントをクリアするタイミングの設定です。
134行目は、カウントする周期の設定。
135行目は、PWMのモードに設定。(このマイコンはモードが複数あるためです。)
136~137行目は、コンペアマッチしたときの動作の設定。
138~139行目は、周波数の設定をしています。

 

この設定で生成される波形は、下図のようになります。

 

続きを読む ›

Posted in Pi:Co Classic3 製作記


マイクロマウス研修 Part9(岩本)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

マイクロマウス研修(岩本)一覧
Part1Part2Part3Part4Part5Part6Part7Part8、Part9

番外
Part8.1

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

こんにちは岩本です。
今回はサンプルプログラムSTEP4の中身を確認していきたいと思います。
まずは、取り敢えずメインプログラムの全体像を確認します。

 

37~43行目の_LED関数の定義は下図の様になっています。
led_dataの値によってLEDの点灯条件を制御しています。
LED0は、led_dataと1を&で比較していますので、led_dataの値が2進数で1桁目が1になった時、点灯します。
LED1は、led_dataを1つ右ビットシフトした後、1と比較していますので、led_dataの値が2進数で2桁目が1になった時、点灯します。
LED2は、led_dataを2つ右ビットシフトした後、1と比較していますので、led_dataの値が2進数で3桁目が1になった時、点灯します。
LED3は、led_dataを3つ右ビットシフトした後、1と比較していますので、led_dataの値が2進数で4桁目が1になった時、点灯します。

 

なお、”>>”はビット演算子の一つで、”右ビットシフト”と呼ばれます。
右辺の値分だけ右にビットをずらします。また、右側の枠からはみ出た値は消えます。(オーバーフロー)

 

led_dataの中に入る値は、64行目で_LED(mode)と呼び出されています。そして、modeの値は53行目で初期値を1と決めています。
そのため、led_dataの値は最初1となり、”LED0=1&1”となりますので、電源を入れたらLED0のみ値が1となり点灯します。
次に55行目からの無限ループの中身ですが、まず57行目では、関数wait_msを使って待ち時間を作っています。
CHATTERING_WAITの中身は、static_parameters.hファイルで10と定義されていますのでwait_ms(30)が引数となります。
58行目、DISABLE_BUZZERの中身は、macro.hでブザーを止めに行っているだけです。
60行目は、Part8でも紹介したので、そちらを見てください。

 

続きを読む ›

Posted in Pi:Co Classic3 製作記


マイクロマウス研修 Part8.1(番外)(岩本)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

マイクロマウス研修(岩本)一覧
Part1Part2Part3Part4Part5Part6Part7Part8

番外
Part8.1

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

こんにちは岩本です。
今回はサンプルプログラムSTEP3で行ったプログラムについて、もっと簡潔なプログラムの書き方を知ったのでそれについてです。
Part8で下図のプログラムの説明を行いましたが、プログラマーの人たちから見るとこの制御文は長すぎるそうです。

 

今回説明する計算方法は、トグルという計算方法です。
トグルを使用すると、0と1を交互に入力する式を簡単に作ることが出来ます。
今回のLEDにこれを当てはめると、下図のようになります。
上図47行目から54行目と同じ結果が、下図47行目の1行で表すことが出来ますし、変数state_rの宣言も必要無くなります。

 

しかし、”^”(ハット)とは何でしょう?
これは、Part8でも少し登場しました”&”と同じビット演算子の1つです。
2つの値があり、どちらか片方だけ1なら1、どちらも0またはどちらも1の場合は0を返します。
概ねaとbをそのまま、足し算している感じですね(1+1は0になりますが)

 

でも47行目の式は”^=”となっていますね
これは、複合代入演算子と言い、式が省略されている物です。

 

続きを読む ›

Posted in Pi:Co Classic3 製作記


マイクロマウス研修 Part8(岩本)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

マイクロマウス研修(岩本)一覧
Part1Part2Part3Part4Part5Part6Part7、Part8

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

こんにちは岩本です。
今回はサンプルプログラムSTEP3の中身を確認していきたいと思います。

まずは、メインプログラムの確認からです。
STEP3_Switchのメインプログラムは下図のような感じです。
33~36行目は、状態を表すための変数の宣言及び代入。
38行目でPart6でも行った各機能の初期化。
41行目while(1)で42~82行目までを無限ループさせています。
43行目のwhileで44行目から56行目をループさせています。()の中身はループを抜け出す条件です。
()内の”&”は、ビット演算子の一つでビットANDと言い、ビットで計算させる方法です。例えば、0&0の答えは0、0&1は0、1&1の時のみ1となります。
プログラムだけ見ていると少しわかりにくいのですが、SWの値はスイッチを押していないときは1(3.3V)、押しているときは0(0V)が出力されます。(教科書14P・20P参考
このような抵抗の使い方をプルアップ抵抗といいます。
そのため、スイッチを押していないときはWhileの中は1(true)となり、無限ループが発生します。しかも、実行文が無いため、何もしなければ43行目から抜け出せません。
逆にスイッチを押した場合は0(false)となり43行目から抜け出すことが出来ます。
ループから抜け出せたら、どれかのSWが押されたことになりますので、45行目・58行目・71行目の対応するif文が読み込まれます。
例えば、45行目のif文でSW_Rが押された場合の動きとしては、47行目でstate_rに1を足しています。”++”はインクリメント演算子と呼ばれ、変数の値に1を足します。
48行目でstate_rが1より大きくなっていた場合0に戻す処理を行っています。
50行目・53行目でstate_rの値が0か1で、LEDを光らせるかどうかを決めています。
84行目・88行目はチャタリングを除去しています。(教科書20P
これは、スイッチを押した瞬間に瞬間的にoffになり、その後再度ONになった場合、2回スイッチが押された判定になってしまいLEDが光らなくならないようにするための処置です。
86行目は、43行目のwhile文と似ていますが、()内の最初に”!”が付いています。これは論理演算子の一つで、”~ではない”という意味になります。
スイッチを押し続けている間は(SW_R & SW_C & SW_L)の値は0となりますが”!”があるため、”0(false)ではない”(=”1(true)”)という答えになります。つまり、SWを離すまで無限ループになります。

 

ちなみに、 SW_ R・SW_ C・SW_ Lは、portdef.hの中で定義されています。

 

続きを読む ›

Posted in Pi:Co Classic3 製作記


マイクロマウス研修 Part7(岩本)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

マイクロマウス研修(岩本)一覧
Part1Part2Part3Part4Part5Part6、Part7

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

こんにちは岩本です。
今回はサンプルプログラムSTEP2の中身を確認していきたいと思います。

まずは、メインプログラムの確認からです。
init_allで初期化した後、BUZZERを1と0で鳴動を制御し、間に時間待ち時間を作っているようです。
あれ、Part5でLED光らせるのととほぼ一緒ですよね。

 

そういえば、Part5のdefineですでにBUZZER定義されていましたね。

 

それにinit_allの中もPart6でinit_ioの設定でブザーポートの初期化も含まれていましたね。

 

ということで他は殆どSTEP1と同じなのでSTEP2ブザーは終わりです。めちゃ早かった。

続きを読む ›

Posted in Pi:Co Classic3 製作記


マイクロマウス研修 Part6(岩本)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

マイクロマウス研修(岩本)一覧
Part1Part2Part3Part4Part5、Part6

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

こんにちは岩本です。
前回に引き続き、プログラム編です。

前回、途中で終わったので、②と③の続きからです。
②init_allの定義について
③include先の定義は?

init_allでは、設定の初期化を行っています。設定内容は、init.hで関数が纏められています。ここでは、プロトタイプの宣言を行っています。
これは関数の定義をする前に関数を呼び出す場合、コンパイルエラーになる事があるため、先に型を宣言しておくためプロトタイプの宣言を行います。
そのため、メインプログラムの方に#include “init.h”で読み込んでいます。

各関数は以下のような設定を行っています。
init_clockは、クロック発生回路の詳細を設定しています。
init_io(Input/Output)では、入出力を設定しています。
init_cmt(コンペアマッチタイマ)では、タイマーの周期を設定しています。インターバルタイマー(一定周期で何らかのアクションを起こす事)に使用します。
init_mtu(マルチファンクションタイマパルスユニット)は、cmtより複雑な設定ができる上位タイマーと言えます。PI:COでは、スピーカーの鳴動周期やPWM(Pulse Width Modulation(パルス幅変調))用の基本波形の生成等の設定を行ってます。
init_adcは、A/D変換の設定を行っています。ここでは、アナログデータの波形をどれだけの変換時間で計測するかを設定しています。

 

そして、関数の定義自体はinit.cの中で行われています。この時、最初にincludeでinit.hを読み込んでプロトタイプの宣言を読みに行っているのが分かると思います。
また、init_allに関しては、init_clock・init_io・init_cmt・init_mtu・init_adc全ての設定を初期化するため最後に纏めています。
ちなみにinit(initialize)は、初期設定ファイルみたいな意味です。
 

 

init.cでたくさん初期化の設定を行っていますが、LEDを光らせるために全ての初期化が必要なわけではありません。(今後のタイヤを回したりするときに必要になる設定も含まれています。)
そのため、今回必要なioポートの設定のみの解説をします。下図のようにPDR(ポート方向レジスタ)で各ioポートに対して、IO_OUT(出力用のポート)の設定しています。

 

続きを読む ›

Posted in Pi:Co Classic3 製作記


マイクロマウス研修 Part5(岩本)

こんにちは岩本です。
今回は、プログラム編です。

前回、ランプを光らせましたが、作られたプログラムをビルドしただけなので、プログラムの内容は全然わかりませんでした。
私は、プログラム初心者なので、どうやって勉強していこうかと思っていたところ、ちょうど良い教材をオーム社より出版されている事を教えていただきました。
本の名称は『マイクロマウスではじめよう ロボットプログラミング入門』というものです。PI:CO用の教材のため、めちゃめちゃ詳しく書いてありますので参考になります。(以下、教科書と表記する。)

まずは、最初から自分でプログラムを書いていこうと思います。
≪ファイル⇒新規作成⇒ 新しいプロジェクトを作成≫から新規プロジェクトを作成します。(教科書70Pを参照)

 

次にPI:COに使用しているマイコン[R5F5631MDxFM(64pin)]を選択し、プロジェクト名を決めて作成します。

 

作成すると、下図のように最初からいくつかのファイルが生成されます。
この中には、マイコン毎に決められた定義がされています。
詳細は、長くなるので必要な時に別途捕捉します。

 

ここに、サンプルプログラムのSTEP1のプログラムを書いていこうと思います。
まず、試しにサンプルプログラムの文章をそのまま書き写してみます。
このプログラムはWhile(1)で{}内を無限ループさせるプログラムのようです。
whileの()内が1で無限ループとなるのは、条件書式は成立した時には値1,不成立の時には値0になるためです。
{}内を見ていくとLED0~3を点灯させて、待ち時間として、iが0~8388607(0x7fffffは16進数です。)をカウントする間、点灯させ続けるようにしているようです。
その後、同じようにLED0~3を消灯させて、待ち時間として、iが0~8388607をカウントする間、消灯させ続けるというもののようです。
ここで、この画面だけでは分からないものが3種類あります。

①LED0~3の定義は?
②init_allの定義は?
③include先の定義は?

 

①LED0~3の定義は?
色々分からない定義がありますが、取り敢えずそのままビルドしてみます。
するとビルドエラーになると思います。エラーメッセージを見ると、LED0~3が定義されていないようです。
ちなみにエラーしたときは、ネットでエラーコードを調べると何が原因か出てくるので、それを参考にしています。

 

エラーが起きた時は、どうやって定義されているのかをサンプルプログラムで確認しながら定義していくと理解が深まると思います。
サンプルプログラムでは、portdef.hの中でdefineで定義されていました。defineは、ファイルを跨いで定義するときなどに使用します。
ifdefの部分は、少し変わったif文です。”PORTDEF”がdefineしてあったらifdefとelseの間の部分が適用されて、defineされていなかったらelseとendifの間の部分が適用されます。
この分を書く意味は同じ定義を何度も定義させないようにするのに役に立ちます。一応無くてもビルドは通ります。

 

続きを読む ›

Posted in Pi:Co Classic3 製作記