Automated Blind
CAD - 3D Print - C++ - Arduino
Automated Blind
CAD
3D Printed
Description
Working Principle
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:
- 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
- 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.
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:
- The speed is drastically reduced on the output, increasing the time required to lift the blind
- 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
}