4 days until my underwater mermaid shoot in Cenotes in Mexico and the tail

4 days until my underwater mermaid shoot in Cenotes in Mexico and the tail is (dare I say it) ready to go and working. :slight_smile:

I am having to rethink the seashell bra top though – it’s just. not. submersible. The damn thing leaks if I go below a meter or so, and just about all IP68 cases I’ve been able to find are HUGE, at least, wayyy to big to hide in a seashell bra.

I’ve hit upon what I think its a perfect solution. I’ve hooked up an induction coil for charging and an IR sensor for color changing, and I’m gonna just seal the whole thing up in a Case Marine iphone case. I think this is gonna work.

I haven’t been able to find much out there about using IR remotes with Neopixels (except lots of things that say “don’t”) but I’ve actually gotten pretty far. My remote is working with the neopixels for solid colors and brightness changes. I’m running into a problem with animation though… I think this is an “interrupt” issue and I’m not sure how to fix it.

I can get the LEDs to rainbow-fade but I can’t get them to STOP rainbow-fading (other than with a preset delay). Can anyone point me in the right direction? (code in the comments)

#include <Adafruit_NeoPixel.h>
#include <stdlib.h>
#include <IRremote.h>
#include “IRRemoteControl.h”
#include <FastLED.h>

#define RECV_PIN 11
#define NEO_PIN 9
#define NUM_LEDS 16
#define COLOR_ORDER GRB
#define SPEEDO 50
#define STEPS 1
int BRIGHTNESS = 255;
int HUE = 0;
int SATURATION = 255;

CRGB leds[NUM_LEDS];
// Creates an Adafruit_NeoPixel instance
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, NEO_PIN, NEO_GRB + NEO_KHZ800);

uint8_t status = 1; // Strip state: ON/OFF
uint32_t lastColor; // Current color on the strip
uint16_t offset = 0; // Used in the raindow function
long timeRef; // Used for measuring delay in the A-B-C sequences

// Creates an IRRemoteControl instance
IRRemoteControl remote(RECV_PIN);

CRGBPalette16 currentPalette;
TBlendType currentBlending;

void setup()
{ delay( 3000 ); // power-up safety delay
initStrip();

remote.enable();  // Starts the receiver
remote.pair(BRIGHT, brightnessup);
remote.pair(DIM, brightnessup);
    remote.pair(ON, power);  // Pairs buttons to functions
remote.pair(OFF, power);  
    remote.pair(RED, red);
remote.pair(GREEN, green);
remote.pair(BLUE, blue);
remote.pair(WHITE, white);
remote.pair(REDORANGE, redorange);
remote.pair(LIGHTGREEN, lightgreen);
    remote.pair(LIGHTBLUE, lightblue);
remote.pair(ORANGE, orange);
remote.pair(TEAL, teal);
remote.pair(PURPLE, purple);
remote.pair(YELLOWORANGE, yelloworange);
remote.pair(SEABLUE, seablue);
    remote.pair(MAGENTA, magenta);  
remote.pair(YELLOW, yellow);
remote.pair(OCEANBLUE, oceanblue);
remote.pair(PINK, pink);
remote.pair(SMOOTH, runrainbow); 
    /*remote.pair(STROBE, strobe);
    remote.pair(FLASH, flash);
    remote.pair(FADE, fade);*/
    
    FastLED.addLeds<WS2812B, NEO_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness(  BRIGHTNESS );
    currentBlending = BLEND;

}

void loop()
{
// Checks if a button is pressed
// and executes the corresponding function
remote.check();

// Optional: Do your thing here. Just keep it short ;)

}

// Initializes the LED strip
void initStrip()
{
strip.begin();
lastColor = strip.Color(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
setColor(lastColor);
strip.show();
}

// Turns the LED strip on and off
// When turning on, the color from the last operation appears
void power()
{
if ( status )
{
setColor(strip.Color(0, 0, 0));
status = 0;
}
else
{
setColor(lastColor);
status = 1;
}
}

void red()
{
fill_solid(leds, NUM_LEDS, CRGB::Red);
FastLED.show();
}

void green()
{
fill_solid(leds, NUM_LEDS, CRGB::Green);
FastLED.show();
}

void blue()
{
fill_solid(leds, NUM_LEDS, CRGB::Blue);
FastLED.show();
}

void white()
{
fill_solid(leds, NUM_LEDS, CRGB::White);
FastLED.show();
}

void redorange()
{
fill_solid(leds, NUM_LEDS, CRGB::OrangeRed);
FastLED.show();

}

void lightgreen()
{
fill_solid(leds, NUM_LEDS, CRGB::LimeGreen);
FastLED.show();
}

void lightblue()
{
fill_solid(leds, NUM_LEDS, CRGB::Indigo);
FastLED.show();

}

void orange()
{
fill_solid(leds, NUM_LEDS, CRGB::Orange);
FastLED.show();
}

void teal()
{
fill_solid(leds, NUM_LEDS, CRGB::Aqua);
FastLED.show();
}

void purple()
{
fill_solid(leds, NUM_LEDS, CRGB::Purple);
FastLED.show();
}

void yelloworange()
{
fill_solid(leds, NUM_LEDS, CRGB::Goldenrod);
FastLED.show();
}

void seablue()
{
fill_solid(leds, NUM_LEDS, CRGB::Teal);
FastLED.show();
}

void magenta()
{
fill_solid(leds, NUM_LEDS, CRGB::Magenta);
FastLED.show();
}

void yellow()
{
fill_solid(leds, NUM_LEDS, CRGB::Yellow);
FastLED.show();

}

void oceanblue()
{
fill_solid(leds, NUM_LEDS, CRGB::MidnightBlue);
FastLED.show();
}

void pink()
{
fill_solid(leds, NUM_LEDS, CRGB::Pink);
FastLED.show();
}

void rainbow() { //-m2-FADE ALL LEDS THROUGH HSV RAINBOW
HUE++;
if (HUE > 255) {HUE = 0;}
for(int idex = 0 ; idex < NUM_LEDS; idex++ ) {
leds[idex] = CHSV(HUE, 255, 255);
}
LEDS.show();
delay(SPEEDO);
}

void runrainbow() {
int r = 10;
for(int i=0; i<r*100; i++) {
rainbow();
}
}j

//this bit is in every palette mode, needs to be in there just once
void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
uint8_t brightness = BRIGHTNESS;

for( int i = 0; i < NUM_LEDS; i++) {
leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
colorIndex += 1;
}
}

void brightnessup() {
BRIGHTNESS++;
if (BRIGHTNESS > 6) BRIGHTNESS = 1;
switch (BRIGHTNESS) {
case 1: LEDS.setBrightness(8); FastLED.show(); break; // 25% - default
case 2: LEDS.setBrightness(16); FastLED.show(); break; // 50%
case 3: LEDS.setBrightness(32); FastLED.show(); break; // 100%
case 4: LEDS.setBrightness(64); FastLED.show(); break; // 3%
case 5: LEDS.setBrightness(128); FastLED.show(); break; // 6%
case 6: LEDS.setBrightness(255); FastLED.show(); break; // 12%
}
}

void brightnessdown() {
BRIGHTNESS–;
if (BRIGHTNESS > 6) BRIGHTNESS = 1;
switch (BRIGHTNESS) {
case 1: LEDS.setBrightness(255); FastLED.show(); break; // 25% - default
case 2: LEDS.setBrightness(128); FastLED.show(); break; // 50%
case 3: LEDS.setBrightness(64); FastLED.show(); break; // 100%
case 4: LEDS.setBrightness(32); FastLED.show(); break; // 3%
case 5: LEDS.setBrightness(16); FastLED.show(); break; // 6%
case 6: LEDS.setBrightness(8); FastLED.show(); break; // 12%
}
}
// Fills the strip with the given color
void setColor(uint32_t c)
{
for (uint16_t i = 0; i < strip.numPixels(); ++i)
strip.setPixelColor(i, c);
strip.setBrightness(BRIGHTNESS);
strip.show();
}

other issues: the brightness thing I borrowed from @Ashley_M_Kirchner_No but it only counts “up”. I have a brightness up and a brightness down button, and I have them both doing the same thing now but tried (and failed) to turn one into a brightness-down button. What am I missing?

For the rainbow… I think i had a similar issue… where the runrainbow() is looping to fast that its not catching the button/IR command to stop/change the function… While all the other functions run once and stop, then essentially wait

What I’ve done in the past is added a ‘check for button press’ type snippet within the for(int i=0; i<r*100; i++) and for(int idex = 0 ; idex < NUM_LEDS; idex++ ) loops to try and catch it… or else I found that the function wouldn’t change until it hit then end of all the repetitions.

I’m pretty sure this is the problem… I’m also pretty sure there’s a better solution than the hacky method I came up with

my hacky code if you want to see how i did it. I used a catch to skip out of the loop.

You have:
remote.pair(BRIGHT, brightnessup);

And:
remote.pair(DIM, brightnessup);

Both are using the same function. The DIM needs to use brightnessdown as you have it defined.

Also, the counter check in brightnessdown needs to change:
if (BRIGHTNESS < 1) BRIGHTNESS = 6;

As for stopping the rainbow fade, right now once the rainbow loop starts, nothing will stop it. There is no check in place inside of the loop to check whether the remote sent a command. Try sticking a remote.check() call after the LEDS.show() call that’s inside of the rainbow() function.

I fixed the operator and the call on the brightnessdown function and it still doesn’t work. The button now sets the LEDs to full brightness, and then does nothing if I press it again. (or possibly it’s setting it to full brightness again). This isn’t ideal for a “brightness down” button.

void brightnessdown() {
BRIGHTNESS–;
if (BRIGHTNESS < 6) BRIGHTNESS = 1;
switch (BRIGHTNESS) {
case 1: LEDS.setBrightness(255); FastLED.show(); break; // 25% - default
case 2: LEDS.setBrightness(128); FastLED.show(); break; // 50%
case 3: LEDS.setBrightness(64); FastLED.show(); break; // 100%
case 4: LEDS.setBrightness(32); FastLED.show(); break; // 3%
case 5: LEDS.setBrightness(16); FastLED.show(); break; // 6%
case 6: LEDS.setBrightness(8); FastLED.show(); break; // 12%
}
}

adding remote.check(); didn’t work either… I get a rainbow fade for the length of my delay, then it just freezes like that. I’m trying to figure out how to dig into what remote.check() does but I’m getting kind of frustrated.

You didn’t read my complete message. The counter check is wrong in the brightnessdown one.

Don’t call the run rainbow() function. Go straight to rainbow().

that’s what I did… I get a jerky rainbow fade to yellow and then a freeze.

ooh I did fix the brightness thing though. :slight_smile:

Hrm, that’s possibly due to the remote.check() then.Unfortunately, without knowing what that actually does, or how it’s used, there’s no way I can solve that problem. You may just have to stick with your predetermined delay, and at the end of it, call something else so it doesn’t just stop. For example:

static void runrainbow() {
static uint8_t r = 10;
for (volatile uint16_t i = 0; i < r*100; i++) {
rainbow();
}
// call another function here, like:
red();
}

That way when it stops, it will automatically go to the red one and you have control over it with the remote again. One hopes.

it’s a photoshoot anyway. Why the heck do I need a rainbow fade for a photoshoot? Sigh.

LOL! Actually, there’s something to be argued there. Sometimes you will catch it at the right moment without even realizing it and later you’ll appreciate how the colors matched something else around you.

I’ve been having a similar problem where I can’t decode an IR signal when performing animated LED sequences.

Finally solved it (to my satisfaction) here:

http://www.tuline.com/dru/content/arduino-fastled-and-irremote-reliability

I just noticed the bunch (swarm?) of Beetles in the background :slight_smile:

:). I amused the heck out of myself by soldering six little legs on one to use it in my breadboard. (There were, of course, sound effects)

Buzzing sound effects? :slight_smile: