Panel de control táctil para piscina

elmaya
Posts: 1482
Joined: Wed Jun 27, 2018 5:48 pm
Location: El Saucejo - Sevilla

Post

Consiste en un panel de 54cm x 40cm con la imagen aérea de la piscina.

La intención era la de crear un panel de control fácil de usar en el que se pueda identificar fácilmente los diferentes circuitos.
A diferencia de una serie de interruptores en la pared, con la imagen aérea y los sensores táctiles es fácil identificar la zona que se desee encender/apagar.


Consta de un total de 8 canales los cuales se pueden configurar en la nube Supla como interruptor de alimentación, interruptor de luz o temporizador de escaleras.
Por defecto se establecen como temporizador de escaleras.

En este caso concreto se trata de un sistema alimentado con paneles solares por lo que se ha decidido configurar los canales como temporizador de escaleras para establecer una duración de encendido de 10 minutos para el foco que ilumina el camino de acceso “esquina superior izquierda” y de 2 horas para los demás, con esto evitamos que accidentalmente algún foco quede encendido continuamente.

Se opera tanto con los sensores táctiles como desde la App Supla.

panel_54x40_B.jpg
Conexiones:
rele 1 = D1 "Gpio 5"
rele 2 = D5 "Gpio 14"
rele 3 = RX "Gpio 3"
rele 4 = D8 "Gpio 15"
rele 5 = D7 "Gpio 13"
rele 6 = D6 "Gpio 12"
rele 7 = D0 "Gpio 16"
rele 8 = D2 "Gpio 4"

SDA = D4 "gpio 2"
SCL = D3 "gpio 0"

WiFiConfig = Doble Reset.

Piscina8x_bb.png

Code: Select all


#define supla_lib_config_h_  // silences debug messages
#include "LittleFS.h"
#include <Wire.h>
#include <WiFiManager.h>
#include <EEPROM.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#include <ESP8266TrueRandom.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <Adafruit_MPR121.h>
#include <DoubleResetDetector.h>
#include <SuplaDevice.h>
#include <supla/control/relay.h>
#include <supla/network/esp_wifi.h>
Supla::ESPWifi wifi("SSID", "PASS");  //------ Do not change----wifimanager takes care------
#define STORAGE_OFFSET 512
#include <supla/storage/eeprom.h>
Supla::Eeprom eeprom(STORAGE_OFFSET);
extern "C"
{
#include "user_interface.h"
}

//#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

int relay_0_pin = 5;   //------------------- set relay Gpio -----
int relay_1_pin = 14;
int relay_2_pin = 3;
int relay_3_pin = 15;
int relay_4_pin = 13;
int relay_5_pin = 12;
int relay_6_pin = 16;
int relay_7_pin = 4;

#define SDA_PIN 2
#define SCL_PIN 0

char Supla_server[81] = ("Set server address");
char Email[81] = ("set email address");
char Supla_name[81];
char Router_SSID[32];
char Router_Pass[64];
char Supla_status[51];
bool shouldSaveConfig = false;
bool initialConfig = false;
bool starting = true;
int s;
char GUID[SUPLA_GUID_SIZE];
char AUTHKEY[SUPLA_AUTHKEY_SIZE];
byte uuidNumber[16];
static const char logo[] PROGMEM = "<style>html{ background-color: #01DF3A;}</style><div class='s'><svg version='1.1' id='l' x='0' y='0' viewBox='0 0 200 200' xml:space='preserve'><path d='M59.3,2.5c18.1,0.6,31.8,8,40.2,23.5c3.1,5.7,4.3,11.9,4.1,18.3c-0.1,3.6-0.7,7.1-1.9,10.6c-0.2,0.7-0.1,1.1,0.6,1.5c12.8,7.7,25.5,15.4,38.3,23c2.9,1.7,5.8,3.4,8.7,5.3c1,0.6,1.6,0.6,2.5-0.1c4.5-3.6,9.8-5.3,15.7-5.4c12.5-0.1,22.9,7.9,25.2,19c1.9,9.2-2.9,19.2-11.8,23.9c-8.4,4.5-16.9,4.5-25.5,0.2c-0.7-0.3-1-0.2-1.5,0.3c-4.8,4.9-9.7,9.8-14.5,14.6c-5.3,5.3-10.6,10.7-15.9,16c-1.8,1.8-3.6,3.7-5.4,5.4c-0.7,0.6-0.6,1,0,1.6c3.6,3.4,5.8,7.5,6.2,12.2c0.7,7.7-2.2,14-8.8,18.5c-12.3,8.6-30.3,3.5-35-10.4c-2.8-8.4,0.6-17.7,8.6-22.8c0.9-0.6,1.1-1,0.8-2c-2-6.2-4.4-12.4-6.6-18.6c-6.3-17.6-12.7-35.1-19-52.7c-0.2-0.7-0.5-1-1.4-0.9c-12.5,0.7-23.6-2.6-33-10.4c-8-6.6-12.9-15-14.2-25c-1.5-11.5,1.7-21.9,9.6-30.7C32.5,8.9,42.2,4.2,53.7,2.7c0.7-0.1,1.5-0.2,2.2-0.2C57,2.4,58.2,2.5,59.3,2.5z M76.5,81c0,0.1,0.1,0.3,0.1,0.6c1.6,6.3,3.2,12.6,4.7,18.9c4.5,17.7,8.9,35.5,13.3,53.2c0.2,0.9,0.6,1.1,1.6,0.9c5.4-1.2,10.7-0.8,15.7,1.6c0.8,0.4,1.2,0.3,1.7-0.4c11.2-12.9,22.5-25.7,33.4-38.7c0.5-0.6,0.4-1,0-1.6c-5.6-7.9-6.1-16.1-1.3-24.5c0.5-0.8,0.3-1.1-0.5-1.6c-9.1-4.7-18.1-9.3-27.2-14c-6.8-3.5-13.5-7-20.3-10.5c-0.7-0.4-1.1-0.3-1.6,0.4c-1.3,1.8-2.7,3.5-4.3,5.1c-4.2,4.2-9.1,7.4-14.7,9.7C76.9,80.3,76.4,80.3,76.5,81z M89,42.6c0.1-2.5-0.4-5.4-1.5-8.1C83,23.1,74.2,16.9,61.7,15.8c-10-0.9-18.6,2.4-25.3,9.7c-8.4,9-9.3,22.4-2.2,32.4c6.8,9.6,19.1,14.2,31.4,11.9C79.2,67.1,89,55.9,89,42.6z M102.1,188.6c0.6,0.1,1.5-0.1,2.4-0.2c9.5-1.4,15.3-10.9,11.6-19.2c-2.6-5.9-9.4-9.6-16.8-8.6c-8.3,1.2-14.1,8.9-12.4,16.6C88.2,183.9,94.4,188.6,102.1,188.6z M167.7,88.5c-1,0-2.1,0.1-3.1,0.3c-9,1.7-14.2,10.6-10.8,18.6c2.9,6.8,11.4,10.3,19,7.8c7.1-2.3,11.1-9.1,9.6-15.9C180.9,93,174.8,88.5,167.7,88.5z'/></svg>";
#define DRD_TIMEOUT 5
#define DRD_ADDRESS 0

DoubleResetDetector drd(DRD_TIMEOUT, DRD_ADDRESS);
ESP8266WebServer httpServer(81);
ESP8266HTTPUpdateServer httpUpdater;
WiFiManager wifiManager;
Adafruit_MPR121 cap = Adafruit_MPR121();
#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif
uint16_t lasttouched = 0;
uint16_t currtouched = 0;

Supla::Control::Relay *relay_0 = nullptr;
Supla::Control::Relay *relay_1 = nullptr;
Supla::Control::Relay *relay_2 = nullptr;
Supla::Control::Relay *relay_3 = nullptr;
Supla::Control::Relay *relay_4 = nullptr;
Supla::Control::Relay *relay_5 = nullptr;
Supla::Control::Relay *relay_6 = nullptr;
Supla::Control::Relay *relay_7 = nullptr;

void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}

void ondemandwifiCallback () {

  WiFiManagerParameter custom_Supla_server("server", "supla server", Supla_server, 81, "required");
  WiFiManagerParameter custom_Email("email", "Email", Email, 81, "required");
  WiFiManagerParameter custom_Supla_name("name", "Supla Device Name", Supla_name, 81, "required");
  WiFiManagerParameter custom_html_id21("<div><h4> - Supla State -   ");
  WiFiManagerParameter custom_html_id22( Supla_status);
  WiFiManagerParameter custom_html_id23( "</h4></div>");

  wifiManager.setBreakAfterConfig(true);
  wifiManager.setSaveConfigCallback(saveConfigCallback);

  wifiManager.addParameter(&custom_Supla_server);
  wifiManager.addParameter(&custom_Email);
  wifiManager.addParameter(&custom_Supla_name);
  wifiManager.addParameter(&custom_html_id21);
  wifiManager.addParameter(&custom_html_id22);
  wifiManager.addParameter(&custom_html_id23);

  wifiManager.setCustomHeadElement(logo);
  wifiManager.setMinimumSignalQuality(8);
  wifiManager.setConfigPortalTimeout(300);

  if (!wifiManager.startConfigPortal("Pool8X")) {
    Serial.println("Not connected to WiFi but continuing anyway.");
  } else {
    Serial.println("connected...yeey :)");
  }
  strcpy(Supla_server, custom_Supla_server.getValue());
  strcpy(Email, custom_Email.getValue());
  strcpy(Supla_name, custom_Supla_name.getValue());
  wifiManager.getWiFiSSID().toCharArray(Router_SSID, 33);
  wifiManager.getWiFiPass().toCharArray(Router_Pass, 65);
  if (strcmp(Supla_server, "get_new_guid_and_authkey") == 0) {
    Serial.println("new guid & authkey.");
    EEPROM.write(300, 0);
    EEPROM.commit();
    delay(100);
    ESP.reset();
  }
  if (shouldSaveConfig == true) { // ------------------------ wificonfig save --------------
    Serial.println(" config...");
    DynamicJsonDocument json(1024);
    json["Supla_server"] = Supla_server;
    json["Email"] = Email;
    json["Supla_name"] = Supla_name;
    json["Router_SSID"] = Router_SSID;
    json["Router_Pass"] = Router_Pass;
    File configFile = LittleFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }
    serializeJsonPretty(json, Serial);
    serializeJson(json, configFile);
    configFile.close();
    Serial.println("Config written successfully");
    shouldSaveConfig = false;
    initialConfig = false;
    WiFi.mode(WIFI_STA);
    delay(5000);
    ESP.restart();
  }
  WiFi.softAPdisconnect(true);
  initialConfig = false;
}

void status_func(int status, const char *msg) {    //    ------------------------ Status --------------------------
  if (s != status) {
    s = status;
    if (s != 10) {
      strcpy(Supla_status, msg);
    }
  }
}

void guid_authkey(void) {
  if (EEPROM.read(300) != 60) {
    int eep_gui = 301;
    ESP8266TrueRandom.uuid(uuidNumber);
    String uuidString = "";
    for (int i = 0; i < 16; i++) {
      int topDigit = uuidNumber[i] >> 4;
      int bottomDigit = uuidNumber[i] & 0x0f;
      uuidString += "0123456789abcdef"[topDigit];
      uuidString += "0123456789abcdef"[bottomDigit];
    }
    int length_uuid = uuidString.length();
    for (int i = 0; i < length_uuid; ++i) {
      EEPROM.put(eep_gui + i, uuidString[i]);
    }
    int eep_aut = 341;
    ESP8266TrueRandom.uuid(uuidNumber);
    String uuidString2 = "";
    for (int i = 0; i < 16; i++) {
      int topDigit = uuidNumber[i] >> 4;
      int bottomDigit = uuidNumber[i] & 0x0f;
      uuidString2 += "0123456789abcdef"[topDigit];
      uuidString2 += "0123456789abcdef"[bottomDigit];
    }
    int length_uuid2 = uuidString2.length();
    for (int i = 0; i < length_uuid2; ++i) {
      EEPROM.put(eep_aut + i, uuidString2[i]);
    }
    EEPROM.write(300, 60);
    EEPROM.commit();
    delay(0);
  }
  read_guid();
  read_authkey();
  Serial.print("GUID : "); Serial.println(read_guid());
  Serial.print("AUTHKEY : "); Serial.println(read_authkey());
}

String read_guid(void) {
  String read_eeprom = "";
  int i, ii = 0;
  int eep_star = 301;
  int end_guid = eep_star + SUPLA_GUID_SIZE;
  String temp_read = "0x";
  for (i = eep_star; i < end_guid + 16;  i = i + 1) {
    temp_read += char(EEPROM.read(i));
    read_eeprom += char(EEPROM.read(i));
    if ( (i % 2) == 0) {
      char *_guid = strcpy((char*)malloc(temp_read.length() + 1), temp_read.c_str());
      GUID[ii] = strtoul( _guid, NULL, 16);
      temp_read = "0x";
      ii++;
    }
  }
  return read_eeprom;
}

String read_authkey(void) {
  String read_eeprom = "";
  int i, ii = 0;
  int eep_star = 341;
  int end_authkey = eep_star + SUPLA_AUTHKEY_SIZE;
  String temp_read = "0x";
  for (i = eep_star; i < end_authkey + 16;  i = i + 1) {
    temp_read += char(EEPROM.read(i));
    read_eeprom += char(EEPROM.read(i));
    if ( (i % 2) == 0) {
      char *_authkey = strcpy((char*)malloc(temp_read.length() + 1), temp_read.c_str());
      AUTHKEY[ii] = strtoul( _authkey, NULL, 16);
      temp_read = "0x";
      ii++;
    }
  }
  return read_eeprom;
}

void setup() {

  Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY, 1);
  Serial.println(" ");
  EEPROM.begin(1024);
  if (EEPROM.read(300) != 60) {
    initialConfig = true;
  }
  guid_authkey();

  if (WiFi.SSID() == "") {
    initialConfig = true;
  }

  if (LittleFS.begin()) {  // ------------------------- wificonfig read -----------------
    Serial.println("mounted file system");
    if (LittleFS.exists("/config.json")) {
      Serial.println("reading config file");
      File configFile = LittleFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        std::unique_ptr<char[]> buf(new char[size]);
        configFile.readBytes(buf.get(), size);
        DynamicJsonDocument json(1024);
        DeserializationError deserializeError = deserializeJson(json, buf.get());
        serializeJsonPretty(json, Serial);
        if (!deserializeError) {
          Serial.println("\nparsed json");
          if (json.containsKey("Supla_server")) strcpy(Supla_server, json["Supla_server"]);
          if (json.containsKey("Email")) strcpy(Email, json["Email"]);
          if (json.containsKey("Supla_name")) strcpy(Supla_name, json["Supla_name"]);
          if (json.containsKey("Router_SSID")) strcpy(Router_SSID, json["Router_SSID"]);
          if (json.containsKey("Router_Pass")) strcpy(Router_Pass, json["Router_Pass"]);
        } else {
          Serial.println("failed to load json config");
          initialConfig = true;
        }
        configFile.close();
      }
    }
  } else {
    Serial.println("failed to mount FS");
  }
  wifi_station_set_hostname(Supla_name);
  WiFi.mode(WIFI_STA);

  Wire.begin(SDA_PIN, SCL_PIN);

  if (!cap.begin(0x5A)) {
    Serial.println("MPR121 not found, check wiring?");
  }
  Serial.println("MPR121 found!");

  if (drd.detectDoubleReset()) {
    Serial.println("Double Reset Detected");
    ondemandwifiCallback();
  }

  relay_0 = new Supla::Control::Relay(relay_0_pin, true, 224);  // 224 = POWERSWITCH + LIGHTSWITCH + STAIRCASETIMER
  relay_0->getChannel()->setDefault(SUPLA_CHANNELFNC_STAIRCASETIMER);
  relay_0->keepTurnOnDuration();
  relay_0->disableChannelState();

  relay_1 = new Supla::Control::Relay(relay_1_pin, true, 224);
  relay_1->getChannel()->setDefault(SUPLA_CHANNELFNC_STAIRCASETIMER);
  relay_1->keepTurnOnDuration();
  relay_1->disableChannelState();

  relay_2 = new Supla::Control::Relay(relay_2_pin, true, 224);
  relay_2->getChannel()->setDefault(SUPLA_CHANNELFNC_STAIRCASETIMER);
  relay_2->keepTurnOnDuration();
  relay_2->disableChannelState();

  relay_3 = new Supla::Control::Relay(relay_3_pin, true, 224);
  relay_3->getChannel()->setDefault(SUPLA_CHANNELFNC_STAIRCASETIMER);
  relay_3->keepTurnOnDuration();
  relay_3->disableChannelState();

  relay_4 = new Supla::Control::Relay(relay_4_pin, true, 224);
  relay_4->getChannel()->setDefault(SUPLA_CHANNELFNC_STAIRCASETIMER);
  relay_4->keepTurnOnDuration();
  relay_4->disableChannelState();

  relay_5 = new Supla::Control::Relay(relay_5_pin, true, 224);
  relay_5->getChannel()->setDefault(SUPLA_CHANNELFNC_STAIRCASETIMER);
  relay_5->keepTurnOnDuration();
  relay_5->disableChannelState();

  relay_6 = new Supla::Control::Relay(relay_6_pin, true, 224);
  relay_6->getChannel()->setDefault(SUPLA_CHANNELFNC_STAIRCASETIMER);
  relay_6->keepTurnOnDuration();
  relay_6->disableChannelState();

  relay_7 = new Supla::Control::Relay(relay_7_pin, true, 224);
  relay_7->getChannel()->setDefault(SUPLA_CHANNELFNC_STAIRCASETIMER);
  relay_7->keepTurnOnDuration();
  //relay_7->disableChannelState();

  SuplaDevice.setName(Supla_name);
  SuplaDevice.setStatusFuncImpl(&status_func);
  wifi.enableSSL(false);
  wifi.setSsid(Router_SSID);
  wifi.setPassword(Router_Pass);
  SuplaDevice.begin(GUID, Supla_server, Email, AUTHKEY);

  if (initialConfig == true) {
    ondemandwifiCallback();
  }
}

void loop() {

  SuplaDevice.iterate();
  delay(5);
  drd.loop();

  if (WiFi.status() == WL_CONNECTED) {
    if (starting) {
      httpUpdater.setup(&httpServer, "/update", "admin", "pass");
      httpServer.begin();
      starting = false;
    }
    httpServer.handleClient();
  }

  currtouched = cap.touched();
  for (uint8_t i = 0; i < 12; i++) {
    if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
      Serial.print(i); Serial.println(" touched");
      yield();
      if ((i) == 0 ) {
        relay_0->toggle();
      }
      if ((i) == 1 ) {
        relay_1->toggle();
      }
      if ((i) == 2 ) {
        relay_2->toggle();
      }
      if ((i) == 3 ) {
        relay_3->toggle();
      }
      if ((i) == 4 ) {
        relay_4->toggle();
      }
      if ((i) == 5 ) {
        relay_5->toggle();
      }
      if ((i) == 6 ) {
        relay_6->toggle();
      }
      if ((i) == 7 ) {
        relay_7->toggle();
      }
    }
    if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
      Serial.print(i); Serial.println(" released");
    }
  }
  lasttouched = currtouched;
}
Pool_x8.rar
You do not have the required permissions to view the files attached to this post.
radzik_r
Posts: 414
Joined: Sun Aug 11, 2019 5:32 pm

Post

Masz fajne projekty.
Czekam na rozwinięcie.
jaku2k
Posts: 899
Joined: Sun May 24, 2020 8:40 pm

Post

Hola @elmaya:
creo que es un proyecto interesante.

Estoy probando traduicr eso texto a polaco. ¿Qué significa la palabra Cosiste?
elmaya
Posts: 1482
Joined: Wed Jun 27, 2018 5:48 pm
Location: El Saucejo - Sevilla

Post

jaku2k wrote: Thu Jul 15, 2021 1:54 pm Hola @elmaya:
creo que es un proyecto interesante.

Estoy probando traduicr eso texto a polaco. ¿Qué significa la palabra Cosiste?
:lol: :lol: :lol: Error tipográfico por mi parte :lol: :lol: :lol:

es "Consiste" 'para ti seria "Składa się"
jaku2k
Posts: 899
Joined: Sun May 24, 2020 8:40 pm

Post

Gracias.
Pozdrawiam
Jakub
elmaya
Posts: 1482
Joined: Wed Jun 27, 2018 5:48 pm
Location: El Saucejo - Sevilla

Post

jaku2k wrote: Thu Jul 15, 2021 2:17 pmGracias.
Gracias a ti y perdona las molestias. ;)

Supongo que estas pensando en usar con tu proyecto de Arduino Mega
Puedes conectar hasta 4 x MPR121 en un I2C para un total de 32 sensores táctiles
jaku2k
Posts: 899
Joined: Sun May 24, 2020 8:40 pm

Post

elmaya wrote: Thu Jul 15, 2021 2:30 pm
jaku2k wrote: Thu Jul 15, 2021 2:17 pmGracias.
Gracias a ti y perdona las molestias. ;)

Supongo que estas pensando en usar con tu proyecto de Arduino Mega
Puedes conectar hasta 4 x MPR121 en un I2C para un total de 32 sensores táctiles
Para mi no es un problemo - me encanta leer usted proyectos.

No tengo casa tan luja :) Necesito Arduino MEGA para agregar mis reles a Supla. Gracias por la información.
Pozdrawiam
Jakub
zilhos
Posts: 18
Joined: Sat Aug 10, 2019 2:52 am

Post

:o impresionante @elmaya un genio ! Me parece un buen proyecto para probar este fin de semana.
Muchas gracias por compartir!
Saludos

Return to “Ideas y conceptos”