Sketch not allowing actuator movement to be interrupted

I have a question about how my sketch only works if the actuators complete their movement.

I am using an Arduino Mega 2560 with a Multimoto

I am controlling 2 linear actuators that have hall effect sensors.

The user can choose where they want the actuator to move to using a combination of toggle switches. There are 4 switches, and each actuator can have 5 positions.

I am using the hall counter to let the Arduino know where the actuators are and where they should move to.

If I let the actuator’s complete their movement (let the sketch finish it’s work I guess) then everything works just fine.

However, if the movement is interrupted before an actuator reaches it’s target, the sketch seems to “stick” in that part of it’s logic and not loop back to tell the actuator to move, at all. Basically the actuator just stops and will no longer move, unless I tell it to move to the original target location.

For example, if the actuator is told to move to position 1 (fully retracted) and it is interrupted part way, it will just “stop” moving. The only way I can get it to move anywhere is if I repeat the request to move to position 1. Then it will finish it’s sequence and from there, everything goes on ok.

I tried adding in ISR or “state calls” to trigger the sketch to look at the actuator position and move it, in various parts of the switch…case that I am using to try to trigger the sketch to pick up a new target to move to, with no luck.

Here is the ISR/State of the sketch where I look to see where the actuators are:

[code]
void updatePresentPosition()
{
  if (leftReading >= 0 && coarse >= leftReading)
  {
    leftPosition1 = true;
    leftPosition2 = false;
    leftPosition3 = false;
    leftPosition4 = false;
    leftPosition5 = false;
  }
  else if (leftReading >= left1To2 - coarse && left1To2 + coarse >= leftReading)
  {
    leftPosition1 = false;
    leftPosition2 = true;
    leftPosition3 = false;
    leftPosition4 = false;
    leftPosition5 = false;
  }
  else if (leftReading >= left1To3 - coarse && left1To3 + coarse >= leftReading)
  {
    leftPosition1 = false;
    leftPosition2 = false;
    leftPosition3 = true;
    leftPosition4 = false;
    leftPosition5 = false;
  }
  else if (leftReading >= left1To4 - coarse && left1To4 + coarse >= leftReading)
  {
    leftPosition1 = false;
    leftPosition2 = false;
    leftPosition3 = false;
    leftPosition4 = true;
    leftPosition5 = false;
  }
  else if (leftReading >= 6400)
  {
    leftPosition1 = false;
    leftPosition2 = false;
    leftPosition3 = false;
    leftPosition4 = false;
    leftPosition5 = true;
  }
  else if (dir1 = 0 && pwm1 != pwmStop)
  {
    leftRetracting = true;
    leftExtending = false;
  }
  else if (dir1 = 1 && pwm1 != pwmStop)
  {
    leftExtending = true;
    leftRetracting = false;
  }
}

[/code]

And here is the ISR/State that tells the actuators where they need to be moving to. leftActual = 1 etc refers to switch…case states in the main loop.

void updateMovementDirection()
{
  if (leftPosition1 == true && (leftExtending == false || leftRetracting == false))
  {
    leftActual = 1;
  }
  else if (leftPosition2 == true && (leftExtending == false || leftRetracting == false))
  {
    leftActual = 2;
  }
  else if (leftPosition3 == true && (leftExtending == false || leftRetracting == false))
  {
    leftActual = 3;
  }
  else if (leftPosition4 == true && (leftExtending == false || leftRetracting == false))
  {
    leftActual = 4;
  }
  else if (leftPosition5 == true && (leftExtending == false || leftRetracting == false))
  {
    leftActual = 5;
  }
  else if (leftExtending == true)
  {
    leftActual = 6;
  }
  else
  {
    leftActual = 7;
  }
}

I have attached the full sketch below.

I would appreciate any advice on what I am missing.

McClaryActuatorswithHallSensorsV3.ino (40.8 KB)

  1. Learn about arrays.

  2. When you have many case statements with identical code, you can use "fall through" to avoid copy-pasting code. Your first switch(leftActual) in loop() has identical outcomes to cases 2, 3, 4, 5 (but not 6 or 7?)

switch(thingy) {
  case 0:
    doActionZero();
  break;
  case 1:
  case 2:
  case 3:
    doAction1To3();
  break;
  case 4:
    doAction4();
  break;
  default:
    doDefaultActionForAllOtherNumbers();
}

Although I'd probably make that one into something more like... if(leftActual==1) stop(); else driveLeft();

You have a lot of code with lots of magic numbers, so not many people are going to want to open it up and re-interpret all the numbers.

  else if (dir1 = 0 && pwm1 != pwmStop)
  {
    leftRetracting = true;
    leftExtending = false;
  }
  else if (dir1 = 1 && pwm1 != pwmStop)

Oops, common problem. Remember that:
One equal sign assigns a value (and also provides a result), and
Two equal signs are for comparisons.

Also, the final 'else' statement probably does not need an 'if'.

Thank you to both MorganS and vaj4088.

I cleaned up my sketch - what a simplification “falling through” makes! Not only did it make the sketch simpler, if helped to diagnose what the problem was. Why oh why did I not take any C courses in school…

I totally missed the = vs == that was a silly mistake on my part.

Turns out the issue was a combination of that and a logic sequence. Once I cleaned up the loop I realized that I was not resetting the condition of where the actuators were once they were told to retract or extend. Therefore they still “thought” they were at their target until they passed another threshold.

Here is what I had:

void updateLeftRetractFast()
{
  leftRetracting = true;
  dir1 = 0;
  pwm1 = pwmFast;
  digitalWrite(dir_m1Pin, dir1);
  analogWrite(pwm_m1Pin, pwm1);
}

and here is what works

void updateLeftRetractFast()
{
  leftRetracting = true;

  leftPosition1 = false;
  leftPosition2 = false;
  leftPosition3 = false;
  leftPosition4 = false;
  leftPosition5 = false;
  dir1 = 0;
  pwm1 = pwmFast;
  digitalWrite(dir_m1Pin, dir1);
  analogWrite(pwm_m1Pin, pwm1);
}

The mechanisms flow smoothly now, can go crazy with the inputs and the actuators do what they need to do.

Regarding MorganS point about arrays - I agree I should learn about them but I didn’t in this case as this was my first attempt at getting hall encoders working and I didn’t want to make my diagnostics more complicated. Now that it is working I can keep tidying it up.

I posted the updated sketch. My next task is to understand timers beyond making an LED blink on and off.

Thanks again.

McClaryActuatorswithHallSensorsV4.ino (31.4 KB)

Well a simple use of timers applicable to this project is to set a time limit for reaching the next encoder position. Imagine you are driving from position 3 to position 1 and you expect to hit 2 within 3 seconds. If you don't see 2 within that time, the gate is blocked or damaged.