Trouble with motor direction and speed direction

Hi,
I am using an arduino mega with a seeedstudio motor controller version 1.2 (Motor_Shield_V1.0).
The trouble I am having is that I am mapping a joystick from 510 - 1023 to 0 - 255 for forward and 506 - 0 to 0 - 255 for backward. Backward works as expected, it speeds up the motor in reverse as I pull back on the joystick and slows down as I bring it back up. But forward also makes the motor go in reverse and starts out fast then slows down as I push the joystick up. I hope you can help me make the forward function go forward and start slow and speed up as I push the joystick up.
Thanks

void forward()
{
     fspead = map(joystick[1], 510, 1023, 0, 255);
     analogWrite(speedpinA,fspead);//input a simulation value to set the speed
     analogWrite(speedpinB,fspead);
     digitalWrite(pinI4,HIGH);//turn DC Motor B move clockwise
     digitalWrite(pinI3,LOW);
     digitalWrite(pinI2,LOW);//turn DC Motor A move anticlockwise
     digitalWrite(pinI1,HIGH);
}
void backward()//
{
     bspead = map(joystick[1], 506, 0, 0, 255);
     analogWrite(speedpinA,bspead);//input a simulation value to set the speed
     analogWrite(speedpinB,bspead);
     digitalWrite(pinI4,LOW);//turn DC Motor B move anticlockwise
     digitalWrite(pinI3,HIGH);
     digitalWrite(pinI2,HIGH);//turn DC Motor A move clockwise
     digitalWrite(pinI1,LOW);
}
else if (joystick[1] <= 505 && joystick[0] >=509 && joystick[0] <=513) 
      {
        backward();
        if (joystick[1] < 510 && joystick[1] > 502 && joystick[0] >=510 && joystick[0] <=509)
      {  
        stop(); 
      }
      }
        
      else if (joystick[1] >= 510 && joystick[0] >=510 && joystick[0] <=509)
      {
        forward(); 
        if (joystick[1] < 510 && joystick[1] > 502 && joystick[0] >=510 && joystick[0] <=509)
      {  
        stop(); 
      } 
      }

Why are you setting the speed first, and then the direction? Is that the way you drive? Stomp the gas, and then put the car in gear?

Would you elaborate please? Maybe point out in the code exactly what you mean?

Maybe point out in the code exactly what you mean?

Really? I think you should be able to look at the calls being made in forward() and backward(), to see which ones control direction (which gear the car is on) and which control speed (how hard to stomp the gas pedal). You should put the car in gear first.

else if (joystick[1] <= 505 && joystick[0] >=509 && joystick[0] <=513)
      {
        backward();
        if (joystick[1] < 510 && joystick[1] > 502 && joystick[0] >=510 && joystick[0] <=509)
      { 
        stop();
      }
      }

If the value in joystick[1] is less than or equal 505 and greater than or equal 509 and less than or equal to 513, go backwards. Please show a list of values that meet that criteria. What values are less than or equal 505 and greater than or equal 509?

Why are you then testing the values of joystick[1] against another silly range?

Those are not just "silly" ranges. Those are numbers are values are from the joystick. When it is sitting in the center position it
Has a tendency to float around a bit. All that is there to make sure it isn't flipping into other modes. Also, there is two joysticks, 0 & 1.

They are silly ranges. There are NO values less than or equal 505 AND greater than or equal 509.

If you want a deadband (a good idea) a useful range is anything greater than 509 (no upper limit), for forward, and anything less than 500 (no lower limit), for backwards.

Okay, that makes good sense. However, you haven't helped me with either of my two original questions.

modsbyus:
Okay, that makes good sense. However, you haven't helped me with either of my two original questions.

It is reasonable to expect you to make changes first, based on the suggestions that you have been given. If things still don't work, post the revised code.

PaulS:
They are silly ranges. There are NO values less than or equal 505 AND greater than or equal 509.

If you want a deadband (a good idea) a useful range is anything greater than 509 (no upper limit), for forward, and anything less than 500 (no lower limit), for backwards.

You seem to be ignoring the fact that he has TWO joysticks and the value of one is being compared to 505 while the value of the other is being compared to 590.

I really does help if you take the time to READ what's posted BEFORE flaming....

Regards,
Ray L.

aarg:
It is reasonable to expect you to make changes first, based on the suggestions that you have been given. If things still don't work, post the revised code.

I have changed the order for setting the speed to the motor before setting the direction and it was a good suggestion, but it made no difference at all and had absolutely nothing to do with my questions. I like constructive criticism and welcome all the help I can get but I don't need the kind of help that involves picking and bullying. Especially when it has nothing to do with the questions I had. If I was having trouble with how my if statement ranges were being executed then I would have asked. There is plenty of other code there that I have not shared because I am following the rules of the forum. There are other if statements below those listed that may not be executed if those "silly" ranges in the if statements aren't there. Sure there may be a better way of doing that but I didnt ask for help on that and it doesn't help me with the problems I face. If I go into a restaurant to get dinner and the waiter was telling me that I have tied my tie in the most wrong way possible in the rudest way possible I would leave and give terrible reviews about the restaurant and waiter. I try not to come here and I try to do all the research and troubleshooting I can on my own because of PaulS. Every time I come here and ask a question he attacks me about how I am wring my code LONG before he ever gets around to helping me with my problem. I know I am doing something wrong,that is why I am here. I dont need to be chastised

void forward()
{
     fspead = map(joystick[1], 510, 1023, 0, 255);
     digitalWrite(pinI4,HIGH);//turn DC Motor B move clockwise
     digitalWrite(pinI3,LOW);
     digitalWrite(pinI2,LOW);//turn DC Motor A move anticlockwise
     digitalWrite(pinI1,HIGH);
     analogWrite(speedpinA,fspead);//input a simulation value to set the speed
     analogWrite(speedpinB,fspead);
}
void backward()//
{
     bspead = map(joystick[1], 506, 0, 0, 255);
     digitalWrite(pinI4,LOW);//turn DC Motor B move anticlockwise
     digitalWrite(pinI3,HIGH);
     digitalWrite(pinI2,HIGH);//turn DC Motor A move clockwise
     digitalWrite(pinI1,LOW);
     analogWrite(speedpinA,bspead);//input a simulation value to set the speed
     analogWrite(speedpinB,bspead);
}

I'm not sure how this happened but, after adding some debugging everything started working right except for speed direction on the forward function. Then I changed my map in that function from

fspead(joystick[1], 510, 1023, 0, 255);

to

fspead(joystick[1], 510, 1023, 255, 0);

and that fixed the speed direction. I'm okay with this result for now but, if anyone has any idea how adding or removing serial prints changes things let me know.

A simple way to get forward and reverse with center off from a potentiometer is to subtract 512 from the readings. Then you get -512 to +511 (assuming that analogRead() returns 0 to 1023)

...R

Why are you setting the speed first, and then the direction? Is that the way you drive? Stomp the gas, and then put the car in gear?

Why care whether analogWrite or digitalWrite occurs first, this all happens in a few microseconds and
the motor will only have moved a few microns in that time? Its mightily irrelevant as the inductance
of the motor windings means that the current change on that timescale is miniscule.

Typical electrical time-constant for motors are measured in millisecond scale, and mechnical time-constants
are tens of milliseconds.

And of course when you call analogWrite the average latency before the change is acted on is 500us
since the PWM only acts on a new duty cycle at the end of a complete cycle, assuming a 1kHz PWM pin.

maybe im reading this wrong so I made notes. The plan to me just seems flawed. I would have though setting flags to say I want to go forwards or backwards would have made more sense then move the speed based on where the joystick is.

as for
" I'm okay with this result for now but, if anyone has any idea how adding or removing serial prints changes things let me know."

serial print may be acting as a tiny lag which can make some things seem to stay on when they are in fact being switched on and off really fast.

void forward()
{
     fspead = map(joystick[1], 510, 1023, 0, 255);
     analogWrite(speedpinA,fspead);//input a simulation value to set the speed
     analogWrite(speedpinB,fspead);
     digitalWrite(pinI4,HIGH);//turn DC Motor B move clockwise
     digitalWrite(pinI3,LOW);
     digitalWrite(pinI2,LOW);//turn DC Motor A move anticlockwise
     digitalWrite(pinI1,HIGH);
}
void backward()//
{
     bspead = map(joystick[1], 506, 0, 0, 255);
     analogWrite(speedpinA,bspead);//input a simulation value to set the speed
     analogWrite(speedpinB,bspead);
     digitalWrite(pinI4,LOW);//turn DC Motor B move anticlockwise
     digitalWrite(pinI3,HIGH);
     digitalWrite(pinI2,HIGH);//turn DC Motor A move clockwise
     digitalWrite(pinI1,LOW);
}

else if (joystick[1] <= 505 && joystick[0] >=509 && joystick[0] <=513) 
      {//j1 is smaller than 505
      //j0 is larger than 510 and lower than 514

        backward();
      
       if (joystick[1] < 510 && joystick[1] > 502 && joystick[0] >=510 && joystick[0] <=509)
      {  
        // j1 is smaller than 510 but larger than 502
      // but we had to be smaller than 505 to get to this point in the first place
      
      //j0 has to be bigger or equal than 510 and less or equal than 509 so it can only be 509 or 510
      //to get here it had to be between 509 and 513
        stop(); 
      }
      }
      
      //maybe im wrong but what im reading is if j0 is between 513 and 511 go backwards 
    //only if j1 is smaller or equals 502
    
      //if j0 is 509 or 510 and j1 is between 502 and 505 then go backwards 
        // for a millisecond then stop 
        
        
      else if (joystick[1] >= 510 && joystick[0] >=510 && joystick[0] <=509)
      {
        forward(); 
        if (joystick[1] < 510 && joystick[1] > 502 && joystick[0] >=510 && joystick[0] <=509)
      {  
        stop(); 
      } 
      }

dam so confused by the code now I cant even think straight to proof read what I added to the code.

maybe im reading this wrong so I made notes. The plan to me just seems flawed. I would have though setting flags to say I want to go forwards or backwards would have made more sense then move the speed based on where the joystick is.

That is what I am doing. I only gave the part of the code I was having trouble with.

as for
" I'm okay with this result for now but, if anyone has any idea how adding or removing serial prints changes things let me know."

serial print may be acting as a tiny lag which can make some things seem to stay on when they are in fact being switched on and off really fast.

Thanks, maybe. I'm not sure how that would affect the direction of the motor though. Adding the debugging seemed to fix the motor direction with out changing what pins are high and low.

void forward()

{
    fspead = map(joystick[1], 510, 1023, 0, 255);
    analogWrite(speedpinA,fspead);//input a simulation value to set the speed
    analogWrite(speedpinB,fspead);
    digitalWrite(pinI4,HIGH);//turn DC Motor B move clockwise
    digitalWrite(pinI3,LOW);
    digitalWrite(pinI2,LOW);//turn DC Motor A move anticlockwise
    digitalWrite(pinI1,HIGH);
}
void backward()//
{
    bspead = map(joystick[1], 506, 0, 0, 255);
    analogWrite(speedpinA,bspead);//input a simulation value to set the speed
    analogWrite(speedpinB,bspead);
    digitalWrite(pinI4,LOW);//turn DC Motor B move anticlockwise
    digitalWrite(pinI3,HIGH);
    digitalWrite(pinI2,HIGH);//turn DC Motor A move clockwise
    digitalWrite(pinI1,LOW);
}

else if (joystick[1] <= 505 && joystick[0] >=509 && joystick[0] <=513)
     {//j1 is smaller than 505
     //j0 is larger than 510 and lower than 514

backward();
     
      if (joystick[1] < 510 && joystick[1] > 502 && joystick[0] >=510 && joystick[0] <=509)
     {  
       // j1 is smaller than 510 but larger than 502
     // but we had to be smaller than 505 to get to this point in the first place
     
     //j0 has to be bigger or equal than 510 and less or equal than 509 so it can only be 509 or 510
     //to get here it had to be between 509 and 513
       stop();
     }
     }
     
     //maybe im wrong but what im reading is if j0 is between 513 and 511 go backwards
   //only if j1 is smaller or equals 502
   
     //if j0 is 509 or 510 and j1 is between 502 and 505 then go backwards
       // for a millisecond then stop
       
       
     else if (joystick[1] >= 510 && joystick[0] >=510 && joystick[0] <=509)
     {
       forward();
       if (joystick[1] < 510 && joystick[1] > 502 && joystick[0] >=510 && joystick[0] <=509)
     {  
       stop();
     }
     }

//maybe im wrong but what im reading is if j0 is between 513 and 511 go backwards
//only if j1 is smaller or equals 502

//if j0 is 509 or 510 and j1 is between 502 and 505 then go backwards
// for a millisecond then stop

Its... if j0 is between 509 and 510 AND j1 is greater than or equal to 510 then go forward at speed set by j1 as indicated by fspead map in forward function.

I have attached the sketch.

RemoteControlledCarMC.ino (8.68 KB)

wow its nearly impossible to read as theres no pattern

made some changes and added text for changes that need to be made for readability. Also added notes if I think the code is wrong

Remotetest.ino (9.3 KB)

Thanks for your help. Much more than I was expecting. I had a lot more wrong than I realized. Your version is much more readable, cleaner and more efficient. I will definitely be using this sketch as a guideline for the future. Thanks again!