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

RGB emergency - Add support for RGB channel, and use button long press to toggle effect #13

Closed
wants to merge 3 commits into from

Conversation

tyeth
Copy link

@tyeth tyeth commented Nov 13, 2024

I've only got RGB LEDs 🎨 so this adds support for those, along with an orange hazard light mode if the boot button is long pressed rather than clicked.

The onboard RGB LED is also active so that's a nice touch (it's a lovely board - tinyfxw).

Maybe this is over the top, let me know, but it also serves as a useful example.

Also please do feel free to find a better orange, I randomly picked using browser dev tools and was totally unhappy with the result so starting abusing the rgb values 🤓

Note to self:
Next I need to look at understanding the sequence functions better (checkout flashing(0)), or adding an easier way of having flashing RGB FX functions

I've only got RGB LEDs 🎨 
It was also an exercise in understanding how to do multi colour flash. Next I need to look at using the sequences, or adding a flashing RGB FX function
@tyeth
Copy link
Author

tyeth commented Nov 14, 2024

Having played a bit more, it appears that replacing the effects property has not stopped the hazard effect correctly. Not got time to poke at it now, will revisit, but should probably pop instead.
What's strangest is that having gone to orange mode and back it's gone a bit bonkers, even after a reset (still got usb attached) it's doing blue orange (with ocasional red) instead of blue red.
Breaking to repl with boot button does then allow blue red on reset, but it eventually descends into blue orange with blue red orange sometimes. Like one of the effects (orange) will never die 😁

@tyeth
Copy link
Author

tyeth commented Nov 14, 2024

https://youtu.be/xP5sYRU8vQA for a display of the behaviour. I swear when I first ran it there was a simple red/blue flash then after button held it went slow orange flash, and back to blue/red when button held again. Tested a few times. Since then two days have elapsed, one more random plugging in, and then moved upstairs to final spot for a bit of in-view testing. I'll check that I didn't refactor something on the device before raising an issue

@ZodiusInfuser ZodiusInfuser self-requested a review November 15, 2024 10:24
@ZodiusInfuser
Copy link
Member

Hi @tyeth, Thank you for this example! It's quite a nice addition to the simple rescue_vehicle.py I wrote.

Maybe this is over the top, let me know, but it also serves as a useful example.

It's not over the top but it would perhaps be better to submit it as a standalone example, rather than modify the existing one, so others may also benefit from having the same starting point as you in the future. sea_rescue_vehicle.py perhaps?

I'll submit some specific code comments after this.

Also please do feel free to find a better orange, I randomly picked using browser dev tools and was totally unhappy with the result so starting abusing the rgb values 🤓

I only tested with the onboard LED, but (255, 32, 0) looked pretty orange to me. Having that last component be zero is key as that's the blue channel, which orange is famous for not having any of 😆

Next I need to look at understanding the sequence functions better (checkout flashing(0)), or adding an easier way of having flashing RGB FX functions

This could perhaps be solved by a dedicated RGBFlashingFX 🤔

https://youtu.be/xP5sYRU8vQA for a display of the behaviour. I swear when I first ran it there was a simple red/blue flash then after button held it went slow orange flash, and back to blue/red when button held again. Tested a few times.

Thanks for that video. I am really not sure what is going on there. I've not had it happen yet in my quick testing here. I admit I never tried switching loaded effects on the fly as you have done, so there could well be an edge case happening where the old effect is still being held on to. If you do raise an issue, having a minimal code example that produces the issue would be very helpful for debugging.

"""

# Constants
EMERGENCY = COLOURS = [RED,RED,RED,RED,BLUE,BLUE,BLUE,BLUE]
Copy link
Member

Choose a reason for hiding this comment

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

EMERGENCY doesn't seem to be used anywhere?

# Constants
EMERGENCY = COLOURS = [RED,RED,RED,RED,BLUE,BLUE,BLUE,BLUE]
EMERGENCY_BLINK_SPEED = 8
ORANGE = (228,114,28)
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps (255, 32, 0)?

# Variables
tiny = TinyFX() # Create a new TinyFX object to interact with the board
player = MonoPlayer(tiny.outputs) # Create a new effect player to control TinyFX's mono outputs
player = ColourPlayer(tiny.rgb) # Create a new effect player to control TinyFX's RGB output
Copy link
Member

Choose a reason for hiding this comment

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

colour_player for clarity?

# Variables
tiny = TinyFX() # Create a new TinyFX object to interact with the board
player = MonoPlayer(tiny.outputs) # Create a new effect player to control TinyFX's mono outputs
player = ColourPlayer(tiny.rgb) # Create a new effect player to control TinyFX's RGB output
monoplayer = MonoPlayer(tiny.outputs)
Copy link
Member

Choose a reason for hiding this comment

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

mono_player for readability

monoplayer = MonoPlayer(tiny.outputs)

# Create and set up an red blue flashing effect to play, and a hazard one for later
rgbEffect = RGBBlinkFX(colour=COLOURS, # The colour (or colours to blink in sequence)
Copy link
Member

Choose a reason for hiding this comment

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

We tend to use snake case for our variable names, rather than camelCase. E.g. rgb_effect

t = 0 # keep track of boot press duration
dont_exit_yet = True
while dont_exit_yet:
player.start() # Start the effects running
Copy link
Member

Choose a reason for hiding this comment

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

I think start() should be outside of the first while loop. I wonder if repeated calls to it without calling stop first is the cause of your problem 🤔

player.start() # Start the effects running

# Loop until the effect stops or the "Boot" button is pressed
while player.is_running() and not tiny.boot_pressed():
Copy link
Member

Choose a reason for hiding this comment

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

The player is never stopped, so checking is_running() is unnecessary

while player.is_running() and not tiny.boot_pressed():
pass
t = time.ticks_ms()
while player.is_running() and tiny.boot_pressed():
Copy link
Member

Choose a reason for hiding this comment

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

checking is_running() is unnecessary

t = time.ticks_ms()
while player.is_running() and tiny.boot_pressed():
pass
if time.ticks_ms() - t > 500: # long press - toggle effect
Copy link
Member

Choose a reason for hiding this comment

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

The more robust way to do this check is time.ticks_diff(time.ticks_ms(), t) > 500. See: https://docs.micropython.org/en/latest/library/time.html#time.ticks_diff

Also, from my resting, I found having short press be effect switch, and long press be stop, felt like a better user experience

while player.is_running() and tiny.boot_pressed():
pass
if time.ticks_ms() - t > 500: # long press - toggle effect
player.effects = [hazardEffect] if player.effects[0] is rgbEffect else [rgbEffect]
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 surprised this worked! player.effects may appear as a list but is actually two functions hidden by properties. As such there may be cases where effects[0] would not equal the effect your originally entered into it.

Perhaps a safer way would be to have a separate mode variable that you use to set the new effect and then toggle for the next time e.g. mode = not mode

@ZodiusInfuser
Copy link
Member

@tyeth Have you had chance to look at my comments on this?

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