Ramp speed of DC motor with PWM and joystick input

I am working on a project where I use radio communication with the nrf24L101 modules to transmit joystick data to control 2 DC motors.

The type of joystick I will be using is an arcade joystick as pictured below.
image

Unlike the small analog joysticks which work using potentiometers, this one works off 4 switches so it can send digital signals. Therefore I can't use PWM to slow and speed up the motors corresponding to the joystick input. Instead what I want to do is to increase the motor speed depending on how long the joystick is held.

Basically in the logic of the code I read the axisdata array which contains all the HIGH and LOW signals for the switches from the transmitter side. If a LOW signal is detected I want to run the for loop which ramps up the motors, but as soon as the signal is HIGH, it should exit the for loop and stop the motors. The problem I am having is with the exiting the for loop part, and I think it has something to do with how I nest it in the if statement but I'm not too sure.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>


int axisdata[8];

RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";


int dirA = 7;
int speedA = 6;
int dirB = 4;
int speedB = 5;

void setup(){

pinMode(dirA, OUTPUT);
pinMode(speedA, OUTPUT);
pinMode(dirB, OUTPUT);
pinMode(speedB, OUTPUT);


 Serial.begin(9600);
 radio.begin();
 //Serial.println("TEST nRF24L01+ receiver");
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  //radio.setChannel(76);
 
}

void loop(){

if (radio.available()) {
    //Serial.println("TEST nRF24L01+ receiver");
      radio.read(&axisdata, sizeof(axisdata));

  } if (axisdata[0] == LOW && axisdata[4] == LOW){
      //for (int i = 0; i < 255; i++){
       Serial.print("Up switch: ");
  //Serial.println(axisdata[0]);
      analogWrite(speedA, 100);
      digitalWrite(dirA, HIGH);
      analogWrite(speedB, 100);
      digitalWrite(dirB, HIGH);
      //delay(20);
  

  } else if (axisdata[1] == LOW && axisdata[5] == LOW){
      //for (int i = 0; i < 255; i++){
      Serial.print("Down switch: ");
  //Serial.println(axisdata[1]);
      analogWrite(speedA, 100);
      digitalWrite(dirA, LOW);
      analogWrite(speedB, 100);
      digitalWrite(dirB, LOW);
      //delay(20);
      
      
  } else if (axisdata[0] == LOW && axisdata[5] == LOW){
      analogWrite(speedA, 100);
      digitalWrite(dirA, HIGH);
      analogWrite(speedB, 100);
      digitalWrite(dirB, LOW);

  } else if (axisdata[1] == LOW && axisdata[4] == LOW){
      analogWrite(speedA, 100);
      digitalWrite(dirA, LOW);
      analogWrite(speedB, 100);
      digitalWrite(dirB, HIGH);

  } else if (axisdata[0] == LOW){
      analogWrite(speedA, 100);
      digitalWrite(dirA, HIGH);
      
  } else if (axisdata[4] == LOW){
      analogWrite(speedB, 100);
      digitalWrite(dirB, HIGH);

  } else if (axisdata[1] == LOW){
      analogWrite(speedA, 100);
      digitalWrite(dirA, LOW);
      
  } else if (axisdata[5] == LOW){
      analogWrite(speedB, 100);
      digitalWrite(dirB, LOW);


  } else if(axisdata[0] == HIGH && axisdata[1] == HIGH){
    analogWrite(speedA, 0);
    analogWrite(speedB, 0);
    
  } else{
    Serial.println("Fail");
    
  }

}

Add 2 variables for the instantaneous speed of each motor. When, for example, the condition for increasing the speed of motor is met, if its speed is less than the maximum, then increase it. When you need to decrease the speed you decrement the variable if it is greater than 0. That's how you do it, not with a 'for' loop and you can use 'delay ()' to determine how fast to accelerate/decelerate each motor but it might be good to remove 'delay ()' completely and you use 'millis ()' for non blocking program.

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