Controlling linear actuators with PCA9685

Hey, everyone! Looking for some sage wisdom on a project I'm trying to figure out.

Short version:
I'm attempting to control a 12v linear actuator with a PWM9685. I can get it to power out the actuator arm once, but I can't get it to retract, control the timing...nada.

Here's the code I got from the interwebs, but I get the sense that it's just powering the actuator, not controlling it; seems a little complicated for "run it out", y'know?

//Libraries
#include <Wire.h>//https://www.arduino.cc/en/reference/wire
#include <Adafruit_PWMServoDriver.h>//https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
//Constants
#define nbPCAServo 16
//Parameters
int MIN_IMP [nbPCAServo] ={500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500};
int MAX_IMP [nbPCAServo] ={2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500};
int MIN_ANG [nbPCAServo] ={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int MAX_ANG [nbPCAServo] ={180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180};
//Objects
Adafruit_PWMServoDriver pca= Adafruit_PWMServoDriver(0x40);
void setup(){
//Init Serial USB
Serial.begin(9600);
Serial.println(F("Initialize System"));
pca.begin();
pca.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
}
void loop(){
pcaScenario();
}
void pcaScenario(){/* function pcaScenario */
////Scenario to test servomotors controlled by PCA9685 I2C Module
for (int i=0; i<nbPCAServo; i++) {
Serial.print("Servo");
Serial.println(i);
//int middleVal=((MAX_IMP[i]+MIN_IMP[i])/2)/20000*4096; // conversion µs to pwmval
//pca.setPWM(i,0,middleVal);
for(int pos=(MAX_IMP[i]+MIN_IMP[i])/2;pos<MAX_IMP[i];pos+=10){
pca.writeMicroseconds(i,pos);delay(10);
}
for(int pos=MAX_IMP[i];pos>MIN_IMP[i];pos-=10){
pca.writeMicroseconds(i,pos);delay(10);
}
for(int pos=MIN_IMP[i];pos<(MAX_IMP[i]+MIN_IMP[i])/2;pos+=10){
pca.writeMicroseconds(i,pos);delay(10);
}
pca.setPin(i,0,true); // deactivate pin i
}
}
int jointToImp(double x,int i){/* function jointToImp */
////Convert joint angle into pwm command value
int imp=(x - MIN_ANG[i]) * (MAX_IMP[i]-MIN_IMP[i]) / (MAX_ANG[i]-MIN_ANG[i]) + MIN_IMP[i];
imp=max(imp,MIN_IMP[i]);
imp=min(imp,MAX_IMP[i]);
return imp;
}

My wiring is all correct (double- and triple-checked), so I'm kind of at a loss on how to proceed. Thoughts?

Thanks in advance!
Jordan G.

Please post schematics and links to the datasheets of the actuator and the actuator.

1 Like

@Railroader reminded me to post schematics and datasheets, so here's what I've got:

Actuator:
Stroke Length:1''
Input Voltage:12 VDC
Maximum Load:4.5lbs (20N)
Travel Speed :0.6in/sec(15mm/sec)
Duty Cycle :10%
Limit Switches:Pre-installed
Gears:Lubricated Metal Gears
Weather Resistance:IP66 Rated(suitable for outdoor use)
Material :6061 Aluminum Exterior

Wiring schematic (replace the servo with an actuator wired to power and ground on the PWM):

Need anything else to get inside my process, @Railroader? :grinning:

Post a link to the actuator.

What makes you think it is controlled like a servo? Most are not.

See? THIS is the kind of feedback I come here for. :stuck_out_tongue:

I figured that since the arm is moved BY a servo, I could control it LIKE a servo. Here's the link:

That link goes to a sales site. Post link to the electrical information, how that unit is running, its connections etc.

essential info.

It seems to literally just have a power and ground. I'm able to actuate it with direct 12vDC.

Not sure I can. That link is where I bought it, and it's all the info I've got.

I know it's got a power wire and a ground, and I've successfully run it with direct 12v DC current. I'm just looking to essentially apply that current on demand, in a pattern I've chosen beforehand, via Arduino.

Sorry I can't provide more info; I'm very much a hobbyist engineer.

Bingo, so it's a 2-terminal connection; rotates one way with +12 on one wire, 0V on the other, rotates the other way with 0 on the first wire, +12 on the second.

Your Arduino is not able to drive that without a suitable driver circuit.

I guess, yeah. Black to black, red to red it actuates out; reverse those, and it pulls back in.

That's why I used the PWM; I've used it before to move servos forward and backward on command. I assumed it would work for this, as it takes in a 12V dc current.

Or, using a DPDT relay as a reverser. Do you require speed control, or just end-to-end as fast as possible?

No speed control; being able to choose the range of actuation would be good, though, for my purposes. Since I know the speed of the actuator, that would equate to "apply 12V to the actuator's forward progression for this long, and then apply it in reverse for this long".

No, because a servo has an internal circuit that translates pulse width from the Arduino into position. This new device is not a servo.
You can get solid state drivers, or use a DPDT relay. If this sounds like it's beyond your technical prowess, people here will help, but you'll have to answer more questions. I'm leaving now, work to do.
C

1 Like

Same. I appreciate the info, though, thanks a million!

Then you need a standard, bi-directonal motor driver, capable of handling the start/stall current (typically 5-10X the free running current). Pololu has the best selection.

I see the product page has very little useful information. Use your multimeter to measure the free running current, and multiply that by 10 to pick a motor driver and a power supply. A rough guess might be 12V at 3 Amperes, minimum. More current would be better.

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