Elseは、If文の条件が成り立たなかった場合、ElseからEndIfまでの<文>(命令)を実行します。前進EndIfLoop条件ループ文を使った例です。10LoopPA(ポートA)、PC(ポートC)の値を直接読んだり出力することでも同じことが出来ます。詳しくはこちらをご覧ください。※ここでは2進数(B'101')を使っています。2進数や16進数はこちらをご覧ください。※上の例の前進のように引数を省略すると前進の信号を出した後、待ち時間なしで次の命令を実行できます。DEFINEは第1引数の名前を定義して第2引数から次の行までの<文>に置き換えます。解かりやすい命令や定数を定義したりします。※定義名は数字以外で始まり半角アルファベット、全角文字、数字が使えますが半角と全角の混在は禁止です。//In2またはIn3(OR条件)がLowならThenからEndIfの間を実行UターンEndIfLoopプログラムで何回も同じ処理をすることがあります。この部分をサブルーチン(部品)化するとプログラムが見やすくコンパクトになります。BASICではプロシージャと関数にあたりますが両者の違いは関数は値を返しますがプロシージャは返しません。下は前のプログラムにメロディのプロシージャを追加したものです。最初と障害物を感知した時、動作します。//第2引数Wのパルス幅の音を0.2秒鳴らすNextEndProcプロシージャや関数はそのままではなにも動作しません。呼び出しによって動作し処理の終わりとともに呼ばれた場所に戻ります。どこに在ってかまいませんがプログラムの見やすさを考えると後半に置いた方が良いでしょう。※最初に実行する部分(上の例ではMELODYからLoopまで)をメインプログラム、プロシージャや関数部分をサブプログラムと呼びます。BASICでは変数を使った演算ができます。下のプログラムは触覚が障害物を感知した回数をカウントし、3回ごとにメロディを2回鳴らすというものです。//第2引数Wのパルス幅の音を0.2秒鳴らすNextEndProcプロシージャと違い関数は値を返します。引数として使っています。このように関数は引数など<式>の中で使うことができます。このプログラムを実行して0,1ビット(左の触覚:In2と右の触覚:In3)をアース(ビスに接触)してみてください。ブザーの回数が変わるはずです。※関数は<式>以外でもプロシージャのように独立して使うこともできます。ポートAの0,1ビットをマスクして戻り値とするEndFunction※myubasic.iniを編集(例えば、'前進'を'FF'に変える)すると命令をカスタマイズすることができます。※いろいろなロボットの工作例はこちら※メロディなど音階の設定はこちら※ゆっくり前進したいなどモーターのスピードをコントロールするにはこちら※RCサーボの制御はこちらそのほかいろいろなことが出来ます。BASIC言語仕様やリファレンスなどをご覧ください。以下は次の行までなにも実行しない。CPUが16F630の場合、使えません。88専用)を使わないかぎり値は全てByte型(0-255)となり以下の注意が必要です。※Byte型の-1は255と判断されます。1-2の計算結果は255となり、255(-1)+1は0となります。※一般に-1<0は真ですがByte型では255<0と判断され偽となります。Nextループを実行しません。255の場合、Aが255の次に0に戻る為、無限ループとなります。-1の場合、Aが0の次に255となる為、無限ループとなります。88専用)の場合、この問題はありません。※T1L,T1Hは連動して動く125KHzの16ビットタイマです。T1Lは0.008mSec,T1Hは0.008x256=2.048mSecで動作し524.288mSecで一周します。88の場合、T1Lは0.004mSec,T1Hは0.004x256=1.024mSecで動作し262.144mSecで一周します。<変数名、プロシージャ名、関数名について>半角の英文字で始まり英文字、数字、'_'が使用できる。大文字、小文字の区別はしない。文字数によってコンパイルされるプログラムサイズは変化しない。88専用)で宣言してから使う。Byte型またはInt型で宣言した変数はグローバル変数となりプログラム中どこでも有効です。変数は','コンマで区切って複数宣言できる。配列は()内に数を指定する。使える変数、配列、内部スタックの合計はCPUが16F630の場合は、9バイト以下。プログラムサイズは127バイトまで。※CPUが16F688の場合は、80バイト以下。プログラムサイズは255バイトまで。※CPUが16F88の場合は、80バイト以下。プログラムサイズは2047バイトまで。※プロシージャ、関数を呼出すとローカル変数の数だけ関数はさらに戻り値の1バイト分内部スタックを使います。プロシージャ、関数から戻ると内部スタックは開放されます。//変数AbcとDD(0)からDD(3)までの配列が使える<プロシージャと関数>プログラムで何回も同じ処理をすることがあります。この部分をプロシージャや関数としてまとめ呼び出すようにするとプログラムが見やすくコンパクトになります。引数を設定して値を変えて呼び出すことで複雑な処理も可能になります。関数は値を返すことができ<式&gtの中で使うことができます。EndFunctionの間に処理を書きますが、そのままではなにも動作しません。呼び出しによって動作し処理の終わりとともに呼ばれた場所に戻ります。()内に変数を宣言するとローカル変数となります。呼び出しはプロシージャ名、関数名で行いますが引数は省略できます。関数は引数を()で囲う。ローカル変数は引数を値渡しで受け取ります。関数は内部で値を関数名に代入することで外部に返します。※呼び出し側の引数よりローカル変数を多く宣言した場合、多い部分は受け渡しの無いローカル変数として使えます。※プロシージャ、関数内からプロシージャや関数の呼び出しはCPUが16F630の場合、深さ8レベルまで可能。※CPUが16F688の場合、深さ20レベルまで可能。※CPUが16F88の場合、深さ10レベルまで可能。※ローカル変数や関数は内部スタックを使うため、深い呼び出しはスタックエラーとなります。※ローカル変数は局所変数ともいい宣言したプロシージャ、関数内のみ有効な変数です。BASICでは転送ボタン(V1.26)を押した時、コンパイルと同時にエラーチェックを行います。文法エラーがあった場合、ダイヤログが現れエラー部分が表示されコンパイルは中止されます。コンパイルされた場合、右下のボックスにコンパイルサイズやミュウロボ命令が表示されます。◆PwerOnStartについてPwerOnStart命令がプログラムの先頭に入っていると基板のスイッチONとともにプログラムがスタートします。この状態で新しいプログラムを転送するには、一旦スイッチを切り、転送ケーブルを接続してから基盤のスイッチを入れれば新しいプログラムを転送できます。ところがパソコンの中には、この方法で転送できないものがあります。この対応についてはこちら<ミュウロボ制御基板のエラーについて>ミュウロボ制御基板では以下の場合、エラーとなり警告音を鳴らし続けます。1、127バイト以上の転送。CPUがPIC16F688の場合は255バイト2、深さ8レベル以上のプロシージャ、関数の呼び出し。スタックの合計が9バイトを越えた場合。88の場合は80バイト4、16F630以外ででコンパイルしたものをPIC16F630に転送したとき。BASIC側で正しくコンパイルされても127バイトを越えた転送はエラーとなります。※エラーの場合は一旦電源を切りプログラムを修正してから再転送してください。以下は次の行までなにも実行しない。Byte型の変数や配列をコンマで区切って宣言する配列は()内に数を指定する。Int型の変数や配列をコンマで区切って宣言する配列は()内に数を指定する。第1引数のプロシージャを第2引数の回数(0-255)を繰り返す。デバッグモードとなりレジスタの値をシリアルポートに出力。プログラムポインタ:コマンドコード:AH.A.ARG2.ARG1.IXP.IX.IXM.FSR.INDFレジスタの内容をシリアルポートに出力し停止。BASICで扱う値は全てバイト型(0-255)です。-1は255と同じです。Nextループを実行しません。255の場合、Aが255の次に0に戻る為、無限ループとなります。-1の場合、Aが0の次に255となる為、無限ループとなります。関数から抜け出し呼ばれた場所に戻る※myubasic.iniを編集(例えば、'前進'を'FF'に変える)すると命令をカスタマイズすることができます。※モーター制御命令などの出力命令は、出力命令以外の命令の間も出力状態を維持します。前進の後、Buzzerを実行するとブザーを鳴らしながら前進します。BASICの入出力プログラムミュウロボ制御基板はPIC16F630を使って入出力をコントロールしています。ポートAはRA5以外入力用、ポートCは出力に設定されています。S4,M2L<基板の入力ポート:In1-In4>In1からIn4はセンサーなどを接続する入力ポートです。In1にはタクトスイッチが標準で接続されています。これらの入力ポートはプルアップされていて入力が無い状態ではHighとなっています。Thenなどの命令が用意されています。下はタクトスイッチ(In1)が押されたときブザーを鳴らすプログラム例です。上の回路図からスイッチが押されるとIn1(RA4)がLowになることを理解してください。1EndIfLoopこれらのプログラムはどれも同じ動作をしますがコンパイルサイズは異なります。ポートAのビット4(RA4)だけを調べる方法ですがビット4は16進表記で&h10、10進表記で16です。これとポートAとAND演算を行うことで可能です。このようにAND演算して特定のビットだけを選別することをマスクするといいます。<基板の出力ポート:S1-S6>S1からS6はRCサーボを制御するポートですが右図のように抵抗を介してLEDを光らせることもできます。LB1638)が接続されていてDCモーターの制御が可能です。BASICの出力命令には"前進","右回り","停止"などのモーター制御命令、ポート出力命令"PortOut"などがある他、PA(ポートA)やPC(ポートC)に直接値を代入する方法もあります。※モーター制御命令などの出力命令は、出力命令以外の命令の間も出力状態を維持します。前進の後、Buzzerを実行するとブザーを鳴らしながら前進します。第1引数(0-255)x0.1秒だけ第2引数のデータ(0-255)をポートに出力するPortOut命令は、出力する時間とPIC16F630のポートCの下位6ビットとポートAの5ビット目を組み合わせた値を指定します。前進(5)とモーター左(16)を同時実行するには、それそれの値を加えた値(21)をポートに出力します。実行すると前進します。2進表記を使うとビット操作が解りやすくなります。書くことで可能となります。上の回路図を見るとポートAのビット5は出力に設定され基板のLEDと圧電ブザーに繋がっています。これを0.1秒ごとに反転するプログラムを作ってみました。ビットを反転するにはXORを使います。//0.1秒のウエイトLoop◆2進数と16進数コンピュータデータの最小単位はビットです。1か0、ONかOFFかです。これが8つ集まった単位がバイトとなります。1バイトはB'00000000'からB'11111111'までの数、0から255までの数字を扱います。16進数は4ビットを0からFの1文字で表しますから1バイトは上位4ビット、下位4ビットの2文字で表現します。上の表から後退を2進数で表すとB'00100010'となり10進数では34となります。これを16進では左表から&h22と表します。ポート出力命令や下のLED制御ではビットごとのデータを扱うので2進数や16進数を使うと便利です。(10進数の16)●ブレッドボードを使ったLEDの制御ブレッドボードを使うと電子回路の実験が簡単にできます。ミュウロボ制御基板側には電子部品店で売られているシングルピンソケット(メス)を半田付けしてありブレッドボードのLEDとはジャンパー線を使って上右図の配線をしてあります。基板で使われているPIC16F630はポートCが出力にセットされていて抵抗を介してLEDを直接点灯させることができます。<PortOut命令を使ってLEDを光らせる>ポート出力命令は、出力する時間とPIC16F630のポートCの下位6ビット(RC0-RC5)とポートAの5ビット目を組み合わせた値を指定します。※右上図の配線の場合、各LEDはポートCの値によって光ったり消えたりします。第2引数のデータn(0-255)をポートに出力する◆2進数を理解する右図は、10進数と2進数の比較表です。2進数の'1'はLEDの点灯、'0'は消灯となります。PortOut命令の第2引数を'5'とした場合、右表から2進数では'0101'となりますからLEDは1つおきに光ります。逆に'1010'と光らせるには、ポート出力命令の第2引数を10進数の'10'と指定します。下のプログラムは0.1秒ごとLEDを交互に光らせたものです。//ポートCにB'1010'(10)を0.1秒間出力Loop◆2進数・16進数の表記方法B'1010'と書くと2進数を表記できます。これは右表から10進数の10です。※上のプログラムはLED4個を交互に光らせているものです。値を変えることでLED6個の制御ができます。<ポートCに直接値をセットしてLEDを光らせる>ポートC(PC)に値を入力後、時間命令(wait)を実行することでLEDを光らせることができます。m下のプログラムは0.1秒ごとLEDの2進数を1づつ増やすというものです。ポートCの値を1づつ増やしています。//0.1秒の待ち時間LoopMYUROBO-1基板には入力ポートを4個持っています。In1には標準でタクトスイッチが接続されています。下のプログラムはタクトスイッチを押した時、ポートCの値を1減らし離すと1増やすよう上のプログラムを改良したものです。//0.1秒の待ち時間Loop下のプログラムはシフト命令を利用してタクトスイッチを押している間LEDが下か上へ、離している間上から下へ点灯するようにしてあります。0EndIfLoop。