Flying Castle – Modellbau mit WS-LED

Flying Castle – Modellbau mit WS-LED

Code bereits vorhanden. Dieser Artikel ist noch Under Construction.

Kurzinformation: Ich bin absoluter Fan eines Youtube-Creators und habe dort durch ein Video, ein Script erhalten um mit WS-LED´s Fackeln zu simulieren. Nicht wie die großen E27 Lampen sondern pro LED. Da mein Modell allerdings einen Magierturm besitzt indem ich randomly grüne Blitze feuern wollte musste ich das Script entsprechend anpassen damit es auf einem einzelnen Arduino Nano laufen kann. Das Script hat einige sehr interessante Facetten durch die ich sehr viel lernen durfte.

Den Aufbau gehen wir hier einfach mal einzeln durch.

Beginnen wir damit das ich zur Ansteuerung der WS-LED´s die FastLED Bibliothek benutze. Dann definiere ich 2 PIN´s. Einen für die Fackeln und einen für den Magierblitz.

C
#include <FastLED.h>

#define LED_PIN 3
#define NUM_LEDS 14
#define LED_MAGICAN_PIN 5
#define NUM_MAGICAN_LEDS 5

Dann erstellen wir zwei Klassen (Torch&Magic_Spell) die inhaltlich gleich gestrickt sind. In diesen Abschnitten wird der Begriff oft vorkommen. Was das genau ist erkläre ich weiter unten. Zuerst kommt die Klasse Torch.
Die Klasse Torch beinhaltet 4 Methoden/Funktionen.

  • void init (Initialisieren der LED´s bzw. des Strips)
  • void tick (Berechnen/Zuweisen der verbleibenden Ticks)
  • void apply_transition_vector (Berechnen der neuen Farben)
  • void compute_new_transition_vector

Zu Beginn der Klasse definiere ich zwei Variablen und initialisiere diese mit dem Startwert 0. Diese benötige ich später um die entsprechenden Berechnungen durchzuführen.
CRGB ist eine Funktion aus der FastLED Bibliothek. Mit dieser erzeugen wir einen Pointer namens led.
Zuletzt erzeugen wir noch ein Array mit einer Größe von 3 Feldern.

Dann starten wir in den Public Bereich der Klasse, indem wir die Methode „init“ definieren. In dieser Methode wird der LED-Streifen initialisiert. Hier wird dann in die Variable „led“ der Inhalt des Pointers geladen.

C
class Torch {
  int ticks_left = 0;
  int max_ticks_per_cycle = 0;
  CRGB* led;
  float transition_vector[3];

 public:
  Torch() {};
  
  void init(int max_ticks, CRGB* led_ptr) {
      led = led_ptr;
      max_ticks_per_cycle = max_ticks;
      led->r = 120;
      led->g = 50;
  }

  void tick() {
    if (ticks_left <= 0) {
      ticks_left = random(10, max_ticks_per_cycle);
      compute_new_transition_vector(ticks_left);
      
    }
    apply_transition_vector();
    ticks_left--;
  }
  
 void apply_transition_vector() {
  (led->r + transition_vector[0] > 255) ? led->r = 255 : (led->r + transition_vector[0] < 0) ? led->r = 0 : led->r += transition_vector[0];
  (led->g + transition_vector[1] > 255) ? led->g = 255 : (led->g + transition_vector[1] < 0) ? led->g = 0 : led->g += transition_vector[1];
 }
 
 void compute_new_transition_vector(int steps) {
  float r;
  float brightness = (float)random(25, 100) / 100.0;
  float g = 50 * brightness;
  r = 205 * brightness;
  transition_vector[0] = (r - led->r) / ticks_left;
  transition_vector[1] = (g - led->g) / ticks_left;
  transition_vector[2] = 0;
 }
 
};
C
class Magic_Spell {
  int ticks_left = 0;
  int max_ticks_per_cycle = 0;
  CRGB* led;
  float transition_vector[3];

 public:
  Magic_Spell() {};
  
 //Initalisierung des Strips und anzeigen der LED´s in der Farbe beim Start
  void init(int max_ticks, CRGB* led_ptr) {
      led = led_ptr;
      max_ticks_per_cycle = max_ticks;
      led->r = 0;
      led->g = 120;
      led->b = 50;
    }

  void tick() {
    if (ticks_left <= 0) {
      ticks_left = random(20, max_ticks_per_cycle);
      compute_new_transition_vector(ticks_left);
      
    }
    apply_transition_vector();
    ticks_left--;
  }
  
 void apply_transition_vector() {
  (led->r + transition_vector[0] > 255) ? led->r = 255 : (led->r + transition_vector[0] < 0) ? led->r = 0 : led->r += transition_vector[0];
  (led->g + transition_vector[1] > 255) ? led->g = 255 : (led->g + transition_vector[1] < 0) ? led->g = 0 : led->g += transition_vector[1];
  (led->b + transition_vector[2] > 255) ? led->b = 255 : (led->b + transition_vector[2] < 0) ? led->b = 0 : led->b += transition_vector[2];
 }
 
 void compute_new_transition_vector(int steps) {
  float r;
  float brightness = (float)random(25, 100) / 100.0;
  float g = 200 * brightness;
  float b = 40 * brightness;
  //r = 205 * brightness;
  transition_vector[0] = (r - led->r) / ticks_left;
  transition_vector[1] = (g - led->g) / ticks_left;
  transition_vector[2] = (b - led->b) / ticks_left;
 }
 
};
C
CRGB leds[NUM_LEDS];
Torch torches[NUM_LEDS];

CRGB MAGIC_leds[NUM_MAGICAN_LEDS];
Magic_Spell spells[NUM_MAGICAN_LEDS];
C
void setup() {
  FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, NUM_LEDS);
  for (int i = 0; i < NUM_LEDS; i++) {
      torches[i].init(15, &leds[i]);
  }
  FastLED.addLeds<NEOPIXEL, LED_MAGICAN_PIN>(MAGIC_leds, NUM_MAGICAN_LEDS);
  for (int i = 0; i < NUM_MAGICAN_LEDS; i++) {
      spells[i].init(15, &MAGIC_leds[i]);
  }
  Serial.begin(9600);
  FastLED.show();
  delay(2000);
}
C
int randomflash = 0;
void loop() {
    for (int i = 0; i < NUM_LEDS; i++) {
      torches[i].tick();
    }
    for (int i = 0; i < NUM_MAGICAN_LEDS; i++) {
      spells[i].tick();
    }
randomflash = random(100);
if(randomflash > 98){
Serial.println("FLASH");
    for (int i = 0; i < NUM_MAGICAN_LEDS; i++) {
      MAGIC_leds[i]= CRGB( 255, 0, 0);
    }
};
    FastLED.show();
    delay(20);
}