ESP8266 Wemos D1 + windows blinds + servo too fast movement

Hi Everyone, this is my first post on this forum, I will be grateful for any help in my project.
I’m trying to build driver for my living room 5 windows blinds, I have temporarily installed servo on blinds so far. This installation is working except one little thing: the noise of servo, I know that by default servo is changing position as fast as it can do, but when I tested it in other test project in Arduino Leonardo with small delays added, it worked much quieter. I’ve used Rui Santos’ example, slightly modified to my concept. To move servo I just open prepared link i.e. http://192.168.100.214/set?slide1=2500 when last number is servo position i microseconds, this allows mi to run this script remotely from raspberry pi’s cron schedule (morning/evening).
Is there any simple solution to add some delay in moveServo function’s loop or should I find any other solution? I don’t need smooth movement with every microsecond, I think i.e. 10 steps will be sufficient. I’ve tried using millis() but it works only in main loop, I don’t know whether it’s possible or recommended to use millis() in functions outside main loop.
I will be very grateful for help.
Below is my code:

#include <Arduino.h>
#include <Servo.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>

Servo servo1;
Servo servo2;
AsyncWebServer server(80);


// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "";
const char* password = "";

const char* SLIDE_1 = "slide1";
const char* SLIDE_2 = "slide2";
const char* SEC_COUNT = "sec_count";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}


void moveServo(Servo &servoId, int destPos) {
  int curPos = servoId.readMicroseconds();
  Serial.println("curPos = " + String(curPos));
  Serial.println("destPos = " + String(destPos)); 
  
  if (curPos < destPos) {
    for (int i = curPos; i < destPos; i = i + 10) { 
      servoId.writeMicroseconds(i);
      }
  }
              
  else {
    // destPos = pozycja docelowa
    for (int i = curPos; i > destPos; i = i - 10) {
      servoId.writeMicroseconds(i);
      //Serial.println(String(i));
    }
  }

}

void setup() {
  Serial.begin(9600);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    //Serial.println("WiFi Failed!");
    return;
  }
 // Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
  
  

 servo1.attach(2); //d4
 servo2.attach(4); //d2

 server.on("/restart", HTTP_GET, [] (AsyncWebServerRequest *request) {
  ESP.restart();
  request->send(200, "text/html");
  });


  // Send a GET request to <ESP_IP>/set?input1=<inputMessage>
  server.on("/set", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    String inputParam;
    String servoPos;
    
    // GET input1 value on <ESP_IP>/set?input1=<inputMessage>
    if (request->hasParam(SLIDE_1)) {
      servoPos = request->getParam(SLIDE_1)->value();
      //servo1.writeMicroseconds(servoPos.toInt());
      moveServo(servo1, servoPos.toInt());
      inputParam = SLIDE_1;
    }

    else if (request->hasParam(SLIDE_2)) {
      servoPos = request->getParam(SLIDE_2)->value();
      servo2.writeMicroseconds(servoPos.toInt()); 
      inputParam = SLIDE_2;
    }
    
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    //Serial.println(inputMessage);
    
    request->send(200, "text/html");
  });

  server.on("/read", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    String inputParam;
    String servoPos;
    String Pos;
    
    if (request->hasParam(SLIDE_1)) {
      servoPos = request->getParam(SLIDE_1)->value();
      //Pos = servo1.read();
      Pos = servo1.readMicroseconds();
      
      inputParam = SLIDE_1;
    }

    else if (request->hasParam(SLIDE_2)) {
      servoPos = request->getParam(SLIDE_2)->value();
      //Pos = servo2.read();
      Pos = servo2.readMicroseconds();
      inputParam = SLIDE_2;
    }
    request->send(200, "text/html", Pos);
    });
  server.onNotFound(notFound);
  server.begin();
}

void loop() {
}

One simple way would be to make destPos for each servo global variables and check in loop whether any adjustment is needed. Use millis to make the change as slow as you like.

wildbill: You are my hero! :slight_smile: Thank you very much.
It was so simple, shame on me. Why didn’t I get the idea so far?
For testing purposes only I’ve put there the delay() function - yes, yes I know, I’m going to change it to millis() function later.
Now it’s time to think about power management…

Below is working code with silent moving servo.

#include <Arduino.h>
#include <Servo.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>



Servo servo1;
Servo servo2;
AsyncWebServer server(80);


// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "jrch_ap";
const char* password = "GiulBot47";

int curPos;
int destPos;


const char* SLIDE_1 = "slide1";
const char* SLIDE_2 = "slide2";
const char* SEC_COUNT = "sec_count";


void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

/*
void moveServo(Servo &servoId, int destPos) {
  curPos = servoId.readMicroseconds();
  Serial.println("curPos = " + String(curPos));
  Serial.println("destPos = " + String(destPos)); 
  
  if (curPos < destPos) {
    for (int i = curPos; i < destPos; i = i + 10) { 
      servoId.writeMicroseconds(i);
      }
  }
        
        
  else {
    // destPos = pozycja docelowa
    for (int i = curPos; i > destPos; i = i - 10) {
      servoId.writeMicroseconds(i);
      //Serial.println(String(i));
    }
  }

}
*/

void setup() {
  Serial.begin(9600);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    //Serial.println("WiFi Failed!");
    return;
  }
 // Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
  
  

 servo1.attach(2); //d4
 servo2.attach(4); //d2

 server.on("/restart", HTTP_GET, [] (AsyncWebServerRequest *request) {
  ESP.restart();
  request->send(200, "text/html");
  });


  // Send a GET request to <ESP_IP>/set?input1=<inputMessage>
  server.on("/set", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    String inputParam;
    String servoPos;
    
    // GET input1 value on <ESP_IP>/set?input1=<inputMessage>
    if (request->hasParam(SLIDE_1)) {
      servoPos = request->getParam(SLIDE_1)->value();
      //servo1.writeMicroseconds(servoPos.toInt());
      //moveServo(servo1, servoPos.toInt());
      destPos = servoPos.toInt();
      inputParam = SLIDE_1;
    }

    else if (request->hasParam(SLIDE_2)) {
      servoPos = request->getParam(SLIDE_2)->value();
      servo2.writeMicroseconds(servoPos.toInt()); 
      inputParam = SLIDE_2;
    }
    
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    //Serial.println(inputMessage);
    
    request->send(200, "text/html");
  });

  server.on("/read", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    String inputParam;
    String servoPos;
    String Pos;
    
    if (request->hasParam(SLIDE_1)) {
      servoPos = request->getParam(SLIDE_1)->value();
      //Pos = servo1.read();
      Pos = servo1.readMicroseconds();
      
      inputParam = SLIDE_1;
    }

    else if (request->hasParam(SLIDE_2)) {
      servoPos = request->getParam(SLIDE_2)->value();
      //Pos = servo2.read();
      Pos = servo2.readMicroseconds();
      inputParam = SLIDE_2;
    }
    request->send(200, "text/html", Pos);
    });
  server.onNotFound(notFound);
  server.begin();
}




void loop() {
curPos = servo1.readMicroseconds();
if (curPos < destPos) {
    for (int i = curPos; i <= destPos; i = i + 10) { 
      servo1.writeMicroseconds(i);
      delay(20);
      }
  }
        
        
  else {
    // destPos = pozycja docelowa
    for (int i = curPos; i >= destPos; i = i - 10) {
      servo1.writeMicroseconds(i);
      //Serial.println(String(i));
      delay(20);
    }
  }
  
}

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