Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By btidey
#85274 State machines are actually very simple and a good way of representing logic and timing in a maintainable way. The switch statement is at the heart of most state machines.

Take a look at the following where I try to represent your functionaity in a simple state machine. I haven't compiled or tested this but you should be able to see the flow.

Code: Select all#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "fauxmoESP.h"

#define WIFI_SSID "lemainemachon"
#define WIFI_PASS "jibajaba"
#define REMOTE_BTN_1 4 //up (D2)
#define REMOTE_BTN_2 14//down (D5)
#define REMOTE_BTN_3 12  //select (D6)
#define REMOTE_BTN_4 5//stop (D1)
#define UP "blinds Up"
#define Down "blinds Down"
#define Light_Block "Blinds light Block"

fauxmoESP fauxmo;

#define STATE_IDLE 0
#define STATE_UP_START 1
#define STATE_UP_STOP 2
#define STATE_DOWN_START 3
#define STATE_DOWN_STOP 4
#define UP_DELAY 1000
#define DOWN_DELAY 1000


int state = STATE_IDLE;
unsigned long nextStateTime;

void setup() {
  // Init serial port and clean garbage
  Serial.begin(115200);
  Serial.println();

  // Wi-Fi connection
  wifiSetup();

  // Set Buttons
  pinMode(REMOTE_BTN_1, OUTPUT);          //up
  digitalWrite(REMOTE_BTN_1, HIGH);
  pinMode(REMOTE_BTN_2, OUTPUT);          //down
  digitalWrite(REMOTE_BTN_2, HIGH);
  pinMode(REMOTE_BTN_3, OUTPUT);          //select
  digitalWrite(REMOTE_BTN_3, HIGH);
  pinMode(REMOTE_BTN_4, OUTPUT);          //stop
  digitalWrite(REMOTE_BTN_4, HIGH);

  fauxmo.createServer(true); // not needed, this is the default value
  fauxmo.setPort(80); // This is required for gen3 devices
  fauxmo.enable(true);
 
  fauxmo.addDevice(UP);
  fauxmo.addDevice(Down);
  fauxmo.addDevice(Light_Block);

  fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {                          //command recieved
   
    // Callback when a command from Alexa is received.
    Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
   
    if ( (strcmp(device_name, UP) == 0) ) {
      state = STATE_UP_START;
    }
   
    if ( (strcmp(device_name, Down) == 0) ) {                                                                                         //blinds down
      state = STATE_DOWN_START;
    }
  });
}

void stateMachine() {
   unsigned long m = millis();
   if(m > nextStateTime) {
      switch(state) {
         case STATE_IDLE :
            nextStateTime = m;
            break;
         case STATE_UP_START :
            digitalWrite(REMOTE_BTN_1, LOW);
            state = STATE_UP_STOP;
            nextStateTime = m + UP_DELAY;
            Serial.println("up started");
            break;
         case STATE_UP_STOP :
            digitalWrite(REMOTE_BTN_1, HIGH);
            state = STATE_IDLE;
            nextStateTime = m;
            Serial.println("up stopped");
            break;
         case STATE_DOWN_START :
            digitalWrite(REMOTE_BTN_2, LOW);
            state = STATE_DOWN_STOP;
            nextStateTime = m + DOWN_DELAY;
            Serial.println("down started");
            break;
         case STATE_DOWN_STOP :
            digitalWrite(REMOTE_BTN_2, HIGH);
            state = STATE_IDLE;
            nextStateTime = m;
            Serial.println("down stopped");
            break;
      }
   }
}

void loop() {
  fauxmo.handle();
  stateMachine();
}

// Wi-Fi Connection
void wifiSetup() {
  WiFi.mode(WIFI_STA);
  Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
    Serial.print("attempting to connect to wifi");
  while (WiFi.status() != WL_CONNECTED) {   
    Serial.print(".");
    delay(100);
  }
  Serial.println();
  Serial.printf("Connected to - SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}
User avatar
By GreenBlood
#85275 That’s interesting, will have a play:-)

btidey wrote:State machines are actually very simple and a good way of representing logic and timing in a maintainable way. The switch statement is at the heart of most state machines.

Take a look at the following where I try to represent your functionaity in a simple state machine. I haven't compiled or tested this but you should be able to see the flow.

Code: Select all#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "fauxmoESP.h"

#define WIFI_SSID "lemainemachon"
#define WIFI_PASS "jibajaba"
#define REMOTE_BTN_1 4 //up (D2)
#define REMOTE_BTN_2 14//down (D5)
#define REMOTE_BTN_3 12  //select (D6)
#define REMOTE_BTN_4 5//stop (D1)
#define UP "blinds Up"
#define Down "blinds Down"
#define Light_Block "Blinds light Block"

fauxmoESP fauxmo;

#define STATE_IDLE 0
#define STATE_UP_START 1
#define STATE_UP_STOP 2
#define STATE_DOWN_START 3
#define STATE_DOWN_STOP 4
#define UP_DELAY 1000
#define DOWN_DELAY 1000


int state = STATE_IDLE;
unsigned long nextStateTime;

void setup() {
  // Init serial port and clean garbage
  Serial.begin(115200);
  Serial.println();

  // Wi-Fi connection
  wifiSetup();

  // Set Buttons
  pinMode(REMOTE_BTN_1, OUTPUT);          //up
  digitalWrite(REMOTE_BTN_1, HIGH);
  pinMode(REMOTE_BTN_2, OUTPUT);          //down
  digitalWrite(REMOTE_BTN_2, HIGH);
  pinMode(REMOTE_BTN_3, OUTPUT);          //select
  digitalWrite(REMOTE_BTN_3, HIGH);
  pinMode(REMOTE_BTN_4, OUTPUT);          //stop
  digitalWrite(REMOTE_BTN_4, HIGH);

  fauxmo.createServer(true); // not needed, this is the default value
  fauxmo.setPort(80); // This is required for gen3 devices
  fauxmo.enable(true);
 
  fauxmo.addDevice(UP);
  fauxmo.addDevice(Down);
  fauxmo.addDevice(Light_Block);

  fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {                          //command recieved
   
    // Callback when a command from Alexa is received.
    Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
   
    if ( (strcmp(device_name, UP) == 0) ) {
      state = STATE_UP_START;
    }
   
    if ( (strcmp(device_name, Down) == 0) ) {                                                                                         //blinds down
      state = STATE_DOWN_START;
    }
  });
}

void stateMachine() {
   unsigned long m = millis();
   if(m > nextStateTime) {
      switch(state) {
         case STATE_IDLE :
            nextStateTime = m;
            break;
         case STATE_UP_START :
            digitalWrite(REMOTE_BTN_1, LOW);
            state = STATE_UP_STOP;
            nextStateTime = m + UP_DELAY;
            Serial.println("up started");
            break;
         case STATE_UP_STOP :
            digitalWrite(REMOTE_BTN_1, HIGH);
            state = STATE_IDLE;
            nextStateTime = m;
            Serial.println("up stopped");
            break;
         case STATE_DOWN_START :
            digitalWrite(REMOTE_BTN_2, LOW);
            state = STATE_DOWN_STOP;
            nextStateTime = m + DOWN_DELAY;
            Serial.println("down started");
            break;
         case STATE_DOWN_STOP :
            digitalWrite(REMOTE_BTN_2, HIGH);
            state = STATE_IDLE;
            nextStateTime = m;
            Serial.println("down stopped");
            break;
      }
   }
}

void loop() {
  fauxmo.handle();
  stateMachine();
}

// Wi-Fi Connection
void wifiSetup() {
  WiFi.mode(WIFI_STA);
  Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
    Serial.print("attempting to connect to wifi");
  while (WiFi.status() != WL_CONNECTED) {   
    Serial.print(".");
    delay(100);
  }
  Serial.println();
  Serial.printf("Connected to - SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}
User avatar
By GreenBlood
#85279 I’ve studied the code, a very nice simpleish solution:-) will see if I get get it to play when I get some time to....play;-)

Cheers Steve
GreenBlood wrote:That’s interesting, will have a play:-)

btidey wrote:State machines are actually very simple and a good way of representing logic and timing in a maintainable way. The switch statement is at the heart of most state machines.

Take a look at the following where I try to represent your functionaity in a simple state machine. I haven't compiled or tested this but you should be able to see the flow.

Code: Select all#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "fauxmoESP.h"

#define WIFI_SSID "lemainemachon"
#define WIFI_PASS "jibajaba"
#define REMOTE_BTN_1 4 //up (D2)
#define REMOTE_BTN_2 14//down (D5)
#define REMOTE_BTN_3 12  //select (D6)
#define REMOTE_BTN_4 5//stop (D1)
#define UP "blinds Up"
#define Down "blinds Down"
#define Light_Block "Blinds light Block"

fauxmoESP fauxmo;

#define STATE_IDLE 0
#define STATE_UP_START 1
#define STATE_UP_STOP 2
#define STATE_DOWN_START 3
#define STATE_DOWN_STOP 4
#define UP_DELAY 1000
#define DOWN_DELAY 1000


int state = STATE_IDLE;
unsigned long nextStateTime;

void setup() {
  // Init serial port and clean garbage
  Serial.begin(115200);
  Serial.println();

  // Wi-Fi connection
  wifiSetup();

  // Set Buttons
  pinMode(REMOTE_BTN_1, OUTPUT);          //up
  digitalWrite(REMOTE_BTN_1, HIGH);
  pinMode(REMOTE_BTN_2, OUTPUT);          //down
  digitalWrite(REMOTE_BTN_2, HIGH);
  pinMode(REMOTE_BTN_3, OUTPUT);          //select
  digitalWrite(REMOTE_BTN_3, HIGH);
  pinMode(REMOTE_BTN_4, OUTPUT);          //stop
  digitalWrite(REMOTE_BTN_4, HIGH);

  fauxmo.createServer(true); // not needed, this is the default value
  fauxmo.setPort(80); // This is required for gen3 devices
  fauxmo.enable(true);
 
  fauxmo.addDevice(UP);
  fauxmo.addDevice(Down);
  fauxmo.addDevice(Light_Block);

  fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {                          //command recieved
   
    // Callback when a command from Alexa is received.
    Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
   
    if ( (strcmp(device_name, UP) == 0) ) {
      state = STATE_UP_START;
    }
   
    if ( (strcmp(device_name, Down) == 0) ) {                                                                                         //blinds down
      state = STATE_DOWN_START;
    }
  });
}

void stateMachine() {
   unsigned long m = millis();
   if(m > nextStateTime) {
      switch(state) {
         case STATE_IDLE :
            nextStateTime = m;
            break;
         case STATE_UP_START :
            digitalWrite(REMOTE_BTN_1, LOW);
            state = STATE_UP_STOP;
            nextStateTime = m + UP_DELAY;
            Serial.println("up started");
            break;
         case STATE_UP_STOP :
            digitalWrite(REMOTE_BTN_1, HIGH);
            state = STATE_IDLE;
            nextStateTime = m;
            Serial.println("up stopped");
            break;
         case STATE_DOWN_START :
            digitalWrite(REMOTE_BTN_2, LOW);
            state = STATE_DOWN_STOP;
            nextStateTime = m + DOWN_DELAY;
            Serial.println("down started");
            break;
         case STATE_DOWN_STOP :
            digitalWrite(REMOTE_BTN_2, HIGH);
            state = STATE_IDLE;
            nextStateTime = m;
            Serial.println("down stopped");
            break;
      }
   }
}

void loop() {
  fauxmo.handle();
  stateMachine();
}

// Wi-Fi Connection
void wifiSetup() {
  WiFi.mode(WIFI_STA);
  Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
    Serial.print("attempting to connect to wifi");
  while (WiFi.status() != WL_CONNECTED) {   
    Serial.print(".");
    delay(100);
  }
  Serial.println();
  Serial.printf("Connected to - SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}