diff --git a/data-src/index.js b/data-src/index.js
index d2400e8..46f0a39 100644
--- a/data-src/index.js
+++ b/data-src/index.js
@@ -1954,7 +1954,7 @@ class Somfy {
this.loadPins('input', document.getElementById('selTransRXPin'));
//this.loadSomfy();
ui.toElement(document.getElementById('divTransceiverSettings'), {
- transceiver: { config: { proto: 0, SCKPin: 18, CSNPin: 5, MOSIPin: 23, MISOPin: 19, TXPin: 12, RXPin: 13, frequency: 433.42, rxBandwidth: 97.96, type: 56, deviation: 11.43, txPower: 10, enabled: false } }
+ transceiver: { config: { proto: 0, SCKPin: 18, CSNPin: 5, MOSIPin: 23, MISOPin: 19, TXPin: 12, RXPin: 13, frequency: 433.42, rxBandwidth: 97.96, type: 56, deviation: 11.43, txPower: 10, enabled: false, noiseDetection: false } }
});
this.loadPins('out', document.getElementById('selShadeGPIOUp'));
this.loadPins('out', document.getElementById('selShadeGPIODown'));
diff --git a/src/ConfigFile.cpp b/src/ConfigFile.cpp
index d496632..5dc1801 100644
--- a/src/ConfigFile.cpp
+++ b/src/ConfigFile.cpp
@@ -708,7 +708,8 @@ bool ShadeConfigFile::readTransRecord(transceiver_config_t &cfg) {
cfg.frequency = this->readFloat(cfg.frequency);
cfg.rxBandwidth = this->readFloat(cfg.rxBandwidth);
cfg.deviation = this->readFloat(cfg.deviation);
- cfg.txPower = this->readInt8(cfg.txPower);
+ cfg.txPower = this->readInt8(cfg.txPower);
+ cfg.noiseDetection = this->readBool(false);
if(this->file.position() != startPos + this->header.transRecordSize) {
ESP_LOGD(TAG, "Reading to end of transceiver record");
this->seekChar(CFG_REC_END);
@@ -1065,7 +1066,8 @@ bool ShadeConfigFile::writeTransRecord(transceiver_config_t &cfg) {
this->writeFloat(cfg.frequency, 3);
this->writeFloat(cfg.rxBandwidth, 2);
this->writeFloat(cfg.deviation, 2);
- this->writeInt8(cfg.txPower, CFG_REC_END);
+ this->writeInt8(cfg.txPower);
+ this->writeBool(cfg.noiseDetection, CFG_REC_END);
return true;
}
bool ShadeConfigFile::exists() { return LittleFS.exists("/shades.cfg"); }
diff --git a/src/Somfy.cpp b/src/Somfy.cpp
index 7a8ad51..c5c3e31 100644
--- a/src/Somfy.cpp
+++ b/src/Somfy.cpp
@@ -3,6 +3,7 @@
#include
#include
#include
+#include "driver/gpio.h"
#include "esp_log.h"
#include "Utils.h"
#include "ConfigSettings.h"
@@ -45,6 +46,9 @@ int sort_asc(const void *cmp1, const void *cmp2) {
}
static int interruptPin = 0;
+static volatile bool noiseDetected = false;
+static volatile unsigned long noiseStart = 0;
+static volatile uint32_t noiseCount = 0;
static uint8_t bit_length = 56;
somfy_commands translateSomfyCommand(const String& string) {
if (string.equalsIgnoreCase("My")) return somfy_commands::My;
@@ -4187,6 +4191,21 @@ void Transceiver::sendFrame(byte *frame, uint8_t sync, uint8_t bitLength) {
}
}
void RECEIVE_ATTR Transceiver::handleReceive() {
+ if (noiseDetected) return;
+ if (somfy.transceiver.config.noiseDetection) {
+ unsigned long now = millis();
+ if (noiseStart == 0) noiseStart = now;
+ if (now - noiseStart >= 10000) {
+ noiseStart = now;
+ noiseCount = 0;
+ }
+ noiseCount++;
+ if (noiseCount > 100) {
+ gpio_intr_disable((gpio_num_t)interruptPin);
+ noiseDetected = true;
+ return;
+ }
+ }
static unsigned long last_time = 0;
const long time = micros();
const unsigned int duration = time - last_time;
@@ -4358,7 +4377,7 @@ void Transceiver::processFrequencyScan(bool received) {
currRSSI = -100;
}
- if(millis() - lastScan > 100 && somfy_rx.status == waiting_synchro) {
+ if(millis() - lastScan > 100 && (somfy_rx.status == waiting_synchro || noiseDetected)) {
lastScan = millis();
this->emitFrequencyScan();
currFreq += 0.01f;
@@ -4538,6 +4557,7 @@ void transceiver_config_t::fromJSON(JsonObject& obj) {
if(!obj["enabled"].isNull()) this->enabled = obj["enabled"];
if(!obj["txPower"].isNull()) this->txPower = obj["txPower"];
if(!obj["proto"].isNull()) this->proto = static_cast(obj["proto"].as());
+ if(!obj["noiseDetection"].isNull()) this->noiseDetection = obj["noiseDetection"];
/*
if (!obj["internalCCMode"].isNull()) this->internalCCMode = obj["internalCCMode"];
if (!obj["modulationMode"].isNull()) this->modulationMode = obj["modulationMode"];
@@ -4625,7 +4645,8 @@ void transceiver_config_t::save() {
pref.putBool("radioInit", true);
pref.putChar("txPower", this->txPower);
pref.putChar("proto", static_cast(this->proto));
-
+ pref.putBool("noiseDetect", this->noiseDetection);
+
/*
pref.putBool("internalCCMode", this->internalCCMode);
pref.putUChar("modulationMode", this->modulationMode);
@@ -4724,6 +4745,7 @@ void transceiver_config_t::load() {
this->txPower = pref.getChar("txPower", this->txPower);
this->rxBandwidth = pref.getFloat("rxBandwidth", this->rxBandwidth);
this->proto = static_cast(pref.getChar("proto", static_cast(this->proto)));
+ this->noiseDetection = pref.getBool("noiseDetect", false);
this->removeNVSKey("internalCCMode");
this->removeNVSKey("modulationMode");
this->removeNVSKey("channel");
@@ -4857,6 +4879,14 @@ bool Transceiver::begin() {
}
void Transceiver::loop() {
somfy_rx_t rx;
+ if (noiseDetected && rxmode != 3 && this->config.noiseDetection) {
+ if (millis() - noiseStart > 100) {
+ gpio_intr_enable((gpio_num_t)interruptPin);
+ noiseDetected = false;
+ noiseStart = 0;
+ noiseCount = 0;
+ }
+ }
if(rxmode == 3) {
if(this->receive(&rx))
this->processFrequencyScan(true);
diff --git a/src/SomfyController.ino.cpp b/src/SomfyController.ino.cpp
new file mode 100644
index 0000000..ce50111
--- /dev/null
+++ b/src/SomfyController.ino.cpp
@@ -0,0 +1,147 @@
+# 1 "C:\\Users\\oem\\AppData\\Local\\Temp\\tmpahrx2jqr"
+#include
+# 1 "C:/Users/oem/Documents/PlatformIO/Projects/ESPSomfy-RTS/src/SomfyController.ino"
+#include "esp_log.h"
+#include
+#include
+#include
+#include "ConfigSettings.h"
+#include "ESPNetwork.h"
+#include "Web.h"
+#include "Sockets.h"
+#include "Utils.h"
+#include "Somfy.h"
+#include "MQTT.h"
+#include "GitOTA.h"
+#include "esp_core_dump.h"
+
+static const char *TAG = "Main";
+
+ConfigSettings settings;
+Web webServer;
+SocketEmitter sockEmit;
+ESPNetwork net;
+rebootDelay_t rebootDelay;
+SomfyShadeController somfy;
+MQTTClass mqtt;
+GitUpdater git;
+
+uint32_t oldheap = 0;
+void listDir(const char *dirname, uint8_t levels);
+void setup();
+void loop();
+#line 28 "C:/Users/oem/Documents/PlatformIO/Projects/ESPSomfy-RTS/src/SomfyController.ino"
+void listDir(const char *dirname, uint8_t levels) {
+ ESP_LOGI(TAG, "Listing: %s", dirname);
+ File root = LittleFS.open(dirname);
+ if (!root || !root.isDirectory()) {
+ ESP_LOGE(TAG, "Failed to open directory");
+ return;
+ }
+ File file = root.openNextFile();
+ while (file) {
+ if (file.isDirectory()) {
+ ESP_LOGI(TAG, " DIR : %s", file.name());
+ if (levels) listDir(file.path(), levels - 1);
+ } else {
+ ESP_LOGI(TAG, " FILE: %-30s %d bytes", file.name(), file.size());
+ }
+ file = root.openNextFile();
+ }
+}
+
+void setup() {
+ Serial.begin(115200);
+ ESP_LOGI(TAG, "Startup/Boot....");
+ esp_core_dump_summary_t summary;
+ if (esp_core_dump_get_summary(&summary) == ESP_OK) {
+ ESP_LOGW(TAG, "*** Previous crash coredump found ***");
+ ESP_LOGW(TAG, " Task: %s", summary.exc_task);
+ ESP_LOGW(TAG, " PC: 0x%08x", summary.exc_pc);
+#ifdef CONFIG_IDF_TARGET_ARCH_XTENSA
+ ESP_LOGW(TAG, " Cause: %d", summary.ex_info.exc_cause);
+ char bt_buf[256] = {0};
+ int pos = 0;
+ for (int i = 0; i < summary.exc_bt_info.depth; i++) {
+ pos += snprintf(bt_buf + pos, sizeof(bt_buf) - pos, " 0x%08x", summary.exc_bt_info.bt[i]);
+ }
+ ESP_LOGW(TAG, " Backtrace:%s", bt_buf);
+#elif CONFIG_IDF_TARGET_ARCH_RISCV
+ ESP_LOGW(TAG, " Cause: %d", summary.ex_info.mcause);
+ ESP_LOGW(TAG, " MTVAL: 0x%08x RA: 0x%08x SP: 0x%08x",
+ summary.ex_info.mtval, summary.ex_info.ra, summary.ex_info.sp);
+#endif
+ }
+ ESP_LOGI(TAG, "Mounting File System...");
+
+
+ if (LittleFS.begin()) {
+ ESP_LOGI(TAG, "Total: %d bytes", LittleFS.totalBytes());
+ ESP_LOGI(TAG, "Used: %d bytes", LittleFS.usedBytes());
+ ESP_LOGI(TAG, "Free: %d bytes", LittleFS.totalBytes() - LittleFS.usedBytes());
+ listDir("/", 3);
+ } else {
+ ESP_LOGE(TAG, "LittleFS mount failed!");
+ }
+
+ if(LittleFS.begin()) ESP_LOGI(TAG, "File system mounted successfully");
+ else ESP_LOGE(TAG, "Error mounting file system");
+ settings.begin();
+ if(WiFi.status() == WL_CONNECTED) WiFi.disconnect(true);
+ delay(10);
+ webServer.startup();
+ webServer.begin();
+ delay(1000);
+ net.setup();
+ somfy.begin();
+
+#if ESP_ARDUINO_VERSION_MAJOR >= 3
+ const esp_task_wdt_config_t wdt_config = { .timeout_ms = 15000, .idle_core_mask = 1, .trigger_panic = true };
+ esp_task_wdt_init(&wdt_config);
+#else
+ esp_task_wdt_init(15, true);
+#endif
+ esp_task_wdt_add(NULL);
+
+}
+
+void loop() {
+
+
+ if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) {
+ ESP_LOGI(TAG, "Rebooting after %lums", rebootDelay.rebootTime);
+ net.end();
+ ESP.restart();
+ return;
+ }
+ uint32_t timing = millis();
+
+ net.loop();
+ if(millis() - timing > 100) ESP_LOGD(TAG, "Timing Net: %ldms", millis() - timing);
+ timing = millis();
+ esp_task_wdt_reset();
+ somfy.loop();
+ if(millis() - timing > 100) ESP_LOGD(TAG, "Timing Somfy: %ldms", millis() - timing);
+ timing = millis();
+ esp_task_wdt_reset();
+ if(net.connected() || net.softAPOpened) {
+ if(!rebootDelay.reboot && net.connected() && !net.softAPOpened) {
+ git.loop();
+ esp_task_wdt_reset();
+ }
+ webServer.loop();
+ esp_task_wdt_reset();
+ if(millis() - timing > 100) ESP_LOGD(TAG, "Timing WebServer: %ldms", millis() - timing);
+ esp_task_wdt_reset();
+ timing = millis();
+ sockEmit.loop();
+ if(millis() - timing > 100) ESP_LOGD(TAG, "Timing Socket: %ldms", millis() - timing);
+ esp_task_wdt_reset();
+ timing = millis();
+ }
+ if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) {
+ net.end();
+ ESP.restart();
+ }
+ esp_task_wdt_reset();
+}
\ No newline at end of file
diff --git a/src/Web.cpp b/src/Web.cpp
index 907f40f..ca40c14 100644
--- a/src/Web.cpp
+++ b/src/Web.cpp
@@ -374,6 +374,7 @@ static void serializeTransceiverConfig(JsonFormatter &json) {
json.addElem("txPower", cfg.txPower);
json.addElem("proto", static_cast(cfg.proto));
json.addElem("enabled", cfg.enabled);
+ json.addElem("noiseDetection", cfg.noiseDetection);
json.addElem("radioInit", cfg.radioInit);
}
static void serializeAppVersion(JsonFormatter &json, appver_t &ver) {