limit switch code help needed

Hi all,

I am looking for a bit of help. I am looking at using two limit switches to stop a stepper motor and then set the motor counter to a certain number.

The reason for this is the device the motor is driving can be moved manually thus the stepper would not know where it is.

I have the code working as it should but the problem I am struggling with is, when the limit switch is pressed it sets the counter as it should but because the switch is still pressed when I try to control the stepper via MQTT it it won't move it just keeps resetting the counter.

#include <SimpleTimer.h>    //https://github.com/marcelloromani/Arduino-SimpleTimer/tree/master/SimpleTimer
#include <ESP8266WiFi.h>    //if you get an error here you need to install the ESP8266 board manager 
#include <ESP8266mDNS.h>    //if you get an error here you need to install the ESP8266 board manager 
#include <PubSubClient.h>   //https://github.com/knolleary/pubsubclient
#include <ArduinoOTA.h>     //https://github.com/esp8266/Arduino/tree/master/libraries/ArduinoOTA
#include <AH_EasyDriver.h>  //http://www.alhin.de/arduino/downloads/AH_EasyDriver_20120512.zip



#define USER_SSID                 
#define USER_PASSWORD             
#define USER_MQTT_SERVER          
#define USER_MQTT_PORT            1883
#define USER_MQTT_USERNAME        "mqtt"
#define USER_MQTT_PASSWORD        
#define USER_MQTT_CLIENT_NAME          ArduinoOTA

#define STEPPER_SPEED             35                  
#define STEPPER_STEPS_PER_REV     1028            
#define STEPPER_MICROSTEPPING     0              
#define DRIVER_INVERTED_SLEEP     1              

#define STEPS_TO_CLOSE            50              
#define STEPPER_DIR_PIN           D2
#define STEPPER_STEP_PIN          D1
#define STEPPER_SLEEP_PIN         D3
#define STEPPER_MICROSTEP_1_PIN   14
#define STEPPER_MICROSTEP_2_PIN   12
int OPEN_LIMIT_PIN = D5;
int CLOSE_LIMIT_PIN = D6;



WiFiClient espClient;
PubSubClient client(espClient);
SimpleTimer timer;
AH_EasyDriver shadeStepper(STEPPER_STEPS_PER_REV, STEPPER_DIR_PIN , STEPPER_STEP_PIN, STEPPER_MICROSTEP_1_PIN, STEPPER_MICROSTEP_2_PIN, STEPPER_SLEEP_PIN);

//Global Variables
bool boot = true;
int currentPosition = 0;
int newPosition = 0;
char positionPublish[50];
bool moving = false;
char charPayload[50];

const char* ssid = USER_SSID ;
const char* password = USER_PASSWORD ;
const char* mqtt_server = USER_MQTT_SERVER ;
const int mqtt_port = USER_MQTT_PORT ;
const char *mqtt_user = USER_MQTT_USERNAME ;
const char *mqtt_pass = USER_MQTT_PASSWORD ;
const char *mqtt_client_name = USER_MQTT_CLIENT_NAME ;




//Functions
void setup_wifi() {
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect()
{
  int retries = 0;
  while (!client.connected()) {
    if (retries < 150)
    {
      Serial.print("Attempting MQTT connection...");
      if (client.connect(mqtt_client_name, mqtt_user, mqtt_pass))
      {
        Serial.println("connected");
        if (boot == false)
        {
          client.publish(USER_MQTT_CLIENT_NAME"/checkIn", "Reconnected");
        }
        if (boot == true)
        {
          client.publish(USER_MQTT_CLIENT_NAME"/checkIn", "Rebooted");
        }
        // ... and resubscribe
        client.subscribe(USER_MQTT_CLIENT_NAME"/blindsCommand");
        client.subscribe(USER_MQTT_CLIENT_NAME"/positionCommand");
      }
      else
      {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");
        retries++;
        // Wait 5 seconds before retrying
        delay(5000);
      }
    }
    if (retries > 149)
    {
      ESP.restart();
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length)
{
  Serial.print("Message arrived [");
  String newTopic = topic;
  Serial.print(topic);
  Serial.print("] ");
  payload[length] = '\0';
  String newPayload = String((char *)payload);
  int intPayload = newPayload.toInt();
  Serial.println(newPayload);
  Serial.println();
  newPayload.toCharArray(charPayload, newPayload.length() + 1);
  if (newTopic == USER_MQTT_CLIENT_NAME"/blindsCommand")
  {
    if (newPayload == "OPEN")
    {
      client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", "0", true);
    }
    else if (newPayload == "CLOSE")
    {
      int stepsToClose = STEPS_TO_CLOSE;
      String temp_str = String(stepsToClose);
      temp_str.toCharArray(charPayload, temp_str.length() + 1);
      client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", charPayload, true);
    }
    else if (newPayload == "STOP")
    {
      String temp_str = String(currentPosition);
      temp_str.toCharArray(positionPublish, temp_str.length() + 1);
      client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", positionPublish, true);
    }
  }
  if (newTopic == USER_MQTT_CLIENT_NAME"/positionCommand")
  {
    if (boot == true)
    {
      newPosition = intPayload;
      currentPosition = intPayload;
      boot = false;
    }
    if (boot == false)
    {
      newPosition = intPayload;
    }
  }

}

void processStepper()
{
  if (newPosition > currentPosition)
  {
#if DRIVER_INVERTED_SLEEP == 1
    shadeStepper.sleepON();
#endif
#if DRIVER_INVERTED_SLEEP == 0
    shadeStepper.sleepOFF();
#endif
    shadeStepper.move(80, FORWARD);
    currentPosition++;
    moving = true;
  }
  if (newPosition < currentPosition)
  {
#if DRIVER_INVERTED_SLEEP == 1
    shadeStepper.sleepON();
#endif
#if DRIVER_INVERTED_SLEEP == 0
    shadeStepper.sleepOFF();
#endif
    shadeStepper.move(80, BACKWARD);
    currentPosition--;
    moving = true;
  }
  if (newPosition == currentPosition && moving == true)
  {
#if DRIVER_INVERTED_SLEEP == 1
    shadeStepper.sleepOFF();
#endif
#if DRIVER_INVERTED_SLEEP == 0
    shadeStepper.sleepON();
#endif
    String temp_str = String(currentPosition);
    temp_str.toCharArray(positionPublish, temp_str.length() + 1);
    client.publish(USER_MQTT_CLIENT_NAME"/positionState", positionPublish);
    moving = false;
  }
  Serial.println(currentPosition);
  Serial.println(newPosition);
}

void checkIn()
{
  client.publish(USER_MQTT_CLIENT_NAME"/checkIn", "OK");
}


//Run once setup
void setup() {
  Serial.begin(115200);

  pinMode(OPEN_LIMIT_PIN, INPUT);
  pinMode(CLOSE_LIMIT_PIN, INPUT);


  shadeStepper.setMicrostepping(STEPPER_MICROSTEPPING);            // 0 -> Full Step
  shadeStepper.setSpeedRPM(STEPPER_SPEED);     // set speed in RPM, rotations per minute
#if DRIVER_INVERTED_SLEEP == 1
  shadeStepper.sleepOFF();
#endif
#if DRIVER_INVERTED_SLEEP == 0
  shadeStepper.sleepON();
#endif
  WiFi.mode(WIFI_STA);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  ArduinoOTA.setHostname(USER_MQTT_CLIENT_NAME);
  ArduinoOTA.begin();
  delay(10);
  timer.setInterval(((1 << STEPPER_MICROSTEPPING) * 5800) / STEPPER_SPEED, processStepper);
  timer.setInterval(90000, checkIn);



}


void loop()
{
  if (!client.connected())
  {
    reconnect();
  }
  client.loop();
  ArduinoOTA.handle();
  timer.run();

  Serial.println(currentPosition);
  if ( (digitalRead(OPEN_LIMIT_PIN) == LOW) && (currentPosition > 0) )
  {
    newPosition = 0;
    currentPosition = newPosition;
    Serial.println(currentPosition);
    client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", positionPublish, true);

  }

  if ( (digitalRead(CLOSE_LIMIT_PIN ) == LOW) && (currentPosition < 50) )

{ close_limit ();
  }
  }


void close_limit ()

{
  newPosition = 50;
  currentPosition = newPosition;
  Serial.println(currentPosition);
  Serial.println("close");
  client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", positionPublish, true);
  digitalWrite(CLOSE_LIMIT_PIN, HIGH);
}

I tried putting the limit switch in void loop and creating it as a seperate function but got the same result.

Thanks in advance

When the switch is pressed, set a flag that prevents reading the switch again. Don't reset the flag until you are at a point where it is okay to test for the switch again.

How do you have your switches wired? Do you have a pullup resistor? Since you didn't configure the input with INPUT_PULLUP I assume you do.

What is the purpose for this line?

  digitalWrite(CLOSE_LIMIT_PIN, HIGH);

I suspect it doesn't do what you intend.

Hi I have changed the config to include input pullup.

that line was meant set the pin high when the program starts.

The switches are simply wired to an earth pin

Thanks

D4vew5577:
Hi I have changed the config to include input pullup.

that line was meant set the pin high when the program starts.

The switches are simply wired to an earth pin

Thanks

If you digitalWrite to an input it actually enables or disables the internal pull-up. That is not the preferred way to enable/disable the internal pull-up. Indeed, digitalWrite to an input other than in the setup() function is pretty much never needed and not a good idea. You should remove that line of code.