Trying to Make a Joystick Controlled Motor

Hello! I'm pretty new to Arduino, and I've been going through a tutorial series on it. I decided to try to branch off, however, and try my hand at a small project. Unfortunately, I haven't been completely successful.

Here's the idea: I want to make a joystick controlled DC motor with a toggle action, so if I push the joystick either all the way up, all the way to the side, or at a 45 degree angle positively, the motor will operate at 255 - full power. At the equilibrium joystick position, the motor should be at half speed, and by pushing the joystick, the motor will turn on and off.

Here's the hardware: The L293D motor controller and a 3-6V DC motor from the Elegoo "The Most Complete Starter Kit."

Here's the reasoning to my most recent approach: I hooked up everything using an external power supply and the L293D as well as the motor. My reasoning was to assign a "switchposold" and read a "switchposnew" and if the switchposold was 0 and the switchpos new was 1, that means the button is pushed. If the button is pushed, then set the motorstate to 0 if it's 1 and 1 if it's 0. Then I could use if statements to manipulate the motorspeed with the joystick given that the motorstate is 1. I've worked out an equation to get motorspeed from the joystick.

Here's my code;

int speedpin = 5;//this is pin 1 on the L293D
int dirpin1 = 4;//this is pin 2 on the L293D
int dirpin2 = 3;//this is pin 7 on the L293D
int motorspeed;//variable to control the speed
int xpin = A0;//the pin reading the x value of the joystick
int ypin = A1;//the pin reading the y value of the joystick
int xpos;// this is the x position variable
int ypos;//this is the y position variable
int switchposnew;//the value of the switch that is being read
int switchposold = 1; // the stagnant value of the button
int switchpin = 2;//the pin that the pushbutton of the joystick is connected to
int motorstate;// a number 1 or 0 to tell if the motor is on or off

void setup() {
  // put your setup code here, to run once:
pinMode(speedpin, OUTPUT);
pinMode(dirpin1, OUTPUT);
pinMode(dirpin2, OUTPUT);
Serial.begin(2000000);
pinMode(xpin, INPUT);
pinMode(ypin, INPUT);
pinMode(switchpin, INPUT);
digitalWrite(switchpin, HIGH);//So that an external pullup resistor isn't necessary
}

void loop() {
  // put your main code here, to run repeatedly:
digitalWrite(dirpin1, LOW);
digitalWrite(dirpin2, HIGH);
xpos = 1023.- analogRead(xpin);//makes the joystick better for my preferences
ypos = analogRead(ypin);
switchposnew = digitalRead(switchpin);

if(switchposold == 0 && switchposnew == 1){//Basically, if the button has been released from being pushed
  if(motorstate==0){
    motorstate = 1;
  }
  else{
    motorstate =0;
  }
}// these commands simplify the motor into being on or off depending on the toggle of the pushbutton switch
if (motorstate == 0){
  motorspeed = 0;
}
switchposnew = digitalRead(switchpin);//reads the state of the switch for the next loop
while(motorstate == 1 && switchposnew !=0){//as long as the motor is spinning and the button isn't pushed, you can controll the speed with the following equation
  motorspeed = (255./1023.)*(xpos+ypos) - 127.7;//control's the speed of the motor using the joystick
  switchposnew = digitalRead(switchpin);// updates the position of the button
}
if (motorspeed<0){
  motorspeed = 0;//prevents the motor speed from going negative
}
if (motorspeed>255){
  motorspeed = 255;//prevents the motor speed from going higher than full
}
switchposold = switchposnew;//refreshes the old switch position so the toggle function works.
Serial.println(motorspeed);
}

The motor isn't working as I would like. I haven't told the motor to spin up in the code, yet, but the motorstate doesn't cleanly alternate between 0 and 1 when I push the switch.

Does anyone have any advice for this project or the way I'm going about it?
Thanks!!!

Yay! First post and proper use of code tags! Karma++

I have not done a deep dive into your code but I would separate the testing.
Just hook up the joystick and read the values of the buttons and the joystick positions. Print them to the serial monitor.
Do you get values that you expect? If so, then move on.

I just wonder if some of you issue with the button bouncing.

it may be easier if the code detects a button press rather than when the button is pressed ...

... by testing for a button state change when old != new. Old is updated whenever there is a change (perhaps add a small delay to debounce).

a button press occurs when there is a change and new is active (pressed). Toggle motorstate (as you do) when a button press event occurs

when motorstate is set to zero set the speed to zero

when motor state is set to true, read the joystick once and update the motor speed with limits (as you do)

you code is a bit confusing by the three switchpin reads.

Of course with this approach, the motor speed is only set during a button press.

perhaps rather than toggling motorstate, the motor speed can be set to zero when the button is pressed and the motor speed calculated from the joystick is <= zero.

I can see how the three pin reads are confusing, but I basically used them as a failsafe just to make sure the reads were updating.

Can you explain why the motor speed is only set when the button is pressed? I put that in a while loop, so then won't it infinitely loop and update the speed according to the position of the joystick unless the conditions aren't fulfilled? That was my logic. I don't want to have the motor speed to be set once per button press; I want to be able to actively adjust the speed of the motor and then toggle it on/off with the button.

Does that make sense?
Thanks again for you help!!

I want to be able to actively adjust the speed of the motor and then toggle it on/off with the button.

then when motorstate is true, why don't you just read the joystick and update the speed? it seems like you only wanted to do it when the button was pressed.

otherwise (when motorstate is false) just set the motor speed to zero

your code tests for motorstate == 0, but it also does the code following the if. maybe that code should be in an else without the motorstate and switchposnew test

Oh Man!!! Thank you very much!!
Like I said before, I'm pretty new, and this has definitely been the most challenging experience I've had so far. Thank you all for your responses!