Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!



Meteor Rain with LD...
 
Share:
Notifications
Clear all

[Solved] Meteor Rain with LDR in a marble track

8 Posts
2 Users
0 Reactions
1,065 Views
(@ledmeup)
Active Member
Joined: 3 years ago
Posts: 11
Topic starter  

Hi folks (and especially Hans)!

I want to add an LED strip with the Meteor Rain to my marble track.

The ball triggers an LDR which starts the sketch. It should run 5 times and then go back into a waiting status to be triggered again.

Thing is that Meteor Rain runs forever in my sketch and I can`t find the mistake.

I would be so greatful for help.

Stay healthy!

Thomas

Here is the sketch I did:

/* LDR triggered LED Strip with WS2812B and LED effect "Meteor Rain" (Tweaking 4 All)

 */

#define FASTLED_INTERNAL // just used to mute the Pragma messages when compiling
#include "FastLED.h"
#define NUM_LEDS 105
CRGB leds[NUM_LEDS];
#define PIN 6
const int analogPin = A0; // pin that the sensor is attached to
const int ledPin1 = A2; // pin that the green LED is attached to
const int ledPin2 = A1; // pin that the yellow LED is attached to
const int threshold = 500; // an arbitrary threshold level that's in the range of the analog input
int ldrlows;                             //creates a variable integer called 'ldrlows'

void setup()
{
  FastLED.addLeds < WS2811, PIN, GRB > (leds, NUM_LEDS).setCorrection(TypicalLEDStrip );
  for (int i=0; i<4; i++) meteorRain(0xff,0xff,0xff,10, 50, true, 30);
  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  // LDR an PIN A0
  pinMode (A0, INPUT);
   Serial.begin(9600);
}

//  REPLACE FROM HERE 

void loop() {
  
  // read the value of the ldr:
  int analogValue = analogRead(analogPin);
analogRead(A0); 
  // if the analog value is high enough, turn on the LED2(yellow):
  if (analogValue > threshold) {
    digitalWrite(ledPin2, HIGH);
  } else {
    digitalWrite(ledPin2, LOW);
  }
if (analogValue < threshold) {  //if the analog value of A0 is smaller than 800 then
    ldrlows = 1; //write ldrlows 1;
 }
  else {
 ldrlows = 0;
 }
  // print the analog value:
 Serial.println(ldrlows);
  // if the analog value is low enough, turn on the LED1green:
  if (analogValue < threshold) {
    digitalWrite(ledPin1, HIGH);
    meteorRain(0xff,0xff,0xff,10, 50, true, 30);
  } else {
    digitalWrite(ledPin1, LOW);
  } 

  delay(50); // delay in between reads for stability
}

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  setAll(0,0,0);
 
  for(int i = 0; i < NUM_LEDS+NUM_LEDS; i++) {
   
   
    // fade brightness all LEDs one step
    for(int j=0; j<NUM_LEDS; j++) {
      if( (!meteorRandomDecay) || (random(10)>5) ) {
        fadeToBlack(j, meteorTrailDecay );        
      }
    }
   
    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j <NUM_LEDS) && (i-j>=0) ) {
        setPixel(i-j, red, green, blue);
      }
    }
   
    showStrip();
    delay(SpeedDelay);
  }
}

void fadeToBlack(int ledNo, byte fadeValue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
    // NeoPixel
    uint32_t oldColor;
    uint8_t r, g, b;
    int value;
   
    oldColor = strip.getPixelColor(ledNo);
    r = (oldColor & 0x00ff0000UL) >> 16;
    g = (oldColor & 0x0000ff00UL) >> 8;
    b = (oldColor & 0x000000ffUL);

    r=(r<=10)? 0 : (int) r-(r*fadeValue/256);
    g=(g<=10)? 0 : (int) g-(g*fadeValue/256);
    b=(b<=10)? 0 : (int) b-(b*fadeValue/256);
   
    strip.setPixelColor(ledNo, r,g,b);
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[ledNo].fadeToBlackBy( fadeValue );
 #endif  
}

//  REPLACE TO HERE 

void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.show();
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
 #endif
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
 #endif
}

void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

Thomas


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2728
 

Hi Thomas,

I made a few changes ... 

  • I used 2 digital pins for LED1 and LED2, instead of the Analog pins.
  • The meteor function is called 5 times with a for-loop in "void loop()".
  • Changed the analogPin and ledPIn1/2 to "#define" calls, so things take up less memory.
  • Reformatted the code a little for readability (always a good idea).
  • I optimized some code since you're using FastLED anyway ... 😊 

The code below had NOT been tested, so things may not work as hoped for, since I do not have the hardware handy ... 😊 

Let me know how it worked ... 

You stay healthy as well! 😉 

/* LDR triggered LED Strip with WS2812B and LED effect "Meteor Rain" (Tweaking4All) */

#define FASTLED_INTERNAL  // just used to mute the Pragma messages when compiling
#include "FastLED.h"

#define NUM_LEDS 105
CRGB leds[NUM_LEDS];
#define PIN 6

// Used Define since that does not take up any memory
#define analogPin A0     // LDR pin
#define ledPin1   12     // digital pin that the green LED is attached to
#define ledPin2   13     // digital pin that the yellow LED is attached to

#define threshold 500    // an arbitrary threshold level that's in the range of the analog input

void setup() {
  FastLED.addLeds < WS2811, PIN, GRB > (leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  fill_solid( leds, NUM_LEDS, CRGB(0,0,0));
  FastLED.show();
  
  // initialize the LED pins for output: 
  // Note: I picked 2 digital pins for this (#12 and #13) instead of the analog pins you used!
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  
  // LDR an PIN A0
  pinMode(analogPin, INPUT);

  // Initialize serial monitor/port
  Serial.begin(9600);
}


void loop() {

  // read the value of the ldr:
  int analogValue = analogRead(analogPin);
  
  // Did something pass the LDR (= dark?)
  if (analogValue < threshold) {
    Serial.println("MARBLE PASSED LDR <------");
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, HIGH);

    // run meteor rain 5x
    for(int i; i<5; i++) {
      meteorRain(0xff, 0xff, 0xff, 10, 50, true, 30);
    }
  } else {
    Serial.println("LDR Did not detect anything");
    digitalWrite(ledPin1, HIGH);
    digitalWrite(ledPin2, LOW);
    
    // All LEDs black
    fill_solid( leds, NUM_LEDS, CRGB(0,0,0));
    FastLED.show();
  }
  
  delay(50); // delay in between reads for stability
}

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
  // All LEDs black
  fill_solid( leds, NUM_LEDS, CRGB(0,0,0));
  FastLED.show();

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

    // fade brightness all LEDs one step
    for (int j = 0; j < NUM_LEDS; j++) {
      if ((!meteorRandomDecay) || (random(10) > 5)) {
        leds[j].fadeToBlackBy(meteorTrailDecay);
      }
    }

    // draw meteor
    for (int j = 0; j < meteorSize; j++) {
      if ((i - j < NUM_LEDS) && (i - j >= 0)) {
        leds[i - j] = CRGB(red, green, blue);
      }
    }

    FastLED.show();
    delay(SpeedDelay);
  }
}

 


   
ReplyQuote
(@ledmeup)
Active Member
Joined: 3 years ago
Posts: 11
Topic starter  

Hi Hans!

I checked out your sketch. It works absolutely fine! Thank you very much.

There is just one little thing I corrected: in the void loop: =0 was missing, so i was undeclared.

But never mind, you did a great job! (As always ;o)

👍

Have a nice day,

Thomas

Thomas


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2728
 

Awesome Thomas! Glad to hear that. 😊 👍 

I'm not sure where the "=0" is supposed to be placed (I need more coffee to wake up haha).
Would you mind posting the full code - this way others may benefit from it as well 😊 


   
ReplyQuote
(@ledmeup)
Active Member
Joined: 3 years ago
Posts: 11
Topic starter  

Now here is a desciption of the gizmo I built up:

It is an element in my fischertechnik marble track. The ball triggers the LDR which starts the sketch on the NANO. Then the Meteor Rain runs 5 times and the module is ready for the next triggering.

Sounds simple? Well, the devil is in the details!

First you have to calibrate the LDR. Depending on the light emission of the LED used and the surrounding light, the resistance of the LDR differs.

So it has to be checked with the serial monitor using an analog output. Depending on that the threshold has to be defined. In this case it is 850.

For the lightbeams I use LEDs between 10000 and 20000 mcd in red. They usually work sufficient.

The green LED indicates the Ready Status of the circuit, the orange one indicates triggering. So if something is wrong you know where to check.

When you load the sketch to the Arduino DISCONNECT the LED strip. Otherwise the Arduino tries to power the strip. With 105 LEDs the Arduino goes up in smoke!

Happy New Year!  😮 

And put a 1000uF capacitator between VCC and GND of the powersupply. It protects the strip.

Additionally the resistor for the dataline of the strip is neccessary. The values differ between 330 and 470. Both should be fine.

I split up the strip to create an impact area of 20 LEDs. That meant A LOT of soldering but it was worth it! Be sure to solder VERY preciselly for the soldering points on the

WS2812 are very tiny and lots of short circuits are at hand 🤐 

The code is not too complex. Anyway, I needed Hans´ help. Again. Thank you Hans. You are the man! 👍 

Any questions? Post ´em.

Have fun!

Thomas

/* LDR triggered LED Strip with WS2812B and LED effect "Meteor Rain" (Tweaking4All) */

#define FASTLED_INTERNAL  // just used to mute the Pragma messages when compiling
#include "FastLED.h"

#define NUM_LEDS 105
CRGB leds[NUM_LEDS];
#define PIN 6

// Used Define since that does not take up any memory
#define analogPin A0     // LDR pin
#define ledPin1   12     // digital pin that the green LED is attached to
#define ledPin2   13     // digital pin that the yellow LED is attached to

#define threshold 850    // an arbitrary threshold level that's in the range of the analog input

void setup() {
  FastLED.addLeds < WS2811, PIN, GRB > (leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  fill_solid( leds, NUM_LEDS, CRGB(0,0,0));
  
  FastLED.show();
  
  // initialize the LED pins for output: 
  // Note: I picked 2 digital pins for this (#12 and #13) instead of the analog pins you used!
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  
  // LDR an PIN A0
  pinMode(analogPin, INPUT);

  // Initialize serial monitor/port
  Serial.begin(9600);
}


void loop() {

  // read the value of the ldr:
  int analogValue = analogRead(analogPin);
  
  // Did something pass the LDR (= dark?)
  if (analogValue < threshold) {
    Serial.println("MARBLE PASSED LDR <------");
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, HIGH);

    // run meteor rain 5x
    for(int i=0; i<5; i++) {
     //  meteorRain(0xff, 0xff, 0xff, 10, 50, true, 30);
      // colour RED:
     meteorRain(255, 48, 48, 10, 50, true, 30); 
     // hot pink
  //    meteorRain(255, 110, 180, 10, 50, true, 30);
    }
  } else {
    Serial.println("LDR Did not detect anything");
    digitalWrite(ledPin1, HIGH);
    digitalWrite(ledPin2, LOW);
    
    // All LEDs black
    fill_solid( leds, NUM_LEDS, CRGB(0,0,0));
    FastLED.show();
  }
  
  delay(50); // delay in between reads for stability
}

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
  // All LEDs black
  fill_solid( leds, NUM_LEDS, CRGB(0,0,0));
  FastLED.show();

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

    // fade brightness all LEDs one step
    for (int j = 0; j < NUM_LEDS; j++) {
      if ((!meteorRandomDecay) || (random(10) > 5)) {
        leds[j].fadeToBlackBy(meteorTrailDecay);
      }
    }

    // draw meteor
    for (int j = 0; j < meteorSize; j++) {
      if ((i - j < NUM_LEDS) && (i - j >= 0)) {
        leds[i - j] = CRGB(red, green, blue);
      }
    }

    FastLED.show();
    delay(SpeedDelay);
  }
}

 

Thomas


   
ReplyQuote
(@ledmeup)
Active Member
Joined: 3 years ago
Posts: 11
Topic starter  

OOps!

Forgot the curcuit:

And a video of the working gizmo

 

Thomas


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2728
 

Awesome! Thank you Thomas for sharing!

Looks great  👍 


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2728
 

Just posted the video here again (testing the forum)


   
ReplyQuote
Share: