Esp8266 Window Blinds MQTT

So my blinds actually have a twist rod to manually rotate them, I assume this will still work?

Something like this:
https://i.ytimg.com/vi/tlkX1HtAMOE/maxresdefault.jpg

Yes, it works the same. Just make sure you bought the correct servo adapter for your rod thickness.

Have a look at the wemos D1 Minis, they have power sheilds you can buy.
The d1 mini is the same esp8266 as the Nodemcu just less pins

I used this code and adapted it to my coffee maker, somewhat successfully. Robot Coffee Maker!

Hello, i am still learning a lot about HA and arduino code.
I have my tilt blinds currently working with the following code.

 *  Contains code from: 
 *  https://github.com/jjhtpc/esp8266MQTTBlinds
 */

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <Servo.h>
#include <ArduinoOTA.h>

MDNSResponder mdns;
ESP8266WebServer server(80);

#include <PubSubClient.h>

#define wifi_ssid "FRITZ!Box 7369" // Enter your WIFI SSID
#define wifi_password "92046947804299306590" // Enter your WIFI Password

#define mqtt_server "10.0.0.47" // Enter your MQTT server IP. 
#define mqtt_user "arnold" // Enter your MQTT username
#define mqtt_password "sandra" // Enter your MQTT password

WiFiClient espClient;
PubSubClient client(espClient);
Servo myservo;

int val;
int cur_val;
int pos;
char msg[3];
int level;
int cur_off; 
int itsatrap = 0;
int servoPin = 13;
int max_angle = 133;


void setup() {
  Serial.begin(115200);

  setup_wifi();

  client.setServer(mqtt_server, 1883);
  
  client.setCallback(callback);

}


void setup_wifi() {

  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(wifi_ssid, wifi_password);

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

  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  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");
  });
  
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

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

  if (mdns.begin("Blinds2", WiFi.localIP())) {
    Serial.println("MDNS responder started");
  }
  
}

void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);
    String mytopic(topic);
    if (mytopic == "blinds2/level/state") {
          cur_val = message.toInt();
          cur_val = map (cur_val, 0, 100, max_angle, 0);
    }
    if (itsatrap == 0 && mytopic == "blinds2/cmd" && message.equalsIgnoreCase("on")) {
      myservo.attach(servoPin);
      delay(100);
      for (pos = max_angle; pos >= cur_val; pos -= 1) {
        myservo.write(pos);
        delay(20);
      }
    myservo.detach();
    client.publish("blinds2/cmd/state", "on", true);
    cur_off = 0;
    delay(1000);
    }
    else if (mytopic == "blinds2/cmd" && message.equalsIgnoreCase("off")) {
      myservo.attach(servoPin);
      delay(100);
      for (pos = cur_val; pos <= max_angle; pos += 1) {
        myservo.write(pos);
        delay(20);
      }
    myservo.detach();
    client.publish("blinds2/cmd/state", "off", true);
    client.publish("blinds2/level/state", "100", true); // Comment out if you want the blinds to retain the last position, otherwise they will open to 100% when turned on again.
    cur_off = 1;
    delay(1000); 
    }
    else if (mytopic == "blinds2/level") {
      myservo.attach(servoPin);
      delay(100);
      val = message.toInt();
      level = val;
      val = map (val, 0, 100, max_angle, 0);
      if (cur_off == 1) {
        for (pos = max_angle; pos >= val; pos -= 1) {
          myservo.write(pos);
          delay(20);
        }
        cur_off = 0;
      } else if (cur_val > val) {
        for (pos = cur_val; pos >= val; pos -= 1) {
          myservo.write(pos);
          delay(20);
        }
      } else {
        for (pos = cur_val; pos <= val; pos += 1) {
          myservo.write(pos);
          delay(20);
        }
      }
    myservo.detach();
    sprintf(msg, "%ld", level);
    client.publish("blinds2/level/state", msg, true);
    client.publish("blinds2/cmd/state", "on", true);  
    itsatrap = 1;
    delay(1000);
    }
    else {
      itsatrap = 0;
    }
}


void loop() {

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


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESPBlindst2", mqtt_user, mqtt_password)) {
      Serial.println("connected");

      client.subscribe("blinds2/level/state");
      client.subscribe("blinds2/cmd/state");
      client.subscribe("blinds2/level");
      client.subscribe("blinds2/cmd");

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

This code works fine but i would like to understand it better so that i can make some adjustments to make it fit my needs even better.

For instants I would like to reverse the operation because i have blinds that need a mirror setup

And i would like to know if it is possible to make the servo turn a bit more, because now i can only open till blinds are half open. Sometimes i need them to open just a little more.

What should i change to make them run faster or slower.
I know this is an old topic but i hope someone can still help.

int max_angle = 133; // This should allow the blinds to go up more or less - beware if it’s not a continuous servo changing this may break it! - it’s MAX angle for a reason!

Not sure what you mean by a “mirror” setup, surely the blinds still go up and down from the top, not up and down from the floor?

As for speed up and down yes it’s possible but beware that I suspect it’s set up for specific hardware and changing the delays may either cause harm to the servo or the servo will miss some commands - however it’s up to you - just adjust the delay(20); lines to whatever you like - smaller = faster - larger = slower.

By mirror setup i mean that the servo needs to be mounted on the other side of the blinds.
I am not lifting the blinds, i am just tilting.
I have one mounted on the right side, if i mount it on the left side, the open and close needs to be just the opposite.

I also got the guy who built the code to respond, and he has written a slight different code that should be able to reverse operation.
But is i try to change that value 133 even by 1 up or down, it won’t work anymore.

can someone help me integrate mqtt and figure out why my servo is not responding.

https://pastebin.com/5aJ8rmvq

Please help me. I am using D1 mini for operate my servo, but not working.

Config.yaml
    
    platform: mqtt
    name: "Window Bottom Center"
    state_topic: "blind/bc/state"
    command_topic: "blind/bc/command"
    brightness_state_topic: "blind/bc/state"
    brightness_command_topic: "blind/bc/level"
    brightness_scale: 100
    qos: 0
    payload_on: "ON"
    payload_off: "OFF"
    optimistic: false
    retain: true

Arduino file

#include <Servo.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiAP.h>
#include <ESP8266WiFiGeneric.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WiFiScan.h>
#include <ESP8266WiFiSTA.h>
#include <ESP8266WiFiType.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>

#include <PubSubClient.h>


/************ WIFI and MQTT INFORMATION (CHANGE THESE FOR YOUR SETUP) ******************/
#define wifi_ssid "My SSID" //enter your WIFI SSID
#define wifi_password "My SSID password" //enter your WIFI Password

#define mqtt_server "192.168.1.xxx" // Enter your MQTT server adderss or IP. I use my DuckDNS adddress (yourname.duckdns.org) in this field
#define MQTT_PORT            1883             // [MqttPort] MQTT port (10123 on CloudMQTT)
#define mqtt_user "username" //enter your MQTT username
#define mqtt_password "Password" //enter your password








WiFiClient espClient;
PubSubClient client(espClient);

Servo myservo;

int val;
int itsatrap = 0;


void setup() {
  Serial.begin(115200);

  setup_wifi();

  client.setServer(mqtt_server, 1883); //CHANGE PORT HERE IF NEEDED
  client.setCallback(callback);

}


void setup_wifi() {

  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(wifi_ssid, wifi_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 callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);
    String mytopic(topic);
    if (itsatrap == 0 && mytopic == "blind/bc/state" && message.equals("ON")){  
      myservo.attach(D4);
      delay(500);
      myservo.write(90); 
      client.publish("blind/bc/command", "ON");
      delay(1000);
      myservo.detach();
      }
    else if (mytopic == "blind/bc/state" && message.equalsIgnoreCase("OFF")){
      myservo.attach(D4);
      delay(500);
      myservo.write(0);  
      client.publish("blind/bc/command", "OFF");
      delay(1000);
      myservo.detach();
    }
    else if (mytopic == "<Your Brightness Topic>"){
      myservo.attach(D4);
      delay(500);
      val = message.toInt(); //converts command to integer to be used for positional arrangement
      val = map (val, 0, 99, 0, 180);
      myservo.write(val);
      client.publish("<Your State Topic>", "ON");
      delay(3000);
      myservo.detach();
      itsatrap = 1;
    }
    else{
        itsatrap = 0;
    }

}



void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
  if (client.connect("ESPBlindstl", mqtt_user, mqtt_password)) {
      Serial.println("connected");

      client.subscribe("<Your Payload Topic>");
      client.subscribe("<Your Brightness Topic>");
      client.publish("<Your State Topic>", "OFF");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

Please help me with where do i need add state_topic, command_topic and brightness_command_topic. If i fill all you mention like your ("<Your Payload Topic>");, then i faceing a error in Arduino IDE

  client.subscribe("<Your Payload Topic>");  ?
  client.subscribe("<Your Brightness Topic>"); is it brightness_command_topic "blind/bc/level" or brightness_state_topic "blind/bc/state" ?
  client.publish("<Your State Topic>", "OFF");     state_topic: "blind/bc/state" ?

########################################################################
################### Configuration.yaml ########################
########################################################################

  light:
      - platform: mqtt
        name: "Window Bottom Center"
        state_topic: "blind/bc/state"
        command_topic: "blind/bc/command"
        brightness_state_topic: "blind/bc/state"
        brightness_command_topic: "blind/bc/level"
        brightness_scale: 100
        qos: 0
        payload_on: "ON"
        payload_off: "OFF"
        optimistic: false
        retain: true

      - platform: mqtt
        name: "Window Bottom Right"
        state_topic: "blind/br/state"
        command_topic: "blind/br/command"
        brightness_state_topic: "blind/br/state"
        brightness_command_topic: "blind/br/level"
        brightness_scale: 100
        qos: 0
        payload_on: "ON"
        payload_off: "OFF"
        optimistic: false
        retain: true

#####################################################################
############### Arduino sketch ##################
####################################################################

#include <Servo.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiAP.h>
#include <ESP8266WiFiGeneric.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WiFiScan.h>
#include <ESP8266WiFiSTA.h>
#include <ESP8266WiFiType.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>

#include <PubSubClient.h>


/************ WIFI and MQTT INFORMATION (CHANGE THESE FOR YOUR SETUP) ******************/
#define wifi_ssid "netgear" //enter your WIFI SSID
#define wifi_password "netgear478" //enter your WIFI Password

#define mqtt_server "192.168.1.145" // Enter your MQTT server adderss or IP. I use my DuckDNS adddress (yourname.duckdns.org) in this field
#define mqtt_user "someone" //enter your MQTT username
#define mqtt_password "someone" //enter your password








WiFiClient espClient;
PubSubClient client(espClient);

Servo myservo;

int val;
int itsatrap = 0;


void setup() {
  Serial.begin(115200);

  setup_wifi();

  client.setServer(mqtt_server, 1883); //CHANGE PORT HERE IF NEEDED
  client.setCallback(callback);

}


void setup_wifi() {

  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(wifi_ssid, wifi_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 callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);
    String mytopic(topic);
    if (itsatrap == 0 && mytopic == "<Your Payload Topic>" && message.equals("ON")){  
      myservo.attach(D4);
      delay(500);
      myservo.write(90); 
      client.publish("<Your State Topic>", "ON");
      delay(1000);
      myservo.detach();
      }
    else if (mytopic == "<Your Payload Topic>" && message.equalsIgnoreCase("OFF")){
      myservo.attach(D4);
      delay(500);
      myservo.write(0);  
      client.publish("<Your State Topic>", "OFF");
      delay(1000);
      myservo.detach();
    }
    else if (mytopic == "<Your Brightness Topic>"){
      myservo.attach(D4);
      delay(500);
      val = message.toInt(); //converts command to integer to be used for positional arrangement
      val = map (val, 0, 99, 0, 180);
      myservo.write(val);
      client.publish("<Your State Topic>", "ON");
      delay(3000);
      myservo.detach();
      itsatrap = 1;
    }
    else{
        itsatrap = 0;
    }

}



void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
  if (client.connect("ESPBlindstl", mqtt_user, mqtt_password)) {
      Serial.println("connected");

      client.subscribe("<Your Payload Topic>");
      client.subscribe("<Your Brightness Topic>");
      client.publish("<Your State Topic>", "OFF");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

I see a couple of things above that look to be out of place. First you have to replace everything that has a <>. Replace it with whatever you use as your state or topic. Second it doesn’t look like you have any of your wifi or mqtt info filled out. Also what is the error you are receiving on arduino compile?

@jjhtpc Thanks a lot ! now working.

Is’t possible to decrease servo rotating speed like this video
I tried to change myservo.write(90); to myservo.write(90,10); in Arduino sketch, but facing a error
**no matching function for call to 'Servo::write(int, int)'**

You could do a while loop incrementing by 1 and then delaying by a few micro-seconds until you reach the value you want. You would probably need to nest it in an if statement though with thoughts on position and if the current position is greater than or less than the desired position.

I try to follow KISS and try to ignore the speed of the change.

can someone help me integrate mqtt and figure out why my servo is not responding. this is to get a project to build automated blinds using a esp8266, button and 20kg analog servo.
thank you!

*************Arduino sketch ********************

#include <ESP8266WiFi.h>
#include <DNSServer.h>            //Local DNS Server used for redirecting all requests to the configuration portal
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
#include <ESP8266mDNS.h>
#include <Servo.h>
 
#define WLAN_SSID       "********" //change to your Wifi SSID
#define WLAN_PASS       "********" //change to your Wifi Password
 
MDNSResponder mdns;
ESP8266WebServer server(80);
 
int servoPin = 0; //Servo on GPIO0 or NODEMCU pin D3
const int buttonPin = 12; //manual button on GPIO12 or NODEMCU pin D6
int buttonState = 0;
int direction = 0;
int setting = 0; //Startup with blinds closed
int position = 90;
Servo servoA;
 
 
String webPage = "";
 
void setup(void) {
 
 
   WiFi.mode(WIFI_STA);
  webPage += "<body onload='la()'><div style='text-align:left;display:inline-block;min-width:340px;'><div style='text-align:center;'><h1>ESP8266 Web Server</h1><p><h2>Blinds</h2><br></div>";
  webPage += "<br/><style>div,fieldset,input,select{padding:5px;font-size:1em;}input{width:100%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;}select{width:100%;}textarea{resize:none;width:98%;height:318px;padding:5px;overflow:auto;}body{text-align:center;font-family:verdana;}td{padding:0px;}button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;;cursor:pointer;}button:hover{background-color:#006cba;}a{text-decoration:none;}.p{float:left;text-align:left;}.q{float:right;text-align:right;}</style><a href=\"0\"><button>0</button></a><br>";
  webPage += "<br/><a href=\"10\"><button>10</button></a><br>";
  webPage += "<br/><a href=\"20\"><button>20</button></a><br>";
  webPage += "<br/><a href=\"30\"><button>30</button></a><br>";
  webPage += "<br/><a href=\"40\"><button>40</button></a><br>";
  webPage += "<br/><a href=\"50\"><button>50</button></a><br>";
  webPage += "<br/><a href=\"60\"><button>60</button></a><br>";
  webPage += "<br/><a href=\"70\"><button>70</button></a><br>";
  webPage += "<br/><a href=\"80\"><button>80</button></a><br>";
  webPage += "<br/><a href=\"90\"><button>90</button></a><br>";
  webPage += "<br/><a href=\"100\"><button>100</button></a><br></body>";
 
 
  delay(5000);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(115200);
  delay(500);
  Serial.println("Blind Startup Sequence");
  delay(500);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);
  WiFi.begin(WLAN_SSID, WLAN_PASS);
  // Set a static IP (optional)
  //IPAddress ip(10,0,1,50);
  //IPAddress gateway(10,0,1,1);
  //IPAddress subnet(255, 255, 255, 0);
  //WiFi.config(ip, gateway, subnet);
  // End of set a static IP (optional)
  delay(2000);
  int i = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    ESP.wdtFeed();
    if (i > 10)                                        // Try 40 times to connect to Wifi
      Serial.print("Restarting Wifi"); ESP.reset();    // Reset Wifi stack if more than 40 trys
    i++;
 
  }
 
  Serial.println();
  Serial.println("WiFi connected");
  Serial.println("IP address: "); Serial.println(WiFi.localIP());
 
  if (mdns.begin("esp8266", WiFi.localIP())) {
    Serial.println("MDNS responder started");
  }
 
server.on("/", []() { server.send(200, "text/html", webPage); });
server.on("/100", []() { server.send(200, "text/html", webPage); setting = 180; });
server.on("/99", []() { server.send(200, "text/html", webPage);  setting = 180; });
server.on("/98", []() { server.send(200, "text/html", webPage);  setting = 180; });
server.on("/97", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/96", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/95", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/94", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/93", []() { server.send(200, "text/html", webPage);  setting = 171; });
server.on("/92", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/91", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/90", []() { server.send(200, "text/html", webPage);  setting = 162; });
 
server.on("/89", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/88", []() { server.send(200, "text/html", webPage);  setting = 162; });
server.on("/87", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/86", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/85", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/84", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/83", []() { server.send(200, "text/html", webPage);  setting = 153; });
server.on("/82", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/81", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/80", []() { server.send(200, "text/html", webPage);  setting = 144; });
 
server.on("/79", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/78", []() { server.send(200, "text/html", webPage);  setting = 144; });
server.on("/77", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/76", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/75", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/74", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/73", []() { server.send(200, "text/html", webPage);  setting = 135; });
server.on("/72", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/71", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/70", []() { server.send(200, "text/html", webPage);  setting = 126; });
 
server.on("/69", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/68", []() { server.send(200, "text/html", webPage);  setting = 126; });
server.on("/67", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/66", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/65", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/64", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/63", []() { server.send(200, "text/html", webPage);  setting = 117; });
server.on("/62", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/61", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/60", []() { server.send(200, "text/html", webPage);  setting = 108; });
 
server.on("/59", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/58", []() { server.send(200, "text/html", webPage);  setting = 108; });
server.on("/57", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/56", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/55", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/54", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/53", []() { server.send(200, "text/html", webPage);  setting = 99; });
server.on("/52", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/51", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/50", []() { server.send(200, "text/html", webPage);  setting = 90; });
 
server.on("/49", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/48", []() { server.send(200, "text/html", webPage);  setting = 90; });
server.on("/47", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/46", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/45", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/44", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/43", []() { server.send(200, "text/html", webPage);  setting = 81; });
server.on("/42", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/41", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/40", []() { server.send(200, "text/html", webPage);  setting = 72; });
 
 
server.on("/39", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/38", []() { server.send(200, "text/html", webPage);  setting = 72; });
server.on("/37", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/36", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/35", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/34", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/33", []() { server.send(200, "text/html", webPage);  setting = 63; });
server.on("/32", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/31", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/30", []() { server.send(200, "text/html", webPage);  setting = 54; });
 
server.on("/29", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/28", []() { server.send(200, "text/html", webPage);  setting = 54; });
server.on("/27", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/26", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/25", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/24", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/23", []() { server.send(200, "text/html", webPage);  setting = 45; });
server.on("/22", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/21", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/20", []() { server.send(200, "text/html", webPage);  setting = 36; });
 
server.on("/19", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/18", []() { server.send(200, "text/html", webPage);  setting = 36; });
server.on("/17", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/16", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/15", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/14", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/13", []() { server.send(200, "text/html", webPage);  setting = 27; });
server.on("/12", []() { server.send(200, "text/html", webPage);  setting = 18; });
server.on("/11", []() { server.send(200, "text/html", webPage);  setting = 18; });
server.on("/10", []() { server.send(200, "text/html", webPage);  setting = 18; });  
 
server.on("/9", []() { server.send(200, "text/html", webPage);   setting = 18; });
server.on("/8", []() { server.send(200, "text/html", webPage);   setting = 18; });
server.on("/7", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/6", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/5", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/4", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/3", []() { server.send(200, "text/html", webPage);   setting = 9; });
server.on("/2", []() { server.send(200, "text/html", webPage);   setting = 0; });
server.on("/1", []() { server.send(200, "text/html", webPage);   setting = 0; });
server.on("/0", []() { server.send(200, "text/html", webPage);   setting = 0; });
  server.begin();
  Serial.println("HTTP server started");
}
void loop() {
 
buttonState = digitalRead(buttonPin);
 
if(buttonState == LOW && setting < 180 && direction == 0){
  setting++;
  delay(0);
  if(setting == 180){
    direction = 1;
    }
  }
 
if(buttonState == LOW && setting > 0 && direction == 1){
  setting--;
  delay(0);
  if(setting == 0){
    direction = 0;
    }
  }
 
if(buttonState == LOW && setting == 180 && direction == 0){
  setting--;
  delay(0);
  }
 
if(buttonState == LOW && setting == 0 && direction == 1){
  setting++;
  delay(0);
  }
 
if(position < setting){
   servoA.attach(servoPin);
   servoA.write(position++);
   delay(5);
     Serial.print("Setting: ");  
     Serial.println(setting);
     Serial.print("Position: ");
     Serial.println(position);
   }
   
if(position > setting){
   servoA.attach(servoPin);
   servoA.write(position--);
   delay(5);
     Serial.print("Setting: ");  
     Serial.println(setting);
     Serial.print("Position: ");
     Serial.println(position);
   }
 
if(position == setting){
  servoA.detach();
  }
server.handleClient();
}

Could it also be possible to let your blinds / luxaflex go up or down? In addition to being able to tilt it now. So that your blinds / luxaflex are fully automated?

Someone already built this application in a small housing? Have our blinds removed and measured but I only have a space of 2.5cm x 2.5cm, so I also need a smaller servo.

I think someone said that some micro servos still have enough torque to rotate the blinds. Lifting them is a much tougher task.

After some searching and measuring the sizes I came out on this servo:

This should fit and hope that he can provide enough torque power, we’re going to see it :slight_smile:
Only need to design and print a holder with the 3d printer. When it is done I will share the results and make STL files available.

You may have to change code a little bit with a digital servo. I think all of the writes that I coded are analog writes, and I can’t remember but I think the pin I have it on may be an analog pin. Digital servos work with this, but you will want to know that they act a little different they are a little more reactive and their open and close happens extremely fast.

Honestly I have no idea what the differences are between digital or analog. Maybe I can delay it, so the servo does not respond very quickly and abruptly. Will take a look at your code and investigate which adjustments are needed.