AccelStepper + wifi problem

Hello,

I have made a feeder for my aqua tank. It's a spinning wheel which is moved by a stepper. At the moment I can test it using serial commands. That works pretty well.
Here is the working code.

#include <AccelStepper.h>
#include <Servo.h>


#define dirPin 33
#define stepPin 32
#define motorInterfaceType 1
#define SERVO_PIN 26 // ESP32 pin GIOP26 connected to servo motor

Servo servoMotor;

String command;

const int MS1 = 14;
const int MS2 = 13;
const int MS3 = 12;
int MOTOR_STEPS = 200;

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);


const int sensorPin = 15;  //photoelectric pin
int lightInit;  // initial value
int lightVal;   // light reading
bool nulled = false;
bool executed = false;
bool going = false;

/*  Postions for boxes
  const int g1 = -260;
  const int g2 = -60;
  const int g3 = 175;
  const int g4 = 395;
  const int g5 = 600;
  const int b1 = -480;
  const int b2 = -695;
  const int b3 = -900;
  const int b4 = -1115;
  const int b5 = -1340;
  const int s1 = 795;
  const int s2 = 1005;
  const int s3 = 1220;
  const int s4 = 1433;
  const int s5 = 1650;
*/

void nullposition() {
  stepper.enableOutputs();
  lightVal = analogRead(sensorPin);
  Serial.println("go to null position");
  Serial.println(lightVal);
  stepper.setMaxSpeed(300);
  if (executed == false && lightVal > 300) {
    stepper.runToNewPosition(-100);
    Serial.println("executed - true");
    executed = true;
    delay(2000);
  }
  lightVal = analogRead(sensorPin); // read the current light levels


  stepper.moveTo(4000);
  while (lightVal < 300 && nulled != true) {// Full speed up to 300
    stepper.run();
    lightVal = analogRead(sensorPin); // read the current light levels

  }




  stepper.stop(); // Stop as fast as possible: sets new target
  stepper.runToPosition();
  stepper.setCurrentPosition(0);  //set steppercounter to 0 aufter reaching endstop switch
  nulled = true;
  Serial.println("null position set");
  Serial.println(stepper.currentPosition());
  stepper.setMaxSpeed(1000);
  stepper.disableOutputs();



  // delay(10);
}


void setup() {
  Serial.begin(115200);
  servoMotor.attach(SERVO_PIN);  // attaches the servo on ESP32 pin
  lightInit = analogRead(sensorPin);
  Serial.println(lightInit);
  stepper.setPinsInverted(false, false, true);
  stepper.setEnablePin(25);
  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(MS3, OUTPUT);
  digitalWrite(MS1, HIGH);
  digitalWrite(MS2, HIGH);
  digitalWrite(MS3, HIGH);


  // Set the maximum speed and acceleration:
  stepper.setMaxSpeed(1000);   //(1000)
  stepper.setAcceleration(1000);  //(1000)
  nullposition();

}

void moveposition() {
  stepper.enableOutputs();
  stepper.setMaxSpeed(1000);   //(1000)
  stepper.setAcceleration(1000);  //(1000)
  MOTOR_STEPS = command.toInt();

  if (nulled == true) {
    Serial.print("fahren");
    stepper.moveTo(MOTOR_STEPS);
    while (stepper.currentPosition() != MOTOR_STEPS) {
      stepper.run();
      Serial.println(stepper.currentPosition());
    }
    //   nulled = false;

    //stepper.disableOutputs();
  }
}

void empty()
{
  // rotates from 110 degrees to 0 degrees
  for (int pos = 110; pos >= 0; pos -= 1) {
    servoMotor.write(pos);
    delay(20); // waits 15ms to reach the position
  }
  for (int pos = 0; pos <= 110; pos += 1) {
    // in steps of 10 degree
    servoMotor.write(pos);
    delay(20); // waits 15ms to reach the position
  }
  //delay(5000);
  moveemptyposition();
}

void moveemptyposition() {
  stepper.enableOutputs();
  stepper.setMaxSpeed(1000);   //(1000)
  stepper.setAcceleration(1000);  //(1000)
  MOTOR_STEPS = stepper.currentPosition() - 850;
  stepper.moveTo(MOTOR_STEPS);
  while (stepper.currentPosition() != MOTOR_STEPS) {
    stepper.run();
    Serial.println(stepper.currentPosition());

  }

  MOTOR_STEPS = -200;
  stepper.moveTo(MOTOR_STEPS);
  while (stepper.currentPosition() != MOTOR_STEPS) {
    stepper.run();
    Serial.println(stepper.currentPosition());

  }
  nulled = false;
  nullposition();
}

void loop() {

  if (Serial.available()) {

    command = Serial.readStringUntil('\n');
    command.trim();
    Serial.print("you have typed: ");
    Serial.println(command);
    if (command.equals("99")) {
      //Serial.println("go to null position");
      nulled = false;
      nullposition();

    }
    else if (command.equals("999")) {
      empty();
    }
    else  {
      moveposition();
    }

  }

}

In future I want to trigger the events using MQTT. So it is necessary to add a wifi connection.
As soon as I connect the device to wifi, the serial commands do not work anymore and also for example the automated initial nullposition() to calibrate the device with using a photoelectric endstop switch does not work anymore. It starts moving but it does not stop passing the sensor.
I have removed everything additional in the code and found out that as soon as setup_wifi(); is executed, these things do not work anymore.
any suggestions?

here is the extended code:

#include <AccelStepper.h>
#include <Servo.h>
#include "WiFi.h"
#include <PubSubClient.h>
#include <WiFiUdp.h>

#define dirPin 33
#define stepPin 32
#define motorInterfaceType 1
#define SERVO_PIN 26 // ESP32 pin GIOP26 connected to servo motor
String temp = "";  //temporär
String packet = "";
String received = "";

Servo servoMotor;

//WIFI
const char *ssid     = "myssid";                                //your Wifi SSID
const char *password = "password";
const char* deviceName = "esp32_feeder";

String command;

const int MS1 = 14;
const int MS2 = 13;
const int MS3 = 12;
int MOTOR_STEPS = 200;

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

const short int LED_BUILTIN = 1; //GPIO1
const int sensorPin = 15;  //photoelectric pin
int lightInit;  // initial value
int lightVal;   // light reading
bool nulled = false;
bool executed = false;
bool going = false;
/*
  const int g1 = -260;
  const int g2 = -60;
  const int g3 = 175;
  const int g4 = 395;
  const int g5 = 600;
  const int b1 = -480;
  const int b2 = -695;
  const int b3 = -900;
  const int b4 = -1115;
  const int b5 = -1340;
  const int s1 = 795;
  const int s2 = 1005;
  const int s3 = 1220;
  const int s4 = 1433;
  const int s5 = 1650;
  String color;   // color reading
*/


const char* mqtt_server = "192.168.178.44";
const int mqttPort = 1883;
const char* mqttUser = "mosq";
const char* mqttPassword = "mqttpassword";
//mqtt ende

// WiFi connect timeout per AP. Increase when connecting takes longer.
const uint32_t connectTimeoutMs = 5000;
unsigned long previousMillis = 0;                   // will store last time updated
const long interval = 15000;                        // interval at which to run   muss 15000 sein
unsigned long previousMillisLED = 0;                // will store last time LED was updated
unsigned long intervalLED = 1000;                   // interval at which to blink (milliseconds)
int ledState = LOW;

WiFiClient espClient;
PubSubClient client(espClient);


void nullposition() {
  stepper.enableOutputs();
  lightVal = analogRead(sensorPin);
  Serial.println("go to null position");
  Serial.println(lightVal);
  stepper.setMaxSpeed(300);
  if (executed == false && lightVal > 300) {
    stepper.runToNewPosition(-100);
    Serial.println("executed - true");
    executed = true;
    delay(2000);
  }
  lightVal = analogRead(sensorPin); // read the current light levels


  stepper.moveTo(4000);
  while (lightVal < 300 && nulled != true) {// Full speed up to 300
    stepper.run();
    lightVal = analogRead(sensorPin); // read the current light levels

  }




  stepper.stop(); // Stop as fast as possible: sets new target
  stepper.runToPosition();
  stepper.setCurrentPosition(0);  //set steppercounter to 0 aufter reaching endstop switch
  nulled = true;
  Serial.println("null position set");
  Serial.println(stepper.currentPosition());
  stepper.setMaxSpeed(1000);
  stepper.disableOutputs();



  // delay(10);
}


void setup() {
  Serial.begin(115200);
  servoMotor.attach(SERVO_PIN);  // attaches the servo on ESP32 pin
  lightInit = analogRead(sensorPin);
  Serial.println(lightInit);

  setup_wifi();

  pinMode(LED_BUILTIN, OUTPUT); // Initialize the BUILTIN_LED1 pin as an output
  digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH
  stepper.setPinsInverted(false, false, true);
  stepper.setEnablePin(25);
  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(MS3, OUTPUT);
  digitalWrite(MS1, HIGH);
  digitalWrite(MS2, HIGH);
  digitalWrite(MS3, HIGH);

  /*
    client.setServer(mqtt_server, mqttPort);
    client.setCallback(callback);
    reconnect();
  */
  // Set the maximum speed and acceleration:
  stepper.setMaxSpeed(1000);   //(1000)
  stepper.setAcceleration(1000);  //(1000)
  nullposition();

}


void callback(char* topic, byte* payload, unsigned int length) {
  String sTopic = String(topic);
  Serial.print("topic empfangen: ");
  Serial.println(String(topic));


  if (sTopic == "aqua/received") {

    temp = "";

    for (int i = 0; i < length; i++) {
      temp += ((char)payload[i]);
    }
    received = temp;
    Serial.println(received);

  }

}

void setup_wifi() {


  WiFi.begin(ssid, password);

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

  Serial.println("Connected to the WiFi network");
}
void reconnect() {

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi not connected!");
    void setup_wifi();
  }
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    char clientid[25];
    snprintf(clientid, 25, "WIFI-Display-%08X", "12345"); //this adds the mac address to the client for a unique id
    Serial.print("Client ID: ");
    Serial.println(clientid);
    if (client.connect(clientid)) {
      Serial.println("connected");


      client.subscribe("aqua/received");

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 1 second before retrying
      delay(1000);
    }
  }
}
void moveposition() {
  nullposition();
  stepper.enableOutputs();

  stepper.setMaxSpeed(1000);   //(1000)
  stepper.setAcceleration(1000);  //(1000)
  MOTOR_STEPS = command.toInt();

  if (nulled == true) {
    Serial.print("fahren");
    stepper.moveTo(MOTOR_STEPS);
    while (stepper.currentPosition() != MOTOR_STEPS) {
      stepper.run();
      Serial.println(stepper.currentPosition());
    }
    //   nulled = false;

    //stepper.disableOutputs();
  }
}

void empty()
{
  // rotates from 110 degrees to 0 degrees
  for (int pos = 110; pos >= 0; pos -= 1) {
    servoMotor.write(pos);
    delay(20); // waits 15ms to reach the position
  }
  for (int pos = 0; pos <= 110; pos += 1) {
    // in steps of 10 degree
    servoMotor.write(pos);
    delay(20); // waits 15ms to reach the position
  }
  //delay(5000);
  moveemptyposition();
}

void moveemptyposition() {
  stepper.enableOutputs();
  stepper.setMaxSpeed(1000);   //(1000)
  stepper.setAcceleration(1000);  //(1000)
  MOTOR_STEPS = stepper.currentPosition() - 850;
  stepper.moveTo(MOTOR_STEPS);
  while (stepper.currentPosition() != MOTOR_STEPS) {
    stepper.run();
    Serial.println(stepper.currentPosition());

  }

  MOTOR_STEPS = -200;
  stepper.moveTo(MOTOR_STEPS);
  while (stepper.currentPosition() != MOTOR_STEPS) {
    stepper.run();
    Serial.println(stepper.currentPosition());

  }
  nulled = false;
  nullposition();
}

void loop() {

  if (Serial.available()) {

    command = Serial.readStringUntil('\n');
    command.trim();
    Serial.print("you have typed: ");
    Serial.println(command);
    if (command.equals("99")) {
      //Serial.println("go to null position");
      nulled = false;
      nullposition();

    }
    else if (command.equals("999")) {
      empty();
    }
    else  {
      moveposition();
    }

  }
  /*
    if (WiFi.status() == WL_CONNECTED) {                            //blink blue LED while wifi is connected

      unsigned long currentMillisLED = millis();

      if (currentMillisLED - previousMillisLED > intervalLED) {
        // save the last time you blinked the LED
        previousMillisLED = currentMillisLED;
        ledState = !ledState;
        // if the LED is off turn it on and vice-versa:
        if (ledState == HIGH) {
          digitalWrite(BUILTIN_LED1, LOW);
          intervalLED = 100;
        } else {
          digitalWrite(BUILTIN_LED1, HIGH);
          intervalLED = 3000;
        }
      }
    }
  */
  // reconnect();


  /*
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {

      Serial.print("received momentan: ");
      Serial.println(received);
    if (received == "true") {
      //measure();

      Serial.print("received jetzt: ");
      Serial.println(received);
      Serial.println("publish werte zu smartphone");
    //  client.publish("aqua/display/temperatur", tempStringaqua);
    //  client.publish("aqua/display/zeit", t.c_str());
      received = "false";

    }
     previousMillis = currentMillis;
    }

  */
  // client.loop();

}


void convert2Json()
{
  // Temperature in Celsius

  packet = "";


  packet.concat(("{\"temp\": "));
  // packet.concat(temperature);


  packet.concat("}");
  Serial.println(packet);
  //client.publish("sensors/room/aqua", packet.c_str());
  Serial.println("sensors/room/aqua  published");
}


some of the code can take a long time like

may be adding a yield() during long operations to give a chance to the WiFi activity to happen and pat the watchdog would be good

Hm, the WiFi thing happens before that step and is successful.
The motor also starts spinning at exactly this point but it does not stop anymore by passing the photoelectric sensor.
I so not know why.
And where exactly should i add that yield?

I would say anywhere you have something taking time in a blocking way and no call to delay()

but it's just a guess, may be AccelStepper does call yield() for you

OK, understood.
Do you have any Idea why in the first code it is possible to make command inputs using the serial monitor interface and by using the 2nd code it just does not Work anymore?

I don't know for sure

you use for example Serial.readStringUntil('\n'); which blocks and has a builtin timeout so you can get part of a command if the timeout kicks in (I don't know how commands are sent (Serial monitor ?) and then when you come back you get the rest of the command...

I would recommend against using those builtin functions and suggest to study Serial Input Basics to handle the input in a non blocking way

Of course I trust you have selected suitable pins that are not related to the WiFi or Serial connection for your setup on your board ? (which board did you pick ?)

Maybe your Idea with the board leads in the right direction. It's a regular esp32 Dev board with 38 Pins

Oh, I have found an interesting case:

That could be the case. I will check that in about 15 minutes.

hey man,
thank you for all your suggestions. In the end it was the thing that you can't use ADC2 pins to make analog reads during wifi is enabled.

great - so using the wrong pin.

those are catchy indeed as many pins have specific usage

maybe you can have a look at this: Logical question (easy) ;)

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