Using an arduino to control a linear actuator

Hello,

I'm new to using Arduino. I'm using ElapsedMillis library to control my linear actuator but it's not working properly. Any help would be much appreciated.

I'm trying to move the actuator forward by 300 mm and backward by 100 mm. The speed of the linear actuator is 30mm/s

#include <elapsedMillis.h>

const int relay1 = 2;
const int relay2 = 3;
uint32_t period;
int func_variable;

void setup()
{

int func_variable = 0;
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
Serial.begin(9600);

}

void extendActuator()

{
//Serial.println("extendActuator");
digitalWrite(relay1, HIGH);
digitalWrite(relay2, LOW);
}

void retractActuator()

{
//Serial.println("retractActuator");
digitalWrite(relay1, LOW);
digitalWrite(relay2, HIGH);
}

void stopActuator()

{
//Serial.println("stopActuator");
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
}

void moveFixedDistance(int distance)
{
const int actuator_speed = 30;
const int reqtime = distance/30;
uint32_t period = reqtime * 1000;
elapsedMillis timeElapsed = 0;
while(timeElapsed < period )
{
extendActuator();
}

delay(5000);
}

void moveFixedDistanceDown(int distance)
{
const int actuator_speed = 30;
const int reqtime = distance/30;
uint32_t newperiod = reqtime * 1000;

elapsedMillis newtimeElapsed = 0;
while(newtimeElapsed < newperiod )
{
retractActuator();
}

delay(10000);
}

void singleFunction(int distance)
{
if( distance > 0)
{
moveFixedDistance((distance));
}

else
{
moveFixedDistanceDown(abs(distance));
}

}

void loop()

{
if( func_variable == 0)
{
func_variable++ ;
singleFunction(300);
}

if( func_variable == 1 )
{
func_variable++;
singleFunction(-100);
}

delay(15000);
}

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

What model Arduino are you using?
Can you post link to spec/data for the actuator please?

Thanks.. Tom... :slight_smile:

it's not working properly

What does it do ?

I'm trying to move the actuator forward by 300 mm and backward by 100 mm. The speed of the linear actuator is 30mm/s

So you need to move it in one direction for 10 seconds and the other way for 3.3 seconds. What should happen after that ?

Your code looks very complicated for such a simple requirement. Does the Arduino need to be doing anything else at the same time as controlling the actuator ? If not then a couple of delay()s of the appropriate length would do what you want. If the free running of loop() must not be blocked because of the need to do other things then the BlinkWithoutDelay principle using millis() will do what you want. No need for a library for such a simple requirement and I am not sure that you are using it correctly anyway.

Hi,
How accurate do you want the 300mm and 100mm movements, because the actuator is not going to stop instantly.
Also when you are starting, has to start form zero speed and get to 30mm/sec, this takes time.

Does your actuator have a position feedback output.

Tom... :slight_smile:

One problem is that you tell it to start moving but you don't tell it to stop. It will keep moving until you tell it to stop.

Here is a simplified version:

const int actuator_speed = 30;  //  mm/S


const int relay1 = 2;
const int relay2 = 3;


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


  stopActuator();
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);

  move_millimeters(300);
  stopActuator();


  delay(10000);


  move_millimeters(-100);
  stopActuator();


  delay(10000);
}

void extendActuator()
{
  //Serial.println("extendActuator");
  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, LOW);
}


void retractActuator()
{
  //Serial.println("retractActuator");
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, HIGH);
}


void stopActuator()
{
  //Serial.println("stopActuator");
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
}


void move_millimeters(int distance)
{
  if (distance > 0)
  {
    extendActuator();
    delay((distance * 1000) / actuator_speed);
  }
  else
  {
    retractActuator();
    delay((-distance * 1000) / actuator_speed);
  }
}


void loop()
{
  delay(15000);
}

There also the potential of accumulated positioning errors.
Hopefully, the actuator motor stops at a physical limit, then subsequent movement will be referenced from that.

Either way, you may need a limit sensor (switch or onto) to determine the absolute position (or calibration) before moving again.