Skip to content

Add INA219 usermod support and update platformio.ini#361

Open
Topchris18 wants to merge 2 commits intoMoonModules:mdevfrom
Topchris18:usermod_ina219
Open

Add INA219 usermod support and update platformio.ini#361
Topchris18 wants to merge 2 commits intoMoonModules:mdevfrom
Topchris18:usermod_ina219

Conversation

@Topchris18
Copy link
Copy Markdown

@Topchris18 Topchris18 commented Apr 16, 2026

Summary by CodeRabbit

  • New Features
    • Added INA219 I2C current and power sensor support for monitoring power consumption.
    • Real-time current, power, and voltage readings shown in device information, with “Initializing…”/“Not found” states.
    • Fully configurable: I2C address, shunt resistor, maximum current range, bus voltage range, and read interval.
    • Settings persist across restarts.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 16, 2026

Walkthrough

This PR adds INA219 I2C current/power sensor support to WLED via a new usermod, updates build registration and usermod ID, and adds an optional Adafruit INA219 library entry in platformio.ini.

Changes

Cohort / File(s) Summary
INA219 Usermod Implementation
usermods/INA219_v2/usermod_ina219.h
New UsermodINA219 class: joins I2C, constructs Adafruit_INA219 with configurable address, applies calibration presets, periodically reads shunt/bus voltages, computes current/power, exposes readings via JSON, and persists settings.
Build Integration & ID
wled00/usermods_list.cpp, wled00/const.h
Conditional include/registration of the new usermod and addition of USERMOD_ID_INA219 macro (44).
Project Configuration
platformio.ini
Added commented optional adafruit/Adafruit INA219 @ 1.2.1 library entry under lib_deps.

Sequence Diagram(s)

sequenceDiagram
    actor System as WLED
    participant Usermod as INA219 Usermod
    participant I2C as I2C Bus
    participant Sensor as INA219 Sensor
    participant Config as Config/JSON

    System->>Usermod: setup()
    Usermod->>I2C: joinWire()
    Usermod->>Sensor: instantiate & begin(address)
    Usermod->>Sensor: applyCalibration(busVoltage,maxCurrent)
    Sensor-->>Usermod: ready / not found

    loop every readInterval
        System->>Usermod: loop()
        Usermod->>Sensor: read shunt voltage
        Sensor-->>Usermod: V_shunt
        Usermod->>Sensor: read bus voltage
        Sensor-->>Usermod: V_bus
        Usermod->>Usermod: calculate current & power
        Usermod-->>Config: addToJsonInfo(readings)
    end

    System->>Usermod: readFromConfig()
    Config-->>Usermod: settings
    Usermod->>Usermod: reinit or reapply calibration
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding INA219 usermod support and updating platformio.ini, which matches the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@platformio.ini`:
- Around line 297-298: The new global dependency line "adafruit/Adafruit INA219
@ 1.2.1" was added under the global [env] and therefore affects all build
environments; revert this change from the global section and either move the
dependency into the specific environment(s) that need the INA219 or leave it
commented with a clear TODO requiring explicit maintainer/WLED org approval
before enabling. Ensure you reference the dependency string "adafruit/Adafruit
INA219 @ 1.2.1" when making the change and add a brief sign-off note (e.g.,
"Requires maintainer approval") so reviewers can approve before it becomes
active.

In `@usermods/INA219_v2/usermod_ina219.h`:
- Around line 119-120: The computation of current (current_mA = shuntVoltage_mV
/ (shuntResistor_mOhm / 1000.0f)) can divide by zero or a tiny value if
shuntResistor_mOhm is misconfigured; validate and clamp shuntResistor_mOhm when
loading config (where it’s set) to a safe minimum (e.g. >0 and not near-zero)
and add a runtime guard before computing current in the measurement path (check
shuntResistor_mOhm against the minimum, skip or set current_mA/power_mW to 0 and
log/warn if invalid). Ensure you update symbols: shuntResistor_mOhm validation
at config load and the check around current_mA/power_mW calculation that uses
shuntVoltage_mV and loadVoltage_V.
- Around line 62-69: applyCalibration currently favors 32V calibrations whenever
maxCurrentRange_A > 0.4, ignoring a configured busVoltageRange_V of 16V; update
applyCalibration to first branch on busVoltageRange_V (e.g., if
busVoltageRange_V <= 16) and then choose the correct current-based calibration
(call ina219->setCalibration_16V_400mA for <=0.4A else a 16V+higher-current
routine if available), otherwise for busVoltageRange_V > 16 choose the 32V
calibrations (use ina219->setCalibration_32V_1A or ina219->setCalibration_32V_2A
based on maxCurrentRange_A); make the same voltage-first decision wherever the
settings from busVoltageRange_V/maxCurrentRange_A are applied (references:
function applyCalibration, variables busVoltageRange_V and maxCurrentRange_A,
and methods ina219->setCalibration_16V_400mA, ina219->setCalibration_32V_1A,
ina219->setCalibration_32V_2A).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9ca8f889-7b42-4cb8-858e-7c6fa6fed515

📥 Commits

Reviewing files that changed from the base of the PR and between 83368c3 and c3e9aec.

📒 Files selected for processing (4)
  • platformio.ini
  • usermods/INA219_v2/usermod_ina219.h
  • wled00/const.h
  • wled00/usermods_list.cpp

Comment thread platformio.ini Outdated
Comment thread usermods/INA219_v2/usermod_ina219.h Outdated
Comment thread usermods/INA219_v2/usermod_ina219.h Outdated
@Topchris18
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 17, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
usermods/INA219_v2/usermod_ina219.h (2)

43-43: lastMeasure duplicates base-class lastTime.

Usermod already provides unsigned long lastTime. Reusing it would slightly shrink the footprint and match convention across usermods. Non-blocking.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@usermods/INA219_v2/usermod_ina219.h` at line 43, The field lastMeasure
duplicates the base-class Usermod's lastTime; remove the unsigned long
lastMeasure declaration from usermod_ina219.h and update all usages in the
INA219 usermod (references to lastMeasure in methods like setup(), loop(),
read/measure routines) to use lastTime instead so the mod reuses the inherited
timer field and reduces footprint while preserving behavior.

217-222: PROGMEM static member definitions in header — potential ODR risk if header is included elsewhere.

Defining UsermodINA219::_readInterval[] et al. in the header is currently safe because this header is included only once (via usermods_list.cpp with #ifdef USERMOD_INA219 guard). However, if the header is ever included from a second translation unit (e.g., tests, a future companion .cpp, or another usermod), you'll get multiple-definition linker errors.

Consider marking them inline (C++17) to allow safe multi-inclusion, or move them to a companion .cpp. Other usermods in the repo use this pattern, so this is optional.

♻️ Proposed change (C++17)
-const char UsermodINA219::_readInterval[]    PROGMEM = "readInterval-ms";
-const char UsermodINA219::_i2cAddress[]      PROGMEM = "i2cAddress";
-const char UsermodINA219::_shuntResistor[]   PROGMEM = "shuntResistor-mOhm";
-const char UsermodINA219::_maxCurrentRange[] PROGMEM = "maxCurrentRange-A";
-const char UsermodINA219::_busVoltageRange[] PROGMEM = "busVoltageRange-V";
+inline const char UsermodINA219::_readInterval[]    PROGMEM = "readInterval-ms";
+inline const char UsermodINA219::_i2cAddress[]      PROGMEM = "i2cAddress";
+inline const char UsermodINA219::_shuntResistor[]   PROGMEM = "shuntResistor-mOhm";
+inline const char UsermodINA219::_maxCurrentRange[] PROGMEM = "maxCurrentRange-A";
+inline const char UsermodINA219::_busVoltageRange[] PROGMEM = "busVoltageRange-V";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@usermods/INA219_v2/usermod_ina219.h` around lines 217 - 222, The PROGMEM
static definitions (UsermodINA219::_readInterval, _i2cAddress, _shuntResistor,
_maxCurrentRange, _busVoltageRange) in the header can cause ODR
multiple-definition errors if the header is included in more than one TU; fix by
either marking these static data definitions inline (C++17) or moving them into
a companion .cpp file where they are defined once; update the header to declare
them (if moving) or add the inline specifier to each definition and keep the
PROGMEM storage so UsermodINA219 still references the same symbols.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@usermods/INA219_v2/usermod_ina219.h`:
- Around line 201-210: readFromConfig() currently only calls setup() when the
I2C address changes, which misses the case where enabled transitions from
false→true; update readFromConfig() to track the previous enabled state (e.g.
oldEnabled) and if oldEnabled != enabled and enabled == true call setup() to
force sensor initialization (use same setup() that handles I2C init and sets
sensorFound/ina219), and when enabled transitions to false clear or reset
sensorFound and ina219 to avoid stale state; keep the existing address-change
logic but ensure both paths handle the enabled flag consistently.
- Around line 190-199: After reading JSON into i2cAddress, readInterval and
busVoltageRange_V via getJsonValue, add validation and clamping: validate
i2cAddress against the supported INA219 addresses (0x40,0x41,0x44,0x45) and if
not one of those set a safe default (e.g. 0x40) and log the correction; ensure
readInterval is >= 1 (or a chosen minimum) and if zero or too small set it to
the minimum and log; for busVoltageRange_V only accept 16 or 32 (clamp or
default to 32) and log adjustments. Place these checks immediately after the
getJsonValue lines (near variables i2cAddress, readInterval, busVoltageRange_V)
so begin() will receive valid values. Ensure configComplete remains accurate if
values were corrected and keep the existing shuntResistor_mOhm min clamp logic.

---

Nitpick comments:
In `@usermods/INA219_v2/usermod_ina219.h`:
- Line 43: The field lastMeasure duplicates the base-class Usermod's lastTime;
remove the unsigned long lastMeasure declaration from usermod_ina219.h and
update all usages in the INA219 usermod (references to lastMeasure in methods
like setup(), loop(), read/measure routines) to use lastTime instead so the mod
reuses the inherited timer field and reduces footprint while preserving
behavior.
- Around line 217-222: The PROGMEM static definitions
(UsermodINA219::_readInterval, _i2cAddress, _shuntResistor, _maxCurrentRange,
_busVoltageRange) in the header can cause ODR multiple-definition errors if the
header is included in more than one TU; fix by either marking these static data
definitions inline (C++17) or moving them into a companion .cpp file where they
are defined once; update the header to declare them (if moving) or add the
inline specifier to each definition and keep the PROGMEM storage so
UsermodINA219 still references the same symbols.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f446a9fc-73ad-45d1-bc7d-bee6245ef75e

📥 Commits

Reviewing files that changed from the base of the PR and between c3e9aec and 4bb2dfe.

📒 Files selected for processing (2)
  • platformio.ini
  • usermods/INA219_v2/usermod_ina219.h
✅ Files skipped from review due to trivial changes (1)
  • platformio.ini

Comment on lines +190 to +199
configComplete &= getJsonValue(top[F("enabled")], enabled, false);
configComplete &= getJsonValue(top[FPSTR(_readInterval)], readInterval, (uint32_t)5000);
configComplete &= getJsonValue(top[FPSTR(_i2cAddress)], i2cAddress, (uint8_t)0x40);
configComplete &= getJsonValue(top[FPSTR(_shuntResistor)], shuntResistor_mOhm, 100.0f);
if (shuntResistor_mOhm < 1.0f) {
USER_PRINTLN(F("[INA219]: shuntResistor-mOhm clamped to minimum 1 mOhm."));
shuntResistor_mOhm = 1.0f;
}
configComplete &= getJsonValue(top[FPSTR(_maxCurrentRange)], maxCurrentRange_A, 2.0f);
configComplete &= getJsonValue(top[FPSTR(_busVoltageRange)], busVoltageRange_V, (uint8_t)32);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Validate i2cAddress and readInterval.

No bounds checks on user-supplied config:

  • i2cAddress: the INA219 only supports 0x40/0x41/0x44/0x45 (and combinations). Arbitrary addresses will just cause begin() to silently fail on reload.
  • readInterval: a user-entered 0 makes now - lastMeasure < 0 always false and triggers a read every loop() call, hammering the I²C bus.
  • busVoltageRange_V: any value other than 16/32 will fall into the 32V branch at Line 68; either document or clamp.
🛡️ Proposed validation
     configComplete &= getJsonValue(top[FPSTR(_readInterval)],    readInterval,        (uint32_t)5000);
+    if (readInterval < 50) { readInterval = 50; configComplete = false; }
     configComplete &= getJsonValue(top[FPSTR(_i2cAddress)],      i2cAddress,          (uint8_t)0x40);
+    if (i2cAddress != 0x40 && i2cAddress != 0x41 && i2cAddress != 0x44 && i2cAddress != 0x45) {
+      USER_PRINTLN(F("[INA219]: invalid i2cAddress, reset to 0x40."));
+      i2cAddress = 0x40;
+      configComplete = false;
+    }
     configComplete &= getJsonValue(top[FPSTR(_shuntResistor)],   shuntResistor_mOhm,  100.0f);
📝 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
configComplete &= getJsonValue(top[F("enabled")], enabled, false);
configComplete &= getJsonValue(top[FPSTR(_readInterval)], readInterval, (uint32_t)5000);
configComplete &= getJsonValue(top[FPSTR(_i2cAddress)], i2cAddress, (uint8_t)0x40);
configComplete &= getJsonValue(top[FPSTR(_shuntResistor)], shuntResistor_mOhm, 100.0f);
if (shuntResistor_mOhm < 1.0f) {
USER_PRINTLN(F("[INA219]: shuntResistor-mOhm clamped to minimum 1 mOhm."));
shuntResistor_mOhm = 1.0f;
}
configComplete &= getJsonValue(top[FPSTR(_maxCurrentRange)], maxCurrentRange_A, 2.0f);
configComplete &= getJsonValue(top[FPSTR(_busVoltageRange)], busVoltageRange_V, (uint8_t)32);
configComplete &= getJsonValue(top[F("enabled")], enabled, false);
configComplete &= getJsonValue(top[FPSTR(_readInterval)], readInterval, (uint32_t)5000);
if (readInterval < 50) { readInterval = 50; configComplete = false; }
configComplete &= getJsonValue(top[FPSTR(_i2cAddress)], i2cAddress, (uint8_t)0x40);
if (i2cAddress != 0x40 && i2cAddress != 0x41 && i2cAddress != 0x44 && i2cAddress != 0x45) {
USER_PRINTLN(F("[INA219]: invalid i2cAddress, reset to 0x40."));
i2cAddress = 0x40;
configComplete = false;
}
configComplete &= getJsonValue(top[FPSTR(_shuntResistor)], shuntResistor_mOhm, 100.0f);
if (shuntResistor_mOhm < 1.0f) {
USER_PRINTLN(F("[INA219]: shuntResistor-mOhm clamped to minimum 1 mOhm."));
shuntResistor_mOhm = 1.0f;
}
configComplete &= getJsonValue(top[FPSTR(_maxCurrentRange)], maxCurrentRange_A, 2.0f);
configComplete &= getJsonValue(top[FPSTR(_busVoltageRange)], busVoltageRange_V, (uint8_t)32);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@usermods/INA219_v2/usermod_ina219.h` around lines 190 - 199, After reading
JSON into i2cAddress, readInterval and busVoltageRange_V via getJsonValue, add
validation and clamping: validate i2cAddress against the supported INA219
addresses (0x40,0x41,0x44,0x45) and if not one of those set a safe default (e.g.
0x40) and log the correction; ensure readInterval is >= 1 (or a chosen minimum)
and if zero or too small set it to the minimum and log; for busVoltageRange_V
only accept 16 or 32 (clamp or default to 32) and log adjustments. Place these
checks immediately after the getJsonValue lines (near variables i2cAddress,
readInterval, busVoltageRange_V) so begin() will receive valid values. Ensure
configComplete remains accurate if values were corrected and keep the existing
shuntResistor_mOhm min clamp logic.

Comment on lines +201 to +210
if (!initDone) {
DEBUG_PRINTLN(F("[INA219] config loaded."));
} else {
DEBUG_PRINTLN(F("[INA219] config (re)loaded."));
if (oldAddress != i2cAddress) {
setup(); // reinitialize sensor with new I2C address
} else {
applyCalibration(); // update PGA gain for new voltage/current range
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Re-entering setup() from readFromConfig() — verify behavior when disabled.

At Line 206, setup() is invoked on I²C-address change. If the user simultaneously toggled enabled to false, setup() short-circuits at Line 80, but sensorFound/ina219 keep their previous values. That's benign, but toggling enabled from falsetrue via config edit won't re-run setup() at all (no address change path) — the sensor will stay uninitialized until reboot. Consider forcing re-init when enabled transitions to true as well.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@usermods/INA219_v2/usermod_ina219.h` around lines 201 - 210, readFromConfig()
currently only calls setup() when the I2C address changes, which misses the case
where enabled transitions from false→true; update readFromConfig() to track the
previous enabled state (e.g. oldEnabled) and if oldEnabled != enabled and
enabled == true call setup() to force sensor initialization (use same setup()
that handles I2C init and sets sensorFound/ina219), and when enabled transitions
to false clear or reset sensorFound and ina219 to avoid stale state; keep the
existing address-change logic but ensure both paths handle the enabled flag
consistently.

@softhack007
Copy link
Copy Markdown
Collaborator

217-222: PROGMEM static member definitions in header — potential ODR risk if header is included elsewhere.

Defining UsermodINA219::_readInterval[] et al. in the header is currently safe because this header is included only once (via usermods_list.cpp with #ifdef USERMOD_INA219 guard). However, if the header is ever included from a second translation unit (e.g., tests, a future companion .cpp, or another usermod), you'll get multiple-definition linker errors.

Consider marking them inline (C++17) to allow safe multi-inclusion, or move them to a companion .cpp. Other usermods in the repo use this pattern, so this is optional.

@coderabbitai this pattern is "normal" for usermods in WLED-MM. Each usermod is included exactly once from usermods_list.cpp. the PROGMEM constants are intended to reduce flash size, especially on esp8266. Defining them 'inline' (c++17) creates a risk of duplicating strings again, which would counter the original intention.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 17, 2026

Tip

For best results, initiate chat on the files or code changes.

@softhack007, thank you for the clear explanation. I understand now — the single-inclusion guarantee via the #ifdef USERMOD_INA219 guard in usermods_list.cpp makes the ODR concern moot in practice, and using inline would undermine the very purpose of PROGMEM by potentially causing string duplication. I'll remember this established pattern for future reviews.


✏️ Learnings added
Learnt from: softhack007
URL: https://github.com/MoonModules/WLED-MM/pull/361

Timestamp: 2026-04-17T19:40:08.034Z
Learning: In MoonModules/WLED-MM, defining `static const char[] PROGMEM` members for usermod config-key strings in the header file (rather than a companion `.cpp`) is the intentional and repo-normal pattern. Each usermod header is included exactly once via `#ifdef USERMOD_<NAME>` in `usermods_list.cpp`, so there is no ODR risk. Do NOT suggest marking these `inline` (C++17), as that risks duplicating the strings and defeats the flash-saving purpose of `PROGMEM`, especially on ESP8266. Do not flag this pattern as an issue in code reviews.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Applies to usermods/**/*.{cpp,h,hpp} : Store repeated strings in usermods as `static const char[] PROGMEM`

Learnt from: softhack007
Repo: MoonModules/WLED-MM PR: 0
File: :0-0
Timestamp: 2026-04-04T00:29:49.127Z
Learning: In MoonModules/WLED-MM, function-level doc comment blocks (e.g. /* ***** */ style headers) are NOT required during code reviews, especially not for previously existing functions. Do not flag missing function-level comments as review issues in this repository.

Learnt from: softhack007
Repo: MoonModules/WLED-MM PR: 0
File: :0-0
Timestamp: 2026-04-02T22:23:41.534Z
Learning: In MoonModules/WLED-MM, the approved VLA guidance for cpp.instructions.md reads: "Avoid Variable Length Arrays (VLAs): GCC/Clang support VLAs as an extension (not part of the C++ standard), so they look like a legitimate feature — but they are allocated on the stack at runtime. On ESP32/ESP8266, FreeRTOS task stacks are typically only 2–8 KB; a VLA whose size depends on a runtime parameter (segment dimensions, pixel counts, etc.) can silently exhaust the stack and cause the program to behave in unexpected ways or crash. Prefer a fixed-size array with a compile-time bound, or heap allocation (d_malloc / p_malloc) for dynamically sized buffers. Any VLA must be explicitly justified in the PR."

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Applies to wled00/**/*.{cpp,h,hpp,c} usermods/**/*.{cpp,h,hpp,c} : Wrap platform-conditional C++ includes in `#ifdef ARDUINO_ARCH_ESP32` / `#ifdef ESP8266`

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Applies to wled00/**/*.{cpp,h,hpp,c} usermods/**/*.{cpp,h,hpp,c} : Prefer `constexpr` over `#define` for compile-time constants in C++

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Applies to wled00/**/*.{cpp,h,hpp,c} usermods/**/*.{cpp,h,hpp,c} : Avoid `String` in hot paths in C++; acceptable in config/setup code

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Applies to wled00/**/*.{cpp,h,hpp,c} usermods/**/*.{cpp,h,hpp,c} : Use `F("string")` for C++ string constants to save RAM on ESP8266

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Applies to wled00/**/*.{cpp,h,hpp,c} usermods/**/*.{cpp,h,hpp,c} : Use `IRAM_ATTR`, `WLED_O2_ATTR`, `__attribute__((hot))` function attributes for hot-path C++ code

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Applies to wled00/**/*.{cpp,h,hpp,c} usermods/**/*.{cpp,h,hpp,c} : Use `uint_fast16_t` / `uint_fast8_t` in hot-path C++ code for performance

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Applies to wled00/**/*.{cpp,h,hpp,c} usermods/**/*.{cpp,h,hpp,c} : Call `reserve()` on C++ strings/vectors to pre-allocate and avoid fragmentation

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Applies to wled00/**/*.{cpp,h,hpp,c} usermods/**/*.{cpp,h,hpp,c} : Do not use VLAs in C++; use fixed arrays or heap allocation

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Applies to wled00/**/*.{cpp,h,hpp,c} usermods/**/*.{cpp,h,hpp,c} : Use `PSTR()` with `DEBUG_PRINTF_P()` for C++ format strings to save RAM

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T23:40:02.017Z
Learning: Changes to `platformio.ini` require maintainer approval

Learnt from: CR
Repo: MoonModules/WLED-MM PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-04-14T23:39:33.574Z
Learning: Applies to platformio.ini : Modifications to `platformio.ini` must be approved explicitly by a maintainer or WLED organisation Member — modifications to the global build environment may break GitHub Actions builds

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants