"Shimmering" LEDs

I haven't been able to find much on the web, but I figure there's something out there....

I am trying to create a shimmering effect with a bunch of LEDs. (I have no idea how many, yet)

They're intended to be an indirect backlight, with the effect of moonlight glinting off of a lake or stream. In other words, a gentle but rapid shifting of light in a fairly random pattern. I don't need "solid lines" (as you would see on a wall nearby). I know that can't be accomplished with LEDs alone.

I'm not looking for a complete solution, because I'm not 100% sure how the final product would turn out. Plus, I won't learn anything that way. Really, I'm just looking for similar projects and code snippets/pseudocode to get some ideas as to how to do it.

Thanks in advance!

take a white bright-led array and put a polarizing filter above (you can find those in lcd displays).

I had a 5x7 array of green leds displaying a kind of glimmering pattern and it looks pretty cool with the filter above.
The program uses 3 levels of brightness for each led and it seems to add up to the effect.
I can give you the code, but it's a bit messy without a wiring pattern and the comments aren't deep in details.

Yeah, I'd love to take a peek at the code, if you don't mind :slight_smile:

I like the idea of the polarizing filter, too.

Here's the code, but it may appear a bit confusing.
I used a special technique to emulate different brightness levels by changing the duty cycle of each led.
The only problem is that the cpu needed to process it increases proportionally with the amount of brightness levels

/****************************************************
*  5x7 Led Array driver with multiple brightness.   *
*  2 HCF4094 shift registers used with common       *
*  strobe and common data but different clock pins. *
*****************************************************/

//For the timer interrupt
#include <avr/interrupt.h>
#include <avr/io.h>

#define strobePin 12
#define dataPin 11
#define clockPPin 8
#define clockNPin 7

byte lMatrix[5][7];

int cycle=0; //each line is scanned [maxCycle] times.
int vLine=0; //vertical line scanned
int maxCycle = 3; //max brightness, or amount of brightness levels

int refreshRate = 80; //Images per second

long frame = 0; //frame index increases after each refresh
long lastChange = 0; //for animation, records the frame index of last image change

void setup(){
  //Setting interrupt to ~1200Hz, meaning 80Hz refresh rate for the LCD
  TCCR2A |= (1 << WGM21);
  TCCR2A &= ~(1 << WGM20);
  TCCR2B |= (1 << CS22)|(1 << CS21);
  TCCR2B &= ~(1 << CS20);
  TIMSK2 |= (1 << OCIE2A);
  OCR2A = 12500/refreshRate/maxCycle-1;  
  //16000000/5/256=12500 (clock/vertical lines/timer prescaler)
  
  pinMode(strobePin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPPin, OUTPUT);
  pinMode(clockNPin, OUTPUT);
  
  //Setting up initial picture
  int tmp=0;
  int dir=1;
  for (int i=0; i<5; i++){
    for (int j=0; j<7; j++){
      tmp+=dir;
      if (tmp>=maxCycle)dir=-1;
      if (tmp<=0)dir=1;
      lMatrix[i][j]=tmp;
    }
  }

  sei();
}

//changing the picture to be displayed
void setDisplay(){
  int tmp;
  for (int i=0; i<5; i++){
    for (int j=0; j<7; j++){
      tmp=lMatrix[i][j]+1;
      if (tmp>maxCycle)tmp=0;
      lMatrix[i][j]=tmp;
    }
  }
}

//displaying the image on the led array 
void displayLine(){
  int i=0;
  int pinState;

  cycle++;
  if (cycle>maxCycle){
    cycle=1;
    vLine++;
    if (vLine>4){
      vLine=0;
      digitalWrite(dataPin,1);
      pulsePClock();
      frame++;
    }else{
      digitalWrite(dataPin,0);
      pulsePClock();
    }
  }  
  
  for (i=6; i>=0; i--){
    if (lMatrix[vLine][i] < cycle){pinState=1;}else{pinState=0;}
    //if (i>3){pinState=0;}else{pinState=1;}
    digitalWrite(dataPin, pinState);
    pulseNClock();
  }
  
  pulseStrobe();
}

void pulseNClock(){
  digitalWrite(clockNPin, 1);
  delayMicroseconds(2);
  digitalWrite(clockNPin, 0);
}

void pulsePClock(){
  digitalWrite(clockPPin, 1);
  delayMicroseconds(2);
  digitalWrite(clockPPin, 0);
}

void pulseStrobe(){
  digitalWrite(strobePin, 1);
  delayMicroseconds(10);
  digitalWrite(strobePin, 0);
}

//timer interrupt
ISR(TIMER2_COMPA_vect) {  
  if (frame >= lastChange+5){
    setDisplay();
    lastChange=frame;
  }
  displayLine();
};  

void loop(){
}