1

Topic: Joystick control variables

Hi Forum

new to remoteXY so hoping someone on here  can offer me suggestions.

I am using remote xy with two joystick controls connected through ESP8266 to Arduino UNO using an L298d type motor shield.

I want to use the joystick controls to operate the 4 dc motors on the shield separately to control an RC model.

My problem is when i try to use the joystick x, y variables to run the different motors it seems to be engaging two motors on each joystick regardless of which access i am pushing the joystick on, so basically if i push joystick 1 forward on the y axis i want motor 1 to run forward and same if i pull it back, then motor two is controlled by x axis. I expect this is standard requirements  but my issue is i push forward on y axis and both motors run, hope that explains sufficiently.

Following is the code i am using so would really appreciate it if someone on here has an idea where i am going wrong. As below i am using the AFMotor library to control the motors and i am just hard coding in speed for now to max.


// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__ESP8266_HARDSERIAL_POINT

#include <RemoteXY.h>
#include <Servo.h>
#include <AFMotor.h>

// RemoteXY connection settings
#define REMOTEXY_SERIAL Serial
#define REMOTEXY_SERIAL_SPEED 115200
#define REMOTEXY_WIFI_SSID "RemoteXY"
#define REMOTEXY_WIFI_PASSWORD "12345678"
#define REMOTEXY_SERVER_PORT 6377
#define REMOTEXY_ACCESS_PASSWORD "12345678"

// Motor declarations
AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);

// RemoteXY configurate 
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 255,4,0,0,0,21,0,10,13,0,
  5,32,68,31,30,30,2,26,31,5,
  32,3,30,31,31,2,26,31
  };
 
// this structure defines all the variables and events of your control interface
struct
{

    // input variables
  int8_t FrontBucket_x; // =-100..100 x-coordinate joystick position
  int8_t FrontBucket_y; // =-100..100 y-coordinate joystick position
  int8_t Drive_x; // =-100..100 x-coordinate joystick position
  int8_t Drive_y; // =-100..100 y-coordinate joystick position

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;

#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////

void setup()
{
  RemoteXY_Init ();
 
//set joystick x,y variables to center initially
  RemoteXY.FrontBucket_x = 0;
  RemoteXY.FrontBucket_y = 0;
  RemoteXY.Drive_x = 0;
  RemoteXY.Drive_y = 0;

//set motors to stop state initially
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);   
}

void loop()
{
  RemoteXY_Handler ();

//Call functions in a constant loop
  drive_stick();
  steer_stick();
  loader_stick();
  bucket_stick();
 
}

//Method to control the drive control
void drive_stick()
{
  if (RemoteXY.Drive_x > 0)
  {
    motor1.run(FORWARD);
    motor1.setSpeed(255);
  }
  else if (RemoteXY.Drive_x < 0)
  {
    motor1.run(BACKWARD);
    motor1.setSpeed(255);   
  }
  else
  {
    motor1.run(RELEASE);
  }
}

//Method to control the steering control
void steer_stick()
{
  if (RemoteXY.Drive_y > 0)
  {
    motor2.run(FORWARD);
    motor2.setSpeed(255);
  }
  else if (RemoteXY.Drive_y < 0)
  {
    motor2.run(BACKWARD);
    motor2.setSpeed(255);   
  }
  else
  {
    motor2.run(RELEASE);
  }
}

//Method to control the loader arm
void loader_stick()
{
  //Front Arm Control
  if (RemoteXY.FrontBucket_x > 0)
  {
    motor3.run(FORWARD);
    motor3.setSpeed(255);
  }
  else if (RemoteXY.FrontBucket_x < 0)
  {
    motor3.run(BACKWARD);
    motor3.setSpeed(255);   
  }
  else
  {
    motor3.run(RELEASE);
  }
}

//Method to control the bucket
void bucket_stick()
{
  if (RemoteXY.FrontBucket_y > 0)
  {
    motor4.run(FORWARD);
    motor4.setSpeed(255);
  }
  else if (RemoteXY.FrontBucket_y < 0)
  {
    motor4.run(BACKWARD);
    motor4.setSpeed(255);   
  }
  else
  {
    motor4.run(RELEASE);
  }
}

2

Re: Joystick control variables

Can't see much wrong.....

However, you have put your motor declarations inside the RemoteXY code generated by the online editor. This is not usual, and will hamper you every time you change the GUI layout. Normal practice is to just copy the whole block from the editor output and paste it in over the existing block.  To make it even easier, you can create a new tab in the IDE for the RemoteXY block, then it's a simple case of (in the editor) Get Source Code, highlight the whole block of code (I usually just select from the header to the footer, as they are easy to see), e.g.

//////////////////////////////////////////////
//        RemoteXY include library        //
//////////////////////////////////////////////
.
.
.
.
/////////////////////////////////////////////
//           END RemoteXY include      //
/////////////////////////////////////////////

then Copy (Ctrl-C)

return to my sketch, open the tab for the RemoteXY stuff...

select all (Ctrl-A)

then Paste (Ctrl-V)

If you move your motor declarations out of the RemoteXY section, you won't have to keep putting them back.  They can go anywhere in front of void setup();

You will, of course have to #include your RemoteXY tab (by name) in the main body of the sketch.

You might also want to consider giving your motors more meaningful names - e.g. "motor1" = "Drive_x" etc. This will help when reading your code for debugging. There will be no conflict between your Drive_x and RemoteXY.Drive_x

Other than that your code should be working, as far as I can tell.

2B, or not 2B, that is the pencil ...

3

Re: Joystick control variables

I think I see the problem now - you will find it incredibly difficult to keep your Y axis at zero when moving the joystick up and down in the X axis, and vice-versa.  As soon as you come off zero, the motors will spring to life at maximum speed !

Change your >0, <0 tests to something that will give you a wider deadband - perhaps >10, <10 or similar.

2B, or not 2B, that is the pencil ...

4

Re: Joystick control variables

Hey Daba

appreciate your reply and your suggestions re: my code, i get what you mean about making it easier to copy in the remoteXY code if i keep  my variables/declarations out of the remoteXY body of code.

I have no done  this .

Also that was a good spot on why i was having issues with the code i changed it as per your suggestion to make the > and < values in the IF code , i went for >50 <-50.
It worked a treat and i now have my uno wifi talking to the motor shield from my remoteXY app on  my mobile, all 4 motors will run independently .
Thanks for your help here i guess looking back at it the 0 value was causing confusion i can see it now.

Happy new year.

5

Re: Joystick control variables

Glad to help.....

With a little more effort you can make the "active" range of your joystick values control the speed of the motors rather than just switching them to full speed.  This will give you more control of the model.

Lines 49-52 : giving your motors meaningful names

Lines 57-67 : defining data used in the coding : note I have used memory locations here rather than just #define them, because at a later date you might want to set them via RemoteXY, like a "Setup" page, for instance.

NOTE : I have only done this for Drive_X, you would need to replicate the same coding for the other motors.

How it works. ....

Line 104

 Drive_x.setSpeed(map(abs(RemoteXY.Drive_x), RemoteXY.Drive_x - Deadband, 100, Drive_min, Drive_max));

this code sets the speed reference for the drive, and does not care about direction.

map : scales the input value : from input value minimum to maximum : to output value min to max

abs(....) doesn't care about direction, so gives positive numbers, which is what you need for the speed setting.

Line 105

constrain(Drive_x.setSpeed, Drive_min, Drive_max);

the constrain function "forces" the setSpeed variable to fall within min to max, because "map" will work beyond the input variable range, it is just a linear scaling function.

Note that I have successfully done the equivalent of lines 104 and 105 in one statement, but found it hard to understand later !!

Lines 107 to 109
This is similar to your original code, and starts and stops the motor, in the required direction, when the joystick moves out of the deadband.

Untested, that's up to you...

Here's the code ....

// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__ESP8266_HARDSERIAL_POINT

#include <RemoteXY.h>
#include <Servo.h>
#include <AFMotor.h>

/////////////////////////////////////////////
//           RemoteXY include              //
/////////////////////////////////////////////

// RemoteXY connection settings
#define REMOTEXY_SERIAL Serial
#define REMOTEXY_SERIAL_SPEED 115200
#define REMOTEXY_WIFI_SSID "RemoteXY"
#define REMOTEXY_WIFI_PASSWORD "12345678"
#define REMOTEXY_SERVER_PORT 6377
#define REMOTEXY_ACCESS_PASSWORD "12345678"

// RemoteXY configurate 
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 255,4,0,0,0,21,0,10,13,0,
  5,32,68,31,30,30,2,26,31,5,
  32,3,30,31,31,2,26,31
  };
 
// this structure defines all the variables and events of your control interface
struct
{

    // input variables
  int8_t FrontBucket_x; // =-100..100 x-coordinate joystick position
  int8_t FrontBucket_y; // =-100..100 y-coordinate joystick position
  int8_t Drive_x; // =-100..100 x-coordinate joystick position
  int8_t Drive_y; // =-100..100 y-coordinate joystick position

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;

#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////

// Motor declarations
AF_DCMotor Drive_x(1);
AF_DCMotor Drive_y(2);
AF_DCMotor FrontBucket_x(3);
AF_DCMotor FrontBucket_y(4);

// variable and constant definitions

// declare joystick deadband
uint8_t Deadband = 10;

// min and max speeds of the motors
// determine these yourself
int8_t  Drive_min = 50;
int8_t  Drive_max = 255;
int8_t  BucketX_min = 35;
int8_t  BucketX_max = 120;
int8_t  BucketY_min = 20;
int8_t  BucketY_max = 150;



void setup()
{
  RemoteXY_Init ();
 
//set joystick x,y variables to center initially
  RemoteXY.FrontBucket_x = 0;
  RemoteXY.FrontBucket_y = 0;
  RemoteXY.Drive_x = 0;
  RemoteXY.Drive_y = 0;

//set motors to stop state initially
  Drive_x.run(RELEASE);
  Drive_y.run(RELEASE);
  FrontBucket_x.run(RELEASE);
  FrontBucket_y.run(RELEASE);   
}

void loop()
{
  RemoteXY_Handler ();

//Call functions in a constant loop
  drive_stick();
  steer_stick();
  loader_stick();
  bucket_stick();
 
}

//Method to control the drive
void drive_stick()
{ 
  // firstly calculate the drive speed setting, regardless of direction
  Drive_x.setSpeed(map(abs(RemoteXY.Drive_x), RemoteXY.Drive_x - Deadband, 100, Drive_min, Drive_max));
  constrain(Drive_x.setSpeed, Drive_min, Drive_max);
  
  if (RemoteXY.Drive_x > Deadband) Drive_x.run(FORWARD);
  else if (RemoteXY.Drive_x < Deadband*-1) Drive_x.run(BACKWARD);
  else Drive_x.run(RELEASE);
}

//Method to control the steering
void steer_stick()
{
  if (RemoteXY.Drive_y > Deadband)
  {
    Drive_y.run(FORWARD);
    Drive_y.setSpeed(255);
  }
  else if (RemoteXY.Drive_y < Deadband*-1)
  {
    Drive_y.run(BACKWARD);
    Drive_y.setSpeed(255);   
  }
  else
  {
    Drive_y.run(RELEASE);
  }
}

//Method to control the loader arm
void loader_stick()
{
  //Front Arm Control
  if (RemoteXY.FrontBucket_x > Deadband)
  {
    FrontBucket_x.run(FORWARD);
    FrontBucket_x.setSpeed(255);
  }
  else if (RemoteXY.FrontBucket_x < Deadband*-1)
  {
    FrontBucket_x.run(BACKWARD);
    FrontBucket_x.setSpeed(255);   
  }
  else
  {
    FrontBucket_x.run(RELEASE);
  }
}

//Method to control the bucket
void bucket_stick()
{
  if (RemoteXY.FrontBucket_y > Deadband)
  {
    FrontBucket_y.run(FORWARD);
    FrontBucket_y.setSpeed(255);
  }
  else if (RemoteXY.FrontBucket_y < Deadband*-1)
  {
    FrontBucket_y.run(BACKWARD);
    FrontBucket_y.setSpeed(255);   
  }
  else
  {
    FrontBucket_y.run(RELEASE);
  }
}
2B, or not 2B, that is the pencil ...