Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
project:ledbar:sketch-autonomous [2011/09/18 17:42]
pasky current version
project:ledbar:sketch-autonomous [2011/09/18 19:00] (current)
pasky
Line 1: Line 1:
 +===== Ledbar: Arduino-autonomous control =====
  
 +You also need the TLC5940 library downloaded in ~/​sketchbook/​libraries. Modify tlc_config.h NUM_TLCS to correspond to the currently connected number of TLC boards (e.g. 2).
 +
 +<​code>​
 +#include "​Tlc5940.h"​
 +
 +#define CH 3
 +
 +#define TLCCH(tlc_num,​ ch_num) ((tlc_num)*16 + (ch_num))
 +
 +unsigned int xr1 = 19543;
 +
 +int cpin[][CH] = {
 +  {TLCCH(0, 2), TLCCH(0, 1), TLCCH(0, 0)},
 +  {TLCCH(0, 5), TLCCH(0, 4), TLCCH(0, 3)},
 +  {TLCCH(0, 8), TLCCH(0, 7), TLCCH(0, 6)},
 +  {TLCCH(0, 12), TLCCH(0, 11),​TLCCH(0,​ 10)},
 +  {TLCCH(0, 15),​TLCCH(0,​ 14),​TLCCH(0,​ 13)},
 +
 +  {TLCCH(1, 2), TLCCH(1, 1), TLCCH(1, 0)},
 +  {TLCCH(1, 5), TLCCH(1, 4), TLCCH(1, 3)},
 +  {TLCCH(1, 8), TLCCH(1, 7), TLCCH(1, 6)},
 +  {TLCCH(1, 12), TLCCH(1, 11), TLCCH(1, 10)},
 +  {TLCCH(1, 15), TLCCH(1, 14), TLCCH(1, 13)},
 +};
 +#define cpinsets (sizeof(cpin)/​sizeof(cpin[0]))
 +
 +/* cca 2.7ohm resistor per channel */
 +int cmax[cpinsets][CH] = {
 +  { 1600, 4000, 2200 },
 +  { 1600, 4000, 2200 },
 +  { 1600, 4000, 2200 },
 +  { 1600, 3900, 2000 },
 +  { 1600, 3700, 3000 },
 +
 +  { 1600, 4000, 2200 },
 +  { 1600, 4000, 2200 },
 +  { 1600, 3400, 3000 },
 +  { 1600, 4000, 2200 },
 +  { 1600, 3400, 3000 },
 +};
 +int c[cpinsets][CH];​
 +
 +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, led = 0;
 +  for (led = 0; led < cpinsets; led++)
 +    for (i = 0; i < CH; i++)
 +      c[led][i] = cmax[led][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(int led)
 +{
 +  static const int maxstep = 2;
 +  static const int maxbounce = maxstep * 2;
 +  static const int maxgrad = 16;
 +  static const int cmaxgrad[CH] = {maxgrad, maxgrad, maxgrad};
 +  static const int dampening = 8; // less means tend to smaller gradient
 +  static int g[cpinsets][CH];​
 +
 +  int i;
 +
 +  for (i = 0; i < CH; i++) {
 +    g[led][i] += r(maxstep) * (r(2) ? 1 : -1);
 +    /* dampening */ g[led][i] += (g[led][i] > 0 ? -1 : 1) * r(abs(g[led][i])) / dampening;
 +    if (g[led][i] < -cmaxgrad[i]) g[led][i] = -cmaxgrad[i] + r(maxbounce);​ else if (g[led][i] > cmaxgrad[i]) g[led][i] = cmaxgrad[i] - r(maxbounce);​
 +
 +    c[led][i] += g[led][i];
 +    if (c[led][i] < 0) { c[led][i] = 0; g[led][i] = -g[led][i] + r(maxbounce)-maxbounce/​2;​ } else if (c[led][i] > cmax[led][i]) { c[led][i] = cmax[led][i];​ g[led][i] = -g[led][i] + r(maxbounce)-maxbounce/​2;​ }
 +  }
 +}
 +
 +void rainbow(int led)
 +{
 +  static int huephases[cpinsets];​
 +  static int huephases_i[cpinsets];​
 +#define HUEPHASE_LEN 512
 +
 +  static int ini;
 +  if (!ini) {
 +    ini = 1;
 +    int v_max = 6 * HUEPHASE_LEN;​
 +    for (int l = 0; l < cpinsets; l++) {
 +      int i = v_max * l / cpinsets;
 +      huephases[l] = i / HUEPHASE_LEN;​
 +      huephases_i[l] = i % HUEPHASE_LEN;​
 +    }
 +  }
 +
 +  { int huephase = huephases[led],​ huephase_i = huephases_i[led];​
 +  ​
 +#define huephase_to_c_inc(cc) (uint32_t) huephase_i * cmax[led][cc] / HUEPHASE_LEN
 +#define huephase_to_c_dec(cc) (cmax[led][cc] - (uint32_t) huephase_i * cmax[led][cc] / HUEPHASE_LEN)
 +  switch (huephase) {
 +    case 0: c[led][0] = cmax[led][0];​ c[led][1] = huephase_to_c_inc(1);​ c[led][2] = 0; break;
 +    case 1: c[led][0] = huephase_to_c_dec(0);​ c[led][1] = cmax[led][1];​ c[led][2] = 0; break;
 +    case 2: c[led][0] = 0; c[led][1] = cmax[led][1];​ c[led][2] = huephase_to_c_inc(2);​ break;
 +    case 3: c[led][0] = 0; c[led][1] = huephase_to_c_dec(1);​ c[led][2] = cmax[led][2];​ break;
 +    case 4: c[led][0] = huephase_to_c_inc(0);​ c[led][1] = 0; c[led][2] = cmax[led][2];​ break;
 +    case 5: c[led][0] = cmax[led][0];​ c[led][1] = 0; c[led][2] = huephase_to_c_dec(2);​ break;
 +  }
 +  ​
 +  huephase_i++;​
 +  if (huephase_i > HUEPHASE_LEN) {
 +    huephase_i = 0;
 +    huephase = (huephase + 1) % 6;
 +  }
 +  ​
 +  huephases[led] = huephase; huephases_i[led] = huephase_i;
 +  }
 +}
 +
 +/* One iteration of constant brightest white (useful for tuning constants for particular LEDs). */
 +void white(int led)
 +{
 +  int i;
 +  int mask = 1|2|4; // R, G, B
 +  for (i = 0; i < CH; i++) {
 +    c[led][i] = mask & (1 << i) ? cmax[led][i] : 0;
 +  }
 +}
 +
 +
 +void custom(int led)
 +{
 +  long red =   100 - abs (led-9) * 10;
 +  long green = 30;
 +  long blue =  100 - abs(led-1) * 10;
 +  ​
 +  c[led][0] = red  * cmax[led][0] / 100;
 +  c[led][1] = green* cmax[led][1] / 100;
 +  c[led][2] = blue * cmax[led][2] / 100;
 +}
 +
 +
 +/* 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(int led)
 +{
 +  static const int steps = 20;
 +  static int s = 0;
 +  static int d = 1;
 +
 +  int i;
 +  for (i = 0; i < CH; i++) {
 +    c[led][i] = (uint32_t) cmax[led][i] * s / steps;
 +  }
 +  if (s == steps) {
 +    d = -1;
 +  } else if (s == 0) {
 +    d = 1;
 +  }
 +  s += d;
 +}
 +
 +void loop()
 +{
 +  Tlc.clear();​
 +
 +  int led;
 +  for (led = 0; led < cpinsets; led++) {
 +    //​random_walk(led);​
 +    rainbow(led);​
 +    //​white(led);​
 +    //​custom(led);​
 +    //​grey(led);​
 +  }
 +
 +  int i;
 +  for (i = 0; i < CH; i++) {
 +    for (led = 0; led < cpinsets; led++) {
 +      //​Serial.print(cpin[led][i],​ DEC); Serial.print("​="​);​ Serial.print(c[led][i],​ DEC); Serial.print("/"​);​ Serial.print(cmax[led][i],​ DEC); Serial.print("​ ");
 +      Tlc.set(cpin[led][i],​ c[led][i]);
 +    }
 +  }
 +  //​Serial.print(NUM_TLCS,​ DEC);
 +  //​Serial.println();​
 +
 +  /* Tlc.update() sends the data to the TLCs.  This is when the LEDs will
 +     ​actually change. */
 +  Tlc.update();​
 +
 +  delay(wait);​
 +}
 +</​code>​
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Noncommercial-Share Alike 4.0 International
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki