Limit Switch Reset

I am working on a program to run a motor with at timer. The motor runs until a limit switch is triggered. The motor then waits for the next timer interval and then proceeds again until the limit switch is triggered.

My problem is this. I am using one limit switch that stops the motor when it goes to a High reading - this works fine already. The switch state must then be reset to Low by code for the motor to proceed when the timer says start (as the switch is initially still triggered High at the motor restart). I am certain I need to use a switch state type code but I am drawing a blank on how to do it. The switch is on Pin 2 and I have the variables SwitchState and LastSwitchState but i just cant seem to work out the logic. Any help would be most appreciated.

T

Please read this:-
How to use this forum

Now post your schematic and what you have written so far.

In addition to what @Grumpy_Mike has said ...

Let's assume the motor is moving in direction A when it triggers the limit switch.
Presumably the next move will require the motor to run in the opposite direction (direction B) away from the limit switch ?

If the limit switch is just used by your software (i.e. it does NOT directly cut power to the motor) your code should be able to ignore the switch setting when the motor is to move in direction B. That will allow the switch to unset when the motor moves away from it.

What is to stop it running too far in direction B?

...R

I will post the code shortly but I am running the motor in the same direction past the limit switch. The switch just stops it at location A then it must move on to location B in the same direction triggered by the timer.

The switch is wired to trigger a pin not cut the power.

T

doctjh:
I will post the code shortly but I am running the motor in the same direction past the limit switch. The switch just stops it at location A then it must move on to location B in the same direction triggered by the timer.

That does not sound like a "limit" to me - perhaps a "location" switch :slight_smile:

In any case ...

Does the program "know" that the motor has not yet reached A ?
If so you can set a flag variable when A is reached and happily ignore switch A and move on to B if the flag is set.

...R

Hi,

  1. Motor hits location switch.
  2. TIMER turns ON, MOTOR turned OFF
  3. TIMER period ends.
    4, MOTOR turned ON.
  4. LOOP back to 1.

You just need to know when the switch changes state when the motor hits it.

Tom.... :slight_smile:

Here is the codes for the motor timer and location switch. I am using a motor adafruit motor shield and the limit switch on pin 2. I am just using a simple timer as a test at this stage.

/*
Limit swith and stepping motor code StepperTestrev4
*/

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();

// A stepper motor with 200 steps per revolution (1.8 degree)
// connected to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

const int SWITCH=2; //The Button is connected to pin 2
boolean timerstate; //timer state variable
boolean check; //timer state variable
int SwitchState = 0;
int LastSwitchState = 0;
unsigned long StartTime;

void setup()
{

pinMode (SWITCH, INPUT); //Set button as input (not required)
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("Stepper test!");

AFMS.begin(); // create with the default frequency 1.6KHz
//AFMS.begin(1000); // OR with a different frequency, say 1KHz

myMotor->setSpeed(10); // 10 rpm

}

void loop() {

timersub(); // check timer

while (timerstate == true) //could also be if loop
{
switchsub(); //check status of limit switch

}

}

int switchsub() {

SwitchState = digitalRead(SWITCH); // 0 is low (run) and 1 is high (stop) this line is not used

if (digitalRead(SWITCH) == LOW)
{
Serial.println(SwitchState);
myMotor->step(1, FORWARD, DOUBLE); //if switch is not triggered run motor

}
else
{
Serial.println("STOP");
Serial.println(SwitchState);
delay(500);
myMotor->release(); // release motor - stop if switch is triggered
timerstate=false; // reset timer
}
return timerstate;
}

int timersub() {

StartTime = millis()/1000; // simple timer test to start motor at two times - just placeholder
Serial.print("Time ");
Serial.println(StartTime);

if ((StartTime == 5) || (StartTime == 30)) {
timerstate = true;

}

return timerstate;
}

Hi,
Have you got a pull-high or pull-low resistor on the location switch, so that when the switch is open the input pin is not floating?

Tom... :slight_smile:

doctjh:
Here is the codes for the

If you have looked through a few other Forum Threads (you should do) you will have seen that code should look like this.

Please edit your post and use the code button </> to display your code properly so we can easily select it and copy it to a text editor.

...R

Yes I have a pull up resistor.

Sorry for entering my code in a sloppy manner - i don't do this very often and i could not find the button for it! (Yes I now realize it is the first button!).

Thanks
T

/*
Limit swith and stepping motor code StepperTestrev4
*/

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 

// A stepper motor with 200 steps per revolution (1.8 degree)
// connected to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

const int SWITCH=2;      //The Button is connected to pin 2
boolean timerstate;      //timer state variable
boolean check;      //timer state variable
int SwitchState = 0;
int LastSwitchState = 0;
unsigned long StartTime;

void setup()
{

  pinMode (SWITCH, INPUT);   //Set button as input (not required)
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Stepper test!");

  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  
  myMotor->setSpeed(10);  // 10 rpm   

}


void loop() {
  
  
  timersub(); // check timer
  
  
  while (timerstate == true)  //could also be if loop
  {
    switchsub(); //check status of limit switch

  }

  
}

int switchsub() {

  SwitchState = digitalRead(SWITCH);  // 0 is low (run) and 1 is high (stop) this line is not used
  
    
  
  if (digitalRead(SWITCH) == LOW)
  {
    Serial.println(SwitchState);
    myMotor->step(1, FORWARD, DOUBLE); //if switch is not triggered run motor
  
  }
  else
  {
    Serial.println("STOP");
    Serial.println(SwitchState);
    delay(500);
    myMotor->release(); // release motor - stop if switch is triggered
    timerstate=false; // reset timer
  }
  return timerstate; 
}

int timersub() {
    
    StartTime = millis()/1000;  // simple timer test to start motor at two times - just placeholder
    Serial.print("Time ");
    Serial.println(StartTime);    
    
    if ((StartTime == 5) || (StartTime == 30)) {
      timerstate = true;

    }
 
      
   return timerstate; 
}

Don't treat millis() as a fixed value. It continually changes for 49 days. You need to work with the difference. Also, it is much easier to work directly with the millis() value rather than converting it to seconds.

Look at how millis() is used to manage time in the demo several things at a time. Don't use WHILE for anything that takes more than a few millisecs. Just use the natural repeat of loop() to keep things going. Ensure that loop() can repeat as often as possible - hundreds or thousands of times per second.

If I understand things,

  • you want the motor to move until it triggers the switch.
  • Then you want it to wait for a period.
  • Then you want it to continue moving in the same direction until it triggers another switch.

The way to do that is

  • start the motor moving.
  • When the switch is triggered stop the motor and save the value of millis()
  • Keep checking the value of millis() until the difference from the saved value exceeds the interval
  • Start the motor moving again

...R