Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added individual led brightness option to led strip #73

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

plattysoft
Copy link

Added a new utility method that can receive an integer array of brightness.

It is backwards compatible, if individual brightness is set, the maximum brightness is returned for getBrighness()

Copy link
Member

@jdkoren jdkoren left a comment

Choose a reason for hiding this comment

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

I have two main concerns:

  1. Should global brightness and individual brightness be completely separated, and the driver uses whichever approach was last elected?
  2. Issues around the length of the individual brightness values array.

@@ -162,14 +171,35 @@ public void setBrightness(int ledBrightness) {
throw new IllegalArgumentException("Brightness needs to be between 0 and "
+ MAX_BRIGHTNESS);
}
mLedBrightness = ledBrightness;
mLedBrightnessGlobal = ledBrightness;
for (int i=0; i<mLedBrightness.length; i++) {
Copy link
Member

Choose a reason for hiding this comment

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

I would say use Arrays.fill here, but see the comment about keeping global brightness and individual brightness separate.

final Direction currentDirection = mDirection; // Avoids reading changes of mDirection during loop
for (int i = 0; i < colors.length; i++) {
byte brightness = (byte) (0xE0 | mLedBrightness[i]); // Less brightness possible
Copy link
Member

Choose a reason for hiding this comment

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

This line will throw index out of bounds exception if colors.length is larger than mBrightness.length. We would need to decide how to handle this (fallback to some value? throw an exception?).

Copy link
Author

Choose a reason for hiding this comment

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

in this case I think an Index out of bounds exception is fine (after the changes). The developer is passing two arrays, one for brightness and one for colors, both should be of the same length.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure throwing an exception is the best option. This method previously could never throw that exception, so ideally we wouldn't change that behavior. (Even if we do decide to throw, we should be the ones throwing it so that we can provide an appropriate message.)

One alternative, for example, would be to repeat the final brightness value.

Copy link
Author

Choose a reason for hiding this comment

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

I'm more in favor of returning an exception of the length of the arrays is different, so it does not behave unexpectedly, will implement that later.

Copy link
Author

Choose a reason for hiding this comment

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

so, @jdkoren I think this is good now, right?

@@ -67,7 +67,16 @@
private Mode mLedMode;

// RGB LED strip settings that have sensible defaults.
private int mLedBrightness = MAX_BRIGHTNESS >> 1; // default to half
private int mLedBrightnessGlobal = MAX_BRIGHTNESS/2;
private int mLedBrightness[] = new int[] {
Copy link
Member

Choose a reason for hiding this comment

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

This array has 7 elements, is it because the RainbowHAT has 7 LEDs? I don't think it's good to assume that users of this driver are also using the RainbowHAT or that they have a certain number of LEDs connected.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1
For example, the ReSpeaker 2-Mic Hat has Apa102 LEDs but only three of them.

Copy link
Author

Choose a reason for hiding this comment

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

Good point. I was thinking only of the one on the Rainbow HAT. I'll change it to behave in the same way as the values.

*/
public int getBrightness() {
return mLedBrightness;
return mLedBrightnessGlobal;
Copy link
Member

Choose a reason for hiding this comment

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

I don't like that we can only provide one value here. To me it makes better sense to add a int getBrightness(int index) (or a int[] getBrightnessArray()), which then makes me think we should not try to have global brightness and individual brightness be synchronized at all: either the user uses global brightness, or the user uses individual brightness. (Assuming that's the way forward, we could use the global brightness by default.)

Copy link
Author

Choose a reason for hiding this comment

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

yes, we can return an array of int, then we can be consistent about returning the array of brightness as it is or null if only global brightness is set. I do think that keeping them in sync makes sense as long as the logic is clear. Also, I agree. I do not expect a developer to mix them on the same project.
Will do some changes later today.

@@ -67,7 +67,16 @@
private Mode mLedMode;

// RGB LED strip settings that have sensible defaults.
private int mLedBrightness = MAX_BRIGHTNESS >> 1; // default to half
private int mLedBrightnessGlobal = MAX_BRIGHTNESS/2;
Copy link
Member

@jdkoren jdkoren Sep 18, 2017

Choose a reason for hiding this comment

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

nit: This was changed to division, while the ones below are still using shift. Perhaps revert this line?

@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for the commit author(s). If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again.

@plattysoft
Copy link
Author

updated mail preferences

@googlebot
Copy link

CLAs look good, thanks!

@@ -67,7 +67,8 @@
private Mode mLedMode;

// RGB LED strip settings that have sensible defaults.
private int mLedBrightness = MAX_BRIGHTNESS >> 1; // default to half
private int mLedBrightnessGlobal = MAX_BRIGHTNESS >> 1; // Default to half
private int mLedBrightness[];
Copy link
Contributor

Choose a reason for hiding this comment

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

best practice dictates to put the array initialiser on the field type, so you can easily see the difference between a single int and an int array.

private int[] mLedBrightness;

Copy link
Author

Choose a reason for hiding this comment

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

good point, thanks!

@@ -162,13 +163,33 @@ public void setBrightness(int ledBrightness) {
throw new IllegalArgumentException("Brightness needs to be between 0 and "
+ MAX_BRIGHTNESS);
}
mLedBrightness = ledBrightness;
mLedBrightnessGlobal = ledBrightness;
mLedBrightness = null;
Copy link
Contributor

Choose a reason for hiding this comment

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

why do you make it null? (issues later that you have to null check) Can you just make an empty array / clear it?

Copy link
Author

Choose a reason for hiding this comment

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

I make it null to invalidate it, so when the user calls write later, the global value is used instead. This is to allow switching from individual brightness to global brightness.
I am open to do it in any other way, I just thought this one was the simpler one.

Copy link
Contributor

Choose a reason for hiding this comment

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

you could fill the array with the global brightness instead of relying on null to say that there is no individual brightness (Connascence of Values)

Copy link
Author

Choose a reason for hiding this comment

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

but the original request for change suggested by jdkoren was to keep them separated.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's not my repo, so it was just a suggestion 👍 I'd go with the mod's advice ;-)

return mLedBrightnessGlobal;
}

public int[] getIndividualBrightness() {
return mLedBrightness;
Copy link
Contributor

Choose a reason for hiding this comment

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

this can now return null, you could use @Nullable

Copy link
Author

Choose a reason for hiding this comment

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

good point, thanks!

@plattysoft
Copy link
Author

Hey @jdkoren I did the changes you requested almost a week ago, please comment if you require more changes, approve this PR or discard it.

@proppy
Copy link
Contributor

proppy commented Sep 28, 2017

Did we consider (ab)using the android.graphics.Color alpha channel as a brightness indicator?

@plattysoft
Copy link
Author

plattysoft commented Sep 28, 2017

@proppy the original idea was to keep backwards compatibility. The simplest way to keep the backwards compatibility was to add a brightness array, but the idea of using the alpha channel is very interesting.

jdkoren
jdkoren previously requested changes Oct 6, 2017
Copy link
Member

@jdkoren jdkoren left a comment

Choose a reason for hiding this comment

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

Can we add unit tests for setIndividualBrightness (the values are being returned by getIndividualBrightness) and for the new ways write can behave?

@proppy
Copy link
Contributor

proppy commented Oct 6, 2017

@plattysoft @jdkoren I don't think it would break backward compatibility since currently the alpha channel is ignored (this would only affect people who used the driver with Color integer that had a brightness component).

@jdkoren
Copy link
Member

jdkoren commented Oct 6, 2017

@proppy I actually like the idea, it would remove the need for both setBrightness and setIndividualBrightness, and there would be no concerns about mismatched array lengths. I think the backwards compatibility issue is this:

Suppose my code calls write({ 0x00ff0000, 0xffff0000 });. Both LEDs would light up red, with the same brightness. Let's presume I'm using the default brightness of MAX_BRIGHTNESS >> 1.
Using the alpha channel for brightness, this call now behaves differently than before in 2 ways: The two LEDs are no longer the same, and neither would be at the default brightness. (The first would be off, the second would be on at full brightness.)

It's worth exploring, but we would need to communicate this change to developers and also make sure our samples are updated accordingly.

@Fleker
Copy link
Contributor

Fleker commented Oct 6, 2017

If we move to using the alpha value of Color, should we deprecate setBrightness? That would help communicate the definitive way to change the brightness.

We'd keep the method for now but explain why it's being deprecated.

@jdkoren
Copy link
Member

jdkoren commented Oct 6, 2017

@Fleker Yes, we would deprecate it.

@plattysoft
Copy link
Author

So, should I move on to just add the tests, or should we discard this approach and move towards the alpha channel? I'm happy to do it either way, just looking for a confirmation @jdkoren

@mangini
Copy link
Contributor

mangini commented Dec 19, 2017

I like using alpha for individual brightness. To maintain backwards compatibility, instead of deprecating setBrightness, I suggest the following changes:

  • if globalBrightness is set (0-255), individual colors' alpha are ignored and globalBrightness is used for all LED's instead
  • if globalBrightness is UNSET (e.g., -1), individual colors' alpha are used
  • if setBrightness is called with a UNSET value (-1), it is unset

So, the following changes would be required:

  • describe this behavior in javadoc
  • rename mLedBrighness and ledBrightness to mGlobalBrightness and globalBrightness
  • create a private GLOBAL_BRIGHTNESS_UNSET=-1 constant
  • create a unsetBrightness() public method (ideally should be called unsetGlobalBrightness, but it's better to keep parity with the existing setter/getter methods)
  • change write behavior to use color<<24 for alpha if mGlobalBrightness is UNSET

@mangini mangini dismissed jdkoren’s stale review December 19, 2017 23:23

Assuming Color transparency is used, these specific change requests are moot - although the new code will still need tests.

@mangini mangini self-requested a review December 19, 2017 23:25
Copy link
Contributor

@mangini mangini left a comment

Choose a reason for hiding this comment

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

Adding my comment as a review now:

I like using alpha for individual brightness. To maintain backwards compatibility, instead of deprecating setBrightness, I suggest the following changes:

  • if globalBrightness is set (0-255), individual colors' alpha are ignored and globalBrightness is used for all LED's instead
  • if globalBrightness is UNSET (e.g., -1), individual colors' alpha are used
  • if setBrightness is called with a UNSET value (-1), it is unset

So, the following changes would be required:

  • describe this behavior in javadoc
  • rename mLedBrighness and ledBrightness to mGlobalBrightness and globalBrightness
  • create a private GLOBAL_BRIGHTNESS_UNSET=-1 constant
  • create a unsetBrightness() public method (ideally should be called unsetGlobalBrightness, but it's better to keep parity with the existing setter/getter methods)
  • change write behavior to use color<<24 for alpha if mGlobalBrightness is UNSET

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.

7 participants