Bluetooth command only last for a second or so

Hi I am making an Android App to control a robot using arduino mega.

the problem i am facing is when I touch the button, robot only moves for a second or so. I have to repetitively touch the button for it to continuously move.

Is there a command I need to use for it to continuously move as long as I am touching the button?

Arduino Code I am using is

//MOTOR pins definition
#define E1 2  // Enable Pin for motor 1
#define E2 7  // Enable Pin for motor 2
 
#define I1 3  // Control pin 1 for motor 1
#define I2 4  // Control pin 2 for motor 1
#define I3 5  // Control pin 1 for motor 2
#define I4 6    // Control pin 2 for motor 2
//Motor Pins definition ends here

// LED pin attached to Arduino D13
int LED = 13;


char command = 'S';
char prevCommand = 'A';
int velocity = 0;   
unsigned long timer0 = 2000;  //Stores the time (in millis since execution started) 
unsigned long timer1 = 0;  //Stores the time when the last command was received from the phone

void setup() 
{       
  Serial.begin(9600);  //Set the baud rate to that of your Bluetooth module.
  pinMode(LED , OUTPUT);
  //Setting input/output for Motor Pins  
  pinMode(E1, OUTPUT);
  pinMode(E2, OUTPUT);
  pinMode(I1, OUTPUT);
  pinMode(I2, OUTPUT);
  pinMode(I3, OUTPUT);
  pinMode(I4, OUTPUT);
//Setting input/output for Motor Pins ends here


}

void loop(){
  if(Serial.available() > 0){ 
    timer1 = millis();   
    prevCommand = command;
    command = Serial.read(); 
    //Change pin mode only if new command is different from previous.   
    if(command!=prevCommand){
      //Serial.println(command);
      switch(command){
      case 'F':  
        GoForward();
        break;
      case 'B':  
        GoBack();
        break;
      case 'L':  
        TurnLeft();
        break;
      case 'R':
        TurnRight();  
        break;
      case 'S':  
        StopMotor();
        break; 
      case 'I':  //FR  
        ForwardRight();
      break; 
      case 'J':  //BR  
        BackRight();
      break;        
      case 'G':  //FL  
        ForwardLeft();
      break; 
      case 'H':  //BL
        ForwardRight();
      break;        
      case 'W':  //Light ON 
        digitalWrite(LED, HIGH);
        break;
      case 'w':  //Font OFF
        digitalWrite(Light, LOW);
        break;        
      }
    }
  }
  else{
    timer0 = millis();  //Get the current time (millis since execution started).
    //Check if it has been 500ms since we received last command.
    if((timer0 - timer1)>500){  
      //More tan 500ms have passed since last command received, car is out of range.
      //Therefore stop the car and turn lights off.
      digitalWrite(LED, LOW);
      StopMotor();
    }
  }  
}




void GoBack()
{
    digitalWrite(E1, HIGH);
    digitalWrite(E2, HIGH);
    
    digitalWrite(I1, LOW);
    digitalWrite(I2, HIGH);  //This will set the circuitry of the H-bridge appropriately (e.g. the gates)
    digitalWrite(I3, LOW);
    digitalWrite(I4, HIGH);
      
}

void GoForward()
{
    analogWrite(E1, 255);
    analogWrite(E2, 255);
    
    digitalWrite(I1, HIGH);
    digitalWrite(I2, LOW);  //This will set the circuitry of the H-bridge appropriately (e.g. the gates)
    digitalWrite(I3, HIGH);
    digitalWrite(I4, LOW);
      
}


void TurnLeft()
{
    digitalWrite(E1, HIGH);
    digitalWrite(E2, HIGH);
    
    digitalWrite(I1, HIGH);
    digitalWrite(I2, LOW);  //This will set the circuitry of the H-bridge appropriately (e.g. the gates)
    digitalWrite(I3, LOW);
    digitalWrite(I4, LOW);
      
}

void ForwardLeft()
{
    analogWrite(E1, 255);
    analogWrite(E2, 255);
    
    digitalWrite(I1, HIGH);
    digitalWrite(I2, LOW);  //This will set the circuitry of the H-bridge appropriately (e.g. the gates)
    digitalWrite(I3, LOW);
    digitalWrite(I4, HIGH);
      
}

void BackLeft()
{
    analogWrite(E1, 255);
    analogWrite(E2, 255);
    
    digitalWrite(I1, LOW);
    digitalWrite(I2, HIGH);  //This will set the circuitry of the H-bridge appropriately (e.g. the gates)
    digitalWrite(I3, HIGH);
    digitalWrite(I4, LOW);
      
}


void TurnRight()
{
    digitalWrite(E1, HIGH );
    digitalWrite(E2, HIGH);
    
    digitalWrite(I1, LOW);
    digitalWrite(I2, LOW);  //This will set the circuitry of the H-bridge appropriately (e.g. the gates)
    digitalWrite(I3, HIGH);
    digitalWrite(I4, LOW);
      
}

void ForwardRight()
{
    analogWrite(E1, 255);
    analogWrite(E2, 255);
    
    digitalWrite(I1, LOW);
    digitalWrite(I2, HIGH);  //This will set the circuitry of the H-bridge appropriately (e.g. the gates)
    digitalWrite(I3, HIGH);
    digitalWrite(I4, LOW);
      
}

void BackRight()
{
    analogWrite(E1, 255);
    analogWrite(E2, 255);
    
    digitalWrite(I1, HIGH);
    digitalWrite(I2, LOW);  //This will set the circuitry of the H-bridge appropriately (e.g. the gates)
    digitalWrite(I3, LOW);
    digitalWrite(I4, HIGH);
      
}
   
void StopMotor()
{
    digitalWrite(E1, HIGH );
    digitalWrite(E2, HIGH);
    
    digitalWrite(I1, LOW);
    digitalWrite(I2, LOW);  //This will set the circuitry of the H-bridge appropriately (e.g. the gates)
    digitalWrite(I3, LOW);
    digitalWrite(I4, LOW);
    
    
    
}

Any help is much appreciated!!

The code seems specifically to stop the robot if there is no command within 500 millisecs.

The way it is written it seems to expect the Android device to send characters all the time and, perhaps, your Android code is only sending a character when you press a button.

You either need to modify the Android code (which is not an Arduino issue) or the Arduino code so that their expectations coincide.

...R

Why has this Thread arrived here rather than in the section on Interfacing w/ Software on the Computer ?

...R

Hi Thanks for the reply.

How do I chande the Arduino code accordingly. Also is it possible for me to move the question to the appropriate forum now?

Part of my android code is

  btnUp.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    btnUp.setBackgroundResource(R.drawable.button_arrow_green_up_select);
                    goForward();
                    return true;
                }
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    btnUp.setBackgroundResource(R.drawable.button_arrow_green_up);
                    Stop();
                }

                return false;
            }
        });

        btnDown.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    btnDown.setBackgroundResource(R.drawable.button_arrow_green_down_select);
                    goBackward();
                    return true;
                }
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    btnDown.setBackgroundResource(R.drawable.button_arrow_green_down);
                    Stop();
                }

                return false;
            }
        });
 private void goForward()
    {
        if (btSocket!=null)
        {
            try
            {
                btSocket.getOutputStream().write("F".toString().getBytes());
            }
            catch (IOException e)
            {
                msg("Error");
            }
        }
    }

    private void goBackward()
    {
        if (btSocket!=null)
        {
            try
            {
                btSocket.getOutputStream().write("B".toString().getBytes());
            }
            catch (IOException e)
            {
                msg("Error");
            }
        }
    }
// fast way to call Toast
    private void msg(String s)
    {
        Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private class ConnectBT extends AsyncTask<Void, Void, Void>  // UI thread
    {
        private boolean ConnectSuccess = true; //if it's here, it's almost connected

        @Override
        protected void onPreExecute()
        {
            progress = ProgressDialog.show(Main.this, "Connecting...", "Please wait!!!");  //show a progress dialog
        }

        @Override
        protected Void doInBackground(Void... devices) //while the progress dialog is shown, the connection is done in background
        {
            try
            {
                if (btSocket == null || !isBtConnected)
                {
                 myBluetooth = BluetoothAdapter.getDefaultAdapter();//get the mobile bluetooth device
                 BluetoothDevice dispositivo = myBluetooth.getRemoteDevice(address);//connects to the device's address and checks if it's available
                 btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
                 BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
                 btSocket.connect();//start connection
                }
            }
            catch (IOException e)
            {
                ConnectSuccess = false;//if the try failed, you can check the exception here
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
        {
            super.onPostExecute(result);

            if (!ConnectSuccess)
            {
                msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
                finish();
            }
            else
            {
                msg("Connected.");
                isBtConnected = true;
            }
            progress.dismiss();
        }
    }
}

I think I see where the problem is. I will try and let you know :slight_smile:

I got rid of the 500ms Stop motor from the arduino code. Thanks for your help. It works Now :slight_smile: