How to improve the analogue range of Arduino Joysticks

hi all i have a robot chassis powered by 4 drill sized motors. The end result was an incredibly twitchy bot when used in small spaces. i am controlling it with an arduino joystick communicating via xbee to another xbee arduino. The range of the potentiometers in the joystick is rather poor. there is nothing till you get about 70% power, so i cant drive the bot as slowly as i would like. Is there a way to tweak the joystick to improve the range to get atleast 30% of the power?

incase anyone is interested here is my projects on the Lets Make Robots website

http://letsmakerobots.com/robot/project/terrestial-explorer-v10

Hi.

You need to ask yourself whether you've identified the problem, or are you assuming it is the joystick ?

I haven't seen your project (yet), i don't care much for problems introduced here and then pointed to some external site to go and find out more about the problem. Don't see this as an attack on your person, but isn't this about your problem, that you need help with ? Why do we need to go somewhere else so we can decide we can or can not help you ?

Did you use 'map' to create some transition between the joystick value, and that of the analog output to your motor ?

I wouldn't surprise me if you needed to create a few different steps when controlling the motors. First, a motor (other loads that use coils too) needs a higher current to start, than that it needs to keep on going. So perhaps you should aid the start of that motor by sending it a "higher start speed", and then drop to wherever you want it to go (and which it will still accept to keep running, loaded or not).

You might also find that there could be smaller differences in actual speed when getting closer to 100 % of linear control signal. So some research into the properties of steering speed and the motors you are using would be what you need right now, before you can go on and be able to predict the handling of your vehicle.

Remember that the load also needs to be taken into account. So do you run with different weights, and will the vehicle be on any slopes and such ?

The end result was an incredibly twitchy bot when used in small spaces.

You need to post your arduino/joystick code for evaluation. Your problem may be with your wireless connection or the motor control and mechanical setup.

Hi, What model ESC are you using, are they programmable. Have you checked that the linear response from the joystick is still linear at the input to the ESC.

The motors may need some starting current, especially when under load, so you may have to program some non linear response to the joystick input.

If you lift the robot off the ground and operate the joysticks, do you have better control with no load?

Tom.. :)

MAS3:
Hi.

You need to ask yourself whether you’ve identified the problem, or are you assuming it is the joystick ?

Yes i have narrowed the issue down to the joysticks. i have tried using different potentiometers and it has worked well, and has given me a smoother response over a wider range. i will try and modify the potentiometers in the joysticks and hopefully that allows me to access a larger range. The link was to show you the configuration that i had (skid steer)

TomGeorge:
Hi,
What model ESC are you using, are they programmable.

If you lift the robot off the ground and operate the joysticks, do you have better control with no load?

Tom… :slight_smile:

Hi tom, I am using generic 30 Amp esc’s they have worked well smoothly with my old helicopter potentiometers but because i am using a custom made remote, its difficult to implement them in the small space i have in the remote.

zoomkat:
You need to post your arduino/joystick code for evaluation. Your problem may be with your wireless connection or the motor control and mechanical setup.

Here is my code. (Transmitter)

#include <EasyTransfer.h>
EasyTransfer ET;

int potpin1 = 0;
int potpin2 = 1;

struct SEND_DATA_STRUCTURE{
  int servo1val;
  int servo2val;
};

SEND_DATA_STRUCTURE txdata;

void setup(){
  //Serial.begin(115200);
  Serial.begin(9600);
  
  ET.begin(details(txdata), &Serial);
  //pinMode(potpin1, INPUT);
  //pinMode(potpin2, INPUT);
 
}

void loop(){  

  txdata.servo1val = analogRead(potpin1);
  txdata.servo2val = analogRead(potpin2);
  
  txdata.servo1val = map(txdata.servo1val, 0, 1023, 0, 179);
  txdata.servo2val = map(txdata.servo2val, 0, 1023, 0, 179);
    
  ET.sendData();
  }

And my receiver

#include <Servo.h>

#include <EasyTransfer.h>
EasyTransfer ET;

Servo myservo1;
Servo myservo2;



struct RECEIVE_DATA_STRUCTURE{
  int servo1val;
  int servo2val;
};

RECEIVE_DATA_STRUCTURE txdata;

void setup(){
  //Serial.begin(115200);
  Serial.begin(9600);
 
  ET.begin(details(txdata), &Serial);
  myservo1.attach(9);
  myservo2.attach(10);
    
  }

void loop(){
  if(ET.receiveData()){
   
    myservo1.write(txdata.servo1val);
    myservo2.write(txdata.servo2val);
    Serial.println(txdata.servo1val);
  }
}

You can use MultiMap() to create a non-linear, pseudo-exponential rate for the motors.

A little smoothing of the analogReads would be a good idea as well. Something like:

void loop(){ 
  unsigned int newservo1val;
  unsigned int newservo2val;

  newservo1val = map(analogRead(potpin1), 0, 1023, 0, 179);
  newservo2val = map(analogRead(potpin2), 0, 1023, 0, 179);

  if (newservo1val > txdata.servo1val) {
    txdata.servo1val += 1;
  } else if (newservo1val < txdata.servo1val) {
    txdata.servo1val -= 1;
  }

  if (newservo2val > txdata.servo2val) {
    txdata.servo2val += 1;
  } else if (newservo2val < txdata.servo2val) {
    txdata.servo2val -= 1;
  }
 
  ET.sendData();
  }

I took a look at your project on LMR; you did a very nice job on your controller. I thought you did it with CNC when I first looked at it.

Chagrin:
You can use MultiMap() to create a non-linear, pseudo-exponential rate for the motors.

A little smoothing of the analogReads would be a good idea as well. Something like:

void loop(){ 

unsigned int newservo1val;
  unsigned int newservo2val;

newservo1val = map(analogRead(potpin1), 0, 1023, 0, 179);
  newservo2val = map(analogRead(potpin2), 0, 1023, 0, 179);

if (newservo1val > txdata.servo1val) {
    txdata.servo1val += 1;
  } else if (newservo1val < txdata.servo1val) {
    txdata.servo1val -= 1;
  }

if (newservo2val > txdata.servo2val) {
    txdata.servo2val += 1;
  } else if (newservo2val < txdata.servo2val) {
    txdata.servo2val -= 1;
  }

ET.sendData();
  }




I took a look at your project on LMR; you did a very nice job on your controller. I thought you did it with CNC when I first looked at it.

Thanks a bunch. i’ll test it and get back to you soon!