Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# ------------------------------------------------------------------------------

# CI/release binaries
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, nodemcuv2_160, esp8266_2m_160, esp01_1m_full_160, nodemcuv2_compat, esp8266_2m_compat, esp01_1m_full_compat, esp32dev, esp32dev_V4, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_16MB_opi, esp32s3dev_8MB_opi, esp32s3_4M_qspi, esp32_wrover, usermods
default_envs = esp32dev

src_dir = ./wled00
data_dir = ./wled00/data
Expand Down Expand Up @@ -445,7 +445,8 @@ platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32\" #-D WLED_DISABLE_BROWNOUT_DET
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32\" #-D WLED_DISABLE_BROWNOUT_DET
-D USERMOD_ROTARYRACKDIMMER
lib_deps = ${esp32.lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
Expand Down
23 changes: 23 additions & 0 deletions usermods/usermod_rotaryrackdimmer/usermod_rotaryrackdimmer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "wled.h"
#include "../usermods/usermod_rotaryrackdimmer/usermod_rotaryrackdimmer.h"

Usermod* usermod_rotary = nullptr;

void userSetup() {
usermod_rotary = new Usermod_RotaryRackDimmer();
usermods.add(usermod_rotary);
Serial.println(F("[RotaryRackDimmer] usermod geladen!"));
}

void userConnected() {
// Optioneel
}

void userLoop() {
// Optioneel, laat usermod zelf zijn werk doen
}

void Usermod_RotaryRackDimmer::addToJsonInfo(JsonObject &root) {
JsonObject user = root["usermod"];
user["RotaryRackDimmer"] = "Actief";
}
Comment on lines +20 to +23
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Move method implementation to header file.

The addToJsonInfo method implementation should be in the header file since it's part of the class definition. Implementing class methods in separate files outside the class definition violates C++ best practices and can cause linking issues.

Move this implementation to the header file within the class definition:

-void Usermod_RotaryRackDimmer::addToJsonInfo(JsonObject &root) {
-  JsonObject user = root["usermod"];
-  user["RotaryRackDimmer"] = "Actief";
-}

Add to the header file within the class:

void addToJsonInfo(JsonObject &root) override {
  JsonObject user = root["usermod"];
  user["RotaryRackDimmer"] = "Active";
}
🤖 Prompt for AI Agents
In usermods/usermod_rotaryrackdimmer/usermod_rotaryrackdimmer.cpp lines 20 to
23, move the implementation of the addToJsonInfo method from the .cpp file to
the header file. Place the method definition inside the class declaration in the
header file, marking it as override, and update the string value to "Active" as
suggested. This ensures the method is inline and avoids potential linking
issues.

38 changes: 38 additions & 0 deletions usermods/usermod_rotaryrackdimmer/usermod_rotaryrackdimmer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include "wled.h"

class Usermod_RotaryRackDimmer : public Usermod {
private:
int pinA = 33; // A (CLK) pin van de encoder
int pinB = 13; // B (DT) pin van de encoder
int lastState = 0;
Comment on lines +7 to +9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Make pin assignments and step size configurable.

The hardcoded pin assignments and brightness step should be configurable through the WLED web interface for better usability and hardware flexibility.

 class Usermod_RotaryRackDimmer : public Usermod {
 private:
-  int pinA = 33;  // A (CLK) pin van de encoder
-  int pinB = 13;  // B (DT) pin van de encoder
+  int pinA = 33;  // A (CLK) pin of encoder - configurable
+  int pinB = 13;  // B (DT) pin of encoder - configurable
+  int stepSize = 5;  // Brightness step size - configurable
   int lastState = 0;

Then implement proper addToConfig and readFromConfig methods to handle these parameters.

🤖 Prompt for AI Agents
In usermods/usermod_rotaryrackdimmer/usermod_rotaryrackdimmer.h around lines 7
to 9, the pin assignments and step size are hardcoded, limiting flexibility.
Modify the code to make pinA, pinB, and the brightness step size configurable
via the WLED web interface by adding corresponding variables and UI controls.
Then implement the addToConfig and readFromConfig methods to save and load these
parameters from the configuration, ensuring they persist across restarts.


public:
void setup() override {
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
lastState = digitalRead(pinA);
}

void loop() override {
int currentState = digitalRead(pinA);
if (currentState != lastState) {
if (digitalRead(pinB) != currentState) {
// Rechtsom → dim omhoog
bri = min(255, bri + 5);
} else {
// Linksom → dim omlaag
bri = max(0, bri - 5);
Comment on lines +23 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using stepSize variable instead of hardcoded value.

The brightness adjustment uses a hardcoded step of 5, but this should use the configurable stepSize variable for consistency.

       if (digitalRead(pinB) != currentState) {
-        bri = min(255, bri + 5);
+        bri = min(255, bri + stepSize);
       } else {
-        bri = max(0, bri - 5);
+        bri = max(0, bri - stepSize);
       }
🤖 Prompt for AI Agents
In usermods/usermod_rotaryrackdimmer/usermod_rotaryrackdimmer.h around lines 23
to 26, the brightness adjustment uses a hardcoded step value of 5. Replace this
hardcoded value with the configurable stepSize variable to ensure consistent and
adjustable brightness increments and decrements.

}
lastState = currentState;
colorUpdated(CALL_MODE_DIRECT_CHANGE);
}
}
Comment on lines +18 to +31
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add debouncing to prevent erratic behavior.

Rotary encoders are prone to bouncing, which will cause erratic brightness changes. The current implementation lacks debouncing and may trigger multiple times per detent.

Add debouncing with a simple time-based approach:

 class Usermod_RotaryRackDimmer : public Usermod {
 private:
   int pinA = 33;
   int pinB = 13;
   int lastState = 0;
+  unsigned long lastChangeTime = 0;
+  const unsigned long debounceDelay = 2; // 2ms debounce

   void loop() override {
     int currentState = digitalRead(pinA);
-    if (currentState != lastState) {
+    if (currentState != lastState && (millis() - lastChangeTime) > debounceDelay) {
       if (digitalRead(pinB) != currentState) {
-        bri = min(255, bri + 5);
+        bri = min(255, bri + stepSize);
       } else {
-        bri = max(0, bri - 5);
+        bri = max(0, bri - stepSize);
       }
       lastState = currentState;
+      lastChangeTime = millis();
       colorUpdated(CALL_MODE_DIRECT_CHANGE);
     }
   }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In usermods/usermod_rotaryrackdimmer/usermod_rotaryrackdimmer.h around lines 18
to 31, the loop function handling the rotary encoder input lacks debouncing,
causing erratic brightness changes due to signal bouncing. To fix this,
implement a simple time-based debounce by recording the last time the state
changed and only processing changes if a minimum debounce interval (e.g., 5-10
milliseconds) has passed since the last update. Add a timestamp variable to
track the last update time and check this before updating brightness and
lastState.


void addToConfig(JsonObject &root) override {}
bool readFromConfig(JsonObject &root) override { return true; }
Comment on lines +33 to +34
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Implement proper configuration methods.

The configuration methods are currently empty but should handle the configurable parameters (pins and step size) to make the usermod user-friendly.

-  void addToConfig(JsonObject &root) override {}
-  bool readFromConfig(JsonObject &root) override { return true; }
+  void addToConfig(JsonObject &root) override {
+    JsonObject top = root.createNestedObject(FPSTR("RotaryRackDimmer"));
+    top["pinA"] = pinA;
+    top["pinB"] = pinB;
+    top["stepSize"] = stepSize;
+  }
+  
+  bool readFromConfig(JsonObject &root) override {
+    JsonObject top = root[FPSTR("RotaryRackDimmer")];
+    if (top.isNull()) return false;
+    
+    pinA = top["pinA"] | pinA;
+    pinB = top["pinB"] | pinB;
+    stepSize = top["stepSize"] | stepSize;
+    
+    return true;
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void addToConfig(JsonObject &root) override {}
bool readFromConfig(JsonObject &root) override { return true; }
void addToConfig(JsonObject &root) override {
JsonObject top = root.createNestedObject(FPSTR("RotaryRackDimmer"));
top["pinA"] = pinA;
top["pinB"] = pinB;
top["stepSize"] = stepSize;
}
bool readFromConfig(JsonObject &root) override {
JsonObject top = root[FPSTR("RotaryRackDimmer")];
if (top.isNull()) return false;
pinA = top["pinA"] | pinA;
pinB = top["pinB"] | pinB;
stepSize = top["stepSize"] | stepSize;
return true;
}
🤖 Prompt for AI Agents
In usermods/usermod_rotaryrackdimmer/usermod_rotaryrackdimmer.h at lines 33-34,
the addToConfig and readFromConfig methods are empty and need to be implemented
to handle the usermod's configurable parameters such as pins and step size.
Modify addToConfig to serialize these parameters into the provided JsonObject,
and update readFromConfig to deserialize and apply these parameters from the
JsonObject, ensuring the usermod can save and restore its configuration
properly.


String getId() override { return F("RotaryRackDimmer"); }
};

1 change: 1 addition & 0 deletions wled00/usermod.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "wled.h"

/*
* This v1 usermod file allows you to add own functionality to WLED more easily
* See: https://github.com/wled-dev/WLED/wiki/Add-own-functionality
Expand Down