A simple example to drive an APA-102 LED strip.

Dependencies:   mbed APA102b Ping SLCD

Committer:
rosienej
Date:
Tue Apr 14 00:15:32 2015 +0000
Revision:
6:27f43abd16e2
Parent:
4:50ce957663ee
added a few more modes;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rosienej 0:afc41b8e2360 1 #include "mbed.h"
rosienej 1:2d02f55d47c5 2 #include "Ping.h"
rosienej 3:2788a714b18e 3 #include "SLCD.h"
rosienej 3:2788a714b18e 4
rosienej 1:2d02f55d47c5 5 #include "APA102a.h"
rosienej 0:afc41b8e2360 6
rosienej 3:2788a714b18e 7 SLCD slcd;
rosienej 3:2788a714b18e 8 DigitalIn Button(PTC12);
rosienej 1:2d02f55d47c5 9 Ping ping(PTA13);
rosienej 1:2d02f55d47c5 10
rosienej 1:2d02f55d47c5 11 APA102a LEDs(PTA16, PTA17, PTA15,1000000); // mosi, miso, sclk, rate
rosienej 0:afc41b8e2360 12
rosienej 0:afc41b8e2360 13 // This function was downloaded from:
rosienej 0:afc41b8e2360 14 // http://blog.saikoled.com/post/43693602826/why-every-led-light-should-be-using-hsi
rosienej 0:afc41b8e2360 15 // Blog Post attributed to Brian Neltner
rosienej 0:afc41b8e2360 16
rosienej 0:afc41b8e2360 17 // Function example takes H, S, I, and a pointer to the
rosienej 0:afc41b8e2360 18 // returned RGB colorspace converted vector. It should
rosienej 0:afc41b8e2360 19 // be initialized with:
rosienej 0:afc41b8e2360 20 //
rosienej 0:afc41b8e2360 21 // int rgb[3];
rosienej 0:afc41b8e2360 22 //
rosienej 0:afc41b8e2360 23 // in the calling function. After calling hsi2rgb
rosienej 0:afc41b8e2360 24 // the vector rgb will contain red, green, and blue
rosienej 0:afc41b8e2360 25 // calculated values.
rosienej 0:afc41b8e2360 26 //
rosienej 0:afc41b8e2360 27
rosienej 0:afc41b8e2360 28 void hsi2rgb(float H, float S, float I, int* rgb) {
rosienej 0:afc41b8e2360 29
rosienej 0:afc41b8e2360 30 int r, g, b;
rosienej 0:afc41b8e2360 31 H = fmod(H,360); // cycle H around to 0-360 degrees
rosienej 0:afc41b8e2360 32 H = 3.14159*H/(float)180; // Convert to radians.
rosienej 0:afc41b8e2360 33 S = S>0?(S<1?S:1):0; // clamp S and I to interval [0,1]
rosienej 0:afc41b8e2360 34 I = I>0?(I<1?I:1):0;
rosienej 0:afc41b8e2360 35
rosienej 0:afc41b8e2360 36 // Math! Thanks in part to Kyle Miller.
rosienej 0:afc41b8e2360 37 if(H < 2.09439) {
rosienej 0:afc41b8e2360 38 r = 255*I/3*(1+S*cos(H)/cos(1.047196667-H));
rosienej 0:afc41b8e2360 39 g = 255*I/3*(1+S*(1-cos(H)/cos(1.047196667-H)));
rosienej 0:afc41b8e2360 40 b = 255*I/3*(1-S);
rosienej 0:afc41b8e2360 41 } else if(H < 4.188787) {
rosienej 0:afc41b8e2360 42 H = H - 2.09439;
rosienej 0:afc41b8e2360 43 g = 255*I/3*(1+S*cos(H)/cos(1.047196667-H));
rosienej 0:afc41b8e2360 44 b = 255*I/3*(1+S*(1-cos(H)/cos(1.047196667-H)));
rosienej 0:afc41b8e2360 45 r = 255*I/3*(1-S);
rosienej 0:afc41b8e2360 46 } else {
rosienej 0:afc41b8e2360 47 H = H - 4.188787;
rosienej 0:afc41b8e2360 48 b = 255*I/3*(1+S*cos(H)/cos(1.047196667-H));
rosienej 0:afc41b8e2360 49 r = 255*I/3*(1+S*(1-cos(H)/cos(1.047196667-H)));
rosienej 0:afc41b8e2360 50 g = 255*I/3*(1-S);
rosienej 0:afc41b8e2360 51 }
rosienej 0:afc41b8e2360 52 rgb[0]=r;
rosienej 0:afc41b8e2360 53 rgb[1]=g;
rosienej 0:afc41b8e2360 54 rgb[2]=b;
rosienej 0:afc41b8e2360 55 }
rosienej 6:27f43abd16e2 56 /// pseudo random number
rosienej 6:27f43abd16e2 57 unsigned int m_z=12434,m_w=33254;
rosienej 0:afc41b8e2360 58
rosienej 6:27f43abd16e2 59 unsigned int rnd() {
rosienej 6:27f43abd16e2 60 m_z = 36969 * (m_z & 65535) + (m_z >>16);
rosienej 6:27f43abd16e2 61 m_w = 18000 * (m_w & 65535) + (m_w >>16);
rosienej 6:27f43abd16e2 62 return ((m_z <<16) + m_w);
rosienej 6:27f43abd16e2 63 }
rosienej 0:afc41b8e2360 64
rosienej 0:afc41b8e2360 65 int main()
rosienej 0:afc41b8e2360 66 {
rosienej 0:afc41b8e2360 67 // Quick example to drive an APA-102 LED Strip from a FRDM-KL46z
rosienej 0:afc41b8e2360 68
rosienej 0:afc41b8e2360 69 // http://www.insomnialighting.com/catalog/index.php?main_page=product_info&products_id=61
rosienej 0:afc41b8e2360 70 // Wire the unit up to SPI, common ground and give it 5 volt power.
rosienej 0:afc41b8e2360 71
rosienej 0:afc41b8e2360 72 // Shift through the spectrum, slowly rotate.
rosienej 0:afc41b8e2360 73
rosienej 0:afc41b8e2360 74 // Setup the spi for 8 bit data, high steady state clock,
rosienej 0:afc41b8e2360 75 // second edge capture, with a 1MHz clock rate
rosienej 1:2d02f55d47c5 76
rosienej 0:afc41b8e2360 77 int rgb[3];
rosienej 1:2d02f55d47c5 78 unsigned char r,g,b;
rosienej 4:50ce957663ee 79 const int N=66; // Number of APA-102 Elements
rosienej 6:27f43abd16e2 80 // const int N=144;
rosienej 1:2d02f55d47c5 81 int range;
rosienej 1:2d02f55d47c5 82 unsigned int Pixel;
rosienej 1:2d02f55d47c5 83 unsigned int Pixels[N];
rosienej 0:afc41b8e2360 84
rosienej 2:5a9388a7ac62 85 float hue,sat,ints;
rosienej 3:2788a714b18e 86 float hue_adjust =0;
rosienej 2:5a9388a7ac62 87
rosienej 2:5a9388a7ac62 88 const int NumberOfRays = 19;
rosienej 2:5a9388a7ac62 89
rosienej 2:5a9388a7ac62 90
rosienej 2:5a9388a7ac62 91 float RayHues[19] = // hues are 0 to 360, http://en.wikipedia.org/wiki/HSL_and_HSV
rosienej 2:5a9388a7ac62 92 {0.0,19.0,38.0,57.0,76.0,95.0,114.0,
rosienej 2:5a9388a7ac62 93 133.0,152.0,171.0,190.0,209.0,228.0,
rosienej 2:5a9388a7ac62 94 247.0,266.0,285.0,304.0,323.0,342.0};
rosienej 2:5a9388a7ac62 95
rosienej 2:5a9388a7ac62 96 float RaySats[19] = // hues are 0 to 360, http://en.wikipedia.org/wiki/HSL_and_HSV
rosienej 2:5a9388a7ac62 97 {0.8,0.8,0.8,0.8,0.8,0.8,0.8,
rosienej 2:5a9388a7ac62 98 0.8,0.8,0.8,0.8,0.8,0.8,0.8,
rosienej 2:5a9388a7ac62 99 0.8,0.8,0.8,0.8,0.8};
rosienej 2:5a9388a7ac62 100
rosienej 2:5a9388a7ac62 101 float RayInts[19] = // hues are 0 to 360, http://en.wikipedia.org/wiki/HSL_and_HSV
rosienej 2:5a9388a7ac62 102 {0.8,0.8,0.8,0.8,0.8,0.8,0.8,
rosienej 2:5a9388a7ac62 103 0.8,0.8,0.8,0.8,0.8,0.8,0.8,
rosienej 2:5a9388a7ac62 104 0.8,0.8,0.8,0.8,0.8};
rosienej 2:5a9388a7ac62 105
rosienej 2:5a9388a7ac62 106 int RayLengths[19] = {3, 4, 5, 4, 2, 5, 4, 2, 4,5,3,4,3,2,2,3,2,4,5};
rosienej 2:5a9388a7ac62 107
rosienej 2:5a9388a7ac62 108 int Rays[19][5] = {
rosienej 2:5a9388a7ac62 109 {1 ,20,39, 0, 0}, //3
rosienej 2:5a9388a7ac62 110 {2 ,21,40,53, 0}, //4
rosienej 2:5a9388a7ac62 111 {3 ,22,41,54,64}, //5
rosienej 2:5a9388a7ac62 112 {4 ,23,42,55, 0}, //4
rosienej 2:5a9388a7ac62 113 {5 ,24, 0, 0, 0}, //2
rosienej 2:5a9388a7ac62 114 {6 ,25,43,56,65}, //5
rosienej 2:5a9388a7ac62 115 {7 ,26,44,57, 0}, //4
rosienej 2:5a9388a7ac62 116 {8 ,27, 0, 0, 0}, //2
rosienej 2:5a9388a7ac62 117 {9 ,28,45,58, 0}, //4
rosienej 2:5a9388a7ac62 118 {10,29,46,59,66}, //5
rosienej 2:5a9388a7ac62 119 {11,30,47, 0, 0}, //3
rosienej 2:5a9388a7ac62 120 {12,31,48,60, 0}, //4
rosienej 2:5a9388a7ac62 121 {13,32,49, 0, 0}, //3
rosienej 2:5a9388a7ac62 122 {14,33, 0, 0, 0}, //2
rosienej 2:5a9388a7ac62 123 {15,34, 0, 0, 0}, //2
rosienej 2:5a9388a7ac62 124 {16,35,50, 0, 0}, //3
rosienej 2:5a9388a7ac62 125 {17,36, 0, 0, 0}, //2
rosienej 2:5a9388a7ac62 126 {18,37,51,61,0}, //4
rosienej 2:5a9388a7ac62 127 {19,38,52,62,63}}; //5
rosienej 2:5a9388a7ac62 128
rosienej 2:5a9388a7ac62 129
rosienej 0:afc41b8e2360 130 int colors=0x000000;
rosienej 3:2788a714b18e 131
rosienej 3:2788a714b18e 132 int Mode=0;
rosienej 6:27f43abd16e2 133 const int NModes = 8;
rosienej 3:2788a714b18e 134
rosienej 1:2d02f55d47c5 135 LEDs.SetBuffer(Pixels,1,N, N,0, false,false);
rosienej 3:2788a714b18e 136 slcd.Home();
rosienej 3:2788a714b18e 137 slcd.printf("%d",Mode);
rosienej 6:27f43abd16e2 138
rosienej 6:27f43abd16e2 139
rosienej 3:2788a714b18e 140
rosienej 0:afc41b8e2360 141 while (true) {
rosienej 1:2d02f55d47c5 142 ping.Send();
rosienej 1:2d02f55d47c5 143 wait_ms(50); // update rate.
rosienej 1:2d02f55d47c5 144 range = ping.Read_cm();
rosienej 3:2788a714b18e 145 colors+=range/10;
rosienej 3:2788a714b18e 146
rosienej 3:2788a714b18e 147 if (!Button ){
rosienej 3:2788a714b18e 148 Mode++;
rosienej 3:2788a714b18e 149 Mode = (Mode %NModes);
rosienej 3:2788a714b18e 150 slcd.Home();
rosienej 3:2788a714b18e 151 slcd.printf("%d",Mode);
rosienej 3:2788a714b18e 152
rosienej 3:2788a714b18e 153 }
rosienej 3:2788a714b18e 154
rosienej 6:27f43abd16e2 155 for(int i = 0;i<19;i++) RaySats[i] = 0.8;
rosienej 6:27f43abd16e2 156 for(int i = 0;i<19;i++) RayInts[i] = 0.8;
rosienej 6:27f43abd16e2 157
rosienej 6:27f43abd16e2 158
rosienej 3:2788a714b18e 159 switch(Mode){
rosienej 3:2788a714b18e 160 case 0: hue_adjust =0;
rosienej 3:2788a714b18e 161 break; // just display the last "static" image
rosienej 3:2788a714b18e 162 case 1: hue_adjust = range; // rotate the hue by the range
rosienej 3:2788a714b18e 163 break;
rosienej 3:2788a714b18e 164 case 2: hue_adjust = colors; // change the spin rate by the range
rosienej 3:2788a714b18e 165 break;
rosienej 3:2788a714b18e 166 case 3: hue_adjust++; // spin at a fixed rate
rosienej 3:2788a714b18e 167 break;
rosienej 6:27f43abd16e2 168 case 4: for(int i = 0;i<19;i++) RaySats[i] = 1.0/(1.0*(rnd()%16+1));
rosienej 6:27f43abd16e2 169 break;
rosienej 6:27f43abd16e2 170 case 5: for(int i = 0;i<19;i++) RayInts[i] = 1.0/(1.0*(rnd()%16+1));
rosienej 6:27f43abd16e2 171 break;
rosienej 6:27f43abd16e2 172 case 6: for(int i = 0;i<19;i++) RayInts[i] = 1.0/(1.0*(rnd()%16+1));
rosienej 6:27f43abd16e2 173 for(int i = 0;i<19;i++) RaySats[i] = 1.0/(1.0*(rnd()%16+1));
rosienej 6:27f43abd16e2 174 break;
rosienej 6:27f43abd16e2 175 case 7: hue_adjust = rnd()%16;
rosienej 6:27f43abd16e2 176 break;
rosienej 3:2788a714b18e 177
rosienej 3:2788a714b18e 178 }
rosienej 0:afc41b8e2360 179
rosienej 0:afc41b8e2360 180
rosienej 2:5a9388a7ac62 181 for(int i=0;i<NumberOfRays;i++)
rosienej 1:2d02f55d47c5 182 {
rosienej 2:5a9388a7ac62 183 for(int j=0;j<RayLengths[i];j++)
rosienej 2:5a9388a7ac62 184 {
rosienej 6:27f43abd16e2 185
rosienej 3:2788a714b18e 186 hue = RayHues[i]+ hue_adjust;
rosienej 2:5a9388a7ac62 187 sat = RaySats[i];
rosienej 2:5a9388a7ac62 188 ints = RayInts[i];
rosienej 2:5a9388a7ac62 189 hsi2rgb(hue, sat, ints,rgb);
rosienej 2:5a9388a7ac62 190 r = rgb[0];
rosienej 2:5a9388a7ac62 191 g = rgb[1];
rosienej 2:5a9388a7ac62 192 b = rgb[2];
rosienej 2:5a9388a7ac62 193
rosienej 2:5a9388a7ac62 194 Pixel=LEDs.IRGB(7,r,g,b);
rosienej 6:27f43abd16e2 195 Pixels[Rays[i][j]-1]=Pixel; // arrays in C++ start at zero. Need to subtract 1.
rosienej 6:27f43abd16e2 196
rosienej 0:afc41b8e2360 197 }
rosienej 2:5a9388a7ac62 198 }
rosienej 3:2788a714b18e 199 /*
rosienej 3:2788a714b18e 200 for(int i=0;i<N;i++)
rosienej 3:2788a714b18e 201 {
rosienej 3:2788a714b18e 202 hue = (1.0*i)/(1.0*N) * 360 + hue_adjust;
rosienej 3:2788a714b18e 203 sat = 0.8;
rosienej 3:2788a714b18e 204 ints = 0.7;
rosienej 3:2788a714b18e 205 hsi2rgb(hue, sat, ints,rgb);
rosienej 3:2788a714b18e 206 r = rgb[0];
rosienej 3:2788a714b18e 207 g = rgb[1];
rosienej 3:2788a714b18e 208 b = rgb[2];
rosienej 3:2788a714b18e 209
rosienej 3:2788a714b18e 210 Pixel=LEDs.IRGB(7,r,g,b);
rosienej 3:2788a714b18e 211 Pixels[i]=Pixel;
rosienej 3:2788a714b18e 212 }
rosienej 3:2788a714b18e 213 */
rosienej 1:2d02f55d47c5 214 LEDs.Repaint();
rosienej 3:2788a714b18e 215
rosienej 0:afc41b8e2360 216 }
rosienej 0:afc41b8e2360 217 }