Analog Joystick Gives values above 3000

I had an elegoo 5v joystick lying around and decided to test it out. It was giving numbers above 2000 and 3000 when it should be giving values from 0-1023. I purchased a pack of similar joysticks (Teyleten on amazon) which give the same result. (I am trying to center these 0-1023 values around the origin by simply subtracting 512)

I am using a 12v 5amp power supply to power 2 stepper motors, and sharing this power with a buck converter to step down to 5v to power my esp32 and joystick. I have checked the voltage on the buck converter's output (5.02v) so I think that is okay.

The last lines of code show how I am printing the joystick values to the serial monitor.

Side note: While I should first tackle the joystick reading issue, I would also appreciate anybody's advice on why my stepper motors move 1 step at a time (about 1-2 times per second). I have tried debugging by printing .speed() of each stepper to the serial monitor. This says they are being fed the correct speeds. However, they still only step about once per second, albeit in the correct direction (CW/CCW depending on my conditional statement).

#include <AccelStepper.h>

// Define some steppers and the pins the will use
AccelStepper stepper1(AccelStepper::FULL2WIRE, 19, 18);  // left stepper
AccelStepper stepper2(AccelStepper::FULL2WIRE, 17, 16);  // right stepper


#define PI 3.14159

//pins
const int x_pin = 36;
const int y_pin = 39;
const int SW = 34;

//vars for analog readings
float x;  //left right
float y;  //up down

//vars for speeds/directions etc
float hypotenuse;

float p1;
float p2;

float q1;
float q2;
float var1;

const int deadzone = 55;

void setup() {
  Serial.begin(115200);

  stepper1.setMaxSpeed(512.0);
  stepper1.setAcceleration(1000.0);

  stepper2.setMaxSpeed(512.0);
  stepper2.setAcceleration(1000.0);
}

void loop() {
  x = analogRead(x_pin) - 512;  // xpin reads 0 to 1023 where 512 is middle (stationary)
  y = analogRead(y_pin) - 512;  // ypin reads 0 to 1023 where 512 is middle (stationary)

  hypotenuse = sqrt((x * x) + (y * y));


  if (hypotenuse > deadzone) {

    if (x > 0 && y > 0) {  // first quadrant

      if (x > y) {

        p1 = (PI / 4 + atan(y / x)) / (PI / 2);  // % for RIGHT motor
        p2 = 1 - p1;                             // % for LEFT motor

        q1 = p1 * p1;
        q2 = p2 * p2;

        var1 = sqrt(hypotenuse * hypotenuse / (q1 + q2));

        stepper2.setSpeed(-var1 * p1);  //negative for counterclockwise
        stepper1.setSpeed(-var1 * p2);  //negative for counterclockwise

      } else {

        p1 = (PI / 4 + atan(x / y)) / (PI / 2);  // % for RIGHT motor
        p2 = 1 - p1;                             // % for LEFT motor

        q1 = p1 * p1;
        q2 = p2 * p2;

        var1 = sqrt(hypotenuse * hypotenuse / (q1 + q2));

        stepper2.setSpeed(-var1 * p1);  //negative for counterclockwise
        stepper1.setSpeed(var1 * p2);   //positive for clockwise
      }
    }

    else if (x < 0 && y > 0) {  // second quadrant

      if (y > -x) {

        p1 = (PI / 4 + atan(-x / y)) / (PI / 2);  // % for right motor
        p2 = 1 - p1;                              // % for left motor

        q1 = p1 * p1;
        q2 = p2 * p2;

        var1 = sqrt(hypotenuse * hypotenuse / (q1 + q2));

        stepper2.setSpeed(-var1 * p1);  //negative for counterclockwise
        stepper1.setSpeed(var1 * p2);   //positive for clockwise

      } else {

        p1 = (PI / 4 + atan(y / -x)) / (PI / 2);  // % for RIGHT motor
        p2 = 1 - p1;                              // % for LEFT motor

        q1 = p1 * p1;
        q2 = p2 * p2;

        var1 = sqrt(hypotenuse * hypotenuse / (q1 + q2));

        stepper2.setSpeed(var1 * p1);  //positive for clockwise
        stepper1.setSpeed(var1 * p2);  //positive for clockwise
      }
    }

    else if (x < 0 && y < 0) {  // third quadrant

      if (-x > -y) {

        p1 = (PI / 4 + atan(-y / -x)) / (PI / 2);  // % for RIGHT motor
        p2 = 1 - p1;                               // % for LEFT motor

        q1 = p1 * p1;
        q2 = p2 * p2;

        var1 = sqrt(hypotenuse * hypotenuse / (q1 + q2));

        stepper2.setSpeed(var1 * p1);  //positive for clockwise
        stepper1.setSpeed(var1 * p2);  //positive for clockwise

      } else { 

        p1 = (PI / 4 + atan(-x / -y)) / (PI / 2);  // % for right motor
        p2 = 1 - p1;                               // % for left motor

        q1 = p1 * p1;
        q2 = p2 * p2;

        var1 = sqrt(hypotenuse * hypotenuse / (q1 + q2));

        stepper2.setSpeed(var1 * p1);   //positive for clockwise
        stepper1.setSpeed(-var1 * p2);  //negative for counterclockwise
      }
    }

    else if (x > 0 && y < 0) {  // forth quadrant

      if (-y > x) {

        p1 = (PI / 4 + atan(x / -y)) / (PI / 2);  // % for right motor
        p2 = 1 - p1;                              // % for left motor

        q1 = p1 * p1;
        q2 = p2 * p2;

        var1 = sqrt(hypotenuse * hypotenuse / (q1 + q2));

        stepper2.setSpeed(-var1 * p1);  //negative for counterclockwise
        stepper1.setSpeed(var1 * p2);   //positive for clockwise

      } else {

        p1 = (PI / 4 + atan(-y / x)) / (PI / 2);  // % for RIGHT motor
        p2 = 1 - p1;                              // % for LEFT motor

        q1 = p1 * p1;
        q2 = p2 * p2;

        var1 = sqrt(hypotenuse * hypotenuse / (q1 + q2));

        stepper2.setSpeed(-var1 * p1);  //negative for counterclockwise
        stepper1.setSpeed(-var1 * p2);  //negative for counterclockwise
      }
    }

    else if (x == 0) {  // if joystick on y-axis
      if (y > 0) {
        stepper2.setSpeed(-hypotenuse);
        stepper1.setSpeed(hypotenuse);
      } else {
        stepper2.setSpeed(hypotenuse);
        stepper1.setSpeed(-hypotenuse);
      }
    }

    else if (y == 0) {  // if joystick on x-axis
      if (x > 0) {
        stepper2.setSpeed(hypotenuse);
        stepper1.setSpeed(hypotenuse);
      } else {
        stepper2.setSpeed(-hypotenuse);
        stepper1.setSpeed(-hypotenuse);
      }
    }
  }

  else {  // joystick in "deadzone" (no movement)
    stepper1.setSpeed(0);
    stepper2.setSpeed(0);
  }
  stepper1.runSpeed();
  stepper2.runSpeed();

  Serial.print("LR: ");
  Serial.print(x);
  Serial.print(" UD: ");
  Serial.println(y);
  Serial.println(hypotenuse);
  Serial.println(var1);
  Serial.println(stepper1.speed()); // prints correct speed
  Serial.println(stepper2.speed()); // prints correct speed
}

You should have checked the data sheet for the ESP32 module, had you done so you would have seen it has a 12bit resolution (0-4096) as opposed to a regular Arduino’s (like Uno and Mega etc.) 10bit resolution. (0-1023)

1 Like

If you want to revert to a 10 bit resolution and have the same range of numbers as before, look here for how to do it:-
Set A/D resoloution

1 Like

I actually just tried this

    // Set ADC resolution to 10 bits

  analogSetWidth(10); 

in my setup() function and am still getting values above 3500.

EDIT: I see you mention "same range as before"

That is because you did not read that site I posted correctly.

The correct command is:-

analogReadResolution(10);

Did you read that link at all?

2 Likes

okay you caught me. lesson learned: do not substitute google generated AI response for stranger willing to help.

however, all of my joysticks read -450 on the x, 200 on the y after I center by subtracting 512.

If you were to read through my code, you can see that the ONLY place I am changing the value of x/y is when reading from the analog pin. I do not alter these values at all, yet they do not work as expected. moving all the way left/ all the way right give the same value.

I understand these are low quality joysticks, but they all behave the same way.

Then do not subtract 512. Then they should read 0 to 1023.

With the center position at about 512, give or take the jitter on any A/D reading.

1 Like

I guess what I meant to say is that when the joysticks are in the centered position, they all read at about (690,690), yet when moved to their extremities correctly read (0,1023) or (0,0) or (1023,1023). Also, they can be rotated about 90 degrees give or take before changing value at all. They also max out to 1023 before going even halfway. I'm beginning to think they really are THAT bad, but the fact that they are all centered at (690,690) is beyond me.

TLDR: about to leave a 1 star review for Teyleten joysticks on amazon.

Besides having a standard 12bit A/D, the ESP32 is a 3.3V logic board. If you feed the joysticks with 5V, they'll output a 5V signal, which is no good. Try feeding the joysticks with 3.3V.

2 Likes

A bit unfair when it is your misunderstanding of what you are doing.

1 Like

I'd award you with a solution if the forums allowed giving multiple per topic. While the center position still is not centered (~470,470), I think you are certainly correct about the logic board voltage. @Grumpy_Mike I learned a lot this weekend including the fact that esp32 != arduino. I (quite literally) did not know ohm's law 2 weeks ago. 5 stars to you and teyleten

1 Like

It won't. But you can move the solution, if you first delete the original solution, then you can reassign it.

I didn’t deserve it to being with so I’m am fine with that.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.