NodeMCU Sexy Curtains
The room employing this particular device is un-ish-viewable during the day light tho highly visible at night with interior lights, alight. Due to these parameters, the curtains automatically (photoresistor) open-close relative. Amended is a wifi (lower-case) channel to permit a voice activated command (url submit) to open-close the curtains, shd the moment arise, mmm-hmm.


Ingredients
NodeMCU ESP8266 12E
Photoresistor
(2) MG995 Servo (mod'd to 360)
5 Volt Power Supply
String

Sexy Code
// NodeMCU Sexy Curtains
// Vije Miller

#include <ESP8266WiFi.h>
#include <Servo.h>

// Wifi Data (Static)
IPAddress ip(192, 168, 1, 47);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
const char* ssid = "ssid";
const char* pass = "password";
WiFiServer server(80);

Servo left;
Servo right;

// Stop
int zero = 90;

int ols = 85;
int ors = 95;
int cls = 95;
int crs = 85;

// Servo Position (Time)
// 1 = 1 Second = Full Close
// 10 = Full Open
int pos = 0;
// Half Rotation -> Specific
int slow = 910;
int full = 10;

int sensor = 0;

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

left.attach(D5);
right.attach(D6);

left.write(zero);
right.write(zero);

// Connect
Serial.print("SSID: ");
Serial.println(ssid);
WiFi.config(ip, gateway, subnet);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected");
server.begin();
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");

delay(5000);
}


void loop() {

// Sensin'
sensor = analogRead(A0);

// Convert to simplier times
sensor = map(sensor, 0, 1023, 0, full);

// Gotta' see it to believe it
Serial.print(sensor);
Serial.print(" ");
Serial.println(pos);

// Listenin'?
WiFiClient client = server.available();
if (client) {
if (client.available()) {

String query = client.readStringUntil('\r');

if (query.indexOf("/o") != -1) {
open_fast();
Serial.print(pos);
Serial.print(" ");
Serial.println("open fast");
delay(200000);
} else if (query.indexOf("/c") != -1) {
close_fast();
Serial.print(pos);
Serial.print(" ");
Serial.println("close fast");
// Set to a generous (2) minutes for sex
delay(200000);
}
}
client.flush();
}

// Now whadda'ya do?
if (sensor > pos) {
open_slow();
} else if (sensor < pos) {
close_slow();
} else {
hold();
}

delay(100);
}

void open_slow() {
if (pos < full) {
left.write(ols);
right.write(ors);
delay(slow);
pos++;
}
hold();
}

void close_slow() {
if (pos > 0) {
left.write(cls);
right.write(crs);
delay(slow);
pos--;
}
hold();
}

void open_fast() {
if (pos < full) {
left.write(ols);
right.write(ors);
pos = pos * 1000;
delay(pos);
pos = full;
}
hold();
}

void close_fast() {
if (pos > 0) {
left.write(cls);
right.write(crs);
pos = pos * 1000;
delay(pos);
pos = 0;
}
hold();
}

// Don't ya' move
void hold() {
left.write(zero);
right.write(zero);
delay(5000);
}

Notation(s)
1. Timing is every thing .. preferring servos as opposed to steppers, this code requires a precise timing-per-rotation for the width of the curtain draw.
2. Patience .. just bcz it runs at 16mhz doesn't mean you shd. Averaging sensor reads .. delays .. give 'er a rest other wise the curtains will be flappin' back and forth like a chicken raised by geese tryin' to head south.

Archive
https://hackaday.io/project/164851-nodemcu-sexy-curtains

04:21:26 66-019