Usermod APDS9960 help requested

Created usermod APDS9960; compiles, there is no usermod listed on the WLED app usermod page.

Added the include for usermode APDS9960. Requesting help to see what I am missing.

#pragma once

#include "wled.h"
#include <Wire.h>
#include "Adafruit_APDS9960.h"

class USERMOD_APDS9960 : public Usermod {
  private:
    
  public:
    void setup() {
      Wire.begin();
      apds.begin();
      apds.enableProximity(true);
    }

    void loop() {
      uint16_t proximity = apds.readProximity();
      if (proximity > PROXIMITY_THRESHOLD) {
        // Object is close to the sensor, set the LED brightness to maximum
        bri = 255;
      } else {
        // Object is far from the sensor, reduce the LED brightness
        bri = map(proximity, 0, PROXIMITY_THRESHOLD, 0, 255);
      }
      strip.setBrightness(bri);
      strip.show();          
    }
};


William

Look at the existing usermods.
Of particular interest may be VL53L0X or PIR sensor.

Thank you blazoncek! Will check it out.
Appreciate the help.

William

Tried this; still not working:

#pragma once

#include "wled.h"
#include <Wire.h>
#include "Adafruit_APDS9960.h"

class USERMOD_APDS9960 : public Usermod {
  private:
    
  public:

    Adafruit_APDS9960 apds;

    int PROXIMITY_THRESHOLD = 100;

    //I²C SCL and SDA pins
    #define HW_PIN_SCL 21
    #define HW_PIN_SDA 22

    //the pin that the interrupt is attached to
    #define INT_PIN 3

    void setup() {
      Wire.begin(HW_PIN_SCL, HW_PIN_SDA);
      apds.begin();
      apds.enableProximity(true);
      //set the interrupt threshold to fire when proximity reading goes above 175
      apds.setProximityInterruptThreshold(0, 175); 
      //enable the proximity interrupt
      apds.enableProximityInterrupt();
    }

    void loop() {
      uint16_t proximity = apds.readProximity();
      if (proximity > PROXIMITY_THRESHOLD) {
        // Object is close to the sensor, set the LED brightness to maximum
        bri = 255;
      } else {
        // Object is far from the sensor, reduce the LED brightness
        bri = map(proximity, 0, PROXIMITY_THRESHOLD, 0, 255);

      }
      strip.setBrightness(bri);
      strip.show();          
    }

    void addToConfig(JsonObject& root)
    {
      JsonObject top = root.createNestedObject("APDS9960");
      JsonArray pins = top.createNestedArray("pin");
      pins.add(HW_PIN_SCL);
      pins.add(HW_PIN_SDA);
    }
};

Compiles; nothing shows up in WLED app, Usermods page.

This is my platformio_override.ini:

[env:esp32dev_usermod_APDS9960]
extends = env:esp32dev
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BLYNK #-D WLED_DISABLE_BROWNOUT_DET
 -D USERMOD_APDS9960 
lib_deps = ${env.lib_deps}
  adafruit/Adafruit BusIO@^1.14.1

  # RECOMMENDED
  # Accept new functionality in a backwards compatible manner and patches
  adafruit/Adafruit APDS9960 Library @ ^1.2.3

  # Accept only backwards compatible bug fixes
  # (any version with the same major and minor versions, and an equal or greater patch version)
  adafruit/Adafruit APDS9960 Library @ ~1.2.3

  # The exact version
  adafruit/Adafruit APDS9960 Library @ 1.2.3

William

Did you also add it to the ‘usermod_lists.ccp’ in the wled00 directory?

Yes, added to both places in “usermod.lists.cpp”; the include and registered the usermod.

I do not understand what needs to be done for platformio.override.ini.

Appreciate the reply.

William

Are you sure it is compiling/building the correct environment?

Add this line in your file above ‘#pragma once’ line:

#warning **** Included USERMOD_APDS9960 ****

#pragma once

#include "wled.h"
#include <Wire.h>
#include "Adafruit_APDS9960.h"
...
...

And check if you compile issues the warning, this way you’re sure it compiles correctly.

(as example here)

In file included from wled00/usermods_list.cpp:56:0:
wled00/../usermods/BME280_v2/usermod_bme280.h:2:2: warning: #warning **** Included USERMOD_BME280 version 2.0 **** [-Wcpp]
 #warning **** Included USERMOD_BME280 version 2.0 ****
  ^

Will do this morning; thank you for your assistance.

Update:

Inserted " #warning **** Included USERMOD_APDS9960 **** " in both locations; does not appear when compiling.

William

Ok, then you need to make sure platform IO compiles the right environment.
Click the Platform IO icon on the Bar → Project Tasks, you should see all available environments, expand yours (esp32dev_usermod_APDS9960) and click build.

Made some progress; was able to see the warning that was added, when compiling. Still no usermods in the WLed app. I have no esp32dev_usermod_APDS9960 environment; only esp32dev.

Only reference under Project tasks for usermod_APDS9960 is the Usermod folder has sub folder USERMOD_APDS9960 with usermod_apds9960.h in the sub folder.

William

You should create one. Preferably in platformio_override.ini.

Take existing [env:esp32dev] as an example and add desired build_flags. If you added include directives to usermod_list.cpp in the way other usermods are added there then it will compile your usermod as well (you will see a warning message if you added #pragma directive).

If the usermod is visible in WLED very much depends how usermod communicates with it. The description of that is in the example usermod.

Platformio_override.ini for usermod_apds9960:

[platformio]
[env:esp32dev_APDS9960]
board = esp32dev
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
platform = espressif32@3.4
upload_speed = 921600
build_flags = ${common.build_flags_esp32}
  -D WLED_RELEASE_NAME=ESP32 
  -D USERMOD_APDS9960/usermod_apds9960
lib_deps = ${esp32.lib_deps}
   adafruit/Adafruit BusIO@^1.14.1
	adafruit/Adafruit APDS9960 Library @ ^1.2.3
	adafruit/Adafruit APDS9960 Library @ ~1.2.3
	adafruit/Adafruit APDS9960 Library @ 1.2.3
   lorol/LittleFS_esp32 @ ^1.0.6
upload_port = COM3

Still find no ESP32_APDS9960 on the Platformio root.

See anything missing in Platformio_override.inni?

This is a bare minimum:

[platformio]
default_envs = esp32dev_APDS9960

[env:esp32dev_APDS9960]
extends = env:esp32dev
upload_speed = 921600
upload_port = COM3
build_flags = ${common.build_flags_esp32}
  -D USERMOD_APDS9960
lib_deps = ${esp32.lib_deps}
  adafruit/Adafruit BusIO@^1.14.1
  adafruit/Adafruit APDS9960 Library@^1.2.3

Using -D USERMOD_APDS9960 will only work if you correctly modified usermod_list.cpp.

Thank you for helping with this issue.

Made the changes; is there something I can put in the apds9960.h file that will show on the WLED app, User Mod page? Warning displayed when compiled… Still nothing on User Mod page.

William

Straight from Example v2 usermod file:

    /*
     * addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
     * It will be called by WLED when settings are actually saved (for example, LED settings are saved)
     * If you want to force saving the current state, use serializeConfig() in your loop().
     * 
     * CAUTION: serializeConfig() will initiate a filesystem write operation.
     * It might cause the LEDs to stutter and will cause flash wear if called too often.
     * Use it sparingly and always in the loop, never in network callbacks!
     * 
     * addToConfig() will make your settings editable through the Usermod Settings page automatically.
     *
     * Usermod Settings Overview:
     * - Numeric values are treated as floats in the browser.
     *   - If the numeric value entered into the browser contains a decimal point, it will be parsed as a C float
     *     before being returned to the Usermod.  The float data type has only 6-7 decimal digits of precision, and
     *     doubles are not supported, numbers will be rounded to the nearest float value when being parsed.
     *     The range accepted by the input field is +/- 1.175494351e-38 to +/- 3.402823466e+38.
     *   - If the numeric value entered into the browser doesn't contain a decimal point, it will be parsed as a
     *     C int32_t (range: -2147483648 to 2147483647) before being returned to the usermod.
     *     Overflows or underflows are truncated to the max/min value for an int32_t, and again truncated to the type
     *     used in the Usermod when reading the value from ArduinoJson.
     * - Pin values can be treated differently from an integer value by using the key name "pin"
     *   - "pin" can contain a single or array of integer values
     *   - On the Usermod Settings page there is simple checking for pin conflicts and warnings for special pins
     *     - Red color indicates a conflict.  Yellow color indicates a pin with a warning (e.g. an input-only pin)
     *   - Tip: use int8_t to store the pin value in the Usermod, so a -1 value (pin not set) can be used
     *
     * See usermod_v2_auto_save.h for an example that saves Flash space by reusing ArduinoJson key name strings
     * 
     * If you need a dedicated settings page with custom layout for your Usermod, that takes a lot more work.  
     * You will have to add the setting to the HTML, xml.cpp and set.cpp manually.
     * See the WLED Soundreactive fork (code and wiki) for reference.  https://github.com/atuline/WLED
     * 
     * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
     */

Please start listening and check other usermods and how they behave.

@Tech500 I’ve been struggling with this and I think I’ve figured it out.
The addToConfig fn gets give the ‘um’ JsonObject, and you need to fill it in with whatever config information you need. WLED will take it, and display it on the usermods config page, where the user can modify it. Then when the page is Saved, the data is provided to your usermod by calling the readFromConfig fn with the populated ‘um’ JsonObject.

Here is the flow as I understand it: Usermod internal variables → (addToConfig populates json) → usermod config page presents the json → (Human modifies) → (readFromConfig reads from json) → Usermod internal variables.
As you can see, your usermod instance is intended to hold the master copy of the config data.
The cfg.json persists the data.

For the details look at some working examples.