简体   繁体   English

通过蓝牙将来自 Arduino 的超声波传感器的数据发送到 Android

[英]Sending data from ultrasonic sensor from Arduino to Android via Bluetooth

I am working with my diploma thesis and I have problem with communication Arduino -> Android using bluetooth.我正在处理我的文凭论文,但我在使用蓝牙进行 Arduino -> Android 的通信时遇到问题。 This is my app: Activity where I want to display distance to obstruction这是我的应用程序:我想显示到障碍物距离的活动

In the TextView, I want to put data from Arduino with the distance and I need idea, I can't find something, how sending data from different sensors to different Views (for example front, back bumper, left and right).在 TextView 中,我想将来自 Arduino 的数据与距离和我需要的想法,我找不到东西,如何将数据从不同的传感器发送到不同的视图(例如前,后保险杠,左右)。

Here you have arduino code:这里有 arduino 代码:

 #include <SoftwareSerial.h>
// Mid-back sensor
#define trigPinLeft 11 
#define echoPinLeft 10
// Right-back sensor (looking from back)
#define trigPinRight 7
#define echoPinRight 6
SoftwareSerial btSerial = SoftwareSerial(0,1);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  btSerial.begin(115200);
  // Mid-back sensor
  pinMode(trigPinLeft, OUTPUT);
  pinMode(echoPinLeft, INPUT);
  // Right-back sensor 
  pinMode(trigPinRight, OUTPUT);
  pinMode(echoPinRight, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  long durationLeft, distanceLeft;
  digitalWrite(trigPinLeft, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPinLeft, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPinLeft, LOW);
  durationLeft = pulseIn(echoPinLeft, HIGH);
  distanceLeft = (durationLeft *0.034 / 2);
  if (distanceLeft>=400 || distanceLeft<=18){
    Serial.println("Out of range"); 
    btSerial.println("Out of range");
  }
  else{
    Serial.print("BACK LEFT: ");
    Serial.print(distanceLeft);
    Serial.println(" cm");
    btSerial.println(distanceLeft + "cm");
  }
  //delayMicroseconds(1);

  long durationRight, distanceRight;
  digitalWrite(trigPinRight, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPinRight, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPinRight, LOW);
  durationRight = pulseIn(echoPinRight, HIGH);
  distanceRight = (durationRight *0.034 / 2);
  if (distanceRight>=400 || distanceRight<=18){
    Serial.println("Out of range"); 
    btSerial.println("Out of range");
  }
  else{
    Serial.print("BACK RIGHT: ");
    Serial.print(distanceRight);
    Serial.println(" cm");
    btSerial.println(distanceRight + "cm");
  }
  delay(10000);
}

This is Android-Studio code where I want one time get data from Arduino to one textView (not working):这是 Android-Studio 代码,我想一次将数据从 Arduino 获取到一个 textView(不工作):

public class HomeActivity extends AppCompatActivity {

ImageView imageView;
TextView rearLeft,rearMid,rearRight,frontLeft,frontMid,frontRight;
public static final String PREFS_NAME = "ParkingPrefsFile";
public static final String FIRST_TIME = "firstTime";
public static final String IMAGE_VAL = "imageValue";
private BluetoothServerSocket mmServerSocket;
private BluetoothAdapter mAdapter;
private BluetoothDevice mDevice;
private static final UUID MY_UUID = UUID.fromString("5951c386-e2e7-485d-aebe-a32eec769f7b");

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);
    imageView = (ImageView) findViewById(R.id.carView);
    rearLeft = (TextView) findViewById(R.id.rearLeftText);
    rearMid = (TextView) findViewById(R.id.rearMidText);
    rearRight = (TextView) findViewById(R.id.rearRightText);
    frontLeft = (TextView) findViewById(R.id.frontLeftText);
    frontMid = (TextView) findViewById(R.id.frontMidText);
    frontRight = (TextView) findViewById(R.id.frontRightText);
    BluetoothSocket socket = null;
    mAdapter = BluetoothAdapter.getDefaultAdapter();

    SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
    boolean firstTime = sharedPreferences.getBoolean(FIRST_TIME,false);

    if(!firstTime){
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putBoolean(FIRST_TIME,true);
        int image = getIntent().getIntExtra("image", R.drawable.ic_default);
        imageView.setImageResource(image);
        editor.putString(IMAGE_VAL, String.valueOf(getIntent().getIntExtra("image",R.drawable.ic_default)));
        editor.commit();
    }
    else {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        int image = getIntent().getIntExtra("image", Integer.parseInt(sharedPreferences.getString(IMAGE_VAL,null )));
        imageView.setImageResource(image);
        editor.putString(IMAGE_VAL, String.valueOf(getIntent().getIntExtra("image",image)));
        editor.commit();
    }

    /*try{
        //mmServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord("My Adapter", MY_UUID);
        mmServerSocket.accept();
    } catch (IOException e) {
        e.printStackTrace();
    }*/

    /*byte[] buffer = new byte[256];
    int bytes;
    try{
        mmServerSocket.close();
        InputStream inputStream = null;
        OutputStream outputStream = null;
        inputStream = socket.getInputStream();
        outputStream = socket.getOutputStream();

        DataInputStream mmInputStream = new DataInputStream(inputStream);
        DataOutputStream mmOutputStream = new DataOutputStream(outputStream);

        bytes = mmInputStream.read(buffer);
        String readMessage = new String(buffer, 0 , bytes);

        rearLeft.setText(readMessage);
    } catch (IOException e) {
        e.printStackTrace();
    }*/

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.home_activity_menu,menu);
    return true;
}
}

I compiled and runed app, but after I saw splashscreen, I had white screen and lag on the phone.我编译并运行了应用程序,但是在看到启动画面后,我有白屏并在手机上滞后。 I hadn't errors in Android-Studio.我在 Android-Studio 中没有错误。 Thanks for help.感谢帮助。

You clearly seem to have threading issue.您显然似乎有线程问题。

In your HomeActivity you have commented out the code that allows to open a Bluetooth Server on your Phone so that your Arduino device may connect to it, supplying the relevant UUID and other relevant parameters in RFCOM mode.在您的HomeActivity ,您已注释掉允许在手机上打开蓝牙服务器的代码,以便您的 Arduino 设备可以连接到它,并在 RFCOM 模式下提供相关的UUID和其他相关参数。

That code, however, is network-related and blocking and therefore should never be executed on the app UI Thread which is responsible to handle all UI tasks such as displaying views, monitoring user interactions (touch events) etc.然而,该代码与网络相关且阻塞,因此不应在负责处理所有 UI 任务(例如显示视图、监视用户交互(触摸事件)等)的应用程序UI 线程上执行。

This is the reason why your phone displays a white screen with lag.这就是您的手机显示滞后的白屏的原因。

So you should definitely execute the Bluetooth logic on a separate thread.因此,您绝对应该在单独的线程上执行蓝牙逻辑。

I'd propose the following class to handle all bluetooth-related logic.我建议使用以下 class 来处理所有与蓝牙相关的逻辑。 It's very straightforward.这很简单。

public class BluetoothHandler {

    private final Handler handler;
    private final BluetoothAdapter bluetoothAdapter;

    @Nullable
    private BluetoothServerSocket serverSocket;
    private BluetoothSocket bluetoothSocket;


    public BluetoothHandler(Context context) {
        final HandlerThread ht = new HandlerThread("Bluetooth Handler Thread", Thread.NORM_PRIORITY);
        ht.start(); // starting thread

        this.handler = new Handler(ht.getLooper());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            this.bluetoothAdapter = ((BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
        } else {
            this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        }
    }


    public void startBluetoothServer() {
        // execute code in our background worker thread
        this.handler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    serverSocket = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("name", "your UUID");
                    bluetoothSocket = serverSocket.accept(); // will wait as long as possible (no timeout) so there is blocking

                    // do your logic to retrieve in and out put streams to read / write data from / to your Arduino device

                }  catch (IOException ioe) {

                }
            } 
        });
    }


    @AnyThread
    public void writeData(byte[] data) {
        // remember, all network operation are to be executed in a background thread
        this.handler.post(new Runnable() {
            @Override
            public void run() {
                // write data in output stream     
            }
        });
    }


    @AnyThread
    public void readData(OnDataReadCallback callback) {
        // remember, all network operation are to be executed in a background thread
        this.handler.post(new Runnable() {
            @Override
            public void run() {
                // read data and notify via callback.
            }
        });
    }


    @AnyThread // should be call from your Activity onDestroy() to clear resources and avoid memory leaks.
    public void termainte() {
       try {
           if (serverSocket != null) {
               serverSocket.close();
           }

           if (bluetoothSocket != null) {
                bluetoothSocket.close();
           }
       } catch (IOException ioe) {

       }

        this.handler.getLooper().quit(); // will no longer be usable. Basically, this class instance is now trash.
    }


    public interface OnDataReadCallback {
        @WorkerThread // watch out if you need to update some view, user your Activity#runOnUiThread method !
        void onDataRead(byte[] data);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM