GARAGEDOOR + LAN8720

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

1 relay and 2 sensors.
ESP32+LAN8720_GARAGEDOOR_esquemático.png
ESP32+LAN8720_GARAGEDOOR_esquemático.png (146.77 KiB) Viewed 6620 times

configuration with WiFiConfig:
keep Gpio 0 connected to GND for at least 5 seconds.
Led connected to Gpio 33 lights up indicating WiFiConfig mode.
connect to the WiFi network named "GARAGE_LAN" and open the page 192.168.4.1 in the web browser.
click on setup and fill in the fields.
press "save".
Captura de pantalla (190).png
Captura de pantalla (190).png (30.91 KiB) Viewed 6620 times

Supla LAN8720 library: https://en-forum.supla.org/viewtopic.ph ... 11#p116011

Code: Select all

#define supla_lib_config_h_  // silences debug messages
#include "soc/soc.h"           // ------------ disable brownout detection ----------
#include "soc/rtc_cntl_reg.h"  // ------------ disable brownout detection ----------
#include "ESPRandom.h"
#include <FS.h>
#include <SPIFFS.h>
#include <WiFiManager.h>
#include <EEPROM.h>
#include <ArduinoJson.h>
#include <SuplaDevice.h>
#include <supla/sensor/normally_open.h>
#include <supla/control/relay.h>
#include <supla/network/esp32eth.h>
  Supla::ESPETH Eth(1);  // uint_t ETH_ADDR = I²C-address of Ethernet PHY (0 or 1)

/*
  ***LAN8720 (50MHz) Osc. Enable to GND ***
     *** ESP32 ***       *** LAN8720 ***
  GPIO17 - EMAC_TX_CLK : nINT/REFCLK (50MHz)
  GPIO18 - SMI_MDIO    : MDIO
  GPIO19 - EMAC_TXD0   : TX0      
  GPIO21 - EMAC_TX_EN  : TX_EN
  GPIO22 - EMAC_TXD1   : TX1
  GPIO23 - SMI_MDC     : MDC
  GPIO25 - EMAC_RXD0   : RX0  
  GPIO26 - EMAC_RXD1   : RX1
  GPIO27 - EMAC_RX_DV  : CRS
  GND                  : GND
  3V3                  : VCC
*/

int relay_1_pin = 4;     //------------------- set relay Gpio -----
int sensor_1_pin = 14;   //------------------- set sensor Gpio ----
int sensor_2_pin = 13;   //------------------- set sensor Gpio ----
int wificonfig_pin = 0;
int led_pin = 33;

int C_W_state = HIGH;
int last_C_W_state = HIGH;
unsigned long time_last_C_W_change = 0;
long C_W_delay = 5000;               // ---------------------- config delay 5 seconds ---------------------------
char Supla_server[81] = ("Set server address");
char Email[81] = ("set email address");
char Supla_name[81]= ("GARAGE_LAN");
char Supla_status[51];
bool shouldSaveConfig = false;
bool initialConfig = false;
int s;
char GUID[SUPLA_GUID_SIZE];
char AUTHKEY[SUPLA_AUTHKEY_SIZE];
byte uuidNumber[16]; // UUIDs in binary form are 16 bytes long
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 FORMAT_SPIFFS_IF_FAILED true
WiFiManager wifiManager;

Supla::Control::Relay *relay_1 = nullptr;
Supla::Sensor::NormallyOpen *sensor_1 = nullptr;
Supla::Sensor::NormallyOpen *sensor_2 = nullptr;

void saveParamCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
  wifiManager.stopConfigPortal();
}
void ondemandwifiCallback () {
  digitalWrite(led_pin, LOW);

  wifiManager.setConfigPortalBlocking(true);
  wifiManager.setCleanConnect(true);
  wifiManager.setBreakAfterConfig(true);
  wifiManager.setSaveParamsCallback(saveParamCallback);
  wifiManager.setCustomHeadElement(logo);
  wifiManager.setMinimumSignalQuality(8);
  wifiManager.setConfigPortalTimeout(300);
  std::vector<const char *> menu = {"param", "sep", "update", "sep", "info", "restart"};
  wifiManager.setMenu(menu);
  wifiManager.setTitle("&#66&#121&#46&#46&#69&#108&#77&#97&#121&#97");

  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.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);

  if (!wifiManager.startConfigPortal("GARAGE_LAN")) {
    // 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());
  if (strcmp(Supla_server, "get_new_guid_and_authkey") == 0) {
    Serial.println("new guid & authkey.");
    EEPROM.write(300, 0);
    EEPROM.commit();
    delay(100);
    ESP.restart();
  }
  if (shouldSaveConfig == true) { // ------------------------ wificonfig save --------------
    Serial.println(" config...");
    DynamicJsonDocument json(1024);
    json["Supla_server"] = Supla_server;
    json["Email"] = Email;
    json["Supla_name"] = Supla_name;
    File configFile = SPIFFS.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;
    delay(5000);
    ESP.restart();
  }
  WiFi.softAPdisconnect(true);
  initialConfig = false;
  digitalWrite(led_pin, HIGH);
}
void guid_authkey(void) {
  if (EEPROM.read(300) != 60) {
    int eep_gui = 301;
    ESPRandom::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;
    ESPRandom::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]);
    }
    for (int x = 0; x < 50; ++x) {
      EEPROM.write(x, 50);
    }
    EEPROM.write(300, 60);
    EEPROM.commit();
  }
  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 status_func(int status, const char *msg) {
  if (s != status) {
    s = status;
    if (status != 10) {
      strcpy(Supla_status, msg);
    }
  }
}

void setup() {

  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);  // ------------ disable brownout detection ----------

  Serial.begin(115200);
  delay(200);
  Serial.println(" ");
  Serial.println(" ");
  EEPROM.begin(512);
  pinMode(wificonfig_pin, INPUT_PULLUP);
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, HIGH);

  if (EEPROM.read(300) != 60) {
    initialConfig = true;
  }
  guid_authkey();

  if (!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {                 //---------- WiFi Config ----------------------
    Serial.println("SPIFFS Mount Failed !Format!");
    initialConfig = true;
  } else {
    Serial.println("mounted file system");
    File configFile = SPIFFS.open ("/config.json", "r");
    if (!configFile || configFile.isDirectory()) {
      Serial.println("- failed to open file for reading");
    } else {
      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"]);
      } else {
        Serial.println("failed to load json config");
        initialConfig = true;
      }
      configFile.close();
    }
  }

  relay_1 = new Supla::Control::Relay(relay_1_pin, true, 15);
  relay_1->getChannel()->setDefault(SUPLA_CHANNELFNC_CONTROLLINGTHEGARAGEDOOR);

  sensor_1 = new Supla::Sensor::NormallyOpen(sensor_1_pin, true);
  sensor_1->getChannel()->setDefault(SUPLA_CHANNELFNC_OPENINGSENSOR_GARAGEDOOR);
  sensor_1->disableChannelState();

  sensor_2 = new Supla::Sensor::NormallyOpen(sensor_2_pin, true);
  sensor_2->getChannel()->setDefault(SUPLA_CHANNELFNC_OPENINGSENSOR_GARAGEDOOR);
  sensor_2->disableChannelState();

  SuplaDevice.setName(Supla_name);
  SuplaDevice.setStatusFuncImpl(&status_func);
  SuplaDevice.begin(GUID, Supla_server, Email, AUTHKEY);

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

void loop() {

  int C_W_read = digitalRead(wificonfig_pin); {
    if (C_W_read != last_C_W_state) {
      time_last_C_W_change = millis();
    }
    if ((millis() - time_last_C_W_change) > C_W_delay) {
      if (C_W_read != C_W_state) {
        C_W_state = C_W_read;
        if (C_W_state == LOW) {
          ondemandwifiCallback () ;
        }
      }
    }
    last_C_W_state = C_W_read;
  }

  SuplaDevice.iterate();
  delay(25);

}

Edit: fix in "Save Params Callback"
radzik_r
Posts: 390
Joined: Sun Aug 11, 2019 5:32 pm

Fajne, przetestowałem, i działa.

Jeśli ktoś martwi sie zasięgiem wifi w szafie rozdzielczej to można już budować sterownik z potężnym mikroprocesorem i LAN.

Już mam pomysł na wykorzystanie tego.


Cool, tested it, and it works.
If someone is worried about the range of wifi in the switch cabinet, you can already build a controller with a powerful microprocessor and LAN.
I already have an idea to use it.
Post Reply

Return to “Ideas and concepts”