Physical switches being ignored

I am using an Uno Wifi with 2 x Megamoto to move 2 linear actuators, which are lowering and or raising a mowing deck to target height.

My issue is - when I trigger switch one ( a toggle switch) to "arm" the system, the sketch ignores the initial triggering of the switch. When I check the Serial Monitor - I can see that the Arduino recognizes that the input has moved to "high", and the correct Switch - Case has been chosen, but no action has happened. If I cycle the switch once, then the actuators move as intended.

This also occurs with the Switch 2 input. I have to cycle the switch a 2nd time, then the system works.

If I leave the sketch running for a period of time, say 5 minutes, the issue reappears. Switches have to be cycled 2 times for the action to happen.

Any thoughts?

[code]
/* Update August 16 2022

  Rowmower V2
  Chuck Baresich

  This code is to move 2 linear actuators based on 2 input positions.  Positions are up and down, with the fully lowered position being default.

  Each actuator being controlled with timing

  ----- Sketch adapted from the following sources:
  Linear Actuator Control using preset position
  RobotGeek
  Demo MegaMoto Robot Power test sketch
  ------

  Set up global variables for each linear actuator

  Actuators from Progressive Automations, model PA-17

  Actuator 1, "left" is the actuator on the left side of the frame
  PA 1706;  10" stroke, with 0.55 to 0.66" per second under load or no load

  Actuator 2, "right" is the actuator lifting the frame on the right side

  Positions:  booleans to record where the Actuators actually are or were

  Fully extended means frame is fully raised.  Fully retracted means frame is fully lowered

  Positions are named for their associated "position"
  left:
  p1:  fully extended
  p2:  Mid Point
  p3:  fully retracted (default)

  right:
  p1:  fully extended
  p2:  Mid point
  p3:  Fully retracted (default)

*/

// logical positions of the actuators
boolean pos1, pos2, pos3;
boolean leftExtending;
boolean leftRetracting;

boolean rightExtending;
boolean rightRetracting;

// constants for timing of the actuator movement

const float outSpeed = 0.50;
const float inSpeed = 0.60;
const float stroke = 10;

// constant for target height, used to determine position 2 location
const float height = 4;
const float targetPos = stroke - height;

const float leftFactor = 1100;
const float rightFactor = 1000;

// may not need these
const float pos1Stroke = stroke;
const float pos2Stroke = targetPos;
const float pos3Stroke = stroke;

// Extend timing

// left
const float leftOutToP1 = (pos1Stroke / outSpeed) * leftFactor;  //
const float leftOutToP2 = (pos2Stroke / outSpeed) * leftFactor;  //
const float leftOutToP3 = (pos3Stroke / outSpeed) * leftFactor;  //

// right
const float rightOutToP1 = (pos1Stroke / outSpeed) * rightFactor;
const float rightOutToP2 = (pos2Stroke / outSpeed) * rightFactor;
const float rightOutToP3 = (pos3Stroke / outSpeed) * rightFactor;

// Retract timing
// left
const float leftInToP1 = (pos1Stroke / inSpeed) * leftFactor;
const float leftInToP2 = ((stroke - targetPos) / inSpeed) * leftFactor; // from fully extended
const float leftInToP3 = (pos3Stroke / inSpeed) * leftFactor;
//right
const float rightInToP1 = (pos1Stroke / inSpeed) * rightFactor;
const float rightInToP2 = ((stroke - targetPos) / inSpeed) * rightFactor; // from fully extended
const float rightInToP3 = (pos3Stroke / inSpeed) * rightFactor;   //*************************************

// Constants for inputs for height selection switches, labeled 1 for Extended, 2 for Target, and 3 for Retracted
const int b1Pin = 2; // if there is no input on this pin, then system is considered disarmed and actuators fully extend
// if there is input on b1Pin, then system is considered arm and defaults to fully retracted.
const int b2Pin = 4; // Trigger to raise to target height

int b1State = 0;
int b2State = 0;

// constants for stability of actuator movement
const float coarse = 500;
const int pwmFast = 255;
const int pwmLFast = 255;
const int pwmSlow = 120;
const int pwmStop = 0;

//  MegaMoto Plus - bottom is Left actuator, top is right acuator
// Left - Use Pin 8 to enable
// Extend - Pin 11
// Retract - Pin 3

// Right - use Pin 8 to enable
// Extend - Pin 9
// Retract - Pin 10

const int enablePin = 8;  // enables both Mega Motos
const int leftExtendPin = 11;
const int leftRetractPin = 3;
const int rightExtendPin = 9;
const int rightRetractPin = 10;

int pwmL, pwmR;  // for left and right actuators
int current;
int actuatorTarget;

const byte CPin = 0;  // analog input channel
int CRaw;      // raw A/D value
float CVal;    // adjusted Amps value

unsigned long previousMillis = 0;

void setup() {

  Serial.begin(9600);

  // Set pin modes
  // Boom switch input pins
  pinMode(b1Pin, INPUT); digitalWrite(b1Pin, LOW);
  pinMode(b2Pin, INPUT); digitalWrite(b2Pin, LOW);

  pinMode(enablePin, OUTPUT); digitalWrite(enablePin, LOW);
  pinMode(leftExtendPin, OUTPUT);
  pinMode(leftRetractPin, OUTPUT);
  pinMode(rightExtendPin, OUTPUT);
  pinMode(rightRetractPin, OUTPUT);

  //Set initial actuator settings to pull at 0 speed for safety

  pwmL = pwmStop; pwmR = pwmStop;
  analogWrite(leftExtendPin, pwmL);
  analogWrite(leftRetractPin, pwmL);
  analogWrite(rightExtendPin, pwmR);
  analogWrite(rightRetractPin, pwmR);

  // Calibrate Actuators by extending them fully first.
  Serial.println(" Extending Left and Right Actuators");
  delay(300);

  pwmL = pwmLFast; pwmR = pwmFast;
  digitalWrite(enablePin, HIGH);
  analogWrite(leftExtendPin, pwmL);
  analogWrite(rightExtendPin, pwmR);
  delay(stroke / outSpeed * leftFactor);
  // now that they are extended stop them.
  Serial.println("Stopping the Actuators");
  delay(300);
  digitalWrite(enablePin, LOW);
  pwmL = pwmStop; pwmR = pwmStop;
  analogWrite(leftExtendPin, pwmL);
  analogWrite(rightExtendPin, pwmR);
  delay(20);

  pos1 = true; pos2 = false; pos3 = false;
  leftExtending = false;
  leftRetracting = false;
  rightRetracting = false;
  rightExtending = false;

} // End setup

void loop()
{
  unsigned long currentMillis = millis();

  if (leftExtending == false && leftRetracting == false) {
    updateBoomSwitchState();
    updateActuatorTargets();
    updateActuatorCurrentPosition();
  }

  switch (actuatorTarget)
  {
    case 3: // case 3,  Position 3.  Left and Right to be fully retracted
      Serial.print(" C3 Actuator needs to be at P3 ");

      switch (current)
      {
        case 53: // Actuators already in Position 3
          Serial.print(" Actuator = P3 ");
          pos1 = false;
          pos2 = false;
          pos3 = true;
          break;

        case 52: // Actuators were in Position 2
          Serial.print(" Actuator = P2 go to P3 ");

          updateRetractFast();

          if (currentMillis - previousMillis >= (leftInToP3 - leftInToP2)) {
            previousMillis = currentMillis;

            updateStop();
            // what we want to be the case
            pos1 = false;
            pos2 = false;
            pos3 = true;

          }
          break;

        case 51: // Actuators were in Position 1
          Serial.print(" Actuator = P1 go to P3 ");
          updateRetractFast();

          if (currentMillis - previousMillis >= leftInToP3) {
            previousMillis = currentMillis;

            updateStop();

            // what we want to be the case
            pos1 = false;
            pos2 = false;
            pos3 = true;

          }
          break;
      }
      break;
    case 2: // Actuators need to be in Position 2, the target
      Serial.print(" C2 Actuators need to be at P2");
      
      switch (current)
      {
        case 51: // Case 1, actuators were in position 1
          Serial.print(" Actuator = P1 go to P2 ");
          updateRetractFast();

          if (currentMillis - previousMillis >= leftInToP2) {
            previousMillis = currentMillis;

            updateStop();

            // what we want to be the case
            pos1 = false;
            pos2 = true;
            pos3 = false;

          }
          break;

        case 52: // Case 2 - actuators already were in Position 2
          Serial.print(" Actuator = P2 ");
          pos1 = false;
          pos2 = true;
          pos3 = false;
          break;

        case 53: // Case 3 - actuators were in Position 3
          Serial.print(" Actuator = P3 go to P2 ");
          updateExtendFast();

          if (currentMillis - previousMillis >= leftOutToP2) {
            previousMillis = currentMillis;

            updateStop();

            // what we want to be the case
            pos1 = false;
            pos2 = true;
            pos3 = false;

          }
          break;
      }
      break;
    case 1: // Actuators need to be in Position 1, fully extended
    Serial.print(" Actuators need to be at P1 ";
    
      switch (current)
      {
        case 53: // Case 3 - Actuators were in Position 3
          Serial.print(" Actuator = P3 go to P1 ");
          updateExtendFast();

          if (currentMillis - previousMillis >= leftOutToP1) {
            previousMillis = currentMillis;

            updateStop();

            // what we want to be the case
            pos1 = true;
            pos2 = false;
            pos3 = false;

          }
          break;

        case 52: // case 2: Actuators were in Position 2
          Serial.print(" Actuator = P2 go to P1 ");
          updateExtendFast();

          if (currentMillis - previousMillis >= (leftOutToP1 - leftOutToP2)) {

            updateStop();

            // what we want to be the case
            pos1 = true;
            pos2 = false;
            pos3 = false;

          }
          break;

        case 51: // case 3, actuators already were in Position 1
          Serial.print(" Actuators = P1 ");
          pos1 = true;
          pos2 = false;
          pos3 = false;
          break;
      }
      break;
  }
  //Serial.print(" PWML: ");
  //Serial.print(pwmL);
  //Serial.print(" PWMR: ");
  //Serial.print(pwmR);
  Serial.print(" Act Target");
  Serial.print(actuatorTarget);
  Serial.print("  current : ");
  Serial.print(current);
  //Serial.print("  B1 : ");
  //Serial.print(b1State);
  //Serial.print(" B2 : ");
  Serial.println(b2State);

}
//  -----------------------------START STATES  ---------------------------------------------------------
// states set up
// actuator 1 - default, 1, 2, 3
// actuator 2 - default, 1, 2, 3
//----------------------------------------------------------------------------------
void updateBoomSwitchState()
{
  b1State = digitalRead(b1Pin);
  b2State = digitalRead(b2Pin);
}
// --------------------------------------------------------------------------------------
void updateActuatorTargets()
{
  // b1 is on means system is armed
  // b2 is on means move to target position
  if (b1State == HIGH && b2State == HIGH)  //  system armed, move to target position
  {
    actuatorTarget = 2;
  }
  else if (b1State == HIGH && b2State == LOW)    //  system is armed, move to default retracted position
  {
    actuatorTarget = 3;
  }
  else // Ignore all other switches, move system to fully extended position
  {
    actuatorTarget = 1;
  }
}
// -------------------------------------------------------------------------------------------
void updateActuatorCurrentPosition()
{
  //if (leftP3 == true && rightP3 == true)// left and right are fully retracted
  if (pos3 != false)
  {
    current = 53;
  }
  else if (pos2 != false)//(leftP2 == true && rightP2 == true) // left and right partially extended
  {
    current = 52;
  }
  else if (pos1 != false) // left and right are fully fully extended
  {
    current = 51;
  }
}
// ----------------------------------------------------------------------------------------------------
void updateExtendFast()//  Used to extend both actuators
{
  leftExtending = true;
  rightExtending = true;
  // rightRetracting = false;
  pwmL = pwmLFast;
  pwmR = pwmFast;
  digitalWrite(enablePin, HIGH);
  analogWrite(leftExtendPin, pwmL);
  // analogWrite(leftRetractPin, 0);
  analogWrite(rightExtendPin, pwmR);
  // analogWrite(rightRetractPin, 0);
}

//---------------------------------------------------------------------------------------------------------
void updateExtendSlow()//  Used to extend both actuators
{
  leftExtending = true;
  //leftRetracting = false;
  rightExtending = true;
  //rightRetracting = false;
  pwmL = pwmSlow;
  pwmR = pwmSlow;
  digitalWrite(enablePin, HIGH);
  analogWrite(leftExtendPin, pwmL);
  // analogWrite(leftRetractPin, 0);
  analogWrite(rightExtendPin, pwmR);
  // analogWrite(rightRetractPin, 0);
}

//---------------------------------------------------------------------------------------------------------
void updateRetractFast()// Used to retract both actuators
{
  // leftExtending = false;
  leftRetracting = true;
  // rightExtending = false;
  rightRetracting = true;
  pwmL = pwmFast;
  pwmR = pwmFast;
  digitalWrite(enablePin, HIGH);
  analogWrite(leftRetractPin, pwmL);
  // analogWrite(leftExtendPin, 0);
  analogWrite(rightRetractPin, pwmR);
  // analogWrite(rightExtendPin, 0);
}

//---------------------------------------------------------------------------------------------------------
void updateRetractSlow()// Used to retract both actuators
{
  // leftExtending = false;
  leftRetracting = true;
  // rightExtending = false;
  rightRetracting = true;
  pwmL = pwmSlow;
  pwmR = pwmSlow;
  digitalWrite(enablePin, HIGH);
  analogWrite(leftRetractPin, pwmL);
  // analogWrite(leftExtendPin, 0);
  analogWrite(rightRetractPin, pwmR);
  // analogWrite(rightExtendPin, 0);
}

//---------------------------------------------------------------------------------------------------------
void updateStop()  //Used to stop actuators
{

  digitalWrite(enablePin, LOW);

  leftExtending = false;
  leftRetracting = false;
  rightExtending = false;
  rightRetracting = false;
  pwmL = pwmStop; pwmR = pwmStop;
  analogWrite(leftExtendPin, pwmL);
  analogWrite(leftRetractPin, pwmL);
  analogWrite(rightExtendPin, pwmR);
  analogWrite(rightRetractPin, pwmR);
}
//  -----------------------------------------------end of states  ---------------------------------------
[/code]

Should be const float stroke = 10.0; so that the stroke variable does not get accidently turned into an int.

I take it the issue is about b1Pin and b2Pin?

Try INPUT_PULLUP - I think the old way is to write HIGH to the pin after setting INPUT, just use the modern version to be sure.

a7

Yes and no. The issue relates to the b1 and b2 pins. Arduino recognizes they are triggered, but does not take the desired action until the exact 2nd time they are triggered. i.e. B1 gets pulled to high with 5v, release, pull again away we go. I will amend I forgot about the decimal.

Did you do as post#3 suggested? What are the results?

That updateBoomSwitchState() is intergral to checking the b1/2 switch states, it might be prudent to checkout the gate keeper if (leftExtending == false && leftRetracting == false) with a serial print.

such as

Serial.print( "leftExtending ");
Serial.print( leftExtending );
Serial.print( " leftRetracting " );
Serial.print( leftRetracting );
Serial.println();
if (leftExtending == false && leftRetracting == false)

may or may not provide useful information.

Do you have pulldown resistors on the button pins?

Yes I do have pulldown resistors, when I check Serial Print for the B1 and B2 pins, they function as expected.

I tried removing the if statement and just having

updateBoomSwitchState(); on it's own as the first line of the void loop. Made no difference.

Not yet - I will do that tomorrow. We were using the RowMower as part of a demonstration today I didn't want to mess with it too much. Will try tomorrow and see if it helps.

Could be switch bounce? Maybe try a debounce library like ezButton.
https://www.arduino.cc/reference/en/libraries/ezbutton/

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