- 締切済み
H8/3048 マイコンのプログラムについて教えてください。
すいません、助けてください。 モーターを制御するインバーターがあります。 そのインバーターには、左回り、右回りという、 2つの入力があります。 これは、スイッチをつけて直接グランドに落としている時間だけ回るという入力です。 この入力に対して、H8を追加して動きを自動化したいと思っています。 内容は、 左、右、リミットの3つのスイッチをつけ、 端まで動いて、リミットスイッチが切れたら止まるというものです。 リミットスイッチがOFFの場合、 左または右を押した場合、0.5秒 その方向に回り、停止。 リミットスイッチがONの場合、 左または右を押した場合、リミットスイッチがOFFになったら止まる。 このような動きの場合、どんなプログラムを書けば いいんでしょうか? よろしくお願いします。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- R32C
- ベストアンサー率39% (115/290)
ソースを拝見しましたが、その展示物にはちょっと近くに行きたくないですね。:)#軽く聞き流してください。 典型的な有限状態マシン(FSM)ですので、 一度ステートチャートや、マトリックス表を書いた上でコードにする というのもいいかと思います。 ステートチャートは、フリーのUMLツールなど使ってみては いかがでしょうか。 UMLツールのダウンロードは、会員登録が必要なようです。 「有限状態マシン(FSM)」は、ネットで検索するとわかると思います。
- R32C
- ベストアンサー率39% (115/290)
展示ディスプレイ用の模型を回転させるのでしたら 安全性に注意が必要ですね。 途中、回転を止める操作は別途ハードスイッチで「全停止」するので しょうか、それともそのH8マイコンで停止するのであれば、 回転中にスイッチの読み込みが必要になります。
補足
かなり時間が経ちましたが、あれからいくつか参考になりそうな本を買い Interest さんのプログラムを参考にやってみました。 == /* H8-3048/F */ /* port4からスイッチ情報を入力し、 */ /* port5のLED1とLED2を点灯する。OPT SW */ /* */ /* sw1は、上SW P4.DR.BIT.B4 */ /* sw2は、下SW P4.DR.BIT.B5 */ /* sw3は、リミットSW P4.DR.BIT.B6 */ /* 0=on 1=off */ /* LED 1 は、スピコン上 P5.DR.BYTE = 0x01 */ /* LED 2 は、スピコン下 P5.DR.BYTE = 0x02 */ /* スピコンにはOPT SWにて */ /* sw1 を押すと LED1が点灯する。 */ /* sw2 を押すと LED2を点灯する。 */ /* */ /* sw3 が押されている場合、 */ /* sw1が押された場合、sw3が離されるまでLED1を点灯 */ /* sw2が押された場合、sw3が離されるまでLED2を点灯 */ #include <3048.h> /* メイン関数 ****************************************/ void main(void){ P4.DDR = 0x00; /*port4(16進数0)入力に設定 操作用sw1~4*/ P4.PCR.BYTE = 0xff; /*port4プルアップon */ P5.DDR = 0xff; /*port5(16進数1)出力に設定 表示LED */ P5.PCR.BYTE = 0x00; /*port5プルアップoff */ while(1) { if(P4.DR.BIT.B6 == 0) /*リミットスイッチ状態 == ON*/ { if( P4.DR.BIT.B4 == 0) /*上SW ON*/ { while (P4.DR.BIT.B6 == 1) /*リミットSWがOFFになるまで続く*/ P5.DR.BYTE = 0x01; } else if ( P4.DR.BIT.B5 == 0) /*下SWON*/ { while (P4.DR.BIT.B6 == 1) /*リミットSWがOFFになるまで続く*/ P5.DR.BYTE = 0x02; } } P5.DR.BYTE = 0x00; /*モータを止める*/ else /*リミットスイッチがOFF*/ { if( P4.DR.BIT.B4 == 0 ) /*上SW == ON */ { P5.DR.BYTE = 0x01; } /*port5のLED1を点灯モータを上に*/ else if( P4.DR.BIT.B5 == 0 ) /*下SW == ON*/ { P5.DR.BYTE = 0x02; } /*port5のLED2を点灯モータを下に*/ else if ( P4.DR.BIT.B4 == 1 || P4.DR.BIT.B5 == 1 ) /*上下OFF*/ { P5.DR.BYTE = 0x00; } /*なにもしない*/ } == 上記ですと、sw1,2が押されている状態で、sw3を押すとLEDは点きますが、 希望している仕様にはなりませんでした。 そこで、次の書き込みのようにしました。 GCC Developerで書いているのですが、後半のelseの使い方がエラーで コンパイルできず、どう直したらいいのかわかりません。 この流れで希望の仕様に近づいているでしょうか? ご指導ください。 よろしくお願いします。 == #include <3048.h> /* メイン関数 ****************************************/ void main(void){ P4.DDR = 0x00; /*port4(16進数0)入力に設定 操作用sw1~4*/ P4.PCR.BYTE = 0xff; /*port4プルアップon */ P5.DDR = 0xff; /*port5(16進数1)出力に設定 表示LED */ P5.PCR.BYTE = 0x00; /*port5プルアップoff */ while(1) { if(P4.DR.BIT.B6 == 0) /* リミットスイッチ状態 == ON の場合 */ { if( P4.DR.BIT.B4 == 0) /* 上SW ON */ { while (P4.DR.BIT.B6 == 1) /* リミットSWがOFFになるまで続く*/ P5.DR.BYTE = 0x01; } else if ( P4.DR.BIT.B5 == 0) /* 下SWON*/ { while (P4.DR.BIT.B6 == 1) /* リミットSWがOFFになるまで続く*/ P5.DR.BYTE = 0x02; } } P5.DR.BYTE = 0x00; /* モータを止める */ } else /* リミットスイッチがOFF */ { if( P4.DR.BIT.B4 == 0 ) /* 上SW == ON */ { P5.DR.BYTE = 0x01; } /* port5のLED1を点灯モータを上に */ else if( P4.DR.BIT.B5 == 0 ) /*下SW == ON */ { P5.DR.BYTE = 0x02; } /* port5のLED2を点灯モータを下に */ P5.DR.BYTE = 0x00; /* なにもしない */ } }
- Interest
- ベストアンサー率31% (207/659)
文面からFURUTA_Hさんが学生さんでは無さそうだとお見受けしましたが、お仕事に関係あるご質問なら、この手のサイトを当てにするのはリスクが大きいですよね。 すごーくザックリですが日本語で書いてみました。 while(1){ リミットスイッチ状態 = リミットスイッチの状態を取得する(); 左右スイッチ状態 = 左右スイッチの状態を取得する(); if( リミットスイッチ状態 == OFF ){ if( 左右スイッチ状態 == 右 ){ モータを右に回す(); 500ms待つ(); モータを止める(); } else if( 左右スイッチ状態 == 左 ){ モータを左に回す(); 500ms待つ(); モータを止める(); } else{ // 左右スイッチが真ん中にある状態 なにもしない。 } } else{ // リミットスイッチがON if( (左右スイッチ状態 == 右) || (左右スイッチ状態 == 左)){ while( ON == リミットスイッチの状態を取得する() ){ モータを回す回す(); // どちらに回す? 仕様未定義!! } モータを止める(); else{ // 左右スイッチが真ん中にある状態 なにもしない。 } } }
補足
具体的な書き込みありがとうございます。 氏のプログラムを元にやってみました。 詳細は、最新の書き込みにしました。 再度、ご指導よろしくお願いします。
- Interest
- ベストアンサー率31% (207/659)
こんな内容が学校の課題だとも思えませんし、高々この程度の処理を行うのにH8/3048にOSをのせることも無かろうと思います。 ここでいう「インバータ」は、論理を反転させる素子という意味でいいですか? ごくあたりまえなマイコンのプログラムの流れからすると、 1.スタートアップルーチン(アセンブリ言語) 2.周辺回路の初期化 3.(割り込みを使うなら割り込み許可) 4.主となる処理を行う無限ループ 左右スイッチの操作で割り込みをかけられるかどうかは回路図みてないとわかりませんが、どうなっていますか? > リミットスイッチがOFFの場合、 > 左または右を押した場合、0.5秒 その方向に回り、停止。 > > リミットスイッチがONの場合、 > 左または右を押した場合、リミットスイッチがOFFになったら止まる。 この仕様からは (a) 左スイッチまたは右スイッチが押されていない場合 (b) 左スイッチまたは右スイッチが同時に押された場合 (c) 左スイッチが押されたまま右スイッチが押され、左スイッチが離された場合 等にどのように動けばよいのか読み取れません。 また、「スイッチが押された」というのは、 (1) 押し下げられた時点 (2) 押されたままの状態 (3) スイッチから手が離れた時点 のどのタイミングで判断するのでしょうか。
補足
ご回答ありがとうございます。 >こんな内容が学校の課題だとも思えませんし、高々この程度の処理を行うのにH8/3048にOSをのせることも無かろうと思います。 はい、学校の課題でもありません。 約 30cmほどの展示ディスプレイ用の模型を動かそうと思っております。 H8の選択は、過去に買ったものが手付かずになっていたため 今度こそ使えないかと思った次第です。 >ここでいう「インバータ」は、論理を反転させる素子という意味でいいですか? インバーターとは、モーターを駆動させるためのインバーターで、 その入力端子は、時計回り、反時計回りの2つの入力があり、 それぞれをグランドに落とすとモーターが回ります。 また、その入力には、フォトカプラやリレーで入力できるものです。 >左右スイッチの操作で割り込みをかけられるかどうかは回路図みてないとわかりませんが、どうなっていますか? 回路図に関しては、現在、下記のそれぞれの端子があるのみです。 時計回り、反時計回り、グランド 両側跳ね返りの2回路3接点 リミットスイッチの押してON、グランド です。 リミットスイッチですが、 リミットスイッチ自体が、ギヤボックスに付いています。 そのギヤボックスに、アルミの角パイプが通るようになっており、 ギヤボックス自体がパイプに沿って左右に動きます。 角パイプの両側の側面に、穴を開け、 その穴をリミットスイッチが検知するという仕組みの模型です。 秋月のH8/3048に、それぞれを入力できれば…と思っています。 >> リミットスイッチがOFFの場合、 >> 左または右を押した場合、0.5秒 その方向に回り、停止。 >> >> リミットスイッチがONの場合、 >> 左または右を押した場合、リミットスイッチがOFFになったら止まる。 >この仕様からは >(a) 左スイッチまたは右スイッチが押されていない場合 >(b) 左スイッチまたは右スイッチが同時に押された場合 >(c) 左スイッチが押されたまま右スイッチが押され、左スイッチが離された場合 >等にどのように動けばよいのか読み取れません。 仕様に関しては、 b) と c)は、跳ね返りのスイッチのためありません。 >また、「スイッチが押された」というのは、 >(1) 押し下げられた時点 >(2) 押されたままの状態 >(3) スイッチから手が離れた時点 >のどのタイミングで判断するのでしょうか。 スイッチが押されたというのは、 1)のスイッチが押し下げられた時点です。 こんな状況です。 よろしくお願いします。
- EgEg000
- ベストアンサー率50% (1/2)
FURUTA_Hさん こんにちは。 インバーターへの信号をH8で出すということですが、、、 たぶん、インバーター入力は24Vor12Vなので、、直接ドライブできないですよね? どうするのでしょうか? あと、H8のどのピンにどの信号を追加するのか、もう少し具体的に 回路図などを提示してくれないと答えにくいです。 そして、利用する言語やOSなども明らかにしていただいたほうが 回答しやすくなると思います。 よろしく!!
お礼
EgEg000 さん ご回答ありがとうございます。 詳細も書くべきできた。 すいません。 わかる範囲での詳細は、まとめて最新のご回答に レスさせていただきます。 ありがとうございました!
- jacta
- ベストアンサー率26% (845/3158)
マイコンのプログラムの場合、学校の課題ではなく仕事の可能性が高い気がしますが(高専とかならあるかも)... 仕事を丸投げするのであれば、有償が原則です。しかるべき外注費を払って、しかるべき場所で商談を行ってください。
補足
jacta さまへ ご回答ありがとうございます。 そのしかるべき場所がわからずに こちらに書き込んでしまいました。 大変失礼致しました。
お礼
UMLツールを拝見しました。 早速研究してみます。 ありがとうございました。