Help FastLED: add 3rd Button to toggle Brightness;Bicycle Indicators ws2812b

Hi I’m new to arduino and coding in general and need some help…

I am currently running a ardunio nano with 4 ws2812b strips, each with 15 leds as bicycle indicators.

  • 2 for the front; always running white light
  • 2 for the back; always running red light

added 2 tactile switches(off(on); 6x6x5mm); one for each handle

  • push left switch: FrontLeft/BackLeft goes alternating white/red to orange and back
  • push right switch: FrontRight/BackRight goes alternating white/red to orange and back

and here is where i’m stuck… i want to add a 3rd button to change through some brightness modes but keep my code for the blinking

like
mode1 front brightness 100%/back brightness 100%/orange brightness 100%
mode2 front brightness 80%/back brightness 80%/orange brightness 100%
mode3 front brightness 40%/back brightness 50%/orange brightness 100%
mode4 front brightness 0%/back brightness 50%/orange brightness 100%

i’ve set my max_bright = 192 i knew its not max but my 100%

maybe someone even knows how to get some indicator running light; stuck on that aswell

lesept

How about this ?

helped me with his knowledge on this project to build “my” code but now i’m stuck and need help

#include <FastLED.h>


#define PIN_STRIP1 6
#define PIN_STRIP2 7
#define PIN_STRIP3 8
#define PIN_STRIP4 9
#define PIN_BUTTON1 2
#define PIN_BUTTON2 3
#define COLOR_ORDER GRB
#define LED_TYPE WS2812B
#define NUM_LEDS 15
uint8_t max_bright = 192; //guess that needs to be gone when the modes work
CRGB leds1[NUM_LEDS];
CRGB leds2[NUM_LEDS];
CRGB leds3[NUM_LEDS];
CRGB leds4[NUM_LEDS];


void setup() {
  LEDS.addLeds<LED_TYPE, PIN_STRIP1, COLOR_ORDER>(leds1, NUM_LEDS).setCorrection( TypicalLEDStrip );
  LEDS.addLeds<LED_TYPE, PIN_STRIP2, COLOR_ORDER>(leds2, NUM_LEDS).setCorrection( TypicalLEDStrip );
  LEDS.addLeds<LED_TYPE, PIN_STRIP3, COLOR_ORDER>(leds3, NUM_LEDS).setCorrection( TypicalLEDStrip );
  LEDS.addLeds<LED_TYPE, PIN_STRIP4, COLOR_ORDER>(leds4, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(max_bright);


  pinMode(PIN_BUTTON1, INPUT_PULLUP);
  pinMode(PIN_BUTTON2, INPUT_PULLUP);

}

void loop() {

  fill_solid(leds1, NUM_LEDS, CRGB::White);
  fill_solid(leds2, NUM_LEDS, CRGB::White);
  fill_solid(leds3, NUM_LEDS, CRGB::Red);
  fill_solid(leds4, NUM_LEDS, CRGB::Red);

  Checkbuttons();

  FastLED.show();
  FastLED.clear();

}



void Checkbuttons()
{
  bool StateB1 = digitalRead(PIN_BUTTON1);
  bool StateB2 = digitalRead(PIN_BUTTON2);


  if (!StateB1) ChangeStrip1 ();
  if (!StateB2) ChangeStrip2 ();
  if (!StateB1 and !StateB2) ChangeStrip3 ();
}


void ChangeStrip1 () {
  for (int i = 0; i < 4; i++) {
    fill_solid(leds3, NUM_LEDS, CRGB::Gold);
    fill_solid(leds1, NUM_LEDS, CRGB::Gold);
    FastLED.show();
    delay(400);
    fill_solid(leds3, NUM_LEDS, CRGB::Red);
    fill_solid(leds1, NUM_LEDS, CRGB::White);
    FastLED.show();
    delay(250);
    FastLED.show();
  }
}

void ChangeStrip2 () {
  for (int i = 0; i < 4; i++) {
    fill_solid(leds4, NUM_LEDS, CRGB::Gold);
    fill_solid(leds2, NUM_LEDS, CRGB::Gold);
    FastLED.show();
    delay(400);
    fill_solid(leds4, NUM_LEDS, CRGB::Red);
    fill_solid(leds2, NUM_LEDS, CRGB::White);
    FastLED.show();
    delay(250);
    FastLED.show();
  }
}

void ChangeStrip3 () {
  for (int i = 0; i < 900; i++){
  for (int i = 0; i < 8; i++) {
    fill_solid(leds3, NUM_LEDS, CRGB::Gold);
    fill_solid(leds1, NUM_LEDS, CRGB::Gold);
    fill_solid(leds4, NUM_LEDS, CRGB::Gold);
    fill_solid(leds2, NUM_LEDS, CRGB::Gold);
    FastLED.show();
    delay(400);
    fill_solid(leds4, NUM_LEDS, CRGB::Red);
    fill_solid(leds2, NUM_LEDS, CRGB::White);
    fill_solid(leds3, NUM_LEDS, CRGB::Red);
    fill_solid(leds1, NUM_LEDS, CRGB::White);
    FastLED.show();
    delay(250);
    FastLED.show();
    }    
  for (int i = 0; i < 15; i++) {
    fill_solid(leds4, NUM_LEDS, CRGB::Blue);
    fill_solid(leds2, NUM_LEDS, CRGB::Blue);
    fill_solid(leds3, NUM_LEDS, CRGB::Blue);
    fill_solid(leds1, NUM_LEDS, CRGB::Blue);
    FastLED.show();
    delay(100);
    fill_solid(leds4, NUM_LEDS, CRGB::Red);
    fill_solid(leds2, NUM_LEDS, CRGB::White);
    fill_solid(leds3, NUM_LEDS, CRGB::Red);
    fill_solid(leds1, NUM_LEDS, CRGB::White);
    FastLED.show();
    delay(50);
    fill_solid(leds4, NUM_LEDS, CRGB::Blue);
    fill_solid(leds2, NUM_LEDS, CRGB::Blue);
    fill_solid(leds3, NUM_LEDS, CRGB::Blue);
    fill_solid(leds1, NUM_LEDS, CRGB::Blue);
    FastLED.show();
    delay(100);
    fill_solid(leds4, NUM_LEDS, CRGB::Red);
    fill_solid(leds2, NUM_LEDS, CRGB::White);
    fill_solid(leds3, NUM_LEDS, CRGB::Red);
    fill_solid(leds1, NUM_LEDS, CRGB::White);
    FastLED.show();
    delay(100);
    FastLED.show();
    }
  for (int i = 0; i < 8; i++) {
    fill_solid(leds3, NUM_LEDS, CRGB::Gold);
    fill_solid(leds1, NUM_LEDS, CRGB::Gold);
    fill_solid(leds4, NUM_LEDS, CRGB::Gold);
    fill_solid(leds2, NUM_LEDS, CRGB::Gold);
    FastLED.show();
    delay(400);
    fill_solid(leds4, NUM_LEDS, CRGB::Red);
    fill_solid(leds2, NUM_LEDS, CRGB::White);
    fill_solid(leds3, NUM_LEDS, CRGB::Red);
    fill_solid(leds1, NUM_LEDS, CRGB::White);
    FastLED.show();
    delay(250);
    FastLED.show();
    }
 }
}

if someone can share his knowledge with me, it would mean a lot to me and my powerbank who’s getting worn out …

thanks in advance M

what does ChangeStrip3( ) do ?

it changes all 4 LED strips to white/red with alternating orange as an emergency/hazard light

but to get to the ChangeStrip3 it cycles 3 times; either 2x left 1x right or 1x right 1xleft

Use an LDR from an analog pin to ground with pinMode of INPUT_PULLUP to automatically set the brightness.

Good choice the Nano, though since you are not likely to be using USB on the road, a Pro Mini would be appropriate. :grinning:

@Paul_B My brother gave me ~20 Nanos he had over from a project.
I thought about buying a Pro Mini but since i’m running it from a 18650 battery the size of the Nano isn’t too big.

And i found some code i could modify for my needs, with 3 different modes:

  • only blinkers
  • blinkers + knightrider running light in the back(red)
  • blinkers + permanent white in front, red in the back

I’ve 3d-printed some handlebar adapters for the 5x5x6mm tactile switches + 7x2812b LED housing and a box for the nano, 2 slide switches(on/off), 18650 battery with loading/+5v chip. And now im just waiting for my jst hx 2.54 connectors to make the box detachable from the LEDs/handlebar switches.

#include <FastLED.h>                       
#define NUM_STRIPS 4                        
#define NUM_LEDS_PER_STRIP 7  

CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP];

uint8_t gHue = 0;                          

const int buttonPinL = 2;                   
const int buttonPinR = 3;                   
int buttonPinEng = 4;                 
int buttonPinKnightRider = 5;        

int buttonStateL = 0;
int buttonStateR = 0;
int engineOn = 0;
int KnightRiderState = 0;

int stateL = 0;
int stateR = 0;

uint8_t gBrtL = 0;
uint8_t gBrtR = 0;

int maxBrt = 192;                           

int delayTurnLedAnim = 40; 
int delayTurnLedOff = 250; 
int delayLedToDayLight = 50; 
int nrAnimAfterOff = 6; 

void setup() { 
  //Serial.begin(9600);
  pinMode(buttonPinL, INPUT);
  pinMode(buttonPinR, INPUT);
  pinMode(buttonPinEng, INPUT);
  pinMode(buttonPinKnightRider, INPUT);
  
  FastLED.addLeds<WS2812B, 8>(leds[0], NUM_LEDS_PER_STRIP); //led strip for front left | NEOPIXEL gave the wrong color
  FastLED.addLeds<WS2812B, 9>(leds[1], NUM_LEDS_PER_STRIP); //led strip for front right
  FastLED.addLeds<WS2812B, 10>(leds[2], NUM_LEDS_PER_STRIP); //led strip for rear left
  FastLED.addLeds<WS2812B, 11>(leds[3], NUM_LEDS_PER_STRIP); //led strip for rear right

  attachInterrupt(digitalPinToInterrupt(buttonPinL),btnPressL,RISING); 
  attachInterrupt(digitalPinToInterrupt(buttonPinR),btnPressR,RISING);

  fill_solid(leds[0], NUM_LEDS_PER_STRIP, CRGB::Black);
  fill_solid(leds[1], NUM_LEDS_PER_STRIP, CRGB::Black); 
  fill_solid(leds[2], NUM_LEDS_PER_STRIP, CRGB::Black);
  fill_solid(leds[3], NUM_LEDS_PER_STRIP, CRGB::Black);
  FastLED.show();
}

void loop() {

    buttonStateL = digitalRead(buttonPinL); 
    buttonStateR = digitalRead(buttonPinR);
    KnightRiderState = digitalRead(buttonPinKnightRider);
    engineOn = digitalRead(buttonPinEng);

  //function for hazard lights
  if(stateL != 0 && stateR != 0){ 
    
    for(int dot = 0; dot < NUM_LEDS_PER_STRIP; dot++) { 
        leds[0][dot] = 0xff6a00;
        leds[1][dot] = 0xff6a00;
        leds[2][dot] = 0xff6a00;
        leds[3][dot] = 0xff6a00;
        FastLED.show();
        delay(delayTurnLedAnim);
    }
    
    delay(delayTurnLedOff);
    fill_solid(leds[0], NUM_LEDS_PER_STRIP, CRGB::Black);
    fill_solid(leds[1], NUM_LEDS_PER_STRIP, CRGB::Black);
    fill_solid(leds[2], NUM_LEDS_PER_STRIP, CRGB::Black);
    fill_solid(leds[3], NUM_LEDS_PER_STRIP, CRGB::Black);
    FastLED.show();
    delay(delayTurnLedOff);

    if(buttonStateL != HIGH || buttonStateR != HIGH){
      
      if(buttonStateL == HIGH){
        stateL = 1;
      }else{
        stateL = 0;
        gBrtL = 0;        
      }
      
      if(buttonStateR == HIGH){
        stateR = 1;
      }else{
        stateR = 0;
        gBrtR = 0; 
      }
      
      if(buttonStateL != HIGH && buttonStateR != HIGH){
        delay(delayLedToDayLight);        
      }
      
    }

  //function for left turn lights
  }else if(stateL != 0){
    
    if(KnightRiderState == HIGH && engineOn == LOW){
      fill_solid(leds[1], NUM_LEDS_PER_STRIP, CRGB::Black);
      fill_solid(leds[3], NUM_LEDS_PER_STRIP, CRGB::Black);
    }
    
    for(int dot = 0; dot < NUM_LEDS_PER_STRIP; dot++) { 
        leds[0][dot] = 0xff6a00; // color for left turn light
        leds[2][dot] = 0xff6a00;
        FastLED.show();
        delay(delayTurnLedAnim);
    }
    
    delay(delayTurnLedOff);
    fill_solid(leds[0], NUM_LEDS_PER_STRIP, CRGB::Black);
    fill_solid(leds[2], NUM_LEDS_PER_STRIP, CRGB::Black);
    FastLED.show();
    delay(delayTurnLedOff);

    stateL++;
    if(stateL >= nrAnimAfterOff && buttonStateL != HIGH){
      stateL = 0;
      gBrtL = 0;
      delay(delayLedToDayLight);
    }

  //function for right turn lights
  }else if(stateR != 0){
    
    if(KnightRiderState == HIGH && engineOn == LOW){
      fill_solid(leds[0], NUM_LEDS_PER_STRIP, CRGB::Black);
      fill_solid(leds[2], NUM_LEDS_PER_STRIP, CRGB::Black);
    }
      
    for(int dot = 0; dot < NUM_LEDS_PER_STRIP; dot++) { 
        leds[1][dot] = 0xff6a00;
        leds[3][dot] = 0xff6a00;
        FastLED.show();
        delay(delayTurnLedAnim);
    }
    
    delay(delayTurnLedOff);
    fill_solid(leds[1], NUM_LEDS_PER_STRIP, CRGB::Black);
    fill_solid(leds[3], NUM_LEDS_PER_STRIP, CRGB::Black);
    FastLED.show();
    delay(delayTurnLedOff);

    stateR++;
    if(stateR >= nrAnimAfterOff && buttonStateR != HIGH){
      stateR = 0;
      gBrtR = 0;
      delay(delayLedToDayLight);
    }





   
  }else{
    
    if(stateL == 0 && engineOn == HIGH){
      if(gBrtL <= maxBrt){
        EVERY_N_MILLISECONDS( 1 ) { gBrtL++; } 
        fill_solid( leds[0], NUM_LEDS_PER_STRIP, CHSV(0,0,gBrtL));
        fill_solid( leds[2], NUM_LEDS_PER_STRIP, CRGB::Red);
        fill_solid( leds[3], NUM_LEDS_PER_STRIP, CRGB::Red);
        FastLED.show();
      }
    }else{
      if(gBrtL > 0){
        EVERY_N_MILLISECONDS( 1 ) { gBrtL--; } 
        fill_solid( leds[0], NUM_LEDS_PER_STRIP, CHSV(0,0,gBrtL));
        fill_solid( leds[2], NUM_LEDS_PER_STRIP, CRGB::Black);
        FastLED.show();
      }else{
        if(KnightRiderState == HIGH){          
          gHue = 0;
          fadeToBlackBy( leds[0], NUM_LEDS_PER_STRIP, 7);
          int pos = beatsin16( 30, 0, NUM_LEDS_PER_STRIP-1 );
          leds[0][pos] += CRGB::White;
          fadeToBlackBy( leds[2], NUM_LEDS_PER_STRIP, 7);
          pos = beatsin16( 30, 0, NUM_LEDS_PER_STRIP-1 );
          leds[2][pos] += CRGB::Red;
          FastLED.show();
        }
      }
    }

    if(stateR == 0 && engineOn == HIGH){
      if(gBrtR <= maxBrt){     
        EVERY_N_MILLISECONDS( 1 ) { gBrtR++; }
        fill_solid( leds[1], NUM_LEDS_PER_STRIP, CHSV(0,0,gBrtR));
        fill_solid( leds[3], NUM_LEDS_PER_STRIP, CRGB::Red);
        fill_solid( leds[2], NUM_LEDS_PER_STRIP, CRGB::Red);
        FastLED.show();  
      }     
    }else{
      if(gBrtR > 0){        
        EVERY_N_MILLISECONDS( 1 ) { gBrtR--; }
        fill_solid( leds[1], NUM_LEDS_PER_STRIP, CHSV(0,0,gBrtR));
        fill_solid( leds[3], NUM_LEDS_PER_STRIP, CRGB::Black);
        FastLED.show();
      }else{
        if(KnightRiderState == HIGH){          
          gHue = 0;
          //EVERY_N_MILLISECONDS( 20 ) { gHue++; }
          fadeToBlackBy( leds[1], NUM_LEDS_PER_STRIP, 7);
          int pos = beatsin16( 30, 0, NUM_LEDS_PER_STRIP-1 );
          leds[1][pos] += CRGB::White;
          fadeToBlackBy( leds[3], NUM_LEDS_PER_STRIP, 7);
          pos = beatsin16( 30, 0, NUM_LEDS_PER_STRIP-1 );
          leds[3][pos] += CRGB::Red;
          FastLED.show();
        }
      }
    }
  }
}

void btnPressL(){
  stateL = 1;
  for(int nr = 0; nr < 1500; nr++) { 
    buttonStateR = digitalRead(buttonPinR);
    if(buttonStateR == 1){
        stateR = 1;     
      }
  }
}

void btnPressR(){
   stateR = 1;
   for(int nr = 0; nr < 1500; nr++) { 
     buttonStateL = digitalRead(buttonPinL); 
     if(buttonStateL == 1){
        stateL = 1;
      }
   }
}

That’s the prototype version 0.2 with electronics and battery seperated from each other.

I am not complaining - the Nano is pretty much my standard choice for non-Internet applications, the UNO is not really practical.

For Internet - WiFi - you use the ESP8266, either an ESP-01 for up to 4 I/O or WeMOS D1 Mini if you need a few more I/O.

The only caveat is that if you are running from a battery, you are wasting some power in the USB interface chip (which may vary depending on which "genuine" or clone version it is) while a Pro Mini does not have this.

Sorry but it is not practical for me to review your code at this time. :cold_sweat:

Code is working fine.

I just don't want to be some who just post "solved + deadlink".

The Nano(clone) is not powered via the mini-USB Port, the cable you see in the Picture goes directly to the GND/VIN pins. Do you know if this skips the USB-Interfacechip you mentioned?

Thought about running it the code via a WeMos(/or cheaper alternative) and send the taster-signal to a second WeMos in my backpack equiped with LEDs and mirror the backlights. Maybe with the next version, when i got some time to read me through the cheapest way to interconnect 2 chips.