Go Down

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

kas

Quote
❝Hi,
I really really like your work.  

I have three vehicles using your RC Commander and now want to convert some of them to the TOTAL RC Commander.
I will be happy to send you $9.00 (USD) for one copy of the TOTAL RC Commander (assuming that it could be used eventually on all three vehicles.
I have installed IP cameras to a PC and to an automobile.  I am a bit familiar with Android phones.  I am somewhat comfortable with the RC Commander and bluetooth.

My eMail (and PayPal) address is NCxxx@HotMail.com

Thanks.
Hi Bob,
check your mail   ;)


Juris3D

Hello! Even I am electronics hobbyist for decades, but only recently I did "catch RC virus" :) Well, probably partially because now I have a son 4 yrs old, so we can already share interests :)
So, I am collecting projects, Android applications, to see what would be good for me to experiment. This joystick looks good! After a quick look-around, I have a question. In apk options I am not finding PWM range settings (to limit max speed of motors when joystick is in some max position). I am yet to be looking into INO files of available projects (i am bad at programming from scratch, only can modify), but should max PWM be hard-coded at Arduino side (not very comfy)? OR am I missing something here :)   ?
Thanks in advance!
Thanks for this project in any case!

kas

#752
Aug 11, 2016, 11:34 am Last Edit: Aug 11, 2016, 05:18 pm by kas
Hello! Even I am electronics hobbyist for decades, but only recently I did "catch RC virus" :) Well, probably partially because now I have a son 4 yrs old, so we can already share interests :)
So, I am collecting projects, Android applications, to see what would be good for me to experiment. This joystick looks good! After a quick look-around, I have a question. In apk options I am not finding PWM range settings (to limit max speed of motors when joystick is in some max position). I am yet to be looking into INO files of available projects (i am bad at programming from scratch, only can modify), but should max PWM be hard-coded at Arduino side (not very comfy)? OR am I missing something here :)   ?
Thanks in advance!
Thanks for this project in any case!
Hi Juris3D,

Thanks for the kind words
You may be missing something  ;)  please google for PWM arduino

analogWrite() function send a modulated signal with a defined duty cycle
  analogWrite(pin, 0)       0% duty cycle     0 Volt output
  analogWrite(pin, 191)     75% duty cycle 
  analogWrite(pin, 255)   100% duty cycle   5 Volts output

So, no PWM settings in Joystick BT Commander
Within your Arduino sketch, you may adjust max motor speed by clamping analogWrite value using constrain() or scale it using map()

Driving servo motors is another story



Juris3D

Thank You for answer!
Well, one reason why I was asking about setting PWM limits from Android side, is because there are several projects that have that feature. I can quickly name two (maybe there are more): "Szabo RC Car" (not in Google store, found in Instructables) and "Arduino Joystick Controller" by Andi.Co.
It is nice feature to be able set maximum speed lower than value 255, maybe it can be implemented here too. I could even imagine presets like "gears" buttons, that can be configured each to particular maximum speed.

kas

#754
Aug 13, 2016, 07:20 am Last Edit: Aug 13, 2016, 07:32 am by kas
This feature was once built in, and deprecated with V4.0 release
I like the K.I.S.S approach and hate bloated software  ;)

Joystick BT Commander currently outputs a solid  [-100 +100] signal for each axis
These values reflect JOYSTICK position
Values customisation is definitly a user responsibility and should be implemented within Arduino sketch

It is dead easy to create "gear buttons" for LOW/HIGH max speed
Should you need sample code, just let me know



pedrobrio

#755
Aug 20, 2016, 10:19 am Last Edit: Aug 20, 2016, 02:23 pm by pedrobrio
Sorry I am trying to test your app  AndroTest V2.0 with Arduino UNO and Android Nexus 4 (joystick commander)

I am not receiving any STX in cmd[0] , ony 0 and 224.

Could you help  :(

I solved the issue just changing Serial1.begin(9600); I have a bluethooth HC-06

With that everything works like a charm :=)



kas

I solved the issue just changing Serial1.begin(9600); I have a bluethooth HC-06
With that everything works like a charm :=)
Hi pedrobrio

Glad it works  ;)

To avoid any potential communication errors, I strongly suggest to revert to Serial1.begin(57600)
and set your HC-06 BT card to 57600 bps
Should you need any help, let us know




Juris3D

Hello to developer and all hobbyists here. I bought tank chassis and also I am getting that "Total RC" APK with camera support. I would be very thankful for some basic INO file that goes with current APK version, for driving 2-motor vehicle (tank). As for hardware, I have Arduinos (nano, uno, pro micro), bluetooth module HC-05, and several kinds of typical motor drivers (L298, L293).
Oh, and especially awesome would be, if there are some framework for "gears" buttons, discussed a little before. By that I mean couple buttons that can set maximum speed of wehicle.
Big Thanks in advance!

kas

#758
Sep 03, 2016, 10:30 am Last Edit: Sep 03, 2016, 10:54 am by kas
Hi Juris,

First make sure you read the Android controlled RC tank with on-board Video thread


See it in action: >> video <<

and fullspool experience



Let's check that your hardware is up and running
This basic code will move your tank forward/backward, without RC control:
Code: [Select]
// ***********************************************************************
// *   TankControl   V0.1                                    @kas 2016   *
// *   Code for driving a generic tank with two motors and L298 driver   *
// ***********************************************************************

// Rev history
// V0.1  Basic moves, no RC control


#define   DIR_L     5        // direction control for left motor
#define   PWM_L     6        // PWM control for left motor
#define   DIR_R     8        // direction control for right motor
#define   PWM_R     9        // PWM control for right motor

void setup()  {
  pinMode(PWM_L, OUTPUT);
  pinMode(PWM_R, OUTPUT);
  pinMode(DIR_L, OUTPUT);
  pinMode(DIR_R, OUTPUT);
}

void loop() {
  forward(100);             // forward low speed
  delay(1000);   
  forward(255);             // forward full speed
  delay(1000);   
  stopped();                // stop
  delay(1000);
  backward(100);            // backward low speed
  delay(1000);   
  backward(255);            // backward full speed
  delay(1000);   
  stopped();                // stop
  delay(2000);   
}

void forward(int pwmValue)    {
  digitalWrite(DIR_L, HIGH);
  digitalWrite(DIR_R, HIGH);
  analogWrite(PWM_L, pwmValue);
  analogWrite(PWM_R, pwmValue);
}

void backward(int pwmValue)   {
  digitalWrite(DIR_L, LOW);
  digitalWrite(DIR_R, LOW);
  analogWrite(PWM_L, pwmValue);
  analogWrite(PWM_R, pwmValue);
}

void stopped()   {
  analogWrite(PWM_L, 0);
  analogWrite(PWM_R, 0);
}

For next sketches, the roadmap is
- basic RC control
- differential drive
- normal/turbo speed ("gear" buttons)
- battery voltage display
- battery current monitoring
- who knows...   ;)

EDIT: depending on your motors setup, you may have to invert DIR_R pin level in forward() and backward() functions.


Juris3D

#759
Sep 05, 2016, 02:52 pm Last Edit: Sep 05, 2016, 02:58 pm by Juris3D
Thank You for help! I will tell my progress here, it may be not very fast from my side - have several things going on, commonly called "Real Life (TM)"...  ;-D
But I am not totally blank, already made some "proof of concept", got tank chassis working from very simple Android apk "Robo RC" (just two speed sliders there, nothing else), so I know that all parts are working together.

Juris3D

#760
Sep 06, 2016, 08:54 am Last Edit: Sep 06, 2016, 09:01 am by Juris3D
I checked this initial tank control sketch, and it didn't really work well. Back and Forward speeds were different, one of directions were acting wrong. I investigated Arduino code from project "Robo RC", and realized we are driving L298 wrong here. Thing is, one of two inputs has to be set LOW and other one feeded with PWM, but - for oposite direction roles are changed: now -second- input has to be set LOW, and now PWM we feed to first input. I modified sketch. Changed pin names that are consistent with markings on typical L298 modules (IN1, IN2, IN3, IN4, with added "L" and "R" to easier "reading").
Changed "stopping" too. Now it works fine.
Arduino code (still without remote control, tank movies slow forward, stop, faster forward, stop, slow backward, stop, faster backward, stop. Repeat):

Code: [Select]
// ***********************************************************************
// *   TankControl   V0.2                                    @kas 2016   *
// *   Code for driving a generic tank with two motors and L298 driver   *
// ***********************************************************************

// Rev history
// V0.2  Basic moves, no RC control

//#define   DIR_L     5        // direction control for left motor
//#define   PWM_L     6        // PWM control for left motor
//#define   DIR_R     8        // direction control for right motor
//#define   PWM_R     9        // PWM control for right motor

#define   IN1_L     3        // direction control for left motor
#define   IN2_L     5        // PWM control for left motor
#define   IN3_R     6        // direction control for right motor
#define   IN4_R     9        // PWM control for right motor

void setup()  {
  pinMode(IN1_L, OUTPUT);
  pinMode(IN2_L, OUTPUT);
  pinMode(IN3_R, OUTPUT);
  pinMode(IN4_R, OUTPUT);
}

void loop() {
  delay(4000);
  forward(88);             // forward low speed
  delay(2000);   
    stopped();                // stop
  delay(2000);
  forward(177);             // forward higher speed (full - 255)
  delay(2000);   
  stopped();                // stop
  delay(2000);
  backward(88);            // backward low speed
  delay(2000);   
    stopped();                // stop
  delay(2000);
  backward(177);            // backward higher speed (full - 255)
  delay(2000);   
    stopped();                // stop
  delay(4000);   
}

void forward(int pwmValue)    {
  digitalWrite(IN1_L, LOW);
  digitalWrite(IN3_R, LOW);
  analogWrite(IN2_L, pwmValue);
  analogWrite(IN4_R, pwmValue);
}

void backward(int pwmValue)   {
  digitalWrite(IN2_L, LOW);
  digitalWrite(IN4_R, LOW);
  analogWrite(IN1_L, pwmValue);
  analogWrite(IN3_R, pwmValue);
}

void stopped()   {
  digitalWrite(IN1_L, LOW);
  digitalWrite(IN3_R, LOW);
  digitalWrite(IN2_L, LOW);
  digitalWrite(IN4_R, LOW);
}


P.S.: I changed pin definitions just because to be the same as from "Robo RC" project.

kas

Sorry, I should have googled for this specific driver

The Robo RC setup may work...  ::)  (and it apparently does  ;) )

PWM signals should normally be fed to ENA (motorA) and ENB (motorB)
Please look here

The Robo RC only use 2 pins per motor, while the "normal" setup uses 3 pins

I will prepare the RC version code based on your modified sketch



kas

#762
Sep 06, 2016, 08:40 pm Last Edit: Sep 06, 2016, 08:42 pm by kas
Here it is:
Code: [Select]

// ***********************************************************************
// *   TankControl   V0.3                                    @kas 2016   *
// *   Code for driving a generic tank with two motors and L298 driver   *
// ***********************************************************************

// Rev history
// V0.3  Basic moves (FW/BW only), with RC control, no buttons, no feedback
// V0.2  Basic moves, no RC control

// Arduino pin#0 to TX BlueTooth module
// Arduino pin#1 to RX BlueTooth module
// -->> remove pin#0 connection before downloading the sketch <<--
// make sure your BT board is set @57600 bps

#define   IN1_L     3        // direction control for left motor
#define   IN2_L     5        // PWM control for left motor
#define   IN3_R     6        // direction control for right motor
#define   IN4_R     9        // PWM control for right motor

#define    STX          0x02
#define    ETX          0x03

byte cmd[8] = {0, 0, 0, 0, 0, 0, 0, 0};                 // bytes received

void setup()  {
  pinMode(IN1_L, OUTPUT);
  pinMode(IN2_L, OUTPUT);
  pinMode(IN3_R, OUTPUT);
  pinMode(IN4_R, OUTPUT);
  Serial.begin(57600);         //  XXXXXXX   change to actual BT card baud rate   XXXXXXXXXXXXXXX
  while(Serial.available())  Serial.read();           // empty RX buffer
}

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)          getJoystickState(cmd);     // 6 Bytes  ex: < STX "200" "180" ETX >
    }
  }
}

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

  map(joyY,-100,100,-255,255);
 
  if(joyY>10)           forward(joyY);
  else if(joyY<-10)     backward(-joyY);
  else                  stopped();
}
 
void forward(int pwmValue)    {
  digitalWrite(IN1_L, LOW);
  digitalWrite(IN3_R, LOW);
  analogWrite(IN2_L, pwmValue);
  analogWrite(IN4_R, pwmValue);
}

void backward(int pwmValue)   {
  digitalWrite(IN2_L, LOW);
  digitalWrite(IN4_R, LOW);
  analogWrite(IN1_L, pwmValue);
  analogWrite(IN3_R, pwmValue);
}

void stopped()   {
  digitalWrite(IN1_L, LOW);
  digitalWrite(IN3_R, LOW);
  digitalWrite(IN2_L, LOW);
  digitalWrite(IN4_R, LOW);
}

Forward/Backward only, no buttons, no feedback
Purpose is to check BT communication
Set Serial.begin() to actual BT card baud rate

Quote
For next sketches, the roadmap is
- basic RC control
- differential drive
- normal/turbo speed ("gear" buttons)
- battery voltage display
- battery current monitoring
- who knows...   ;)
more:
 - Dead Man feature (Bluetooth out of range)
 - lights ON/OFF


Disclaimer:
I currently have no way to check this code, it  _should_  work...
at least it compiles  ;)



Juris3D

// V0.3  Basic moves (FW/BW only), with RC control, no buttons, no feedback
I currently have no way to check this code, it  _should_  work...
at least it compiles  ;)

I confirm, that this test sketch V0.3 is working. Forward and backward is working from "Total RC Commander" joystick, with proportional speed.

PWM signals should normally be fed to ENA (motorA) and ENB (motorB)
The Robo RC only use 2 pins per motor, while the "normal" setup uses 3 pins

Yes, I am aware, that "proper" implementation would be IN1/IN2 - HIGH/LOW - LOW/HIGH, and PWM feed to "EN". But since this simplified 2-pin solution works, there is a reason (besides Arduino ports economy) to keep it for tests: there are other "fancy" motor drivers around that has only 2 pins for input. Probably this simplified solution will fit for them too, and - I will be able to check it actually! Just today I got "assortment" of motor drivers modules from China, I think 3 different kinds. Will post here as soon as I try them.

For next sketches, the roadmap is ....
I could suggest some future feature: "shift", or "mode" switch, and it would change commander apk joystick control from tank driving, to camera pan/tilt (and back, obviously). I am "borrowing" that idea from apk "Arduino Joystick Controller"
https://play.google.com/store/apps/details?id=com.andico.control.joystick&hl=en

kas

Quote
I confirm, that this test sketch V0.3 is working. Forward and backward is working from "Total RC Commander" joystick, with proportional speed
Perfect
Next step: differential stirring for left and right turns (V0.4)

Code: [Select]

// ***********************************************************************
// *   TankControl   V0.4                                    @kas 2016   *
// *   Code for driving a generic tank with two motors and L298 driver   *
// ***********************************************************************

// Rev history
// V0.4  Differential drive (FW/BW/left/right)
// V0.3  Basic moves (FW/BW only), with RC control, no buttons, no feedback
// V0.2  Basic moves, no RC control

#define   IN1_L     3        // direction control for left motor
#define   IN2_L     5        // PWM control for left motor
#define   IN3_R     6        // direction control for right motor
#define   IN4_R     9        // PWM control for right motor

#define    STX          0x02
#define    ETX          0x03

byte cmd[8] = {0, 0, 0, 0, 0, 0, 0, 0};                 // bytes received

void setup()  {
  pinMode(IN1_L, OUTPUT);
  pinMode(IN2_L, OUTPUT);
  pinMode(IN3_R, OUTPUT);
  pinMode(IN4_R, OUTPUT);
  Serial.begin(57600);         //  XXXXXXX   change to actual BT card baud rate   XXXXXXXXXXXXXXX
  while(Serial.available())  Serial.read();           // empty RX buffer
}

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)          getJoystickState(cmd);     // 6 Bytes  ex: < STX "200" "180" ETX >
    }
  }
}

void getJoystickState(byte data[8])    {
  int pwm_L, pwm_R;
  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

  if(joyY >-10)  {                                                    // differential steering
    pwm_L = (joyY - (3*joyX)/4);
    pwm_R = (joyY + (3*joyX)/4);
  }  else  {
    pwm_L = (joyY + (3*joyX)/4);
    pwm_R = (joyY - (3*joyX)/4);
  }
  pwm_L = map(pwm_L, -100, 100, -255, 255);
  pwm_R = map(pwm_R, -100, 100, -255, 255);
  pwm_L = constrain(pwm_L, -255, 255);
  pwm_R = constrain(pwm_R, -255, 255);

  motorControl_Left(pwm_L);
  motorControl_Right(pwm_R);
}
 
void motorControl_Left(int pwmValue)  {
  if(pwmValue >=0) {                                                // forward
    digitalWrite(IN1_L, LOW);
    analogWrite (IN2_L, pwmValue);
  }  else  {                                                        // backward
    digitalWrite(IN1_L, -pwmValue);
    analogWrite (IN2_L, LOW);
  }
}

void motorControl_Right(int pwmValue)  {
  if(pwmValue >=0) {                                                // forward
    digitalWrite(IN3_R, LOW);
    analogWrite(IN4_R, pwmValue);
  }  else  {                                                        // backward
    digitalWrite(IN3_R, -pwmValue);
    analogWrite(IN4_R, LOW);
  }
}

void stopped()   {
  digitalWrite(IN1_L, LOW);
  digitalWrite(IN3_R, LOW);
  digitalWrite(IN2_L, LOW);
  digitalWrite(IN4_R, LOW);
}




Quote
I could suggest some future feature: "shift", or "mode" switch, and it would change commander apk joystick control from tank driving, to camera pan/tilt
You got it   :smiley-evil:
Quote
For next sketches, the roadmap is
- basic RC control
- differential drive
- normal/turbo speed ("gear" buttons)
- battery voltage display
- battery current monitoring (stalled motors detection)
- Dead Man feature (Bluetooth out of range)
- lights ON/OFF
- who knows...   ;)
more:
 - mode switch for camera pan/tilt



For improved reliability, please set your BT card @57600 bps



Go Up