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