Trouble with turning off a pin using millis


#1

I used the blink without delay example to help me write this. The idea is that I would click the widget in the dashboard on then off and let the code turn the pin off after a period of time. I have my variable “oneHour” currently set to 5000. When I turn on my widget in the dashboard, the pin goes high then almost immediately goes low. I think I’m close but…

CAYENNE_IN(VIRTUAL_PIN3)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt(); // 0 to 1
  unsigned long currentMillis = millis();
  unsigned long previousMillis = 0;
  // read the state of the switch into a local variable:
  reading = digitalRead(buttonPin);
  buttonState = reading;
  Serial.print("buttonState ");
  Serial.print(buttonState);  
      // assuming you wire your relay as normally open
      if (currentValue == 1 || buttonState == 1) {
        Serial.println("1st if");
        digitalWrite(ledPin, HIGH);
        digitalWrite(relayPin, HIGH);
        count++;
        if (currentMillis - previousMillis >= oneHour){
          previousMillis = currentMillis;
          Serial.println("2nd if");
          if (count > preCount){                 
            Serial.println("3rd if");
            digitalWrite(ledPin, LOW);
            digitalWrite(relayPin, LOW);
            buttonState = 0;
            preCount = count;
          }
        }
      }
    }

#2

i have a similar problem , i made 2 switches ( buttons ) on my dashboard and i programmed my ESP8266 E12 module but the problem is when i click on of them some times the other turns OFF i dont know why , maybe there is a bug in the website


#3

Thanks for your reply. I dont think we are seeing the same problem. If I remove my millis counting code I can turn it on/off. My issue is that it turns on but then immediately turns back off. It happens very quickly.


#4

Hi @modsbyus,

Try this method:

Cheers,

Craig


#5

I tried the library you suggested.Still a no go. The relay turns on but doesn’t turn back off.
Heres my full program. Maybe I am just doing something stupid.

//#define CAYENNE_DEBUG // Uncomment to show debug messages
#define CAYENNE_PRINT Serial // Comment this out to disable prints and save space

#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Timer.h"
#define VIRTUAL_PIN1 V1
#define VIRTUAL_PIN2 V2
#define VIRTUAL_PIN3 V3
Timer t;

// Digital pin the DS18B20 is connected to. Do not use digital pins 0 or 1 since those conflict with the use of Serial.
const int tmpPin = D7;
const int buttonPin = D4;     // the number of the pushbutton pin
const int ledPin =  D5;      // the number of the LED pin
const int relayPin = D6; // Pin to controll relay
const int relayMon = D3;  // Loopback from relay pin output
int reading;              //variable to store button state
int buttonState;         // variable for reading the pushbutton status
OneWire oneWire(tmpPin);
DallasTemperature sensors(&oneWire);

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "s755pmgd4p";
// Your network name and password.
char ssid[] = "obnoxious";
char password[] = "flabergast";

void setup()
{
  Serial.begin(9600);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  //initialize the relay pin as an output
  pinMode(relayPin, OUTPUT);
  Cayenne.begin(token, ssid, password);
  sensors.begin();
  t.pulse(relayPin, 10 * 1000, LOW); // 10 seconds
  
}

void loop()
{
  Cayenne.run();
    
}

CAYENNE_OUT(V1)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  
  // This command writes the temperature in Celsius to the Virtual Pin.
  //Cayenne.virtualWrite(VIRTUAL_PIN, sensors.getTempCByIndex(0));
  // To send the temperature in Fahrenheit use the corresponding code below.
  //Cayenne.fahrenheitWrite(VIRTUAL_PIN, sensors.getTempFByIndex(0));
  //Serial.print(VIRTUAL_PIN, sensors.getTempCByIndex(0));
  Cayenne.virtualWrite(VIRTUAL_PIN1, sensors.getTempFByIndex(0));
  
}

CAYENNE_OUT(V2)
{
  Cayenne.virtualWrite(VIRTUAL_PIN2, digitalRead(relayMon));
}

CAYENNE_IN(VIRTUAL_PIN3)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt(); // 0 to 1
  // read the state of the switch into a local variable:
  reading = digitalRead(buttonPin);
  buttonState = reading;
  Serial.print("buttonState ");
  Serial.print(buttonState);  
      // assuming you wire your relay as normally open
      if (currentValue == 1 || buttonState == 1) {
        digitalWrite(relayPin, HIGH);
        t.update();
        buttonState = 0;
      }
    }

#6

@modsbyus,

I suggest you run the following code as is to see how the timer pulse function works:

//#define CAYENNE_DEBUG         // Uncomment to show debug messages
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#define relayPin D6 // Pin to control relay

#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Timer.h"

Timer t; //timer struct

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "s755pmgd4p";
// Your network name and password.
char ssid[] = "obnoxious";
char password[] = "flabergast";

void setup()
{
  pinMode(relayPin, OUTPUT);
  Serial.begin(9600);
  Cayenne.begin(token, ssid, password);
}

void loop()
{
  Cayenne.run();
  t.update();
}

CAYENNE_IN(V3)
{
   if(getValue.asInt() == 1) //only pulse when high
   {
      t.pulse(relayPin, 1000, 1); //pin, time(milliseconds), initial state
   }
}

#7

I tried your code and it worked great. I decided to do away with the physical button. After adding back in my monitoring pin and DS18B20 temp sensor, the temp is displayed but the relayPin wont come on when I use the dashboard button.

//#define CAYENNE_DEBUG // Uncomment to show debug messages
#define CAYENNE_PRINT Serial // Comment this out to disable prints and save space

#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Timer.h"
#define VIRTUAL_PIN1 V1
#define VIRTUAL_PIN2 V2
#define VIRTUAL_PIN3 V3
Timer t;

// Digital pin the DS18B20 is connected to. Do not use digital pins 0 or 1 since those conflict with the use of Serial.
const int tmpPin = D5;
const int ledPin =  D7;      // the number of the LED pin
const int relayPin = D6; // Pin to controll relay
const int relayMon = D3;  // Loopback from relay pin outputstatus
OneWire oneWire(tmpPin);
DallasTemperature sensors(&oneWire);

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "obnoxious2";
// Your network name and password.
char ssid[] = "obnoxious";
char password[] = "flabergast";

void setup()
{
  Serial.begin(9600);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  //initialize the relay pin as an output
  pinMode(relayPin, OUTPUT);
  Cayenne.begin(token, ssid, password);
  sensors.begin();
  
  
}

void loop()
{
  Cayenne.run();
  t.update();
    
}

CAYENNE_OUT(V1)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  
  // This command writes the temperature in Celsius to the Virtual Pin.
  //Cayenne.virtualWrite(VIRTUAL_PIN, sensors.getTempCByIndex(0));
  // To send the temperature in Fahrenheit use the corresponding code below.
  //Cayenne.fahrenheitWrite(VIRTUAL_PIN, sensors.getTempFByIndex(0));
  //Serial.print(VIRTUAL_PIN, sensors.getTempCByIndex(0));
  Cayenne.virtualWrite(VIRTUAL_PIN1, sensors.getTempFByIndex(0));
  
}

CAYENNE_OUT(V2)
{
  Cayenne.virtualWrite(VIRTUAL_PIN2, digitalRead(relayMon));
}

CAYENNE_IN(VIRTUAL_PIN3)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt(); // 0 to 1
        if (currentValue == 1) {
         t.pulse(relayPin, 3600000, 0); //pin, time(milliseconds), initial state
         t.pulse(ledPin, 3600000, 0); //pin, time(milliseconds), initial state
        }
    }