Android Bluetooth joystick

Hi Bob1943

I think your “Joystick bt commander” is brilliant

Thanks 8)

I am having intermittent problems connecting from Android to Arduino via HC-05 module and very rarely get data from Arduino to Android

Can you be more specific, I would expect the App to always work or always fail... :roll_eyes: :roll_eyes:

Is there a correct boot up sequence between Arduino and Anroid or doesn’t it matter?

No, doesn't matter

When I changed the baud rate in AT commands I used AT+UART=57600,0,0 – is that correct?

Yes, make sure you have entered the Command mode I just prepared a sketch for my new HC-05 board. Will display - device name - firmware version - serial parameters

// Iteaduino BT board configurator - BASIC version

// Utility will display actual Baud rate

// TX BT board pin to Arduino D2
// RX BT board pin to Arduino D3
// 5V BT board pin to Arduino 5V
// GND BT board pin to Arduino GND

// set Serial Monitor @57600bps

#include "SoftwareSerial.h"

SoftwareSerial mySerial(2, 3);          // BlueTooth module TX RX
char response[30];                      // responses from module
int rv = 0;                             // return value

void setup()  {
  Serial.begin(57600);
  mySerial.begin(38400);                  //  config mode bps
  mySerial.setTimeout(500); 
  delay(300);
  Serial.print("\n\nIteaduino BT board configurator ");
  Serial.print("\nSearching ...");        
  mySerial.write("at\r\n");               // BT card bug ???
  delay(20);
  mySerial.readBytes(response, 15);
  mySerial.write("at\r\n");               // "AT" will respond with "OK" if it is working
  delay(20);
  response[0] = 0;
  rv = mySerial.readBytes(response, 15);
  response[rv] = 0;
  if (strncmp(response, "OK", 2)==0)    Serial.println("\n\nBluetooth Module found");
  else  {
    Serial.println("\nERROR: Bluetooth Module not responding!");
    Serial.println("Make sure there are no active bluetooth connection and try again");
    while(1);
  }
  
  delay(100);
  mySerial.write("at+name?\r\n");               // Check device name
  while(mySerial.available() == 0);
  rv = mySerial.readBytes(response, 30);
  response[rv] = 0;
  if (strncmp(response, "+NAME:", 6)==0)  {
    Serial.print("Name: ");
    Serial.println(response);
  }  else  {  
    Serial.println("Error checking name");
    while(1);
  }

  delay(100);
  mySerial.write("at+version?\r\n");           // Check firmware version
  while(mySerial.available() == 0);
  response[0] = 0;
  rv = mySerial.readBytes(response, 30);
  response[rv] = 0;
  Serial.print("Version: ");
  Serial.println(response);

  delay(100);
  mySerial.write("at+uart?\r\n");           // Check serial parameters
  while(mySerial.available() == 0);
  response[0] = 0;
  rv = mySerial.readBytes(response, 30);
  response[rv] = 0;
  Serial.print("Serial: ");
  Serial.println(response);
}

void loop() { }

Please confirm your BT board baud rate

Also I think I may have a mismatch of Wiring diagram/ino code/Android app. Can you email me details of where I can get the latest drawings/codes etc.

Bluetooth TX connected to D2 and RX connected to D3 Joystick bluetooth Commander V4.0 is here AndroTest V1.3.ino is there

Please answer the 9 questions as per above

@n3kx

Base on your responses, problem is the BT card to Arduino board serial connection Is your BT card HC-05 or HC-06 ?? let me have a link to your specific model You may reverse TX and RX cables just to make sure, this will not harm anything Did you actuallly check you BT card baud rate ?? they usually default to 9600bps Have succesfully used this card for other projects ??

Can you see the scrolling Joystick values in the Serial Monitor ??

My model is HC-05 and it work @9600bps. I use your older version and it works, even on version 4.0 it works Arduino receive joystick data as button data no problem. But datafields doesnt change there are always showing XXXX.

I have this type of Bluetooth: http://www.ebay.com/itm/Wireless-Serial-6-Pin-Bluetooth-RF-Transceiver-Module-HC-05-RS232-Master-Slave-D-/400709013564?pt=LH_DefaultDomain_2&hash=item5d4c1e503c

Hi, thanks for your rapid response. Your assistance in helping is excellent. Hope I have answered your questions so I can get a response from Arduino UNO back to Android

I used the AT Command setup at this URL http://arduinofy.blogspot.co.uk/2013/10/tutorial-programming-hc-05-at-mode-with.html

when completed AT+UART? Returned: 57600,0,0

Your sketch headed: // Iteaduino BT board configurator - BASIC version Returned the following error message:

Iteaduino BT board configurator Searching ... ERROR: Bluetooth Module not responding! Make sure there are no active bluetooth connection and try again I couldn’t find anything paired with the HC-05 The red BT LED flashed on/off about every half second

Your sketch headed: AndroTest V1.3 - @kas2014\ndemo for V4.X (6 button version) Only Connections: .Arduino pin#2 to TX BlueTooth module . Arduino pin#3 to RX BlueTooth module ..Arduino 3.3v to 3.3 BlueTooth module ..Arduino GND to GND NOTE: Key and 5v not connected

Paired and connected with Android (v4.0.4) OK. Still only xxx showing bottom left. Interesting point is that button B5 stays locked the same as other buttons until pressed again to release. (I did notice at one time it did act like a push button – maybe that was when data got fed back). Just a thought I think the connection problems may be down to me as that problem appears to have gone away. My only problem now (apart from error in BT board configurator mentioned above) is the failure to get a signal from Arduino to Adoid.

Answers to 9 question in reply #197 1..Version v4.0.4 2. Yes 3. Yes 4. Yes 5. Yes 6. Yes 7. NO – Initially Red LED flashes continuously but when connected it flashes twice every couple of seconds (not solid red as in question) 8. Yes 9. Yes

Observations: I am not experienced with serial coms., but understand there are parity and stop bits. When I changed the BT module to 57600 baud I sent AT+UART=57600,0,0 and the AT command AT+UART? returned: 57600,0,0 Is that OK?

BT Red LED flashes rapldly before pairing. Then when paired changes to on/off flash every 2 seconds then but when connected it flashes twice every couple of seconds.

UNO TX LED flashes about every 2 seconds and whenever a button is pressed. When the joystick is moved it constantly flickers, then after about 10 seconds of continuous joystick movement the TX LED locks on. Opening the serial monitor window seems to return it back to normal. UNO RX LED only ever flashes when uploading code

Hope some of this makes sense – thanks again for your help Bob

@ n3kx

even on version 4.0 it works Arduino receive joystick data as button data no problem. But datafields doesnt change there are always showing XXXX

Interesting Android to Arduino communication is OK Arduino to Android communication is not wired correctly

I have this type of Bluetooth: ...

The link is broken, please double check and let me know

Which Arduino board do you use ?? Can you post a photo of you setup ?? Did you modify the actual demo sketch ??

My model is HC-05 and it work @9600bps

Although this is not the cause of your problem, 9600bps is too slow for the data stream and generates transmission errors

I strongly urge everybody to set speed @57600bps

Depending on your specific model, I can post a tool for this adjustment

@ n3kx

I just downgraded my HC-05 board to 9600bps and could reproduce your situation ]:) ]:) ]:)

Please modify demo sketch as follow: in void loop() line #3 change "delay(5);" to "delay(2);" in void loop() last line remove "delay(5);"

Did you make any change in Option for advanced users ?? Let me know your current settings for - Refresh interval - Time out count

Today I bought HC-06 and it work @9600 pbs. So can you post code how to change it to whatever it need . I try change delay but same results.

Today I bought HC-06 and it work @9600 pbs. So can you post code how to change it to whatever it need . I try change delay but same results.

Glad it works with HC-06 Please scroll up to reply #15 and download the HC-06 config tool

I own HC-05 and HC-06 cards and they both work flawlessly @57600bps

Did you make any change in "Option for advanced users" ?? Let me know your current settings for - Refresh interval - Time out count

Please reply

@Bob1943

Still only xxx showing bottom left

Are you referring to the joystick position field at bottom left of android device screen ?? :astonished: This should indicate joystick position at App start up, even before any connection It should read (-100,-100) for South West position and (100,100) for North East position

Interesting point is that button B5 stays locked the same as other buttons until pressed again to release. (I did notice at one time it did act like a push button – maybe that was when data got fed back).

This is normal behavior when not connected

My only problem now (apart from error in BT board configurator mentioned above) is the failure to get a signal from Arduino to Android.

  • You can follow joystick position and buttons state on you Serial Monitor
  • Datafields don't update, B5 is not in "push" mode Correct ??

Answers to 9 question in reply #197 1..Version v4.0.4

I was talking about App version, should be V4.0 OK ??

the AT command AT+UART? returned: 57600,0,0 Is that OK?

Yes According to documentation Param2 = stop bit: 0->1 bit 1->2 bits Param3 = parity bit: 0->None 1->Odd parity 2->Even parity Arduino serial is 8N1 (1 stop bit, no parity)

UNO TX LED flashes about every 2 seconds and whenever a button is pressed. When the joystick is moved it constantly flickers,

This reflects the data flowing from Arduino to Serial Monitor

then after about 10 seconds of continuous joystick movement the TX LED locks on. Opening the serial monitor window seems to return it back to normal.

Strange :relaxed: :relaxed:

Did you change any setting in Advanced options ?? Try "reset Option" to restore initial parameters EDIT: also set Refresh interval @100ms, Timeout count @every 10 intervals

Finally let me have a link to your specific BT board

Data flow from Arduino to Android problem SOLVED

I am using Joystick BT Commander on an Android Tablet. This allows Apps to be closed by swiping the minimised app icon off the screen. This was the problem.

When I closed the App by using back button (hairpin arrow) and confirm “Total RC Commander - close this controller” and then re-open the App it works OK. Data received back from Arduino and Button 5 is in push mode. Apologies for inconvenience and thanks for your time. It is great to see the care and level of attention that you provide to the users of your App. Again many thanks - Brilliant App Bob

Data flow from Arduino to Android problem SOLVED ..... It is great to see the care and level of attention that you provide to the users of your App. Again many thanks - Brilliant App Bob

Thanks Bob for the good new and the kind words 8)

I am investing time because this App should bring a lot to the Arduino community It is a universal remote for most projects, using wide spread (Android) technologies. I told my friend to download the App and within a minute he took control of my RC tank He was rather impressed :astonished: :astonished: :astonished:

During my support session, I did some interesting stress tests yesterday. I tried various data refresh interval at different baud rates and found some minor glitches. Please use AndroTest_V14.ino

#define VERSION     "\n\nAndroTest V1.4 - @kas2014\ndemo for V4.X  (6 button version)"

// V1.4  improved communication errors handling
// V1.3  renamed for publishing, posted on 09/05/2014
// V1.2  Text display   ** not backward compatible **
// V1.1  Integer display
// V1.0  6 buttons + 4 data char implemented

    **  The message exceeds the maximum allowed length (9500 characters)  **
See next message

This updated sketch features optimized timing and better transmission error management Again, make sure your BT board is set @57600bps Avoid using 25ms refresh interval and continuous timeout count, that's too much data I am also preparing V5.0, with a pure ASCII communication protocol

Some thoughts

  1. Where is AndroTest_V14.ino – only some lines showing?

  2. In the Android app can you recognise when the app has been closed ‘illegally’ and act upon that action next time the app is opened. Might make it idiot proof.

  3. When you first touch the yellow joystick dot, it immediately moves to the centre of the touch point. This changes the xy numbers – most noticeable when you touch the edge. (I want to control two servos but don’t want them to move until the joystick is moved intentionally). Can the touch point be recognised without moving the yellow dot?

  4. What do I need to change to alter the data fields fed back to the Android and can it be coded in “Your code here” areas in the Arduino sketch. I am doing number crunching on Arduino from Joystick positions and would like to send three values back to android.

Here it is

#define VERSION     "\n\nAndroTest V1.41 - @kas2014\ndemo for V4.X  (6 button version)"

// V1.41 minor modifications
// V1.4  improved communication errors handling
// V1.3  renamed for publishing, posted on 09/05/2014
// V1.2  Text display   ** not backward compatible **
// V1.1  Integer display
// V1.0  6 buttons + 4 data char implemented

// Demo setup:
// Button #1 controls pin13 LED
// Button #2 starts DEBUG
// Button #3 displays demo message
// Button #4 toggle datafield display rate
// Button #5 configured as "push" button (momentary)

// Arduino pin#2 to TX BlueTooth module
// Arduino pin#3 to RX BlueTooth module
// make sure your BT board is set @57600 bps
// better remove SoftSerial for PWM based projects

// For Mega 2560:
// remove   #include "SoftwareSerial.h", SoftwareSerial mySerial(2,3);
// search/replace  mySerial  >> Serial1
// pin#18 to RX bluetooth module, pin#19 to TX bluetooth module

#include "SoftwareSerial.h"

#define    STX          0x01
#define    ETX          0x00
#define    ledPin       13
#define    SLOW         1000                           // Datafields refresh rate (ms)
#define    FAST         250                            // Datafields refresh rate (ms)

SoftwareSerial mySerial(2,3);                           // BlueTooth module: pin#2=TX pin#3=RX
int i=0;
byte cmd[6] = {0, 0, 0, 0, 0, 0};                       // bytes received
byte buttonStatus = 0;                                  // first Byte sent to Android device
long previousMillis = 0;                                // will store last time Buttons status was updated
boolean setButtonFeedback = false;                      // momentary buttons feedback to Android device
long sendInterval = SLOW;                               // interval between Buttons status transmission (milliseconds)
String displayStatus = "xxxx";                          // message to Android device

void setup()  {
  Serial.begin(57600);
  mySerial.begin(57600);                                // 57600 = max value for softserial
  pinMode(ledPin, OUTPUT);     
  Serial.println(VERSION);
  while(mySerial.available())  mySerial.read();         // empty RX buffer    //  <<mod XXXXXXXX 
}

void loop() {
  if(mySerial.available())  {                            // data received from smartphone
    delay(2);                                                              //  <<mod XXXXXXXX
    cmd[0] =  mySerial.read();  
    if(cmd[0] == STX)  {
      i=1;      
      while(mySerial.available())  {
        delay(1);                                                          //  <<mod XXXXXXXX
        cmd[i] = mySerial.read();
        if(cmd[i]>127 || i>5)                               break;   // Communication error << XXX Mod
        if((cmd[i]==ETX) && ((i==2 && cmd[1]>2) || i==5))   break;   // Button or Joystick data
        i++;
      }
      if     (i==2 && cmd[1]>48 && cmd[1]<68)     getButtonState(cmd[1]);                         // 3 Bytes
      else if(i==5 && cmd[1]<3  && cmd[3]<3 )     getJoystickState(cmd);                          // 6 Bytes
    }
  }
  sendBlueToothData();                                                       //  <<mod XXXXXXXX
//    delay(5);                                                              //  <<mod XXXXXXXX
// your code here
}

void sendBlueToothData()  {
  static long previousMillis = 0;                             
  long currentMillis = millis();
  if(setButtonFeedback == true)  {                      // allow momentary button visual effect
    previousMillis = currentMillis + 250;   
    setButtonFeedback = false;
  }
  if(currentMillis - previousMillis > sendInterval) {   // send data to smartphone
    previousMillis = currentMillis; 

// Data frame transmitted back from Arduino to Android device:
// < 0X02   Buttons state   0X01   DataField#1   0x04   DataField#2   0x05   DataField#3    0x03 >  
// < 0X02       01011       0X01      120.00     0x04      -4500      0x05   Motor enabled  0x03 >    // example

    mySerial.print((char)0x2);                                                 // Start of Transmission
    mySerial.print(getButtonStatusString());      mySerial.print((char)0x1);   // buttons status feedback
    mySerial.print(GetDataField_1_int());         mySerial.print((char)0x4);   // datafield #1
    mySerial.print(GetDataField_2_float());       mySerial.print((char)0x5);   // datafield #2
    mySerial.print(displayStatus);                                             // datafield #3
    mySerial.print((char)0x3);                                                 // End of Transmission
  }  
}

String getButtonStatusString()  {
  String bStatus = "";
  for(int i=0; i<6; i++)  {
    if(buttonStatus & (B100000 >>i))      bStatus += "1";
    else                                  bStatus += "0";
  }
  return bStatus;
}

int GetDataField_1_int()  {            // Data dummy values sent to Android device for demo purpose
  static int i= -30;                   // Replace with your own code
  i ++;
  if(i >0)    i = -3000;
  return i;  
}

float GetDataField_2_float()  {       // Data dummy values sent to Android device for demo purpose
  static float i=50;                  // Replace with your own code
  i-=.5;
  if(i <-50)    i = 50;
  return i;  
}

void getJoystickState(byte data[6])    {                             //  <<mod XXXXXXXX   nasty bug, was byte data[5]
  int joyX = (data[1]<<7) + data[2];
  int joyY = (data[3]<<7) + data[4];
  joyX = joyX - 200;                                            // Offset to avoid
  joyY = joyY - 200;                                            // transmitting negative numbers
  if(joyX<-100 || joyX>100 || joyY<-100 || joyY>100)    return; // commmunication error
  
  Serial.print("Joystick position:  ");
  Serial.print(joyX); Serial.print(", "); Serial.println(joyY);
    
// Your code here ...
}

void getButtonState(int bStatus)  {
  switch (bStatus) {
// -----------------  BUTTON #1  -----------------------
    case '1':
      buttonStatus |= B000001;        // ON
      Serial.println("\n** Button_1: ON **");    // your code here...
      displayStatus = "LED <ON>";
      Serial.println(displayStatus);
      digitalWrite(ledPin, HIGH);
      break;
    case '2':
      buttonStatus &= B111110;        // OFF
      Serial.println("\n** Button_1: OFF **");    // your code here...
      displayStatus = "LED <OFF>";
      Serial.println(displayStatus);
      digitalWrite(ledPin, LOW);
      break;
// -----------------  BUTTON #2  -----------------------
    case '3':
      buttonStatus |= B000010;        // ON
      Serial.println("\n** Button_2: ON **");    // your code here...
      break;
    case '4':
      buttonStatus &= B111101;        // OFF
      Serial.println("\n** Button_2: OFF **");    // your code here...
      break;
// -----------------  BUTTON #3  -----------------------
    case '5':
      buttonStatus |= B000100;        // ON
     // setButtonFeedback = true;            moved to button #5 (for push buttons)
      Serial.println("\n** Button_3: ON **");    // your code here...
      displayStatus = "Motor #1 enabled"; // Demo text message
      Serial.println(displayStatus);
      break;
    case '6':
      buttonStatus &= B111011;      // OFF
      Serial.println("\n** Button_3: OFF **");    // your code here...
      displayStatus = "Motor #1 stopped";
      Serial.println(displayStatus);
      break;
// -----------------  BUTTON #4  -----------------------
    case '7':
      buttonStatus |= B001000;       // ON
      Serial.println("\n** Button_4: ON **");    // your code here...
      displayStatus = "Datafield update <FAST>";
      Serial.println(displayStatus);
      sendInterval = FAST;
      break;
    case '8':
      buttonStatus &= B110111;    // OFF
      Serial.println("\n** Button_4: OFF **");    // your code here...
      displayStatus = "Datafield update <SLOW>";
      Serial.println(displayStatus);
      sendInterval = SLOW;
     break;
// -----------------  BUTTON #5  -----------------------
    case '9':           // configured as momentary button
//      buttonStatus |= B010000;        // ON
      setButtonFeedback = true;                     // moved from button #3
      Serial.println("\n** Button_5: + pushed + **"); // your code here...
      displayStatus = "Button_5: ++ pushed ++";
      break;
//   case 'A':
//     buttonStatus &= B101111;        // OFF
//     break;
// -----------------  BUTTON #6  -----------------------
    case 'B':
      buttonStatus |= B100000;        // ON
      Serial.println("\n** Button_6: ON **");    // your code here...
       displayStatus = "Button #6 ON"; // Demo text message
     break;
    case 'C':
      buttonStatus &= B011111;        // OFF
      Serial.println("\n** Button_6: OFF **");    // your code here...
      displayStatus = "Button #6 OFF";
      break;
// -----------------------------------------------------
  }
}

EDIT: moved setButtonFeedback from button #3 to button #5 (push button)
Added 1ms delay after while(mySerial.available())
Renamed to AndroTest V1.41 see Reply #225

  1. In the Android app can you recognise when the app has been closed ‘illegally’ and act upon that action next time the app is opened. Might make it idiot proof.

Not sure to understand, please clarify "This allows Apps to be closed by swiping the minimized app icon off the screen"

Can the touch point be recognised without moving the yellow dot?

I understand your concern, makes sense, let me think about it...

  1. What do I need to change to alter the data fields fed back to the Android and can it be coded in “Your code here” areas in the Arduino sketch. I am doing number crunching on Arduino from Joystick positions and would like to send three values back to android.

To send back three values to Android (data_1, data_2,data_3,) just modify sendBlueToothData()

void sendBlueToothData()  {

    ......................
    ......................

    mySerial.print((char)0x2);                                                 // Start of Transmission
    mySerial.print(getButtonStatusString());      mySerial.print((char)0x1);   // buttons status feedback
    mySerial.print(data_1);                       mySerial.print((char)0x4);   // datafield #1
    mySerial.print(data_2);                       mySerial.print((char)0x5);   // datafield #2
    mySerial.print(data_3);                                                    // datafield #3
    mySerial.print((char)0x3);                                                 // End of Transmission
  }  
}

Hi, Thanks for information

The swipe-to-close feature is about 40 seconds into video at this site: http://blog.laptopmag.com/9-awesome-android-ice-cream-sandwich-tips

This method is what was causing problem about no data from Arduino to Android. I wonder if this happens with other users?

The swipe-to-close feature is about 40 seconds into video at this site:
http://blog.laptopmag.com/9-awesome-android-ice-cream-sandwich-tips
This method is what was causing problem about no data from Arduino to Android. I wonder if this happens with other users?

I can’t replicate the “swipe” problem both on Galaxy Tab3 tablet and Motorola G phone (V4.4.2)
Please let me have a step by step procedure

I am using a 7 inch tablet which doesn't have phone but allows multitasking. My Samsung GT-S5570 phone won't recognise the HC-05 so I can't test on mobile phone. However, the link below shows how to swipe on Galaxy 3. Hope this helps. I think all Android tablets have swipe-to-close so others may also have a problem. If you want I can video the actions. Just let me know

https://www.youtube.com/watch?v=I5wRaFSDIPo

(anyone know why my Samsung GT-S5570 phone won't recognise the HC-05)

@ Bob1943

  1. When you first touch the yellow joystick dot, it immediately moves to the centre of the touch point. This changes the xy numbers – most noticeable when you touch the edge. (I want to control two servos but don’t want them to move until the joystick is moved intentionally). Can the touch point be recognised without moving the yellow dot?

I understand your concern, makes sense, let me think about it...

I addressed the situation ;) Please let me have your email via PM, I will send you V4.1 for testing

I addressed the situation ;) Please let me have your email via PM, I will send you V4.1 for testing

Check your mail ...

Hi Kas, This version V4.1 works fine. Wherever you touch on the yellow spot is returned as coordinate 0,0 (x,y) which is exactly what I was looking for. No jumpy servos anymore. - Many thanks