User Tools

Site Tools


project:ledbar:random
#include "Tlc5940.h"

#define CH 3

#define TLCCH(tlc_num, ch_num) ((tlc_num)*16 + (ch_num))

unsigned int xr1 = 19543;
int c[CH];

//int cmax[CH] = { 3900, 4095, 3500 }; - old led
//int cmax[CH] = { 2800, 4095, 3500 }; - new led, max intensity
/* cca 3ohm resistor per channel */
int cmax[CH] = { 1600, 3900, 2100 }; // - new led, same visual perception
//int cpin[CH] = {4, 5, 6};
//int cpin2[CH] = {12, 14, 13};
int cpin2[CH] = {TLCCH(1, 9), TLCCH(1, 10), TLCCH(1, 11)};
int cpin3[CH] = {TLCCH(0, 9), TLCCH(0, 10), TLCCH(0, 11)};
int wait = 10;

void setup()
{
  Serial.begin(9600);
  /* Call Tlc.init() to setup the tlc.
     You can optionally pass an initial PWM value (0 - 4095) for all channels.*/
  Tlc.init();
  int i = 0;
  for (i = 0; i < CH; i++)
    c[i] = cmax[i] / 2;
  xr1 += analogRead(0);
}

int r(int ceiling)
{
  xr1 = 16807 * (xr1 & 0xfff) + (xr1 >> 12);
  return xr1 % ceiling;
}

/* One iteration of random colorspace walk. */
void random_walk()
{
  static const int maxstep = 2;
  static const int maxbounce = maxstep * 2;
  static const int maxgrad = 32;
  static const int cmaxgrad[CH] = {maxgrad, maxgrad, maxgrad};
  //static const int cmaxgrad[CH] = { cmax[0]/(4096/maxgrad), cmax[1]/(4096/maxgrad), cmax[2]/(4096/maxgrad) };
  static const int dampening = 8; // less means tend to smaller gradient
  static int g[CH] = {0, 0, 0};

  int i;

  for (i = 0; i < CH; i++) {
    g[i] += r(maxstep) * (r(2) ? 1 : -1);
    /* dampening */ g[i] += (g[i] > 0 ? -1 : 1) * r(abs(g[i])) / dampening;
    if (g[i] < -cmaxgrad[i]) g[i] = -cmaxgrad[i] + r(maxbounce); else if (g[i] > cmaxgrad[i]) g[i] = cmaxgrad[i] - r(maxbounce);

    c[i] += g[i];
    if (c[i] < 0) { c[i] = 0; g[i] = -g[i] + r(maxbounce)-maxbounce/2; } else if (c[i] > cmax[i]) { c[i] = cmax[i]; g[i] = -g[i] + r(maxbounce)-maxbounce/2; }
  }
}

/* One iteration of constant brightest white (useful for tuning constants for particular LEDs). */
void white()
{
  int i;
  for (i = 0; i < CH; i++) {
    c[i] = cmax[i];
  }
}

/* White "breathing" effect to a certain degree of intensity. Good for identifying a point where further intensity change does not make any difference. */
void grey()
{
  static const int steps = 100;
  static const int cdelta = 1*1024/steps;
  static int s = 0;
  static int d = 1;
  
  s += d;
  if (s <= 0 || s >= steps) d = -d;

  int i;
  for (i = 0; i < CH; i++) {
    c[i] = cmax[i] - cdelta * s;
  }
}

void loop()
{
  Tlc.clear();
  
  random_walk();
  //white();
  //grey();

  int i;
  for (i = 0; i < CH; i++) {
    Serial.print(c[i], DEC); Serial.print(" ");
    //Tlc.set(cpin[i], c[i]);
    Tlc.set(cpin2[i], c[i]);
    Tlc.set(cpin3[i], c[i]);
  }
  Serial.println();

  /* Tlc.update() sends the data to the TLCs.  This is when the LEDs will
     actually change. */
  Tlc.update();

  delay(wait);
}
project/ledbar/random.txt · Last modified: 2011/04/08 16:38 by pasky