ST_Anything slows NodeMCU response times

1) Give a description of the problem

I am using a NodeMCU 12E to automate opening and closing of a pet door. The following hardware list and diagram below will provide an idea what is being done.
2 SPST switches for manual operation (open/close) of the door.
2 SPST switches for automatic motor shutoff at limit of open & close.
1 SPST Relay 3V coil for switching 12v motor power supply.
1 DPDT Relay 3V coil for reversing polarity on motor for open and close direction.

I got the arduino sketch operating properly on the Node MCU (without ST_Anything first) and response to manually activating switches is as expected and nearly instantaneous as monitored in serial monitor and via LED activation. Boolean logic for activating motor below:

if (digitalRead(closeLimitPin) == HIGH || digitalRead(openLimitPin)==HIGH) {
digitalWrite(motorStatePin, LOW); // Set pin to 0V for motor power OFF.
}
else if (digitalRead(closeButtonPin) == HIGH || digitalRead(remoteControl) == HIGH) {
digitalWrite(motorStatePin, HIGH); // Set pin to 1V for motor power on.
digitalWrite(motorDirPin, LOW); // Set pin to 0V for CLOSE Direction.
}
else if (digitalRead(openButtonPin) == HIGH) || digitalRead(PIN_remoteControl) == LOW) {
digitalWrite(motorStatePin, HIGH); // Set pin to 1V for motor power on.
digitalWrite(motorDirPin, HIGH); // Set pin to 1V for OPEN direction.
}
else {
digitalWrite(motorStatePin, LOW); // Set pin to 0V for motor power OFF.

I added ST_Anything with 4 contact sensors and one switch defined. The contact sensors are for monitoring status of the physical switches and the virtual switch is for activating a Digital Output pin which is used in the boolean logic for remotely opening and closing the door.
Successfully recognized my ST_Anything Parent and 5 Child devices in Smartthings Classic App.
I have two problems:
A) when I attempt to toggle the switch from the app I just get a “TurningOn” message indefinitely.
B) response times to physical interactions (switch activations) is delayed 1-30 seconds as evidenced both in the serial monitor and direct observation of test LEDs.

2) What is the expected behaviour?
A) Toggling switch device in Smartthings App will toggle HIGH/LOW value of NodeMCU pin.
B) no delay in response to activation of switches.

3) What is happening/not happening?
I have two problems:
A) when I attempt to toggle the switch from the app I just get a “TurningOn” message indefinately.
B) response times to physical interactions (switch activations) is delayed 1-30 seconds as evidenced both in the serial monitor and direct observation of test LEDs.

4) Wiring Diagram

I’m sorry, but I’m not understanding something. You have an “open limit switch” and a “close limit switch”. how are these implemented? Do you have a physical sensor or some kind that detects when the door is fully open or fully closed? I don’t understand how those are actually wired to control the actions of the motor.

Also, any logic that you put in place that is done through the cloud is going to be delayed. You are going to want to work your limiting switches into the callback method within the board itself. Otherwise you will run the motor for too long.

Since you had a sketch you liked, you might consider looking at one of the WIFI examples in the Smarthings directory of the Arduino library. These show you how to use the library to incorporate the ST_Anything communication with your own sketch, so as not to limit it to the ST_anything architecture.

@Ryan780, thanks for the reply.
The Open & Close limit switches are physical devices that are closed by contact with the door when it reaches full open or closed position. There are also two physical toggle switches to manually activate door open/close.

I am trying to use ST_Anything to remotely activate a 5th pin whose state is included in the boolean logic running on the ESP8266.

I agree about running the logic locally to prevent processing delay, that is why I built and tested my sketch without ST_Anything to begin with. Without ST_Anything the response times are instantaneous. I have no logic being processed in the cloud; however, the delay only started when I incorporated ST_Anything - I can’t tell if it is a delay due to monitoring the pin states or if there is some other communication occurring that is holding up the processor.

When I integrated ST_Anything into my stand alone sketch I used ST_Anything_Multiples_ESP8266WiFi as my template. I didn’t see any guidance on how to incorporate the ST_Anything communication with my sketch (I just reviewed all the #included files and tried to determine what was happening - I think I understand about 25% of what is being done).

You mention “callback method”. I have seen “callback” in some of the ST_Anything files. I’m not sure what this is or how it works. I simply put my if/then/else logic into the Loop() and then added the st::Everything::run(); line.

Thanks for your help.

/*
  Cat Door 

  Opens and closes automated door using Node MCU 12E.
  2 SPST switches for manual operation of the door.
  2 SPST switches for automatic motor shutoff at limit of open & close.
  1 SPST Relay 3V coil for switching 12v motor power supply.
  2 DPDT Relay 3V coil for reversing polarity on motor for open and close direction.
  
*/





//******************************************************************************************
// SmartThings Library for ESP8266WiFi
//******************************************************************************************
#include <SmartThingsESP8266WiFi.h>

//******************************************************************************************
// ST_Anything Library 
//******************************************************************************************
#include <Constants.h>       //Constants.h is designed to be modified by the end user to adjust behavior of the ST_Anything library
#include <Device.h>          //Generic Device Class, inherited by Sensor and Executor classes
#include <Sensor.h>          //Generic Sensor Class, typically provides data to ST Cloud (e.g. Temperature, Motion, etc...)
#include <Executor.h>        //Generic Executor Class, typically receives data from ST Cloud (e.g. Switch)
#include <InterruptSensor.h> //Generic Interrupt "Sensor" Class, waits for change of state on digital input 
#include <PollingSensor.h>   //Generic Polling "Sensor" Class, polls Arduino pins periodically
#include <Everything.h>      //Master Brain of ST_Anything library that ties everything together and performs ST Shield communications

//#include <PS_Illuminance.h>  //Implements a Polling Sensor (PS) to measure light levels via a photo resistor

#include <IS_Button.h>       //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin for button presses
#include <S_TimedRelay.h>    //Implements a Sensor to control a digital output pin with timing capabilities

#include <PS_TemperatureHumidity.h>  //Implements a Polling Sensor (PS) to measure Temperature and Humidity via DHT library. 
//#include <PS_Water.h>        //Implements a Polling Sensor (PS) to measure presence of water (i.e. leak detector)
//#include <IS_Motion.h>       //Implements an Interrupt Sensor (IS) to detect motion via a PIR sensor
#include <IS_Contact.h>      //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin
#include <EX_Switch.h>       //Implements an Executor (EX) via a digital output to a relay
//#include <EX_Alarm.h>        //Implements Executor (EX)as an Alarm Siren capability via a digital output to a relay



  int i = 0;

//*************************************************************************************************
//NodeMCU v1.0 ESP8266-12e Pin Definitions (makes it much easier as these match the board markings)
//*************************************************************************************************
  #define LED_BUILTIN 16
  #define BUILTIN_LED 16

  #define D0 16  //no internal pullup resistor
  #define D1  5
  #define D2  4
  #define D3  0  //must not be pulled low during power on/reset, toggles value during boot
  #define D4  2  //must not be pulled low during power on/reset, toggles value during boot
  #define D5 14
  #define D6 12
  #define D7 13
  #define D8 15  //must not be pulled high during power on/reset

  
//******************************************************************************************
//Define which ESP8266 12E/NodeMCU 12E pins will be used for each device
//******************************************************************************************

  #define PIN_openSwitch D7            // MCU D7 – Manual open switch
  #define PIN_openLimitSwitch D2       // MCU D2 – Stop power when door open
  #define PIN_closeSwitch D6           // MCU D6 – Manual close switch
  #define PIN_closeLimitSwitch D1      // MCU D1 – Stop power when door closed
  #define PIN_motorState D8            // MCU D8 – Power on/off    1=on, 0=off
  #define PIN_motorDir D5              // MCU D5 – Motor Direction  1=Open (NO), 0=Close (NC)
  #define PIN_remoteControl D0         // MCU D0 – Web Based control  1=Open, 0=Close

//******************************************************************************************
//ESP8266 WiFi Information
//******************************************************************************************
String str_ssid     = "xxxxxxxx";           //  <---You must edit this line!
String str_password = "xxxxxxxx";           //  <---You must edit this line!
IPAddress ip(10, 0, 0, 105);                  // Device IP Address       //  <---You must edit this line!
IPAddress gateway(10, 0, 0, 1);               // Router gateway          //  <---You must edit this line!
IPAddress subnet(255, 255, 255, 0);           // LAN subnet mask         //  <---You must edit this line!
IPAddress dnsserver(75, 75, 75, 75);          // DNS server              //  <---You must edit this line!
const unsigned int serverPort = 8090;         // port to run the http server on
IPAddress hubIp(10, 0, 0, 100);               // smartthings hub ip //  <---You must edit this line!
const unsigned int hubPort = 39500;           // smartthings hub port


//------------------------------------------------------------------------------------------
// the setup function runs once when you press reset or power the board
//------------------------------------------------------------------------------------------
void setup() 
{
//  Serial.begin(9600);

  pinMode(PIN_openSwitch, INPUT);               // initialize digital pins as an INPUT.
  pinMode(PIN_openLimitSwitch, INPUT);                // initialize digital pins as an INPUT.
  pinMode(PIN_closeSwitch, INPUT);              // initialize digital pins as an INPUT.
  pinMode(PIN_closeLimitSwitch, INPUT);               // initialize digital pins as an INPUT.
  pinMode(PIN_motorState, OUTPUT);              // initialize digital pins as an output.
  pinMode(PIN_motorDir, OUTPUT);                // initialize digital pins as an output.
  pinMode(PIN_remoteControl, OUTPUT);              // initialize digital pins as an output. 



  //******************************************************************************************
  //Declare each Device that is attached to the Arduino
  //  Notes: - For each device, there is typically a corresponding "tile" defined in your 
  //           SmartThings Device Hanlder Groovy code, except when using new COMPOSITE Device Handler
  //         - For details on each device's constructor arguments below, please refer to the 
  //           corresponding header (.h) and program (.cpp) files.
  //         - The name assigned to each device (1st argument below) must match the Groovy
  //           Device Handler names.  (Note: "temphumid" below is the exception to this rule
  //           as the DHT sensors produce both "temperature" and "humidity".  Data from that
  //           particular sensor is sent to the ST Hub in two separate updates, one for 
  //           "temperature" and one for "humidity")
  //         - The new Composite Device Handler is comprised of a Parent DH and various Child
  //           DH's.  The names used below MUST not be changed for the Automatic Creation of
  //           child devices to work properly.  Simply increment the number by +1 for each duplicate
  //           device (e.g. contact1, contact2, contact3, etc...)  You can rename the Child Devices
  //           to match your specific use case in the ST Phone Application.
  //******************************************************************************************
  
  
  //Interrupt Sensors 
    static st::IS_Contact             sensor1(F("contact1"), PIN_openLimitSwitch, HIGH, false, 0);
    static st::IS_Contact             sensor2(F("contact2"), PIN_closeLimitSwitch, HIGH, false, 0);
    static st::IS_Contact             sensor3(F("contact3"), PIN_openSwitch, HIGH, false, 0);
    static st::IS_Contact             sensor4(F("contact4"), PIN_closeSwitch, HIGH, false, 0); 
  
  //Executors
     static st::EX_Switch executor1(F("switch1"), PIN_remoteControl, LOW); 

  //*****************************************************************************
  //  Configure debug print output from each main class 
  //  -Note: Set these to "false" if using Hardware Serial on pins 0 & 1
  //         to prevent communication conflicts with the ST Shield communications
  //*****************************************************************************
  st::Everything::debug=true;
  st::Executor::debug=true;
  st::Device::debug=true;
  st::PollingSensor::debug=true;
  st::InterruptSensor::debug=true;

  //*****************************************************************************
  //Initialize the "Everything" Class
  //*****************************************************************************

  //Initialize the optional local callback routine (safe to comment out if not desired)
//  st::Everything::callOnMsgSend = callback;
  
  //Create the SmartThings ESP8266WiFi Communications Object
    //STATIC IP Assignment - Recommended
    st::Everything::SmartThing = new st::SmartThingsESP8266WiFi(str_ssid, str_password, ip, gateway, subnet, dnsserver, serverPort, hubIp, hubPort, st::receiveSmartString);
 
    //DHCP IP Assigment - Must set your router's DHCP server to provice a static IP address for this device's MAC address
    //st::Everything::SmartThing = new st::SmartThingsESP8266WiFi(str_ssid, str_password, serverPort, hubIp, hubPort, st::receiveSmartString);

  //Run the Everything class' init() routine which establishes WiFi communications with SmartThings Hub
  st::Everything::init();
  
  //*****************************************************************************
  //Add each sensor to the "Everything" Class
  //*****************************************************************************
  st::Everything::addSensor(&sensor1);
  st::Everything::addSensor(&sensor2);
  st::Everything::addSensor(&sensor3);
  st::Everything::addSensor(&sensor4); 
      
  //*****************************************************************************
  //Add each executor to the "Everything" Class
  //*****************************************************************************
  st::Everything::addExecutor(&executor1);
     
  //*****************************************************************************
  //Initialize each of the devices which were added to the Everything Class
  //*****************************************************************************
  st::Everything::initDevices();
  




}

// the loop function runs over and over again forever
void loop() {
  //*****************************************************************************
  //Execute the Everything run method which takes care of "Everything"
  //*****************************************************************************
  st::Everything::run();

  
//  Serial.print("\t\t"); Serial.print("Close Switch");
//  Serial.print("\t\t"); Serial.print("Open Switch");
//  Serial.print("\t\t"); Serial.print("On/Off");
//  Serial.print("\t\t"); Serial.print("Direction"); Serial.print("\n");

  
  if (digitalRead(PIN_closeLimitSwitch) == HIGH || digitalRead(PIN_openLimitSwitch)==HIGH)  // This test will need to be separated distributed to next two if statements 
    {
      digitalWrite(PIN_motorState, LOW);   // Set pin to 0V for motor power OFF.
    }

 else if (digitalRead(PIN_closeSwitch) == HIGH || digitalRead(PIN_remoteControl) == HIGH) 
    {
        digitalWrite(PIN_motorState, HIGH);   // Set pin to 1V for motor power on.
        digitalWrite(PIN_motorDir, LOW);      // Set pin to 0V for CLOSE Direction.
    }

  else if (digitalRead(PIN_openSwitch) == HIGH || digitalRead(PIN_remoteControl) == LOW) 
    {
        digitalWrite(PIN_motorState, HIGH);    // Set pin to 1V for motor power on.
        digitalWrite(PIN_motorDir, HIGH);      // Set pin to 1V for OPEN direction.
    }
  else
    {
        digitalWrite(PIN_motorState, LOW);   // Set pin to 0V for motor power OFF.
    }
  
//  Serial.print(i++);
//  Serial.print("\t\t\t"); Serial.print(digitalRead(PIN_closeSwitch));
//  Serial.print("\t\t\t"); Serial.print(digitalRead(PIN_openSwitch));
//  Serial.print("\t\t");   Serial.print(digitalRead(PIN_motorState));
//  Serial.print("\t\t\t"); Serial.println(digitalRead(PIN_motorDir)); Serial.print("\n");
   
//  delay(250);                       // wait for a 1/4 second
}

Well, that is the reason you are seeing slow-downs. The ST_Anything library was not intended to do what you are trying to do.

First thing you want to do, pull everything out that is not ST_Anything. You won’t need any of it. Also, you have a delay in your software. This won’t work as it is blocking receiving anything from the hub or anything else processing during the delay. Cannot use delay with ST_Anything.

What I don’t understand is how you get the motor to go in two directions. It is not clear from me how you are doing that.

But in general, this will require an entire re-write in order to use ST_Anything. You aren’t not using it correctly. I do not have the necessary hours it will take to rewrite it for you. So, I would recommend you read some of the ST_Anything thread and try to re-write it yourself. If i have some time this weekend or next week I can try to help you more but you are basically asking “do this for me” and I don’t have the time. Sorry.

What you want to do is set the board up using ONLY the ST_Anything setup. Then use the callback feature to execute commands locally on the board.

So, I would start with a new copy of the example sketch and start over.

I don’t believe that what he has in the loop() should negatively impact ST_Anything. He’s just checking the status of the contact sensor digital input pins and updating the corresponding digital output pins accordingly. Those two digital outputs are not controlled by ST_Anything. So, what his code it doing should be harmless… :thinking:

His delay() statement is commented out within the loop() routine. So again, it should be harmless.

In the main ST_Anything thread I have asked him to try recreating the Parent device and to run some tests, including having his extra code in the loop() routine commented out just to double check that it is not causing any issues.

It could be a WiFi issue, or a hub issue (I asked hime to reboot his ST hub as well for good measure… :wink: )

Thanks Ryan and Dan for the assistance.

I did not intend to give the impression I wanted anyone to “do this for me”, on the contrary, as a hobby I actually want to learn by doing; I just ran up against a problem that I couldn’t see a solution to.

The DPDT relay when triggered by the digital out pin for motor direction will switch the polarity of the inputs to the DC motor.

I am stepping back and testing using the suggestions Dan provided this afternoon to see if I can isolate what might be introducing the delays I’m seeing.

Thanks again for the support.

Dan

Progress!

I started with a fresh copy of the ST_Anything_Multiples_ESP8266WiFi sketch and only replaced the sample sensors/executors with my devices.
Resulting behavior was still delayed responses to contact switch activation as seen in the serial monitor.
I reset the Smartthings hub and BINGO! I now have fast response to sensor activation in the serial monitor again.

I went back to my original sketch and tested with my custom code commented and still had good response time in teh serial monitor. Uncommented my custom code and behavior is fast and working as expected, EXCEPT…

I still cannot activate the switch child device. When I attempt to toggle within the ST classic app it just hangs at “turning on”

I did delete the parent & all child devices individually from the app and re-discover, but that hasn’t helped.

Any more suggestions?

Thanks again,
Dan

Problem resolutions

  1. Hard reset of the SmartThings hub resolved the delayed processing observed in the NodeMCU serial monitor.
  2. Review of SmartThings Web IDE Live Log revealed misconfiguration of parent device IP address in SmartThings Classic Mobile App preventing communication from app to NodeMCU.
1 Like