ROBOTベヌスandroid、arduino、bluetooth。 再垰的。 パヌト2

前回の蚘事では、 Android、arduino、bluetoothに基づくROBOT。 最初は、ロボットの䞀般的なスキヌムによっお提案され、AndroidずArduino間のデヌタ送受信の技術を提瀺したした。 そしお、最埌に泚文した郚品ずモゞュヌルのリストがありたす。 詳现を受け取り図1、コメントを考慮し、最初のロボットである反射型ロボットの䜜成に進みたす。



図1



目次



蚘事1.に基づくロボットandroid、arduino、bluetooth。 開始する

蚘事2.に基づくロボットandroid、arduino、bluetooth。 再垰的。 パヌト2



蚘事を読んでいる人はすでに次のこずを考えおいるず想定されたす。

-゚レクトロニクスの基本抂念

-前の蚘事



問題の声明



次の機胜を実行するロボットを䜜成したす。

-スマヌトフォンを䜿甚したリモヌトコントロヌル前方、埌方、巊、右

-スマヌトフォンの前にある物䜓たでの距離に関するデヌタを送信したす超音波センサヌに基づく

-自埋制埡モヌドがありたす障害物に遭遇するず、郚屋の呚りを連続的に移動し、移動方向を倉曎しお、障害物を旋回させたす。



理論のビット



私たちの䞖界は耇雑なシステムであり、膚倧な数のオブゞェクトが特定の物理法則に埓っお盞互䜜甚するため、このシステム内で機胜するロボットを䜜成するこずは非垞に骚の折れる䜜業です。 最初のロボットを䜜成するプロセスを簡玠化するために、環境ロボットが配眮されるずロボットのアクションを抜象化するずいう抂念を䜿甚したす。 さらなる蚘事では、環境を耇雑にし、それに応じおロボットの動䜜を耇雑にしたす。



抜象環境


最初のロボットが䜏む環境は2次元の䞖界であり、次の特城がありたす。

1完党に芳察可胜、すなわち ロボットセンサヌは、い぀でも環境の状態に関する完党な情報ぞのアクセスを提䟛したす。 ロボットは、この䞖界で起こるすべおを認識するために内郚状態を維持する必芁がないため、完党に芳察可胜な環境のバリ゚ヌションが䟿利です。

2確定的。 媒䜓の次の状態が珟圚の状態ずロボットによっお実行されるアクションによっお完党に決定される堎合、そのような媒䜓は決定論ず呌ばれたす。 それ以倖の堎合、確率的です。

3゚ピ゜ヌド。 䞀時的な問題の環境では、ロボットの䜓隓は耇雑な゚ピ゜ヌドで構成されたす。 各゚ピ゜ヌドには、ロボットによる環境の認識ず、1぀のアクションの実行が含たれたす。 さらに、次の゚ピ゜ヌドが前の゚ピ゜ヌドで実行されたアクションに䟝存しないこずが非垞に重芁です。 環境の゚ピ゜ヌドバヌゞョンでは、各゚ピ゜ヌドでのアクションの遞択は、゚ピ゜ヌド自䜓にのみ䟝存したす。

4静的。 ロボットが次のアクションを遞択する途䞭で環境が倉化する可胜性がある堎合、そのような環境はロボットの動的ず呌ばれたす。 それ以倖の堎合は静的です。

5連続-媒䜓の離散バヌゞョンず連続バヌゞョンの違いは、媒䜓の状態、時間の考慮方法、゚ヌゞェントの認識ずアクションに関連する可胜性がありたす。 私たちの堎合、環境の状態は継続的に倉化するず考えられおいたす。 たずえば、チェスのゲヌムは、有限数の異なる状態を持っおいるため、離散的です。

6シングル゚ヌゞェントは、1぀のオブゞェクトロボットが配眮されおいる環境であり、他のオブゞェクトはそれに圱響を䞎えず、競合したせん。



ロボットの動䜜の抜象化


1移動-ロボットは2方向前埌に移動し、その堎で向きを倉えるこずができたす巊、右

2ロボットセンサヌ超音波センサヌ、オブゞェクトたでの距離を決定できたす。 距離は0.02メヌトルから4メヌトルたで決定できたす。



したがっお、この蚘事で䜜成したロボットは単玔な反射型ロボットであるず刀断したす。 このようなロボットは、珟圚の知芚行為に基づいお行動を遞択し、知芚行為の残りの履歎を無芖したす。



䜿甚される郚品ずモゞュヌルに関する簡単な情報



HG7881゚ンゞンドラむバヌ。 ロボットのモヌタヌを制埡するには、䜎電力の制埡信号をモヌタヌを制埡するのに十分な電流に倉換するデバむスが必芁です。 このようなデバむスは、゚ンゞンドラむバヌず呌ばれたす。



HG7881は2チャンネル゚ンゞンドラむバヌです。2.5〜12 Vの電源から電力を䟛絊できたす。ドラむバヌ出力の説明

è¡š1

おわりに 説明
B-ia ゚ンゞンB入力AIA
B-ib ゚ンゞンB入力BIB
GND 地球マむナス
Vcc 動䜜電圧2.5-12Vプラス
A-IA ゚ンゞンA入力AIA
A-ib ゚ンゞンA入力BIB


゚ンゞンを必芁な方法で動䜜させるには、出力B-IA、B-IB、A-IA、A-IBに論理信号HIGH、LOWを䟛絊する必芁がありたす。 ゚ンゞンの真理倀衚

è¡š2

IA IB ゚ンゞン状態
L L オフ
H L 進む
L H 逆
H H オフ


超音波距離センサヌHC-SR04。 オブゞェクトからの音波の反射時間を枬定するこずにより、オブゞェクトたでの距離を決定したす。



センサヌは短い超音波パルスを発し時間0、物䜓から反射しおセンサヌが受信したす。 距離は、゚コヌが受信されるたでの時間ず空気䞭の音速に基づいお蚈算されたす。

10ÎŒsのパルスが出力Trigに送信され、超音波モゞュヌルは呚波数40 kHzの超音波信号を8パック攟出し、゚コヌを怜出したす。 オブゞェクトたでの枬定距離ぱコヌの幅に比䟋し゚コヌ、次の匏で蚈算できたす。

パルス幅/ 58 =距離cm。



ロボットの組み立おずすべおのモゞュヌルの接続



プラットフォヌムを組み立おたす図2。



図2

゚ンゞンをドラむバヌに接続したす図3。 ドラむバヌコネクタごずに2぀のモヌタヌ、぀たり プラットフォヌムの巊偎のモヌタヌを「モヌタヌB」コネクタヌに、右偎のモヌタヌを「モヌタヌA」に接続したす。 プラットフォヌムは、远跡されるプラットフォヌムず同様に制埡されたす。 前埌に移動する堎合、すべおの゚ンゞンは䞀方向に同期しお動䜜し、右に曲がるずプラットフォヌムの右偎の゚ンゞンが停止し、巊に曲がるず巊偎の゚ンゞンが停止し、右に゚ンゞンが同期しお動きたす。



図3

プラットフォヌムの䞊郚を固定したす。 ゚ンゞンドラむバヌ、arduino、バッテリヌ、BTモゞュヌル、および超音波センサヌをブレッドボヌドに接続したす図4



図4

接続図を図5に瀺したす。 Arduino、超音波センサヌ、゚ンゞンドラむバヌしたがっお゚ンゞン自䜓は、盎列に接続された4぀のバッテリヌ1.2 V、2700 mA / hで駆動され、BTモゞュヌルには3.3 VのArduino出力から電力が䟛絊されたす。



図5

ロボットは組み立おられおいたす。アンドロむドから送信されたコマンドを実行するように匷制する必芁がありたす。



Arduino STEP 1のスケッチ-リモヌトロボット制埡



前にBTモゞュヌルから電源を切断するこずを忘れずに、スケッチをarduinoにロヌドしたすそうしないずロヌドできたせん。

Arduino STEP 1のスケッチ
//  char incomingbyte; //     //motors A (RIGHT) int R_A_IA = 9; // A-IA int R_A_IB = 10; // A-IB //motors B (LEFT) int L_B_IA = 11; // B-IA int L_B_IB = 12; // B-IB //  void setup() { Serial.begin(38400); //motors RIGHT pinMode(R_A_IA,OUTPUT); digitalWrite(R_A_IA, HIGH); pinMode(R_A_IB,OUTPUT); digitalWrite(R_A_IB, HIGH); //motors LEFT pinMode(L_B_IA,OUTPUT); digitalWrite(L_B_IA, HIGH); pinMode(L_B_IB,OUTPUT); digitalWrite(L_B_IB, HIGH); } void go_forward(){ //motors LEFT digitalWrite(L_B_IA, LOW); digitalWrite(L_B_IB, HIGH); //motors RIGHT digitalWrite(R_A_IA, LOW); digitalWrite(R_A_IB, HIGH); } void go_back(){ //motors LEFT digitalWrite(L_B_IA, HIGH); digitalWrite(L_B_IB, LOW); //motors RIGHT digitalWrite(R_A_IA, HIGH); digitalWrite(R_A_IB, LOW); } void go_right(){ //motors LEFT digitalWrite(L_B_IA, LOW); digitalWrite(L_B_IB, HIGH); //motors RIGHT digitalWrite(R_A_IA, LOW); digitalWrite(R_A_IB, LOW); } void go_left(){ //motors LEFT digitalWrite(L_B_IA, LOW); digitalWrite(L_B_IB, LOW); //motors RIGHT digitalWrite(R_A_IA, LOW); digitalWrite(R_A_IB, HIGH); } void stop_robot(){ //motors LEFT digitalWrite(L_B_IA, LOW); digitalWrite(L_B_IB, LOW); //motors RIGHT digitalWrite(R_A_IA, LOW); digitalWrite(R_A_IB, LOW); } //   void loop() { if (Serial.available() > 0){ incomingbyte = Serial.read(); if (incomingbyte == '1'){ go_forward(); Serial.println("FORWARD"); } if (incomingbyte == '2'){ go_back(); Serial.println("BACK"); } if (incomingbyte == '3'){ go_right(); Serial.println("RIGHT"); } if (incomingbyte == '4'){ go_left(); Serial.println("LEFT"); } if (incomingbyte=='0'){ stop_robot(); Serial.println("STOP"); } } }
      
      







倉数を宣蚀したすR_A_IA、R_A_IB-゚ンゞンAを制埡する端末の番号を決定したす右偎の゚ンゞン、L_B_IA、L_B_IB-゚ンゞンBを制埡する番号の結論巊偎の゚ンゞン。シリアル接続を開始し、デヌタ転送速床をビット/ cボヌ-38400で蚭定したす。モヌタヌを制埡する端末の動䜜モヌド-出力出力を蚭定し、すべおの出力にHIGHを適甚したす぀たり、モヌタヌがオフになりたす衚2。

関数を定矩したすgo_forward、go_back、go_right、go_left、stop_robot、これらぱンゞンを回転の順方向たたは逆方向に開始し、それによっおロボットを前進、埌退、右、巊、停止、それに応じお。

メむンプログラムサむクルでは、BTモゞュヌルから受信しおシリアルポヌトに凊理されたデヌタが読み取られお凊理されたす。 受信したコマンドに応じお、1぀たたは別の機胜が実行され、その実行に関するテキストがシリアルポヌト経由で送信されたす。



Androidアプリケヌションステップ1-ロボットをリモヌトコントロヌルする



新しいプロゞェクト「Android application project」を䜜成したす。 前の蚘事で曞いたように、BTを䜿甚するには、BTをアプリケヌションで䜿甚する暩利を蚭定する必芁がありたす。 これを行うには、マニフェストに移動し、[アクセス蚱可]タブを遞択しお[远加]をクリックし、[アクセス蚱可を䜿甚]をクリックしお、次の暩限を蚭定したす。android.permission.BLUETOOTH、android.permission.BLUETOOTH_ADMIN

メむンアクティビティを䜜成し、res / layout / activity_main.xmlにコヌドを配眮したす。

コアアクティビティステップ1
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/txtrobot" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="  " /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/b1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="100" android:text="" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="100" > <Button android:id="@+id/b4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="100" android:text="" /> <Button android:id="@+id/b0" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="100" android:text="" /> <Button android:id="@+id/b3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="100" android:text="" /> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/b2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="100" android:text="" /> </LinearLayout> </LinearLayout>
      
      







これは、メむンアクティビティの倖芳です。



txtrobotテキストボックスには、必芁なすべおの情報が衚瀺されたす。 ボタンb0、b1、b2、b3、b4は、arduinoにコマンドを送信したす0、1、2、3、4

ここでsrc /../ MainActivity.javaに移動するず、メむンコヌドが配眮されたす。

前の蚘事のステップ4で、BTでデヌタを送受信できるコヌドが提瀺されたした。 このコヌドを基瀎ずしおみたしょう。

onPauseおよびonResumeアクティベヌション状態では、AndroidでのBTの存圚を確認し、それが有効になっおいるかどうかを刀断するための条件を远加したす。 前の蚘事では、BTが無効になっおいる堎合にアプリケヌションを起動するず、゚ラヌで終了し、その埌BTをオンにするこずを提案したため、この条件は存圚したせんでした。

  if (btAdapter != null){ if (btAdapter.isEnabled()){ //  } }
      
      





ボタンを保存するための倉数を宣蚀したす。

 Button b0, b1, b2, b3, b4;
      
      





IDで怜玢

  b0 = (Button) findViewById(R.id.b0);// b1 = (Button) findViewById(R.id.b1);// b2 = (Button) findViewById(R.id.b2);// b3 = (Button) findViewById(R.id.b3);// b4 = (Button) findViewById(R.id.b4);//
      
      





これらのボタンを抌しおコマンドを送信するためのハンドラヌを䜜成したす。

  b0.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("0"); } }); b1.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("1"); } }); b2.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("2"); } }); b3.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("3"); } }); b4.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("4"); } });
      
      





完党なアプリケヌションコヌド

アプリケヌションコヌドステップ1
 package com.example.rob_2_3_0; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; import com.example.rob_2_3_0.R; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import android.bluetooth.*; import android.content.Intent; public class MainActivity extends Activity { private static final int REQUEST_ENABLE_BT = 1; final int ArduinoData = 1; final String LOG_TAG = "myLogs"; private BluetoothAdapter btAdapter = null; private BluetoothSocket btSocket = null; private static String MacAddress = "20:11:02:47:01:60"; // MAC-   private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); private ConnectedThred MyThred = null; public TextView mytext; Button b0, b1, b2, b3, b4; boolean fl=false; Handler h; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btAdapter = BluetoothAdapter.getDefaultAdapter(); mytext = (TextView) findViewById(R.id.txtrobot); if (btAdapter != null){ if (btAdapter.isEnabled()){ mytext.setText("Bluetooth .  ."); }else { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } }else { MyError("Fatal Error", "Bluetooth "); } b0 = (Button) findViewById(R.id.b0);// b1 = (Button) findViewById(R.id.b1);// b2 = (Button) findViewById(R.id.b2);// b3 = (Button) findViewById(R.id.b3);// b4 = (Button) findViewById(R.id.b4);// b0.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("0"); } }); b1.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("1"); } }); b2.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("2"); } }); b3.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("3"); } }); b4.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("4"); } }); h = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case ArduinoData: byte[] readBuf = (byte[]) msg.obj; String strIncom = new String(readBuf, 0, msg.arg1); mytext.setText("  Arduino: " + strIncom); break; } }; }; } @Override public void onResume() { super.onResume(); if (btAdapter != null){ if (btAdapter.isEnabled()){ BluetoothDevice device = btAdapter.getRemoteDevice(MacAddress); Log.d(LOG_TAG, "***  Device***"+device.getName()); try { btSocket = device.createRfcommSocketToServiceRecord(MY_UUID); Log.d(LOG_TAG, "... ..."); } catch (IOException e) { MyError("Fatal Error", " onResume()    : " + e.getMessage() + "."); } btAdapter.cancelDiscovery(); Log.d(LOG_TAG, "***   ***"); Log.d(LOG_TAG, "***...***"); try { btSocket.connect(); Log.d(LOG_TAG, "***  ***"); } catch (IOException e) { try { btSocket.close(); } catch (IOException e2) { MyError("Fatal Error", " onResume()    " + e2.getMessage() + "."); } } MyThred = new ConnectedThred(btSocket); MyThred.start(); } } } @Override public void onPause() { super.onPause(); Log.d(LOG_TAG, "...In onPause()..."); if (btAdapter != null){ if (btAdapter.isEnabled()){ if (MyThred.status_OutStrem() != null) { MyThred.cancel(); } try { btSocket.close(); } catch (IOException e2) { MyError("Fatal Error", " onPause()    " + e2.getMessage() + "."); } } } }//OnPause private void MyError(String title, String message){ Toast.makeText(getBaseContext(), title + " - " + message, Toast.LENGTH_LONG).show(); finish(); } //     private class ConnectedThred extends Thread{ private final BluetoothSocket copyBtSocket; private final OutputStream OutStrem; private final InputStream InStrem; public ConnectedThred(BluetoothSocket socket){ copyBtSocket = socket; OutputStream tmpOut = null; InputStream tmpIn = null; try{ tmpOut = socket.getOutputStream(); tmpIn = socket.getInputStream(); } catch (IOException e){} OutStrem = tmpOut; InStrem = tmpIn; } public void run() { byte[] buffer = new byte[1024]; int bytes; while(true){ try{ bytes = InStrem.read(buffer); h.obtainMessage(ArduinoData, bytes, -1, buffer).sendToTarget(); }catch(IOException e){break;} } } public void sendData(String message) { byte[] msgBuffer = message.getBytes(); Log.d(LOG_TAG, "*** : " + message + "***" ); try { OutStrem.write(msgBuffer); } catch (IOException e) {} } public void cancel(){ try { copyBtSocket.close(); }catch(IOException e){} } public Object status_OutStrem(){ if (OutStrem == null){return null; }else{return OutStrem;} } } }
      
      







このアプリケヌションでは、Androidを䜿甚しおロボットを制埡し、BTコマンドをArduinoに送信し、そこからテキスト応答を受信できたす。 タスクの最初の郚分が完了したした。



Arduino STEP 2のスケッチ-自埋ロボット制埡モヌド



超音波センサヌを䜿甚するには、既補のラむブラリを䜿甚したす

超音波-HC-SR04.zip

ファむルを解凍し、スケッチが配眮されおいるディレクトリに配眮したす

ラむブラリを接続する

 #include "Ultrasonic.h"
      
      





Ultrasonicコンストラクタヌは、TrigずEchoがそれぞれ接続されるピン番号の2぀のパラメヌタヌを受け入れたす。

 Ultrasonic ultrasonic(5, 6);
      
      





オブゞェクトたでの距離に関するデヌタをセンチメヌトル単䜍で取埗したす。

 float dist_cm = ultrasonic.Ranging(CM); //   
      
      





BTモゞュヌルを介した埌続の送信のために、シリアルポヌトにデヌタを転送したす。

  Serial.print("*"); Serial.print(dist_cm); Serial.print("#");
      
      





蚘号「*」および「」は、オブゞェクトたでの距離に関する情報の送信ブロックの開始ず終了を意味したす。 これは、必芁なデヌタを盞互に明確に分離するために必芁です。なぜなら、それらが転送されるず、䞀郚が倱われたり遅れたりするからです。

Arduinoでロヌドするための完党なスケッチ

Arduino STEP 2のスケッチ
 #include "Ultrasonic.h" //  char incomingbyte; int i=0; //motors A (LEFT) int R_A_IA = 9; // A-IA int R_A_IB = 10; // A-IB //motors B (RIGHT) int L_B_IA = 11; // B-IA int L_B_IB = 12; // B-IB //      Ultrasonic ultrasonic(5, 6); //  void setup() { Serial.begin(38400); //RIGHT pinMode(R_A_IA,OUTPUT); digitalWrite(R_A_IA, HIGH); pinMode(R_A_IB,OUTPUT); digitalWrite(R_A_IB, HIGH); //LEFT pinMode(L_B_IA,OUTPUT); digitalWrite(L_B_IA, HIGH); pinMode(L_B_IB,OUTPUT); digitalWrite(L_B_IB, HIGH); } void go_forward(){ //LEFT digitalWrite(L_B_IA, LOW); digitalWrite(L_B_IB, HIGH); //RIGHT digitalWrite(R_A_IA, LOW); digitalWrite(R_A_IB, HIGH); } void go_back(){ //LEFT digitalWrite(L_B_IA, HIGH); digitalWrite(L_B_IB, LOW); //RIGHT digitalWrite(R_A_IA, HIGH); digitalWrite(R_A_IB, LOW); } void go_right(){ //LEFT digitalWrite(L_B_IA, LOW); digitalWrite(L_B_IB, HIGH); //RIGHT digitalWrite(R_A_IA, LOW); digitalWrite(R_A_IB, LOW); } void go_left(){ //LEFT digitalWrite(L_B_IA, LOW); digitalWrite(L_B_IB, LOW); //RIGHT digitalWrite(R_A_IA, LOW); digitalWrite(R_A_IB, HIGH); } void stop_robot(){ //LEFT digitalWrite(L_B_IA, LOW); digitalWrite(L_B_IB, LOW); //RIGHT digitalWrite(R_A_IA, LOW); digitalWrite(R_A_IB, LOW); } //   void loop() { if (Serial.available() > 0){ incomingbyte = Serial.read(); if (incomingbyte == '1'){ go_forward(); } if (incomingbyte == '2'){ go_back(); } if (incomingbyte == '3'){ go_right(); } if (incomingbyte == '4'){ go_left(); } if (incomingbyte=='0'){ stop_robot(); } } float dist_cm = ultrasonic.Ranging(CM); //    Serial.print("*"); Serial.print(dist_cm); Serial.print("#"); }
      
      









Androidアプリケヌションステップ2-ロボットの自埋制埡



ボタン「b5」自動制埡をメむンアクティビティに远加したす。 コヌドは次のずおりです。

コアアクティビティステップ2
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/b5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="" /> </LinearLayout> <TextView android:id="@+id/txtrobot" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="  " /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/b1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="100" android:text="" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="100" > <Button android:id="@+id/b4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="100" android:text="" /> <Button android:id="@+id/b0" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="100" android:text="" /> <Button android:id="@+id/b3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="100" android:text="" /> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/b2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="100" android:text="" /> </LinearLayout> </LinearLayout>
      
      





内容


したがっお、䞻なアクティビティは次の圢匏になりたす。



倉数b5を宣蚀したす。

 Button b0, b1, b2, b3, b4, b5;
      
      





たた、自動制埡が有効になっおいるかどうかを刀別できるフラグ

 boolean fl=false;
      
      





IDで怜玢

 b5 = (Button) findViewById(R.id.b5);//
      
      





抌すためのハンドラヌを䜜成したす。

  b5.setOnClickListener(new OnClickListener() { public void onClick(View v) { Log.d(LOG_TAG, " "); if (!fl){ Log.d(LOG_TAG, "  "); fl=true; b1.setEnabled(false); b2.setEnabled(false); b3.setEnabled(false); b4.setEnabled(false); MyThred.sendData("1"); Log.d(LOG_TAG, " 1"); } } });
      
      





たた、ボタンハンドラ "b0"停止に倉曎を加えたす。

  b0.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("0"); if (fl) { fl = false; b1.setEnabled(true); b2.setEnabled(true); b3.setEnabled(true); b4.setEnabled(true); } } });
      
      







ロボットが独立しお郚屋を動き回り、障害物を迂回できるようにするアルゎリズムを䜜成するこずは残っおいたす。

arduinoから送信されたオブゞェクトたでの距離に関する受信デヌタを凊理したす。 オブゞェクトたでの距離が50 cm未満の堎合は、右に曲がりたす。それ以倖の堎合は、たっすぐに食べたす。

  byte[] readBuf = (byte[]) msg.obj; String strIncom = new String(readBuf, 0, msg.arg1); sb.append(strIncom);//   int beginOfLineIndex = sb.indexOf("*");//    int endOfLineIndex = sb.indexOf("#");//    //     *#    if ((endOfLineIndex > 0) && (beginOfLineIndex == 0)) { String sbprint = sb.substring(beginOfLineIndex+1, endOfLineIndex-3); mytext.setText("  Arduino: " + sbprint); if (fl){ int dist = Integer.parseInt(sbprint); if (dist<50) { MyThred.sendData("3"); } else { MyThred.sendData("1"); } } } sb.delete(0, sb.length());
      
      





完党なアクティビティコヌドは次のずおりです。

アプリケヌションコヌドステップ2
 package com.robot.rob_2_3; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.UUID; import com.robot.rob_2_3.R; import android.os.Bundle; import android.os.CountDownTimer; import android.os.Handler; import android.app.Activity; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import android.bluetooth.*; import android.content.Intent; public class MainActivity extends Activity { private static final int REQUEST_ENABLE_BT = 1; final int ArduinoData = 1; final String LOG_TAG = "myLogs"; private BluetoothAdapter btAdapter = null; private BluetoothSocket btSocket = null; private static String MacAddress = "20:11:02:47:01:60"; // MAC-   private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); private static final long MILLIS_PER_SECOND = 0; private ConnectedThred MyThred = null; public TextView mytext; Button b0, b1, b2, b3, b4, b5; boolean fl=false; Handler h; private StringBuilder sb = new StringBuilder(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btAdapter = BluetoothAdapter.getDefaultAdapter(); mytext = (TextView) findViewById(R.id.txtrobot); if (btAdapter != null){ if (btAdapter.isEnabled()){ mytext.setText("Bluetooth .  ."); }else { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } }else { MyError("Fatal Error", "Bluetooth "); } b0 = (Button) findViewById(R.id.b0);// b1 = (Button) findViewById(R.id.b1);// b2 = (Button) findViewById(R.id.b2);// b3 = (Button) findViewById(R.id.b3);// b4 = (Button) findViewById(R.id.b4);// b5 = (Button) findViewById(R.id.b5);// b0.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("0"); if (fl) { fl = false; b1.setEnabled(true); b2.setEnabled(true); b3.setEnabled(true); b4.setEnabled(true); } } }); b1.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("1"); } }); b2.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("2"); } }); b3.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("3"); } }); b4.setOnClickListener(new OnClickListener() { public void onClick(View v) { MyThred.sendData("4"); } }); b5.setOnClickListener(new OnClickListener() { public void onClick(View v) { Log.d(LOG_TAG, " "); if (!fl){ Log.d(LOG_TAG, "  "); fl=true; b1.setEnabled(false); b2.setEnabled(false); b3.setEnabled(false); b4.setEnabled(false); MyThred.sendData("1"); Log.d(LOG_TAG, " 1"); } } }); h = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case ArduinoData: byte[] readBuf = (byte[]) msg.obj; String strIncom = new String(readBuf, 0, msg.arg1); sb.append(strIncom);//   int beginOfLineIndex = sb.indexOf("*");//    int endOfLineIndex = sb.indexOf("#");//    //     *#    if ((endOfLineIndex > 0) && (beginOfLineIndex == 0)) { //    , String sbprint = sb.substring(beginOfLineIndex+1, endOfLineIndex-3); //    mytext.setText("  Arduino: " + sbprint); if (fl){ int dist = Integer.parseInt(sbprint); if (dist<50) { MyThred.sendData("3"); } else { MyThred.sendData("1"); } } } sb.delete(0, sb.length()); break; } }; }; } @Override public void onResume() { super.onResume(); if (btAdapter != null){ if (btAdapter.isEnabled()){ BluetoothDevice device = btAdapter.getRemoteDevice(MacAddress); Log.d(LOG_TAG, "***  Device***"+device.getName()); try { btSocket = device.createRfcommSocketToServiceRecord(MY_UUID); Log.d(LOG_TAG, "... ..."); } catch (IOException e) { MyError("Fatal Error", " onResume()    : " + e.getMessage() + "."); } btAdapter.cancelDiscovery(); Log.d(LOG_TAG, "***   ***"); Log.d(LOG_TAG, "***...***"); try { btSocket.connect(); Log.d(LOG_TAG, "***  ***"); } catch (IOException e) { try { btSocket.close(); } catch (IOException e2) { MyError("Fatal Error", " onResume()    " + e2.getMessage() + "."); } } MyThred = new ConnectedThred(btSocket); MyThred.start(); } } } @Override public void onPause() { super.onPause(); Log.d(LOG_TAG, "...In onPause()..."); if (btAdapter != null){ if (btAdapter.isEnabled()){ if (MyThred.status_OutStrem() != null) { MyThred.cancel(); } try { btSocket.close(); } catch (IOException e2) { MyError("Fatal Error", " onPause()    " + e2.getMessage() + "."); } } } }//OnPause private void MyError(String title, String message){ Toast.makeText(getBaseContext(), title + " - " + message, Toast.LENGTH_LONG).show(); finish(); } //     private class ConnectedThred extends Thread{ private final BluetoothSocket copyBtSocket; private final OutputStream OutStrem; private final InputStream InStrem; public ConnectedThred(BluetoothSocket socket){ copyBtSocket = socket; OutputStream tmpOut = null; InputStream tmpIn = null; try{ tmpOut = socket.getOutputStream(); tmpIn = socket.getInputStream(); } catch (IOException e){} OutStrem = tmpOut; InStrem = tmpIn; } public void run() { byte[] buffer = new byte[1024]; int bytes; while(true){ try{ bytes = InStrem.read(buffer); h.obtainMessage(ArduinoData, bytes, -1, buffer).sendToTarget(); }catch(IOException e){break;} } } public void sendData(String message) { byte[] msgBuffer = message.getBytes(); Log.d(LOG_TAG, "*** : " + message + "***" ); try { OutStrem.write(msgBuffer); } catch (IOException e) {} } public void cancel(){ try { copyBtSocket.close(); }catch(IOException e){} } public Object status_OutStrem(){ if (OutStrem == null){return null; }else{return OutStrem;} } } }
      
      









提瀺されたarduinoのスケッチず連動しお䜜成されたAndroidのアプリケヌションは、ロボットを独立しおリモヌト制埡するこずも、ロボットが前方に移動し、必芁に応じお障害物を回避する自埋制埡モヌドをオンにするこずもできたす。

この䜜業の結果は、最も単玔な反射ロボットです。 特定のテンプレヌトアプリケヌションずスケッチに基づいたより耇雑なアルゎリズムをさらに適甚するず、モデル、目暙、ナヌティリティ、孊習ロボットなどに基づいおロボットを䜜成できたす。

次の蚘事では、たった1぀のモゞュヌルを泚文したした。

お名前 リンク あなたがたの䟡栌 䟡栌摩擊 数量 金額
Wifiモゞュヌル dx.com/p/hi-link-hlk-rm04-serial-port-ethernet-wi-fi-adapter-module-blue-black-214540#.UutHKD1_sd0 14,99 524.65 1 524.65


合蚈524.65



前の蚘事ぞのコメントで、ハブナヌザヌの叞什官は、車茪を再発明するのではなく、暙準のFirmataプロトコルarduinoずサヌバヌ間でデヌタを亀換するためのプロトコルを䜿甚するこずを掚奚したした。 残念ながら、BTず連動したAndroidの実行可胜なラむブラリは芋぀かりたせんでした。 ラむブラリを曞くのに十分な時間ず゚ネルギヌがないので、この蚘事ではホむヌルの再発明を続けたす。 Habrナヌザヌの誰かがそのようなラむブラリに関する情報を持っおいる堎合は、共有しおください。



All Articles