project:ledbar:sketch-autonomous
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| project:ledbar:sketch-autonomous [2011/04/20 20:51] – created pasky | project:ledbar:sketch-autonomous [2011/09/18 17:00] (current) – pasky | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ===== Ledbar: Arduino-autonomous control ===== | ||
| + | You also need the TLC5940 library downloaded in ~/ | ||
| + | |||
| + | < | ||
| + | #include " | ||
| + | |||
| + | #define CH 3 | ||
| + | |||
| + | #define TLCCH(tlc_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, 15), | ||
| + | |||
| + | {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)/ | ||
| + | |||
| + | /* 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); | ||
| + | |||
| + | c[led][i] += g[led][i]; | ||
| + | if (c[led][i] < 0) { c[led][i] = 0; g[led][i] = -g[led][i] + r(maxbounce)-maxbounce/ | ||
| + | } | ||
| + | } | ||
| + | |||
| + | 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], | ||
| + | | ||
| + | #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]; | ||
| + | case 1: c[led][0] = huephase_to_c_dec(0); | ||
| + | case 2: c[led][0] = 0; c[led][1] = cmax[led][1]; | ||
| + | case 3: c[led][0] = 0; c[led][1] = huephase_to_c_dec(1); | ||
| + | case 4: c[led][0] = huephase_to_c_inc(0); | ||
| + | case 5: c[led][0] = cmax[led][0]; | ||
| + | } | ||
| + | | ||
| + | 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 " | ||
| + | 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++) { | ||
| + | // | ||
| + | rainbow(led); | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | } | ||
| + | |||
| + | int i; | ||
| + | for (i = 0; i < CH; i++) { | ||
| + | for (led = 0; led < cpinsets; led++) { | ||
| + | // | ||
| + | Tlc.set(cpin[led][i], | ||
| + | } | ||
| + | } | ||
| + | // | ||
| + | // | ||
| + | |||
| + | /* Tlc.update() sends the data to the TLCs. This is when the LEDs will | ||
| + | | ||
| + | Tlc.update(); | ||
| + | |||
| + | delay(wait); | ||
| + | } | ||
| + | </ | ||