Motor soft start and stop

Okay guys I am very new to Arduino and programing and am having a bit of a hard time trying to complete my project. I am attempting to run a linear actuator off of 2 momentary switches (one for up and one for down. The motor will be controlling a lid to a box that needs to open and close softly. So far I am only able to open an close the motor at a set speed am scratching my head on how to get the "soft" functions. any advice would be appreciated.
I am using an Uno with a BTS 7960

int RPWM = 10; 
int LPWM = 11; 
int downPin = 3; 
int upPin = 6;
int Speed = 150;


void setup() {
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(downPin, INPUT_PULLUP);
  pinMode(upPin, INPUT_PULLUP);
  
  }

void loop() 
{ 
 
  if(digitalRead(upPin)==LOW){ //check if extension button is pressed
    analogWrite(RPWM, 0);
    analogWrite(LPWM, Speed);
    
  } 

  else if(digitalRead(downPin)==LOW){ //check if retraction button is pressed
    analogWrite(RPWM, Speed);
    analogWrite(LPWM, 0);
    
  } 

  else{ //if no button is pushed, remain stationary
    analogWrite(RPWM, 0); 
    analogWrite(LPWM, 0);
  }
}

What are the "soft" functions?

I am not sure that’s there are soft functions. It is just my term for trying to describe what I am trying to do.
Go from 50%power to 100% over I second and then ramp from 100 to 50% over 2 secods

Do you mean duty cycle from 50% to 100%?

Then you can increment the duty cycle e.g. by +5 every 100ms.

But don't expect really smooth behavior, the motor will overcome friction and start abruptly at some duty cycle. Also the RPM will not be proportional to the duty cycle.

Yes that is what I am meaning. I am not looking for the smoothest of movement just can’t have the motor slam closed or open

Look up state machine for the states ramp-up, run, ramp-down and BlinkWithoutDelay example for the timed increments and decrements.

Do you think that I could just replace the “int Speed=“ with a code that does a simple ramp up and down. I need the same speed function for both buttons and in the same order.

Sorry for my ignorance I am very new to this. I took a bigger bite than I though on this project.

That's not sufficient, wrong approach.

Take a look at the example called "Fading" in the IDE code window.
file>examples>analog>Fading

It shows you how to ramp up and down the pwm duty cycle.
You should be able to adapt the levels and timing it to your motor.

okay so I have got another chance to take a look at the code. I can get the fade function to kind of work. However, it will only run when the switch is pressed and will ramp from 0-255 and then go back to zero and start the process again. I would like to only push the button once and then have the motor ramp from 0-255 and stay there for a pre determined amount of time. What do i need to change to do this.

int RPWM = 10; 
int LPWM = 11; 
int downPin = 3; 
int upPin = 6;
int Start = 0;
int Speed = 100;
int inc = 1;


unsigned long startTime = 0;
unsigned long interval = 1000;


void setup() {
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(downPin, INPUT_PULLUP);
  pinMode(upPin, INPUT_PULLUP);
  Serial.begin(9600);
  }

void loop(){ 

 
  if(digitalRead(upPin)==LOW){ //check if extension button is pressed
    analogWrite(RPWM, 0);
    analogWrite(LPWM, Speed);
    startTime = millis();
    Speed = Speed + inc; 
    Serial.println("Extending");
   
   
   if (millis() - startTime >= interval){
      analogWrite (RPWM, 0);
      analogWrite ( LPWM, 0);
   }
  }
 else if(digitalRead(downPin)==LOW){ //check if retraction button is pressed
    analogWrite(RPWM, Speed);
    analogWrite(LPWM, 0);
    startTime= millis ();
    Speed = Speed + inc;
    Serial.println("Retracting"); 
 
  
  if (millis() - startTime >= interval){
      analogWrite (RPWM, 0);
      analogWrite ( LPWM, 0);
 
    }  
 }
  else{ //if no button is pushed, remain stationary
    analogWrite(RPWM, 0); 
    analogWrite(LPWM, 0);
  }
}

I would like to only push the button once and then have the motor ramp from 0-255 and stay there for a pre determined amount of time. What do i need to change to do this

It was suggested earlier that you could use a state machine to control the operations. An alternative which might be easier to understand is to use boolean control variables to enable operations. This example uses them to set retracting and extending true or false

This example ramps from 100 to 250 over 750 ms and runs for a total of 1 second. You can easily adjust the ramp up and down increments and timings and total run time as you wish.

int RPWM = 10;
int LPWM = 11;
int downPin = 3;
int upPin = 6;
int Start = 0;
int Speed = 100; //starting pwm value
int inc = 1;

unsigned long startTime = 0;
unsigned long rampInterval = 5; //raise or lower pwm value every 5 ms

unsigned int motorRunningTime = 1000; //total running time in milliseconds
unsigned int cycleCount = 0; //number of ramp intervals
boolean extending = false;
boolean retracting = false;


void setup() {
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(downPin, INPUT_PULLUP);
  pinMode(upPin, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {

  if (digitalRead(upPin) == LOW and extending == false) {
    analogWrite(RPWM, 0);
    analogWrite(LPWM, Speed);
    startTime = millis();
    Serial.println("Extending");
    extending = true;
  }

  if (extending and millis() - startTime >= rampInterval)
  {
    cycleCount += 1;
    startTime += rampInterval;
    if (Speed < 250) //limit max speed
      Speed = Speed + inc;
    analogWrite(LPWM, Speed);

    if (cycleCount == motorRunningTime / rampInterval) //count == 200 1 second of extending
    {
      analogWrite (RPWM, 0);
      analogWrite (LPWM, 0);
      extending = false;
      Speed = 100; //reset starting speed
      cycleCount = 0;//reset cycle count
    }
  }

  if (digitalRead(downPin) == LOW and retracting == false) {
    analogWrite(RPWM, Speed);
    analogWrite(LPWM, 0);
    startTime = millis ();
    Serial.println("Retracting");
    retracting = true;
  }

  if (retracting and millis() - startTime >= rampInterval) {
    cycleCount += 1;
    startTime = millis();
    if (Speed < 250) //limit max speed
      Speed = Speed + inc;
    analogWrite(RPWM, Speed);

    if (cycleCount == motorRunningTime / rampInterval)
    {
      analogWrite (RPWM, 0);
      analogWrite (LPWM, 0);
      retracting = false;
      Speed = 100; //reset starting speed
      cycleCount = 0;
    }
  }
}

Thank you! I was hoping to atl least get my motor moving the way that I wanted before I attempted to tackle the state machine. Every time I look into it my eyes start to cross. But I am slowly improving, I think…

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