• 締切済み

H8/3048 マイコンのプログラムについて教えてください。

すいません、助けてください。 モーターを制御するインバーターがあります。 そのインバーターには、左回り、右回りという、 2つの入力があります。 これは、スイッチをつけて直接グランドに落としている時間だけ回るという入力です。 この入力に対して、H8を追加して動きを自動化したいと思っています。 内容は、 左、右、リミットの3つのスイッチをつけ、 端まで動いて、リミットスイッチが切れたら止まるというものです。 リミットスイッチがOFFの場合、 左または右を押した場合、0.5秒 その方向に回り、停止。 リミットスイッチがONの場合、 左または右を押した場合、リミットスイッチがOFFになったら止まる。 このような動きの場合、どんなプログラムを書けば いいんでしょうか? よろしくお願いします。

みんなの回答

  • R32C
  • ベストアンサー率39% (115/290)
回答No.6

ソースを拝見しましたが、その展示物にはちょっと近くに行きたくないですね。:)#軽く聞き流してください。 典型的な有限状態マシン(FSM)ですので、 一度ステートチャートや、マトリックス表を書いた上でコードにする というのもいいかと思います。 ステートチャートは、フリーのUMLツールなど使ってみては いかがでしょうか。 UMLツールのダウンロードは、会員登録が必要なようです。 「有限状態マシン(FSM)」は、ネットで検索するとわかると思います。

参考URL:
http://jude.change-vision.com/jude-web/product/community.html
FURUTA_H
質問者

お礼

UMLツールを拝見しました。 早速研究してみます。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • R32C
  • ベストアンサー率39% (115/290)
回答No.5

展示ディスプレイ用の模型を回転させるのでしたら 安全性に注意が必要ですね。 途中、回転を止める操作は別途ハードスイッチで「全停止」するので しょうか、それともそのH8マイコンで停止するのであれば、 回転中にスイッチの読み込みが必要になります。

FURUTA_H
質問者

補足

かなり時間が経ちましたが、あれからいくつか参考になりそうな本を買い 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)
回答No.4

文面からFURUTA_Hさんが学生さんでは無さそうだとお見受けしましたが、お仕事に関係あるご質問なら、この手のサイトを当てにするのはリスクが大きいですよね。 すごーくザックリですが日本語で書いてみました。 while(1){  リミットスイッチ状態 = リミットスイッチの状態を取得する();  左右スイッチ状態   = 左右スイッチの状態を取得する();  if( リミットスイッチ状態 == OFF ){    if( 左右スイッチ状態 == 右 ){      モータを右に回す();      500ms待つ();      モータを止める();    }    else if( 左右スイッチ状態 == 左 ){      モータを左に回す();      500ms待つ();      モータを止める();    }    else{ // 左右スイッチが真ん中にある状態      なにもしない。    }  }  else{     // リミットスイッチがON    if( (左右スイッチ状態 == 右) || (左右スイッチ状態 == 左)){     while( ON == リミットスイッチの状態を取得する() ){      モータを回す回す(); // どちらに回す? 仕様未定義!!     }     モータを止める();    else{ // 左右スイッチが真ん中にある状態      なにもしない。    }  } }

FURUTA_H
質問者

補足

具体的な書き込みありがとうございます。 氏のプログラムを元にやってみました。 詳細は、最新の書き込みにしました。 再度、ご指導よろしくお願いします。

全文を見る
すると、全ての回答が全文表示されます。
  • Interest
  • ベストアンサー率31% (207/659)
回答No.3

こんな内容が学校の課題だとも思えませんし、高々この程度の処理を行うのにH8/3048にOSをのせることも無かろうと思います。 ここでいう「インバータ」は、論理を反転させる素子という意味でいいですか? ごくあたりまえなマイコンのプログラムの流れからすると、 1.スタートアップルーチン(アセンブリ言語) 2.周辺回路の初期化 3.(割り込みを使うなら割り込み許可) 4.主となる処理を行う無限ループ 左右スイッチの操作で割り込みをかけられるかどうかは回路図みてないとわかりませんが、どうなっていますか? > リミットスイッチがOFFの場合、 > 左または右を押した場合、0.5秒 その方向に回り、停止。 > > リミットスイッチがONの場合、 > 左または右を押した場合、リミットスイッチがOFFになったら止まる。 この仕様からは (a) 左スイッチまたは右スイッチが押されていない場合 (b) 左スイッチまたは右スイッチが同時に押された場合 (c) 左スイッチが押されたまま右スイッチが押され、左スイッチが離された場合 等にどのように動けばよいのか読み取れません。 また、「スイッチが押された」というのは、 (1) 押し下げられた時点 (2) 押されたままの状態 (3) スイッチから手が離れた時点 のどのタイミングで判断するのでしょうか。

FURUTA_H
質問者

補足

ご回答ありがとうございます。 >こんな内容が学校の課題だとも思えませんし、高々この程度の処理を行うのに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)
回答No.2

FURUTA_Hさん こんにちは。 インバーターへの信号をH8で出すということですが、、、 たぶん、インバーター入力は24Vor12Vなので、、直接ドライブできないですよね? どうするのでしょうか? あと、H8のどのピンにどの信号を追加するのか、もう少し具体的に 回路図などを提示してくれないと答えにくいです。 そして、利用する言語やOSなども明らかにしていただいたほうが 回答しやすくなると思います。 よろしく!!

FURUTA_H
質問者

お礼

EgEg000 さん ご回答ありがとうございます。 詳細も書くべきできた。 すいません。 わかる範囲での詳細は、まとめて最新のご回答に レスさせていただきます。 ありがとうございました!

全文を見る
すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

マイコンのプログラムの場合、学校の課題ではなく仕事の可能性が高い気がしますが(高専とかならあるかも)... 仕事を丸投げするのであれば、有償が原則です。しかるべき外注費を払って、しかるべき場所で商談を行ってください。

FURUTA_H
質問者

補足

jacta さまへ ご回答ありがとうございます。 そのしかるべき場所がわからずに こちらに書き込んでしまいました。 大変失礼致しました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 神社の本殿の参拝

    神社の本殿の周りに道がある場合右回り、左回りどちらで回ったらいいのでしょう? つまり、本殿に向かって右・左どちらに行けばいいのでしょうか

  • H8マイコンでC言語で、パルスモータを制御

    パルスモータを使用した、自動車のパワーウィンドウシミュレートプログラムを作成したいのですが、if文の書き方がわかりません。 1.プログラム開始時、窓が閉まっている状態を想定。2.完全に閉じた状態から左回りに5回転したときの状態を完全に開いた状態とする。3.完全に開いた状態から右回りに5回転したときに、窓が完全に閉じた状態となる。 キー入力は、A :左回り全開:窓が完全に閉じた状態(5回転目)になるまで左回転し、停止。B :左回り部分開:キー押下時に左回転。キーを離す、窓が完全に閉じた状態になったら停止。C :右回り部分閉:キー押下時に右回転。キーを離す、窓が完全に開いた状態になったら停止。D :右回り全閉 :窓が完全に開いた状態(5回転目)になるまで右回転し、停止。 ヒントを教えてください。お願いします。 #include <stdio.h> #include <key.h> /* 外部ポート A1,B1,C1 */ #define EPA1 (*((unsigned char *)0x60000)) #define EPB1 (*((unsigned char *)0x60001)) #define EPC1 (*((unsigned char *)0x60002)) #define EPCW1 (*((unsigned char *)0x60003)) void wait(long); void counterclockwise (void); void clockwise (void); unsigned char Keydat, count, cf, state; int cwpuls,ccwpuls; void main(){ //開始時は、窓が閉じている状態 state = 0; //回転数を初期化 count = 0; /* uPD71055(82c55) 初期化 */ init_key(); Keydat = 0; cf = 0; while (1) { if((Keydat = get_key_code())==KEY_A){ //左回り全開 clockwise(); //全開(5回転目)になったら停止 EPC1 = 0; /* 一度電流OFF */ wait(90000);/* 時間まち */ } else if (Keydat == KEY_B){ //左回り部分開 clockwise(); //全開(5回転目)になったら停止 EPC1 = 0; /* 一度電流OFF */ wait(90000);/* 時間まち */ } else if (Keydat == KEY_C){ //右回り部分閉 counterclockwise(); //全閉(5回転目)になったら停止 EPC1 = 0; wait(90000); } else if (Keydat == KEY_D){ //左回り全閉 counterclockwise(); //全閉(5回転目)になったら停止 EPC1 = 0; wait(90000); } } } void wait(long time) { long i; for (i = 0; i < time; i++) ; } void counterclockwise (void){ for (cwpuls = 0; cwpuls < 96; cwpuls++){/* CW方向96パルス回す*/ cf++; if (cf == 4) { cf = 0; } /* 励磁相カウンタ+1*/ switch (cf) { case 0:EPC1 = 0x50; /* 励磁パターン出力 */ break; case 1:EPC1 = 0x60; break; case 2:EPC1 = 0xa0; break; case 3:EPC1 = 0x90; break; } wait(1000); // モーター速度 } } void clockwise (void){ for (ccwpuls = 0; ccwpuls < 96;ccwpuls++){/* CCW方向96パルス回す*/ cf--; if (cf == 0xff) { cf = 3; } /* 励磁相カウンター -1 */ switch(cf) { case 0:EPC1 = 0x50; /* 励磁パターン出力 */ break; case 1:EPC1 = 0x60; break; case 2:EPC1 = 0xa0; break; case 3:EPC1 = 0x90; break; } wait(1000); //200~500が限界 } }

  • 四畳半のたたみの敷き方

    本当にくだらない質問ですみません。 四畳半の敷き方を教えてください。 (言葉だけだと難しいですが、下の文章を理解してください。) 半畳を真ん中にして、右回りと左回りができると思います。 半畳に立ったとして、その前の半畳3枚分で一畳横長になるのは まん前の半畳分とその右ですか?左ですか? (右だと多分右回り、左だと多分左回りな気がします。)

  • 金庫の開け方について

    金庫の開け方について教えて下さい。 例えば、以下のダイヤルの場合、どのようにまわしていくのでしょうか?(防犯上の為、実際の数字とは変えてあります) 右4回 34 左3回 72 右2回 55 左1回 04 自分は、一番初めは0から右に回し、0を4回越えてから34で止め、左回りで0を3回過ぎてからの72で止め、右回りで0を2回越えた55で止め、左回りに0を1回越えてすぐの04で止めていますが、開きません。いろいろなパターンでやっているのですが、うまくいきません。 どなたか、助けてください。

  • 100V/200V4Pモーターが現在ついています、パワーが無く・・・

    100V/200V4P400Wモーターが現在ついています、パワーが無く・・・困っています、良い方法がありましたら、お教え願います。 富士電機さんのMBC6087Aと言う100V200Vモーターが付いています、機械はタイヤ交換の右回り左回りに使用しています、今現在は100V50HZ使用です、200Vにした方がパワーはありますか?また、インバーターを購入して三相200Vで2本使用するとか??本体側は4本のスイッチからの配線です。ご意見をお願いいたします。

  • スイッチ・インバータ・タイマー・モーターの接続方法

    当方、配線の知識がほとんどありません。 スイッチ・インバータ・タイマー・モーター(三相)の接続を考えています。スイッチを1度押し、回転速度を調整する目的でインバータを介してモーターを動かし、3秒後に停止させます。インバータの制御回路でスイッチを押している間だけ作動するまではできたのですが、タイマーをどのように接続したらよいかわかりません。当方のインバータは古いのか、タイマー機能がありません。簡単な説明過ぎますが、ご存知の方、よろしくお願いいたします。 スイッチ:接点構成1aの押しボタン インバータ:パナソニック dv-551 タイマー:富士電機機器制御 MS4SA モーター:産業用汎用モーター

  • 時計回りっていつから?

    日本では「右回り、左回り」っていうのを欧米では「clockwise(時計回り)とかcounterclockwise(逆時計回り)」なんていいますね。日本でも環状線なんかに使われています。右・左というより判り易くてありがたいのですが、時計の発明される前はなんて言っていたのでしょう?右回り、左回りなど生物発祥以来の現象ですし、時計は最近の文明のはず。どなたか教えてください。

  • ACモータの位相制御とインバータ制御

    Q1. 単相ACモータの速度制御には インバータ制御とトライアック等による位相制御がありますが 両者はどのような場合に使い分けられているのでしょうか? Q2. (1)インバータ制御は使えなくて位相制御しかできないモータ (2)位相制御は使えなくてインバータ制御しかできないモータ (3)どちらも使えるモータ モータの種類によって、そのように分類されることが ありましたら教えてください。

  • DCモータの回転方向

    DCモータの回転方向をトグルスイッチを使って制御したいのですが,トグルスイッチには「ON-OFF-ON」を使って,スイッチがOFFのとき,モータをブレーキ状態にさせる回路はどのように作ればいいでしょうか? また,回転方向を切り替えるトグルスイッチ1つで,2・3個のモータを別々に動かす場合,どこにスイッチを入れるのが一番いいでしょうか?

  • インバータとモータ

    どなたか、よろしくお願いします。 シーケンサ(FX2N-32MR、DC24入力、DC24Vリレー出力)とインバータ(FR-S540E-0.4K)で0.2kwのモータ二つを同時制御(ON/OFF)しようと思ってます。 モータブレーキの制御方法について教えてください。 よろしくお願いします。