Actuator pulsing instead of moving smoothly to position

I have been working with this sketch - so far it is performing as I would like with one exception - the actuators “pulse” their way to their positions rather than moving smoothly.

The issue is it makes them slow.

I am thinking it has to do with the Serial.print I wrote into the sketch to troubleshoot it.

Just wondering if this is the case - I see several references to cautions about Serial.print in readxxx() situations.

If so - can I make things smoothly by increasing the baud rate to 115,200 or should I just remove the serial.prints altogether as now I don’t really need them?

I can’t include the entire sketch as it is too long, here are some snippets as well as the file:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  unsigned int configWord;

  // Set pin modes
  // Linear Actuator 1 - Lower Belt

  // Boom switch input pins
  pinMode(b1Pin, INPUT);
  pinMode(b2Pin, INPUT);
  pinMode(b3Pin, INPUT);
  pinMode(b4Pin, INPUT);
  pinMode(b5Pin, INPUT);
  pinMode(b6Pin, INPUT);

  //
  pinMode(ss_m1Pin, OUTPUT); digitalWrite(ss_m1Pin, LOW);  // HIGH = not selected
  pinMode(ss_m2Pin, OUTPUT); digitalWrite(ss_m2Pin, LOW);
  pinMode(ss_m3Pin, OUTPUT); digitalWrite(ss_m3Pin, LOW);
  pinMode(ss_m4Pin, OUTPUT); digitalWrite(ss_m4Pin, LOW);

  // L9958 DIRection pins
  pinMode(dir_m1Pin, OUTPUT);
  pinMode(dir_m2Pin, OUTPUT);
  pinMode(dir_m3Pin, OUTPUT);
  pinMode(dir_m4Pin, OUTPUT);

  // L9958 PWM pins
  pinMode(pwm_m1Pin, OUTPUT);  digitalWrite(pwm_m1Pin, LOW);
  pinMode(pwm_m2Pin, OUTPUT);  digitalWrite(pwm_m2Pin, LOW);    // Timer1
  pinMode(pwm_m3Pin, OUTPUT);  digitalWrite(pwm_m3Pin, LOW);
  pinMode(pwm_m4Pin, OUTPUT);  digitalWrite(pwm_m4Pin, LOW);    // Timer0

  // L9958 Enable for all 4 motors
  pinMode(enable_motorsPin, OUTPUT);
  digitalWrite(enable_motorsPin, HIGH);  // HIGH = disabled

  configWord = 0b0000010000001100;

  SPI.begin();
  SPI.setBitOrder(LSBFIRST);
  SPI.setDataMode(SPI_MODE1);  // clock pol = low, phase = high

  // Motor 1
  digitalWrite(ss_m1Pin, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(ss_m1Pin, HIGH);
  // Motor 2
  digitalWrite(ss_m2Pin, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(ss_m2Pin, HIGH);
  // Motor 3
  digitalWrite(ss_m3Pin, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(ss_m3Pin, HIGH);
  // Motor 4
  digitalWrite(ss_m4Pin, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(ss_m4Pin, HIGH);

  //Set initial actuator settings to pull at 0 speed for safety
  dir1 = 0; dir2 = 0; dir3 = 0; dir4 = 0; // Set direction
  pwm1 = 0; pwm2 = 0; pwm3 = 0; pwm4 = 0; // Set speed (0-255)

  digitalWrite(enable_motorsPin, LOW);// LOW = enabled
} // End setup

void loop() {
  readButton();
}

void readButton()
{
  // All switches off - default position all actuators
  // All switches on - default position all actuators

  b1State = digitalRead(b1Pin);
  Serial.print("B1:");
  Serial.print(b1State);
  b2State = digitalRead(b2Pin);
  Serial.print(" B2:");
  Serial.print(b2State);
  b3State = digitalRead(b3Pin);
  Serial.print(" B3:");
  Serial.print(b3State);
  b4State = digitalRead(b4Pin);
  Serial.print(" B4:");
  Serial.print(b4State);
  b5State = digitalRead(b5Pin);
  Serial.print(" B5:");
  Serial.print(b5State);
  b6State = digitalRead(b6Pin);
  Serial.print(" B6:");
  Serial.println(b6State);
  // Check voltage on Switch 1, If it is HIGH, then Check Voltage on Switch 6
  // Else If Switch 1 is HIGH and 6 is HIGH, then move all actuators to default position

  if (b1State == HIGH && b6State == HIGH)
  {
    updateActuator1Default();
    updateActuator2Default();
    updateActuator3Default();
    updateActuator4Default();

  }
  else if (b1State == HIGH && b6State == LOW && b5State == HIGH)
    //  Switch 1 and 5 are on, 6 is off, POSITION 6
  {
    updateActuator1Position6Right();
    updateActuator2Position6Right();
    updateActuator3Default();
    updateActuator4Position6();

  }
  else if (b1State == HIGH && b6State == LOW && b5State == LOW && b4State == HIGH)
  {
    // Switch 1 is on, switches 5 and 6 are off, POSITION 5
    updateActuator1Position5Left();
    updateActuator2Position5Right();
    updateActuator3Default();
    updateActuator4Position5();

  }
  else if (b1State == HIGH && b6State == LOW && b5State == LOW && b4State == LOW)
  {
    // Switch 1 on, all switches on right side are off POSITION 4
    updateActuator1Position4Right();
    updateActuator2Position4Right();
    updateActuator3Default();
    updateActuator4Default();
  }

and the states:

void updateActuator1Default()
{
  Serial.print("A1Default: ");
  Serial.print(act1Default);
  Serial.print("A1NOW: ");
  // move actuator to default position
  pot1Current = analogRead(pot1Pin);
    Serial.print(pot1Current);
  if (act1Default > pot1Current && act1Default > pot1Current + coarse)
  {
    actuator1_Extending = true;
    actuator1_Retracting = false;
    dir1 = 1;
    pwm1 = 255;
    digitalWrite(dir_m1Pin, dir1);
    analogWrite(pwm_m1Pin, pwm1);
    Serial.print("A1 Extending");
  }
  else if (act1Default < pot1Current && act1Default < pot1Current + coarse)
  {
    actuator1_Retracting = true;
    actuator1_Extending = false;
    dir1 = 0;
    pwm1 = 255;
    digitalWrite(dir_m1Pin, dir1);
    digitalWrite(pwm_m1Pin, pwm1);
    Serial.print("A1 Retracting");
  }
  if (actuator1_Extending = true && pot1Current > act1Default)
  {
    dir1 = 1;
    pwm1 = 0;
    digitalWrite(dir_m1Pin, dir1);
    digitalWrite(pwm_m1Pin, pwm1);
    boolean actuator1_Extending = false;
    Serial.print("A1 IDLE");
  }
  if (actuator1_Retracting = true && pot1Current < act1Default)
  {
    dir1 = 0;
    pwm1 = 0;
    digitalWrite(dir_m1Pin, dir1);
    digitalWrite(pwm_m1Pin, pwm1);
    boolean actuator1_Retracting = false;
    Serial.print("A1 IDLE");
  }
}
// -------------------------------------------------------------------------------------------------
void updateActuator2Default()
{
  Serial.print("A2 Default: ");
  Serial.print(act2Default);
  Serial.print("A2NOW: ");
  pot2Current = analogRead(pot2Pin);
    Serial.print(pot2Current);
  if (act2Default > pot2Current && act2Default > pot2Current + coarse)
  {
    actuator2_Extending = true;
    actuator2_Retracting = false;
    dir2 = 1;
    pwm2 = 255;
    digitalWrite(dir_m2Pin, dir2);
    analogWrite(pwm_m2Pin, pwm2);
    Serial.print("A2 Extending");
  }
  else if (act2Default < pot2Current && act2Default < pot2Current + coarse)
  {
    actuator2_Retracting = true;
    actuator2_Extending = false;
    dir2 = 0;
    pwm2 = 255;
    digitalWrite(dir_m2Pin, dir2);
    digitalWrite(pwm_m2Pin, pwm2);
Serial.print("A2 Retracting");  
  }
  if (actuator2_Extending = true && pot2Current > act2Default)
  {
    dir2 = 1;
    pwm2 = 0;
    digitalWrite(dir_m2Pin, dir2);
    digitalWrite(pwm_m2Pin, pwm2);
    boolean actuator2_Extending = false;
    Serial.print("A2 IDLE");
  }
  if (actuator2_Retracting = true && pot2Current < act2Default)
  {
    dir2 = 0;
    pwm2 = 0;
    digitalWrite(dir_m2Pin, dir2);
    digitalWrite(pwm_m2Pin, pwm2);
    boolean actuator2_Retracting = false;
    Serial.print("A2 IDLE");
  }
}

}

There are no delay() 's the sketch

BeltdividerV4.ino (38.6 KB)

I am thinking it has to do with the Serial.print I wrote into the sketch to troubleshoot it.

Once you know that the switches are being read correctly, do you learn any more leaving the Serial.print()s in?

    actuator1_Extending = true;
    actuator1_Retracting = false;

Why do you need two booleans? What other things might the actuator be doing?

What I would do to locate the source of the problem is to ditch 90 % of that code. Simply have loop() move one actuator to fully extended, and then move that same actuator until it is fully retracted. If the actuator moves smoothly, then the problem is the code. If not, the problem is the hardware (I’d suspect inadequate power).

  if (actuator1_Retracting = true && pot1Current < act1Default)

Do you REALLY want an assignment there? I’d expect a comparison (==).

There are no delay() 's the sketch

There are. Serial.print() becomes a blocking function when the outgoing buffer gets full.

What other things might the actuator be doing?

Not moving ?

I disabled the serial.prints as you suggested PaulS. What happens then is the sketch stops working altogether.

I did this by adding // in front of each line that referred to the Serial.print.

I did not notice the assignment - I believe you are correct it should be a comparison. I will make that adjustment and see if it helps. It also reminded me to credit the two sketches I got this from (robotgeek). I will make that notation immediately.

Regarding power - the actuators require 5amp each max and are being fed from a 30 amp 10 gauge wire which I felt was strong enough. I did try hooking up one actuator at a time - did not make any difference. The multimoto itself has LED’s that flash “in time” whether there are actuators hooked up or not.

Seems strange to me. I don’t understand why a Serial.print is making a sketch function or not function.

The specific line, that if you enable, are here (note the Serial.prints that are disabled, they make no difference) This is why I think maybe the assignment is the issue.

void updateActuator1Position2Left()
{
  pot1Current = analogRead(pot1Pin);
  //Serial.print(" A1P2GOAL: ");
  // Serial.print(act1P2);
  // Serial.print(" A1NOW: ");
  // Serial.print(pot1Current);
  if (act1P2 > pot1Current && act1P2 > pot1Current + coarse)
  {
    actuator1_Extending = true;
    actuator1_Retracting = false;
    dir1 = 1;
    pwm1 = 255;
    digitalWrite(dir_m1Pin, dir1);
    analogWrite(pwm_m1Pin, pwm1);
    Serial.print("A1 Extending");
[/color]  }
  else if (act1P2 < pot1Current && act1P2 < pot1Current + coarse)
  {
    actuator1_Retracting = true;
    actuator1_Extending = false;
    dir1 = 0;
    pwm1 = 255;
    digitalWrite(dir_m1Pin, dir1);
    digitalWrite(pwm_m1Pin, pwm1);
   Serial.print("A1 Retracting");
[/color]  }
  if (actuator1_Extending = true && pot1Current > act1P2)
  {
    dir1 = 1;
    pwm1 = 0;
    digitalWrite(dir_m1Pin, dir1);
    digitalWrite(pwm_m1Pin, pwm1);
    boolean actuator1_Extending = false;
    // Serial.print("A1 IDLE");

I neglected to mention in my initial post that the pulsing is directly related to the baud rate set for the serial.print. i.e. if you set it at 115200, the pulsing is very quick, or at 100, it pulses at a matching rate.

For example 4800 is once per second. At the slower baud rates, the actuators move quickly between pulses as they have more time but it isn’t right.

  if (actuator1_Extending = true && pot1Current > act1P2)
  {
    dir1 = 1;
    pwm1 = 0;
    digitalWrite(dir_m1Pin, dir1);
    digitalWrite(pwm_m1Pin, pwm1);
    boolean actuator1_Extending = false;

So, now you have two variables called actuator1_Extending with different values and different scopes. Not usually a good idea.

the actuators require 5amp each max and are being fed from a 30 amp 10 gauge wire which I felt was strong enough.

If that 10 gauge wire is connected to a 9V battery, there is no way in hell that it will supply 5 A. So, what IS supplying the power?

A SHORT sketch that unconditionally drives ONE actuator is still in order.

Hi,

It also reminded me to credit the two sketches I got this from (robotgeek). I will make that notation immediately.

So you have combined two sketches?

PaulS: A SHORT sketch that unconditionally drives ONE actuator is still in order.

Good idea, then develop your own code stage by stage so you understand it and get sections working before you program for another stage of your sketch. We need the specs for your actuator and your driver please. Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png? Thanks.. Tom.. :)

PaulS - I am using a 9V power supply for the Mega and the Multimoto uses its own 12V supply which is coming directly from relay off vehicle battery.

I corrected the comparison’s (==) and this seems to have solved my issue at least on a bench test. Going to test tomorrow if I can get away from the office.

Regarding the Boolean operator - I searched the forums for this but did not find it an answer.

Should I be using the following syntax:

    actuator1_Retracting = true;
    actuator1_Extending = false;
    dir1 = 0;
    pwm1 = 255;
    digitalWrite(dir_m1Pin, dir1);
    digitalWrite(pwm_m1Pin, pwm1);

or this:

 else if (act1P2 < pot1Current && act1P2 < pot1Current + coarse)
  {
    boolean actuator1_Retracting = true;
    boolean actuator1_Extending = false;
    dir1 = 0;
    pwm1 = 255;
    digitalWrite(dir_m1Pin, dir1);
    digitalWrite(pwm_m1Pin, pwm1);

What I am trying to do is tell the actuators to stop moving based on the direction they are moving - that is if they are extending, I set the pwm to 0 and reverse the direction to form an “idle” state for them.

Here is a picture of my bench model. I tried to do a Fritz but there the Multimoto shield I am using is not part of it to include and I am not skilled enough to add it. This is the best I can do for now.

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
In particular how you have your power supplies connected, please no Fritzy diagrams.

Thanks… Tom. :slight_smile:

Here is the drawing I tried to post last night. The forum was blocking my picture yesterday for some reason.

I don’t have access to CAD and I am not a professional at this so don’t mock my drawing skills please…

diagram.pdf (75.3 KB)

WP_20160519_23_34_20_Pro.jpg

Hi, Thanks for the diag, can you post links to specs on your moto shield and your actuators please. What is the application?

I hope your 9V supply is not a smokedetector battery. I would suggest you write code to control just ONE actuator smoothly first, to prove your hardware and power supply.

Tom.... :)

TomGeorge - I have written a sketch and using my configuration I can move one actuator from fully retracted to fully extended with no issues. They are moving a small gate with virtually zero load on them.

I attached a schematic of the multimoto from the robotpower website.

I updated the sketch as suggested by PaulS and actuators 1, 2 and 3 perform, for a while, as expected however 4 does not.

Here is my issue - when I first load up the sketch onto the Mega, actuators 1, 2 and 3 do what I expect and switch positions, etc.

However, actuator 4 does not move, instead it seems to get stuck going the wrong way. It is not a wiring issue, I tried reversing them. My sketch is telling the actuator to extend but it does not.

It is not a power issue because the other actuators are either all moving or have moved and “settled” into their targets.

In addition, after several switch “sequences” sometimes actuators 1 and 2 will start to move in reverse, i.e. instead of extending they retract.

I am concerned about the Boolean operators I am using but before that - help me to understand how the “states” work.

I am pretty certain that the state is called on from the void loop. In my sketch, I have a loop calling to the state readbutton(), and within this state, it calls on other states to do work based on switch positions.

I am wondering if this is a mistake (calling a new state from an existing state) and whether I should move my entire if/else chain into the loop and eliminate the state readbutton().

My second question relating to states - is when does the sketch exit the state? does it look to the condition, the condition calls the state, the state runs, then the sketch looks to the condition to see if it is still true, and then runs the state again? Or does the state run continuously “in the background” until the conditions change? Why I ask this is I am wondering how many states can run simultaneously successfully before something locks up.

Or is there a way to “clear the memory” when a condition changes?

Thank you in advance for your help.

MultiMoto-v1_6_schematic.pdf (98.5 KB)

I updated the sketch as suggested by PaulS

Please post the updated program.

Sorry I did not click on add another attachment.

BeltdividerV5.ino (39.5 KB)

How are the switches wired ?

Do you have any pulldown resistors on the input pins or are they floating at an uncertain voltage when not taken HIGH by the switches ?

I do not have pull down resistors on the wires directly. I have them wired using voltage dividers so I thought that adding another resistor would be unnecessary. You can correct me if I am wrong.

In my original sketch I had the Serial.print monitor the switch states and I watched them - never got any false readings (either 0 or 1 depending on switch state), I have disabled this for now.

Regardless - even if I did get a false reading - actuators 1 and 2 should always be moving in the same direction based on switch state, they should never move opposite yet they do after a while.

Hi,

I do not have pull down resistors on the wires directly. I have them wired using voltage dividers so I thought that adding another resistor would be unnecessary. You can correct me if I am wrong.

Can you post a diagram of how you have connected your switches in a voltage divider please.
A picture as well would help, your last picture showed the press buttons but no resistors at all.
WP_20160519_23_34_20_Pro.jpg
What is your 9V supply?
Thanks … Tom… :slight_smile:

Hi, Can you tell me what each of your buttons are supposed to do and what each of your pots are supposed to do?

Thnaks Tom... :)

Each pot is built into the PA14P linear actuators, they are being used to tell the arduino whether the actuator needs to extend or retract (or be stationary).

I added another diagram.

diagram2.pdf (42.7 KB)

Hi, What are the pots on the protoboard for. So you want the actuator to move to predetermined positions, a position for each button? Are they the preset positions for the buttons to use as position points?

Tom... :)

I was using the pots on the protoboard to simulate my acutuators moving. This way I could see via the LED lights on the multimoto shield if the onboard relays were triggering the acutuators to move the way they needed to.

Just a way to bench test as the machine I am putting this on is large and awkward to maneuver around.