From 9cd057020e9beb0498c894573f58892f0b8be715 Mon Sep 17 00:00:00 2001 From: czQery Date: Thu, 4 Jun 2026 18:50:34 +0200 Subject: [PATCH 1/3] added ACS712 usermod --- usermods/ACS712/ACS712.cpp | 126 +++++++++++++++++++++++++++++++++++ usermods/ACS712/library.json | 5 ++ 2 files changed, 131 insertions(+) create mode 100644 usermods/ACS712/ACS712.cpp create mode 100644 usermods/ACS712/library.json diff --git a/usermods/ACS712/ACS712.cpp b/usermods/ACS712/ACS712.cpp new file mode 100644 index 0000000000..24389babfe --- /dev/null +++ b/usermods/ACS712/ACS712.cpp @@ -0,0 +1,126 @@ +#include "wled.h" + +#ifdef WLED_DISABLE_MQTT +#error "This user mod requires MQTT to be enabled." +#endif + +class ACS712 : public Usermod { + private: + bool initPin = false; + bool initMQTT = false; + float current = 0; + float lastCurrent = 0; + double sumCurrent = 0; + unsigned long lastTime = 0; + String currentTopic = ""; + + bool enabled = false; + int8_t pin = -1; + uint8_t currentRatio = 100.0; + uint16_t resolution = 4095.0; + int16_t offset = 0; + + static const char _name[]; + static const char _enabled[]; + static const char _current[]; + static const char _resolution[]; + static const char _offset[]; + + + void _mqttInitialize() { + currentTopic = String(mqttDeviceTopic) + "/current"; + + String ha = String("homeassistant/sensor/") + mqttClientID + "/" + FPSTR(_current) + "/config"; + StaticJsonDocument<1024> json; + + json[F("name")] = serverDescription+String(" Current"); + json[F("state_topic")] = currentTopic; + json[F("device_class")] = FPSTR(_current); + json[F("unique_id")] = String(mqttClientID); + json[F("unit_of_measurement")] = F("mA"); + + String jsonSer; + serializeJson(json, jsonSer); + mqtt->publish(ha.c_str(), 0, true, jsonSer.c_str()); + } + + public: + void setup() override { + } + + void loop() override { + if (!enabled || strip.isUpdating() || pin == -1 || (millis() - lastTime < 5000)) return; + if (!initPin) { + pinMode(pin, INPUT); + initPin = true; + } + + if (!initMQTT && WLED_MQTT_CONNECTED) { + _mqttInitialize(); + initMQTT = true; + } + + sumCurrent = 0; + for(int i = 0; i < 100; i++){ + current = analogRead(pin); + + current = (current - (resolution / 2.0f)) * (5000.0f / (resolution * currentRatio)); + current = current * 1000; + current = current + offset; + + sumCurrent += current; + } + + current = sumCurrent/100; + if (initMQTT) mqtt->publish(currentTopic.c_str(), 0, true, String((current+lastCurrent)/2.0).c_str()); + + lastCurrent = current; + lastTime = millis(); + } + + void addToConfig(JsonObject &root) override { + JsonObject top = root.createNestedObject(FPSTR(_name)); + top[FPSTR(_enabled)] = enabled; + top["pin"] = pin; + top[FPSTR(_current)] = currentRatio; + top[FPSTR(_resolution)] = resolution; + top[FPSTR(_offset)] = offset; + } + + bool readFromConfig(JsonObject& root) override { + JsonObject top = root[FPSTR(_name)]; + bool configComplete = !top.isNull(); + configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled, enabled); + configComplete &= getJsonValue(top["pin"], pin, pin); + configComplete &= getJsonValue(top["current"], currentRatio, currentRatio); + configComplete &= getJsonValue(top["resolution"], resolution, resolution); + configComplete &= getJsonValue(top["offset"], offset, offset); + + return configComplete; + } + + void appendConfigData() override { + oappend(F("dd=addDropdown('")); + oappend(String(FPSTR(_name)).c_str()); + oappend(F("','")); + oappend(String(FPSTR(_current)).c_str()); + oappend(F("');")); + oappend(F("addOption(dd,'5A',185.0);")); + oappend(F("addOption(dd,'20A',100.0);")); + oappend(F("addOption(dd,'30A',66.0);")); + oappend(F("addInfo('")); + oappend(String(FPSTR(_name)).c_str()); + oappend(F(":")); + oappend(String(FPSTR(_offset)).c_str()); + oappend(F("',1,'(use to calibrate 0mA)');")); + } +}; + +const char ACS712::_name[] PROGMEM = "ACS712"; +const char ACS712::_enabled[] PROGMEM = "enabled"; +const char ACS712::_current[] PROGMEM = "current"; +const char ACS712::_resolution[] PROGMEM = "resolution"; +const char ACS712::_offset[] PROGMEM = "offset"; + +static ACS712 acs712; +REGISTER_USERMOD(acs712); diff --git a/usermods/ACS712/library.json b/usermods/ACS712/library.json new file mode 100644 index 0000000000..e5d53c91d3 --- /dev/null +++ b/usermods/ACS712/library.json @@ -0,0 +1,5 @@ +{ + "name": "ACS712", + "build": { "libArchive": false }, + "dependencies": {} +} From f5228fd53c2984f7c2cc120a22dc030281d18690 Mon Sep 17 00:00:00 2001 From: czQery Date: Thu, 4 Jun 2026 20:10:10 +0200 Subject: [PATCH 2/3] fix itendation & added config values clamping --- usermods/ACS712/ACS712.cpp | 221 +++++++++++++++++++------------------ 1 file changed, 112 insertions(+), 109 deletions(-) diff --git a/usermods/ACS712/ACS712.cpp b/usermods/ACS712/ACS712.cpp index 24389babfe..1056a8a36b 100644 --- a/usermods/ACS712/ACS712.cpp +++ b/usermods/ACS712/ACS712.cpp @@ -5,115 +5,118 @@ #endif class ACS712 : public Usermod { - private: - bool initPin = false; - bool initMQTT = false; - float current = 0; - float lastCurrent = 0; - double sumCurrent = 0; - unsigned long lastTime = 0; - String currentTopic = ""; - - bool enabled = false; - int8_t pin = -1; - uint8_t currentRatio = 100.0; - uint16_t resolution = 4095.0; - int16_t offset = 0; - - static const char _name[]; - static const char _enabled[]; - static const char _current[]; - static const char _resolution[]; - static const char _offset[]; - - - void _mqttInitialize() { - currentTopic = String(mqttDeviceTopic) + "/current"; - - String ha = String("homeassistant/sensor/") + mqttClientID + "/" + FPSTR(_current) + "/config"; - StaticJsonDocument<1024> json; - - json[F("name")] = serverDescription+String(" Current"); - json[F("state_topic")] = currentTopic; - json[F("device_class")] = FPSTR(_current); - json[F("unique_id")] = String(mqttClientID); - json[F("unit_of_measurement")] = F("mA"); - - String jsonSer; - serializeJson(json, jsonSer); - mqtt->publish(ha.c_str(), 0, true, jsonSer.c_str()); - } - - public: - void setup() override { - } - - void loop() override { - if (!enabled || strip.isUpdating() || pin == -1 || (millis() - lastTime < 5000)) return; - if (!initPin) { - pinMode(pin, INPUT); - initPin = true; - } - - if (!initMQTT && WLED_MQTT_CONNECTED) { - _mqttInitialize(); - initMQTT = true; - } - - sumCurrent = 0; - for(int i = 0; i < 100; i++){ - current = analogRead(pin); - - current = (current - (resolution / 2.0f)) * (5000.0f / (resolution * currentRatio)); - current = current * 1000; - current = current + offset; - - sumCurrent += current; - } - - current = sumCurrent/100; - if (initMQTT) mqtt->publish(currentTopic.c_str(), 0, true, String((current+lastCurrent)/2.0).c_str()); - - lastCurrent = current; - lastTime = millis(); - } - - void addToConfig(JsonObject &root) override { - JsonObject top = root.createNestedObject(FPSTR(_name)); - top[FPSTR(_enabled)] = enabled; - top["pin"] = pin; - top[FPSTR(_current)] = currentRatio; - top[FPSTR(_resolution)] = resolution; - top[FPSTR(_offset)] = offset; - } - - bool readFromConfig(JsonObject& root) override { - JsonObject top = root[FPSTR(_name)]; - bool configComplete = !top.isNull(); - configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled, enabled); - configComplete &= getJsonValue(top["pin"], pin, pin); - configComplete &= getJsonValue(top["current"], currentRatio, currentRatio); - configComplete &= getJsonValue(top["resolution"], resolution, resolution); - configComplete &= getJsonValue(top["offset"], offset, offset); - - return configComplete; - } - - void appendConfigData() override { - oappend(F("dd=addDropdown('")); - oappend(String(FPSTR(_name)).c_str()); - oappend(F("','")); - oappend(String(FPSTR(_current)).c_str()); - oappend(F("');")); - oappend(F("addOption(dd,'5A',185.0);")); - oappend(F("addOption(dd,'20A',100.0);")); - oappend(F("addOption(dd,'30A',66.0);")); - oappend(F("addInfo('")); - oappend(String(FPSTR(_name)).c_str()); - oappend(F(":")); - oappend(String(FPSTR(_offset)).c_str()); - oappend(F("',1,'(use to calibrate 0mA)');")); - } + private: + bool initPin = false; + bool initMQTT = false; + float current = 0; + float lastCurrent = 0; + double sumCurrent = 0; + unsigned long lastTime = 0; + String currentTopic = ""; + + bool enabled = false; + int8_t pin = -1; + uint8_t currentRatio = 100.0; + uint16_t resolution = 4095.0; + int16_t offset = 0; + + static const char _name[]; + static const char _enabled[]; + static const char _current[]; + static const char _resolution[]; + static const char _offset[]; + + + void _mqttInitialize() { + currentTopic = String(mqttDeviceTopic) + "/current"; + + String ha = String("homeassistant/sensor/") + mqttClientID + "/" + FPSTR(_current) + "/config"; + StaticJsonDocument<1024> json; + + json[F("name")] = serverDescription+String(" Current"); + json[F("state_topic")] = currentTopic; + json[F("device_class")] = FPSTR(_current); + json[F("unique_id")] = String(mqttClientID); + json[F("unit_of_measurement")] = F("mA"); + + String jsonSer; + serializeJson(json, jsonSer); + mqtt->publish(ha.c_str(), 0, true, jsonSer.c_str()); + } + + public: + void setup() override { + } + + void loop() override { + if (!enabled || strip.isUpdating() || pin == -1 || (millis() - lastTime < 5000)) return; + if (!initPin) { + pinMode(pin, INPUT); + initPin = true; + } + + if (!initMQTT && WLED_MQTT_CONNECTED) { + _mqttInitialize(); + initMQTT = true; + } + + sumCurrent = 0; + for(int i = 0; i < 100; i++){ + current = analogRead(pin); + + current = (current - (resolution / 2.0f)) * (5000.0f / (resolution * currentRatio)); + current = current * 1000; + current = current + offset; + + sumCurrent += current; + } + + current = sumCurrent/100; + if (initMQTT) mqtt->publish(currentTopic.c_str(), 0, true, String((current+lastCurrent)/2.0).c_str()); + + lastCurrent = current; + lastTime = millis(); + } + + void addToConfig(JsonObject &root) override { + JsonObject top = root.createNestedObject(FPSTR(_name)); + top[FPSTR(_enabled)] = enabled; + top["pin"] = pin; + top[FPSTR(_current)] = currentRatio; + top[FPSTR(_resolution)] = resolution; + top[FPSTR(_offset)] = offset; + } + + bool readFromConfig(JsonObject& root) override { + JsonObject top = root[FPSTR(_name)]; + bool configComplete = !top.isNull(); + configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled, enabled); + configComplete &= getJsonValue(top["pin"], pin, pin); + configComplete &= getJsonValue(top["current"], currentRatio, currentRatio); + configComplete &= getJsonValue(top["resolution"], resolution, resolution); + configComplete &= getJsonValue(top["offset"], offset, offset); + + if (currentRatio == 0) currentRatio = 100; + if (resolution == 0) resolution = 4095; + + return configComplete; + } + + void appendConfigData() override { + oappend(F("dd=addDropdown('")); + oappend(String(FPSTR(_name)).c_str()); + oappend(F("','")); + oappend(String(FPSTR(_current)).c_str()); + oappend(F("');")); + oappend(F("addOption(dd,'5A',185.0);")); + oappend(F("addOption(dd,'20A',100.0);")); + oappend(F("addOption(dd,'30A',66.0);")); + oappend(F("addInfo('")); + oappend(String(FPSTR(_name)).c_str()); + oappend(F(":")); + oappend(String(FPSTR(_offset)).c_str()); + oappend(F("',1,'(use to calibrate 0mA)');")); + } }; const char ACS712::_name[] PROGMEM = "ACS712"; From c37db7c141e3bd95a5668d14a91845760c548308 Mon Sep 17 00:00:00 2001 From: czQery Date: Thu, 4 Jun 2026 20:19:30 +0200 Subject: [PATCH 3/3] fixed inconsistent float suffix --- usermods/ACS712/ACS712.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/usermods/ACS712/ACS712.cpp b/usermods/ACS712/ACS712.cpp index 1056a8a36b..79b437466c 100644 --- a/usermods/ACS712/ACS712.cpp +++ b/usermods/ACS712/ACS712.cpp @@ -16,8 +16,8 @@ class ACS712 : public Usermod { bool enabled = false; int8_t pin = -1; - uint8_t currentRatio = 100.0; - uint16_t resolution = 4095.0; + uint8_t currentRatio = 100; + uint16_t resolution = 4095; int16_t offset = 0; static const char _name[]; @@ -71,8 +71,8 @@ class ACS712 : public Usermod { sumCurrent += current; } - current = sumCurrent/100; - if (initMQTT) mqtt->publish(currentTopic.c_str(), 0, true, String((current+lastCurrent)/2.0).c_str()); + current = sumCurrent/100.0f; + if (initMQTT) mqtt->publish(currentTopic.c_str(), 0, true, String((current+lastCurrent)/2.0f).c_str()); lastCurrent = current; lastTime = millis(); @@ -108,9 +108,9 @@ class ACS712 : public Usermod { oappend(F("','")); oappend(String(FPSTR(_current)).c_str()); oappend(F("');")); - oappend(F("addOption(dd,'5A',185.0);")); - oappend(F("addOption(dd,'20A',100.0);")); - oappend(F("addOption(dd,'30A',66.0);")); + oappend(F("addOption(dd,'5A',185);")); + oappend(F("addOption(dd,'20A',100);")); + oappend(F("addOption(dd,'30A',66);")); oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":"));