project:ledbar:sketch-autonomous
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
project:ledbar:sketch-autonomous [2011/09/18 15:42] – current version 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); | ||
+ | } | ||
+ | </ |
project/ledbar/sketch-autonomous.txt · Last modified: 2011/09/18 17:00 by pasky