Led fur coat

Status
Not open for further replies.
what type of battery pack are you using, did you not want to include the power pack within the housing?

haha! i'm doing the exact same thing after seeing the exact same guy last year at burning man! here's his facebook - https://www.facebook.com/fflightingreno

and i'm having this exact same problem with the teensy! it's really slow at calculating plasma functions. hilarious!!!

i have 465 lights on my vest. i'm using this battery: http://www.amazon.com/External-Battery-Pack-Limefuel-Flashlight/dp/B00DV81YIA

running the lights with a luminosity value of 8 (of 100) in HSL calculations and they get pretty bright but they don't overload the battery which can only supply 2.1 amps. but this is plenty! and the bonus is that this battery can run for about 4 hours if i'm pulling down all the amps.

20140720_102927_crop.jpg

this photo was taken with the lights running at a luminosity of 4! (note, fur not attached yet).
 
by the way my plasma is running at about 15fps. still too slow for me. i'm using a teensy 3.1.

i use an array for the grid to lookup which lights to draw:

Code:
const int paletteLength = 256;
int rainbowColors[paletteLength];

const int gridLookup[gridPixels] = {
  -1,   -1,   47,   48,   85,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  396,  397,  435,   -1,   -1,
  -1,   -1,   46,   49,   84,   -1,   -1,   -1,   -1,   -1,  150,  151,  186,  187,  222,  223,  258,  259,  294,  295,  330,   -1,   -1,   -1,   -1,   -1,  395,  398,  434,   -1,   -1, 
  -1,   -1,   45,   50,   83,   -1,   -1,   -1,   -1,   -1,  149,  152,  185,  188,  221,  224,  257,  260,  293,  296,  329,   -1,   -1,   -1,   -1,   -1,  394,  399,  433,   -1,   -1, 
  -1,   -1,   44,   51,   82,   -1,   -1,   -1,   -1,   -1,  148,  153,  184,  189,  220,  225,  256,  261,  292,  297,  328,   -1,   -1,   -1,   -1,   -1,  393,  400,  432,   -1,   -1, 
  -1,   -1,   43,   52,   81,   -1,   -1,   -1,   -1,   -1,  147,  154,  183,  190,  219,  226,  255,  262,  291,  298,  327,   -1,   -1,   -1,   -1,   -1,  392,  401,  431,   -1,   -1, 
  -1,   13,   42,   53,   80,   -1,   -1,   -1,   -1,   -1,  146,  155,  182,  191,  218,  227,  254,  263,  290,  299,  326,   -1,   -1,   -1,   -1,   -1,  391,  402,  430,  436,   -1, 
  -1,   14,   41,   54,   79,   -1,   -1,   -1,   -1,   -1,  145,  156,  181,  192,  217,  228,  253,  264,  289,  300,  325,   -1,   -1,   -1,   -1,   -1,  390,  403,  429,  437,   -1, 
  12,   15,   40,   55,   78,   -1,   -1,   -1,   -1,   -1,  144,  157,  180,  193,  216,  229,  252,  265,  288,  301,  324,   -1,   -1,   -1,   -1,   -1,  389,  404,  428,  438,  463, 
  11,   16,   39,   56,   77,   -1,   -1,   -1,   -1,   -1,  143,  158,  179,  194,  215,  230,  251,  266,  287,  302,  323,   -1,   -1,   -1,   -1,   -1,  388,  405,  427,  439,  462, 
  10,   17,   38,   57,   76,   86,   -1,   -1,   -1,  123,  142,  159,  178,  195,  214,  231,  250,  267,  286,  303,  322,  331,   -1,   -1,   -1,  368,  387,  406,  426,  440,  461, 
   9,   18,   37,   58,   75,   87,  104,  105,  122,  124,  141,  160,  177,  196,  213,  232,  249,  268,  285,  304,  321,  332,  349,  350,  367,  369,  386,  407,  425,  441,  460, 
   8,   19,   36,   59,   74,   88,  103,  106,  121,  125,  140,  161,  176,  197,  212,  233,  248,  269,  284,  305,  320,  333,  348,  351,  366,  370,  385,  408,  424,  442,  459, 
   7,   20,   35,   60,   73,   89,  102,  107,  120,  126,  139,  162,  175,  198,  211,  234,  247,  270,  283,  306,  319,  334,  347,  352,  365,  371,  384,  409,  423,  443,  458, 
   6,   21,   34,   61,   72,   90,  101,  108,  119,  127,  138,  163,  174,  199,  210,  235,  246,  271,  282,  307,  318,  335,  346,  353,  364,  372,  383,  410,  422,  444,  457, 
   5,   22,   33,   62,   71,   91,  100,  109,  118,  128,  137,  164,  173,  200,  209,  236,  245,  272,  281,  308,  317,  336,  345,  354,  363,  373,  382,  411,  421,  445,  456, 
   4,   23,   32,   63,   70,   92,   99,  110,  117,  129,  136,  165,  172,  201,  208,  237,  244,  273,  280,  309,  316,  337,  344,  355,  362,  374,  381,  412,  420,  446,  455, 
   3,   24,   31,   64,   69,   93,   98,  111,  116,  130,  135,  166,  171,  202,  207,  238,  243,  274,  279,  310,  315,  338,  343,  356,  361,  375,  380,  413,  419,  447,  454, 
   2,   25,   30,   65,   68,   94,   97,  112,  115,  131,  134,  167,  170,  203,  206,  239,  242,  275,  278,  311,  314,  339,  342,  357,  360,  376,  379,  414,  418,  448,  453, 
   1,   26,   29,   66,   67,   95,   96,  113,  114,  132,  133,  168,  169,  204,  205,  240,  241,  276,  277,  312,  313,  340,  341,  358,  359,  377,  378,  415,  417,  449,  452, 
   0,   27,   28,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  416,  450,  451 };

and i prerender my colour palette:
Code:
void setup() {
  for (int i=0; i<paletteLength; i++) {
    int hue = (float)i/(float)paletteLength*360.0;
    int saturation = 100;
    int lightness = globalBrightness * 100;
    rainbowColors[i] = makeColor(hue, saturation, lightness);
  }
}

and then my plasma just does a time shift to make it "move". it looks pretty good.

(This code has a bug and is VERY SLOW! SEE POST 34 for the final faster unbugged version!)

Code:
double plasmaT = 0.0;

void loop() {
  plasma();
}

void plasma() {
  int  pixelPosition;
  float c;
  int plasmashape = 100;
  int plasmashape2 = 150;
  int plasmashape3 = 40;
  double plasmashape4 = .7;
  int plasmashape5 = 60;
  double speed = .05;
  
  for (int color=0; color < paletteLength; color++) {

    plasmaT += speed;
    if(plasmaT > 100 || plasmaT < 0)
      speed *= -1;

    digitalWrite(1, HIGH);

    for (int yy=0; yy < gridHeight; yy++) {
      for (int xx=0; xx < gridWidth; xx++) {
        pixelPosition = xx + (yy * gridWidth);
        if(gridLookup[pixelPosition]>-1) {
          
          int x = xx*2;
          int y = yy*4;
          
          c = sin(x / plasmashape3);
          c =+ cos(x / plasmashape5 * plasmaT);
          c += sin(dist(x, y, (plasmashape * sin(-plasmaT) + 160), (plasmashape * cos(-plasmaT) + 80)) / plasmashape3);
          c = abs((int)(plasmashape2+(c*plasmashape2)) % 256);
          leds.setPixel(gridLookup[pixelPosition], rainbowColors[(int)c]);
          //Serial.print((int)c);
          //Serial.println(" ");
        }
      }
    }

    leds.show();
    digitalWrite(1, LOW);
    delayMicroseconds(15000);
  }
}


helper functions:
Code:
// Convert HSL (Hue, Saturation, Lightness) to RGB (Red, Green, Blue)
//
//   hue:        0 to 359 - position on the color wheel, 0=red, 60=orange,
//                            120=yellow, 180=green, 240=blue, 300=violet
//
//   saturation: 0 to 100 - how bright or dull the color, 100=full, 0=gray
//
//   lightness:  0 to 100 - how light the color is, 100=white, 50=color, 0=black
//
int makeColor(unsigned int hue, unsigned int saturation, unsigned int lightness) {
	unsigned int red, green, blue;
	unsigned int var1, var2;

	if (hue > 359) hue = hue % 360;
	if (saturation > 100) saturation = 100;
	if (lightness > 100) lightness = 100;

	// algorithm from: http://www.easyrgb.com/index.php?X=MATH&H=19#text19
	if (saturation == 0) {
		red = green = blue = lightness * 255 / 100;
	} else {
		if (lightness < 50) {
			var2 = lightness * (100 + saturation);
		} else {
			var2 = ((lightness + saturation) * 100) - (saturation * lightness);
		}
		var1 = lightness * 200 - var2;
		red = h2rgb(var1, var2, (hue < 240) ? hue + 120 : hue - 240) * 255 / 600000;
		green = h2rgb(var1, var2, hue) * 255 / 600000;
		blue = h2rgb(var1, var2, (hue >= 120) ? hue - 120 : hue + 240) * 255 / 600000;
	}
	return (red << 16) | (green << 8) | blue;
}

double dist(int a, int b, double c, double d) {
  return sqrt(double((a - c) * (a - c) + (b - d) * (b - d)));
}
 
Last edited:
if anyone has any nifty little graphic functions that i can add to this i would love to see them.

i also have a nice little rainbow effect that shifts around the x and y axis over time. it looks a lot like a plasma with straight lines.
 
Your speed problems are not surprising, provided you are using float variables on a Microcontroller without floating point hardware.
 
you should have seen it when i had ALL those variables as floats. it was quite chunky. maybe 5fps. i just tried changing that last float variable to a double and i think i gained a couple extra fps. ;) it's still not as blazing as i would like though. the rainbow effect i'm using is very speedy. it's a variation of the octo rainbow test code thingy.

this runs super duper:
Code:
//rainbow vars
double tiltX = 2.00;
double tiltY = 4.00;
double tiltXShift = 0.03;
double tiltYShift = 0.06;
const double tilXMax = 6.00;
const double tilYMax = 6.00;

void rainbow() {
  int x, y, offset, pixelPosition;
  
  for (int color=0; color < paletteLength; color++) {
    tiltX+=tiltXShift;
    tiltY+=tiltYShift;
    if(tiltX>tilXMax || tiltX<0.00)
      tiltXShift *= -1;
    if(tiltY>tilYMax || tiltY<0.00)
      tiltYShift *= -1;
      
    digitalWrite(1, HIGH);
    for (y=0; y < gridHeight; y++) {
      for (x=0; x < gridWidth; x++) {
        pixelPosition = x + (y * gridWidth);
        
        if(gridLookup[pixelPosition]>-1) {
          int index = (color + (int)((double)x*tiltX) + (int)((double)y*tiltY)) % paletteLength;
          leds.setPixel(gridLookup[pixelPosition], rainbowColors[index]);
        }
      }
    }
    leds.show();
    digitalWrite(1, LOW);
    delayMicroseconds(20000);
  }
}
 
If it were me, I would first try, converting to using floating point math functions instead of double math functions.
Example: sin -> sinf, cos ->cosf ...

I know in my code base for doing hexapod robot IK, where I am experimenting with converting from fixed point math to floating point math, this cut the overhead by a lot. Still no where near as fast as the fixed point functions that are table driven in the normal phoenix code base...
If you are interested, you can see some of the timing differences in the thread http://forums.trossenrobotics.com/showthread.php?6632-PhantomX-using-a-Teensy-3-1/page23
(look at posts 223 and 224)

Kurt
 
i'm a looking at your results correctly:

sin(double) takes ~ 10000us

vs sinf(float) taking ~ 180000us

i think i'll go with the speed over the precision.
 
oh, but i just tried that and wow that did make quite a difference. holy shit balls.

we're up to around 20 - 24 fps now i think.

here's the updated function. SO FAST! Thanks KurtE!

Code:
float plasmaT = 0.0;

void loop() {
  plasma();
}
void plasma() {
  int  pixelPosition;
  float c;
  float plasmashape = 75;
  float plasmashape2 = 127;
  float plasmashape3 = 40.74;
  float plasmashape4 = .727;
  float speed = .05;
  
  for (int color=0; color < paletteLength; color++) {

    plasmaT += speed;
    if(plasmaT > 100 || plasmaT < 0)
      speed *= -1;

    digitalWrite(1, HIGH);

    for (int yy=0; yy < gridHeight; yy++) {
      for (int xx=0; xx < gridWidth; xx++) {
        pixelPosition = xx + (yy * gridWidth);
        if(gridLookup[pixelPosition]>-1) {
          
          int x = xx*2;
          int y = yy*4;
          
          c = sinf(x / plasmashape3);
          c =+ cosf(x / 60.74 - plasmashape4*plasmaT);
          c += sinf(dist(x, y, (plasmashape * sinf(-plasmaT) + 160), (plasmashape * cosf(-plasmaT) + 80)) / plasmashape3);
          c = abs((int)(plasmashape2+(c*plasmashape2)) % 256);
          leds.setPixel(gridLookup[pixelPosition], rainbowColors[(int)c]);
        }
      }
    }  
  
    leds.show();
    digitalWrite(1, LOW);
    delayMicroseconds(15000);
  }
}
 
Last edited:
Your speed problems are not surprising, provided you are using float variables on a Microcontroller without floating point hardware.

does anyone think I would get even faster speeds if I switched from OctoWS2811 to FastSPI instead? I'm only using one strand but the OctoWS2811 is the only one I've been able to get working...
 
10544220_320079451486366_1666951095_n.jpg

here's what it look like with the fur on running with that rainbow palette. i'll post the code to generate four more awesome palettes shortly. ;)
 
Well, hopefully Teensy 3.1++ (or 3.2 or 4.0 or whatever Paul calls it) will be announced soon. One of the features that Paul has hinted at is hardware single precision float support.
 
Status
Not open for further replies.
Back
Top