{"id":69,"date":"2017-05-03T20:07:12","date_gmt":"2017-05-03T20:07:12","guid":{"rendered":"http:\/\/www.cribbstechnologies.com\/?page_id=69"},"modified":"2017-05-31T04:21:51","modified_gmt":"2017-05-31T04:21:51","slug":"horizontal-blinds-hardware","status":"publish","type":"page","link":"https:\/\/www.cribbstechnologies.com\/index.php\/home-automation\/horizontal-plantation-blind-automation\/horizontal-blinds-hardware\/","title":{"rendered":"Horizontal Blinds &#8211; Hardware"},"content":{"rendered":"<p>[et_pb_section bb_built=&#8221;1&#8243; admin_label=&#8221;section&#8221; fullwidth=&#8221;on&#8221;][et_pb_fullwidth_header admin_label=&#8221;Fullwidth Header&#8221; title=&#8221;Horizontal Blinds Automation&#8221; background_layout=&#8221;dark&#8221; background_url=&#8221;http:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170503_172720.jpg&#8221; saved_tabs=&#8221;all&#8221; \/][\/et_pb_section][et_pb_section bb_built=&#8221;1&#8243; admin_label=&#8221;section&#8221;][et_pb_row admin_label=&#8221;row&#8221;][et_pb_column type=&#8221;3_4&#8243;][et_pb_text admin_label=&#8221;Research&#8221; background_layout=&#8221;light&#8221; text_orientation=&#8221;left&#8221; use_border_color=&#8221;off&#8221; border_color=&#8221;#ffffff&#8221; border_style=&#8221;solid&#8221;]<\/p>\n<h1>Hardware<\/h1>\n<h3>The Research<\/h3>\n<p>When I first started this project I first looked for commercially available hardware that would do what I want: control the tilt and height of my blinds. Most automated blind solutions fall into three categories:<\/p>\n<ol>\n<li>Roll-up blinds: These blinds are like what you would see in a storefront where a sheet of material is on a spool and can be raised\/lowered with a chain<\/li>\n<li>Horizontal blinds that use a pull loop to accomplish tilting the tilting<\/li>\n<li>Horizontal blinds that use a control wand to accomplish the tilting<\/li>\n<\/ol>\n<p>Categories 2 and 3 are both for horizontal blinds but didn&#8217;t fit my needs as my blinds look similar to\u00a0<a href=\"http:\/\/www.shadesshuttersblinds.com\/discount_fauxwood_blinds?c=17583&amp;w=024&amp;h=073&amp;p=02&amp;gclid=CIO2-eS_1NMCFVM7gQod1WgKAA\">these<\/a>. There are two pull cords for the tilt adjustment: one moves the blinds one way and the other moves them the opposite. None of the solutions were suitable for my situation; on top of this they were unable to raise or lower the blinds. Even if they were suitable the price was pretty high: $75-250 depending on the solution!<\/p>\n<p>I decided to roll my own using inexpensive parts to test everything and so far so good. Each set of blinds that will be retrofitted will have:<\/p>\n<ul>\n<li>1 ESP8826 microcontroller<\/li>\n<li>1 995 metal gear servo<\/li>\n<li>3 roller lever microswitches<\/li>\n<li>1 12V &#8211; 5V DC buck converter<\/li>\n<li>1 Dual-channel H-bridge<\/li>\n<li>2 12VDC gear motor<\/li>\n<li>2 pulleys<\/li>\n<li>some 3d printed parts<\/li>\n<\/ul>\n<p>I chose a NodeMCU to do the prototyping with but will probably end up using a WeMos D1 mini as the final platform. The microswitches will be used to allow local control of the blinds in locations and functions similar to the original controls.<\/p>\n<p>[\/et_pb_text][et_pb_text admin_label=&#8221;Investigation&#8221; background_layout=&#8221;light&#8221; text_orientation=&#8221;left&#8221; use_border_color=&#8221;off&#8221; border_color=&#8221;#ffffff&#8221; border_style=&#8221;solid&#8221;]<\/p>\n<h3>Investigation<\/h3>\n<p>I pulled a set of blinds down to see what I could do and found that the tilt was controlled by a little worm and wheel mechanism that turned a 1\/4&#8243; rod that ran the width of the blinds. This in turn pulled on one of two strings to control the angle of the ladder that the blind slats lie in. The body of the top \u00a0of the blinds is made from \u00a0bent sheet metal that is shaped into a U. I designed and 3d printed a bracket to hold the servo in the proper position as well as a servo horn adapter to attach to the rod that controls the tilt. In this picture you can also see an earlier iteration of the switch and actuator arm that will be used to control the tilt electronically.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-196\" src=\"http:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170421_113928-300x225.jpg\" alt=\"\" width=\"300\" height=\"225\" srcset=\"https:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170421_113928-300x225.jpg 300w, https:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170421_113928-768x576.jpg 768w, https:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170421_113928-1024x768.jpg 1024w, https:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170421_113928-510x382.jpg 510w, https:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170421_113928-1080x810.jpg 1080w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Here&#8217;s a different look at that mechanism. A string will go through the body and attach to the arm. Pulling the string will depress the roller lever on the switch and open a connection on the microcontroller.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-198\" src=\"http:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170408_150940-1-300x225.jpg\" alt=\"\" width=\"300\" height=\"225\" srcset=\"https:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170408_150940-1-300x225.jpg 300w, https:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170408_150940-1-768x576.jpg 768w, https:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170408_150940-1-1024x768.jpg 1024w, https:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170408_150940-1-510x382.jpg 510w, https:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170408_150940-1-1080x810.jpg 1080w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>[\/et_pb_text][et_pb_text admin_label=&#8221;Integration&#8221; background_layout=&#8221;light&#8221; text_orientation=&#8221;left&#8221; use_border_color=&#8221;off&#8221; border_color=&#8221;#ffffff&#8221; border_style=&#8221;solid&#8221;]<\/p>\n<h3>Integration<\/h3>\n<p>The next step was to wire it all up and program it to work. Cue nest of wiring:<br \/>\n<iframe loading=\"lazy\" src=\"https:\/\/www.youtube.com\/embed\/-r2Bo1AW7v8\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<h4>Description of the solution<\/h4>\n<p>The easiest way to integrate DIY solutions into Home Assistant is via <a href=\"http:\/\/mqtt.org\/\">MQTT<\/a>, a protocol for IoT(Internet of Things) devices. MQTT works as a pub\/sub broker. The implementation I&#8217;m using is for my broker is\u00a0<a href=\"https:\/\/mosquitto.org\/\">Mosquitto<\/a>\u00a0running on a CentOS 7 platform. The NodeMCU platform has Wi-Fi hardware built in and is relatively easy to get sending\/receiving messages via MQTT. I also needed a switch to enable local control of the hardware.<\/p>\n<h4>Implementation of the solution<\/h4>\n<p>I decided to use four different MQTT topics one each for tilt command, tilt status, raise\/lower command, raise\/lower status. As of now I&#8217;m still waiting on parts for the raise\/lower and haven&#8217;t figured out how I&#8217;m going to handle status. The program expects to receive a value from 0-180 on the tilt command topic and will send this value to the servo to tilt the blinds to the appropriate position. The method that actually controls moving the servo also handles updating the tilt status topic with the current position. This made adding the switch to control simple.<\/p>\n<p>[\/et_pb_text][et_pb_text admin_label=&#8221;Text&#8221; background_layout=&#8221;light&#8221; text_orientation=&#8221;left&#8221; use_border_color=&#8221;off&#8221; border_color=&#8221;#ffffff&#8221; border_style=&#8221;solid&#8221;]<\/p>\n<pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\r\n#include &amp;lt;ESP8266WiFi.h&amp;gt;\r\n#include &amp;lt;PubSubClient.h&amp;gt;\r\n#include &amp;lt;Servo.h&amp;gt;\r\n\/\/ Update these with values suitable for your network.\r\nconst char* ssid = &quot;&quot;;\r\nconst char* password = &quot;&quot;;\r\nconst char* mqtt_server = &quot;&quot;;\r\nconst char* mqtt_user = &quot;&quot;;\r\nconst char* mqtt_password = &quot;&quot;;\r\n\r\nconst int TILT_SERVO_PIN = D1;\r\nconst int TILT_SWITCH_PIN = D2;\r\nconst int UP_SWITCH_PIN = D3;\r\nconst int DOWN_SWITCH_PIN = D4;\r\nconst int MOTOR_UP_PIN = D5;\r\nconst int MOTOR_DOWN_PIN = D6;\r\nconst int MOTOR_ENABLE_PIN = D7;\r\nconst bool RAISE = true;\r\nconst bool LOWER = false;\r\nconst int positions&#x5B;] = {20, 35, 50, 65, 80, 95, 110, 125, 140, 155, 170};\r\nconst int POSITIONS_SIZE = 11;\r\n\r\nconst char* IDENTIFIER = &quot;livingRoom0&quot;;\r\nconst char* STATUS_TOPIC = &quot;livingRoom0\/status&quot;;\r\nconst char* TILT_TOPIC = &quot;livingRoom0\/tilt&quot;;\r\nconst char* RAISE_TOPIC = &quot;livingRoom0\/raise&quot;;\r\n\r\nint tiltPosition = 0;\r\nint currentPositionIndex = 0;\r\nbool increase = true;\r\nbool drivingMotors = false;\r\n\r\n\r\n\r\nServo myservo;\r\nWiFiClient espClient;\r\nPubSubClient client(espClient);\r\n\r\nvoid setup_wifi() {\r\n   delay(100);\r\n  \/\/ We start by connecting to a WiFi network\r\n    Serial.print(&quot;Connecting to &quot;);\r\n    Serial.println(ssid);\r\n    WiFi.begin(ssid, password);\r\n    while (WiFi.status() != WL_CONNECTED) {\r\n      delay(500);\r\n      Serial.print(&quot;.&quot;);\r\n    }\r\n  randomSeed(micros());\r\n  Serial.println(&quot;&quot;);\r\n  Serial.println(&quot;WiFi connected&quot;);\r\n  Serial.println(&quot;IP address: &quot;);\r\n  Serial.println(WiFi.localIP());\r\n}\r\n\r\nvoid moveIt(int position, bool report) {\r\n  myservo.attach(TILT_SERVO_PIN);  \/\/ attaches the servo on pin D1 to the servo object\r\n  myservo.write(position);\r\n\r\n  if (report) {\r\n    tiltPosition = position;\r\n    char message&#x5B;100];\r\n    sprintf(message, &quot;%d&quot;, position);\r\n    const char* toSend = message;\r\n    Serial.print(&quot;Publishing message: &quot;);\r\n    Serial.println(toSend);\r\n    client.publish(STATUS_TOPIC, toSend, false);\r\n  }\r\n  delay(500);\r\n  myservo.detach();\r\n}\r\n\r\nvoid moveIt(int position) {\r\n  moveIt(position, true);\r\n}\r\n\r\nvoid callback(char* topic, byte* payload, unsigned int length) {\r\n  Serial.print(&quot;Received: &quot;);\r\n  Serial.println((char *)payload);\r\n  Serial.print(&quot;Command with length: &quot;);\r\n  Serial.print(length);\r\n  Serial.print(&quot; from MQTT broker is : &#x5B;&quot;);\r\n  Serial.print(topic);\r\n  Serial.print(&quot;] value: &quot;);\r\n  String value = &quot;&quot;;\r\n  for(int i=0;i&amp;lt;length;i++) {\r\n    value = value +  (char)payload&#x5B;i];    \r\n  }\r\n  if (value != &quot;&quot;) {\r\n    if (strcmp(topic, TILT_TOPIC) == 0) {\r\n      Serial.println(value);\r\n      moveIt(value.toInt());\r\n      tiltPosition = value.toInt();\r\n    } else if (strcmp(topic, RAISE_TOPIC) == 0) {\r\n      Serial.println(&quot;Raise command received: &quot; + value);\r\n    }\r\n  }\r\n}\/\/end callback\r\n\r\nvoid reconnect() {\r\n  \/\/ Loop until we're reconnected\r\n  while (!client.connected()) {\r\n    Serial.print(&quot;Attempting MQTT connection...&quot;);\r\n    \/\/ Create a random client ID\r\n    String clientId = &quot;ESP8266Client-&quot;;\r\n    clientId += String(random(0xffff), HEX);\r\n    \/\/ Attempt to connect\r\n    if (client.connect(clientId.c_str(), mqtt_user, mqtt_password)) {\r\n      Serial.println(&quot;connected&quot;);\r\n     \/\/once connected to MQTT broker, subscribe command if any\r\n      client.subscribe(TILT_TOPIC);\r\n      client.subscribe(RAISE_TOPIC);\r\n    } else {\r\n      Serial.print(&quot;failed, rc=&quot;);\r\n      Serial.print(client.state());\r\n      Serial.println(&quot; try again in 5 seconds&quot;);\r\n      \/\/ Wait 6 seconds before retrying\r\n      delay(6000);\r\n    }\r\n  }\r\n} \/\/end reconnect()\r\n\r\nvoid setup() {\r\n  Serial.begin(115200);\r\n  setup_wifi();\r\n  client.setServer(mqtt_server, 1883);\r\n  client.setCallback(callback);\r\n  pinMode(TILT_SWITCH_PIN, INPUT_PULLUP);\r\n  pinMode(UP_SWITCH_PIN, INPUT_PULLUP);\r\n  pinMode(DOWN_SWITCH_PIN, INPUT_PULLUP);\r\n  pinMode(MOTOR_UP_PIN, OUTPUT);\r\n  pinMode(MOTOR_DOWN_PIN, OUTPUT);\r\n  pinMode(MOTOR_ENABLE_PIN, OUTPUT);\r\n  digitalWrite(MOTOR_ENABLE_PIN, HIGH);\r\n}\r\n\r\nvoid loop() {\r\n  if (!client.connected()) {\r\n    reconnect();\r\n  }\r\n  client.loop();\r\n  int tiltStatus = digitalRead(TILT_SWITCH_PIN);\r\n\r\n  if (tiltStatus == LOW &amp;amp;&amp;amp; !drivingMotors) {\r\n      if (increase) {\r\n        currentPositionIndex = currentPositionIndex + 1;\r\n        if (currentPositionIndex &amp;gt; POSITIONS_SIZE - 1) {\r\n          increase = false;\r\n          currentPositionIndex -= 2;\r\n        }\r\n      } else {\r\n        currentPositionIndex = currentPositionIndex - 1;\r\n        if (currentPositionIndex &amp;lt; 0) {\r\n          increase = true;\r\n          currentPositionIndex += 2;\r\n        }\r\n      }\r\n      Serial.print(&quot;Current position index is &quot;);\r\n      Serial.println(currentPositionIndex);\r\n      \r\n      moveIt(positions&#x5B;currentPositionIndex]);\r\n  }\r\n\r\n  int upSwitchStatus = digitalRead(UP_SWITCH_PIN) == LOW;\r\n  int downSwitchStatus = digitalRead(DOWN_SWITCH_PIN) == LOW;\r\n  if (upSwitchStatus &amp;amp;&amp;amp; !downSwitchStatus) {\r\n    Serial.println(&quot;Raising&quot;);\r\n    raiseOrLower(RAISE);\r\n  } else if (downSwitchStatus &amp;amp;&amp;amp; !upSwitchStatus) {\r\n    Serial.println(&quot;Lowering&quot;);\r\n    raiseOrLower(LOWER);\r\n  } else if (!upSwitchStatus &amp;amp;&amp;amp; !downSwitchStatus) {\r\n    if (drivingMotors) {\r\n      drivingMotors = false;\r\n      digitalWrite(MOTOR_UP_PIN, LOW);\r\n      digitalWrite(MOTOR_DOWN_PIN, LOW);\r\n      moveIt(tiltPosition, false);\r\n    }\r\n  }\r\n}\r\n\r\nvoid raiseOrLower(bool isRaise) {\r\n  if (!drivingMotors) {\r\n    moveIt(80, false);\r\n    drivingMotors = true;\r\n  } else {\r\n    if (isRaise) {\r\n      digitalWrite(MOTOR_UP_PIN, HIGH);\r\n      digitalWrite(MOTOR_DOWN_PIN, LOW);\r\n    } else {\r\n      digitalWrite(MOTOR_UP_PIN, LOW);\r\n      digitalWrite(MOTOR_DOWN_PIN, RAISE);\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_4&#8243;][et_pb_code admin_label=&#8221;Code&#8221;]<div id='horizontalBlinds' class='widgets_on_page wop_tiny1  wop_small1  wop_medium1  wop_large1  wop_wide1'>\n\t\t\t<ul><li id=\"nav_menu-4\" class=\"widget widget_nav_menu\"><div class=\"menu-horizontal-blind-menu-container\"><ul id=\"menu-horizontal-blind-menu\" class=\"menu\"><li id=\"menu-item-56\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-56\"><a href=\"https:\/\/www.cribbstechnologies.com\/index.php\/home-automation\/horizontal-plantation-blind-automation\/\">Overview<\/a><\/li>\n<li id=\"menu-item-80\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-80\"><a href=\"https:\/\/www.cribbstechnologies.com\/index.php\/home-automation\/horizontal-plantation-blind-automation\/horizontal-blinds-hardware\/\">Hardware<\/a><\/li>\n<li id=\"menu-item-94\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-94\"><a href=\"https:\/\/www.cribbstechnologies.com\/index.php\/home-automation\/horizontal-plantation-blind-automation\/horizontal-blinds-configuration\/\">Configuration<\/a><\/li>\n<\/ul><\/div><\/li><\/ul><\/div><!-- widgets_on_page -->[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>[et_pb_section bb_built=&#8221;1&#8243; admin_label=&#8221;section&#8221; fullwidth=&#8221;on&#8221;][et_pb_fullwidth_header admin_label=&#8221;Fullwidth Header&#8221; title=&#8221;Horizontal Blinds Automation&#8221; background_layout=&#8221;dark&#8221; background_url=&#8221;http:\/\/www.cribbstechnologies.com\/wp-content\/uploads\/2017\/05\/IMG_20170503_172720.jpg&#8221; saved_tabs=&#8221;all&#8221; \/][\/et_pb_section][et_pb_section bb_built=&#8221;1&#8243; admin_label=&#8221;section&#8221;][et_pb_row admin_label=&#8221;row&#8221;][et_pb_column type=&#8221;3_4&#8243;][et_pb_text admin_label=&#8221;Research&#8221; background_layout=&#8221;light&#8221; text_orientation=&#8221;left&#8221; use_border_color=&#8221;off&#8221; border_color=&#8221;#ffffff&#8221; border_style=&#8221;solid&#8221;] Hardware The Research When I first started this project I first looked for commercially available hardware that would do what I want: control the tilt and height of my blinds. Most automated [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":42,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-69","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.cribbstechnologies.com\/index.php\/wp-json\/wp\/v2\/pages\/69","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cribbstechnologies.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.cribbstechnologies.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.cribbstechnologies.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cribbstechnologies.com\/index.php\/wp-json\/wp\/v2\/comments?post=69"}],"version-history":[{"count":10,"href":"https:\/\/www.cribbstechnologies.com\/index.php\/wp-json\/wp\/v2\/pages\/69\/revisions"}],"predecessor-version":[{"id":199,"href":"https:\/\/www.cribbstechnologies.com\/index.php\/wp-json\/wp\/v2\/pages\/69\/revisions\/199"}],"up":[{"embeddable":true,"href":"https:\/\/www.cribbstechnologies.com\/index.php\/wp-json\/wp\/v2\/pages\/42"}],"wp:attachment":[{"href":"https:\/\/www.cribbstechnologies.com\/index.php\/wp-json\/wp\/v2\/media?parent=69"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}