AE-DRV8830 と HC-05を連携させてモーターを制御する(ブレッドボード編) | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/6964
の続きで、これをユニバーサル基板で作ります。本来ならば、プリント基板を作ってとか、回路図を作ってってことになるのでしょうが、初手なので手作りで半田付け、ってのと最終的には Arduino 用のチップも載せてしまって小型化したかったってのがあります。まあ、やってみた感じでは、ユニバーサル基板で作るのは手作業が大変です…が、感光基盤だと子供がいる家ではできないし、ちょっと考えないと。
材料
- DRV8830 x2 @170円
- HC-05 x1 @1,000 円ぐらい
- オス・メスピン @100円ぐらい?
- ユニバーサル基板 x1 @270円(昔買った)
- 抵抗 10kΩ x2
- コンデンサ 10nF x2
な感じです。まあ、完成品を Amazon.co.jp: Arduino MEGA UNO Duemilanove 最高品質 用の L293D モーター シールド ボード: DIY・工具 あたりで買うのが手っ取り早いのですが(これは、ひどく安いけど、1,000円から2,000円ぐらいです。秋月電子で DRV8830 のキット 650円 を2つ買うってのもありです。本来ならばターミナルブロックを使って給電したり、モーターを回したりすればいいのですが、手元になかったのでピンヘッダで代用。どうせ、Arduino からジャンパーピンを差してテストするので、このほうがやりやすいです。
DRV8830 を使うといいのは、I2C で通信ができるので、通信回線が SCL/SDA の 2本だけで済むことです。L293D を使ったモータードライバだと、モーター2個でGPIO 経由で 4本の線が必要になります。2個くらいだったらそれでもいいけど、4個とか8個とかにふえても SCL/SDA の 2本だけになるから便利ですよね…となっていますが、本当に 4個いけるかどうかは分かりません。モーター駆動のと、信号線の電源が同じになっているので、ノイズが多くてモーターの挙動が信号線に乗ってしまうのは結構問題なんですよね。モーターによってはノイズが乗って、暴走状態になります。もともと、プリンタの駆動系とかを動かすものなので、ミニ四駆とか車輪とかを動かすには向いていないようです。でも、まあ、タミヤのギアボックス付属のモーター FA-130 レベルならば大丈夫でした。
配線
回路図はよくわからないので、ブレッドボードで作ったものを
そのままユニバーサル基板に配置して、
配線します(苦笑)
配線の美意識のかけらもないものですが、まあ、腐ったコードでも動くコードを乗せておくこともあるし、ひとまず動けば ok 的なものなので、これでいいです。ひとまず動きますから。
これを、Arduino とつなげます。
更に、ギアーボックスとつなげます。
ブレッドボードじゃなくてわざわざ基板を使っているのにジャンパーピンが錯綜しているのは、Arduino のシールドになっていないからです。これだと、あまりにも壊れやすいので、もうちょっと頑丈につくらないと駄目なので、昨晩 Arduino 用のシールド基板を注文しました。他にも色々と。
どうやって通信するのか?
HC-05 は Bluetooth 2.0 なので、今流行りの BLE ではありません。なので、iPhone から操作することはできないのですが、単純な SPP 通信(シリアル通信)を使って手軽にパソコンとやり取りができます(最終的には、PS3 Dualshock3 のような既存のコントローラーと通信したいところなのですが、これは Raspberry Pi のほうが非常に簡単なのです。たしか、USB ポートがあってロボットを操作する SBDBT とか)。
Arduino + USBホストシールドの実験。 – robo8080のブログ
http://blog.goo.ne.jp/roboz80/e/9d2fc6e1266932f7ace682b43393217b
でもって、手元の HC-05 は Bluetooth シリアル変換モジュールなので、そのまま Serial を使うことができます。
Arduino のスケッチ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | #include <Wire.h> const int DRV8830a = 0xC8 >> 1 ; // 0x64; const int DRV8830b = 0xC6 >> 1 ; // 0x63; const int FAULTn = 13 ; const int LED = 12 ; int writeRegister( byte drv, byte vset, byte data ) { int vdata = vset << 2 | data ; Wire.beginTransmission( drv ); Wire.write( 0x00 ); Wire.write( (vset<<2) + data ); return Wire.endTransmission(); } void clearError() { Wire.beginTransmission( DRV8830a ); Wire.write(0x01); Wire.write(0x80); } void checkError() { if ( digitalRead(FAULTn) == HIGH ) { return ; } Wire.beginTransmission( DRV8830a ); Wire.write(0x01); Wire.endTransmission(); Wire.requestFrom( DRV8830a, 1 ); byte error = Wire.read(); Serial.println( error, BIN); if ( error & 0b00000011 ) { Serial.println( "over current" ); } else if ( error & 0b00000101 ) { Serial.println( "under voltage" ); } else if ( error & 0b00001001 ) { Serial.println( "over heat" ); } else if ( error & 0b00010001 ) { Serial.println( "limit current" ); } clearError(); } int mode = 0; void setup() { // put your setup code here, to run once: pinMode( FAULTn, INPUT ); pinMode( LED, OUTPUT ); Wire.begin(); Serial.begin(9600); Serial.println( "Motor Standby" ); Serial.println( DRV8830a, HEX); Serial.println( DRV8830b, HEX); writeRegister( DRV8830a, 0x00, 0x00 ); writeRegister( DRV8830b, 0x00, 0x00 ); delay( 2000 ); } void loop() { // put your main code here, to run repeatedly: int len = Serial.available(); if ( len < 2 ) return ; int type = Serial.read(); // M or L int num = Serial.read(); // MF/MB/M0, L0/L1 if ( type == 'M' || type == 'N' ) { int mode = 0; switch ( num ) { case '0' : mode = 0; break ; case 'F' : mode = 1; break ; case 'B' : mode = 2; break ; default : mode = 0; break ; } switch ( mode ) { case 0: Serial.println( "motor standby" ); writeRegister( type == 'M' ? DRV8830a: DRV8830b, 0x00, 0x00 ); break ; case 1: Serial.println( "motor forward" ); writeRegister( type == 'M' ? DRV8830a: DRV8830b, 0x15, 0x02 ); checkError(); // delay( 2000 ); break ; case 2: Serial.println( "motor back" ); writeRegister( type == 'M' ? DRV8830a: DRV8830b, 0x15, 0x01 ); checkError(); // delay( 2000 ); break ; } } if ( type == 'L' ) { Serial.println( "LED on/off" ); int mode = 0; switch ( num ) { case '0' : mode = 0; break ; case '1' : mode = 1; break ; default : break ; } if ( mode == 0 ) { digitalWrite(LED, LOW ); } else { digitalWrite(LED, HIGH ); } } } |
ブレッドボード用に作ったものなので、エラーチェックの FAULTn と LED のコードが入っていますが、”MF” とか “MB” とかいう自作のコマンドを使ってモーターをコントロールします。
Windows ストアアプリから操作する
Android からやるのが見栄えがいいのですが、まずは Windows ストアアプリからやります。
Arduino で Bluetooth シリアル変換モジュール(HC-05)を使う | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/6819
と同じように Package.appxmanifest を設定したあとに、接続とコマンド送信部分を書きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | private async void btn_findDevice_Click( object sender, RoutedEventArgs e) { string selector = RfcommDeviceService.GetDeviceSelector(RfcommServiceId.FromUuid(serviceGuid)); DeviceInformationCollection collection = await DeviceInformation.FindAllAsync(selector); if (collection.Count > 0) { DeviceInformation info = collection.First(); rfcommService = await RfcommDeviceService.FromIdAsync(info.Id); socket = new StreamSocket(); await socket.ConnectAsync(rfcommService.ConnectionHostName, rfcommService.ConnectionServiceName); writer = new DataWriter(socket.OutputStream); reader = new DataReader(socket.InputStream); textOut.Text = "接続しました" ; } else { MessageDialog dialog = new MessageDialog( "デバイスが見つかりませんでした" ); await dialog.ShowAsync(); } } private async void clickMF( object sender, RoutedEventArgs e) { writer.WriteString( "MF" ); await writer.StoreAsync(); } private async void clickMB( object sender, RoutedEventArgs e) { writer.WriteString( "MB" ); await writer.StoreAsync(); } private async void clickM0( object sender, RoutedEventArgs e) { writer.WriteString( "M0" ); await writer.StoreAsync(); } private async void clickNF( object sender, RoutedEventArgs e) { writer.WriteString( "NF" ); await writer.StoreAsync(); } private async void clickNB( object sender, RoutedEventArgs e) { writer.WriteString( "NB" ); await writer.StoreAsync(); } private async void clickN0( object sender, RoutedEventArgs e) { writer.WriteString( "N0" ); await writer.StoreAsync(); } |
画面はボタンを並べただけ。
これだと、Arduino 側からフィードバックがないので、様子がわからないのですが、それなりに動きます。あと、DRV8830 はモーターに流れる電圧を変えることができるので前進後進だけではなく、スピードを変えることができます。このあたりを入れて Arduino のスケッチとストアアプリのコードを変えると結構いけるかなと。ああ、あとバーンと鳴るとか、LED を光らせるとかギミック用のコマンドもいれないと。
で、これは Windows ストアアプリで作ったけど、デスクトップアプリ(WinフォームとかWPFとか)でも作れます。次は、Windows のコンソールアプリで RFCOMM を利用する | Moonmile Solutions Blog を使って WPF アプリに書き直してみます。
you did well even if i cant understand ur language,the picture are enough,, please can you tell me how to configure bluetooth
You can setting at command in HC-05.
please refer
How to enter AT mode in HC-05 bluetooth module
http://forum.arduino.cc/index.php?topic=128991.0
Arduino with HC-05 (ZS-040) Bluetooth module – AT MODE | Martyn Currey
http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
Configuring your Bluetooth Module for the Communication between Scratch and Arduino | Iniciativa Computação na Escola
http://www.computacaonaescola.ufsc.br/?page_id=536&lang=en