Using Switches

Hello. I am working on a project where I am using a switch to control a linear actuator. The problem I am having is I want the actuator to stop moving when the switch is released. Basically exit the loop when the switch is open but the the program still runs through the loop before it stops. I know there’s an easy way to do this, I just can’t get it to work. Thanks.

What have you searched for, or written so far?

It sounds like you want a [u]while() loop[/u] that loops & runs the motor while the switch is pressed. Or, an if-statement to [u]break[/u] out of the loop.

Be careful if you’re using delay() because it can’t read the switch during the delay.

while loops are almost never the answer for waiting for something to physically happen because they block the execution of the rest of your program. while loops are best for things like walking through an array or iterating through a list of numbers. When dealing with physical things happening it is usually best to write state-ful code like a state machine that can keep running while keeping track of the thing you want to wait on.

void loop(){

  if(theSwitchIsNotMade){
        runThe Motor();
  }
   else {
        stopTheMotor();
   }

  //  Do other things. 
}

Arduino IDE

void loop() { }

runs whatever is in it over and over.

It is best to use that to detect events and drive actions especially once you want to do more than one thing at a time.

A contact switch/button has a real world trait of sparking just before the contacts close or just after they open. The name for that is bounce. You can get rid of it by soldering a 1 uF cap across the switch connections or with code. If you go with code then in loop you have one part that only reads the switch and determines if the pin is stable before setting a variable that the motor code part will see as switch-on or switch-off and get nothing during the few milliseconds of bouncing instead of several on-off bounce-events. The code for the switch filters all that out, the motor only sees definite for-sure user choices which really simplifies the motor code.

If you have a capacitor that can work to debounce the switch, it will save you coding now.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

How have you got your switch wired, if it switches to 5V, have you got a 10K resisitor between the Arduino digital input pin and gnd to pull it to gnd when the switch is open.
Or if you are switching to gnd, in the code turn the INPUT_PULLUP resistors on.

You cannot leave an input pin open circuit as it will keep its last state and then begin to pickup noise.

Tom... :slight_smile:

const int buttonPin = 2;
const int fwdPin = 6;
const int revPin = 7;
int buttonState = 0;

void setup() 
{
  pinMode(buttonPin,INPUT_PULLUP);
  pinMode(fwdPin,OUTPUT);
  pinMode(revPin,OUTPUT);
  digitalWrite(fwdPin,LOW);
  digitalWrite(revPin,LOW);
}


void loop() {
  buttonState = digitalRead(buttonPin);
  if(digitalRead(buttonPin) == LOW){
  digitalWrite(fwdPin,HIGH);   
  delay(3500);                       
  digitalWrite(fwdPin,LOW);
  delay(1000);
  digitalWrite(revPin,HIGH);    
  delay(3500);
  digitalWrite(revPin,LOW);
  delay(500);
  }
  
  else {
  digitalWrite(fwdPin,LOW);
  digitalWrite(revPin,LOW);
  }
  
}

Hi,
The problem is you are using delay statements, these STOP the code for the duration of the delay parameter.
In your code when you press the button, the button is not read again for 3500 + 1000 + 3500 + 500 = 8500ms
or 8.5 Seconds.

You need to look in the IDE examples for "Blink without Delay" example that will show you how to use millis instead of the delay function.

Tom... :slight_smile:

LoJack:

const int buttonPin = 2;

const int fwdPin = 6;
const int revPin = 7;
int buttonState = 0;

void setup()
{
  pinMode(buttonPin,INPUT_PULLUP);
  pinMode(fwdPin,OUTPUT);
  pinMode(revPin,OUTPUT);
  digitalWrite(fwdPin,LOW);
  digitalWrite(revPin,LOW);
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if(digitalRead(buttonPin) == LOW){
  digitalWrite(fwdPin,HIGH); 
  delay(3500);                     
  digitalWrite(fwdPin,LOW);
  delay(1000);
  digitalWrite(revPin,HIGH);   
  delay(3500);
  digitalWrite(revPin,LOW);
  delay(500);
  }
 
  else {
  digitalWrite(fwdPin,LOW);
  digitalWrite(revPin,LOW);
  }
 
}

As long as you only want to do one thing at a time, it's okay.
Suppose you want the next press to stop the sequence before it's done? Ooops.

Check out
http://gammon.com.au/blink

I am missing the need for most of this.

void loop() 
{
  buttonState = digitalRead(buttonPin);
  digitalWrite(fwdPin,!buttonState);   //  if the relay works opposite, then remove the !
                   
}  /// END OF LOOP

What I need is for the motor to move forward for 3.5 seconds then reverse for 3.5 seconds when a switch is pressed. I also need it to stop what it's doing whether it's moving forward or reversing as soon as the switch is released

[
const int buttonPin = 2;
const int fwdPin = 6;
const int revPin = 7;
int buttonState = HIGH;
unsigned long previousMillis = 0 ;
const long interval = 3500;

void setup() 
{
  pinMode(buttonPin,INPUT_PULLUP);
  pinMode(fwdPin,OUTPUT);
  pinMode(revPin,OUTPUT);
  digitalWrite(fwdPin,LOW);
  digitalWrite(revPin,LOW);
}


void loop() {
unsigned long currentMillis = millis();
  buttonState = digitalRead(buttonPin);
  if (currentMillis - previousMillis >= interval){
  previousMillis = currentMillis;
 if(digitalRead(buttonPin) == LOW){
 digitalWrite(fwdPin,HIGH);                        
 digitalWrite(fwdPin,LOW);
 //digitalWrite(revPin,HIGH);    
 //digitalWrite(revPin,LOW);
 }
  
  else {
  digitalWrite(fwdPin,LOW);
  digitalWrite(revPin,LOW);
  }
  digitalWrite(buttonPin, buttonState);
  }
}
    
      
/code]

in other words, (reading your words, not the code) - if the button is pressed, move forward (3.5s), then back (3.5s) maximum., BUT if the button is released at any time, forget all of that and just stop whenever you are?

Doesn’t really sound like what you want, does it?
Can you slow down, and explained what you are really trying to achieve.

That's exactly what I need to achieve. Button is pressed, move forward for 3.5s then back 3.5s. If the switch is released at any time I need the motor to stop. This is for safety reasons. The motor is inside a fixture and when you close the door it pressed the switch. But if the operator opens the door for any reason, I need the motor to stop to avoid injury.

LoJack:
That's exactly what I need to achieve. Button is pressed, move forward for 3.5s then back 3.5s. If the switch is released at any time I need the motor to stop. This is for safety reasons. The motor is inside a fixture and when you close the door it pressed the switch. But if the operator opens the door for any reason, I need the motor to stop to avoid injury.

You are trying to make a DEADMAN switch.

Closing the door should not start the process.
You need a START button for the operator to hold down that is interlocked with the doors.

So you are trying to implement a SAFETY DEVICE , you do not do this in software, you do it in HARDWARE.
You need to make the action of opening the door DISCONNECT the POWER form the actuator power supply, as well as stop the process in software, so that even a software failure will not make the actuator operate.

In fact if this machine is capable of injuring someone you should have a readily accessible EMERGENCY STOP BUTTON.

If this is in an industrial situation there will/should be regulations or company protocol about safety of machines and how it is implemented.

Tom... :slight_smile:

Thanks Tom. That’s what I ended up doing. I thought it might be faster and easier to do in the software, but you were right about needing to do it in the hardware.

Good work getting it solved!

There are combinations of tech to do what you want, but Tom is perfectly correct.
As well as a dead-man switch or emergency stop, the underlying principal is a SAFETY INTERLOCK to prevent damage or injury.

An Arduino can assist with this, or raise alarms etc, but must not be the final device to stop you losing a finger or hand.

on the larger machines, there are two start buttons. more than 4 feet apart.
you must have your hands on both to start. that means your hands cannot be in the machine.