Bluetooth: App not receiving data from Arduino HC-05

Hello, I am making a joystick-controlled robotic car for my project. When an obstacle is detected by the ultrasonic sensors, it should send this data to the mobile app and the app will produce a sound to alert the user.

I am having issues with the app not receiving the data which is sent by the Arduino.

To test a simple scenario, I just want the app to make a 'beep' sound when the joystick is pressed. The Arduino IDE will Serial.println("j") just fine, but it is somehow not received by the app. I watched tutorials which used call BluetoothClient1.BytesAvailableToReceive > 0 but it didn't work. I changed the value to > -1 and got some progress. But still, it is not producing the sound when the joystick is pressed.

I am in need of help and I greatly appreciate any assistance I can get. Thank you


#include <Joystick.h>

#include <AxisJoystick.h>

#include <AFMotor.h>

#include <NewPing.h>

AF_DCMotor motor1(1);

AF_DCMotor motor2(2);

AF_DCMotor motor3(3);

AF_DCMotor motor4(4);

//jotstick pins

#define joystick_SWPIN A10

#define joystick_XPIN A8

#define joystick_YPIN A9

//ultrasonic sensor #1 (front center)

#define TRIG1 22

#define ECHO1 24

//ultrasonic sensor #2 (left side)

#define TRIG2 26

#define ECHO2 28

//ultrasonic sensor #3 (right side)

#define TRIG3 30

#define ECHO3 32

//for car movement

int speeds = 100;

Joystick* joystick;

unsigned long debounceDuration = 50;

unsigned long lastTimeButtonStateChanged = 0;

byte lastButtonState = 0; //released

byte MovementMode = 0; //0=translation, 1=rotation

//initiate ultrasonic sensors

NewPing US1(TRIG1, ECHO1, 200);

NewPing US2(TRIG2, ECHO2, 200);

NewPing US3(TRIG3, ECHO3, 200);

void setup()

{

  Serial.begin(9600);

  joystick = new AxisJoystick(joystick_SWPIN, joystick_XPIN, joystick_YPIN);

  motor1.setSpeed(speeds);

  motor2.setSpeed(speeds);

  motor3.setSpeed(speeds);

  motor4.setSpeed(speeds);

  motor1.run(RELEASE);

  motor2.run(RELEASE);

  motor3.run(RELEASE);

  motor4.run(RELEASE);

  pinMode(joystick_SWPIN, INPUT_PULLUP);

}

void loop()

{

  int US1_distance = US1.ping_cm();

  int US2_distance = US2.ping_cm();

  int US3_distance = US3.ping_cm();

  /*

  Serial.print("Distance US1: ");

  Serial.print(US1_distance);

  Serial.print(" cm\n");

  delay(50);

  Serial.print("Distance US2: ");

  Serial.print(US2_distance);

  Serial.print(" cm\n");

  delay(50);

  Serial.print("Distance US3: ");

  Serial.print(US3_distance);

  Serial.print(" cm\n");

  delay(50);

  */

  //int obstacle = checkdistance(distanceInCm);

  if(MovementMode == 0) //MODE: TRANSLATION

  {

    if(joystick->readVRx()==0 && joystick->readVRy()>=253 && joystick->readVRy()<=759)

    {

      //Serial.println("UP");

      if(checkfront(US1_distance) == 0) //no obstacle

      {

        forward();

      }

      else

      {

        //Serial.println("OBSTACLE FRONT");

        stop();

      }

    }

    if(joystick->readVRx()==1023 && joystick->readVRy()>=253 && joystick->readVRy()<=759)

    {

      //Serial.println("DOWN");

      backward();

    }

    if(joystick->readVRx()>=253 && joystick->readVRx()<=739 && joystick->readVRy()==1023)

    {

      //Serial.println("LEFT");

     

      if(checkleft(US2_distance) == 0)

      {

        left();

      }

      else

      {

        //Serial.println("OBSACLE LEFT");

        stop();

      }

    }

    if(joystick->readVRx()>=253 && joystick->readVRx()<=759 && joystick->readVRy()==0)

    {

      //Serial.println("RIGHT");

      if(checkright(US3_distance) == 0)

      {

        right();

      }

      else

      {

        //Serial.println("OBSACLE RIGHT");

        stop();

      }

    }

    if(joystick->readVRx()>=0 && joystick->readVRx()<=253 && joystick->readVRy()>=0 && joystick->readVRy()<=253)

    {

      //Serial.println("FORWARD RIGHT");

      forwardright();

    }

    if(joystick->readVRx()>=0 && joystick->readVRx()<=253 && joystick->readVRy()>=759 && joystick->readVRy()<=1023)

    {

      //Serial.println("FORWARD LEFT");

      forwardleft();

    }

    if(joystick->readVRx()>=739 && joystick->readVRx()<=1023 && joystick->readVRy()>=759 && joystick->readVRy()<=1023)

    {

      //Serial.println("BACKWARDS LEFT");

      backwardleft();

    }

    if(joystick->readVRx()>=759 && joystick->readVRx()<=1023 && joystick->readVRy()>=0 && joystick->readVRy()<=253)

    {

      //Serial.println("BACKWARDS RIGHT");

      backwardright();

    }

  }

  else //MODE: ROTATION

  {

    if(joystick->readVRx()>=253 && joystick->readVRx()<=739 && joystick->readVRy()==1023)

    {

      //Serial.println("ROTATE LEFT");

      rotateleft();

    }

    if(joystick->readVRx()>=253 && joystick->readVRx()<=759 && joystick->readVRy()==0)

    {

      //Serial.println("ROTATE RIGHT");

      rotateright();

    }

  }

  unsigned long timeNow = millis();

 

  if(timeNow - lastTimeButtonStateChanged > debounceDuration)

  {

    byte buttonState = joystick->isPress();

    if(buttonState != lastButtonState)

    {

      lastTimeButtonStateChanged = timeNow;

      lastButtonState = buttonState;

      if(buttonState == 0) //button has been released

      {

        MovementMode = (MovementMode == 0) ? 1 : 0;

        //send to serial button has been pressed

        Serial.println("j");

      }

    }

  }

  if (moveTitle(joystick->multipleRead()) == "NOT")

  {

    //Serial.println("STOP");

    stop();

  }

}

String moveTitle(const Joystick::Move move)

{

  switch (move)

  {

    case Joystick::Move::NOT:

      return "NOT";

    case Joystick::Move::PRESS:

      return "PRESS";

    case Joystick::Move::UP:

      return "LEFT";

    case Joystick::Move::DOWN:

      return "RIGHT";

    case Joystick::Move::RIGHT:

      return "DOWN";

    case Joystick::Move::LEFT:

      return "UP";

    default:

      return "???";

  }

}

int checkfront(int US1_distance)

{

  if(US1_distance > 20 || US1_distance == 0) //no obstacle

  {

    return 0;

  }

  else //got obstacle

  {

    return 1;

  }

}

int checkleft(int US2_distance)

{

  if(US2_distance > 20 || US2_distance == 0) //no obstacle

  {

    return 0;

  }

  else //got obstacle

  {

    return 1;

  }

}

int checkright(int US3_distance)

{

  if(US3_distance > 20 || US3_distance == 0) //no obstacle

  {

    return 0;

  }

  else //got obstacle

  {

    return 1;

  }

}

void stop(){

  motor1.run(RELEASE);

  motor2.run(RELEASE);

  motor3.run(RELEASE);

  motor4.run(RELEASE);

}

void forward() {

  motor1.run(FORWARD);

  motor2.run(FORWARD);

  motor3.run(FORWARD);

  motor4.run(FORWARD);

}

void backward() {

  motor1.run(BACKWARD);

  motor2.run(BACKWARD);

  motor3.run(BACKWARD);

  motor4.run(BACKWARD);

}

void right() {

  motor1.run(BACKWARD);

  motor2.run(FORWARD);

  motor3.run(BACKWARD);

  motor4.run(FORWARD);

}

void left() {

  motor1.run(FORWARD);

  motor2.run(BACKWARD);

  motor3.run(FORWARD);

  motor4.run(BACKWARD);

}

void forwardright() {

  motor1.run(RELEASE);

  motor2.run(FORWARD);

  motor3.run(RELEASE);

  motor4.run(FORWARD);

}

void forwardleft() {

  motor1.run(FORWARD);

  motor2.run(RELEASE);

  motor3.run(FORWARD);

  motor4.run(RELEASE);

}

void backwardleft() {

  motor1.run(RELEASE);

  motor2.run(BACKWARD);

  motor3.run(RELEASE);

  motor4.run(BACKWARD);

}

void backwardright() {

  motor1.run(BACKWARD);

  motor2.run(RELEASE);

  motor3.run(BACKWARD);

  motor4.run(RELEASE);

}

void rotateleft() {

  motor1.run(BACKWARD);

  motor2.run(FORWARD);

  motor3.run(FORWARD);

  motor4.run(BACKWARD);

}

void rotateright() {

  motor1.run(FORWARD);

  motor2.run(BACKWARD);

  motor3.run(BACKWARD);

  motor4.run(FORWARD);

}

Does using your Button btn_playsound play the beep? If the sound beep does not play, where are you setting the Sound Player's source?

Yes, it does play the beep. I tested it by creating a button press which will play the sound and it works.

Great, then perhaps call sound_beep.Play at the arrow in the image?''

might work.

Unfortunately the code does not even go to that branch, it goes to the yellow 'cant detect' statement. My problem is less to do with the sound not playing, and more with the code not being able to return TRUE for the purple block.

Hi @robotinkerer23,
try by rearranging the receiving procedure like this:
image

The procedure "DoTheJob..." for me is dummy, here you have to implement your tasks.
The label L-Ricevuto is just for debug purposes.
Last hint: instead of looking for the exact text "j", you could relax the check by checking only the presence of a "j" in your received string.
Something like:
image
Once you are sure it works, you can return to the exact test (= "j").
Give it a try and let us know if it works.
Cheers.

Hi @uskiara ,
I have followed your suggestions but alas, the app is still not producing a sound when I press my joystick button. Here is the full code in MIT app inventor: (note, the btn_playsound is just for testing to ensure that a sound actually plays. it is not part of the final app)

Here is the serial output (9600) in Arduino IDE:

Here is the application interface with the textbox used to debug:

P.S. I wonder if I need to declare the bluetooth pins or install any library in Arduino IDE? My assumption is the Bluetooth module is working fine since there is no problem in establishing connection (as seen in the app interface), and several YouTube tutorials I watched did not need to declare or install anything from the Arduino side.

Your help is greatly appreciated, thanks

Android version?
You must request / grant permissions (on Android 12+).

(Canned Response)
These blocks can be dragged into your Blocks Editor to request permission(s) for Bluetooth scanning and connecting. All three parts are needed.




Thanks to @Anke for the original code.
My changes include

  • use of the Screen1 permission blocks to avoid the possibility of a typo
  • using a TinyDB tag particular to BT permissions and only for BT permissions.

I normally see two Serial streams in these projects, one for debugging and one for data transfer.

In Designer ClientBluetooth.DelimiterByte : 10

In the example of @uskiara in Designer Clock Enabled.

Comment out all // Serial.println except Serial.println("j");
What do you get on your Serial Monitor when you press the joystickbutton: buttonState?

What Arduino terminals do you have the BT module connected to?

How many bauds is your HC-05 set to?

More examples:

In an attempt to simplify the experiment, I have made a simple circuit using an Arduino, breadboard, the same HC-05 module, and 1 ultrasonic sensor. When the ultrasonic sensor's distance is less than 20cm, the app should make a sound. I followed the YouTube tutorial here: Bluetooth Arduino RECEIVE data + Chart - YouTube [timestamp 6:13]

This is much closer to my actual project since the app is supposed to make a sound when the rc car detects an obstacle, rather than the joystick press which was just used for testing.

Sadly, the app still does not make a sound when I put my hand near the ultrasonic sensor. I suspect it may have something to do with 'ping time' (I don't know the proper term) between the sensor and the app.

In response to @Juan_Antonio , my bluetooth baud is at 9600. Just for good measure, I tried 38,400 and it did not work either. My bluetooth is connected to my Arduino UNO (for testing, it will be switched to Mega for final) with Tx and Rx on the opposite pins respectively.

I have yet to attempt @ABG 's suggestion on the 3-part blocks about permissions. I will update on how that goes. My Android version is 13.

Here's my simple experiment setup:

  1. MIT app inventor


  2. Arduino code and serial output (9600)

#include <NewPing.h>

#define TRIG1 5
#define ECHO1 4

//initiate ultrasonic sensors
NewPing US1(TRIG1, ECHO1, 200);

void setup() 
{
  Serial.begin(38400);
}

void loop()
{
  int US1_distance = US1.ping_cm();

  if(US1_distance > 20 || US1_distance == 0) //no obstacle
  {
    Serial.println("n");
  }
  else //got obstacle 
  {
    Serial.println("d");
  }
}

  1. Phone app

  2. Physical setup

Again, I appreciate all of your help, thank you.

Does this code work with the ultrasonic.zip library?

JoyStick
https://community.appinventor.mit.edu/t/bluetooth-hc-06-arduino-send-receive-send-text-file-multitouch-image/9518/23

Your app should show the raw data received from BlueTooth to aid in debugging.

Assign the incoming data into a global variable, and feed that variable into a Label and into your if/then testing.

Here is a logger you can add to your project to log your incoming messages into a List Picker.
https://groups.google.com/g/mitappinventortest/c/II_RlElGddU/m/J0q_E-2rAwAJ

old hc-05 modules with golden tick N only one red led in bottom left module worked fine with bluetooth client block but latest hc-05 module with blue led and without gloden tick on chip are not connecting with bluetooth client block.

Sorry for this very late reply, but I have been out for one month.
The last post from @akshay_kumar_pal is very interesting, therefore to be sure that the HC05 is working properly, or not, you can run a "ready made" Bluetooth app on your Android device.
Typically I use, and suggest, the following: "Serial Bluetooth Terminal" (SBT) that you can freely download fom Google Playstore. By using that app you can verify whether your HC05 can be paired to your device and if it transmits properly. In this case, you should modify your Arduino code as simple as:

define TIMEOUT 1000
unsigned long Ltimeout = 0L;

void setup()
{
Serial.begin(9600); // assuming that the HC05 works @9600 toward Arduino board
Ltimeout = millis(); // first time acquisition
}

void loop()
{
Serial.println('A'); // Dummy transmission on BT line
while ( (millis() - Ltimeout) < TIMEOUT) ; // do nothing for one second but leaves the CPU alive
Ltimeout = millis(); // acquire the new time for the next waiting
}

Please note that I don't use the delay() function because it could put in a sleeping condition the Arduino CPU, therefore avoiding the correct transmission.
At that moment run on your Android device the SBT, let it search for th e HC05 board within the available BT's in the neighbourhood, pair it, and see what happens. You should receive an 'A' every 1 second.
Once you are done with that, and only after, you can be sure that the system (Arduino+HC05 and Android device) is communicating properly. Until you get this result, it's a waste of time in doing anything else.
Best wishes.