I'm working on a project where I want Alexa to control a light with a timer and the same light with pressing a button to start the timer say for 1 minute (for testing).
I can get them to work individually but when I add the timer code instead of running for 1 minute as expected it seems to run for 30 seconds.
On both the button press and Alexa turns the relay on/off ok.
This is the Alexa code with timer code combined.
#include <Arduino.h>
#include <RCSwitch.h>
#ifdef ESP32
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
#endif
#include "fauxmoESP.h"
#define WIFI_SSID "XXXXXXXX" // edit it according to your router configuration
#define WIFI_PASS "XXXXXXXXX" // edit it according to your router configuration
fauxmoESP fauxmo;
// -----------------------------------------------------------------------------
#define SERIAL_BAUDRATE 115200
int ledState = LOW; // the current state of the output pin
int buttonState = LOW; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
unsigned long previousMillis = 0; // will store last time LED was updated
unsigned long LightONinterval = 1000UL * 60; // 1 minute timer, will be changed to siut
unsigned long currentMillis = 0;
unsigned long lastLight = 0;
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
#define buttonPin D2 // the pin that the pushbutton is attached to
#define Channel1_PIN D0 //Turn light relay on/off
#define ID_Channel1 "Garden light" // Spa lights
// Wifi
// -----------------------------------------------------------------------------
void wifiSetup() {
// Set WIFI module to STA mode
WiFi.mode(WIFI_STA);
// Connect
Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS);
// Wait
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println();
// Connected!
Serial.printf("[WIFI] STATION Mode, SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}
void setup() {
// Init serial port and clean garbage
Serial.begin(SERIAL_BAUDRATE);
Serial.println();
Serial.println();
pinMode(buttonPin, INPUT_PULLUP);
pinMode(Channel1_PIN, OUTPUT);
digitalWrite(buttonPin, HIGH);
digitalWrite(Channel1_PIN, LOW);
wifiSetup();
// By default, fauxmoESP creates it's own webserver on the defined port
// The TCP port must be 80 for gen3 devices (default is 1901)
// This has to be done before the call to enable()
fauxmo.createServer(true); // not needed, this is the default value
fauxmo.setPort(80); // This is required for gen3 devices
// You have to call enable(true) once you have a WiFi connection
// You can enable or disable the library at any moment
// Disabling it will prevent the devices from being discovered and switched
fauxmo.enable(true);
// Add virtual devices
fauxmo.addDevice(ID_Channel1);
fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {
// Callback when a command from Alexa is received.
// You can use device_id or device_name to choose the element to perform an action onto (relay, LED,...)
// State is a boolean (ON/OFF) and value a number from 0 to 255 (if you say "set kitchen light to 50 % " you will receive a 128 here).
// Just remember not to delay too much here, this is a callback, exit as soon as possible.
// If you have to do something more involved here set a flag and process it in your main loop.
Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
if ( (strcmp(device_name, ID_Channel1) == 0) ) {
// Turn channel 1 on,otherwise tutn channel 2 off
if (state) {
Serial.println("RELAY 1 switched ON by Alexa");
//ledState = HIGH;
ledState = !ledState;
digitalWrite(Channel1_PIN, ledState);
//only placed line bekow for testing trying to stop earylswitc hoff
// lastLight = currentMillis;//load the timer with last mills reading
} else {
Serial.println("RELAY 1 switched OFF by Alexa");
// ledState = LOW;
ledState = !ledState;
digitalWrite(Channel1_PIN, ledState);
}
}
});
}
void loop() {
// fauxmoESP uses an async TCP server but a sync UDP server
// Therefore, we have to manually poll for UDP packets
fauxmo.handle();
// This is a sample code to output free heap every 5 seconds
// This is a cheap way to detect memory leaks
static unsigned long last = millis();
if (millis() - last > 5000) {
last = millis();
Serial.printf("[MAIN] Free heap: % d bytes\n", ESP.getFreeHeap());
Serial.println( ledState);
}
// manully activate the timer by a button press
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
// digitalWrite(Channel1_PIN,ledState);
currentMillis = millis() ;
if (ledState == HIGH && currentMillis - lastLight > LightONinterval )
{
lastLight = currentMillis;//load the timer with last mills reading
ledState = !ledState; // Check the state of led
digitalWrite(Channel1_PIN, ledState);
}
lastButtonState = reading;
}
This is just the timer code which runs for the expected 1 minute, Once it has timed out it's self, I can press the button and it runs for the same time 1 minute.
const int buttonPin = 2; // the number of the pushbutton pin
const int Logging_led = 13; // the number of the LED pin
// Variables will change:
int ledState = LOW; // the current state of the output pin
int buttonState = LOW; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
unsigned long previousMillis = 0; // will store last time LED was updated
unsigned long LightONinterval = 1000UL * 60;
// constants won't change :
const long interval = 1000UL * 60;
unsigned long currentMillis ;
unsigned long lastLight = 0;
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
pinMode(buttonPin, INPUT);
pinMode(Logging_led, OUTPUT);
digitalWrite(buttonPin, HIGH);
// set initial LED state
digitalWrite(Logging_led, LOW);
}
void loop() {
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
digitalWrite(Logging_led, ledState);
lastButtonState = reading;
currentMillis = millis() ;
if (ledState == HIGH && currentMillis - lastLight > LightONinterval )
{
ledState = !ledState;
lastLight = currentMillis;
digitalWrite(Logging_led, ledState);
}
}
Not sure what's messing things up ?
Steve