Android Bluetooth joystick

Along with all others, again.. GREAT APP! Nice layout. Easy to use. And all functions work as designed. Can even send data now.

I don't expect you to modify anything, but just a couple of observations...

  1. The condition is rare and does not seem to correlate with any certain circumstance, but it has happened that the yellow stick will lock itself in a position other than "center", usually about the 10 o'clock or the 5 o'clock location. It seems to lock position at about 1/3 the distance from center to the outer ring. I've seen it happen 3 or 4 times in testing.

  2. It would be nice if your APP could receive and display a text message. ie "X axis is clear", "Pump 3 flow rate set to 40%", "Press B1 to launch" etc.

  3. I am experimenting with a continuous rotation servo. I may be able to correct this in my own software but as it is - when the stick is released 3 or 4 readings are sent before the stick settles into the center position. The affect of this is the lack of ability to stop the servo rotation at a precise point. I've tried several different refresh interval and timeout count settings but it does not seem to help. You'd know best, but perhaps the remedy lies in my own Propeller code. The other option would be - upon stick release --> automatic center (100,100) without the intermediate readings.

The above are just observations - no big deal. Joystick is a GREAT educational opportunity to learn about Bluetooth control and most will find a way to incorporate it in their projects as is. Thanks for sharing your work.

@juycce

Great job KAS , i test again and you was right,your app works great with Android 2.3.5,and the HC-06 also compatible (bad thing is i don't receive any data,i can only send) smiley-grin:D so...

You mean data from Arduino to Smartphone ?? Provided the connection is established, it should work :roll_eyes: [u]You may have to drop SoftSerial communication if you still use it[/u] Please post your current Arduino sketch

Based on your replay at post #146 i am trying to modify the arduino code with your permision, so that on vertical move a DC Motor, and the orizontal a Servo (for steering)... the joyY control Vertical joystick movement, and "joyX" the horizontal right ?

Right

@wildatheart

Along with all others, again.. GREAT APP! Nice layout. Easy to use. And all functions work as designed. Can even send data now.

Glad it works, thanks for the comments :)

it has happened that the yellow stick will lock itself in a position other than "center", usually about the 10 o'clock or the 5 o'clock location. It seems to lock position at about 1/3 the distance from center to the outer ring. I've seen it happen 3 or 4 times in testing.

I tried and couldn't reproduce this "feature" What is your App version ?? (Option > About...) When the freezing occurs, - is the BT connection established - what is the displayed joystick position

It would be nice if your APP could receive and display a text message. ie "X axis is clear", "Pump 3 flow rate set to 40%", "Press B1 to launch" etc.

I will think about it ;)

I am experimenting with a continuous rotation servo. I may be able to correct this in my own software but as it is - when the stick is released 3 or 4 readings are sent before the stick settles into the center position. The affect of this is the lack of ability to stop the servo rotation at a precise point.

I understand the point I may be wrong, but a joystick is not supposed to work that way For my pan/tilt servo device, I just uncheck Auto return to center (Option > Joystick behavior) I get a precise positioning, no need to return to center Am I missing something ??

Joystick is a GREAT educational opportunity to learn about Bluetooth control and most will find a way to incorporate it in their projects as is. Thanks for sharing your work

Thanks, comments appreciated :)

Still working on my new toy (see reply #152) For the moment, I am busy tuning my PID motors (more info), while monitoring battery level (8.2V) I just toggle buttons Up or Down; the actual values are displayed in the data fields.

Kas, thanks for giving thought to the possibility of 'text'.

Started a thread in the Parallax forum using your App and the Propeller Quickstart board as a quick and dirty demo. We've been doing a lot with C over there and the timing of this is just right to generate added interest. Feel free to join us.[/ I think there'd be great interest in a brief tutorial on writing Android Apps too.

http://forums.parallax.com/showthread.php/154687-EZ-Bluetooth-in-***C***-and-a-nice-App

If the asterisks mess with the link, copy and paste the entire line. I think its okay if you just click it.

hi kas, you could upload the apk with 6 buttons and 4 data XD XD XD XD

this is the code i have modified a little so i can control the speed (on Vertical) of a continuous servo ,and the normal servo on horizontal … in case someone need it :wink: :

// Andro_Pan&Tilt      V3.1
// Arduino demo sketch for Joystick BT commander V3.X
// Controls two servo motors

// V3.0: Android BT Commander V3.X compatible, no button data management
// V2.5 can receive both Byte & Integer data
// V2.0: removed SoftwareSerial

// Android BT Commander settings:
// Options/Options for advanced users/Data Range        >>>  -180 to +180
// Options/Options for advanced users/Refresh interval  >>>  25ms

//  Arduino pin #0 to TX BlueTooth module
// BT TX to be disconnected from D0 during sketch upload

#include <Servo.h> 

boolean    DEBUG = false;

#define    pinServo_X     9
#define    pinServo_Y     10        //continuous servo 
#define    STX            0x02
#define    ETX            0x03
#define    MAX_Y          2000      // max servo speed limit        
#define    ZERO_Y         1500      // middle servo point
#define    MIN_Y          1000      // min servo speed limit 
#define    ledPin1        13
#define    ledPin2        12

int i=0;
byte cmd[6] = {0, 0, 0, 0, 0, 0};
Servo myservoX;                       // create servo object
Servo myservoY; 
byte buttonStatus = 0;                // first Byte sent to Android device
byte dataByte = 0;                    // second 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 interval = 1000;                 // interval between Buttons status transmission (milliseconds)


void setup()  {
  Serial.begin(9600);
  myservoX.attach(pinServo_X);  
  myservoY.attach(pinServo_Y);  
  pinMode(ledPin1, OUTPUT);     
  pinMode(ledPin2, OUTPUT);   
  if(DEBUG)  Serial.println("Stepper demo for Android BT Commander V3.X");
}

void loop() {
  if(Serial.available())  {                   // data received from smartphone
    delay(5);
    cmd[0] =  Serial.read();  
    if(cmd[0] == STX)  {  
      i=1;      
      while(Serial.available())  {
        cmd[i] = Serial.read();
        if(cmd[i] == ETX)  {
          if(i==2 && cmd[1]>48)                break;    // Button data
          if(i==5 && cmd[1]<3 && cmd[3]<3)     break;    // Joystick data
        }
        if(i>5)   break;
        i++;
      }
      if     (i==2)   getButtonState(cmd[1]);             // 3 Bytes
      else if(i==5)   setServoPosition(cmd);                                     // 5 Bytes
      else            Serial.println("Communication error");
    }
  }  else  {
    long currentMillis = millis();
    if(setButtonFeedback == true)  {                      // allow momentary button visual effect (500 ms)
      previousMillis = currentMillis - interval*0.5;   
      setButtonFeedback = false;
    }  
  }
  delay(5);
}

void setServoPosition(byte data[5])    {
  int joyX = (data[1]<<7) + data[2];
  int joyY = (data[3]<<7) + data[4];
  joyX = joyX - 200;                      
  joyY = joyY - 200;                        
  
  joyX = map(joyX, -180, 180, 180, 0);      // (-180/+180 JBC range)
  joyY = map(joyY,  0, 423, 0, 1023);       // vertical continuous servo value

  joyY+=ZERO_Y;
  joyY = constrain(joyY, MIN_Y, MAX_Y);
  myservoX.write(joyX);
  myservoY.write(joyY);
  if(DEBUG)  {
  Serial.print(joyX); Serial.print(", ");Serial.println(joyY);}
}

void getButtonState(int bStatus)  {
  switch (bStatus) {
    case '1':
      buttonStatus |= B0001;        // Button_1: ON
      Serial.println("Button_1: ON");
      digitalWrite(ledPin1, HIGH);   // LED 1 "ON"
      break;
    case '2':
      buttonStatus &= B1110;        // Button_1: OFF
      Serial.println("Button_1: OFF");
      // your code...      
      digitalWrite(ledPin1, LOW);    // LED 1 "OFF"
      break;
      
    case '3':
      buttonStatus |= B0010;        // Button_2: ON
      DEBUG = true;
      digitalWrite(ledPin2, HIGH);   // LED 2 "ON"    
      break;
      
    case '4':
      buttonStatus &= B1101;        // Button_2: OFF
      DEBUG = false;
      Serial.println("Button_2: OFF");
      digitalWrite(ledPin2, LOW);     
      break;
  }
}

… now i am working on the hard part…control a DC motor on the vertical axis with the TB6612FNG with the PWM
i will need some help

hi kas, you could upload the apk with 6 buttons and 4 data XD XD XD XD

Sorry nemesis159, I missed your recent PM :blush:

The 6 buttons, 4 data bytes App is now released as Joystick BT Plus The actual number of buttons and data fields is adjustable within the Option menu Fields and buttons labels are fully customizable

Road map: Next revision will include an option to perform control using the android device built-in accelerometers Control will be performed by tilting the smartphone/tablet 8) Within this option, joystick will be "read only", reflecting the device inclination.

Please send me your email via PM

EDIT: now renamed as [u]Joystick bluetooth Commander V4.0[/u], available for free on Google Play

Hi, i send you one MP, and thanks for sharing your excellent work XD XD XD XD

Hi people, i need help :roll_eyes:, I'm trying to use this sketch to send rpm data from arduino to this application, but do not understand how data is sent :roll_eyes: :roll_eyes:, if I could explain how it works this is the part would greatly appreciate (explanation to children xD) XD XD XD XD XD XD

byte GetdataByte() { static byte i=0; i +=5; if(i >100) i = 0; return i;

I'm trying to use this sketch to send rpm data from arduino to this application, but do not understand how data is sent :roll_eyes: :roll_eyes:

Will you use Joystick bluetooth Commander/4 button version, or Joystick BT Plus/6 button version ?? (different communication protocols)

How do you obtain RPM data ?? via encoder(s) ?? Did you allready build the code for RPM data aquisition ??

How is the new layout I sent you for Joystick BT Plus ? Please post a screen shot

hi, i use basically this code for rpm http://playground.arduino.cc/Learning/Tachometer#.Uyr2Qfl5NAJ

my firs intent to send data is in 4 butons and 1 data, but now i trying in 6butons 4 data

I'm trying to use this sketch to send rpm data from arduino to this application, but do not understand how data is sent :roll_eyes: :roll_eyes:

Data has to be sent as a positive Byte (0 to 127) You need to scale RPM value in order to stay within this interval If your RPM range is 0 to 12000:

byte GetdataByte()  {
  double data = rpm / 100;
  data = constain(data, 0, 127);             
  return byte(data);
}

To overcome this 127 steps limited resolution, I will switch from byte to integer in next Joystick BT Plus version

XD XD thanks, now i understand, it was not as complicated as it seems, very grateful for the help

Can anyone give me a hand with some errors i have …
I am trying to run the TB6612FNG on the vertical and a Servo on Horizontal …so far the code only moves the motor only when you keep moving a little the joystick (i mean if u stay still with the finger on maximum speed i have no movement) :

#include <Servo.h> 

boolean    DEBUG = true;

#define    pinServo_X     9
#define    PWM_Y          3
#define    STX            0x02
#define    ETX            0x03

#define    MAX_Y          255      // PWM limit
#define    ZERO_Y         0         
#define    MIN_Y          -255       

#define AIN1  4   
#define AIN2  5   // AIN1 and AIN2 as Direction pins
#define STBY  7   // StandBy

int i=0;
byte cmd[6] = {0, 0, 0, 0, 0, 0};
Servo myservoX;                     
Servo myY;                 // ???? it is not a servo
byte buttonStatus = 0;              
byte dataByte = 0;                    
long previousMillis = 0;            
boolean setButtonFeedback = false;    
long interval = 1000;                 


void setup()  {
  Serial.begin(9600);
  myservoX.attach(pinServo_X);  
  myY.attach(PWM_Y);   

pinMode(AIN1,OUTPUT);
pinMode(AIN2,OUTPUT);
pinMode(PWM_Y,OUTPUT);
pinMode(STBY,OUTPUT);
  
}

void loop() {
  if(Serial.available())  {                   // data received from smartphone
    delay(5);
    cmd[0] =  Serial.read();  
    if(cmd[0] == STX)  {  
      i=1;      
      while(Serial.available())  {
        cmd[i] = Serial.read();
        if(cmd[i] == ETX)  {
          if(i==2 && cmd[1]>48)                break;    // Button data
          if(i==5 && cmd[1]<3 && cmd[3]<3)     break;    // Joystick data
        }
        if(i>5)   break;
        i++;
      }
        if(i==5)   setServoPosition(cmd);                                     // 5 Bytes
      else            Serial.println("Communication error");
    }
  }  else  {
    long currentMillis = millis();
    if(setButtonFeedback == true)  {                      // allow momentary button visual effect (500 ms)
      previousMillis = currentMillis - interval*0.5;   
      setButtonFeedback = false;
    }  
  }
  delay(5);
}

void setServoPosition(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
  
  joyX = map(joyX, -180, 180, 180, 0);      // (-180/+180 JBC range)
  joyY = map(joyY,  -100, +100, -255, 255);

  joyY+=ZERO_Y;
  joyY = constrain(joyY, MIN_Y, MAX_Y);
  myservoX.write(joyX);
  myY.write(joyY);
  digitalWrite(STBY, HIGH); //disable standby
  if(DEBUG)  {
  //Serial.print(joyX); Serial.print(", "); 
  Serial.println(joyY);}


  if(joyY > 0)	{
      digitalWrite (AIN1,HIGH);
      digitalWrite (AIN2,LOW);
  } else if(joyY < 0)  {
      digitalWrite (AIN1,LOW);
      digitalWrite (AIN2,HIGH);
  } else if(joyY = 0)  {
      digitalWrite(STBY, LOW); //enable standby

  analogWrite(PWM_Y,joyY);
 }
}

I know that i shouldn’t use servo library for the Vertical Axis (DC Motor) …but i don’t know how to do it ,i tried to change it with PWM but i got errors…also motor kepp making noise (without moving) when joystick is in the middle posicion
On Serial Monitor i get the right values : 255 when joystick full up ---- 0 in the middle ---- and -255 when is down
I apreciate your help,thank you,i hope to get this work :wink:

Yes, using servo library with DC Motor makes no sense :roll_eyes:

Standby is enabled and never driven high again

  } else if(joyY = 0)  {
      digitalWrite(STBY, LOW); //enable standby

Classical error ;)

} else if(joyY = 0)  {        // assignment operator, always TRUE !!

should really be

} else if(joyY == 0)  {         // comparison operator, the way to go

Sample code for DC motors here Take the easy way, build separate codes for DC motor and servo, make sure they both work, and finally combine them

@nemesis159 How is the new layout I sent you for Joystick BT Plus ? Please post a screen shot

You was right about this …i just change it

} else if(joyY == 0)  {         // comparison operator, the way to go

…as for the Stanby it is enabled again :

  myY.write(joyY);
  digitalWrite(STBY, HIGH); //disable standby   <----

Made some small modification and works (but not how it should) : it only have one speed fwd and backword (very very slow :(( ) in the middle get in Standby but it have no speed .On Serial monitor it goes from -255 0 255 …and i test the motor and it works,
What am i doing rong? I just don’t get it,I don’t wanna give up this project…shoud i open a new topic and ask for some advice ?
Thank you KAS

juycce,

There are other glitches in your code

 joyX = map(joyX, -180, 180, 180, 0);  
 joyY = map(joyY,  -100, +100, -255, 255);

Second and third parameters should match App Option > Adv properties > Data Range and should be identical for both joyX and joyY

Did you test the code example at reply #146 ?

For additional help, the Motors Mechanics and Power section seems adequate

Keep us informed :)

@tolisn63

I just tried out the new sketch. It is working great. All button now work as well as the data fields.
Also the camera has very little lag (<0.5sec) after I switched it to a lower res. (320x240) which is absolutely usable.

Thanks for the good new 8) 8) 8)

  1. Is it possible to change the orientation of the settings screen so it is the same as the main control screen ?
    2.Also it would be nice if the data receiving fields could also accept incoming text.

Will look into that matter :wink:

one question, when the buttons are pressed and the color becomes green, does the tablet do that or is it feedback from the arduino ?

This is the real button position

  • button first becomes green “locally” as an Android feature
  • position is then sent to Arduino
  • Arduino sends back the actual button position
    See replies #36 and #73

A good example is toggle (momentary) buttons
Button is set green by Android and reset white by Arduino after 250 milliseconds, to create a visual effect.

thanks for all your hard work.
Looking forward to trying your newest version.

:slight_smile:

@tolisn63

  1. Is it possible to change the orientation of the settings screen so it is the same as the main control screen ? 2.Also it would be nice if the data receiving fields could also accept incoming text.

Will look into that matter ;)

You got it ;) ;) ;) check your mail

Total RC Commander V1.1A - Data fields now accept integers, floats and text messages - Improved video management - adjustable Option screen orientation

Important: To allow text messages, Arduino to Android communication protocol has been modified Please use and adapt "AndroTest_PlusV12_string.ino" demo sketch

Let me have your feedback and a screenshot for your specific Android device

@all Joystick BT Plus (6 buttons, 3 datafields) and Total RC Commander (video from IP camera) will be available on Google Play within a month for a symbolic fee

In the meantime, please contact me via PM

Next version: remote control using built-in accelerometers (see reply #165) :P

Enjoy

EDIT: Joystick BT Plus is now Joystick bluetooth Commander V4.0 available on Google Play as a free upgrade See reply #181

I just posted a video showing tank control using Total RC Commander.

See it in action in the Exhibition Section

To obtain the App, please contact me via PM

Hi Kas Thanks for the reply Can I use hardware serial with this on my mega2560 (it has 4 hardware serial ports) and how ?

Hi tolisn63 Not too familiar with the Mega :|

  • remove #include "SoftwareSerial.h"
  • remove SoftwareSerial mySerial(2,3);
  • search/replace mySerial >> Serial1

pin#19 to TX bluetooth module pin#18 to RX bluetooth module

You should be all set ;) Let me know the outcome