Test program for my Multi_WS2811 library that started out as a fork of heroic/WS2811. My library uses hardware DMA on the FRDM-KL25Z to drive up to 16 strings of WS2811 or WS2812 LEDs in parallel.
Dependencies: Multi_WS2811 mbed MMA8451Q
Fork of WS2811 by
main.cpp
00001 #include "mbed.h" 00002 #include "Colors.h" 00003 #include "MMA8451Q.h" 00004 00005 #define MMA8451_I2C_ADDRESS (0x1d<<1) 00006 00007 #define INSTANTIATE_TEMPLATES 1 00008 #include "WS2811.h" 00009 00010 #include "audio.h" 00011 using namespace NKAudio; 00012 00013 #include "1khz_1sec.h" 00014 00015 AudioFile audioFiles[] = { 00016 { __1khz_1sec_s8, __1khz_1sec_s8_len }, 00017 { 0, 0 } // mark end 00018 }; 00019 00020 // I/O pin usage 00021 // PTD2 (D11) data output for strip# 1 00022 // PTD3 (D12) data output for strip# 2 00023 // PTA12 (D3) servomotor (20 msec period; 1.0-2.0msec ON) 00024 // PTA5 (D5) blinking eyes output (HI = ON) 00025 // PTE30 00026 00027 const unsigned DATA_OUT_PIN1 = 2; // PTD2 00028 const unsigned DATA_OUT_PIN2 = 3; // PTD3 00029 00030 // actually, sides have 21 LEDs each, and ends have 10 LEDs each. 00031 const unsigned MAX_LEDS_PER_STRIP = 31; 00032 00033 // per LED: 3 * 20 mA = 60mA max 00034 // 60 LEDs: 60 * 60mA = 3600 mA max 00035 // 120 LEDs: 7200 mA max 00036 const unsigned nLEDs = MAX_LEDS_PER_STRIP; 00037 00038 template class WS2811<MAX_LEDS_PER_STRIP>; 00039 00040 typedef WS2811<MAX_LEDS_PER_STRIP> MyWS2811; 00041 00042 static MyWS2811 lightStrip1(nLEDs, DATA_OUT_PIN1); 00043 static MyWS2811 lightStrip2(nLEDs, DATA_OUT_PIN2); 00044 00045 Serial pc(USBTX, USBRX); 00046 00047 // accelerometer 00048 static MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS); 00049 00050 // RGB LED on FRDM board 00051 static DigitalOut rled(LED_RED); // PTB18 max = 0.0 00052 static DigitalOut gled(LED_GREEN); // PTB19 max = 0.0 00053 // LED_BLUE is on PTD1 00054 00055 static PwmOut servo(D3); // PTA12 00056 static DigitalOut eyes(D5); // PTA5 00057 00058 // static DigitalOut greenLED2(D4); // max = 1.0 00059 static DigitalIn button1(D6); // low=ON, debounced 00060 // static DigitalIn button2(D7); // low=ON, debounced 00061 00062 // Limits 00063 const float maxBrite = 0.5; 00064 const float minServo = -0.7; // -1.0 = -60° 00065 const float maxServo = 0.6; // 1.0 = +60° 00066 00067 // const float minFlapTime = (maxServo - minServo) * 0.17; // 0.17 seconds / 60° at 4.8V 00068 const float minFlapTime = 0.5; 00069 const float maxFlapTime = 1.0; 00070 float currentPosition = 1.0; 00071 float currentSpeed = 1.0; 00072 00073 // @brief sets different colors in each of the LEDs of a strip 00074 // @param strip the light strip 00075 // @param sat saturation, 0.0 - 1.0 00076 // @param brite brightness, 0.0 - 1.0 00077 // @param hueShift shift, 0.0 - 1.0 is equivalent to 0 - 360 degrees 00078 static void showRainbow(MyWS2811 &strip, float sat, float brite, float hueShift, float hueRange = 1.0, int span = 1, int skip=0) 00079 { 00080 int nLEDs = strip.numPixels(); 00081 int direction, first, last; 00082 00083 if (span < 0) { 00084 direction = -1; 00085 first = nLEDs-1; 00086 last = -1; 00087 span = -span; 00088 skip = -skip; 00089 } else { 00090 direction = 1; 00091 first = 0; 00092 last = nLEDs; 00093 } 00094 00095 for (int i = first; i != last; i += direction) { 00096 uint8_t r, g, b; 00097 float hue = (i * hueRange / nLEDs) + hueShift; 00098 HSBtoRGB(hue, sat, brite, &r, &g, &b); 00099 if ((i + skip) % span == 0) 00100 strip.setPixelColor((unsigned)i, r, g, b); 00101 else 00102 strip.setPixelColor((unsigned)i, 0, 0, 0); 00103 } 00104 strip.show(); 00105 } 00106 00107 static void showSolidColor(MyWS2811 &strip, uint8_t r, uint8_t g, uint8_t b) 00108 { 00109 unsigned nLEDs = strip.numPixels(); 00110 for (unsigned i = 0; i < nLEDs; i++) { 00111 strip.setPixelColor(i, r, g, b); 00112 } 00113 strip.show(); 00114 } 00115 00116 // range is -1.0 (full CCW) to +1.0 (full CW) 00117 static void positionServo(float pos) 00118 { 00119 if (pos < minServo) 00120 pos = minServo; 00121 else if (pos > maxServo) 00122 pos = maxServo; 00123 00124 if (pos < 0.0) { 00125 rled = 0; 00126 gled = 1; 00127 } else if (pos > 0.0) { 00128 rled = 1; 00129 gled = 0; 00130 } else { 00131 rled = gled = 1; 00132 } 00133 00134 servo.pulsewidth_us((1.5 + (pos / 2.0)) * 1000.0); 00135 } 00136 00137 void flap() 00138 { 00139 positionServo(currentPosition); 00140 currentPosition = -currentPosition; 00141 } 00142 00143 static void selfTestServo() 00144 { 00145 pc.printf("Servo:\r\n"); 00146 pc.printf("CCW, "); 00147 positionServo(-1.0); 00148 wait(1.0); 00149 pc.printf("CW, "); 00150 positionServo(+1.0); 00151 wait(1.0); 00152 pc.printf("center.\r\n"); 00153 positionServo(0.0); 00154 } 00155 00156 static void selfTestLEDs() 00157 { 00158 pc.printf("LEDs ."); 00159 rled = 0; // red LED on 00160 wait(0.5); 00161 pc.printf("."); 00162 rled = 1; // red LED off, green LED on 00163 gled = 0; 00164 wait(0.5); 00165 pc.printf("."); 00166 gled = 1; // green LED off, eyes on 00167 eyes = 1; 00168 wait(0.5); 00169 pc.printf("."); 00170 eyes = 0; 00171 pc.printf("\r\n"); 00172 } 00173 00174 static void refreshLightStrips() 00175 { 00176 MyWS2811::startDMA(); 00177 // 24 bits per LED, 800kHz (1.25usec/bit) 00178 // wait_us((MAX_LEDS_PER_STRIP * 24 * 10 / 8) + 100); 00179 } 00180 00181 static void blankLightStrips() 00182 { 00183 showSolidColor(lightStrip1, 0, 0, 0); 00184 showSolidColor(lightStrip2, 0, 0, 0); 00185 refreshLightStrips(); 00186 } 00187 00188 static void selfTestLightStrips() 00189 { 00190 blankLightStrips(); 00191 pc.printf("light strips"); 00192 uint8_t rgb[4] = { (uint8_t)(255 * maxBrite), 0, 0, 0 }; 00193 for (int i = 0; i < 3; i++) { 00194 showSolidColor(lightStrip1, rgb[0], rgb[1], rgb[2]); 00195 showSolidColor(lightStrip2, rgb[1], rgb[2], rgb[0]); 00196 refreshLightStrips(); 00197 wait(1.0); 00198 rgb[3] = rgb[2]; 00199 rgb[2] = rgb[1]; 00200 rgb[1] = rgb[0]; 00201 rgb[0] = rgb[3]; 00202 pc.printf("."); 00203 } 00204 blankLightStrips(); 00205 pc.printf("\r\n"); 00206 } 00207 00208 static void selfTest() 00209 { 00210 pc.printf("self test: "); 00211 00212 selfTestLightStrips(); 00213 selfTestServo(); 00214 selfTestLEDs(); 00215 00216 pc.printf("done\n"); 00217 } 00218 00219 // rainbow that wraps around entire frame 00220 void updateStripsRainbow() 00221 { 00222 static int skip = 0; 00223 00224 showRainbow(lightStrip1, 1.0, maxBrite, currentSpeed, 0.5, 3, skip); 00225 showRainbow(lightStrip2, 1.0, maxBrite, currentSpeed + 0.5, 0.5, -3, skip); 00226 refreshLightStrips(); 00227 skip++; 00228 skip %= 3; 00229 } 00230 00231 void updateEyes() 00232 { 00233 static bool eyesOn; 00234 eyes = eyesOn ? 1 : 0; 00235 eyesOn = !eyesOn; 00236 } 00237 00238 int main(void) 00239 { 00240 pc.baud(115200); 00241 pc.printf("\r\n\r\nNevermore's Revenge!\r\ncompiled " __DATE__ ", " __TIME__ "\r\n"); 00242 00243 lightStrip1.begin(); 00244 lightStrip2.begin(); 00245 00246 rled = 1.0; 00247 gled = 1.0; 00248 servo.period_ms(20); 00249 00250 selfTest(); 00251 00252 Timer elapsedTime; 00253 00254 Ticker flapper; 00255 flapper.attach(flap, maxFlapTime); 00256 00257 Ticker stripUpdater; 00258 stripUpdater.attach(updateStripsRainbow, 0.3); 00259 00260 Ticker eyeUpdater; 00261 eyeUpdater.attach(updateEyes, 0.2); 00262 00263 elapsedTime.start(); 00264 00265 bool lastButton = button1.read(); 00266 00267 for (;; ) { 00268 bool buttonValue = button1.read(); 00269 if (buttonValue != lastButton) { 00270 if (!buttonValue) { 00271 flapper.detach(); 00272 flapper.attach(flap, maxFlapTime); 00273 stripUpdater.detach(); 00274 stripUpdater.attach(updateStripsRainbow, 0.3); 00275 } else { 00276 flapper.detach(); 00277 flapper.attach(flap, minFlapTime); 00278 stripUpdater.detach(); 00279 stripUpdater.attach(updateStripsRainbow, 0.1); 00280 } 00281 } 00282 00283 wait(0.1); 00284 } 00285 }
Generated on Tue Jul 12 2022 18:19:51 by 1.7.2