Pages: [1] 2   Go Down
Author Topic: Smooth animation with an 8x8 RGB LED matrix  (Read 14800 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 4
Posts: 3
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Below are several videos that demonstrate smooth animations running on an 8x8 RGB LED matrix.

The main factors that contribute to the effect:
  • Use of a diffuser screen, placed at just the right distance from the LEDs.
    I used a tracing paper for the screen - it is opaque enough so the pixels blend, but not too much so some contrast remains.
    The physical setup can be seen in the attached images.
  • The calculations that produce the animation are done using a larger number of "virtual pixels" than the ones actually available. These are then rendered onto the low-res matrix.
  • The frame rate is high enough to create the illusion of smooth motion


Examples:
Fire simulation
The logic here is pretty simple.
For each keyframe, a new row of pixels with random brightness values is generated.
In each sub-frame, the matrix is gradually shifted up, interpolating between full rows.
The calculated "raw" brightness is faded according to a fixed mask, to give the flame a shape.
The hue of each pixel is taken from a constant mask, so the inner area of the fire is yellow and the outer area deep red.
The code for this example is available on github.


Particle systems
These next examples use the same hardware setup, but the animation is generated using a particle system library that I posted about yesterday.







Enjoy


* IMG_0757_sml.JPG (268.01 KB, 1024x683 - viewed 217 times.)

* IMG_0753_sml.JPG (241.53 KB, 1024x683 - viewed 95 times.)
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 144
Posts: 5355
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Very nice effect...!


Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Show Your Work
Offline Offline
Edison Member
*
Karma: 14
Posts: 1072
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Holy cow that is really well done.  Where did you get that diffuser screen?  I don't know a lot about them but I have tried diffusing with thin white cloth and paper and never got a good result.

Care to share any code or schematics?
Logged

I have only come here seeking knowledge. Things they would not teach me of in college.

Offline Offline
Newbie
*
Karma: 4
Posts: 3
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, sure smiley

The diffuser screen is made of a sheet of tracing paper, attached to a frame made of foam core - see attached image.
Standard paper is too white and opaque which results in really low contrast and the light hardly getting through.
Note that the distance of the screen from the LED matrix is really important and will be different depending on the specific material used.

The circuit itself is just an off-the-shelf Colorduino - I believe that a Rainbowduino would work just as well.

The code for all the examples (library and sketches) is available on github.




* IMG_0820_sml.JPG (161.2 KB, 800x533 - viewed 68 times.)
Logged

Norfolk UK
Offline Offline
Edison Member
*
Karma: 66
Posts: 2482
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The circuit itself is just an off-the-shelf Colorduino - I believe that a Rainbowduino would work just as well.
Hi giladaya,
I can confirm the code works on Rainbowduino with very little modification. Fantastic work.
Logged

There is no such thing as a stupid question but there are a lot of inquisitive idiots.

Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 130
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello giladaya,

this really looks great. I was searching for some nice Matrix Animations and started a thread, which was not very succesful
LED Matrix - animation pattern.
I´ll try to port your code to my matrix and go on collecting some nice effects smiley

Some time ago I wrote a .NET program which can demonstrate matix animations on a PC. Maybe I´ll release it to make it easier to create some new effects.

Greetings
Thomas
Logged

Europe / Germany
Offline Offline
Sr. Member
****
Karma: 11
Posts: 334
keep it simple
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Respect, well done! Good presentation, too.

I can imagine, that it would look great on a huge indirect working matrix (so, that you just see the projection at a wall) with powerful LED strip elements...

edit, next day:

I have to test that with a serious output device...  smiley-wink

« Last Edit: March 04, 2013, 06:47:31 am by Helmuth » Logged

San Francisco
Offline Offline
Newbie
*
Karma: 0
Posts: 23
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This looks great!

Once my 8x8 matrix arrives, I'd like to try to adapt it as an interactive nightlight, where new particles would be triggered if a PIR motion detector is triggered while ambient light is low. I was thinking I might be able to accomplish this by updating your "Flame.ino" example (https://github.com/giladaya/arduino-particle-sys/blob/master/examples/Flame/Flame.ino). In that example, some of the parameters for the particle system are established in Setup:
Code:
source.x = 112;  
source.y = 1;  
Emitter_Fountain::minLife = 20;  
Emitter_Fountain::maxLife = 80;  
Particle_Std::ay = 1;

I was thinking that I could add some lines to Loop that would adjust these continuously. For instance:
Code:
if (triggerPin == HIGH && ambientLight <= lightThreshold) {      //assuming these are all defined elsewhere...
   Particle_Std::ay = 1;
}
else { Particle_Std::ay = 0; }

I expect this would leave the particles at the bottom of the display most of the time, but then they'd shoot up when the PIR is triggered in the dark.
Any ideas or suggestions for a more elegant implementation, or smarter usage of the library? Thanks! I'm looking forward to experimenting with this.
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@giladaya: Could it be, that you swapped columns and rows ( width and height) in you code?
I'm currently trying to port your "fire"-code to a WS2812 LED strip with 6 columns ( 6 pixel width) and 8 rows (8 pixel hight).

As I understand your code, the function "generateline()" creates a new pixel-line on the bottom line of the matrix. But your code says:
Code:
/**
* Randomly generate the next line (matrix row)
*/
void generateLine(){
  for(unsigned char x=0;x<ColorduinoScreenHeight;x++) {
      line[x] = random(64, 255);
  }
}
So you are using "x" for the position of the "cursor" on the line, but you use the ColorduinoScreenHeight as upper border.
This is not a problem, as long as you use this nomenclature consistently and yout matrix has exactly the same number of rows and columns.
Problems start if the number of columns and rows differ.
Another point is the declaration of the mask-Arrays (valueMask[ColorduinoScreenWidth][ColorduinoScreenHeight] and hueMask[ColorduinoScreenWidth][ColorduinoScreenHeight])
Mario.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

my dream is to make one of this.....
Logged

https://www.facebook.com/pages/TonyMake/160740054064026

(mezzi a disposizione)*(intelligenza)= K (costante)

Show Your Work
Offline Offline
Edison Member
*
Karma: 14
Posts: 1072
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

my dream is to make one of this.....


Set your dreams higher.  This guy did a great job but at this point this is almost a canned project, all the data you need is right here and it isn't all that expensive.  So just do it.  Then design something yourself, that is the real challange.
Logged

I have only come here seeking knowledge. Things they would not teach me of in college.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

beginning from the low side..... nest step is higher  smiley-lol
Logged

https://www.facebook.com/pages/TonyMake/160740054064026

(mezzi a disposizione)*(intelligenza)= K (costante)

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@mkl0815 did you ever manager to port this? I've tried to make this library independent but it seems to rely on the colorduino libraries. All I need is to be able to define the columns and rows and get r,g,b for each pixel. Haven't had any luck so far, if I remove the colorduino library reference everything goes to pot.

@giladaya: Could it be, that you swapped columns and rows ( width and height) in you code?
I'm currently trying to port your "fire"-code to a WS2812 LED strip with 6 columns ( 6 pixel width) and 8 rows (8 pixel hight).

As I understand your code, the function "generateline()" creates a new pixel-line on the bottom line of the matrix. But your code says:
Code:
/**
* Randomly generate the next line (matrix row)
*/
void generateLine(){
  for(unsigned char x=0;x<ColorduinoScreenHeight;x++) {
      line[x] = random(64, 255);
  }
}
So you are using "x" for the position of the "cursor" on the line, but you use the ColorduinoScreenHeight as upper border.
This is not a problem, as long as you use this nomenclature consistently and yout matrix has exactly the same number of rows and columns.
Problems start if the number of columns and rows differ.
Another point is the declaration of the mask-Arrays (valueMask[ColorduinoScreenWidth][ColorduinoScreenHeight] and hueMask[ColorduinoScreenWidth][ColorduinoScreenHeight])
Mario.
Logged

Europe / Germany
Offline Offline
Sr. Member
****
Karma: 11
Posts: 334
keep it simple
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, here a concept, how to map 2 rows to a RGB strip using FastSPI_LED...

Code:
/*
 * Copyright (C) 2013 Gilad Dayagi.  All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 */

 /*
  * An example for the Arduino particle system library
  * A wandering particle that emits colorful smoke
  *
  * Note: this example uses the colorduino library becuse that is what I had,
  * but any device that supports setting a pixel to an RGB value can be used
  */

//#include <Colorduino.h>

#include <FastSPI_LED.h>
#include "ParticleSys.h"
#include "Particle_Std.h"
#include "Particle_Fixed.h"
#include "Emitter_Fountain.h"
#include "PartMatrix.h"

#define NUM_LEDS 20

//change the order of your rgb here
struct CRGB { unsigned char r; unsigned char g; unsigned char b; };
struct CRGB *leds;


const byte numParticles = 50;
boolean pulseOn = false;

Particle_Std particles[numParticles];
Particle_Fixed source;
Emitter_Fountain emitter(0, 0, 5, &source);
ParticleSys pSys(numParticles, particles, &emitter);
PartMatrix pMatrix;

/**
 * Render the particles into a low-resolution matrix
 */
void drawMatrix(){
    pMatrix.reset();
    pMatrix.render(particles, numParticles);
    //update the actual LED matrix
    for (byte y=0;y<8;y++) {
        //for(byte x=0;x<8;x++) {
            //Colorduino.SetPixel(x, y, pMatrix.matrix[x][y].r, pMatrix.matrix[x][y].g, pMatrix.matrix[x][y].b);
              leds[y].r = pMatrix.matrix[3][y].r;
              leds[y].g = pMatrix.matrix[3][y].g;
              leds[y].b = pMatrix.matrix[3][y].b;
             
              leds[NUM_LEDS-y].r = pMatrix.matrix[4][y].r;
              leds[NUM_LEDS-y].g = pMatrix.matrix[4][y].g;
              leds[NUM_LEDS-y].b = pMatrix.matrix[4][y].b;
             
             
             
             
             
     //   }
    }
}

void setup()
{
  FastSPI_LED.setLeds(NUM_LEDS);
  //select your chipset according to your strip type here - have a look at FastSPI documentation
  //i´m using a LPD1101 right know who behaves like a LPD6803
  FastSPI_LED.setChipset(CFastSPI_LED::SPI_LPD6803);
  FastSPI_LED.init();
  FastSPI_LED.start();
  leds = (struct CRGB*)FastSPI_LED.getRGBData();
   
 
  //Colorduino.Init(); // initialize the board
 
  // compensate for relative intensity differences in R/G/B brightness
  // array of 6-bit base values for RGB (0~63)
  // whiteBalVal[0]=red
  // whiteBalVal[1]=green
  // whiteBalVal[2]=blue
  //byte whiteBalVal[3] = {36,63,7}; // for LEDSEE 6x6cm round matrix
  //Colorduino.SetWhiteBal(whiteBalVal);
 
  randomSeed(analogRead(0));
 
  //source.vx = 3;
  //source.vy = 1;
  source.x = 112;
  source.y = 1;
  Emitter_Fountain::minLife = 20;
  Emitter_Fountain::maxLife = 80;
  Particle_Std::ay = 1;
  //PartMatrix::isOverflow = false;
 
  //init all pixels to zero
  pMatrix.reset();
}

void loop()
{
    pSys.update();
    drawMatrix();
    FastSPI_LED.show();

    delay(20);
}
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is incredible work! Can it be adapted to plain arduino and single color 8x8 matrix ?
Logged

Pages: [1] 2   Go Up
Jump to: