在Android Studio中使用蓝牙适配器时滞后

问题描述

我的项目: 用蓝牙控制3个步进电机。 我正在将Android Studio用于该应用程序,并将Arduino用于接收蓝牙数据并控制步进器。

我的问题 当我的Arduino收到数据时,它会滞后或丢失某些数据。

这是我用于与Arduino通信的ConnectedThread.java类。

    package com.example.a3axisrig;
    
    import android.bluetooth.BluetoothSocket;
    import android.os.Handler;
    import android.os.SystemClock;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import static com.example.a3axisrig.MainActivityKt.MESSAGE_READ;
    
    public class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        private final Handler mHandler;
    
        public ConnectedThread(BluetoothSocket socket,Handler handler) {
            mmSocket = socket;
            mHandler = handler;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;
    
            // Get the input and output streams,using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }
    
            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }
    
        @Override
        public void run() {
            byte[] buffer = new byte[1024];  // buffer store for the stream
            int bytes; // bytes returned from read()
            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.available();
                    if(bytes != 0) {
                        buffer = new byte[1024];
                        SystemClock.sleep(10); //pause and wait for rest of data. Adjust this depending on your sending speed.
                        bytes = mmInStream.available(); // how many bytes are ready to be read?
                        bytes = mmInStream.read(buffer,bytes); // record how many bytes we actually read
                        mHandler.obtainMessage(MESSAGE_READ,bytes,-1,buffer)
                                .sendToTarget(); // Send the obtained bytes to the UI activity
                    }
                } catch (IOException e) {
                    e.printStackTrace();
    
                    break;
                }
            }
        }
    
        /* Call this from the main activity to send data to the remote device */
        public void write(char input) {
            //byte[] bytes = input.getBytes();           //converts entered String into bytes
            try {
                mmOutStream.write(input);
            } catch (IOException e) { }
        }
    
        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }



And here's my Activity class(TimelapseActivity.kt) that inflates the view with a joystick to control two motors and a Left and Right buttons to control a 3rd motor.

package com.example.a3axisrig

import android.R.attr.button
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.View.OnTouchListener
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity


private lateinit var setButton: Button
private lateinit var doneButton: Button
private lateinit var backButton: Button
private lateinit var point1Button: Button
private lateinit var point2Button: Button
private lateinit var point3Button: Button

private lateinit var rightButton: Button
private lateinit var leftButton:Button


private var points: Int = 0

class TimelapseActivity : AppCompatActivity(),JoystickView.JoystickListener {
    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_timelapse)
        val joystick = JoystickView(this)

        window.decorView.setBackgroundColor(Color.argb(255,212,212));

        setButton = findViewById(R.id.set_button)
        doneButton = findViewById(R.id.done_button)
        backButton = findViewById(R.id.back_button)

        rightButton = findViewById(R.id.right_button)
        leftButton = findViewById(R.id.left_button)

        point1Button = findViewById(R.id.point1Button)
        point2Button = findViewById(R.id.point2Button)
        point3Button = findViewById(R.id.point3Button)
        point1Button.setBackgroundColor(Color.BLUE)
        point2Button.setBackgroundColor(Color.BLUE)
        point3Button.setBackgroundColor(Color.BLUE)

        setButton.setOnClickListener { view: View ->
            points++
            updatePoints()
            if (mConnectedThread != null) { //First check to make sure thread created
                if (points==1) mConnectedThread!!.write('i') else if (points ==2)mConnectedThread!!.write('o')

            }


        }
        doneButton.setOnClickListener { view: View ->
            val intent = Intent(this,TimelapseSetupActivity::class.java)
            startActivity(intent)
            if (mConnectedThread != null) { //First check to make sure thread created
                mConnectedThread!!.write('r')
            }

        }
        backButton.setOnClickListener { view: View ->
            points=0
            updatePoints()
        }

        leftButton.setOnTouchListener(OnTouchListener { v,event ->
            if (event.action == MotionEvent.ACTION_DOWN) {
                if (mConnectedThread != null) { //First check to make sure thread created
                    mConnectedThread!!.write('a')
                }
            } else if (event.action == MotionEvent.ACTION_UP) {
                if (mConnectedThread != null) { //First check to make sure thread created
                    mConnectedThread!!.write('1')
                }
            }
            true
        })


        rightButton.setOnTouchListener(OnTouchListener { v,event ->
            if (event.action == MotionEvent.ACTION_DOWN) {
                if (mConnectedThread != null) { //First check to make sure thread created
                    mConnectedThread!!.write('9')
                }
            } else if (event.action == MotionEvent.ACTION_UP) {
                if (mConnectedThread != null) { //First check to make sure thread created
                    mConnectedThread!!.write('1')
                }
            }
            true
        })

    }

    override fun onJoystickMoved(xPercent: Float,yPercent: Float,id: Int) {
        Log.d("Joystick","X percent: $xPercent Y percent: $yPercent")
        if (mConnectedThread != null) { //First check to make sure thread created
            if (xPercent > 0.1 && yPercent >0.1) mConnectedThread!!.write('1') //Pan Right & Tilt Up
            else if (xPercent > 0.1 && yPercent< -0.1) mConnectedThread!!.write('2') //Pan Right & Tilt Down
            else if (xPercent < -0.1 && yPercent > 0.1) mConnectedThread!!.write('3') //Pan Left & Tilt Up
            else if (xPercent < -0.1 && yPercent < -0.1) mConnectedThread!!.write('4') //Pan Left & Tilt Down
            else if (xPercent > 0.1) mConnectedThread!!.write('5') //Pan Right
            else if (xPercent < -0.1) mConnectedThread!!.write('6') //Pan Left
            else if (yPercent > 0.1) mConnectedThread!!.write('7') //Tilt Up
            else if (yPercent < -0.1) mConnectedThread!!.write('8') //Tilt Down
            else mConnectedThread!!.write('9')
        }


    }
}



private fun updatePoints(){
    if(points ==1){
        point1Button.setBackgroundColor(Color.GREEN)
    }else if (points ==2){
        point2Button.setBackgroundColor(Color.GREEN)
    }else if (points >=3){
        point3Button.setBackgroundColor(Color.GREEN)
    }else{
        point1Button.setBackgroundColor(Color.BLUE)
        point2Button.setBackgroundColor(Color.BLUE)
        point3Button.setBackgroundColor(Color.BLUE)

    }
}

这是我的arduino代码

#include <AccelStepper.h>
#include <MultiStepper.h>
#include <SPI.h>
#include <Wire.h>
// -----------------------------------BLUETOOTH-----------------------------------


#include <SoftwareSerial.h> // use the software uart
SoftwareSerial bluetooth(0,1); // RX,TX


// -----------------------------------MENU-----------------------------------
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
//#include <Adafruit_PCD8544.h>
#include <ClickEncoder.h>
#include <TimerOne.h>

int contrast = 60;

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

int menuitem = 1;
int frame = 1;
int page = 0;
int mainMenuItem = 1;
int subMenuItem1 = 1;
int subMenuItem2 = 1;
int subMenuItem3 = 1;
int subMenuItem4 = 1;

String menuItem1 = "Setup";
String menuItem2 = "Free Control";
String menuItem3 = "Saved";
String menuItem4 = "Settings";
String setupItem1 = "Timelapse";
String setupItem2 = "Video";
String setupItem3 = "Back";

boolean up = false;
boolean down = false;
boolean middle = false;

bool sliderLengthSet = false;

// ------------------------------------------------------------------------------------

#define JoyX A0
#define JoyY A1
#define JoySwitch 10  // Joystick switch connected

// Rotary Encoder
#define CLK 8
#define DT 9
#define SW 12
int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir = "";
unsigned long lastButtonPress = 0;

ClickEncoder *encoder;
int16_t last,value;

//Opto Trigger
#define opto 13

//limitSwitch
#define limitSwitch 11

AccelStepper tiltStepper(1,2,3);
AccelStepper panStepper(1,4,5);
AccelStepper sliderStepper(1,6,7);
MultiStepper StepperControl;

int JoyXPos = 0;
int JoyYPos = 0;
int tiltSpeed = 60;
int sliderSpeed = 1500;
int panSpeed = 10;
int inOutSpeed = 0;

int panInPoint = 0;
int tiltInPoint = 0;
int sliderInPoint = 0;
int panOutPoint = 0;
int tiltOutPoint = 0;
int sliderOutPoint = 0;

int sliderLength = 43; //in cm (725steps = 1cm)
int sliderLengthInSteps = (sliderLength * 725) - 100; //725steps = 1cm && 100 steps as safety

long gotoposition[3]; // An array to store the In or Out position for each stepper motor

//Rotary Encoder

int clickCount = 0;

bool rotaryEncoderMenuState = true; //true when in Menu mode,false when in slider mode

//Timer
long duration = 3000; //ms

//Intervalometer
int shotDuration = 100; //in ms
int interval = 3000; //in ms
int numberOfShots = 0;

char lastReading;

char bt ;


// ------------------------------------------------------------------ SETUP -------------------------------------------------------------------
void setup() {
  //Bluetooth
  bluetooth.begin(9600); // start the bluetooth uart at 9600 which is its default
  //delay(3000); // wait for settings to take affect.

  //Set initial speed values for the steppers
  tiltStepper.setMaxSpeed(6000);
  tiltStepper.setSpeed(0);
  tiltStepper.setAcceleration(10);
  panStepper.setMaxSpeed(6000);
  panStepper.setSpeed(0);
  panStepper.setAcceleration(5);
  sliderStepper.setMaxSpeed(6000);
  sliderStepper.setSpeed(0);
  sliderStepper.setAcceleration(10);

  StepperControl.addStepper(panStepper);
  StepperControl.addStepper(tiltStepper);
  StepperControl.addStepper(sliderStepper);

  //limitSwitch
  pinMode(limitSwitch,INPUT_PULLUP);

  //Opto Trigger
  pinMode(opto,OUTPUT);


  //  //Go to Home
  //  while (digitalRead(limitSwitch) == 0) {
  //    sliderStepper.setSpeed(500);
  //    sliderStepper.runSpeed();
  //    sliderStepper.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
  //  }
  //  delay(20);
  //  // Move 200 steps back from the limit switch
  //  while (sliderStepper.currentPosition() != -500) {
  //    sliderStepper.setSpeed(-1500);
  //    sliderStepper.run();
  //  }


}



// ------------------------------------------------------------------ LOOP -------------------------------------------------------------------
void loop() {

  //
  //  if (digitalRead(limitSwitch) != 0 || sliderStepper.currentPosition() < sliderLengthInSteps + 3000) {
  //    sliderStepper.setSpeed(1500);
  //    sliderStepper.run();
  //  }



  if (bluetooth.available()) {
    bt = bluetooth.read();
  }

  int inOutSpeed = 500; //steps per second

  // -----------------------------------BLUETOOTH-----------------------------------
  lastReading = bluetooth.read();

  //  while (lastReading == bluetooth.read()) {
  //    lastReading = bluetooth.read();
  switch (bt) {
    case '1':
      sliderStepper.setSpeed(0);
      tiltStepper.setSpeed(0);
      panStepper.setSpeed(0);
      break;
    case '2':
      panStepper.setSpeed(500);
      bluetooth.print("Pan Right");
      break;
    case '3':
      panStepper.setSpeed(-500);
      bluetooth.print("Pan Left");
      break;
    case '4':
      tiltStepper.setSpeed(-500);
      bluetooth.print("Tilt Down");
      break;
    case '5':
      tiltStepper.setSpeed(500);
      bluetooth.print("Tilt Up");
      break;
    case '6':
      //sliderStepper.setSpeed(500);
      bluetooth.print("Slider Right");
      break;
    case '7':
      //sliderStepper.setSpeed(-500);
      bluetooth.print("Slider Left");
      break;
    case '9':
      sliderStepper.setSpeed(500);
      break;
    case 'a':
      sliderStepper.setSpeed(-500);
      break;
    case 'i':
      panInPoint = panStepper.currentPosition();
      tiltInPoint = tiltStepper.currentPosition();
      sliderInPoint = sliderStepper.currentPosition();
      break;
    case 'o':
      panOutPoint = panStepper.currentPosition();
      tiltOutPoint = tiltStepper.currentPosition();
      sliderOutPoint = sliderStepper.currentPosition();
      gotoposition[0] = panInPoint;
      gotoposition[1] = tiltInPoint;
      gotoposition[2] = sliderInPoint;
      //inOutSpeed = findSpeed();
      panStepper.setMaxSpeed(500);
      tiltStepper.setMaxSpeed(300);
      sliderStepper.setMaxSpeed(500);
      StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
      while (panStepper.distanceToGo() != 0 || tiltStepper.distanceToGo() != 0 || sliderStepper.distanceToGo() != 0) {
        StepperControl.run(); // Blocks until all are in position
      }
      delay(200);
      bluetooth.println("o called");
      break;
    case'r':
      bluetooth.println("r called");
      gotoposition[0] = panOutPoint;
      gotoposition[1] = tiltOutPoint;
      gotoposition[2] = sliderOutPoint;
      inOutSpeed = findSpeed();

      bluetooth.println(inOutSpeed);

      panStepper.setMaxSpeed(inOutSpeed);
      tiltStepper.setMaxSpeed(inOutSpeed);
      sliderStepper.setMaxSpeed(inOutSpeed);
      StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
      //StepperControl.runSpeedToPosition(); // Blocks until all are in position

      long timePassed = millis();
      long lastTrigger = millis();
      while (panStepper.distanceToGo() != 0 || tiltStepper.distanceToGo() != 0 || sliderStepper.distanceToGo() != 0) {
        StepperControl.run();
        if ((millis() - lastTrigger) / 1000 == interval / 1000) {
          Serial.println(lastTrigger);
          digitalWrite(opto,HIGH);
          delay(shotDuration);      // wait for a shutter speed
          digitalWrite(opto,LOW);
          //delay(interval+duration);
          Serial.println("triggered");
          lastTrigger = millis();

        }

      }
      break;
  }

  sliderStepper.runSpeed();
  tiltStepper.runSpeed();
  panStepper.runSpeed();
  }

int findSpeed() {
  numberOfShots = duration / (interval + shotDuration);
  if (abs(panInPoint - panOutPoint) > abs(tiltInPoint - tiltOutPoint) && abs(panInPoint - panOutPoint) > abs(sliderInPoint - sliderOutPoint)) {
    return (abs(panInPoint - panOutPoint) / ((duration - (shotDuration * numberOfShots)) / 1000));
  } else if (abs(tiltInPoint - tiltOutPoint) > abs(panInPoint - panOutPoint) && abs(tiltInPoint - tiltOutPoint) > abs(sliderInPoint - sliderOutPoint)) {
    return (abs(tiltInPoint - tiltOutPoint) / ((duration - (shotDuration * numberOfShots)) / 1000));
  } else {
    return (abs(sliderInPoint - sliderOutPoint) / ((duration - (shotDuration * numberOfShots)) / 1000));
  }
}


//----------------------------------------------------- DRAW MENU -----------------------------------------------------


void drawMenu()
{




  //Setup->Timelapse->Next
  panInPoint = panStepper.currentPosition();
  tiltInPoint = tiltStepper.currentPosition();
  sliderInPoint = sliderStepper.currentPosition();


  //Save Out Point
  int inOutSpeed = 0;
  panOutPoint = panStepper.currentPosition();
  tiltOutPoint = tiltStepper.currentPosition();
  sliderOutPoint = sliderStepper.currentPosition();
  Serial.println("out");
  Serial.println(panOutPoint);
  Serial.println(tiltOutPoint);
  Serial.println(sliderOutPoint);


  //go to Start Point
  gotoposition[0] = panInPoint;
  gotoposition[1] = tiltInPoint;
  gotoposition[2] = sliderInPoint;
  Serial.println("in");
  Serial.println(gotoposition[0]);
  Serial.println(gotoposition[1]);
  Serial.println(gotoposition[2]);
  //inOutSpeed = findSpeed();
  panStepper.setMaxSpeed(500);
  tiltStepper.setMaxSpeed(300);
  sliderStepper.setMaxSpeed(1000);
  StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
  StepperControl.runSpeedToPosition(); // Blocks until all are in position
  delay(200);

  //Setup->Timelapse->Next->Next-> Start
  // Execute Move

  gotoposition[0] = panOutPoint;
  gotoposition[1] = tiltOutPoint;
  gotoposition[2] = sliderOutPoint;
  inOutSpeed = findSpeed();

  panStepper.setMaxSpeed(inOutSpeed);
  tiltStepper.setMaxSpeed(inOutSpeed);
  sliderStepper.setMaxSpeed(inOutSpeed);
  StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
  //StepperControl.runSpeedToPosition(); // Blocks until all are in position

  long timePassed = millis();
  long lastTrigger = millis();
  while (panStepper.distanceToGo() != 0 || tiltStepper.distanceToGo() != 0 || sliderStepper.distanceToGo() != 0) {
    StepperControl.run();
    if ((millis() - lastTrigger) / 1000 == interval / 1000) {
      Serial.println(lastTrigger);
      digitalWrite(opto,HIGH);
      delay(shotDuration);      // wait for a shutter speed
      digitalWrite(opto,LOW);
      //delay(interval+duration);
      Serial.println("triggered");
      lastTrigger = millis();

    }

  }



}

我正在接收到我的Arduino的蓝牙数据,并且电动机正在转动,这不是很准确,并且错过了一些按键操作。

请您能帮帮我! :)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...