Need help with electric valve arm

Hello

I’ve had a play around with an ESP01 I have here and come up with a kind of controllable 2 relay setup.

I can’t get the “STOP” command to interrupt the DoAction loop, but I’m sure it’s only something small that I’ve missed.
(It’ll give you something to fix) Update, it was bugging me so I changed my approach, see 2nd script below

This is the Node-RED flow I use to control it with MQTT

Command structure I’ve used is -

Command:Duration in Milliseconds

IE

UP:5000 = UP for 5000ms
DOWN:1500 = Down for 1500ms

STOP = ALL STOP, regardless of current state

UP = UP with a default duration of 500ms
DOWN = DOWN with a default duration of 500ms

[
    {
        "id": "209ddf60.f3782",
        "type": "mqtt out",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "topic": "",
        "qos": "",
        "retain": "",
        "broker": "",
        "x": 3330,
        "y": 400,
        "wires": []
    },
    {
        "id": "8c7b3762.f07ec8",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "UP:300000",
        "payloadType": "str",
        "x": 3070,
        "y": 200,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    },
    {
        "id": "b77fba37.7a8908",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "DOWN:20000",
        "payloadType": "str",
        "x": 3040,
        "y": 400,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    },
    {
        "id": "e72e06b.de6e3f8",
        "type": "mqtt in",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "topic": "Blind01_FB",
        "qos": "2",
        "datatype": "auto",
        "broker": "",
        "x": 3530,
        "y": 480,
        "wires": [
            [
                "b1739811.4bc9f8"
            ]
        ]
    },
    {
        "id": "b1739811.4bc9f8",
        "type": "debug",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "active": true,
        "tosidebar": false,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 3760,
        "y": 480,
        "wires": []
    },
    {
        "id": "22bf4f3c.5a128",
        "type": "mqtt in",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "topic": "Blind01",
        "qos": "2",
        "datatype": "auto",
        "broker": "",
        "x": 3500,
        "y": 400,
        "wires": [
            [
                "bc2f7060.0badc"
            ]
        ]
    },
    {
        "id": "bc2f7060.0badc",
        "type": "debug",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "active": true,
        "tosidebar": false,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 3750,
        "y": 400,
        "wires": []
    },
    {
        "id": "7a7a5e84.96c37",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "STOP",
        "payloadType": "str",
        "x": 3070,
        "y": 620,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    },
    {
        "id": "bd5f8031.91001",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "UP:2000",
        "payloadType": "str",
        "x": 3060,
        "y": 280,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    },
    {
        "id": "2d88268b.a6910a",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "DOWN:1500",
        "payloadType": "str",
        "x": 3050,
        "y": 480,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    },
    {
        "id": "c23071b9.b6248",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "DOWN:6000",
        "payloadType": "str",
        "x": 3050,
        "y": 440,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    },
    {
        "id": "6db34c1a.f27f24",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "UP:6000",
        "payloadType": "str",
        "x": 3060,
        "y": 240,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    },
    {
        "id": "e7022e4a.2119c",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "UP:3000000",
        "payloadType": "str",
        "x": 3070,
        "y": 160,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    },
    {
        "id": "3da71972.8feda6",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "UP",
        "payloadType": "str",
        "x": 3020,
        "y": 120,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    },
    {
        "id": "f6d6d67f.9f3e78",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "DOWN",
        "payloadType": "str",
        "x": 3040,
        "y": 520,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    },
    {
        "id": "acb41424.6c9418",
        "type": "inject",
        "z": "bf2ab0d4.458a7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "Blind01",
        "payload": "stop",
        "payloadType": "str",
        "x": 3050,
        "y": 680,
        "wires": [
            [
                "209ddf60.f3782"
            ]
        ]
    }
]

And this is the Arduino script I use on the ESP8266 / ESP01 board

#include "EspMQTTClient.h"



 #define Identifier "Blind01" // Delimiter is "_"

/* Which software GPio Pin to use (not the same as marked on board)

ESP01 = Pin 2 or 0
NodeMCU = Pin 5
*/

int UP = 2;
int DOWN = 0;



// MQTT client setup example

EspMQTTClient client(
  "WifiSSID",
  "WifiPassword",
  "192.168.1.100",  // MQTT Broker server ip
//  "MQTTUsername",   // Can be omitted if not needed
//  "MQTTPassword",   // Can be omitted if not needed
  Identifier,     // Client name that uniquely identify your device, as set above
//  1883              // The MQTT port, default to 1883. this line can be omitted
 );








int ind1; 
int ind2;
String Command = "OFF" ;
String Duration = "500" ;
int Event;



volatile int state = false;
volatile int flag = false;
String input_state = "OFF";
String LEDState = "System Boot";




void ICACHE_RAM_ATTR changeStatus ();

unsigned long previousMillis = 0; 
const long interval = 150;



void setup() {
  
      Serial.begin(9600);
    delay(2000);


      Serial.println("LED Setup....");
     pinMode(UP,OUTPUT);
     pinMode(DOWN,OUTPUT);
     
    digitalWrite(UP, LOW);
    digitalWrite(DOWN, LOW);
        delay(350);
    digitalWrite(UP, HIGH); 
    digitalWrite(DOWN, LOW); 
        delay(350);
        digitalWrite(UP, LOW);
    digitalWrite(DOWN, LOW);



    delay(2000);

          Serial.println("2nd Blink ....");
      
    digitalWrite(UP, LOW);
    digitalWrite(DOWN, LOW);
        delay(350);
    digitalWrite(UP, HIGH); 
    digitalWrite(DOWN, LOW); 
        delay(350);
        digitalWrite(UP, LOW);
    digitalWrite(DOWN, LOW);






 
    Serial.println("Preparing MQTT Relay control project...");
    

    Serial.println();
    Serial.println();
    Serial.print("Connecting to MQTT broker ");

    
      WiFi.mode(WIFI_OFF);        //Prevents reconnection issue (taking too long to connect)
       delay(1000);
      WiFi.mode(WIFI_STA);        //This line hides the viewing of ESP as wifi hotspot
                                   //WIFI_STA It's very important !!!!
    

  
    Serial.println("");
    Serial.println("No 5 is alive");  

 
}
  


void onConnectionEstablished() {

  client.subscribe(Identifier, [] (const String &payload)  {
    Serial.println(payload);
      ind1 = payload.indexOf(':');  //finds location of first ,
 Command = payload.substring(0, ind1);   //captures first data String
      ind2 = payload.indexOf(':', ind1+1 );   //finds location of second ,
 Duration = payload.substring(ind1+1, ind2);   //captures second data String

 if ( Command != "UP" || Command != "up" || Command != "DOWN" || Command != "down"|| Command == "STOP"|| Command == "stop"|| payload == "STOP"|| payload == "stop"){
        digitalWrite(UP, LOW); // Change these to HIGH if your relays work that way
        digitalWrite(DOWN, LOW);
        client.publish(String(Identifier)+ "_FB", String(Identifier)+ " state = STOPPED");
        Event = 0; // Reset event so that a new message can overide this
                     };

                     

 if ( Command == "UP" || Command == "up" || Command == "DOWN" || Command == "down"){

        Event = 1; // Triggers DoAction timer loop
  
                  }

                  
  }

); // End of Subscribe loop
  
  client.publish(String(Identifier)+ "_FB", String(Identifier)+ " state = " + Command);
//  client.publish(String(Identifier), String(Identifier)+ " is Alive");






}






void loop() {
  client.loop();
  DoAction();
}


void DoAction(){

if (Event >0){

 if ( Command == "UP" || Command == "up"){
        digitalWrite(UP, HIGH); // Change these to HIGH or LOW according to how your relays work
        digitalWrite(DOWN, LOW);
 }



 if ( Command == "DOWN" || Command == "down"){
        digitalWrite(UP, LOW); // Change these to HIGH or LOW according to how your relays work
        digitalWrite(DOWN, HIGH);
  
 }
   client.publish(String(Identifier)+ "_FB", String(Identifier)+ " state = " + Command + ": Time = "+ Duration.toInt());

 if (!Duration){
  Duration = "5000"; // Sets a default duration if none is in the message
 }

 
delay(Duration.toInt()); // Durations of delay set by message
        digitalWrite(UP, LOW); // Change these to HIGH or LOW according to how your relays work
        digitalWrite(DOWN, LOW);
        client.publish(String(Identifier)+ "_FB", String(Identifier)+ " state = STOP");
   Event = 0; // Reset event so that a new message can overide this 

}


}

Good luck, if you fix the STOP command, please do share how you manage it

This might help

https://forum.arduino.cc/index.php?topic=223286.0


Update

Well that didn’t take very long, I must be slowly learning things.

This version of the script (which uses a Time Check routine rather than a Delay command (Which seems to mean “Stop doing everything”) enables the STOP command.

#include "EspMQTTClient.h"



 #define Identifier "Blind01" // Delimiter is "_"

/* Which software GPio Pin to use (not the same as marked on board)

ESP01 = Pin 2 or 0
NodeMCU = Pin 5
*/

int UP = 2; // UP Relay connected to GPio No. (Which is not always the same as marked on the board)
int DOWN = 0; // DOWN Relay connected to GPio No. (Which is not always the same as marked on the board)

// If your relay board is inverted, just go through this Script and swap HIGH for LOW etc


// MQTT client setup example

EspMQTTClient client(
  "WifiSSID", // Your 2.4Ghz WiFi SSid
  "WifiPassword",  // Your WiFi password
  "192.168.1.100",  // MQTT Broker server ip
//  "MQTTUsername",   // Can be omitted if not needed
//  "MQTTPassword",   // Can be omitted if not needed
  Identifier,     // Client name that uniquely identify your device, as defined above
//  1883              // The MQTT port, default to 1883. this line can be omitted
 );







int ind1; 
int ind2;
String Command = "OFF" ;
String Duration = "500" ;
bool Event;
bool Timer;



unsigned long currentMillis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previousMillis = 0;   // will store last time an action happened





void setup() {
  
      Serial.begin(9600);
    delay(2000);


      Serial.println("LED Setup....");
     pinMode(UP,OUTPUT);
     pinMode(DOWN,OUTPUT);
     
    digitalWrite(UP, LOW);
    digitalWrite(DOWN, LOW);
        delay(350);
    digitalWrite(UP, HIGH); 
    digitalWrite(DOWN, LOW); 
        delay(350);
        digitalWrite(UP, LOW);
    digitalWrite(DOWN, LOW);



    delay(2000);

          Serial.println("2nd Blink ....");
      
    digitalWrite(UP, LOW);
    digitalWrite(DOWN, LOW);
        delay(350);
    digitalWrite(UP, HIGH); 
    digitalWrite(DOWN, LOW); 
        delay(350);
        digitalWrite(UP, LOW);
    digitalWrite(DOWN, LOW);






 
    Serial.println("Preparing MQTT Relay control project...");
    

    Serial.println();
    Serial.println();
    Serial.print("Connecting to MQTT broker ");

    
      WiFi.mode(WIFI_OFF);        //Prevents reconnection issue (taking too long to connect)
       delay(1000);
      WiFi.mode(WIFI_STA);        //This line hides the viewing of ESP as wifi hotspot
                                   //WIFI_STA It's very important !!!!
    

  
    Serial.println("");
    Serial.println("No 5 is alive");  

 
}
  


void onConnectionEstablished() {

  client.subscribe(Identifier, [] (const String &payload)  {
    Serial.println(payload);
      ind1 = payload.indexOf(':');  //finds location of first ,
 Command = payload.substring(0, ind1);   //captures first data String
      ind2 = payload.indexOf(':', ind1+1 );   //finds location of second ,
 Duration = payload.substring(ind1+1, ind2);   //captures second data String

 if ( Command == "STOP"|| Command == "stop"|| payload == "STOP"|| payload == "stop"){
        digitalWrite(UP, LOW); // Change these to HIGH if your relays work that way
        digitalWrite(DOWN, LOW);
        client.publish(String(Identifier)+ "_FB", String(Identifier)+ " state = STOPPED");
        Serial.println("Stopped by MQTT command at " + String(currentMillis));
        Event = false; // Reset event so that a new message can overide this
        Timer = false; // Cancel timer
                     };

                     

 if ( Command == "UP" || Command == "up" || Command == "DOWN" || Command == "down"){
 //       Serial.println("MQTT command " state = " + Command + ": Time = "+ Duration.toInt());
        Event = true; // Triggers DoAction timer loop
  
                  }

                  
  }

); // End of Subscribe loop
  
  client.publish(String(Identifier)+ "_FB", String(Identifier)+ " state = " + Command);
  client.publish(String(Identifier), String(Identifier)+ " is Alive");






}






void loop() {

   currentMillis = millis();   // capture the latest value of millis()
                             //   this is equivalent to noting the time from a clock
  client.loop();
  DoAction();
  TimerAction();
}


void DoAction(){

if (Event){


 if (Duration.toInt() == 0){
  Duration = "500"; // Sets a default duration if none is in the message
 }



 if ( Command == "UP" || Command == "up"){
        digitalWrite(UP, HIGH); // Change these to HIGH or LOW according to how your relays work
        digitalWrite(DOWN, LOW);
 }



 if ( Command == "DOWN" || Command == "down"){
        digitalWrite(UP, LOW); // Change these to HIGH or LOW according to how your relays work
        digitalWrite(DOWN, HIGH);

  
 }

         Serial.println("MQTT command = " + Command + ": Time = "+ Duration.toInt());
         
         client.publish(String(Identifier)+ "_FB", String(Identifier)+ " state = " + Command + ": Time = "+ Duration.toInt());

 if (!Duration){
  Duration = "5000"; // Sets a default duration if none is in the message
 }

        previousMillis = currentMillis; // Store point in time when action occured
        Event = false;
        Timer = true; // Start timer
            Serial.println("Timer started at " + String(currentMillis));
}


}



void TimerAction(){
  if (Timer) {
  if (currentMillis - previousMillis >= Duration.toInt()) {

    Serial.println("Timer stopped at " + String(currentMillis));
        Timer = false; 
        digitalWrite(UP, LOW); // Change these to HIGH or LOW according to how your relays work
        digitalWrite(DOWN, LOW);
        client.publish(String(Identifier)+ "_FB", String(Identifier)+ " state = STOP");
    
  }

    
  }

}

image

2 Likes