Simple linear actuator operation

Any ideas why this simple code wont work?
The idea is to extend the actuator at a step of 10mm each time, and then retract at the same rate (not shown here).

#define USE_USBCON

const int bL = A4;  // backLeft

const int bL_extend = 6;
const int bL_retract = 7;

int returnstroke_bL()
{
  int b_L = analogRead(A4);
  b_L = map(b_L, 0, 1023, 0, 350);
  return bL;
}

void setup() {
  // put your setup code here, to run once:
  
  pinMode(bL_extend, OUTPUT); // rear left extend
  pinMode(bL_retract, OUTPUT); // rear left retract
}

void loop() {
  // put your main code here, to run repeatedly:
  
  int current_pos = returnstroke_bL();
  int target_pos = current_pos +10;
  
  while (current_pos < target_pos){
   
   digitalWrite(bL_extend, LOW);
   digitalWrite(bL_retract, HIGH);
   current_pos = returnstroke_bL(); 
  }
   digitalWrite(bL_extend, HIGH);
   digitalWrite(bL_retract, HIGH);
   
  delay(1);
}

Welcome to the forum

What does the sketch actually do ?
How is the actuator powered ?

Please post a simple schematic of your project

Am I right to assume that this part of the code is support to send a continuous pulse train out? :face_with_raised_eyebrow:

Hi all,

No, sorry for the lack of explanation. The actuator does not operate on pwm. It has two digital inputs. For the actuator to extend you supply +5v and 0V and for the actuator to retract the opposite. I can operate the actuator just fine in other scripts I have written. My attempt here is to operate the actuator in steps. Diagram coming up soon.

edit: the supply to the actuator is different than the extend/retract operation. The supply is constant and has an internal H bridge that operates when you alternate the supply to the set of digital inputs.

You need to update current pls within the while loop.

While this might work, I’d be letting the main loop do the work, an slightly restructure your code.

while (current_pos < target_pos){
   
   digitalWrite(bL_extend, LOW);
   digitalWrite(bL_retract, HIGH);
   current_pos = returnstroke_bL(); 
  }

I believe it updates within the while loop

so what about something like this then?
(Compiles, NOT tested!)

#define USE_USBCON

const int bL = A4;  // backLeft

const int bL_extend = 6;
const int bL_retract = 7;

int returnstroke_bL()
{
  int b_L = analogRead(A4);
  b_L = map(b_L, 0, 1023, 0, 350);
  return b_L;
}

void setup() {
  // put your setup code here, to run once:

  pinMode(bL_extend, OUTPUT); // rear left extend
  pinMode(bL_retract, OUTPUT); // rear left retract
  digitalWrite(bL_extend, HIGH);
  digitalWrite(bL_retract, HIGH);
}

void loop() {
  // put your main code here, to run repeatedly:

  int current_pos = returnstroke_bL();

  if (current_pos < 350) { //maximum extension
    int target_pos = current_pos + 10;
    digitalWrite(bL_extend, LOW);
    digitalWrite(bL_retract, HIGH);

    while (current_pos < target_pos) {
      current_pos = returnstroke_bL();
      delay(1); //arbitrary delay
    }
    
    digitalWrite(bL_extend, HIGH);
    digitalWrite(bL_retract, HIGH);

    delay(1000); //wait 1000ms before operation actuator again
  }
}

hope that helps...

ok, you go on thinking that.

i am not being a smartass, I am obviously not understanding what you are saying so please explain.

Inside here, you’re not reading the analog inout any more - so the current_pos won’t change for the comparison…

really?? I think your statement might be incorrect there....

No, but I see you have not provided any way to verify the values of the variables that inform the flow of your code.

Can you add some strategic or even just too many Serila.print() statements to see how it does flow and why?

This

  while (current_pos < target_pos){
   
   digitalWrite(bL_extend, LOW);
   digitalWrite(bL_retract, HIGH);
   current_pos = returnstroke_bL(); 
  }

is the same as this:

  if (current_pos < target_pos) {
    digitalWrite(bL_extend, LOW);
    digitalWrite(bL_retract, HIGH);
  }

  while (current_pos < target_pos) 
    current_pos = returnstroke_bL(); 

in your device, will that be doing what you want? Make bLextend LOW and bLretract HIGH, then hang around for the value read from the feedback mechanism goes bigger than target_pod.

If you don't look into it, you can't know why it doesn't do what you think it should. Printing is simple and inexpensive, if inelegant.

HTH

a7

Isn't that what

is doing?

Ok, that's what you want the sketch to do. What does it actually do? What does "won't work" mean?

analogRead() IS performed in returnstrok_bL(). That part of the code is correct.

Good question.
What it doesn't do is that the actuator starts extending without the step behavior i.e: just extending until it hits its endpoint.

In my head I would expect it to extend in steps i.e move 10mm then briefly stop then again another 10mm and so on. Perhaps the code repeatability is too fast to notice the step movement but with the delays introduced from sherzaad I would have noticed (perhaps I need to play more with the delays)

It actually has the same effect as my code, that is, it keeps extending without the step behavior. perhaps I should play more with the delays

Good inside, I will utilize this approach and report back.

Great input from all. Still trying to figure it out but I have some ideas after you all's input.
So to sum up the problem; I am actually trying to enable the digital outputs for a predetermine time. The time bounds can be defined using the analog encoder input (like what we are trying to do here) or from a simple, lets say for loop. Take the following example:

for (int i = 0; i<10; i++){
    digitalWrite(bL_extend, LOW);
    digitalWrite(bL_retract, HIGH);
}

    digitalWrite(bL_extend, HIGH);
    digitalWrite(bL_retract, HIGH);

Here the outputs will be enabled (in theory) as long as the loop runs (doesn't matter how long it takes ) and then turned off once the runtime exits the loop; but in reality (after I tried it) the actuator just runs until its endpoint limit switch. So what I am missing is maybe the correct way to turn off the outputs.

What everyone is missing is a link to the actuator product page or data sheet.

Avoid the blind leading the blind.