Skip to content

Automated Blind

CAD - 3D Print - C++ - Arduino

Automated Blind

Specification

Automating a standard venitian blind (Manual – 3 lift cords) with customized system based on a microcontroler and a step Motor.
 

Venitian blinds working principle is extremely simple. A set of cords allow you to lift/put down the blind and a rotative rod control the slats orientation.

This project is meant to automate only the lifting system, it must hold the curtain even if it is not powered and the blind must be equaly lifeted on both ends for aesthetic reasons.

Design

Minimalistic. A simple box where the lift cords enter from the top to be rolled around a shaft with two buttons to control the device.

The system is entirely 3D printed, except for the central axis, bearings, screw and nuts. The electronic area is physicaly separated from the mecanical area.
 

The device is pulling all lift cords through a comb and winding them around a compartmentalized roll, each cord being rolled on its own section to avoid overlaying.

CAD

3D Printed

0
Design hours
0
Parts
0
Printing hours
0
Grams of PLA

Description

Working Principle

 
Inked2021-07-27_LI

The lifting cords are pulled and individually winded in their “compartment” around the main roll.

The system is based on a wormgear reducer, which has two main advantage:

  1. Hold the blind position even when the system is not powered, due to its non-backdrivability. The movement can only be transfered from the wormgear to the spur gear
  2. Greatly increase torque at the price of a greatly reduced speed. The ratio is 30:1 in this configuration.

The compartimentalization of the main roll combined with the comb shaped feeder will ensure the ropes would not overlap each other while being winded. Overlaping create disbalance in the lenght of each cord rolled to lift the blind and result in an asymetric raise of each end of the curtain. After testing each solution independantly, the combination appeared to give perfect result.

The comb shaped feeder also prevent any accident by blocking the access to the mechanism.

The mechanism is separated from the command & power supply by a wall to avoid hazards.

2021-07-27 (1)
 

Worm Gear Reducer

As seen previously using a wormgear reducer had multiple advantages. Nontheless, the two main issues coming with the use of this solution are:

  1. The speed is drastically reduced on the output, increasing the time required to lift the blind
  2. High friction between the gear causing waste of energy, and potential damage or premature wear of the gears’ teeth

Despite the reduction ratio, the blind take less than a minute to be lifted or put down, which is totally acceptable for its purpose. In order to reduce the frictions, the gears are lubricated with PTFE Lubricant Spray and after few month of use the system is still working flawlessly. The wormgear has been 3D printed horizontally to ensure the maximum radial resilience.

Code

// Creative Commons - www.ben-amar.com - 2021
// This Code was written for Ben-Amar.com under CC license: BY-NC-SA  (Attribution Mandatory, NonCommercial & ShareAlike)
// You must you credit "Ben-Amar.com" to remix, adapt, and build upon your work non-commercially. You must license your new creations under the identical terms.

//==============================================
//=============================== CONTANTES ====
//==============================================

const int stepPin = 4;            // Step Pin A4988 Driver for Stepper Motor
const int dirPin = 7;             // Dir Pin A4988 Driver for Stepper Motor
const int enPin = 8;              // Enable pin for Stepper (Low = enable)
const int suPin = 5;              // Button to open
const int sdPin = 2;              // Button to close
const int esu = 6;                // End Switch Up
const int esd = 3;                // End Switch Down

//==============================================
//=============================== VARIABLES ====
//==============================================

boolean suState;                  // su = Switch UP: Button to lift the blind (Start & Stop on same button)
boolean sdState;                  // sd = Switch DOWN: Button to Put down the blind (Start & Stop on same button)
boolean esuState;                 // Endswitch Up: Upper Endswitch. The lifting stop if trigger
boolean esdState;                 // Endswitch Down: Upper Endswitch. The lifting stop if trigger
int microSec = 250;               // microsec is used to control the speed of step; initially set à 250

//==============================================
//=============================== VOID SETUP ===
//==============================================

void setup() {

  // ---------------- defines pinMode -------------------

  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(enPin, OUTPUT);
  pinMode(sdPin, INPUT_PULLUP);
  pinMode(suPin, INPUT_PULLUP);
  pinMode(esd, INPUT_PULLUP);
  pinMode(esu, INPUT_PULLUP);

  // ---------------- Initiate Serial -------------------

  Serial.begin(9600);
}

//==============================================
//=============================== VOID LOOP ====
//==============================================

void loop() {

  Serial.println("Start Loop");
  suState = digitalRead(suPin);         // Variable to read value of puch button to lift blind (Puched or not)
  sdState = digitalRead(sdPin);         // Variable to read value of puch button to put down blind (Puched or not)
  esuState = digitalRead(esu);          // Variable to read value of End Switch up (Triggered or not)
  esdState = digitalRead(esd);          // Variable to read value of End Switch down (Triggered or not)

  if ((sdState == LOW) && (esdState == HIGH)) {         // If with 2 statement to put down the blind
    delay (250);                                        // wait
    digitalWrite(enPin, LOW);                          // Enable stepper Motor
    Serial.println("Go Down");                          // display text on S. Monitor
    digitalWrite(dirPin, LOW);                          // Choose direction for stepper motor
    do {                                                // START function do...While C++
      esdState = digitalRead(esd);                     // Read statu of end switch Down (to stop if reach limit)
      sdState = digitalRead(sdPin);                    // Read statu of button to put Down (to stop if pressed again)
      digitalWrite(stepPin, HIGH);                      // Start step
      delayMicroseconds(microSec);                      // Step Duration
      digitalWrite(stepPin, LOW);                       // End the step
      delayMicroseconds(microSec);                      // Break duration
      if (microSec > 15) {                              // (Acceleration) If microSec Higher that targeted value: statement true
        microSec --;                                    // decrement the microSec value of 1
      }                                                 // end of the acceleration IF function
    } while ((sdState == HIGH) && (esdState == HIGH));  // END function do...While C++
    digitalWrite(enPin, HIGH);                         // Disable Stepper to reduce Consumption (NO MORE TORQUE)
    delay (250);                                        // wait
  }
  microSec = 250;                                       // Reset microSec to its default value
  
  if ((suState == LOW) && (esuState == HIGH)) {         // If with 2 statement to lift the blind
    delay (250);                                        // Wait
    digitalWrite(enPin, LOW);                          // Enable the stepper
    Serial.println("Go up");                            // Display text on S. Monitor
    digitalWrite(dirPin, HIGH);                         // Choose Motor Direction
    do {                                                // START function do...While C++
      esuState = digitalRead(esu);                      // Read statu of end switch up (to stop if reach limit)
      suState = digitalRead(suPin);                     // Read statu of button to lift (to stop if pressed again)
      digitalWrite(stepPin, HIGH);                      // Start step
      delayMicroseconds(microSec);                      // Step Duration
      digitalWrite(stepPin, LOW);                       // End Step
      delayMicroseconds(microSec);                      // Break Duration
      if (microSec > 15) {                              // (Acceleration) If microSec Higher that targeted value: statement true
        microSec --;                                    // decrement the microSec value of 1
      }                                                 // end of the acceleration IF function
    } while ((suState == HIGH) && (esuState == HIGH));  // END function do...While C++
    digitalWrite(enPin, HIGH);                         // Disable Stepper to reduce Consumption (NO MORE TORQUE)
    delay (250);                                        // Wait
  }
  microSec = 250;                                       // Reset microSec to its default value
}