Go Down

Topic: Android Bluetooth joystick (Read 382331 times) previous topic - next topic

kri5too

#540
Jan 19, 2016, 07:33 pm Last Edit: Jan 19, 2016, 07:43 pm by kri5too
Code: [Select]
#define VERSION     "\n\nAndroTest V2.0 - @kas2014\ndemo for V5.x App"

// V2.0  changed to pure ASCII Communication Protocol ** not backward compatible **
// 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 pin #13 LED
// Button #4 toggle datafield display rate
// Button #5 configured as "push" button (momentary)
// Other buttons display demo message

// 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


#define    STX          0x02
#define    ETX          0x03
#define    ledPin       13
#define    SLOW         750                            // Datafields refresh rate (ms)
#define    FAST         250                             // Datafields refresh rate (ms)
                      // BlueTooth module: pin#2=TX pin#3=RX
byte cmd[8] = {0, 0, 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
long sendInterval = SLOW;                               // interval between Buttons status transmission (milliseconds)
String displayStatus = "xxxx";                          // message to Android device

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

void loop() {
if(Serial1.available())  {                           // data received from smartphone
  delay(2);
  cmd[0] =  Serial1.read();  
  if(cmd[0] == STX)  {
    int i=1;      
    while(Serial1.available())  {
      delay(1);
      cmd[i] = Serial1.read();
      if(cmd[i]>127 || i>7)                 break;     // Communication error
      if((cmd[i]==ETX) && (i==2 || i==7))   break;     // Button or Joystick data
      i++;
    }
    if     (i==2)          getButtonState(cmd[1]);    // 3 Bytes  ex: < STX "C" ETX >
    else if(i==7)          getJoystickState(cmd);     // 6 Bytes  ex: < STX "200" "180" ETX >
  }
}
sendBlueToothData();
}

void sendBlueToothData()  {
static long previousMillis = 0;                            
long currentMillis = millis();
if(currentMillis - previousMillis > sendInterval) {   // send data back 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

  Serial1.print((char)STX);                                             // Start of Transmission
  Serial1.print(getButtonStatusString());  Serial1.print((char)0x1);   // buttons status feedback
  Serial1.print(GetdataInt1());            Serial1.print((char)0x4);   // datafield #1
  Serial1.print(GetdataFloat2());          Serial1.print((char)0x5);   // datafield #2
  Serial1.print(displayStatus);                                         // datafield #3
  Serial1.print((char)ETX);                                             // 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 GetdataInt1()  {              // Data dummy values sent to Android device for demo purpose
static int i= -30;              // Replace with your own code
i ++;
if(i >0)    i = -30;
return i;  
}

float GetdataFloat2()  {           // 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[8])    {
int joyX = (data[1]-48)*100 + (data[2]-48)*10 + (data[3]-48);       // obtain the Int from the ASCII representation
int joyY = (data[4]-48)*100 + (data[5]-48)*10 + (data[6]-48);
joyX = joyX - 200;                                                  // Offset to avoid
joyY = joyY - 200;                                                  // transmitting negative numbers

if(joyX<-100 || joyX>100 || joyY<-100 || joyY>100)     return;      // commmunication error

// Your code here ...
  Serial.print("Joystick position:  ");
  Serial.print(joyX);  
  Serial.print(", ");  
  Serial.println(joyY);
}

void getButtonState(int bStatus)  {
switch (bStatus) {
// -----------------  BUTTON #1  -----------------------
  case 'A':
    buttonStatus |= B000001;        // ON
    Serial.println("\n** Button_1: ON **");
    // your code...      
    displayStatus = "LED <ON>";
    Serial.println(displayStatus);
    digitalWrite(ledPin, HIGH);
    break;
  case 'B':
    buttonStatus &= B111110;        // OFF
    Serial.println("\n** Button_1: OFF **");
    // your code...      
    displayStatus = "LED <OFF>";
    Serial.println(displayStatus);
    digitalWrite(ledPin, LOW);
    break;

// -----------------  BUTTON #2  -----------------------
  case 'C':
    buttonStatus |= B000010;        // ON
    Serial.println("\n** Button_2: ON **");
    // your code...      
    displayStatus = "Button2 <ON>";
    Serial.println(displayStatus);
    break;
  case 'D':
    buttonStatus &= B111101;        // OFF
    Serial.println("\n** Button_2: OFF **");
    // your code...      
    displayStatus = "Button2 <OFF>";
    Serial.println(displayStatus);
    break;

// -----------------  BUTTON #3  -----------------------
  case 'E':
    buttonStatus |= B000100;        // ON
    Serial.println("\n** Button_3: ON **");
    // your code...      
    displayStatus = "Motor #1 enabled"; // Demo text message
    Serial.println(displayStatus);
    break;
  case 'F':
    buttonStatus &= B111011;      // OFF
    Serial.println("\n** Button_3: OFF **");
    // your code...      
    displayStatus = "Motor #1 stopped";
    Serial.println(displayStatus);
    break;

// -----------------  BUTTON #4  -----------------------
  case 'G':
    buttonStatus |= B001000;       // ON
    Serial.println("\n** Button_4: ON **");
    // your code...      
    displayStatus = "Datafield update <FAST>";
    Serial.println(displayStatus);
    sendInterval = FAST;
    break;
  case 'H':
    buttonStatus &= B110111;    // OFF
    Serial.println("\n** Button_4: OFF **");
    // your code...      
    displayStatus = "Datafield update <SLOW>";
    Serial.println(displayStatus);
    sendInterval = SLOW;
   break;

// -----------------  BUTTON #5  -----------------------
  case 'I':           // configured as momentary button
//      buttonStatus |= B010000;        // ON
    Serial.println("\n** Button_5: ++ pushed ++ **");
    // your code...      
    displayStatus = "Button5: <pushed>";
    break;
//   case 'J':
//     buttonStatus &= B101111;        // OFF
//     // your code...      
//     break;

// -----------------  BUTTON #6  -----------------------
  case 'K':
    buttonStatus |= B100000;        // ON
    Serial.println("\n** Button_6: ON **");
    // your code...      
     displayStatus = "Button6 <ON>"; // Demo text message
   break;
  case 'L':
    buttonStatus &= B011111;        // OFF
    Serial.println("\n** Button_6: OFF **");
    // your code...      
    displayStatus = "Button6 <OFF>";
    break;
}
// ---------------------------------------------------------------
}


kas

Quote
Quote
I did exactly the same but i wont get readings in serial monitor :(
Can you display
  AndroTest V2.0 - @kas2014
  demo for V5.x App

on the Serial Monitor ??



kri5too

Can you display
  AndroTest V2.0 - @kas2014
  demo for V5.x App

on the Serial Monitor ??



Yes, if i upload scketch and start serial monitor, then this text will show up.

kas

#543
Jan 20, 2016, 08:53 am Last Edit: Jan 20, 2016, 08:56 am by kas
Quote
Yes, if i upload scketch and start serial monitor, then this text will show up
OK


Carefully review those 6 questions and answer YES/NO
(If you don't understand a specific item, just tell it)

Android side (smartphone/tablet):
1) go to Option/About and confirm that JBTC App version is V5.2
2) can you move the joystick and display position at bottom left
3) is your BT card already paired with your Android device
4) are you connected ("connected to: XXX", green text at bottom)

Arduino side:
5) is your Bluetooth card already configured @57600 bps  (most are 9600bps by default)
6) is your Bluetooth card LED solid red or green  (blinking = not connected)




kri5too

OK


Carefully review those 6 questions and answer YES/NO
(If you don't understand a specific item, just tell it)

Android side (smartphone/tablet):
1) go to Option/About and confirm that JBTC App version is V5.2
2) can you move the joystick and display position at bottom left
3) is your BT card already paired with your Android device
4) are you connected ("connected to: XXX", green text at bottom)

Arduino side:
5) is your Bluetooth card already configured @57600 bps  (most are 9600bps by default)
6) is your Bluetooth card LED solid red or green  (blinking = not connected)

1.Yes
2.No
3.Yes
4.Yes
5.How to do this ?I think that is solution.
6.If i go home i will chek it.

kas

#545
Jan 20, 2016, 12:03 pm Last Edit: Jan 20, 2016, 12:21 pm by kas
Quote
2) can you move the joystick and display position at bottom left
2.No
::)  ::)  ::)
Data is just above "Connected to..."
(0,0) should change value according to joystick position
Should work even if not connected
Please confirm


Quote
5) is your Bluetooth card already configured @57600 bps  (most are 9600bps by default)
5.How to do this ?I think that is solution.
Is your BT board HC-05 or HC-06 ??
Let me have a link to your specific BT board

In your code, please change
Serial1.begin(57600);                                // 57600 = max value for softserial
to
Serial1.begin(9600);

and let me know the outcome


kri5too

#546
Jan 20, 2016, 08:58 pm Last Edit: Jan 20, 2016, 09:05 pm by kri5too
I changed the Serial1.begin(57600)to 9600 and the joystick values became to serial monitor.
Everything was all right.
But when i writed my code, after that the joystick wont work :(
If i look to serial monitor i dont get joystick values from joystick posison in left. If joystick is right then i get the readings.
What i did wrong ?
Here is my code.. I just wanna run 2 dc motors according joystick position.

Quote
#define VERSION     "\n\nAndroTest V2.0 - @kas2014\ndemo for V5.x App"

// V2.0  changed to pure ASCII Communication Protocol ** not backward compatible **
// 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 pin #13 LED
// Button #4 toggle datafield display rate
// Button #5 configured as "push" button (momentary)
// Other buttons display demo message

// 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 <AFMotor.h>
AF_DCMotor motorV(3,MOTOR12_64KHZ); //vasak moto
AF_DCMotor motorP(4,MOTOR12_64KHZ); //parem moto
int motorSpeed;
int center;
#define    STX          0x02
#define    ETX          0x03
#define    ledPin       13
#define    SLOW         750                            // Datafields refresh rate (ms)
#define    FAST         250                             // Datafields refresh rate (ms)


everything between this is the same code you wrote.

void getJoystickState(byte data[8])    {
 int joyX = (data[1]-48)*100 + (data[2]-48)*10 + (data[3]-48);       // obtain the Int from the ASCII representation
 int joyY = (data[4]-48)*100 + (data[5]-48)*10 + (data[6]-48);
 center=joyX = joyX - 200;                                                  // Offset to avoid
 joyY = joyY - 200;                                                  // transmitting negative numbers

 if(joyX<-100 || joyX>100 || joyY<-100 || joyY>100)     return;      // commmunication error
// Your code here ...
if (joyX>10){
motorSpeed = map(joyX, 0,100,0,255);
motorP.setSpeed(motorSpeed);
motorV.setSpeed(motorSpeed);
motorP.run(FORWARD);
motorV.run(FORWARD);

   Serial.print("Joystick position:  ");
   Serial.print(joyX);  
   Serial.print(", ");  
   Serial.println(joyY);
}}

and continues with your code.

kas

#547
Jan 21, 2016, 09:00 pm Last Edit: Jan 23, 2016, 08:14 am by kas
Quote
If i look to serial monitor i dont get joystick values from joystick posison in left. If joystick is right then i get the readings.
What i did wrong ?
Easy  ;)

change

if (joyX>10){
motorSpeed = map(joyX, 0,100,0,255);
motorP.setSpeed(motorSpeed);
motorV.setSpeed(motorSpeed);
motorP.run(FORWARD);
motorV.run(FORWARD);

   Serial.print("Joystick position:  ");       <--<<  Joystick position only printed if joyX >10 !!
   Serial.print(joyX);  
   Serial.print(", ");  
   Serial.println(joyY);
}}  
                                          

to


if (joyX>10){
motorSpeed = map(joyX, 0,100,0,255);
motorP.setSpeed(motorSpeed);
motorV.setSpeed(motorSpeed);
motorP.run(FORWARD);
motorV.run(FORWARD);
}

   Serial.print("Joystick position:  ");
   Serial.print(joyX);  
   Serial.print(", ");  
   Serial.println(joyY);
}





For better performances, you really need to set your BT board at 57600 bps
Is your board HC-05 or HC-06 ??
Let me have a link to your specific board



fullspool

KAS, awesome app it looks good on my Samsung S5 ! I am not a programmer  so please excuse the noobie questions. I did download your example sketch and got my Adruino uno to work with B1 lighting up my LED on pin 13 using a SH_BT_Board V1.3 HC-05 from ebay.  I am confused when ready this thread
if I need to have the servo libray or use the PID_v1.h ? Where do you find PID_v1.h as it isn't in the standard library .


My Scenario is :

I have a rover that has 2 dc motors connected to an esc
I want to control my rover with my android phone however can not find a suitable sketch or know how to modify an existing sketch to remove the Hbridge that others commonly use on the RC Car builds.

I have hc05 tx going to the rx on the uno and hc05 rx going to the tx on the uno . I notice in some of your example sketches you have the TX (hc-05) going to pin 2 and RX (hc-05) going to pin 3 ? Why not TX/RX pins on the UNO?

I would really like to see real time voltage and Mah but if I could get my rover working I would be really happy :)



kas

Quote
I have hc05 tx going to the rx on the uno and hc05 rx going to the tx on the uno . I notice in some of your example sketches you have the TX (hc-05) going to pin 2 and RX (hc-05) going to pin 3 ? Why not TX/RX pins on the UNO?
In order to display debug info in the Serial Monitor, we need a second Serial connection
 - hardware serial (DO/D1) to PC (debug)
 - software serial (D2/D3) to BT board

You can connect BT card to DO/D1, if debug info's are not required


Quote
I want to control my rover with my android phone however can not find a suitable sketch or know how to modify an existing sketch to remove the Hbridge that others commonly use on the RC Car builds.
Let's first check if the Android/BT card transmission is OK
Please download AndroTest V2.0 demo sketch (with SoftSerial)
and confirm you can display Joystick position and buttons press on your Serial Monitor
Your PC screen should look pretty much like that:



Let us know





fullspool

I have good connection to APP , I used your demo sketch :)

fullspool

KAS,

Now that I have good connection to Joy Stick Commander App, what do you suggest my next step would be? Try and modify someone elses code and remove the Hbridge ? I know where I want to go but don't know how to get there. Thanks for all the help thus far.

kas

#552
Feb 03, 2016, 08:00 pm Last Edit: Feb 04, 2016, 06:04 pm by kas
Most ESC's are driven using a PWM servo signal

This code is the bare minimum for servo's control
As there is no feed back from Arduino to smartphone, DO1 (Arduino TX) is not used,
so you still can display debug info's on the serial monitor

Code: [Select]
#define VERSION     "\n\nAndro_Pan&Tilt V3.6 - @kas2014\n** servo's demo for V5.x App **"

// Controls two servo motors

// V3.6: Android BT Commander V5.X compatible, no button data management
// 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        >>>  -100 to +100
// Options/Options for advanced users/Refresh interval  >>>  50ms

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

#include <Servo.h>

boolean    DEBUG =         true;

#define    pinServo_X     9             // <<  ServoX pin
#define    pinServo_Y     10           // <<  ServoY pin
#define    STX            0x02
#define    ETX            0x03
#define    MIN_Y          0  //45             // vertical move limitation,
#define    MAX_Y          180                 // adjust to needs
#define    ZERO_Y         -1  //60             // vertical zero offset

byte cmd[8] = {0, 0, 0, 0, 0, 0, 0, 0};
Servo myservoX;                         // create servo objects
Servo myservoY;

void setup()  {
  Serial.begin(57600);
  myservoX.attach(pinServo_X); 
  myservoY.attach(pinServo_Y); 
  if(DEBUG)    Serial.println(VERSION);
}

void loop() {
   if(Serial.available())  {                            // data received from smartphone
    delay(2);
    cmd[0] =  Serial.read(); 
    if(cmd[0] == STX)  {
      int i=1;     
      while(Serial.available())  {
        delay(1);
        cmd[i] = Serial.read();
        if(cmd[i]>127 || i>7)                 break;     // Communication error
        if((cmd[i]==ETX) && (i==2 || i==7))   break;     // Button or Joystick data
        i++;
      }
      if(i==7)     setServoPosition(cmd);
    }
  }
}

void setServoPosition(byte data[8])    {
  int joyX = (data[1]-48)*100 + (data[2]-48)*10 + (data[3]-48);       // obtain the Int from the ASCII representation
  int joyY = (data[4]-48)*100 + (data[5]-48)*10 + (data[6]-48);
  joyX = joyX - 200;                                                  // Offset to avoid
  joyY = joyY - 200;                                                  // transmitting negative numbers

  if(joyX<-100 || joyX>100 || joyY<-100 || joyY>100)     return;      // communication error
 
  joyX = map(joyX, -100, 100, 180, 0);   //  << adjust to change motor direction
  joyY = map(joyY, -100, 100, 0, 180);   //  <<

  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);}
}



Don't forget to disconnect BT TX from D0 during sketch upload

** EDIT: code was fixed as per below



fullspool

I tried to upload the sketch but it has errors?


sketch_feb03a.ino: In function 'void setup()':
sketch_feb03a.ino:21:45: error: 'ServoX' was not declared in this scope
sketch_feb03a.ino:35:19: note: in expansion of macro 'pinServo_X'
sketch_feb03a.ino:22:44: error: 'ServoY' was not declared in this scope
sketch_feb03a.ino:36:19: note: in expansion of macro 'pinServo_Y'
Error compiling.

kas

#554
Feb 04, 2016, 06:52 am Last Edit: Feb 04, 2016, 06:52 am by kas
Opps ...  sorry  :-*  :-*
ServoX pin and ServoX pin are just added comments


Please replace

#define    pinServo_X     9             <<  ServoX pin
#define    pinServo_Y     10           <<  ServoY pin

by

#define    pinServo_X     9            // <<  ServoX pin
#define    pinServo_Y     10           // <<  ServoY pin




Go Up