6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

obniz Boardで4台のDC Motorを直接ドライブする方法(4WDメカナムホイール車)

Posted at

#■物語の始まり、想定外のエラーに遭遇
obniz Boadって1つの端子で電流1Aまでとれるので、DC Motorも直接ドライブできてとても便利ですよね。ライブラリも用意されていて、正転も逆転もスピードも簡単にコントロールできるんですよね。
ということで、DC Motor4台をobnizに直接接続してライブラリを使ってメカナムホイール車を走らせるべく、次のようなコードを書きました。
image.png
ところが、下記のエラーで拒否られてしまいました。
image.png

#■ライブラリで制御できるDC Motorは3台まで!!
obnizのDC MotorライブラリはPWMで動いていて、1台のDC Motorで正転と逆転でそれぞれ1つづつ計2つのPWMを占有するようです。obnizのPWMの総数は6個というH/W制約があるため、ライブラリで制御できるDC Motorは3台までということになります。よって、4台目を宣言すると上記のエラーになるわけです。
#■4台の直刺しDC Motorを制御する代替Tips
#正転と逆転で動的に+/-のピンアサインを変更することで、1台のDC Motorを1つのPWMで制御します。
具体的には、+側にしたいピンにPWMを割り当て、-側にしたいピンをoutputでfalseにします。PWMのduty比を変える事でスピードを指定します。これにより4台のDC Motorを接続した場合でも、使用するPWMは4つで済みPWM最大6っまでという制約内で動作させることがてきます。
(原理的には、この方式で最大6台までのDC Motorを直刺しで制御できます。)

##以下0番ピンにDC Motorの-を、1番ピンに+を接続し、スピード50%で制御する場合のコード例です。pwm番号は、DC Motor毎に変えます。
##正転

await obniz.io0.output(false);
await obniz.pwm0.start({io:1});await obniz.pwm0.duty(50);

##逆転

await obniz.io1.output(false);
await obniz.pwm0.start({io:0});await obniz.pwm0.duty(50);

##停止

await obniz.pwm0.end();  

#■(参考)4WDメカナムホイール車への応用例
##動画

##車体
WIN_20191107_12_02_46_Pro.jpg

WIN_20191107_12_01_08_Pro.jpg

##コード

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    <script src="https://unpkg.com/obniz@2.4.0/obniz.js" crossorigin="anonymous"></script>
   </head>
<body>
  <br>
  <font size="5" color="#000000">
  メカナムカー 4WD Direct
  </font>
  <br><br>
  <button id="FORWARD_LEFT"  class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>
  <button id="FORWARD"       class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>
  <button id="FORWARD_RIGHT" class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>
  <br><br>
  <button id="LEFT"          class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>
  <button id="STOP"          class="btn btn-warning" style="width:30%;height:50px;font-size:30px;">停止</button>  
  <button id="RIGHT"         class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>
  <br><br>  
  <button id="BACK_LEFT"     class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>  
  <button id="BACK"          class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>
  <button id="BACK_RIGHT"    class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>
  <br><br> 
  <button id="TURN_LEFT"     class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>
  <button id="NULL2"         class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>  
  <button id="TURN_RIGHT"    class="btn btn-warning" style="width:30%;height:50px;font-size:30px;"></button>
  
<script>
const SP =50;   //走行スピード、上げ過ぎるとLow batteryになるので注意
var obniz = new Obniz("OBNIZ_ID_HERE"); 
obniz.onconnect = async function () {
   /**************/
   /* BUTTON操作 */
   /**************/
   //前進
   $("#FORWARD").on('touchstart mousedown',      async ()=> { await FORWARD(SP);       })
   $("#FORWARD").on('touchend mouseup',          async ()=> { await STOP();            })
   //左前
   $("#FORWARD_LEFT").on('touchstart mousedown', async ()=> { await FORWARD_LEFT(SP);  })
   $("#FORWARD_LEFT").on('touchend mouseup',     async ()=> { await STOP();            })
   //右前
   $("#FORWARD_RIGHT").on('touchstart mousedown',async ()=> { await FORWARD_RIGHT(SP); })      
   $("#FORWARD_RIGHT").on('touchend mouseup',    async ()=> { await STOP();            })
   //左横
   $("#LEFT").on('touchstart mousedown',         async ()=> { await LEFT(SP);          })
   $("#LEFT").on('touchend mouseup',             async ()=> { await STOP();            })
   //右横
   $("#RIGHT").on('touchstart mousedown',        async ()=> { await RIGHT(SP);         })
   $("#RIGHT").on('touchend mouseup',            async ()=> { await STOP();            })
   //左回転
   $("#TURN_LEFT").on('touchstart mousedown',    async ()=> { await TURN_LEFT(SP);     })
   $("#TURN_LEFT").on('touchend mouseup',        async ()=> { await STOP();            })
   //右回転
   $("#TURN_RIGHT").on('touchstart mousedown',   async ()=> { await TURN_RIGHT(SP);    })  
   $("#TURN_RIGHT").on('touchend mouseup',       async ()=> { await STOP();            })
   //左後
   $("#BACK_LEFT").on('touchstart mousedown',    async ()=> { await BACK_LEFT(SP);     })
   $("#BACK_LEFT").on('touchend mouseup',        async ()=> { await STOP();            })
   //右後
   $("#BACK_RIGHT").on('touchstart mousedown',   async ()=> { await BACK_RIGHT(SP);    })     
   $("#BACK_RIGHT").on('touchend mouseup',       async ()=> { await STOP();            })
   //後進
   $("#BACK").on('touchstart mousedown',         async ()=> { await BACK(SP);          })
   $("#BACK").on('touchend mouseup',             async ()=> { await STOP();            })
   //停止
   $("#STOP").on('touchend mouseup',             async ()=> { await STOP();            })

   /*******************/
   /* Motion Controll */
   /*******************/
   async function STOP(){
      await MOVE( "  " , "  " ,
                  "  " , "  " );
   }
   async function FORWARD(speed){
      await MOVE( "" , "" ,
                  "" , "" , speed );
   }  
   async function BACK(speed){
      await MOVE( "" , "" ,
                  "" , "" , speed );
   }    
   async function LEFT(speed){
      await MOVE( "" , "" ,
                  "" , "" , speed );     
   }      
   async function RIGHT(speed){
      await MOVE( "" , "" ,
                  "" , "" , speed );     
   } 
   async function TURN_LEFT(speed){
      await MOVE( "" , "" ,
                  "" , "" , speed );    
   }          
   async function TURN_RIGHT(speed){
      await MOVE( "" , "" ,
                  "" , "" , speed );      
   }
   async function FORWARD_LEFT(speed){
      await MOVE( "  " , "" ,
                  "" , "  " , speed );     
   }
   async function FORWARD_RIGHT(speed){
      await MOVE( "" , "  " ,
                  "  " , "" , speed );     
   }
   async function BACK_LEFT(speed){
      await MOVE( "" , "  " ,
                  "  " , "" , speed );     
   }
   async function BACK_RIGHT(speed){
      await MOVE( "  " , "" ,
                  "" , "  " , speed );   
   }
   async function MOVE( FL,FR,
                        BL,BR,speed ){
      if ( BR == "" ) { await obniz.io0.output(false);await obniz.pwm0.start({io:1});await obniz.pwm0.duty(speed); }     
      if ( BR == "" ) { await obniz.io1.output(false);await obniz.pwm0.start({io:0});await obniz.pwm0.duty(speed); }  
      if ( BR == "  " ) { await obniz.pwm0.end(); }
     
      if ( BL == "" ) { await obniz.io2.output(false);await obniz.pwm1.start({io:3});await obniz.pwm1.duty(speed); }     
      if ( BL == "" ) { await obniz.io3.output(false);await obniz.pwm1.start({io:2});await obniz.pwm1.duty(speed); }
      if ( BL == "  " ) { await obniz.pwm1.end(); }     

      if ( FR == "" ) { await obniz.io4.output(false);await obniz.pwm2.start({io:5});await obniz.pwm2.duty(speed); }
      if ( FR == "" ) { await obniz.io5.output(false);await obniz.pwm2.start({io:4});await obniz.pwm2.duty(speed); }
      if ( FR == "  " ) { await obniz.pwm2.end(); }      

      if ( FL == "" ) { await obniz.io6.output(false);await obniz.pwm3.start({io:7});await obniz.pwm3.duty(speed); }
      if ( FL == "" ) { await obniz.io7.output(false);await obniz.pwm3.start({io:6});await obniz.pwm3.duty(speed); }  
      if ( FL == "  " ) { await obniz.pwm3.end(); }
   }

}
</script>
</body>
</html>

#■まとめ
DC Motorを直刺しできるのはobniz Boardの大きなアドバンテージなので、これを最大限生かす意味で、PWM制約のMAX6台まで直刺しで制御できるようDC Motorライブラリー自体を更新してくれたらうれしいですね。(電源が耐えられないような気もするが。。。)

6
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?