#include <Arduino.h>
#include <WiFi.h>
#include <ESP_FlexyStepper.h> // https://github.com/pkerspe/ESP-FlexyStepper
#include <SinricPro.h> // https://github.com/sinricpro/esp8266-esp32-sdk
#include <SinricProBlinds.h> // https://github.com/sinricpro/esp8266-esp32-sdk
// *********** BEGIN OF CONFIGURATION ************ //
const int MOTOR_DIRECTION_PIN = 16;
const int MOTOR_STEP_PIN = 17;
const int LIMIT_SWITCH_PIN = 26;
const int MIN_POS_MM = 0;
const int MAX_POS_MM = 1000;
const int SPEED_MM_PER_SECOND = 10;
const int ACCEL_MM_PER_SECOND = 10;
const int STEPS_PER_MM = 1;
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASS = "";
const char* BLINDS_ID = "";
const char* APP_KEY = "";
const char* APP_SECRET = "";
// ************ END OF CONFIGURATION ************* //
ESP_FlexyStepper stepper;
SinricProBlinds& blinds = SinricPro[BLINDS_ID];
volatile bool limitSwitchTriggered = false;
void ICACHE_RAM_ATTR limitSwitchHandler() {
limitSwitchTriggered = true;
}
void MoveBlinds(const int percentage) {
int destination_in_mm = map(percentage, 0, 100, MIN_POS_MM, MAX_POS_MM);
stepper.setTargetPositionInMillimeters(destination_in_mm);
}
void handleLimitSwitches() {
if (!limitSwitchTriggered) return;
stepper.emergencyStop();
limitSwitchTriggered = false;
}
void handleMotor() {
handleLimitSwitches();
stepper.processMovement();
}
void setupWiFi() {
Serial.println("Connecting WiFi");
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println("connected!");
}
void setupSinricPro() {
blinds.onRangeValue([](const String& deviceId, int& position) {
Serial.print("Moving blinds to ");
Serial.println(position);
MoveBlinds(position);
return true;
});
blinds.onPowerState([](const String& deviceId, bool & state) {
Serial.print("Blinds turned ");
Serial.println(state ? "On" : "Off");
return true;
});
SinricPro.onConnected([]() {
Serial.println("SirnicPro connected!");
});
SinricPro.onDisconnected([]() {
Serial.println("SirnicPro disconnected!");
});
Serial.println("Connecting to SinricPro. Please wait...");
SinricPro.begin(APP_KEY, APP_SECRET);
}
void setupStepper() {
stepper.connectToPins(MOTOR_STEP_PIN, MOTOR_DIRECTION_PIN);
stepper.setSpeedInMillimetersPerSecond(SPEED_MM_PER_SECOND);
stepper.setAccelerationInMillimetersPerSecondPerSecond(ACCEL_MM_PER_SECOND);
stepper.setStepsPerMillimeter(STEPS_PER_MM);
}
void setupLimitSwitch() {
pinMode(LIMIT_SWITCH_PIN, INPUT_PULLUP);
attachInterrupt(LIMIT_SWITCH_PIN, limitSwitchHandler, FALLING);
}
void setup() {
Serial.begin(115200);
setupWiFi();
setupSinricPro();
setupLimitSwitch();
setupStepper();
}
void loop() {
handleMotor();
SinricPro.handle();
delay(1); // Wokwi delay - not needed in production!
}