Emulador código Matrix pelicula

Buenas,
Tengo un problemilla para controlar 4 matrices led WS2812B de 8*32
El caso es que quiero que cada matriz salga por un pin de datos diferente, para hacer que cada una sea random y no se parezca a la de al lado.
Espero haberme explicado.


#include "FastLED.h"
#include "timer.h"
#include "droplet.h"

#if FASTLED_VERSION < 3001000
#error "Requires FastLED 3.1 or later; check github for latest code."
#endif

#define ROW_MAJOR         1
#define COLUMN_MAJOR      2
#define SNAKE_HORIZONTAL  3
#define SNAKE_VERTICAL    4


/******************************************************************************/
/*** PROGRAM SETTINGS - ADAPT TO YOUR NEEDS! **********************************/
/******************************************************************************/

// Hardware definitions.
#define DATA_PIN    3
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB


// Effect settings.
constexpr unsigned long REFRESH_PERIOD_MS = 20;
constexpr int MAX_BRIGHTNESS = 50;
constexpr unsigned long DROPLET_MIN_RESPAWN_DELAY_MS = 500;
constexpr unsigned long DROPLET_MAX_RESPAWN_DELAY_MS = 5000;
constexpr unsigned long DROPLET_MIN_FALL_DELAY_MS = 50;
constexpr unsigned long DROPLET_MAX_FALL_DELAY_MS = 150;

// "The Matrix" color scheme
const CRGB COLOR_INITIAL(MAX_BRIGHTNESS/2, MAX_BRIGHTNESS, 0);
const CRGB COLOR_REST(0, 0, 0);
const CRGB COLOR_DECAY(20, 1, 1);

// "Fire" color scheme
// const CRGB COLOR_INITIAL(MAX_BRIGHTNESS, MAX_BRIGHTNESS, 0);
// const CRGB COLOR_REST(0, 0, 0);
// const CRGB COLOR_DECAY(1, 5, 1);


// Matrix dimensions.
#define ORDERING SNAKE_HORIZONTAL
constexpr int ROWS = 32;
constexpr int COLS = 8;
constexpr int NUM_LEDS = ROWS * COLS;
constexpr int DROPLETS_PER_COLUMN = 3;
constexpr int NUM_DROPLETS = DROPLETS_PER_COLUMN * COLS;



/******************************************************************************/
/*** GLOBAL :( VARIABLES ******************************************************/
/******************************************************************************/

// Global array with all LEDs.
CRGB leds[NUM_LEDS];

// Auxiliary function to access LEDs as a matrix.
CRGB& matrix(unsigned int row, unsigned int col) {
  unsigned int idx = 
    #if ORDERING==ROW_MAJOR
      row * COLS + col;
    #elif ORDERING==COLUMN_MAJOR
      col * ROWS + row;
    #elif ORDERING==SNAKE_HORIZONTAL
      row * COLS + (row % 2 == 0 ? col : COLS - 1 - col);
    #elif ORDERING==SNAKE_VERTICAL
      // row * COLS + (row % 2 == 0 ? COLS - 1 - col : col);
      col * ROWS + (col % 2 == 0 ? row : ROWS - 1 - row);
    #else
    #error "You must set the macro ORDERING to allow addressing LEDs as a matrix"
    #endif
  return leds[idx];
}

// Array with droplets.
Droplet* droplets[NUM_DROPLETS];

// Timer to "flush" colors when needed.
Timer global_timer(REFRESH_PERIOD_MS);

// Timer to dim colors - it has the same rate as the global one.
Timer dim_timer(REFRESH_PERIOD_MS);


/******************************************************************************/
/*** MAIN PROGRAM - NOTHING TO CHANGE HERE (IN THEORY!) ***********************/
/******************************************************************************/

void setup() {
  // 3 seconds delay for recovery.
  delay(3000);
  
  // Tell FastLED about the LED strip configuration.
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS)
    .setCorrection(TypicalLEDStrip)
    .setDither(MAX_BRIGHTNESS < 255);

  // Initialize droplets.
  for(unsigned int i=0; i<NUM_DROPLETS; i++) {
    droplets[i] = new Droplet(
      i % COLS,
      ROWS,
      DROPLET_MIN_RESPAWN_DELAY_MS,
      DROPLET_MAX_RESPAWN_DELAY_MS,
      DROPLET_MIN_FALL_DELAY_MS,
      DROPLET_MAX_FALL_DELAY_MS
    );
  }
}


void loop()
{
  animate_droplets();

  if(global_timer.tictoc())
    FastLED.show();
}


void animate_droplets() {
  if(dim_timer.tictoc()) {
    for(unsigned int i=0; i<NUM_LEDS; i++) {
      leds[i] -= COLOR_DECAY;
      leds[i] |= COLOR_REST;
    }
  }

  for(unsigned int i=0; i<NUM_DROPLETS; i++) {
    if(droplets[i]->visible()) {
        matrix(droplets[i]->row(), droplets[i]->col()) = COLOR_INITIAL;
    }
    
    droplets[i]->update();
    
    if(droplets[i]->visible()) {
      matrix(droplets[i]->row(), droplets[i]->col()) = CRGB(MAX_BRIGHTNESS, MAX_BRIGHTNESS, MAX_BRIGHTNESS);
    }
  }
}

Este es el código inicial con una matriz, he probado con mil funciones e historias y la verdad estoy perdido.

Un saludo y gracias

Y cual es el problema? No puedes hacer que salga por 4 pines?

El problema es que al repetirse el mismo código en los 4 paneles a la vez resulta un poco extraño.
quiero que cada uno sea diferente al otro.
He hecho una solución chapucera que es uniendo los paneles y aumentando la matriz en la sentencia pero no termina de gustarme y no sale tan bien.
No se si me he explicado correctamente.

que contenido tienen

#include "timer.h"
#include "droplet.h"

No es chapucería, para eso están diseñados los WS, para conectarlos en serie.

Chapucera es para mi porque visualmente no es igual.

Perdón
Ahí va

#ifndef DROPLET_H
#define DROPLET_H

#include "FastLED.h"
#include "timer.h"

/// Class that represents falling droplets.
class Droplet {
private:
  const unsigned int rows_;
  unsigned int row_;
  const unsigned int col_;
  Timer timer_;
  const unsigned long min_wait_before_respawn_;
  const unsigned long max_wait_before_respawn_;
  const unsigned long min_fall_period_;
  const unsigned long max_fall_period_;
  
public:
  Droplet(
    unsigned int col,
    unsigned int rows,
    unsigned long min_wait_before_respawn,
    unsigned long max_wait_before_respawn,
    unsigned long min_fall_period,
    unsigned long max_fall_period
  )
  : rows_(rows)
  , row_(rows)
  , col_(col)
  , timer_(min_wait_before_respawn_)
  , min_wait_before_respawn_(min_wait_before_respawn)
  , max_wait_before_respawn_(max_wait_before_respawn)
  , min_fall_period_(min_fall_period)
  , max_fall_period_(max_fall_period)
  { }

  const unsigned int& row() const { return row_; }
  const unsigned int& col() const { return col_; }
  bool visible() const { return row_ < rows_; }

  void update() {
    if(!timer_.tictoc())
      return;
    
    if(visible()) {
      row_++;

      if(!visible()) {
        timer_.set_period(rand_range(min_wait_before_respawn_, max_wait_before_respawn_, 10));
      }
    }
    else {
      row_ = 0;
      timer_.set_period(rand_range(min_fall_period_, max_fall_period_, 10));
    }
  }

  static unsigned long rand_range(
    unsigned long min_value, 
    unsigned long max_value, 
    unsigned char steps
  )
  {
    return min_value + random8(steps) * (max_value - min_value) / steps;
  }
};

#endif

y este el timer.h

#ifndef TIMER_H
#define TIMER_H

#include <Arduino.h>

/// Simple timer based on the millis() Arduino function.
/** This class allows you to create a timer so that some code fragments get
  * executed at a regular frequency. Note that this is not an "active" timer:
  * you have to poll it frequently enough to know if it is time to execute
  * something.
  *
  * Note that even if an overflow of `millis()` happens, the timer should
  * still work properly.
  *
  * The following snipped shows an example in which two square waves are
  * generated on pins 13 (at 0.5Hz) and 12 (at 10Hz):
  * \code
  * Timer timer1(1000); // elapses every second
  * Timer timer2(50); // elapses every 50 milliseconds
  * int state1 = 0;
  * int state2 = 0;
  *
  * void setup() {
  *   pinMode(13, OUTPUT);
  *   pinMode(12, OUTPUT);
  * }
  *
  * void loop() {
  *   if(timer1.tictoc()) {
  *     digitalWrite(13, state1);
  *     state1 = 1 - state1;
  *   }
  *   if(timer2.tictoc()) {
  *     digitalWrite(12, state2);
  *     state2 = 1 - state2;
  *   }
  * }
  * \endcode
  */
class Timer {
private:
  unsigned long last_tic_; ///< Time at which the timer last expired.
  unsigned long period_ms_; ///< Desired period of the timer.
  
public:
  /// Creates a timer with given period.
  /** @param period_ms period of time (in milliseconds) at which the timer should
    *   periodically expire.
    */
  Timer(unsigned long period_ms) {
    set_period(period_ms);
  }

  /// Change the period of the timer.
  /** Calling this function also resets the timer.
    *  @param period_ms the new period of time (in milliseconds) at which the timer
    *  should periodically expire.
    */
  void set_period(unsigned long period_ms) {
    period_ms_ = period_ms;
    last_tic_ = millis();
  }

  /// Checks if the timer has expired.
  /** @return true if at least `period_ms` milliseconds have passed since the last
    *   time the timer expired.
    */
  bool tictoc() {
    unsigned long tic = millis();
    unsigned long elapsed = tic - last_tic_;
    
    if(elapsed < period_ms_)
      return false;
    
    // Update the target time for the next trigger, trying also to reduce the
    // "time drift".
    last_tic_ = tic - elapsed % period_ms_;
    return true;
  }
};

#endif

Los paneles se conectan en serie y mandas a cada LED el dato que quieras, se van a repetir si tu le mandas la misma data a cada bloque de 256 bytes, sino no.
Salvo que tus paneles no tengan el conector de salida para hacer la conexión...
¿Qué placa estás usando?
Por el asuntito de la memoria, digo.

Mega2560
Tb tengo Arduino UNO

Los paneles tienen entrada y salida, y ahora para disimular están puestos así porque digamos que conectados todos al mismo data se replica en los 4 y no queda bien.
Al no ser random....

Creo que el problema es que el código es para 256 LED (8x32) y tienes 1024 (8x32x4).

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.