Go Down

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

woodygb

#405
Dec 16, 2014, 01:05 am Last Edit: Dec 16, 2014, 01:42 am by woodygb
Take note of the coil pin numbers that I have used..check that they will match your setup.
Retain your pin 13 LED as it is in this code to indicate motor movement ... ON when the steppers are instructed to move and turns OFF when they are idle for 3 secs.

I'd suggest these settings for the Android phone
Go into in Options ...Joystick properties

The joystick behavior box should NOT be ticked.
& Joystick constraint should be BOX.


2nd lump of code....

Code: [Select]
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;
  }
}










AntonioLopez

Thanks Woody, that was fast.

I've tried the code and for some reason the motor turns only one direction and after a while the motor turns off. 

I guess this is the code that is turning it off - #define  TIMEOUT     3000    //Turns off after 3 secs of inactivity.  I know that is in the code I sent you, but for some reason it's not turning back on when I move the pod.

I only hooked up one motor, I think thats why it's interpreted as inactivity.  Maybe?  I'll hook up the other motor to see what happens.

Thanks...........Antonio

AntonioLopez

I've hooked up the second motor and change the pin numbers to match what I have as you said, both motors work, but they both turn in one direction regardless of what I'm doing on the BT commander. And then they turn off.

Thanks...........Antonio

kas

#408
Dec 16, 2014, 07:51 am Last Edit: Dec 16, 2014, 07:57 am by kas
Quote
I just tried your code and the Commander is sending data to the arduino, GREAT, THANKS
So what ??



Why couldn't you see data in the Arduino serial monitor ??
Please explain, as it may be useful for the Community

The onboard TX led does reflect Serial activity (not mySerial), and will flash when data is sent to the Serial Monitor


woodygb

#409
Dec 16, 2014, 09:08 am Last Edit: Dec 16, 2014, 10:19 am by woodygb
Thanks Woody, that was fast.

I've tried the code and for some reason the motor turns only one direction and after a while the motor turns off. 

I guess this is the code that is turning it off - #define  TIMEOUT     3000    //Turns off after 3 secs of inactivity.  I know that is in the code I sent you, but for some reason it's not turning back on when I move the pod.

I only hooked up one motor, I think thats why it's interpreted as inactivity.  Maybe?  I'll hook up the other motor to see what happens.

Thanks...........Antonio
I ASSumed that you could also see activity on the PC monitor via the Serial port ...  it would seem that you cannot... therefore I believe that your original problem still exists.

The stepper code will ...I think .... without any input from the Android joystick ..cause the motors to simply settle @ a end position defined by PotVal 0 and Pos 1024.

So ... it's back to trying to figure out the underlying cause... and get some numbers scrolling on the screen.




woodygb

#410
Dec 16, 2014, 10:29 am Last Edit: Dec 16, 2014, 10:48 am by woodygb
I've modified the first lump of stepper code ...nothing that will fix the problem.... I've simply moved the serial print block up the code and added in a set start position for the stepper.

NOTE:- I never used or programmed steppers.

This should give you something to see on the screen.... but I suspect that it will be static.

However ...try it ...press the buttons on the phone and wiggle the stick..see if ANYTHING changes on the serial monitor screen.

Code: [Select]

  
#define VERSION     "\n\nAndroTest V2.0 - @kas2014\ndemo for V5.x App"
#include "SoftwareSerial.h"
#include <Stepper.h>

#define rxPin 2
#define txPin 3

// change this to the number of steps on your motor
#define  STEPSREV    2047    // 64(fullsteps) * 64 (reduction ratio)= 4096

#define  COIL1_A    11
#define  COIL2_A     9
#define  COIL3_A    10
#define  COIL4_A     8

#define  COIL1_B    4 // ???  PIN NUMBERS GUESSED
#define  COIL2_B    5
#define  COIL3_B    6
#define  COIL4_B    7

#define  ENER_A       13       //Motor A Status led
//#define  ENER_B       ?     //Motor B Status led do you wish a seperate one?

#define  TIMEOUT     3000    //Turns off after 3 secs of inactivity.

// create an instance of the stepper class, specifying
// the number of steps per revolution and pins atached to motor coils.
Stepper myStepperA(STEPSREV, COIL1_A, COIL2_A, COIL3_A, COIL4_A);
Stepper myStepperB(STEPSREV, COIL1_B, COIL2_B, COIL3_B, COIL4_B);
int PotValA;
int PotValB;
int pos_A = 1024;              // stepper A position(0-4096)->(0-360°) CENTERED
int pos_B = 1024;              // stepper B position (0-4096)->(0-360°)CENTERED
unsigned long stamp_A = 0;  // last A move time stamped.
unsigned long stamp_B = 0;  // last B move time stamped.
#define    STX          0x02
#define    ETX          0x03
//#define    ledPin       13
#define    SLOW         750                            // Datafields refresh rate (ms)
#define    FAST         250                             // Datafields refresh rate (ms)

SoftwareSerial mySerial(rxPin,txPin);  // 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()  {
  PotValA = 1023;
  PotValB = 1023;
  Serial.begin(57600);
  mySerial.begin(57600);   // 57600 = max value for softserial
  pinMode(txPin, OUTPUT);
  pinMode(rxPin, INPUT);
  myStepperA.setSpeed(4);  // set the motor speed to 4 RPM
  myStepperB.setSpeed(4);  // set the motor speed to 4 RPM
  pinMode(ENER_A , OUTPUT);
  //  pinMode(ENER_B , OUTPUT);  
  Serial.println(VERSION);
  while(mySerial.available())  mySerial.read();         // empty RX buffer
}

void loop() {
  if(mySerial.available())  {                           // data received from smartphone
    delay(2);
    cmd[0] =  mySerial.read();  
    if(cmd[0] == STX)  {
      int i=1;      
      while(mySerial.available())  {
        delay(1);
        cmd[i] = mySerial.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 >
    }

    if(abs(PotValA - pos_A)> 4){  //if diference is greater than 4 steps.
      if((PotValA - pos_A)> 0){
        digitalWrite(ENER_A, HIGH);   //Motor ENER_Agized.    
        myStepperA.step(1);    // move one step to the right.
        pos_A++;
      }
      if((PotValA - pos_A)< 0){
        digitalWrite(ENER_A, HIGH);   //Motor ENER_Agized.
        myStepperA.step(-1);    // move one step to the left.
        pos_A--;
      }
      stamp_A = millis();  // stamp actual time.  
    }

    if(abs(PotValB - pos_B)> 4){ //if diference is greater than 4 steps.
      if((PotValB - pos_B)> 0){
        digitalWrite(ENER_A, HIGH);  //Motor ENER_Agized. ********   ENER_A led used ...change to ENER_B if required and define another led number
        myStepperB.step(1);  // move one step to the right.
        pos_B++;
      }
      if((PotValB - pos_B)< 0){
        digitalWrite(ENER_A, HIGH);   //Motor ENER_Agized.********  ENER_A led used ...change to ENER_B if required and define another led number
        myStepperB.step(-1);  // move one step to the left.
        pos_B--;
      }
      stamp_B = millis(); // stamp actual time.
    }
    else {      
      if((millis() - stamp_A) > TIMEOUT){   //Turn Off coils after TIMEOUT.
        digitalWrite(COIL1_A, LOW);
        digitalWrite(COIL2_A, LOW);
        digitalWrite(COIL3_A, LOW);
        digitalWrite(COIL4_A, LOW);
        digitalWrite(ENER_A, LOW); //Motor de-ENER_Agized.

        if((millis() - stamp_B) > TIMEOUT)//Turn Off coils after TIMEOUT.
          digitalWrite(COIL1_B, LOW);
        digitalWrite(COIL2_B, LOW);
        digitalWrite(COIL3_B, LOW);
        digitalWrite(COIL4_B, LOW);
        digitalWrite(ENER_A, LOW);//Motor de-ENER_Agized.Motor *********   ENER_A led used ...change to ENER_B if required and define another led number
      }

    }
  }

  sendBlueToothData();
  
  Serial.print("PotValA");
  Serial.print("  :  ");
  Serial.print(PotValA);          
  Serial.print("  :  ");  
  Serial.print("pos_A");
  Serial.print("  :  ");
  Serial.print(pos_A);  
  Serial.print("  :  ");
  Serial.print("PotValB");
  Serial.print("  :  ");
  Serial.print(PotValB);
  Serial.print("  :  ");  
  Serial.print("pos_B");
  Serial.print("  :  ");
  Serial.println(pos_B);
}

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

    mySerial.print((char)STX);                                             // Start of Transmission
    mySerial.print(getButtonStatusString());  
    mySerial.print((char)0x1);   // buttons status feedback
    mySerial.print(GetdataInt1());            
    mySerial.print((char)0x4);   // datafield #1
    mySerial.print(GetdataFloat2());          
    mySerial.print((char)0x5);   // datafield #2
    mySerial.print(displayStatus);                                         // datafield #3
    mySerial.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 purpos_Ae
  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 purpos_Ae
  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

  PotValA =  map (joyX,-100,100,0,2047);//  Map joyX range in the stepper range motor 1
  PotValB =  map (joyY,-100,100,0,2047);//  Map joyY  range in the stepper range motor 2


      
}


woodygb

#411
Dec 16, 2014, 03:41 pm Last Edit: Dec 16, 2014, 04:26 pm by woodygb
@ Kas.

Seeing as how getButtonState appears fine ..... would there be any reason that getButtonState would work ....but getJoystickState is blocked or not implemented?

 
Code: [Select]
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 >


Woody

AntonioLopez

#412
Dec 16, 2014, 06:11 pm Last Edit: Dec 16, 2014, 06:35 pm by AntonioLopez
Hi Kas,

I am seeing data now.  I've tried your code the one that you told should show a line of numbers on the serial monitor and I do see data on the serial monitor.  That video I shot before I tried your code.

Thanks

Woody,

The code with the changes that you posted above, won't compile, here's the error,
      'getButtonState' was not declared in this scope, 

Here's the line:
      if     (i==2)          getButtonState(cmd[1]);    // 3 Bytes  ex: < STX "C" ETX >

I'm posting a video that I just shot with your previous code so you can see what the steppers are doing.

Thanks 

kas

#413
Dec 16, 2014, 06:23 pm Last Edit: Dec 16, 2014, 06:46 pm by kas
Quote
Hi Kas,
I am seeing data now.  I've tried you the do and I do see data on the serial monitor.  That video I shot before I tried your code.
Are you now seeing both Joystick AND button info's in serial monitor, using AndroTest V2.0  ??
What was wrong in your setup ??



Quote
@kas
Seeing as how getButtonState appears fine ..... would there be any reason that getButtonState would work ....but getJoystickState is blocked or not implemented?
Quick check:
Code: [Select]
     
Serial.print("i=");  Serial.println(i);         // <<--- debug
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 >

AntonioLopez

Hi Kas,

The code above won't compile, here's the error for this line
Serial.print("i=");  Serial.println(i);         // <<--- debug 

Error.
expected constructor, destructor, or type conversion before ."token

Sorry, I wish I knew how to fix it.

AntonioLopez

Kas,

Here's the video showing what I can see in the serial monitor.

https://www.youtube.com/watch?v=sDAlXYJT6wA&feature=youtu.be

Let me know what you think.

Thanks

kas

Quote
The code above won't compile, here's the error for this line
Serial.print("i=");  Serial.println(i);         // <<--- debug 
This line is to be added to AndroTest V2.0   ;)

just before
Code: [Select]
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 >

woodygb

#417
Dec 16, 2014, 09:11 pm Last Edit: Dec 16, 2014, 09:22 pm by woodygb
Woody,

The code with the changes that you posted above, won't compile, here's the error,
      'getButtonState' was not declared in this scope, 

Here's the line:
      if     (i==2)          getButtonState(cmd[1]);    // 3 Bytes  ex: < STX "C" ETX >

I'm posting a video that I just shot with your previous code so you can see what the steppers are doing.

Thanks 
I don't think you read my post correctly ....
Quote
I've modified the first lump of stepper code
.. this combined with the second lump that contains the  getButtonState routine will be the COMPLETE code.


2nd lump....
Code: [Select]
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;
  }
}









woodygb

#418
Dec 16, 2014, 10:00 pm Last Edit: Dec 16, 2014, 10:46 pm by woodygb Reason: Additional data
Antonio I think that the problem is nearly identified ...that doesn't however mean that the reason for the problem will be sorted.


Try inserting that extra line of code that Kas posted into the  AndroTest V2.0 ....in the position indicated.

THEN when you run the new modified code you should see i=7 ...which I believe gives a cue for reading the joystick value ...or ... when a button is pressed i=2 a cue that a button has been pressed go read it's value.







kas

#419
Dec 16, 2014, 10:46 pm Last Edit: Dec 16, 2014, 10:49 pm by kas
Quote
Kas,

Here's the video showing what I can see in the serial monitor.
https://www.youtube.com/watch?v=sDAlXYJT6wA&feature=youtu.be
Let me know what you think.

Thanks
:smiley-eek:  :smiley-eek:
In this video datafields and button state are no more updated
Button #5 is configured as "push button" and should be reset by Arduino within 750 milliseconds
Is that the unmodified V2.0 sketch ??
Did you change the mySerial pins ??

Add the debug line to a fresh V2.0 and let us have the result


EDIT
Any possibility to test the App with another Android smartphone or tablet ??

Go Up