A simple example to drive an APA-102 LED strip.
Dependencies: mbed APA102b Ping SLCD
main.cpp@3:2788a714b18e, 2015-04-07 (annotated)
- Committer:
- rosienej
- Date:
- Tue Apr 07 13:55:22 2015 +0000
- Revision:
- 3:2788a714b18e
- Parent:
- 2:5a9388a7ac62
- Child:
- 4:50ce957663ee
added modes
Who changed what in which revision?
User | Revision | Line number | New 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 | 0:afc41b8e2360 | 56 | |
rosienej | 0:afc41b8e2360 | 57 | |
rosienej | 0:afc41b8e2360 | 58 | int main() |
rosienej | 0:afc41b8e2360 | 59 | { |
rosienej | 0:afc41b8e2360 | 60 | // Quick example to drive an APA-102 LED Strip from a FRDM-KL46z |
rosienej | 0:afc41b8e2360 | 61 | |
rosienej | 0:afc41b8e2360 | 62 | // http://www.insomnialighting.com/catalog/index.php?main_page=product_info&products_id=61 |
rosienej | 0:afc41b8e2360 | 63 | // Wire the unit up to SPI, common ground and give it 5 volt power. |
rosienej | 0:afc41b8e2360 | 64 | |
rosienej | 0:afc41b8e2360 | 65 | // Shift through the spectrum, slowly rotate. |
rosienej | 0:afc41b8e2360 | 66 | |
rosienej | 0:afc41b8e2360 | 67 | // Setup the spi for 8 bit data, high steady state clock, |
rosienej | 0:afc41b8e2360 | 68 | // second edge capture, with a 1MHz clock rate |
rosienej | 1:2d02f55d47c5 | 69 | |
rosienej | 0:afc41b8e2360 | 70 | int rgb[3]; |
rosienej | 1:2d02f55d47c5 | 71 | unsigned char r,g,b; |
rosienej | 3:2788a714b18e | 72 | //const int N=67; // Number of APA-102 Elements +1 |
rosienej | 3:2788a714b18e | 73 | const int N=144; |
rosienej | 1:2d02f55d47c5 | 74 | int range; |
rosienej | 1:2d02f55d47c5 | 75 | unsigned int Pixel; |
rosienej | 1:2d02f55d47c5 | 76 | unsigned int Pixels[N]; |
rosienej | 0:afc41b8e2360 | 77 | |
rosienej | 2:5a9388a7ac62 | 78 | float hue,sat,ints; |
rosienej | 3:2788a714b18e | 79 | float hue_adjust =0; |
rosienej | 2:5a9388a7ac62 | 80 | |
rosienej | 2:5a9388a7ac62 | 81 | const int NumberOfRays = 19; |
rosienej | 2:5a9388a7ac62 | 82 | |
rosienej | 2:5a9388a7ac62 | 83 | |
rosienej | 2:5a9388a7ac62 | 84 | float RayHues[19] = // hues are 0 to 360, http://en.wikipedia.org/wiki/HSL_and_HSV |
rosienej | 2:5a9388a7ac62 | 85 | {0.0,19.0,38.0,57.0,76.0,95.0,114.0, |
rosienej | 2:5a9388a7ac62 | 86 | 133.0,152.0,171.0,190.0,209.0,228.0, |
rosienej | 2:5a9388a7ac62 | 87 | 247.0,266.0,285.0,304.0,323.0,342.0}; |
rosienej | 2:5a9388a7ac62 | 88 | |
rosienej | 2:5a9388a7ac62 | 89 | float RaySats[19] = // hues are 0 to 360, http://en.wikipedia.org/wiki/HSL_and_HSV |
rosienej | 2:5a9388a7ac62 | 90 | {0.8,0.8,0.8,0.8,0.8,0.8,0.8, |
rosienej | 2:5a9388a7ac62 | 91 | 0.8,0.8,0.8,0.8,0.8,0.8,0.8, |
rosienej | 2:5a9388a7ac62 | 92 | 0.8,0.8,0.8,0.8,0.8}; |
rosienej | 2:5a9388a7ac62 | 93 | |
rosienej | 2:5a9388a7ac62 | 94 | float RayInts[19] = // hues are 0 to 360, http://en.wikipedia.org/wiki/HSL_and_HSV |
rosienej | 2:5a9388a7ac62 | 95 | {0.8,0.8,0.8,0.8,0.8,0.8,0.8, |
rosienej | 2:5a9388a7ac62 | 96 | 0.8,0.8,0.8,0.8,0.8,0.8,0.8, |
rosienej | 2:5a9388a7ac62 | 97 | 0.8,0.8,0.8,0.8,0.8}; |
rosienej | 2:5a9388a7ac62 | 98 | |
rosienej | 2:5a9388a7ac62 | 99 | 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 | 100 | |
rosienej | 2:5a9388a7ac62 | 101 | int Rays[19][5] = { |
rosienej | 2:5a9388a7ac62 | 102 | {1 ,20,39, 0, 0}, //3 |
rosienej | 2:5a9388a7ac62 | 103 | {2 ,21,40,53, 0}, //4 |
rosienej | 2:5a9388a7ac62 | 104 | {3 ,22,41,54,64}, //5 |
rosienej | 2:5a9388a7ac62 | 105 | {4 ,23,42,55, 0}, //4 |
rosienej | 2:5a9388a7ac62 | 106 | {5 ,24, 0, 0, 0}, //2 |
rosienej | 2:5a9388a7ac62 | 107 | {6 ,25,43,56,65}, //5 |
rosienej | 2:5a9388a7ac62 | 108 | {7 ,26,44,57, 0}, //4 |
rosienej | 2:5a9388a7ac62 | 109 | {8 ,27, 0, 0, 0}, //2 |
rosienej | 2:5a9388a7ac62 | 110 | {9 ,28,45,58, 0}, //4 |
rosienej | 2:5a9388a7ac62 | 111 | {10,29,46,59,66}, //5 |
rosienej | 2:5a9388a7ac62 | 112 | {11,30,47, 0, 0}, //3 |
rosienej | 2:5a9388a7ac62 | 113 | {12,31,48,60, 0}, //4 |
rosienej | 2:5a9388a7ac62 | 114 | {13,32,49, 0, 0}, //3 |
rosienej | 2:5a9388a7ac62 | 115 | {14,33, 0, 0, 0}, //2 |
rosienej | 2:5a9388a7ac62 | 116 | {15,34, 0, 0, 0}, //2 |
rosienej | 2:5a9388a7ac62 | 117 | {16,35,50, 0, 0}, //3 |
rosienej | 2:5a9388a7ac62 | 118 | {17,36, 0, 0, 0}, //2 |
rosienej | 2:5a9388a7ac62 | 119 | {18,37,51,61,0}, //4 |
rosienej | 2:5a9388a7ac62 | 120 | {19,38,52,62,63}}; //5 |
rosienej | 2:5a9388a7ac62 | 121 | |
rosienej | 2:5a9388a7ac62 | 122 | |
rosienej | 0:afc41b8e2360 | 123 | int colors=0x000000; |
rosienej | 3:2788a714b18e | 124 | |
rosienej | 3:2788a714b18e | 125 | int Mode=0; |
rosienej | 3:2788a714b18e | 126 | const int NModes = 4; |
rosienej | 3:2788a714b18e | 127 | |
rosienej | 1:2d02f55d47c5 | 128 | LEDs.SetBuffer(Pixels,1,N, N,0, false,false); |
rosienej | 3:2788a714b18e | 129 | slcd.Home(); |
rosienej | 3:2788a714b18e | 130 | slcd.printf("%d",Mode); |
rosienej | 3:2788a714b18e | 131 | |
rosienej | 0:afc41b8e2360 | 132 | while (true) { |
rosienej | 1:2d02f55d47c5 | 133 | ping.Send(); |
rosienej | 1:2d02f55d47c5 | 134 | wait_ms(50); // update rate. |
rosienej | 1:2d02f55d47c5 | 135 | range = ping.Read_cm(); |
rosienej | 3:2788a714b18e | 136 | colors+=range/10; |
rosienej | 3:2788a714b18e | 137 | |
rosienej | 3:2788a714b18e | 138 | if (!Button ){ |
rosienej | 3:2788a714b18e | 139 | Mode++; |
rosienej | 3:2788a714b18e | 140 | Mode = (Mode %NModes); |
rosienej | 3:2788a714b18e | 141 | slcd.Home(); |
rosienej | 3:2788a714b18e | 142 | slcd.printf("%d",Mode); |
rosienej | 3:2788a714b18e | 143 | |
rosienej | 3:2788a714b18e | 144 | } |
rosienej | 3:2788a714b18e | 145 | |
rosienej | 3:2788a714b18e | 146 | switch(Mode){ |
rosienej | 3:2788a714b18e | 147 | case 0: hue_adjust =0; |
rosienej | 3:2788a714b18e | 148 | break; // just display the last "static" image |
rosienej | 3:2788a714b18e | 149 | case 1: hue_adjust = range; // rotate the hue by the range |
rosienej | 3:2788a714b18e | 150 | break; |
rosienej | 3:2788a714b18e | 151 | case 2: hue_adjust = colors; // change the spin rate by the range |
rosienej | 3:2788a714b18e | 152 | break; |
rosienej | 3:2788a714b18e | 153 | case 3: hue_adjust++; // spin at a fixed rate |
rosienej | 3:2788a714b18e | 154 | break; |
rosienej | 3:2788a714b18e | 155 | |
rosienej | 3:2788a714b18e | 156 | } |
rosienej | 0:afc41b8e2360 | 157 | |
rosienej | 0:afc41b8e2360 | 158 | |
rosienej | 2:5a9388a7ac62 | 159 | for(int i=0;i<NumberOfRays;i++) |
rosienej | 1:2d02f55d47c5 | 160 | { |
rosienej | 2:5a9388a7ac62 | 161 | for(int j=0;j<RayLengths[i];j++) |
rosienej | 2:5a9388a7ac62 | 162 | { |
rosienej | 2:5a9388a7ac62 | 163 | for(int k=0;k<j;k++) |
rosienej | 2:5a9388a7ac62 | 164 | { |
rosienej | 3:2788a714b18e | 165 | hue = RayHues[i]+ hue_adjust; |
rosienej | 2:5a9388a7ac62 | 166 | sat = RaySats[i]; |
rosienej | 2:5a9388a7ac62 | 167 | ints = RayInts[i]; |
rosienej | 2:5a9388a7ac62 | 168 | hsi2rgb(hue, sat, ints,rgb); |
rosienej | 2:5a9388a7ac62 | 169 | r = rgb[0]; |
rosienej | 2:5a9388a7ac62 | 170 | g = rgb[1]; |
rosienej | 2:5a9388a7ac62 | 171 | b = rgb[2]; |
rosienej | 2:5a9388a7ac62 | 172 | |
rosienej | 2:5a9388a7ac62 | 173 | Pixel=LEDs.IRGB(7,r,g,b); |
rosienej | 2:5a9388a7ac62 | 174 | Pixels[Rays[i][k]-1]=Pixel; // arrays in C++ start at zero. Need to subtract 1. |
rosienej | 2:5a9388a7ac62 | 175 | } |
rosienej | 0:afc41b8e2360 | 176 | } |
rosienej | 2:5a9388a7ac62 | 177 | } |
rosienej | 3:2788a714b18e | 178 | /* |
rosienej | 3:2788a714b18e | 179 | for(int i=0;i<N;i++) |
rosienej | 3:2788a714b18e | 180 | { |
rosienej | 3:2788a714b18e | 181 | hue = (1.0*i)/(1.0*N) * 360 + hue_adjust; |
rosienej | 3:2788a714b18e | 182 | sat = 0.8; |
rosienej | 3:2788a714b18e | 183 | ints = 0.7; |
rosienej | 3:2788a714b18e | 184 | hsi2rgb(hue, sat, ints,rgb); |
rosienej | 3:2788a714b18e | 185 | r = rgb[0]; |
rosienej | 3:2788a714b18e | 186 | g = rgb[1]; |
rosienej | 3:2788a714b18e | 187 | b = rgb[2]; |
rosienej | 3:2788a714b18e | 188 | |
rosienej | 3:2788a714b18e | 189 | Pixel=LEDs.IRGB(7,r,g,b); |
rosienej | 3:2788a714b18e | 190 | Pixels[i]=Pixel; |
rosienej | 3:2788a714b18e | 191 | } |
rosienej | 3:2788a714b18e | 192 | */ |
rosienej | 1:2d02f55d47c5 | 193 | LEDs.Repaint(); |
rosienej | 3:2788a714b18e | 194 | |
rosienej | 0:afc41b8e2360 | 195 | } |
rosienej | 0:afc41b8e2360 | 196 | } |