{"id":16623683,"url":"https://github.com/jandelgado/jled","last_synced_at":"2025-03-15T12:30:29.518Z","repository":{"id":37335617,"uuid":"94705769","full_name":"jandelgado/jled","owner":"jandelgado","description":"Non-blocking LED controlling library for Arduino and friends.","archived":false,"fork":false,"pushed_at":"2025-01-12T15:39:04.000Z","size":8016,"stargazers_count":335,"open_issues_count":2,"forks_count":58,"subscribers_count":22,"default_branch":"master","last_synced_at":"2025-02-27T01:24:45.047Z","etag":null,"topics":["arduino","breathe","controlling-leds","effect","embedded","esp-idf","esp32","esp8266","fade","led","mbed","non-blocking","raspberry-pi-pico","stm32"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jandelgado.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-18T18:35:16.000Z","updated_at":"2025-01-01T13:45:35.000Z","dependencies_parsed_at":"2024-10-26T20:35:43.858Z","dependency_job_id":"a88176f4-e1ae-4873-996c-6bd9bfdce56b","html_url":"https://github.com/jandelgado/jled","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jandelgado%2Fjled","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jandelgado%2Fjled/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jandelgado%2Fjled/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jandelgado%2Fjled/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jandelgado","download_url":"https://codeload.github.com/jandelgado/jled/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243730842,"owners_count":20338724,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","breathe","controlling-leds","effect","embedded","esp-idf","esp32","esp8266","fade","led","mbed","non-blocking","raspberry-pi-pico","stm32"],"created_at":"2024-10-12T03:24:37.042Z","updated_at":"2025-03-15T12:30:29.512Z","avatar_url":"https://github.com/jandelgado.png","language":"C++","readme":"\u003ctable\u003e\u003ctr\u003e\u003ctd\u003e\n\u003cb\u003ePreferring Python?\u003c/b\u003e I just released \u003ca href=\"https://github.com/jandelgado/jled-circuitpython\"\u003ejled-circuitpython\u003c/a\u003e,\na JLed implementation for CircuitPython and MicroPython.\n\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n# JLed - Advanced LED Library\n\n![run tests](https://github.com/jandelgado/jled/workflows/run%20tests/badge.svg)\n[![Coverage Status](https://coveralls.io/repos/github/jandelgado/jled/badge.svg?branch=master\u0026dummy=1)](https://coveralls.io/github/jandelgado/jled?branch=master)\n\nAn embedded C++ library to control LEDs. It uses a **non-blocking** approach and can\ncontrol LEDs in simple (**on**/**off**) and complex (**blinking**,\n**breathing** and more) ways in a **time-driven** manner.\n\nJLed got some [coverage on Hackaday](https://hackaday.com/2018/06/13/simplifying-basic-led-effects/)\nand someone did a [video tutorial for JLed](https://youtu.be/x5V2vdpZq1w)  - Thanks!\n\n\u003ctable\u003e\n \u003ctr\u003e\n  \u003cth\u003eJLed in action\u003c/th\u003e\n  \u003cth\u003eInteractive JLed playground\u003c/th\u003e\n \u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003e\u003ca href=\"examples/multiled\"\u003e\u003cimg alt=\"JLed in action\" src=\"doc/jled.gif\" width=256\u003e\u003c/a\u003e\u003c/td\u003e\n  \u003ctd\u003e\u003ca href=\"https://jandelgado.github.io/jled-wasm\"\u003e\u003cimg alt=\"jled running in the browser\" src=\"doc/jled-wasm.png\" width=256\u003e\u003c/a\u003e\n  \u003c/td\u003e\n \u003c/tr\u003e\n\u003c/table\u003e\n\n## Example\n\n```c++\n// breathe LED (on gpio 9) 6 times for 1500ms, waiting for 500ms after each run\n#include \u003cjled.h\u003e\n\nauto led_breathe = JLed(9).Breathe(1500).Repeat(6).DelayAfter(500);\n\nvoid setup() { }\n\nvoid loop() {\n  led_breathe.Update();\n}\n```\n\n## Contents\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n* [Features](#features)\n* [Cheat Sheet](#cheat-sheet)\n* [Installation](#installation)\n    * [Arduino IDE](#arduino-ide)\n    * [PlatformIO](#platformio)\n* [Usage](#usage)\n        * [Output pipeline](#output-pipeline)\n    * [Effects](#effects)\n        * [Static on and off](#static-on-and-off)\n            * [Static on example](#static-on-example)\n        * [Blinking](#blinking)\n            * [Blinking example](#blinking-example)\n        * [Breathing](#breathing)\n            * [Breathing example](#breathing-example)\n        * [Candle](#candle)\n            * [Candle example](#candle-example)\n        * [FadeOn](#fadeon)\n            * [FadeOn example](#fadeon-example)\n        * [FadeOff](#fadeoff)\n        * [Fade](#fade)\n            * [Fade example](#fade-example)\n        * [User provided brightness function](#user-provided-brightness-function)\n            * [User provided brightness function example](#user-provided-brightness-function-example)\n        * [Delays and repetitions](#delays-and-repetitions)\n            * [Initial delay before effect starts](#initial-delay-before-effect-starts)\n            * [Delay after effect finished](#delay-after-effect-finished)\n            * [Repetitions](#repetitions)\n        * [State functions](#state-functions)\n            * [Update](#update)\n            * [IsRunning](#isrunning)\n            * [Reset](#reset)\n            * [Immediate Stop](#immediate-stop)\n        * [Misc functions](#misc-functions)\n            * [Low active for inverted output](#low-active-for-inverted-output)\n            * [Minimum- and Maximum brightness level](#minimum--and-maximum-brightness-level)\n    * [Controlling a group of LEDs](#controlling-a-group-of-leds)\n* [Framework notes](#framework-notes)\n* [Platform notes](#platform-notes)\n    * [ESP8266](#esp8266)\n    * [ESP32](#esp32)\n        * [Using ESP-IDF](#using-esp-idf)\n    * [STM32](#stm32)\n        * [Arduino framework](#arduino-framework)\n    * [Raspberry Pi Pico](#raspberry-pi-pico)\n* [Example sketches](#example-sketches)\n    * [Building examples with PlatformIO](#building-examples-with-platformio)\n    * [Building examples with the Arduino IDE](#building-examples-with-the-arduino-ide)\n* [Extending](#extending)\n    * [Support new hardware](#support-new-hardware)\n* [Unit tests](#unit-tests)\n* [Contributing](#contributing)\n* [FAQ](#faq)\n    * [How do I check if a JLed object is still being updated?](#how-do-i-check-if-a-jled-object-is-still-being-updated)\n    * [How do I restart an effect?](#how-do-i-restart-an-effect)\n    * [How do I change a running effect?](#how-do-i-change-a-running-effect)\n* [Author and Copyright](#author-and-copyright)\n* [License](#license)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n## Features\n\n* non-blocking\n* effects: simple on/off, breathe, blink, candle, fade-on, fade-off, [user-defined](examples/morse) (e.g. morse)\n* supports inverted  polarity of LED\n* easy configuration using fluent interface\n* can control groups of LEDs sequentially or in parallel\n* Portable: Arduino, ESP8266, ESP32, Mbed, Raspberry Pi Pico and more platforms\n  compatible, runs even in the [browser](https://jandelgado.github.io/jled-wasm)\n* supports Arduino, [mbed](https://www.mbed.com), [Raspberry Pi\n  Pico](https://github.com/raspberrypi/pico-sdk) and ESP32\n  [ESP-IDF](https://www.espressif.com/en/products/sdks/esp-idf) SDK's\n* well [tested](https://coveralls.io/github/jandelgado/jled)\n\n## Cheat Sheet\n\n![JLed Cheat Sheet](doc/cheat_sheet.jpg)\n\n## Installation\n\n### Arduino IDE\n\nIn the main menu of the Arduino IDE, select `Sketch` \u003e `Include Library` \u003e\n`Manage Libraries...` and search for `jled`, then press `install`.\n\n### PlatformIO\n\nAdd `jled` to your library dependencies in your `platformio.ini` project file,\ne.g.\n\n```ini\n...\n[env:nanoatmega328]\nplatform = atmelavr\nboard = nanoatmega328\nframework = arduino\nlib_deps=jled\n...\n```\n\n## Usage\n\nFirst, the LED object is constructed and configured, then the state is updated\nwith subsequent calls to the `Update()` method, typically from the `loop()`\nfunction. While the effect is active, `Update` returns `true`, otherwise\n`false`.\n\nThe constructor takes the pin, to which the LED is connected to as\nthe only argument. Further configuration of the LED object is done using a fluent\ninterface, e.g. `JLed led = JLed(13).Breathe(2000).DelayAfter(1000).Repeat(5)`.\nSee the examples section below for further details.\n\n#### Output pipeline\n\nFirst the configured effect (e.g. `Fade`) is evaluated for the current time\n`t`. JLed internally uses unsigned bytes to represent brightness values,\nranging from 0 to 255. Next, the value is scaled to the limits set by\n`MinBrightness` and `MaxBrightness` (optionally). When the effect is configured\nfor a low-active LED using `LowActive`, the brightness value will be inverted,\ni.e., the value will be subtracted from 255. Finally the value is passed to the\nhardware abstraction, which might scale it to the resolution used by the actual\ndevice (e.g. 10 bits for an ESP8266). Finally the brightness value is written\nout to the configure GPIO.\n\n```text\n┌───────────┐    ┌────────────┐    ┌─────────┐    ┌────────┐    ┌─────────┐    ┌────────┐\n│ Evaluate  │    │  Scale to  │    │  Low    │YES │ Invert │    │Scale for│    │Write to│\n│ effect(t) ├───►│ [min, max] ├───►│ active? ├───►│ signal ├───►│Hardware ├───►│  GPIO  │\n└───────────┘    └────────────┘    └────┬────┘    └────────┘    └───▲─────┘    └────────┘\n                                        │ NO                        │\n                                        └───────────────────────────┘\n```\n\n### Effects\n\n#### Static on and off\n\nCalling `On(uint16_t period=1)` turns the LED on. To immediately turn a LED on,\nmake a call like `JLed(LED_BUILTIN).On().Update()`. The `period` is optional\nand defaults to 1ms.\n\n`Off()` works like `On()`, except that it turns the LED off, i.e., it sets the\nbrightness to 0.\n\nUse the `Set(uint8_t brightness, uint16_t period=1)` method to set the\nbrightness to the given value, i.e., `Set(255)` is equivalent to calling `On()`\nand `Set(0)` is equivalent to calling `Off()`.\n\nTechnically, `Set`, `On` and `Off` are effects with a default period of 1ms, that\nset the brightness to a constant value. Specifying a different period has an\neffect on when the `Update()` method will be done updating the effect and\nreturn false (like for any other effects). This is important when for example\nin a `JLedSequence` the LED should stay on for a given amount of time.\n\n##### Static on example\n\n```c++\n#include \u003cjled.h\u003e\n\n// turn builtin LED on after 1 second.\nauto led = JLed(LED_BUILTIN).On().DelayBefore(1000);\n\nvoid setup() { }\n\nvoid loop() {\n  led.Update();\n}\n```\n\n#### Blinking\n\nIn blinking mode, the LED cycles through a given number of on-off cycles, on-\nand off-cycle durations are specified independently. The `Blink()` method takes\nthe duration for the on- and off cycle as arguments.\n\n##### Blinking example\n\n```c++\n#include \u003cjled.h\u003e\n\n// blink internal LED every second; 1 second on, 0.5 second off.\nauto led = JLed(LED_BUILTIN).Blink(1000, 500).Forever();\n\nvoid setup() { }\n\nvoid loop() {\n  led.Update();\n}\n```\n\n#### Breathing\n\nIn breathing mode, the LED smoothly changes the brightness using PWM. The\n`Breathe()` method takes the period of the effect as an argument.\n\n##### Breathing example\n\n```c++\n#include \u003cjled.h\u003e\n\n// connect LED to pin 13 (PWM capable). LED will breathe with period of\n// 2000ms and a delay of 1000ms after each period.\nauto led = JLed(13).Breathe(2000).DelayAfter(1000).Forever();\n\nvoid setup() { }\n\nvoid loop() {\n  led.Update();\n}\n```\n\nIt is also possible to specify fade-on, on- and fade-off durations for the\nbreathing mode to customize the effect.\n\n```c++\n// LED will fade-on in 500ms, stay on for 1000ms, and fade-off in 500ms.\n// It will delay for 1000ms afterwards and continue the pattern.\nauto led = JLed(13).Breathe(500, 1000, 500).DelayAfter(1000).Forever();\n```\n\n#### Candle\n\nIn candle mode, the random flickering of a candle or fire is simulated.\nThe builder method has the following signature:\n  `Candle(uint8_t speed, uint8_t jitter, uin16_t period)`\n\n* `speed` - controls the speed of the effect. 0 for fastest, increasing speed\n  divides into halve per increment. The default value is 7.\n* `jitter` - the amount of jittering. 0 none (constant on), 255 maximum. Default\n  value is 15.\n* `period` - Period of effect in ms.  The default value is 65535 ms.\n\nThe default settings simulate a candle. For a fire effect for example use\ncall the method with `Candle(5 /*speed*/, 100 /* jitter*/)`.\n\n##### Candle example\n\n```c++\n#include \u003cjled.h\u003e\n\n// Candle on LED pin 13 (PWM capable).\nauto led = JLed(13).Candle();\n\nvoid setup() { }\n\nvoid loop() {\n  led.Update();\n}\n```\n\n#### FadeOn\n\nIn FadeOn mode, the LED is smoothly faded on to 100% brightness using PWM. The\n`FadeOn()` method takes the period of the effect as an argument.\n\nThe brightness function uses an approximation of this function (example with\nperiod 1000):\n\n[![fadeon function](doc/fadeon_plot.png)](https://www.wolframalpha.com/input/?i=plot+(exp(sin((t-1000%2F2.)*PI%2F1000))-0.36787944)*108.0++t%3D0+to+1000)\n\n##### FadeOn example\n\n```c++\n#include \u003cjled.h\u003e\n\n// LED is connected to pin 9 (PWM capable) gpio\nauto led = JLed(9).FadeOn(1000).DelayBefore(2000);\n\nvoid setup() { }\n\nvoid loop() {\n  led.Update();\n}\n```\n\n#### FadeOff\n\nIn FadeOff mode, the LED is smoothly faded off using PWM. The fade starts at\n100% brightness. Internally it is implemented as a mirrored version of the\nFadeOn function, i.e., FadeOff(t) = FadeOn(period-t).  The `FadeOff()` method\ntakes the period of the effect as argument.\n\n#### Fade\n\nThe Fade effect allows to fade from any start value `from` to any target value\n`to` with the given duration. Internally it sets up a `FadeOn` or `FadeOff`\neffect and `MinBrightness` and `MaxBrightness` values properly. The `Fade`\nmethod take three arguments: `from`, `to` and `duration`.\n\n\u003ca href=\"examples/fade_from_to\"\u003e\u003cimg alt=\"fade from-to\" src=\"doc/fade_from-to.png\" height=200\u003e\u003c/a\u003e\n\n##### Fade example\n\n```c++\n#include \u003cjled.h\u003e\n\n// fade from 100 to 200 with period 1000\nauto led = JLed(9).Fade(100, 200, 1000);\n\nvoid setup() { }\n\nvoid loop() {\n  led.Update();\n}\n```\n\n#### User provided brightness function\n\nIt is also possible to provide a user defined brightness evaluator. The class\nmust be derived from the `jled::BrightnessEvaluator` class and implement\ntwo methods:\n\n* `uint8_t Eval(uint32_t t) const` - the brightness evaluation function that\n  calculates a brightness for the given time `t`. The brightness must be returned\n  as an unsigned byte, where 0 means LED off and 255 means full brightness.\n* `uint16_t Period() const` - period of the effect.\n\nAll time values are specified in milliseconds.\n\nThe [user_func](examples/user_func) example demonstrates a simple user provided\nbrightness function, while the [morse](examples/morse) example shows how a more\ncomplex application, allowing you to send morse codes (not necessarily with an\nLED), can be realized.\n\n##### User provided brightness function example\n\nThe example uses a user provided function to calculate the brightness.\n\n```c++\nclass UserEffect : public jled::BrightnessEvaluator {\n  public:\n    uint8_t Eval(uint32_t t) const override {\n        // this function changes between 0 and 255 and\n        // vice versa every 250 ms.\n        return 255*((t/250)%2);\n    }\n    // duration of effect: 5 seconds.\n    uint16_t Period() const override { return 5000; }\n};\n```\n\n#### Delays and repetitions\n\n##### Initial delay before effect starts\n\nUse the `DelayBefore()` method to specify a delay before the first effect starts.\nThe default value is 0 ms.\n\n##### Delay after effect finished\n\nUse the `DelayAfter()` method to specify a delay after each repetition of\nan effect. The default value is 0 ms.\n\n##### Repetitions\n\nUse the `Repeat()` method to specify the number of repetitions. The default\nvalue is 1 repetition. The `Forever()` methods sets to repeat the effect\nforever. Each repetition includes a full period of the effect and the time\nspecified by `DelayAfter()` method.\n\n#### State functions\n\n##### Update\n\nCall `Update(int16_t *pLast=nullptr)` or `Update(uint32_t t, int16_t *pLast=nullptr)`\nto periodically update the state of the LED.\n\n`Update` returns `true`, if the effect is active, or `false` when it finished.\n`Update()` is a shortcut to call `Update(uint32_t t)` with the current time in\nmilliseconds.\n\nTo obtain the value of the last written brightness value (after applying min-\nand max-brightness transformations), pass an additional optional pointer\n`*pLast` , where this value will be stored, when it was written. Example:\n\n```c++\nint16_t lastVal = -1;\nled.Update(\u0026lastVal);\nif (lastVal != -1) {\n    // the LED was updated with the brightness value now stored in lastVal\n    ...\n}\n```\n\nMost of the time just calling `Update()` without any parameters is what you want.\n\nSee [last_brightness](examples/last_brightness) example for a working example.\n\n##### IsRunning\n\n`IsRunning()` returns `true` if the current effect is running, else `false`.\n\n##### Reset\n\nA call to `Reset()` brings the JLed object to its initial state. Use it when\nyou want to start-over an effect.\n\n##### Immediate Stop\n\nCall `Stop()` to immediately turn the LED off and stop any running effects.\nFurther calls to `Update()` will have no effect, unless the Led is reset using\n`Reset()` or a new effect is activated. By default, `Stop()` sets the current\nbrightness level to `MinBrightness`.\n\n`Stop()` takes an optional argument `mode` of type `JLed::eStopMode`:\n\n* if set to `JLed::eStopMode::KEEP_CURRENT`, the LEDs current level will be kept\n* if set to `JLed::eStopMode::FULL_OFF` the level of the LED is set to `0`,\n  regardless of what `MinBrightness` is set to, effectively turning the LED off\n* if set to `JLed::eStopMode::TO_MIN_BRIGHTNESS` (default behavior), the LED\n  will set to the value of `MinBrightness`\n\n```c++\n// stop the effect and set the brightness level to 0, regardless of min brightness\nled.Stop(JLed::eStopMode::FULL_OFF);\n```\n\n#### Misc functions\n\n##### Low active for inverted output\n\nUse the `LowActive()` method when the connected LED is low active. All output\nwill be inverted by JLed (i.e., instead of x, the value of 255-x will be set).\n\n##### Minimum- and Maximum brightness level\n\nThe `MaxBrightness(uint8_t level)` method is used to set the maximum brightness\nlevel of the LED. A level of 255 (the default) is full brightness, while 0\neffectively turns the LED off. In the same way, the `MinBrightness(uint8_t level)`\nmethod sets the minimum brightness level. The default minimum level is 0. If\nminimum or maximum brightness levels are set, the output value is scaled to be\nwithin the interval defined by `[minimum brightness, maximum brightness]`: a\nvalue of 0 will be mapped to the minimum brightness level, a value of 255 will\nbe mapped to the maximum brightness level.\n\nThe `uint_8 MaxBrightness() const` method returns the current maximum\nbrightness level. `uint8_t MinBrightness() const` returns the current minimum\nbrightness level.\n\n### Controlling a group of LEDs\n\nThe `JLedSequence` class allows controlling a group of `JLed` objects\nsimultaneously, either in parallel or sequentially, starting the next `JLed`\neffect when the previous finished. The constructor takes the mode (`PARALLEL`,\n`SEQUENCE`), an array of `JLed` objects and the size of the array, e.g.\n\n```c++\nJLed leds[] = {\n    JLed(4).Blink(750, 250).Repeat(10),\n    JLed(3).Breathe(2000).Repeat(5);\n};\n\nauto sequence = JLedSequence(JLedSequence::eMode::PARALLEL, leds).Repeat(2);\n\nvoid setup() {\n}\n\nvoid loop() {\n    sequence.Update();\n}\n```\n\nBecause the size of the array is known at compile time in this example, it is\nnot necessary to pass the array size to the constructor. A second constructor\nis available in case the `JLed` array is created dynamically at runtime:\n`JLed(eMode mode, JLed* leds, size_t n)`.\n\nThe `JLedSequence` provides the following methods:\n* `Update()` - updates the active `JLed` objects controlled by the sequence.\n  Like the `JLed::Update()` method, it returns `true` if an effect is running,\n  else `false`.\n* Use the `Repeat(n)` method to specify the number of repetitions. The default\n  value is 1 repetition. The `Forever()` methods sets to repeat the sequence\n  forever.\n* `Stop()` - turns off all `JLed` objects controlled by the sequence and\n   stops the sequence. Further calls to `Update()` will have no effect.\n* `Reset()` - Resets all `JLed` objects controlled by the sequence and\n   the sequence, resulting in a start-over.\n\n## Framework notes\n\nJLed supports the Arduino and [mbed](https://www.mbed.org) frameworks. When\nusing platformio, the framework to be used is configured in the `platform.ini`\nfile, as shown in the following example, which for example selects the `mbed`\nframework:\n\n```ini\n[env:nucleo_f401re_mbed]\nplatform=ststm32\nboard = nucleo_f401re\nframework = mbed\nbuild_flags = -Isrc\nsrc_filter = +\u003c../../src/\u003e  +\u003c./\u003e\nupload_protocol=stlink\n```\n\nAn [mbed example is provided here](examples/multiled_mbed/multiled_mbed.cpp).\nTo compile it for the F401RE, make your [plaform.ini](platform.ini) look like:\n\n```ini\n...\n[platformio]\ndefault_envs = nucleo_f401re_mbed\nsrc_dir = examples/multiled_mbed\n...\n```\n\n## Platform notes\n\n### ESP8266\n\nThe DAC of the ESP8266 operates with 10 bits, every value JLed writes out gets\nautomatically scaled to 10 bits, since JLed internally only uses 8 bits.  The\nscaling methods make sure that min/max relationships are preserved, i.e., 0 is\nmapped to 0 and 255 is mapped to 1023. When using a user-defined brightness\nfunction on the ESP8266, 8-bit values must be returned, all scaling is done by\nJLed transparently for the application, yielding platform-independent code.\n\n### ESP32\n\nWhen compiling for the ESP32, JLed uses `ledc` functions provided by the ESP32\nESP-IDF SDK.  (See [esspressif\ndocumentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/ledc.html)\nfor details).\n\nThe `ledc` API connects so-called channels to GPIO pins, enabling them to use\nPWM. There are 16 channels available. Unless otherwise specified, JLed\nautomatically picks the next free channel, starting with channel 0 and wrapping\nover after channel 15. To manually specify a channel, the JLed object must be\nconstructed this way:\n\n```c++\nauto esp32Led = JLed(jled::Esp32Hal(2, 7)).Blink(1000, 1000).Forever();\n```\n\nThe `jled::Esp32Hal(pin, chan)` constructor takes the pin number as the first\nargument and the ESP32 ledc channel number on the second position. Note that\nusing the above-mentioned constructor results in non-platform independent code,\nso it should be avoided and is normally not necessary.\n\nFor completeness, the full signature of the Esp32Hal constructor is\n\n```\nEsp32Hal(PinType pin,\n         int chan = kAutoSelectChan,\n         uint16_t freq = 5000,\n         ledc_timer_t timer = LEDC_TIMER_0)\n```\n\nwhich also allows to override the default frequency and timer used, when needed.\n\n#### Using ESP-IDF\n\nSince JLed uses the ESP-IDF SDK, JLed can also be directly used in ESP-IDF\nprojects, without the need of using the Arduino Framework (which is also\npossible). See these repositories for example projects:\n\n* https://github.com/jandelgado/jled-esp-idf-example\n* https://github.com/jandelgado/jled-esp-idf-platformio-example\n\n### STM32\n\n#### Arduino framework\n\nI had success running JLed on a [STM32 Nucleo64 F401RE\nboard](https://www.st.com/en/evaluation-tools/nucleo-f401re.html) using this\n[STM32 Arduino\ncore](https://github.com/rogerclarkmelbourne/Arduino_STM32/tree/master/STM32F4)\nand compiling examples from the Arduino IDE. Note that the `stlink` is\nnecessary to upload sketches to the microcontroller.\n\n### Raspberry Pi Pico\n\nWhen using JLed on a Raspberry Pi Pico, the Pico-SDK and tools can be\nused.  The Pico supports up to 16 PWM channels in parallel. See\nthe [pico-demo](examples/raspi_pico) for an example and build instructions when\nthe Pico-SDK is used.\n\nA probably easier approach is to use the Arduino platform. See\n[platformio.ini](platformio.ini) for details (look for\n`env:raspberrypi_pico_w`, which targets the Raspberry Pi Pico W.\n\n## Example sketches\n\nExample sketches are provided in the [examples](examples/) directory.\n\n* [Hello, world](examples/hello)\n* [Turn LED on after a delay](examples/simple_on)\n* [Breathe effect](examples/breathe)\n* [Candle effect](examples/candle)\n* [Fade LED on](examples/fade_on)\n* [Fade LED off](examples/fade_off)\n* [Fade from-to effect](examples/fade_from_to)\n* [Pulse effect](examples/pulse)\n* [Controlling multiple LEDs in parallel](examples/multiled)\n* [Controlling multiple LEDs in parallel (mbed)](examples/multiled_mbed)\n* [Controlling multiple LEDs sequentially](examples/sequence)\n* [Simple User provided effect](examples/user_func)\n* [Morsecode example](examples/morse)\n* [Last brightness value example](examples/last_brightness)\n* [Custom HAL example](examples/custom_hal)\n* [Custom PCA9685 HAL](https://github.com/jandelgado/jled-pca9685-hal)\n* [Dynamically switch sequences](https://github.com/jandelgado/jled-example-switch-sequence)\n* [JLed compiled to WASM and running in the browser](https://jandelgado.github.io/jled-wasm)\n* [Raspberry Pi Pico Demo](examples/raspi_pico)\n* [ESP32 ESP-IDF example](https://github.com/jandelgado/jled-esp-idf-example)\n* [ESP32 ESP-IDF PlatformIO example](https://github.com/jandelgado/jled-esp-idf-platformio-example)\n\n### Building examples with PlatformIO\n\nTo build an example using [the PlatformIO ide](http://platformio.org/),\nuncomment the example to be built in the [platformio.ini](platformio.ini)\nproject file, e.g.:\n\n```ini\n[platformio]\n; uncomment example to build\nsrc_dir = examples/hello\n;src_dir = examples/breathe\n```\n\n### Building examples with the Arduino IDE\n\nTo build an example sketch in the Arduino IDE, select an example from\nthe `File` \u003e `Examples` \u003e `JLed` menu.\n\n## Extending\n\n### Support new hardware\n\nJLed uses a very thin hardware abstraction layer (hal) to abstract access to\nthe actual MCU/framework used (e.g. ESP32, ESP8266). The hal object encapsulate\naccess to the GPIO and time functionality of the MCU under the framework being\nused.  During the unit test, mocked hal instances are used, enabling tests to\ncheck the generated output.  The [Custom HAL project](examples/custom_hal)\nprovides an example for a user define HAL.\n\n## Unit tests\n\nJLed comes with an exhaustive host-based unit test suite. Info on how to run\nthe host-based provided unit tests [is provided here](test/README.md).\n\n## Contributing\n\n* fork this repository\n* create your feature branch\n* add code\n* add [unit test(s)](test/)\n* add [documentation](README.md)\n* make sure the cpp [linter](https://github.com/cpplint/cpplint) does not\n  report any problems (run `make lint`). Hint: use `clang-format` with the\n  provided [settings](.clang-format)\n* commit changes\n* submit a PR\n\n## FAQ\n\n### How do I check if a JLed object is still being updated?\n\n* Check the return value of the `JLed::Update` method: the method returns `true` if\n  the effect is still running, otherwise `false`.\n* The `JLed::IsRunning` method returns `true` if an effect is running, else `false`.\n\n### How do I restart an effect?\n\nCall `Reset()` on a `JLed` object to start over.\n\n### How do I change a running effect?\n\nJust 'reconfigure' the `JLed` with any of the effect methods (e.g. `FadeOn`,\n`Breathe`, `Blink` etc). Time-wise, the effect will start over.\n\n## Author and Copyright\n\nCopyright 2017-2022 by Jan Delgado, jdelgado[at]gmx.net.\n\n## License\n\n[MIT](LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjandelgado%2Fjled","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjandelgado%2Fjled","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjandelgado%2Fjled/lists"}