Add Adjust topic and improve state handling
Add adjusting topic to allow for tweaking the open/close endpoints. Improved the state handling/transitions so that it will only change states when IDLE.
This commit is contained in:
135
blinds.ino
135
blinds.ino
@@ -6,9 +6,16 @@ WiFiClient net;
|
|||||||
MQTTClient client;
|
MQTTClient client;
|
||||||
AccelStepper stepper(AccelStepper::HALF4WIRE, D0, D2, D1, D3);
|
AccelStepper stepper(AccelStepper::HALF4WIRE, D0, D2, D1, D3);
|
||||||
|
|
||||||
|
// Config
|
||||||
const char ssid[] = "";
|
const char ssid[] = "";
|
||||||
const char pw[] = "";
|
const char wifi_pw[] = "";
|
||||||
const char mqtt_addr[] = "192.168.10.30";
|
const char mqtt_user[] = "";
|
||||||
|
const char mqtt_pw[] = "";
|
||||||
|
const char mqtt_addr[] = "";
|
||||||
|
const char client_name[] = "";
|
||||||
|
|
||||||
|
|
||||||
|
// End Config
|
||||||
|
|
||||||
unsigned long lastMillis = 0;
|
unsigned long lastMillis = 0;
|
||||||
|
|
||||||
@@ -18,69 +25,103 @@ const int SLACK = 1;
|
|||||||
const int OPENING_BLINDS = 2;
|
const int OPENING_BLINDS = 2;
|
||||||
const int CLOSING_BLINDS = 3;
|
const int CLOSING_BLINDS = 3;
|
||||||
const int IDLE = 4;
|
const int IDLE = 4;
|
||||||
|
const int ADJUSTING = 5;
|
||||||
|
|
||||||
int state = SETUP;
|
int state = SETUP;
|
||||||
int previousState = SETUP;
|
int previousState = SETUP;
|
||||||
bool blindsOpen = false;
|
bool blindsOpen = false;
|
||||||
|
|
||||||
|
long fullyOpenPosition = -14000;
|
||||||
|
long fullyClosedPosition = 0;
|
||||||
|
|
||||||
void connect() {
|
void connect() {
|
||||||
Serial.print("checking wifi...");
|
Serial.println("checking wifi...");
|
||||||
while (WiFi.status() != WL_CONNECTED) {
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
Serial.print(".");
|
Serial.print(".");
|
||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.print("\nconnecting...");
|
Serial.println("\nconnecting...");
|
||||||
while (!client.connect("bedroom-blinds-1", "cameron", pw)) {
|
while (!client.connect(client_name, mqtt_user, mqtt_pw)) {
|
||||||
Serial.print(".");
|
Serial.print(".");
|
||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.println("\nconnected!");
|
Serial.println("\nconnected!");
|
||||||
|
|
||||||
client.subscribe("/blinds/bedroom/1");
|
client.subscribe("/bedroom/blinds/2");
|
||||||
|
client.subscribe("/bedroom/blinds/2/adjust");
|
||||||
}
|
}
|
||||||
|
|
||||||
void messageReceived(String &topic, String &payload) {
|
void messageReceived(String &topic, String &payload) {
|
||||||
Serial.println("incoming: " + topic + " - " + payload);
|
Serial.println("incoming: " + topic + " - " + payload);
|
||||||
|
|
||||||
// Note: Do not use the client in the callback to publish, subscribe or
|
if (topic.endsWith("adjust")) {
|
||||||
// unsubscribe as it may cause deadlocks when other things arrive while
|
int adjustment;
|
||||||
// sending and receiving acknowledgments. Instead, change a global variable,
|
sscanf(payload.c_str(), "%d", &adjustment);
|
||||||
// or push to a queue and handle it in the loop after calling `client.loop()`.
|
adjustClosedPosition(adjustment);
|
||||||
if (payload.indexOf("open") != -1) {
|
|
||||||
openBlinds();
|
|
||||||
} else if (payload.indexOf("close") != -1) {
|
|
||||||
closeBlinds();
|
|
||||||
} else {
|
} else {
|
||||||
Serial.println(payload);
|
if (payload.indexOf("open") != -1) {
|
||||||
|
openBlinds();
|
||||||
|
} else if (payload.indexOf("close") != -1) {
|
||||||
|
closeBlinds();
|
||||||
|
} else if (payload.indexOf("reset") != -1) {
|
||||||
|
Serial.println("Resetting current position and setting blinds state to closed");
|
||||||
|
stepper.setCurrentPosition(0);
|
||||||
|
blindsOpen = false;
|
||||||
|
} else {
|
||||||
|
Serial.println(payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateState(int newState) {
|
||||||
|
previousState = state;
|
||||||
|
state = newState;
|
||||||
|
|
||||||
|
if(newState == IDLE) {
|
||||||
|
Serial.println("Transitioning to idle");
|
||||||
|
} else {
|
||||||
|
Serial.print("Moving ");
|
||||||
|
Serial.print(previousState);
|
||||||
|
Serial.print(" -> ");
|
||||||
|
Serial.println(newState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void openBlinds() {
|
void openBlinds() {
|
||||||
if (!blindsOpen) {
|
if (!blindsOpen && state == IDLE) {
|
||||||
Serial.println("Opening Blinds");
|
Serial.println("Opening Blinds");
|
||||||
previousState = state;
|
updateState(OPENING_BLINDS);
|
||||||
state = OPENING_BLINDS;
|
|
||||||
stepper.enableOutputs();
|
stepper.enableOutputs();
|
||||||
stepper.moveTo(-14000);
|
stepper.moveTo(fullyOpenPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void closeBlinds() {
|
void closeBlinds() {
|
||||||
if (blindsOpen) {
|
if (blindsOpen && state == IDLE) {
|
||||||
Serial.println("Closing Blinds");
|
Serial.println("Closing Blinds");
|
||||||
previousState = state;
|
updateState(CLOSING_BLINDS);
|
||||||
state = CLOSING_BLINDS;
|
|
||||||
stepper.enableOutputs();
|
stepper.enableOutputs();
|
||||||
stepper.moveTo(0);
|
stepper.moveTo(fullyClosedPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void adjustClosedPosition(int offset) {
|
||||||
|
if(offset == 0 || state != IDLE) return;
|
||||||
|
|
||||||
|
Serial.print("Adjust by: ");
|
||||||
|
Serial.println(offset);
|
||||||
|
|
||||||
|
updateState(ADJUSTING);
|
||||||
|
stepper.enableOutputs();
|
||||||
|
stepper.move(offset);
|
||||||
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
|
||||||
WiFi.begin(ssid, pw);
|
WiFi.begin(ssid, wifi_pw);
|
||||||
|
|
||||||
client.begin(mqtt_addr, 1883, net);
|
client.begin(mqtt_addr, 1883, net);
|
||||||
client.onMessage(messageReceived);
|
client.onMessage(messageReceived);
|
||||||
@@ -112,15 +153,14 @@ void loop() {
|
|||||||
} else if (previousState == CLOSING_BLINDS) {
|
} else if (previousState == CLOSING_BLINDS) {
|
||||||
stepper.move(-3000);
|
stepper.move(-3000);
|
||||||
} else if (stepper.distanceToGo() == 0) {
|
} else if (stepper.distanceToGo() == 0) {
|
||||||
state = IDLE;
|
updateState(IDLE);
|
||||||
stepper.disableOutputs();
|
stepper.disableOutputs();
|
||||||
Serial.println("Transitioning to IDLE");
|
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
stepper.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update previous to SLACK until we take up the slack
|
stepper.run();
|
||||||
|
|
||||||
|
// Update previous to SLACK until we take up the slack to prevent the stepper from moving forever
|
||||||
previousState = state;
|
previousState = state;
|
||||||
break;
|
break;
|
||||||
case OPENING_BLINDS:
|
case OPENING_BLINDS:
|
||||||
@@ -139,19 +179,46 @@ void loop() {
|
|||||||
bool open = state == OPENING_BLINDS;
|
bool open = state == OPENING_BLINDS;
|
||||||
blindsOpen = open;
|
blindsOpen = open;
|
||||||
sendBlindsUpdate(open);
|
sendBlindsUpdate(open);
|
||||||
previousState = state;
|
updateState(SLACK);
|
||||||
state = SLACK;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case ADJUSTING:
|
||||||
|
if (millis() - lastMillis > 1000) {
|
||||||
|
Serial.println("Adjusting...");
|
||||||
|
lastMillis = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
stepper.run();
|
||||||
|
|
||||||
|
if (stepper.distanceToGo() == 0) {
|
||||||
|
Serial.print("Finished adjusting to: ");
|
||||||
|
Serial.println(stepper.currentPosition());
|
||||||
|
|
||||||
|
updateState(IDLE);
|
||||||
|
stepper.disableOutputs();
|
||||||
|
|
||||||
|
if(blindsOpen) {
|
||||||
|
fullyOpenPosition = stepper.currentPosition();
|
||||||
|
|
||||||
|
Serial.print("New open position: ");
|
||||||
|
Serial.println(fullyOpenPosition);
|
||||||
|
} else {
|
||||||
|
fullyClosedPosition = stepper.currentPosition();
|
||||||
|
|
||||||
|
Serial.print("New closed position: ");
|
||||||
|
Serial.println(fullyClosedPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_stepper() {
|
void setup_stepper() {
|
||||||
previousState = state;
|
updateState(IDLE);
|
||||||
state = IDLE;
|
|
||||||
stepper.setCurrentPosition(-3000);
|
stepper.setCurrentPosition(-3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendBlindsUpdate(bool isOpen) {
|
void sendBlindsUpdate(bool isOpen) {
|
||||||
client.publish("/blinds/bedroom/1/status", isOpen ? "true" : "false", true);
|
client.publish("/bedroom/blinds/2/status", isOpen ? "true" : "false", true);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user