Stepper starts to move when power i pluged in

Im trying to control a stepper motor with a nodemcu hooked to it. I also have a buck converter added in the wireing.

The problem is that when i plug in the power the motor will start to move until I stop it manually witch i think is very odd. I dont want it to do that.
Apart from this the motor and control interface works as intended. I can set max min position and start and stop it as intended.

I have attached the wireing along with the code.

I have not made the code it is taken from a project from here: Motor on a roller blind by pgote - Thingiverse

28BYJ-48 stepper motor
Buck converter

Anyone that can explain why it starts to move when it gets power?

Code split in two posts because it extends the max character allowed in forum…

#include <Stepper_28BYJ_48.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <PubSubClient.h>
#include <WiFiUdp.h>
#include <WiFiManager.h>
#include <ArduinoJson.h>
#include "FS.h"
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <WebSocketsServer.h>
#include <ArduinoOTA.h>
#include "NidayandHelper.h"
#include "index_html.h"

//--------------- CHANGE PARAMETERS ------------------
//Configure Default Settings for Access Point logon
String APid = "BlindsConnectAP";    //Name of access point
String APpw = "nidayand";           //Hardcoded password for access point


// Version number for checking if there are new code releases and notifying the user
String version = "1.3.1";

NidayandHelper helper = NidayandHelper();

//Fixed settings for WIFI
WiFiClient espClient;
PubSubClient psclient(espClient);   //MQTT client
char mqtt_server[40];             //WIFI config: MQTT server config (optional)
char mqtt_port[6] = "1883";       //WIFI config: MQTT port config (optional)
char mqtt_uid[40];             //WIFI config: MQTT server username (optional)
char mqtt_pwd[40];             //WIFI config: MQTT server password (optional)

String outputTopic;               //MQTT topic for sending messages
String inputTopic;                //MQTT topic for listening
boolean mqttActive = true;
char config_name[40];             //WIFI config: Bonjour name of device
char config_rotation[40] = "false"; //WIFI config: Detault rotation is CCW

String action;                      //Action manual/auto
int path = 0;                       //Direction of blind (1 = down, 0 = stop, -1 = up)
int setPos = 0;                     //The set position 0-100% by the client
long currentPosition = 0;           //Current position of the blind
long maxPosition = 2000000;         //Max position of the blind. Initial value
boolean loadDataSuccess = false;
boolean saveItNow = false;          //If true will store positions to SPIFFS
bool shouldSaveConfig = false;      //Used for WIFI Manager callback to save parameters
boolean initLoop = true;            //To enable actions first time the loop is run
boolean ccw = true;                 //Turns counter clockwise to lower the curtain

Stepper_28BYJ_48 small_stepper(D1, D3, D2, D4); //Initiate stepper driver

ESP8266WebServer server(80);              // TCP server at port 80 will respond to HTTP requests
WebSocketsServer webSocket = WebSocketsServer(81);  // WebSockets will respond on port 81

bool loadConfig() {
  if (!helper.loadconfig()){
    return false;
  JsonVariant json = helper.getconfig();

  //Store variables locally
  currentPosition = long(json["currentPosition"]);
  maxPosition = long(json["maxPosition"]);
  strcpy(config_name, json["config_name"]);
  strcpy(mqtt_server, json["mqtt_server"]);
  strcpy(mqtt_port, json["mqtt_port"]);
  strcpy(mqtt_uid, json["mqtt_uid"]);
  strcpy(mqtt_pwd, json["mqtt_pwd"]);
  strcpy(config_rotation, json["config_rotation"]);

  return true;

   Save configuration data to a JSON file
   on SPIFFS
bool saveConfig() {
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& json = jsonBuffer.createObject();
  json["currentPosition"] = currentPosition;
  json["maxPosition"] = maxPosition;
  json["config_name"] = config_name;
  json["mqtt_server"] = mqtt_server;
  json["mqtt_port"] = mqtt_port;
  json["mqtt_uid"] = mqtt_uid;
  json["mqtt_pwd"] = mqtt_pwd;
  json["config_rotation"] = config_rotation;

  return helper.saveconfig(json);

   Connect to MQTT server and publish a message on the bus.
   Finally, close down the connection and radio
void sendmsg(String topic, String payload) {
  if (!mqttActive)

  helper.mqtt_publish(psclient, topic, payload);

void processMsg(String res, uint8_t clientnum){
     Check if calibration is running and if stop is received. Store the location
  if (action == "set" && res == "(0)") {
    maxPosition = currentPosition;
    saveItNow = true;

     Below are actions based on inbound MQTT payload
  if (res == "(start)") {
       Store the current position as the start position
    currentPosition = 0;
    path = 0;
    saveItNow = true;
    action = "manual";
  } else if (res == "(max)") {
       Store the max position of a closed blind
    maxPosition = currentPosition;
    path = 0;
    saveItNow = true;
    action = "manual";
  } else if (res == "(0)") {
    path = 0;
    saveItNow = true;
    action = "manual";
  } else if (res == "(1)") {
       Move down without limit to max position
    path = 1;
    action = "manual";
  } else if (res == "(-1)") {
       Move up without limit to top position
    path = -1;
    action = "manual";
  } else if (res == "(update)") {
    //Send position details to client
    int set = (setPos * 100)/maxPosition;
    int pos = (currentPosition * 100)/maxPosition;
    sendmsg(outputTopic, "{ \"set\":"+String(set)+", \"position\":"+String(pos)+" }");
    webSocket.sendTXT(clientnum, "{ \"set\":"+String(set)+", \"position\":"+String(pos)+" }");
  } else if (res == "(ping)") {
    //Do nothing
  } else {
       Any other message will take the blind to a position
       Incoming value = 0-100
       path is now the position
    path = maxPosition * res.toInt() / 100;
    setPos = path; //Copy path for responding to updates
    action = "auto";

    int set = (setPos * 100)/maxPosition;
    int pos = (currentPosition * 100)/maxPosition;

    //Send the instruction to all connected devices
    sendmsg(outputTopic, "{ \"set\":"+String(set)+", \"position\":"+String(pos)+" }");
    webSocket.broadcastTXT("{ \"set\":"+String(set)+", \"position\":"+String(pos)+" }");

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
    switch(type) {
        case WStype_TEXT:
            Serial.printf("[%u] get Text: %s\n", num, payload);

            String res = (char*)payload;

            //Send to common MQTT and websocket function
            processMsg(res, num);
void mqttCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print("] ");
  String res = "";
  for (int i = 0; i < length; i++) {
    res += String((char) payload[i]);
  processMsg(res, NULL);

  Turn of power to coils whenever the blind
  is not moving
void stopPowerToCoils() {
  digitalWrite(D1, LOW);
  digitalWrite(D2, LOW);
  digitalWrite(D3, LOW);
  digitalWrite(D4, LOW);

   Callback from WIFI Manager for saving configuration
void saveConfigCallback () {
  shouldSaveConfig = true;

void handleRoot() {
  server.send(200, "text/html", INDEX_HTML);
void handleNotFound(){
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  server.send(404, "text/plain", message);


Please attach code and wiring the way told in the advicing topics like “How to use the Forum”, “How to attach code”.
I do have a clear idea but wait for Your code, in the topic, using code tags.

Second part:

void setup(void)
  Serial.print("Starting now\n");

  //Reset the action
  action = "";

  //Set MQTT properties
  outputTopic = helper.mqtt_gettopic("out");
  inputTopic = helper.mqtt_gettopic("in");

  //Set the WIFI hostname

  //Define customer parameters for WIFI Manager
  WiFiManagerParameter custom_config_name("Name", "Bonjour name", config_name, 40);
  WiFiManagerParameter custom_rotation("Rotation", "Clockwise rotation", config_rotation, 40);
  WiFiManagerParameter custom_text("<p><b>Optional MQTT server parameters:</b></p>");
  WiFiManagerParameter custom_mqtt_server("server", "MQTT server", mqtt_server, 40);
  WiFiManagerParameter custom_mqtt_port("port", "MQTT port", mqtt_port, 6);
  WiFiManagerParameter custom_mqtt_uid("uid", "MQTT username", mqtt_server, 40);
  WiFiManagerParameter custom_mqtt_pwd("pwd", "MQTT password", mqtt_server, 40);
  WiFiManagerParameter custom_text2("<script>t = document.createElement('div');t2 = document.createElement('input');t2.setAttribute('type', 'checkbox');t2.setAttribute('id', 'tmpcheck');t2.setAttribute('style', 'width:10%');t2.setAttribute('onclick', \"if(document.getElementById('Rotation').value == 'false'){document.getElementById('Rotation').value = 'true'} else {document.getElementById('Rotation').value = 'false'}\");t3 = document.createElement('label');tn = document.createTextNode('Clockwise rotation');t3.appendChild(t2);t3.appendChild(tn);t.appendChild(t3);document.getElementById('Rotation').style.display='none';document.getElementById(\"Rotation\").parentNode.insertBefore(t, document.getElementById(\"Rotation\"));</script>");
  //Setup WIFI Manager
  WiFiManager wifiManager;

  //reset settings - for testing
  //clean FS, for testing

  //add all your parameters here

  wifiManager.autoConnect(APid.c_str(), APpw.c_str());

  //Load config upon start
  if (!SPIFFS.begin()) {
    Serial.println("Failed to mount file system");

  /* Save the config back from WIFI Manager.
      This is only called after configuration
      when in AP mode
  if (shouldSaveConfig) {
    //read updated parameters
    strcpy(config_name, custom_config_name.getValue());
    strcpy(mqtt_server, custom_mqtt_server.getValue());
    strcpy(mqtt_port, custom_mqtt_port.getValue());
    strcpy(mqtt_uid, custom_mqtt_uid.getValue());
    strcpy(mqtt_pwd, custom_mqtt_pwd.getValue());
    strcpy(config_rotation, custom_rotation.getValue());

    //Save the data

     Try to load FS data configuration every time when
     booting up. If loading does not work, set the default
  loadDataSuccess = loadConfig();
  if (!loadDataSuccess) {
    currentPosition = 0;
    maxPosition = 2000000;

    Setup multi DNS (Bonjour)
  if (MDNS.begin(config_name)) {
    Serial.println("MDNS responder started");
    MDNS.addService("http", "tcp", 80);
    MDNS.addService("ws", "tcp", 81);

  } else {
    Serial.println("Error setting up MDNS responder!");
    while(1) {
  Serial.print("Connect to http://"+String(config_name)+".local or http://");

  //Start HTTP server
  server.on("/", handleRoot);

  //Start websocket

  /* Setup connection for MQTT and for subscribed
    messages IF a server address has been entered
  if (String(mqtt_server) != ""){
    Serial.println("Registering MQTT server");
    psclient.setServer(mqtt_server, String(mqtt_port).toInt());

  } else {
    mqttActive = false;
    Serial.println("NOTE: No MQTT server address has been registered. Only using websockets");

  /* Set rotation direction of the blinds */
  if (String(config_rotation) == "false"){
    ccw = true;
  } else {
    ccw = false;

  //Update webpage

  //Setup OTA
    // Authentication to avoid unauthorized updates


    ArduinoOTA.onStart([]() {
    ArduinoOTA.onEnd([]() {
    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    ArduinoOTA.onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
      else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
      else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
      else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
      else if (error == OTA_END_ERROR) Serial.println("End Failed");

void loop(void)
  //OTA client code

  //Websocket listner

    Serving the webpage

  //MQTT client
  if (mqttActive){
    helper.mqtt_reconnect(psclient, mqtt_uid, mqtt_pwd, { inputTopic.c_str() });

    Storing positioning data and turns off the power to the coils
  if (saveItNow) {
    saveItNow = false;

      If no action is required by the motor make sure to
      turn off all coils to avoid overheating and less energy


    Manage actions. Steering of the blind
  if (action == "auto") {
       Automatically open or close blind
    if (currentPosition > path){
      small_stepper.step(ccw ? -1: 1);
      currentPosition = currentPosition - 1;
    } else if (currentPosition < path){
      small_stepper.step(ccw ? 1 : -1);
      currentPosition = currentPosition + 1;
    } else {
      path = 0;
      action = "";
      int set = (setPos * 100)/maxPosition;
      int pos = (currentPosition * 100)/maxPosition;
      webSocket.broadcastTXT("{ \"set\":"+String(set)+", \"position\":"+String(pos)+" }");
      sendmsg(outputTopic, "{ \"set\":"+String(set)+", \"position\":"+String(pos)+" }");
      Serial.println("Stopped. Reached wanted position");
      saveItNow = true;

 } else if (action == "manual" && path != 0) {
       Manually running the blind
    small_stepper.step(ccw ? path : -path);
    currentPosition = currentPosition + path;

     After running setup() the motor might still have
     power on some of the coils. This is making sure that
     power is off the first time loop() has been executed
     to avoid heating the stepper motor draining
     unnecessary current
  if (initLoop) {
    initLoop = false;

Okey, the code is huge.
Check the terms that makes the stepper run. Use Serial monitor and serial.print at every place the stepper is activated and tell "Now at stepper move pos 1" etc.

You use a quite costly memory usage for ex. action defined as string. Why not define it as a byte and define the different types of action as "#define auto 0", #define manual 1" etc. Then test "if( action == auto)". Never mind, that's not the cause of the fauöt as I can see.

How much experience do you have with Web-servers, MQTT, and HTML?

You have a huge chunk of "ripped" code and you are having a simple problem. GENERALLY, when i start a complex project like this, I break it into parts that i can perfect, then try to incorporate the "pieces" into a project.

I LOVE my NodeMCU's, but this is some deep stuff. You got about 100 things going on here. I've never used MQTT, but this seems a little complex if all you want to do run a motor forward or reverse using a web page.

It seems to me you could use HTML "buttons" or a "Slider" on the web page and just move it from fully closed to fully open or anywhere in-between much easier. BTW, I"m not saying I know how to do it, but it seems simplest.

take a look at this:

Download this code, hook up your Stepper and you can control anything you couple the stepper to...