Új hozzászólás Aktív témák

  • Tankblock

    aktív tag

    Sziasztok, remélem tudtok segíteni.
    Van egy problémám amire nem tudok rájönni:

    //
    // Mod: Add a double knock to send extra message to the MQTT
    //
    //
    //


    #include <FS.h> //this needs to be first, or it all crashes and burns...
    #include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
    #include <DNSServer.h>
    #include <ESP8266WebServer.h>
    #include <WiFiManager.h>
    #include <PubSubClient.h>

    //GPIO Pin definitions
    #define WiFiLED 13
    #define TouchLED 12 //Also operates Relay coil
    #define TouchInput 0

    //Only output info to serial if this is HIGH
    #define fDebug true

    //Set our inital states and values
    boolean ledState = false;
    boolean lastButtonState = false;
    boolean buttonState = false;
    // Removed because of the new concept implemented
    //unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
    //unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers

    // Button timing variables
    unsigned long debounce = 20; // ms debounce period to prevent flickering when pressing or releasing the button
    unsigned long DCgap = 250; // max ms between clicks for a double click event
    unsigned long holdTime = 1000; // ms hold period: how long to wait for press+hold event
    unsigned long longHoldTime = 3000; // ms long hold period: how long to wait for press+hold event
    unsigned long currentTime = 0;

    // Button variables
    boolean buttonVal = HIGH; // value read from button
    boolean buttonLast = HIGH; // buffered value of the button's previous state
    boolean DCwaiting = false; // whether we're waiting for a double click (down)
    boolean DConUp = false; // whether to register a double click on next release, or whether to wait and click
    boolean singleOK = true; // whether it's OK to do a single click
    unsigned long downTime = 0; // time the button was pressed down
    unsigned long upTime = 0; // time the button was released
    boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered
    boolean waitForUp = false; // when held, whether to wait for the up event
    boolean holdEventPast = false; // whether or not the hold event happened already
    boolean longHoldEventPast = false;// whether or not the long hold event happened already


    #define MQTT_VERSION MQTT_VERSION_3_1_1
    const PROGMEM uint16_t MQTT_SERVER_PORT = 1883;
    const PROGMEM char* MQTT_CLIENT_ID = "Enterance Room Light Switch";
    const PROGMEM char* MQTT_USER = "mqtt_user";
    const PROGMEM char* MQTT_PASSWORD = "mqtt_psw";
    const char* MQTT_LIGHT_STATE_TOPIC = "enterance/lightswitch/status";
    const char* MQTT_LIGHT_COMMAND_TOPIC = "enterance/lightswitch/switch";
    const char* MQTT_LIGHT_SPECIAL_TOPIC = "enterance/lightswitch/special";
    const char* LIGHT_ON = "ON";
    const char* LIGHT_OFF = "OFF";
    const char* CLICK = "CLICK";
    const char* LONGPRESS = "LONGPRESS";

    //Create our objects for MQTT and define our IP Address class
    WiFiClient espClient;
    PubSubClient client(espClient);
    IPAddress MQTT_SERVER_IP(192, 168, 1, 140);

    void setup() {

    #if defined(fDebug)
    Serial.begin(115200); Serial.println(); Serial.println(); Serial.println();
    #endif
    //Setup our GPIO pins for input/output as needed
    pinMode(WiFiLED, OUTPUT);
    pinMode(TouchLED, OUTPUT);
    pinMode(TouchInput, INPUT);

    //Turn those LEDS's off :)
    digitalWrite(WiFiLED, HIGH);
    digitalWrite(TouchLED, ledState);

    //Instantiate the WifManager library
    WiFiManager wifiManager;
    //Set a host name
    wifi_station_set_hostname("sonoffTouch");
    //Un remark this if your want to clear the saved connection settings.
    //wifiManager.resetSettings();
    #if defined(fDebug)
    wifiManager.setDebugOutput(true);
    #endif
    //If autoconnection fails, go into AP mode so the user can configure the WiFi connection to the local WLan
    if (!wifiManager.autoConnect("TaTaTatooouchMe")) {
    delay(3000);
    ESP.reset();
    } else {
    //WiFi LED is on when low
    digitalWrite(WiFiLED, LOW);
    //get our MQTT servers address
    //WiFi.hostByName("your_mgtt.server.co.uk", MQTT_SERVER_IP);
    yield();
    //Establish conenction to MQTT server
    client.setServer(MQTT_SERVER_IP , MQTT_SERVER_PORT);
    client.setCallback(callback);
    //Phew, have a bit of a breather to give everything a chance to settle down
    delay(1000);
    }
    }
    // function called to publish the state of the light (on/off)
    void publishLightState() {
    #if defined(fDebug)
    Serial.println("PublishLightState Called");
    Serial.print("Light State: ");
    Serial.println(ledState);
    #endif
    if (ledState == HIGH) {
    #if defined(fDebug)
    Serial.print("Light state high ");
    Serial.println(ledState);
    #endif
    client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_ON, true);
    } else {
    #if defined(fDebug)
    Serial.print("Light state low ");
    Serial.println(ledState);
    #endif
    client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true);
    }
    }

    void publishClickState() {
    #if defined(fDebug)
    Serial.print("Click event ");
    #endif
    client.publish(MQTT_LIGHT_SPECIAL_TOPIC, CLICK, true);
    }

    void publishLongPushState() {
    #if defined(fDebug)
    Serial.print("Long push event ");
    #endif
    client.publish(MQTT_LIGHT_SPECIAL_TOPIC, LONGPRESS, true);
    }

    // function called to turn on/off the light
    void setLightState() {
    //Set our light state, ie turn the touch LED on/off which is the same GPIO pin as the relay.
    digitalWrite(TouchLED, ledState);
    }

    // function called when a MQTT message arrived
    void callback(char* p_topic, byte* p_payload, unsigned int p_length) {
    // concat the payload into a string
    #if defined(fDebug)
    Serial.println("Callback...");
    #endif
    String payload;
    for (uint8_t i = 0; i < p_length; i++) {
    payload.concat((char)p_payload[i]);
    }
    #if defined(fDebug)
    Serial.print("Payload: ");
    Serial.println(payload);
    #endif
    // handle message topic
    if (String(MQTT_LIGHT_COMMAND_TOPIC).equals(p_topic)) {
    // test if the payload is equal to "ON" or "OFF"
    if (payload.equals(String(LIGHT_ON))) {
    if (ledState != true) {
    ledState = true;
    setLightState();
    publishLightState();
    }
    } else if (payload.equals(String(LIGHT_OFF))) {
    ledState = false;
    setLightState();
    yield();
    publishLightState();
    }
    }
    }
    void reconnect() {
    // Loop until we're reconnected
    while (!client.connected()) {
    #if defined(fDebug)
    Serial.print("INFO: Attempting MQTT connection...");
    #endif
    // Attempt to connect
    if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) {
    #if defined(fDebug)
    Serial.println("INFO: connected");
    #endif
    yield();
    // Once connected, publish an announcement...
    publishLightState();
    // ... and resubscribe
    client.subscribe(MQTT_LIGHT_COMMAND_TOPIC);
    } else {
    #if defined(fDebug)
    Serial.print("ERROR: failed, rc=");
    Serial.print(client.state());
    Serial.println("DEBUG: try again in 5 seconds");
    #endif
    // Wait 5 seconds before retrying
    for (int i = 0; i < 500; i++) {

    if ( checkButton() == 1) {
    ledState = !ledState;
    setLightState();
    delay(10);
    }
    }
    }
    }
    }

    void loop() {
    if (!client.connected()) {
    #if defined(fDebug)
    Serial.println("Reconnect");
    #endif
    reconnect();
    }
    //Get the current button state
    // int reading = digitalRead(TouchInput);
    // //De-bounce the button
    // if (reading != lastButtonState){
    // lastDebounceTime = millis();
    // }
    // if ((millis() - lastDebounceTime) > debounceDelay) {
    // // whatever the reading is at, it's been there for longer
    // // than the debounce delay, so take it as the actual current state:
    //
    // // if the button state has changed:
    // if (reading != buttonState) {
    // buttonState = reading;
    //
    // // only toggle the LED if the new button state is HIGH
    // if (buttonState == HIGH) {
    // ledState = !ledState;
    // }
    // // set the LED:
    // setLightState();
    // publishLightState();
    // }
    // }
    // // save the reading. Next time through the loop,
    // // it'll be the lastButtonState:
    // lastButtonState = reading;
    // delay(64);

    int b = checkButton();
    yield();
    if (b == 1) {
    ledState = !ledState;
    setLightState();
    publishLightState();
    }
    if (b == 2) {
    publishClickState();
    }
    if (b == 3) {
    // Not Used
    }

    if (b == 4) {
    publishLongPushState();
    }

    yield();
    client.loop();
    yield();
    }

    int checkButton() {
    int event = 0;
    buttonVal = digitalRead(TouchInput);
    currentTime = millis();
    // Button pressed down
    if (buttonVal == LOW && buttonLast == HIGH && (currentTime - upTime) > debounce)
    {
    downTime = currentTime;
    ignoreUp = false;
    waitForUp = false;
    singleOK = true;
    holdEventPast = false;
    longHoldEventPast = false;
    if ((currentTime - upTime) < DCgap && DConUp == false && DCwaiting == true) DConUp = true;
    else DConUp = false;
    DCwaiting = false;
    }
    // Button released
    else if (buttonVal == HIGH && buttonLast == LOW && (currentTime - downTime) > debounce)
    {
    if (not ignoreUp)
    {
    upTime = currentTime;
    if (DConUp == false) DCwaiting = true;
    else
    {
    event = 2;
    DConUp = false;
    DCwaiting = false;
    singleOK = false;
    }
    }
    }
    // Test for normal click event: DCgap expired
    if ( buttonVal == HIGH && (currentTime - upTime) >= DCgap && DCwaiting == true && DConUp == false && singleOK == true && event != 2)
    {
    event = 1;
    DCwaiting = false;
    }
    // Test for hold
    if (buttonVal == LOW && (currentTime - downTime) >= holdTime) {
    // Trigger "normal" hold
    if (not holdEventPast)
    {
    event = 3;
    waitForUp = true;
    ignoreUp = true;
    DConUp = false;
    DCwaiting = false;
    //downTime = millis();
    holdEventPast = true;
    }
    // Trigger "long" hold
    if ((currentTime - downTime) >= longHoldTime)
    {
    if (not longHoldEventPast)
    {
    event = 4;
    longHoldEventPast = true;
    }
    }
    }
    buttonLast = buttonVal;
    return event;
    }

    Ez egy SONOFF Touch kódja. Ha a checkButtont használom a loopba lévő kikommentezett rész helyett akkor random kifagy stack overflow ra hivatkozik. Mit rontottam el?

Új hozzászólás Aktív témák

Hirdetés