Skip to content

Commit

Permalink
Merge pull request #183 from Legion2/dev
Browse files Browse the repository at this point in the history
Version 0.14.2
  • Loading branch information
Legion2 authored Sep 8, 2020
2 parents bb45884 + 46d70a9 commit ca41ced
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 106 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Check src format
uses: DoozyX/clang-format-lint-action@v0.8
uses: DoozyX/clang-format-lint-action@v0.9
with:
source: './src'
extensions: 'h,cpp'
clangFormatVersion: 9
- name: Check examples format
uses: DoozyX/clang-format-lint-action@v0.8
uses: DoozyX/clang-format-lint-action@v0.9
with:
source: './examples'
extensions: 'h,cpp,ino'
Expand Down
27 changes: 18 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ _This is not an official corsair project._
## Features
* Add support of Corsair DIY device protocol to Arduino.
* Control LEDs with the [Corsair iCUE software](https://www.corsair.com/icue).
* Easy to use with [FastLED](http://fastled.io/).
* [Supported LED chipsets](https://github.com/FastLED/FastLED/wiki/Overview#chipsets). (e.g. WS2812B, WS2801)
* [Support common LED chipsets](https://github.com/FastLED/FastLED/wiki/Overview#chipsets). (e.g. WS2812B, WS2801)
* Support [FastLED](http://fastled.io/).
* Supported platform: Arduino AVR
* Persistent settings for use without a USB connection.
* Hardware Lighting mode.
* Use multiple devices at the same time.
* Repeat or scale LED channels to arbitrary size.

Expand Down Expand Up @@ -91,7 +91,9 @@ Now you can create lighting effects in the "Lighting Channel #" tabs.
- [API Documentation](https://legion2.github.io/CorsairLightingProtocol/)
- [How it works](#how-it-works)
- [Use of multiple devices](#use-of-multiple-devices)
- [Repeat or scale LED channel](#repeat-or-scale-led-channel)
- [Repeat or scale LED channels](#repeat-or-scale-led-channels)
- [Increase the Brightness of the LEDs](#increase-the-brightness-of-the-leds)
- [Hardware Lighting mode](#hardware-lighting-mode)

## How it works
This library uses the USB HID interface of the ATmega32U4.
Expand Down Expand Up @@ -128,10 +130,9 @@ Upload the DeviceIDTool sketch and then open the Serial monitor with baudrate 11
The tool displays the current DeviceID, you can type in a new DeviceID that is saved on the Arduino.
After that, you can upload another sketch.

## Repeat or scale LED channel
## Repeat or scale LED channels
You can repeat or scale LED channel controlled by iCUE onto physical LED strips.
This is very useful if you have very long LED strips that are longer than 60/96/135 LEDs.
This is the maximum number iCUE supports.
This is very useful if you have very long LED strips that are longer than 60/96/135 LEDs, which is the maximum number iCUE supports.

To repeat or scale a LED channel you must apply the `CLP::repeat` or the `CLP:scale` function in the update hook of the FastLEDController.
See the [RepeatAndScale](examples/RepeatAndScale/RepeatAndScale.ino) example for the complete code.
Expand All @@ -146,16 +147,24 @@ For both functions it's **important**, that the CRGB arrays have at least the le
This means if your LED channel from iCUE has 50 LEDs and you use the `repeat` function to control 100 physical LEDs you MUST declare the CRGB array at least with a length of 100.

## Increase the Brightness of the LEDs
By default iCUE only uses 50% of the LEDs brightness even if you set the brightness to max in the iCUE Device Settings.
When using LS100 or LT100 iCUE only uses 50% of the LEDs brightness even if you set the brightness to max in the iCUE Device Settings.
But there are good news, we can increase the brightness with the Arduino so we can use the full brightness of our LEDs.
Add the `CLP::fixIcueBrightness` function to the `onUpdateHook` in the setup function as shown in the [example](examples/AdditionalFeatures/AdditionalFeatures.ino).
Add the `CLP::fixIcueBrightness` function to the `onUpdateHook` in the setup function as shown in the [example](examples/AmbientBacklight/AmbientBacklight.ino).
If there are multiple functions called in `onUpdateHook`, `fixIcueBrightness` should be the first.
Only use this function with LS100 and LT100 devices!
```C++
ledController.onUpdateHook(0, []() {
CLP::fixIcueBrightness(&ledController, 0);
});
```

## Hardware Lighting mode
The [Hardware Lighting mode](https://forum.corsair.com/v3/showthread.php?t=182874) can be configured in iCUE.
It allows you the set lighting effects that will be active when iCUE **is not** running.
This is the case when the PC is off, in sleep mode, booting or the user is logged out.
So if you want to have lighing effects in all these situations, use the Hardware Lighting mode.
If you don't want it, configure a static black color.

# License
This project is licensed under the Apache 2.0 License.

Expand Down
7 changes: 1 addition & 6 deletions examples/AdditionalFeatures/AdditionalFeatures.ino
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,13 @@ void setup() {
FastLED.addLeds<WS2812B, DATA_PIN_CHANNEL_2, GRB>(ledsChannel2, 60);
ledController.addLEDs(0, ledsChannel1, 60);
ledController.addLEDs(1, ledsChannel2, 60);

// modify the RGB values before they are shown on the LED strip
ledController.onUpdateHook(0, []() {
// increase the brightness of channel 1 when using iCUE, because iCUE only set brightness to max 50%
CLP::fixIcueBrightness(&ledController, 0);
});
}

void loop() {
cHID.update();

if (ledController.updateLEDs()) {
FastLED.show();
CLP::printFps(5000);
}
}
2 changes: 2 additions & 0 deletions examples/AmbientBacklight/AmbientBacklight.ino
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ void setup() {
ledController.addLEDs(0, ledsChannel1, 84);
ledController.addLEDs(1, ledsChannel2, 105);
ledController.onUpdateHook(0, []() {
// increase the brightness of channel 1 when using iCUE, because iCUE only set brightness to max 50%
CLP::fixIcueBrightness(&ledController, 0);
// gamma correction with gamma value 2.0. Use napplyGamma_video for other gamma values.
CLP::gammaCorrection(&ledController, 0);
// napplyGamma_video(ledsChannel1, 84, 2.2);
Expand Down
1 change: 1 addition & 0 deletions examples/DebugSketch/DebugSketch.ino
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ void loop() {
if (ledController.updateLEDs()) {
if (printUpdate) Serial.println(F("updateLEDs"));
FastLED.show();
CLP::printFps(5000);
}

if (Serial.available()) {
Expand Down
162 changes: 89 additions & 73 deletions examples/UnitTests/UnitTests.ino
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ protected:
assertEqual(actual.g, expected.g);
assertEqual(actual.b, expected.b);
}
void assertCRGBArray(const CRGB* const leds, int from, int to, const CRGB& expected) {
for (int i = from; i <= to; i++) {
assertCRGB(leds[i], expected);
}
}
};

test(getLEDs) {
Expand All @@ -47,9 +52,7 @@ testF(FastLEDControllerTest, simpleScaleUp) {
fill_solid(leds, 10, CRGB::White);
CLP::scale(&ledController, 0, 20);

for (int i = 0; i < 10; i++) {
assertCRGB(leds[i], CRGB::White);
}
assertCRGBArray(leds, 0, 9, CRGB::White);
}

testF(FastLEDControllerTest, simpleScaleDown) {
Expand All @@ -61,12 +64,23 @@ testF(FastLEDControllerTest, simpleScaleDown) {
fill_solid(leds, 10, CRGB::White);
CLP::scale(&ledController, 0, 10);

for (int i = 0; i < 5; i++) {
assertCRGB(leds[i], CRGB::White);
}
for (int i = 5; i < 10; i++) {
assertCRGB(leds[i], CRGB::Black);
}
assertCRGBArray(leds, 0, 4, CRGB::White);
assertCRGBArray(leds, 5, 9, CRGB::Black);
}

testF(FastLEDControllerTest, simpleScaleDownBoundaries) {
CRGB leds[20];
FastLEDController ledController(false);
fill_solid(leds, 20, CRGB::Black);
ledController.addLEDs(0, leds, 20);

leds[0] = CRGB::White;
leds[19] = CRGB::Red;
CLP::scale(&ledController, 0, 5);

assertCRGBArray(leds, 0, 0, CRGB::White);
assertCRGBArray(leds, 1, 3, CRGB::Black);
assertCRGBArray(leds, 4, 4, CRGB::Red);
}

testF(FastLEDControllerTest, simpleScaleIdentity) {
Expand All @@ -78,12 +92,20 @@ testF(FastLEDControllerTest, simpleScaleIdentity) {
fill_solid(leds, 10, CRGB::White);
CLP::scale(&ledController, 0, 10);

for (int i = 0; i < 10; i++) {
assertCRGB(leds[i], CRGB::White);
}
for (int i = 10; i < 20; i++) {
assertCRGB(leds[i], CRGB::Black);
}
assertCRGBArray(leds, 0, 9, CRGB::White);
assertCRGBArray(leds, 10, 19, CRGB::Black);
}

testF(FastLEDControllerTest, scaleLongStrip) {
CRGB leds[41];
FastLEDController ledController(false);
fill_solid(leds, 41, CRGB::Black);
ledController.addLEDs(0, leds, 27);

fill_solid(leds, 27, CRGB::White);
CLP::scale(&ledController, 0, 41);

assertCRGBArray(leds, 0, 40, CRGB::White);
}

testF(FastLEDControllerTest, LT100) {
Expand All @@ -97,27 +119,21 @@ testF(FastLEDControllerTest, LT100) {
CLP::SegmentScaling segments[2] = {{1, 4}, {26, 26}};
CLP::scaleSegments(&ledController, 0, segments, 2);

for (int i = 0; i < 4; i++) {
assertCRGB(leds[i], CRGB::White);
}
for (int i = 4; i < 30; i++) {
assertCRGB(leds[i], CRGB::Blue);
}
assertCRGBArray(leds, 0, 3, CRGB::White);
assertCRGBArray(leds, 4, 29, CRGB::Blue);
}

testF(FastLEDControllerTest, singleSegmentScaleUp) {
CRGB leds[20];
FastLEDController ledController(false);
fill_solid(leds, 20, CRGB::Black);
ledController.addLEDs(0, leds, 20);
ledController.addLEDs(0, leds, 10);

fill_solid(leds, 10, CRGB::White);
CLP::SegmentScaling segments[] = {{10, 20}};
CLP::scaleSegments(&ledController, 0, segments, 1);

for (int i = 0; i < 20; i++) {
assertCRGB(leds[i], CRGB::White);
}
assertCRGBArray(leds, 0, 19, CRGB::White);
}

testF(FastLEDControllerTest, multiScaleUp) {
Expand All @@ -130,12 +146,8 @@ testF(FastLEDControllerTest, multiScaleUp) {
CLP::SegmentScaling segments[] = {{5, 10}, {5, 20}};
CLP::scaleSegments(&ledController, 0, segments, 2);

for (int i = 0; i < 10; i++) {
assertCRGB(leds[i], CRGB::Black);
}
for (int i = 10; i < 30; i++) {
assertCRGB(leds[i], CRGB::White);
}
assertCRGBArray(leds, 0, 9, CRGB::Black);
assertCRGBArray(leds, 10, 29, CRGB::White);
}

testF(FastLEDControllerTest, multiScaleDown) {
Expand All @@ -148,12 +160,8 @@ testF(FastLEDControllerTest, multiScaleDown) {
CLP::SegmentScaling segments[] = {{10, 5}, {20, 5}};
CLP::scaleSegments(&ledController, 0, segments, 2);

for (int i = 0; i < 5; i++) {
assertCRGB(leds[i], CRGB::Black);
}
for (int i = 5; i < 10; i++) {
assertCRGB(leds[i], CRGB::White);
}
assertCRGBArray(leds, 0, 4, CRGB::Black);
assertCRGBArray(leds, 5, 9, CRGB::White);
}

testF(FastLEDControllerTest, singleSegmentScaleDown) {
Expand All @@ -166,12 +174,8 @@ testF(FastLEDControllerTest, singleSegmentScaleDown) {
CLP::SegmentScaling segments[] = {{20, 10}};
CLP::scaleSegments(&ledController, 0, segments, 1);

for (int i = 0; i < 5; i++) {
assertCRGB(leds[i], CRGB::White);
}
for (int i = 5; i < 10; i++) {
assertCRGB(leds[i], CRGB::Black);
}
assertCRGBArray(leds, 0, 4, CRGB::White);
assertCRGBArray(leds, 5, 9, CRGB::Black);
}

testF(FastLEDControllerTest, SegmentScaleOverlap) {
Expand All @@ -184,12 +188,8 @@ testF(FastLEDControllerTest, SegmentScaleOverlap) {
CLP::SegmentScaling segments[] = {{5, 10}, {10, 5}};
CLP::scaleSegments(&ledController, 0, segments, 2);

for (int i = 0; i < 10; i++) {
assertCRGB(leds[i], CRGB::White);
}
for (int i = 10; i < 15; i++) {
assertCRGB(leds[i], CRGB::Black);
}
assertCRGBArray(leds, 0, 9, CRGB::White);
assertCRGBArray(leds, 10, 14, CRGB::Black);
}

testF(FastLEDControllerTest, SegmentScaleOverlapInverted) {
Expand All @@ -202,12 +202,8 @@ testF(FastLEDControllerTest, SegmentScaleOverlapInverted) {
CLP::SegmentScaling segments[] = {{10, 5}, {5, 10}};
CLP::scaleSegments(&ledController, 0, segments, 2);

for (int i = 0; i < 5; i++) {
assertCRGB(leds[i], CRGB::White);
}
for (int i = 5; i < 15; i++) {
assertCRGB(leds[i], CRGB::Black);
}
assertCRGBArray(leds, 0, 4, CRGB::White);
assertCRGBArray(leds, 5, 14, CRGB::Black);
}

testF(FastLEDControllerTest, SegmentScaleMix) {
Expand All @@ -222,15 +218,9 @@ testF(FastLEDControllerTest, SegmentScaleMix) {
CLP::SegmentScaling segments[] = {{5, 10}, {20, 5}, {5, 10}};
CLP::scaleSegments(&ledController, 0, segments, 3);

for (int i = 0; i < 10; i++) {
assertCRGB(leds[i], CRGB::White);
}
for (int i = 10; i < 15; i++) {
assertCRGB(leds[i], CRGB::Red);
}
for (int i = 15; i < 25; i++) {
assertCRGB(leds[i], CRGB::Blue);
}
assertCRGBArray(leds, 0, 9, CRGB::White);
assertCRGBArray(leds, 10, 14, CRGB::Red);
assertCRGBArray(leds, 15, 24, CRGB::Blue);
}

testF(FastLEDControllerTest, SegmentScaleMixInverted) {
Expand All @@ -245,15 +235,41 @@ testF(FastLEDControllerTest, SegmentScaleMixInverted) {
CLP::SegmentScaling segments[] = {{10, 5}, {5, 20}, {10, 5}};
CLP::scaleSegments(&ledController, 0, segments, 3);

for (int i = 0; i < 5; i++) {
assertCRGB(leds[i], CRGB::White);
}
for (int i = 5; i < 25; i++) {
assertCRGB(leds[i], CRGB::Red);
}
for (int i = 25; i < 30; i++) {
assertCRGB(leds[i], CRGB::Blue);
}
assertCRGBArray(leds, 0, 4, CRGB::White);
assertCRGBArray(leds, 5, 24, CRGB::Red);
assertCRGBArray(leds, 25, 29, CRGB::Blue);
}

testF(FastLEDControllerTest, SegmentScaleMonitor) {
CRGB leds[130];
FastLEDController ledController(false);
fill_solid(leds, 130, CRGB::Black);
ledController.addLEDs(0, leds, 84);

fill_solid(leds, 15, CRGB::White);
fill_solid(leds + 15, 27, CRGB::Red);
fill_solid(leds + 42, 15, CRGB::Blue);
fill_solid(leds + 57, 27, CRGB::Green);
CLP::SegmentScaling segments[] = {{15, 24}, {27, 41}, {15, 24}, {27, 41}};
CLP::scaleSegments(&ledController, 0, segments, 4);

assertCRGBArray(leds, 0, 23, CRGB::White);
assertCRGBArray(leds, 24, 64, CRGB::Red);
assertCRGBArray(leds, 65, 88, CRGB::Blue);
assertCRGBArray(leds, 89, 129, CRGB::Green);
}

testF(FastLEDControllerTest, SegmentScaleLongStrip) {
CRGB leds[41];
FastLEDController ledController(false);
fill_solid(leds, 41, CRGB::Black);
ledController.addLEDs(0, leds, 27);

fill_solid(leds, 27, CRGB::White);
CLP::SegmentScaling segments[] = {{27, 41}};
CLP::scaleSegments(&ledController, 0, segments, 1);

assertCRGBArray(leds, 0, 40, CRGB::White);
}

void setup() {
Expand Down
2 changes: 1 addition & 1 deletion extra/doxygen.conf
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ PROJECT_NAME = "Corsair Lighting Protocol"
# could be handy for archiving the generated documentation or if some version
# control system is used.

PROJECT_NUMBER = 0.14.1
PROJECT_NUMBER = 0.14.2

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=Corsair Lighting Protocol
version=0.14.1
version=0.14.2
author=Leon Kiefer
maintainer=Leon Kiefer
sentence=Control LED strips via USB from a PC.
Expand Down
Loading

0 comments on commit ca41ced

Please sign in to comment.