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.
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
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).
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.
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.
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.
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.
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());
}
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!