Linear actuator control test code

I have a 12v linear actuator that takes a 5v pwm as the control input and outputs a position in the same way.

I've written this small test program. The actuator moves to 3 positions but at each position it moves a little (hunts) and sometimes the reported value from the actuator doesnt seem correct. The actuator is actuator.
Appreciate any ideas.

//initialise button and output states
int Act1ValuePin = A0;    // 0-1023 range. select the input pin for the Actuator position pot select the pin for the LED
int Act1Value = 0;  // variable to store the value coming from the Actuator
int Act2ValuePin = A1;    // 0-1023 range. select the input pin for the Actuator position pot select the pin for the LED
int Act2Value = 0;  // variable to store the value coming from the Actuator
int Act1MotorPin = 3;//PWM outputs. 0-255 range, 25% =64, 50% = 127, 75% = 191
int Act2MotorPin = 5;//PWM outputs
int LastrowNum; // recorded last row number if arrays dont match

 int Act1opState = 255; //neutral
 int Act2opState = 127; //neutral

void setup() {
 
  // declare the Act1MotorPins as an OUTPUT:
  // declare the Act1ValuePins as an INPUT:
  pinMode(Act1MotorPin, OUTPUT);// 
  pinMode(Act2MotorPin, OUTPUT);

  pinMode(Act1ValuePin, INPUT_PULLUP);//
  pinMode(Act2ValuePin, INPUT_PULLUP);


 
   Serial.begin(9600);
 }

 void loop (){ 
Act1opState = 64;//reverse position. 0-255
analogWrite (Act1MotorPin,Act1opState);
Serial.println("Act1opState " );
Serial.println(Act1opState );
delay (500);
Act1Value = analogRead (Act1ValuePin);//0-1023
Serial.println("Act1Value " );
Serial.println(Act1Value );
delay (500);

Act1opState = 127;//reverse position
analogWrite (Act1MotorPin,Act1opState);
Serial.println("Act1opState " );
Serial.println(Act1opState );
delay (500);
Act1Value = analogRead (Act1ValuePin);
Serial.println("Act1Value " );
Serial.println(Act1Value );
delay (500);

Act1opState = 230;//reverse position
analogWrite (Act1MotorPin,Act1opState);
Serial.println("Act1opState " );
Serial.println(Act1opState );
delay (500);
Act1Value =analogRead (Act1ValuePin);
Serial.println("Act1Value " );
Serial.println(Act1Value );
delay (500);
   }  

Please state which Arduino you are using, exactly how the actuator is wired, and post the specs of the 12V power supply.

If you are using the actuator 5V PWM input, the Arduino PWM output may not match the frequency requirement of 1 kHz. In that case it is better to use the Arduino servo library, and the RC servo input.

The data sheet calls for a 1 kHz PWM signal, at least one of the PWM pins' frequency is close enough, make sure you use one of those.

Then write and delay, as you are doing. If it hunts or otherwise isn't motionless, it hunts, that's the actuator no your program.

How are you reading the position?

a7

Servo is PWM, but at 50 Hz with a duty cycle that goes from 1000 us to 2000 us in a 20 ms window.

It looks like a choice to be made when purchasing, not something you can opt for later.

I see the position feedback output, nice.

@kpg which variant do you have, what is the full part number?

a7

Thanks guys.
Its the LIR-50-50-12I

datasheet

My pins on my UNO are;
1 - Green – NC
2 - Blue – Voltage input signal (0–5V interface mode). PWM from Arduino pin 3
3 - Purple – Position Feedback signal (Proportional 0–3.3 V). To analog A0 input on arduino
4 - White – NC
5 - Red – Power (r 12V model)
6 - Black – Ground

12v supply is a lab adjustable PSU

The PWM pin does not output a steady DC voltage, which is what the voltage input expects. To control the actuator with the blue voltage input, use a steady, regulated DC voltage of 0 to 5V (a potentiometer voltage divider from 5V source is OK).

Have a closer look at the actuator data sheet, -I model.

Edit: the actuator may also accept a 1 KHz PWM signal on the blue lead (data sheet is not entirely clear), but Arduino pin 3 outputs 490 Hz PWM.

I did. I can't seem to cut and paste, but it looks like the model @kpg has is fairly intelligent in that it self configures itself by waiting to see what is being fed it as a control signal.

Therefore I think that 1 kHz real PWM should interest it in complying to that control method.

I gotta say the data sheet coukd be clearer on these matters.

On an UNO, PWM pins 5 and 6 are 980 Hz, which should be close enough.

a7

I changed it to pin 6 and it seems slightly better (still hunts a bit then stops at each position) but the feed back value is often still out. Could this be a function of the 3.3v return level?

I changed the program to feed it 100 and 255 at each step and it gives this.


Act1opState 
100 
Act1Value 
1023 
Act1opState 
255 
Act1Value 
1023 
Act1opState 
100 
Act1Value 
978 
Act1opState 
255 
Act1Value 
1023 

I recommend to use either a steady state DC voltage on the blue input wire, or the RC servo library input to the white wire to control the actuator.

Note for RC servo input:

If the motion of the actuator, or of other servos
in your system, seems erratic, place a 1–4Ξ© resistor in series
with the actuator’s red V+ lead wire.

That should not be a problem. I can't say that you'd need to do anything other than wire that signal directly to the analog input. You must have a common ground to have gotten this far, I think.

3 - Purple – Position Feedback signal (Proportional 0–3.3 V)

So you should see values from 0 to about 676.

You may do better with the other ways of controlling it, but as I read the data sheet using an analog voltage 0 .. 5 volts is without the capability of the unit in hand.

Hunting "a bit" then stopping is a typical control system behaviour. If you wrote your own control loop, you might be able to tune the parameters that inform the chosen algorithm (PID, e.g.) to minimise such undesired motion.

I suggest you try it with something like the intended load to see if the control system does better. The tuning you can't do may be suboptimal with an unloaded actuator.

a7

Thank you.

Its part of a much bigger gearbox program and I am using arrays to drive the PWM output based on the feedback number so I dont want to use an analog control (DC voltage).
I will try it loaded.

Good point on the 3.3v and the 676 but if you look at my serial monitor results it seems random and scales above 676.

Remove the input_pullup from your analog pin.

Why not use "4 - White – RC input signal (RC-servo compatible mode)"? Better resolution and stability.

I've not worked with the servo libraries. Anything special i need to know? Thanks

Give me a little while to fetch a test program.

Thank you. I will try that.
It might well work better under load so I think my biggest problem is working out why the feedback numbers seem to vary for the same input.

Connect white wire to pin 9 and try this test program (compiles but UNTESTED).

/*
 Try this test sketch with the Servo library to see how your
 servo responds to different settings, type a position
 (544 to 2400) in the top of serial monitor and hit [ENTER],
 start at 1472) and work your way toward zero (544) 50 micros
 at a time,then toward 2400. 
*/
#include <Servo.h>
Servo servo;
unsigned long timer, interval = 400;
int Act1ValuePin = A0;

void setup() {
  // initialize serial:
  Serial.begin(9600); // set serial monitor baud rate to match
                      // set serial monitor line ending to "NewLine"
  servo.write(1472); // center
  servo.attach(9);
  prntIt();
}

void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {

    // look for the next valid integer in the incoming serial stream:
    int pos = Serial.parseInt();
    if(Serial.read() == '\n'){} //skip 1 second delay
    pos = constrain(pos, 544, 2400);
    servo.writeMicroseconds(pos);
    prntIt();
  }
  if(millis() - timer > interval)
  {
    timer += interval;
    Serial.print("adcValue  ");
    Serial.println(analogRead(Act1ValuePin));
  }
}
void prntIt()
{
  Serial.print("microseconds =  ");
  Serial.println(servo.readMicroseconds());
}  

Also, you might try connecting the AREF pin to the Arduino's 3V3 pin and in the setup() function add:

analogReference(EXTERNAL);

That should give you the full 0 ~ 1023 ADC values.

As a simple try, I put the analogReference (EXTERNAL); in setup and connected ARef to 3.3v.

It didnt seem to alter the input scaling much but it did peak around 800 (not 1023 as expected).

I've also noticed that the speed (delay I add) affects the reading accuracy. In my application I need it to respond and read quickly (500ms).

I've improved the actuator stability at each point by adding a ground from the board to the PSU.

I cant disconnect the PC USB to see if that improves more because I cant see the serial monitor then and wont be able to see the feedback values.

So why would it be so slow at reporting a position change?

OK, seems to be fairly reliable now.

So the summary is;

The actuator mentioned will run with a PWM using the near 1khz O/P as on pin 6.

I ran the external ref function and connected 3.3v to Aref. That almost scales the input to 1023 and ran it to A0 and the actuator detects the right setup nicely. No need for servo code.

Even running short delays it is fairly repeatable with minimal hunting PROVIDING you have good earthing all round.

So good actuator. Simple test code. I will now move it to the more complex gearbox control code and see what gives. Thanks for the help guys! :grinning:

1 Like