Pulse Timer (for misting)

Perhaps???.. I am actually not good at following others (or for that matter my own) code flow and logic just by looking at it without spending a lot of time with it running in front of me to compare what I think should happen with what does :blush:

But as far as a basic if else() then yes that should work… but can be made fractionaly simpler since there is only the two options of HIGH or LOW for the btnState

if (btnState=HIGH)
{
onRelay();
}
else
{
timer.disable(timerId1);
timer.disable(timerId2);
}

Now, where you put this logic code is another matter that may or may not affect its functionality.

ah yes that makes sense, its one or the other.

As to where to put the code, should it go inside Void Loop perhaps as this is the main function we want running over and over?

Nope nope nope :stuck_out_tongue: … You could put it in another fast timed function (100-250ms?) or a Blynk function (reacting to a button or timer widget call), depending on your needs.

Not sure where it’s at now, I compiled it (without error) so I uploaded and nothing happens when I turn D5 on.

The reason I picked Pin 4 for the RelayPin is so when this turns HIGH I can see via the built in LED on the NodeMCU. A separate D4 button I created works, when I press that I see the LED light up on the NodeMCU.

Here’s the code, but nothing’s happening.
I now have a feeling the onRelay and offRelay functions should be nested inside the new function I created (mainfunction)

Also should the btnstate be LOW when declaring it?

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

float MistRunTime;
int DelayTime;
int RelayState = LOW; //assuming active HIGH relay, change to LOW if active LOW
int btnState = HIGH;
int timerId1;
int timerId2;

// Set your Relay and physical button pins here
const int RelayPin = 4;
const int btnPin = 5;

BlynkTimer timer;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "";
char pass[] = "";


// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  // Request the latest state from the server
  Blynk.syncVirtual(V2);
  Blynk.syncVirtual(V3);
  Blynk.syncVirtual(V4);

  // Alternatively, you could override server state using:
  //Blynk.virtualWrite(V2, RelayState);
}

// When App button is pushed - switch the state
BLYNK_WRITE(V2) {
  RelayState = param.asInt();
  digitalWrite(RelayPin, RelayState);
}

void checkPhysicalButton()
{
  if (digitalRead(btnPin) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btnState != LOW) {

      // Toggle Relay state
      RelayState = !RelayState;
      digitalWrite(RelayPin, RelayState);

      // Update Button Widget
      Blynk.virtualWrite(V2, RelayState);
    }
    btnState = LOW;
  } else {
    btnState = HIGH;
  }
}


BLYNK_WRITE (V3) // Time interval for misting 0.5-10 seconds
{
MistRunTime = param.asFloat(); // assigning incoming value from Virtual Pin V3 to a variable

Serial.println(MistRunTime);
}



BLYNK_WRITE (V4) // Time interval for delay 5-120 seconds
{
DelayTime = param.asInt(); // assigning incoming value from Virtual Pin 4 to a variable

Serial.println(DelayTime);
}


void onRelay()
{
digitalWrite(RelayPin, HIGH); //turn relay ON
timerId1 = timer.setTimeout(MistRunTime*1000, offRelay); //run after
}

void offRelay()
{
digitalWrite(RelayPin, LOW);//turn relay OFF
timerId2 = timer.setTimeout(DelayTime*1000, onRelay); //run after
}



void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);

  pinMode(RelayState, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  digitalWrite(RelayState, RelayState);

  // Setup a function to be called every 100 ms
  timer.setInterval(100L, checkPhysicalButton);
}



void mainfuction()
{
  
if (btnState=HIGH)
{
onRelay();
}
else
{
timer.disable(timerId1);
timer.disable(timerId2);
}
}


void loop()
{
  Blynk.run();
  timer.run();
}

I would merge that last timer disabling code into your timed checkPhysicalButton() function… so that if Button ON it works, if OFF it stops… no need to have yet another function like your mainfuction() that, BTW, doesn’t seem to be called from anywhere else anyhow :stuck_out_tongue:

I am heading to sleepn so you are on your own :sleeping:

ok haha what time zone are you
enjoy your sleep :slight_smile:

This is correct, hence why I recommended the use of a flag.

Same here. I tend to have to read and then re-read and then re-read again before I start to understand some snippets of code. Especially when they are not quite finished.

Yes, you did, but this is not the same as D4. Usually, D4 (GPIO 2) is connected to the built-in LED, but this is also one of the pins you want to avoid using (unless you know what you are doing). If it is pulled to the wrong state on boot, your esp may boot in the wrong mode. I think you need to do some research on the difference between the D numbers listed on the board, and the GPIO numbers best used for programming.

No, but I guess it wouldn’t matter that much. It is used as more of a way to avoid rapid toggling of the relay if the button is held down. If you declare it LOW and are holding the button at startup, it will allow the relay to trigger. With it declared as HIGH holding the button on startup will do nothing. You will have to release the button first and then press it again to trigger the relay.

As mentioned before, you should take the time to understand what the code is doing. Otherwise, when attempting future projects it will be like starting from the beginning. I do a lot of cut-and-paste programming, but not blindly. Before using a snippet of code, I take the time to understand what it is doing, how it is doing it and why. When you know these things, it is easier to know where and when to apply them to different projects. It will also aid in situations where you cannot find a code snippet to copy, as you will have a better understanding of how to code.

Pacific… which doesn’t mean much to me with my sleep patterns :stuck_out_tongue:

Well here is my code for an adjustable cycling relay. I have not done a full hardware to test, but the virtual LED does flash in the APP as it should. So I suspect it would work just fine once all hardware is connected. I did notice that the timer for the physical button was behaving strangely once the cycling function was triggered. After trying a few different thing I found that adding a second timer seemed to fix it. I never really got to the root of the issue (it has something to do with the timer.deleteTimer(timerId1) and timer.deleteTimer(timerId2)), as once I figured out adding the second timer fixed it I stopped there. Maybe I will revisit it once I get the rest of the project sorted out.

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "AUTH";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "WIFI";
char pass[] = "PASSWORD";

BlynkTimer timer;
BlynkTimer timer2;

const int relayPin = 12; //GPIO pin relay is attached to (D6)
const int btnPin = 14; //pin physical button is attached to. wired between GPIO13 (D7) and GND

int cycleState = LOW;
int btnState = HIGH;

float RunTime = 1;
int DelayTime = 1;

int timerId1;
int timerId2;
int timerId3;

int ReCnctFlag;  // Reconnection Flag
int ReCnctCount = 0;  // Reconnection counter

int onFlag = 0;

WidgetLED led1(V10);

// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  // Request the latest state from the server
  Blynk.syncVirtual(V1, V2, V7);
  ReCnctCount = 0;

}

// When App button is pushed - switch the state. The button should be on virtual pin 7 and set to switch
BLYNK_WRITE(V7) {
  cycleState = param.asInt();

  if (cycleState == HIGH) {
    onFlag = 1;
    onRelay();

  }
  else if (cycleState == LOW) {
    onFlag = 0;
  }

}

void checkPhysicalButton()
{
  //Serial.println("BUTTON CHECK");
  if (digitalRead(btnPin) == LOW) {
    // btnState is used to avoid sequential toggles
    //Serial.println("BUTTON PRESSED");
    if (btnState != LOW) {

      // Toggle cycleState
      cycleState = !cycleState;
      Blynk.virtualWrite(V7, cycleState);
      if (cycleState == HIGH) {
        onFlag = 1;
        onRelay();
      }
      else if (cycleState == LOW) {
        onFlag = 0;
      }

    }
    btnState = LOW;
  }
  else {
    btnState = HIGH;
  }
}

BLYNK_WRITE (V1) // Time interval for misting 0.5-10 seconds
{
  RunTime = param.asFloat(); // assigning incoming value from pin V1 to a variable

  Serial.println(RunTime);
}



BLYNK_WRITE (V2) // Time interval for delay 5-120 seconds
{
  DelayTime = param.asInt(); // assigning incoming value from pin V2 to a variable

  Serial.println(DelayTime);
}


void onRelay()
{
  if (onFlag == 1) {
    timer.deleteTimer(timerId1);//delete timers in case they are still running, that is buttons turned on/off/on too fast
    timer.deleteTimer(timerId2);//delete timers in case they are still running, that is buttons turned on/off/on too fast
    digitalWrite(relayPin, HIGH); //turn relay ON
    led1.on();
    Serial.println("ON");
    timerId1 = timer.setTimeout(RunTime * 1000, offRelay); //run after
  }

}

void offRelay()
{
  digitalWrite(relayPin, LOW);//turn relay OFF
  led1.off();
  Serial.println("OFF");
  timerId2 = timer.setTimeout(DelayTime * 1000, onRelay); //run after
}

void setup()
{
  // Debug console
  Serial.begin(115200);

  pinMode(relayPin, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  digitalWrite(relayPin, LOW); //relay is active HIGH, start with relay OFF

  WiFi.begin(ssid, pass);  // Non-blocking if no WiFi available
  Blynk.config(auth);
  Blynk.connect();

  // Setup a function to be called every 100 ms
  timerId3 = timer2.setInterval(100L, checkPhysicalButton);
}

void loop()
{
  if (Blynk.connected()) {  // If connected run as normal
    Blynk.run();
  } else if (ReCnctFlag == 0) {  // If NOT connected and not already trying to reconnect, set timer to try to reconnect in 30 seconds
    ReCnctFlag = 1;  // Set reconnection Flag
    Serial.println("Starting reconnection timer in 30 seconds...");
    timer2.setTimeout(30000L, []() {  // Lambda Reconnection Timer Function
      ReCnctFlag = 0;  // Reset reconnection Flag
      ReCnctCount++;  // Increment reconnection Counter
      Serial.print("Attempting reconnection #");
      Serial.println(ReCnctCount);
      Blynk.connect();  // Try to reconnect to the server
    });  // END Timer Function
  }
  timer.run();
  timer2.run();
}

I think I will just give up on it for this year…too much to do and no time to do it, perhaps a Christmas 2019 hobby. :disappointed_relieved:

Merry Christmas and see you next year.