WS2812b fastled

Hi!!!

I'm starting to play with a WS2812B led strip and I'd like to make an animation... Years ago I made a shift light with very simple animations but I'd like to do something more worked.

I show an example of what I want to do...

In the video, you can see how while the rpm's increase, the brightness also varies from each led.

I'm doing tests to get that effect and the only way I get it is with this code.

#include "FastLED.h"

#define NUM_LEDS  20    // Numero de leds
#define PIN       10      // PIN ARDUINO

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<WS2812B, PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.clear();                                   
}

void loop() {
  for(int i = 0; i <= NUM_LEDS; i++) {
    for(int b=0; b< 255; b++){
      leds[i].setRGB(b, 0, 0);
      FastLED.show(); 
    }
  }
  FastLED.clear();
}

Could someone help me to get the animation of the video?

Thanks!

Modified your code a little.

#include "FastLED.h"

#define NUM_LEDS  20    // Numero de leds
#define PIN       3      // PIN ARDUINO

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<WS2812B, PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.clear();                                   
}

void loop() {
  for(int i = 0; i <= NUM_LEDS; i++) {
    for(int b=0; b < 255; b++) {
      if (i < 5)
        leds[i].setRGB(0, b, 0);
      else if ((i >= 5) && (i < 10))
        leds[i].setRGB(b, b, 0);
      else if ((i >= 10) && (i < 15))
        leds[i].setRGB(b, 0, 0);
      else if ((i >= 15) && (i < 20))
        leds[i].setRGB(0, 0, b);
      FastLED.show(); 
    }
  }
  FastLED.clear();
}

I waint to integrate in this code:

#include <FastLED.h>
#define NUMLEDS  20
#define PIN       10      // PIN ARDUINO
int NUM_LEDS = 20;
int seg1_end= 6;
int seg2_end= 13;
int seg3_end= 19;
int rpm;
int shift_rpm = 7200;
int activation_rpm = 7000;
long previousMillis = 0;
long shift_parpadeo = 50;
boolean flashbool = true;
CRGB leds[NUMLEDS];
int rpmtable[32][2];


void setup() {
  // put your setup code here, to run once:
  FastLED.addLeds<WS2812B, PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.clear();   
  Serial.begin(9600);

}

void loop() { 


 for (rpm=6900; rpm< 7300; rpm++){
   Serial.println(rpm);

  LED_ARRAY();

  if (rpm < shift_rpm) {

    for (int a = 0; a < NUM_LEDS; a++) {

      if (rpm > rpmtable[a][0]) {
        switch (rpmtable[a][1]) {
          case 1:
            leds[a] = CRGB::Green;
            break;

            case 2:
            leds[a] = CRGB::Yellow;
            break;

            case 3:
            leds[a] = CRGB::Red;
            break;
        }
      }
      else {
        leds[a] = CRGB::Black;
      }      
      FastLED.show();
    }

  } 
  else {

    unsigned long currentMillis = millis();
    
    if (currentMillis - previousMillis > shift_parpadeo) {
      previousMillis = currentMillis;
      flashbool = !flashbool;

      if (flashbool == true)
        for (int i = 0; i < NUM_LEDS; i++) {
          leds[i] = CRGB::Red;

        } else
        for (int i = 0; i < NUM_LEDS; i++) {
          leds[i] = CRGB::Black;
        }

      FastLED.show();
    }
  }
 }
}
  
void LED_ARRAY() {

  int x;  //calculo rpm por led
  int i;  //for loop variable


      x = ((shift_rpm - activation_rpm) / NUM_LEDS);
      for (i = 0; i < seg1_end + 1; i++) {
        rpmtable[i][0] = activation_rpm + (i * x);
        rpmtable[i][1] = 1;
        
      }
      for (i = seg1_end + 1; i < seg2_end + 1; i++) {
        rpmtable[i][0] = activation_rpm + (i * x);
        rpmtable[i][1] = 2;
      }
      for (i = seg2_end + 1; i < seg3_end + 1; i++) {
        rpmtable[i][0] = activation_rpm + (i * x);
        rpmtable[i][1] = 3;
      }

}

I want to create the animation of the video in my code.

See post #2. You need to add the "real" data and remove the for() loops.

Last week I tried this code and it is very slow...

I was wondering if someone could help me make the code faster

#include <FastLED.h>
#define NUMLEDS  20
#define PIN       10      // PIN ARDUINO
int NUM_LEDS = 20;
int seg1_end= 6;
int seg2_end= 13;
int seg3_end= 19;
int rpm;
int shift_rpm = 7200;
int activation_rpm = 7000;
long previousMillis = 0;
long shift_parpadeo = 50;
boolean flashbool = true;
CRGB leds[NUMLEDS];
int rpmtable[32][2];


void setup() {
  // put your setup code here, to run once:
  FastLED.addLeds<WS2812B, PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.clear();   
  Serial.begin(9600);

}

void loop() { 


 for (rpm=6900; rpm< 7300; rpm++){
   Serial.println(rpm);

  LED_ARRAY();

  if (rpm < shift_rpm) {

    for (int a = 0; a < NUM_LEDS; a++) {
      for(int b=0; b < 255; b++) {

      if (rpm > rpmtable[a][0]) {
        switch (rpmtable[a][1]) {
          case 1:
                   leds[a].setRGB(0, b, 0);

            break;

            case 2:
                    leds[a].setRGB(b, b, 0);

            break;

            case 3:
                    leds[a].setRGB(0, 0, b);

            break;
        }
      }
      else {
        leds[a] = CRGB::Black;
      }      
      FastLED.show();
    }
}  
} 
  else {

    unsigned long currentMillis = millis();
    
    if (currentMillis - previousMillis > shift_parpadeo) {
      previousMillis = currentMillis;
      flashbool = !flashbool;

      if (flashbool == true)
        for (int i = 0; i < NUM_LEDS; i++) {
          leds[i] = CRGB::Red

        } else
        for (int i = 0; i < NUM_LEDS; i++) {
          leds[i] = CRGB::Black;
        }

      FastLED.show();
    }
  }
 }
}
  
void LED_ARRAY() {

  int x;  //calculo rpm por led
  int i;  //for loop variable


      x = ((shift_rpm - activation_rpm) / NUM_LEDS);
      for (i = 0; i < seg1_end + 1; i++) {
        rpmtable[i][0] = activation_rpm + (i * x);
        rpmtable[i][1] = 1;
        
      }
      for (i = seg1_end + 1; i < seg2_end + 1; i++) {
        rpmtable[i][0] = activation_rpm + (i * x);
        rpmtable[i][1] = 2;
      }
      for (i = seg2_end + 1; i < seg3_end + 1; i++) {
        rpmtable[i][0] = activation_rpm + (i * x);
        rpmtable[i][1] = 3;
      }

}

Your code is slow because you are adding brightness to each LED from 0 to 255 as you move from LED to LED. If you unwrap that for() loop and set b=255 it will be very fast. (too fast to see).

Create an array of "RPM" data (or connect a potentiometer to an Analog Input pin).
Read each array element (or read the potentiometer).
Map the data (array or potentiometer) and pass it to the logic loop.

OR... buy this:

Or download this:

Here is what you want. Download, install, configure, done.

https://www.simhubdash.com/

I already knew about the simhub app and installed it before asking on the forum. You can create the different animations with the software, but you don't have access to the .ino file, so I can't edit the inputs and my outputs. (rpm, speed, display...)

Okay. How far is your .ino? Mine lacks mapping an RPM input.

I'm sorry, I don't understand you. I dont speak english very well..

My file has 7 inputs. (Vehicle speed, rpm, lights on, water temp, oil temp, oil pressure and fuel level.

All information is sent via serial port (rpm and speed in real time, temperatures and pressure is updated every 5/10 sec) to a nextion screen.

It is working on a real car and works correctly.

I want to add the animation of the led's that are seen in the video.

When the rpm reaches a value (for example, 7000 rpms) the first led lights up little by little. And so on until all the LED strips are complete.

If the rpms drop I also want the brightness to go down...

I asked in the forum if anyone knew any command from the fastled library, for example the fadetoblackby(). I think the code would be faster...

Thanks!

You can easily program such function yourself, but it won't solve your problem.
Below some suggestions that might help to improve your code:

  1. As far I see your rpmtable[ ][ ] array is contant and is not depends from rpm. In that case you shouldn't repopulate it again at every new rpm value . You can move the LED_ARRAY() function to setup() and run it only once.
  2. At the fade loop
    for(int b=0; b < 255; b++) {
    you change the brightness by one. This is not necessary, since the human eye is not able to distinguish such small changes. Change the brightness in steps of 2, 5 or even 10 units - this will speed up the cycle by the corresponding number of times

And one more note (it has nothing to do with speed) - if your number of diodes is #define NUMLEDS 20, why is the rpmtable size set to 32? describe the table for the required number of diodes

This page, on the right-hand side, shows links to the main topics which have the all functions:

To help with clarity, you can have the page translated to your language with Google Translate:

Hi everyone,

I have been trying to create the code as I told you but I have not been able to do it... I read the information that you posted in the post, and the truth is that I have not succeeded.

I found this example on the forum, which partly does what I want.

I don't know if you can help me more or not.

Thanks in advance.

#include <FastLED.h>
#define LED_PIN     3
#define NUM_LEDS    7
CRGB leds[NUM_LEDS];
int Steps = 16;
int fadeAmount = -(256 / Steps); // 256 / Steps
int brightness = 0;
byte factor = 0;
int myTime  = 70;
int myTime2  = 50;
//----------------------------------------------------------------------------------
void LEDcontrol(int i) {
  for (int j = 0; j < Steps; j++)
  {
    if (i == 0 or i == 1 or i == 2 or i == 3) leds[i] = CRGB(0x006400);
    if (i == 4 or i == 5) leds[i] = CRGB(0xFF0000);
    if (i == 6)  leds[i] = CRGB(0xFFD700);
    if (i > 6)   leds[i] = CRGB(0xFFD700);
    brightness = brightness + fadeAmount;
    leds[i].fadeLightBy(brightness);
    FastLED.show();
    delay(myTime);
  }
}
//----------------------------------------------------------------------------------
void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
}
//----------------------------------------------------------------------------------
void loop() {

  for (int i = 0; i < NUM_LEDS; i++)
  {
    brightness = factor;
    LEDcontrol(i);
    delay(myTime2);
  }
  fadeAmount = -fadeAmount ;
  factor = factor ^ 0xFF ;
}

Please clarify what this example does and what doesn't?

This example performs the animation I'm looking for.

The brightness of led 1 turns on progressively. When it reaches maximum brightness, led 2 begins to light progressively and so on.

In my code I want the leds to dim on and off depending on rpm.

I do not know if I explained well.

Thank you very much in advance.

How fast does your RPM change? If it's a car, then the rpm's typically can change by thousands in one second.
This means that your idea with a smooth warm-up or fade of each diode simply will not work - there is not enough time for a smooth change.

Thanks for the reply.

So... How does it work in the video of the first post?

Hi everyone!

I have achieved the effect with an external variable (like engine rpm).

If anyone has any other suggestions to improve the code, it is appreciated.

I will continue working to reach the goal.

Thanks!!

#include <FastLED.h>
#define NUMLEDS  16
#define PIN       10      // PIN ARDUINO
int NUM_LEDS = 16;
CRGB leds[NUMLEDS];
int val = 0;
int aval = 0;
byte a = 0;


void setup() {
  // put your setup code here, to run once:
  FastLED.addLeds<WS2812B, PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.clear();
  Serial.begin(9600);
}

void loop() {

  aval = analogRead(A0);
  val = map(aval, 0, 1023, 0, 255);
  Serial.println(val);

  if (val > 254) {
    a++;
    delay(500);

  }

  if (val == 0) {
    leds[a] = CRGB::Black;
    a--;
    delay(500);
  }
  
  leds[a].setRGB(val, 0, 0);
  FastLED.show();
}

Hi!

I am making an odometer and a speedometer with a hall sensor. I have little experience with interrupts...

The odometer works fine but the speedometer does not work correctly.
The size of the wheel of my vehicle is 195/45/15. If we translate that measure into linear meters the result is 1.748m.

speed = space / time.

If we count 20 pulses in a certain time (we know that the pulses are equivalent to 1,784m each) we would have the speed in m/unit of time. So, we would have the velocity.

I think the speed is wrongly calculated, also it is not updated instantly.

Could you help me??

volatile static float pulse_distance = 1.784; // in meters
volatile static float odometer;
volatile unsigned long lastPulseTime;
volatile unsigned long interval = 0;
volatile int timeoutCounter;
const int timeoutValue = 10;

volatile unsigned long dist_pulse_count;
unsigned int speed;


void setup() {
  Serial.begin(115200);
  attachInterrupt(0, isr, RISING);
}

void loop() {

  Serial.println(odometer); //en km
  speed= (pulse_distance * dist_pulse_count)*3600 / interval; // 1 sec =1000000us. 1km=1000m-> m/s measure. 1000*3.6-> km/h
  Serial.println(speed);
}

void isr() {

  unsigned long now = micros();
  interval = now - lastPulseTime;
  lastPulseTime = now;
  dist_pulse_count++;
  odometer+= pulse_distance;

}