Dotykowy panel sterowania basenem

Masz pomysł na funkcjonalność lub koncepcję na rozwój projektu. Opisz wszystko tutaj.
jaku2k
Posty: 830
Rejestracja: ndz maja 24, 2020 8:40 pm
Kontakt:

Witam,
poniżej przesyłam przetłumaczony projekt @elmaya.

Składa się z panelu 54cm x 40 cm i zdjęcia basenu z lotu ptaka.

Zamiar był taki, żeby zrobić prosty w obsłudze panel, na którym można bezproblemowo rozpoznać odrębne obiegi.
Zamiast wielu włączników na ścianie mamy zdjęcie, na którym możemy łatwo zidentyfikować obszar, który chcemy włączyć/wyłączyć.

Mamy 8 kanałów, które możemy skonfigurować w Cloudzie jako włącznik zasilania, włącznika światła albo automat schodowy. Domyślnie przekaźniki są ustawione jako automaty schodowe.

W przedstawionym przypadku zasilanie pochodzi z paneli słonecznych. Właśnie dlatego domyślnie kanały są ustawione jako automaty schodowe - umożliwia to skonfigurowanie czasu świecenia żarówek. Przykładowo oświetlenie ścieżki prowadzącej do basenu (lewy górny róg) jest ustawione na 10 minut, a dla pozostałych kanałów - po 2 godziny. Dzięki temu nie przytrafi się sytuacja, w której jakaś żarówka będzie świecić bez przerwy.

Obsługa zarówno przez sensory dotykowe, jak i aplikację SUPLA.
panel_54x40_B.jpg
panel_54x40_B.jpg (880.98 KiB) Przejrzano 929 razy
Połączenia:
przekaźnik 1 = D1 (GPIO 5)
przekaźnik 2 = D5 (GPIO 14)
przekaźnik 3 = RX (GPIO 3)
przekaźnik 4 = D8 (GPIO 15)
przekaźnik 5 = D7 (GPIO 13)
przekaźnik 6 = D6 (GPIO 12)
przekaźnik 7 = D0 (GPIO 16)
przekaźnik 8 = D2 (GPIO 4)

SDA = D4 (GPIO 2)
SCL = D3 (GPIO 0)

WiFiConfig = 2x RESET
Piscina8x_bb.png
Piscina8x_bb.png (615.72 KiB) Przejrzano 929 razy

Kod: Zaznacz cały

#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
firmware + ino
(1.05 MiB) Pobrany 45 razy
Awatar użytkownika
Duch__
Posty: 1772
Rejestracja: śr sie 24, 2016 7:26 pm
Lokalizacja: Opole

Panele synoptyczne wracają do łask ;)
Obrazek
Awatar użytkownika
QLQ
Posty: 2276
Rejestracja: ndz wrz 03, 2017 9:13 am
Lokalizacja: Koszalin

A pinezka najlepszym włącznikiem do tego panelu!
Mam na tym zrobione sterowanie aqwa!! Działa bezbłędnie od 2019r. Może raz się zawiesiło ale nie pamiętam kiedy.
jak coś nie działa to włącz zasilanie.....
ODPOWIEDZ

Wróć do „Pomysły i koncepcje”