RFC: Using a linear actuator.

DrG

Active Member
A close friend of mine repurposed an old rabbit hutch that he had built into a greenhouse of sorts. I have never actually seen it in person, but I built a simple fan controller with an Arduino UNO, a relay and a DS1820 sensor. LCD and a few buttons and he can set the on:/Off temperatures. It works well and he likes it a lot. It was a fun little project.

We also talked about an actuator to open the ceiling. I have never used an actuator, but it sounds like fun so I got one and have been playing around with it a bit. I know many on here have a lot of experience with such devices and that is why I am writing - with a few specific questions but also to get some sanity check comments.

Here is a pic of the 'hutchouse'.

The ceiling is NOT raised in the pic. The high side of the ceiling can be raised about 8" - that is the task. The hutch stands on legs ~3' high. The body is about 60"" X 30". He said that he thought that the ceiling weighed no more than 25-30 lbs. The blue lines are drawn in to represent additional boards to be added to support the actuator, which would be mounted inside. One bracket on the upright post and the other on the ceiling frame. There is a small amount of floor space which houses the current fan controller mentioned previously and can accomodate the additional PS and circuitry..

I purchased this actuator https://www.ebay.com/itm/6-Stroke-Linear-Actuator-DC12V-Electric-Motor-900N-Water-proof-Heavy-Duty-150mm/392124425618?ssPageName=STRK:MEBIDX:IT&_trksid=p2060353.m2749.l2649

I can't conveniently duplicate the specs in the message but they are listed in the advert.

I am using this run-of-the-mill dual relay and an UNO for testing. These are LOW operate and here is the schematic - usual stuff there and I have used these or similar many times. I'm testing using my bench PS.

Here is the schematic I am using to control the actuator. I might have come up with this myself but I also might have seen it somewhere, but can't remember. It is pretty simple.

This circuit works fine for testing using simple functions like those below. It will get more complicated.

C-like:
void RelayOff(){
digitalWrite(IN1, HIGH);
digitalWrite(IN2, HIGH);
}
void RelayExtend(){
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
}

void RelayContract(){
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
}
In my testing, it takes ~14-15 sec for full extension or retraction (basically consistent with the specs). Will that speed change significantly under load? I have it my end to have two or three levels of opening - 2", 4", 6" and to do that by timing, if possible. For the smallest level, I could see a simple read switch and magnet run to an input port to verify it has been raised, but with no position feedback (those cost a whole lot), I don't have any clever ideas (yet) about accomplishing someting like that.

There are limit switches on both ends and the current is cutoff as expected when they are hit. What is the easiest way to verify that or detect a failure. IOW, how can I tap into the 12V line and run it to an input port? Would an opto with resistor work? If yes, where to tap? I am not an EE (if you have not guessed), but I should be able to figure it out...eventually.

The unit claims 900N (225lb) load capacity. That should mange raising one end of a 40lb ceiling - right? Or am I missing something fundamental (again)?

The IP54 rating is far from 'waterproof'. I looked it up and it seemed to be saying it could hold up to a little water spray. Since it would be on the inside, I am hoping that will suffice - I may need to build in a rain detector.

The duty cycle is 25%, so I know that if I operate it for 10 secs, I will not operate it for another 30 sec. That is no big deal programming-wise.

This puzzles me a lot - I see a max current draw of 360-370 mA. The specs say that rated current=3A. I am operating it with no load. Can I expect the draw to jump under load?

All this is a lot of "thinking out loud", but I will appreciate any comments - even laughter.

Pommie

Well-Known Member
Sounds like an interesting project.
Expect the operating time and current to increase (decrease on closing) when under load. Have you considered using a potentiometer to measure the position? One thing to be careful of is the closed position is hit before the limit switch operates, can you arrange it so the actuator pushes the lid open only. This also prevents small fingers etc from being squashed by the 225lb.

Mike.

DrG

Active Member
Sounds like an interesting project.
Expect the operating time and current to increase (decrease on closing) when under load. Have you considered using a potentiometer to measure the position? One thing to be careful of is the closed position is hit before the limit switch operates, can you arrange it so the actuator pushes the lid open only. This also prevents small fingers etc from being squashed by the 225lb.

Mike.
Copy that about the current and speed.

The safety issue is legitimate and I thought about it because that force is substantial. One distinct possibility is simply not make it auto-engage under program control. As it is now, he stretches or climbs up there, lifts it with one hand while propping it open with something...and then reverse it to close. Suppose I made it automatic but under operator action only. IOW, raise and lower buttons He would have to sit there holding a button pressed for up to 15 secs but he could also adjust it to his liking. Even raise, lower and stop buttons if one wanted to avoid having to hold a button pressed.

DrG

Active Member
I had read that thread previously. I looked again and especially the pdf that you had attached. That circuit shows the bridge rectifier to detect when the motor is running. Thanks.

My question was about "playing with the limit switches". Those limit switches are internal to the unit and I see no way to adjust them - that is what I was getting at. Of course, adding external limit switches is a different matter. Edited to add: Benn looking at articles like this one https://www.venturemfgco.com/blog/learn-how-to-adjust-limit-switches-of-your-linear-actuator/ but I am not crazy about going into the unit. Thanks again.

Edited again: Naturally, curiosity got the better of me:

Nothing adjustable screamed out at me. Maybe you need one that cost more than \$30 for that. BTW: I was mindful to get that cheap little gasket all the way on when I tightened it back up, but I could see that the seam night be a good place to add some sealant for additional water resistance.

Last edited:

DrG

Active Member
So, I spoke with my friend today - good talk. I think the plan going forward is to make a control circuit, probably using a pro-mini. It will have three buttons and an LED and the relay board as shown previously.

A button for up (extend), a button for down (retract) and a third button for an over-ride. Press and hold buttons one or two to operate the actuator for as long as it is held (of course the limit switches are in effect). After an operation, I will track operating time and the LED will illuminate RED and when 3X the operating time has elapsed, it will illuminate GREEN, signaling ready to go up or down again.

If the over ride button is pressed and held along with either the up or down buttons, the 25% duty cycle 'rule' will be ignored. This, so that if a situation requiring an urgent need to operate the actuator arises, one can do so without waiting.

He will need to add some boards to the frame to accompany mounting the actuator and, he wants to build a port under the floor (the floor is waterproof currently and that is where the fan controller is at - although in its own enclosure).

In this way, he will be able to effortlessly raise and lower the ceiling as he wants, but always while he is present.

Hopefully, we will get all this together before fall, to have a lengthy testing period. We can then discuss if and what kind of further automation might be desirable to have for next spring.

Thanks for the comments and please make any additional comments if you feel like doing so. I do appreciate them and it is a help to run these matters by folks with more experience with these devices than I have.

KeepItSimpleStupid

Well-Known Member
I would not use the internal limit switches because they generally don't use dynamic braking. The actuator will overrun.
I think the internal limits are for safety.

Some actuators have potentiometer feedback or pulse feedback (switch or optical) - Satelite dishes.

The way of detecting motor running that I put together won;t work with the internal limits.

Siemens makes a pocket door controller (SIDOOR) that has useful info. I have a website for a company that makes a hatch controller. Again, good ideas, Everything seems to fall under "chicken coop door". The topic comes up a lot.

For something fancy like a car window, it does have a learn mode. That's where it finds a stop and counts. It also monitors current during thta up/down calibration cycle. That's how it can detect pinch using position and current.

UP/Down makes sense here, BUT consider the following one button operation:

If at a limit, a momentary push goes opposite the limit.
If moving, a momentary push stops and memorizes direction.
If stopped continue in the memorized direction.
A double-click, stops, pauses and reverses direction.

Probably not suitable, but it's another way.

When you look at the limit circuitry, no relays are engaged when at a limit or stopped. Both engaged is also stop/brake.

You do have fwd/rev/brake and coast as options in some controllers.

ronsimpson

Well-Known Member
I would not use the internal limit switches because they generally don't use dynamic braking. The actuator will overrun.
I have some very old linear actuators with internal switches. They have worked for 15 years. The doors are large and in the roof.
"overrun" they might run for a very small amount after the switches open. But that is compensated for. One switch stops the door well closed. The other stops when the doors are well open but not quite up against the limits. It is probably true there is 1mm of delay to get the motor stopped. Even if there was 1cm of delay then you simple adjust the switches to get the doors to stop where they should.
--edited--
Green house roof vents. 120vac controlled by a thermostat.

KeepItSimpleStupid

Well-Known Member
Thanks. I think linear actuators are poor;y understood.

DrG

Active Member
Just a little update on this project...So, my friend is stopping by tomorrow, and I thought I better get some demo together for him to check out. We will shoot the breeze, grab a Bento box and maybe go take a hike and some nature shots with our cameras - there is a preserve not too far away. I was just reflecting on this as I was getting some code and demo stuff together (seniors do a lot of reflecting ). I have know this guy (and his family) for some 50 years. Starting in Junior High, well before he was married and had children and so on and so forth. I have a couple of close friends like that. If I meet somebody tomorrow, it is not possible for me to know that person as long as I have known these close friends. I really value that (seniors also take stock of what they have more than non-seniors, I think).

Anyways, I moved it off of an UNO and on to a cheap pro-mini clone.

Slapped together three switches for; Up, Down and Over-ride (see earlier text). Everything works fine. I need to dig up and old laptop PS and run the actuator and Promini off of that 12V (hopefully without any PS noise issues) and then slap the whole thing in a box of some sort.

The code is plenty simple

C-like:
//---------------------------------------------------------------------------
// This software is presented strictly as is with no warranty whatsoever.
// Use it at your own risk.
//
// Simple push button operation of a linear actuator.
// Uses a 2 Relay Module wired in a polarity-reversal configuration
// to operate a 12V linear actuator.
// Uses 7 GPIO. Two for relays, 2 for bi-color LED and 3 for switch
// input (up, down, manual over-ride)
//
//=======================================================================
//   Operation Table: Note, relays operate with digital LOW
//   RY1      RY2
//   LOW      LOW   NOP (Load= +12V, +12V) <-- No operation
//   HIGH     HIGH  NOP (Load=   0V,   0V) <-- Normal off mode
//   LOW      HIGH   OP (Load= +12V,   0V) <-- Extend actuator
//   HIGH     LOW    OP (Load=   0V, +12V) <-- Contract actuator
//=======================================================================

// #defines

// Relay GPIO connections
#define IN1 5
#define IN2 6

// switches
#define UpButton A0
#define DownButton A1
#define MOButton A2
#define BPRESSED 1
#define BNOTPRESSED 0

// bi-color LED
#define LED1 10  // moved from A3
#define LED2 11  // moved from A4
#define Red 1
#define Green 2
#define Off 3

// Globals
byte DebounceTime = 25; // ms

// duration accumulators for for duty cycle restriction
unsigned long OPelapsed = 0;
unsigned long NOPelapsed = 0;
unsigned long startNOPtime = 0;

// bi-color led
byte LEDRed = 1;
byte LEDGreen = 2;
byte LEDoff = 3;

// functions
void RelayOff(void);
void RelayExtend(void);
void RelayExtendMO(void);
void RelayContract(void);
void RelayContractMO(void);
void LED(byte);
//____________________________________________________________________
void setup() {
// note: The relays operate when LOW but do not operate on power up
pinMode(IN1, OUTPUT);
digitalWrite(IN1, HIGH);
pinMode(IN2, OUTPUT);
digitalWrite(IN2, HIGH);
pinMode(UpButton, INPUT);     // Up button
pinMode(DownButton, INPUT);   // Down button
pinMode(MOButton, INPUT);     // MO button
pinMode(LED1, OUTPUT);        // bicolor LED
pinMode(LED2, OUTPUT);        // bicolor LED
LED(Green);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, HIGH);
Serial.begin(9600);
Serial.println("   ***  Dual Relay Module Test ***");
Serial.println("  [polarity-reversal configuration]");
Serial.println();
}
//____________________________________________________________________
void loop() {
unsigned long startOPtime = 0, endOPtime = 0, elapsedOPtime = 0;

// if duty cycle has been met, operate and set elapsed OP time
if (OPelapsed == 0) {
Serial.println("Calling for Extend (RY1=ON, RY2=OFF)");
LED(Off);
startOPtime = millis();
RelayExtend();  // operate actuator
endOPtime = millis();
elapsedOPtime = (endOPtime - startOPtime); // elapsed time of operation
OPelapsed = elapsedOPtime;
Serial.print(" Relay operate time was: ");
Serial.println(OPelapsed);
//setLED(LEDRed);
LED(Red);
startNOPtime = millis(); // start NOP
}
}

// if duty cycle has been met, operate and set elapsed OP time
if (OPelapsed == 0) {
Serial.println("Calling for Contract (RY1=ON, RY2=OFF)");
LED(Off);
startOPtime = millis();
RelayContract();  // operate actuator
endOPtime = millis();
elapsedOPtime = (endOPtime - startOPtime); // elapsed time of operation
OPelapsed = elapsedOPtime;
Serial.print(" Relay operate time was: ");
Serial.println(OPelapsed);
LED(Red);
startNOPtime = millis(); // start NOP
}
}

// Manual over-ride UP
// here we execute the request regardless of whether OPelapsed > 0
// we also ADD the operation time to OPelapsed and we reset startNOPtime
Serial.println("Calling for M/O Extend (RY1=ON, RY2=OFF)");
LED(Off);
startOPtime = millis();
RelayExtendMO();  // operate actuator
endOPtime = millis();
elapsedOPtime = (endOPtime - startOPtime); // elapsed time of operation
OPelapsed += elapsedOPtime; // ADD elapsed OP time to OPelapsed
Serial.print(" Relay operate time was: ");
Serial.println(OPelapsed);
LED(Red);
startNOPtime = millis(); // start a NEW NOP time to compensate for a possible increase OP time
}

// Manual over-ride Down
// here we execute the request regardless of whether OPelapsed>0
// we also ADD the operation time to OPelapsed and we reset startNOPtime
Serial.println("Calling for Contract (RY1=ON, RY2=OFF)");
LED(Off);
startOPtime = millis();
RelayContractMO();
endOPtime = millis();
elapsedOPtime = (endOPtime - startOPtime); // elapsed time of operation
OPelapsed += elapsedOPtime; // ADD elapsed OP time to OPelapsed
Serial.print(" Relay operate time was: ");
Serial.println(OPelapsed);
LED(Red);
startNOPtime = millis(); // start a NEW NOP time to compensate for a possible increase OP time
}

// check duty cycle requirement if we have had an operation
if (OPelapsed != 0) {
NOPelapsed = (millis() - startNOPtime); // startNOPtime was set by a relay operate
if (NOPelapsed > (3.0 * OPelapsed) ) {
// we have met the duty cycle requirement
Serial.print(" NOPelapsed while OPelapsed !=0: ");
Serial.println(NOPelapsed);
LED(Green);
NOPelapsed = 0;
OPelapsed = 0;
}
}
}
//____________________________________________________________________
void RelayOff() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, HIGH);
}
//____________________________________________________________________
void RelayExtend() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
delay(DebounceTime);
delay(DebounceTime);
RelayOff();
}
//____________________________________________________________________
void RelayExtendMO() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
delay(DebounceTime);
delay(DebounceTime);
RelayOff();
}
//____________________________________________________________________
void RelayContract() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
delay(DebounceTime);
delay(DebounceTime);
RelayOff();
}
//____________________________________________________________________
void RelayContractMO() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
delay(DebounceTime);
delay(DebounceTime);
RelayOff();
}
//____________________________________________________________________
void LED(byte color) {
switch (color) {
case Red:
digitalWrite(LED1, LOW);
digitalWrite(LED2, HIGH);
break;
case Green:
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
break;
case Off:
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
break;
default:
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
break;
}
}
//____________________________________________________________________
// end
Everything seems to work as expected. I do notice that if you continue to hold the UP button after it has hit the limit switch, the program still counts that time with regard to duty-cycle limit - meaning you have to wait even longer. But, the over ride button should come in handy in that respect. I'll explain it all to him. So far, so good.